{"action":"created","comment":{"url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/comments/39449154","id":39449154,"diff_hunk":"@@ -0,0 +1,178 @@\n+---\n+layout: post\n+title: Rotary Wheel Control with HeavenFresh\n+author: Jason Poon\n+author-link: http://www.jasonpoon.ca\n+date: 2015-09-09 04:35:31\n+categories: universal-windows-app csharp uwp\n+color: blue\n+excerpt: Rotary Wheel Control with HeavenFresh\n+---\n+\n+Windows 10 introduces the Universal Windows Platform (UWP) providing a common app platform enabling the ability to install the same app package onto every Windows 10 device:  phones, desktops, Xbox, IoT, Surface Hub, etc. We worked with [@HeavenFresh](https://twitter.com/heavenfresh) to create a UWP application and, in the process, a rotary wheel user control. This case study describes the approach taken in building the resulting user control including the mechanics involved with drawing a rotary wheel, supporting user interaction, and the usage of storyboards for animations. \n+\n+# Customer Problem\n+\n+[HeavenFresh](http://www.heavenfresh.com/) makes a plethora of products for the home including [AllJoyn](https://ms-iot.github.io/content/en-US/win10/AllJoyn.htm) connected air purifiers and humidifers. In preparation for [IFA Berlin 2015](http://b2b.ifa-berlin.com/), we held a hackfest to build a [Universal Windows Platform](https://msdn.microsoft.com/en-us/library/windows/apps/Dn958439.aspx) application to control HeavenFresh devices from a Windows 10 device. During this collaboration, we wanted a central user interaction element to configure various settings of the humidifer/purifier which led us to building a rotary wheel control.\n+\n+# Overview of the Solution\n+\n+Shown below is a stylized rotary wheel control used in HeavenFresh's application: \n+\n+![Rotary Wheel]({{site.baseurl}}/images/2015-09-09-Rotary-Wheel-Control-with-HeavenFresh/rotary_wheel_styled.gif)\n+\n+Given the labels, the user control creates the necessary number of slices. Touch and mouse events are supported, and when the user completes manipulation of the wheel, the wheel will animate back to the center of the selected slice.\n+\n+# Implementation\n+\n+The rotary wheel can be broken down into following components:\n+\n+* Individual *pie slice*\n+* Collection of slices making a *pie chart*\n+* User manipulation to rotate control\n+* Animation of centering to the selected slice\n+\n+## Pie Slice\n+\n+In its basic form, the rotary wheel is comprised of an arbitrary number of equally sized slices. Leveraging [Jerry Nixon's](http://blog.jerrynixon.com/2012/06/windows-8-animated-pie-slice.html) blog post, three arguments are required to build a slice:\n+\n+* `StartAngle` - start angle of the slice\n+* `Angle` - total angle of the slice\n+* `Radius` - radius of pie slice\n+\n+Centering of the label in the middle of the slice requires two render transformations:\n+\n+1. *rotate* - align the label with the angle of the slice\n+2. *translate* - move the label to the center of the slice\n+\n+The resulting XAML is shown below:\n+\n+```xml\n+<Grid x:Name=\"layoutRoot\">\n+\t<!-- Slice Path (refer to Jerry Nixon post) -->\n+    <userControl:PieSlicePath x:Name=\"pieSlicePath\" Canvas.ZIndex=\"1\" />\n+\n+    <!-- Label -->\n+    <TextBlock x:Name=\"textBlock\" Canvas.ZIndex=\"2\" Text=\"{Binding Label}\" RenderTransformOrigin=\"0.5, 0.5\">\n+        <TextBlock.RenderTransform>\n+            <TransformGroup>\n+                <RotateTransform x:Name=\"textBlockRotate\" />\n+                <TranslateTransform x:Name=\"textBlockTranslate\" />\n+            </TransformGroup>\n+        </TextBlock.RenderTransform>\n+    </TextBlock>\n+</Grid>\n+```\n+\n+### Rotate\n+\n+Firstly, the rotate transform is configured to centered on the textblock with `RenderTransformOrigin=\"0.5, 0.5\"'. Given the total angle of the pie slice (ie. `Angle`), to align the label with the slice, the label is rotated half the total angle: `StartAngle + Angle/2`.  \n+\n+### Translate\n+\n+To appear centered in the middle of the slice, the label is needs to be translated approximately 4/5 the slice radius. \n+\n+![diagram of pie slice with a centered label]({{site.baseurl}}/images/2015-09-09-Rotary-Wheel-Control-with-HeavenFresh/label-center.png)\n+\n+A closer look at the above diagram results in the following right-angle triangle: \n+\n+![trigonometry]({{site.baseurl}}/images/2015-09-09-Rotary-Wheel-Control-with-HeavenFresh/triangle.png)\n+\n+The sides of the triangle can be calculated through basic trigonometry.\n+\n+```c#\n+// where quadrant is an enumeration\n+// NE = 0, SE = 1, SW = 2, NW = 4\n+var quadrantAngle = startAngle + angle/2 - 90*(int)quadrant;\n+\n+var adjacent = Math.Cos(Math.PI/180* quadrantAngle) *radius;\n+var opposite = Math.Sin(Math.PI/180* quadrantAngle) *radius;\n+```\n+\n+In the grid system, translations are relative to the top-left most point of the element (down = positive; up = negative; left = positive; right = negative). The below diagram visually displays the cartesian grid with (0,0) being the top-left most point of the element.\n+\n+![cartesian grid]({{site.baseurl}}/images/2015-09-09-Rotary-Wheel-Control-with-HeavenFresh/cartesian.png)\n+\n+As such, depending on which quadrant the slice is in, the polarities of the X,Y translation will vary.\n+\n+## Pie Chart\n+\n+A pie chart is a collection of pie slices with differing `StartAngle`. The `Angle` of each slice remains constant and can be calculated as `360/<total number of slices>`.\n+\n+```c#\n+var sliceLabels = new[] {'high', 'med', 'low'};\n+var sliceSize = 360/sliceLabels.Count();\n+foreach (var slice in sliceLabels)\n+{\n+    var pieSlice = new PieSlice\n+    {\n+        StartAngle = startAngle,\n+        Angle = sliceSize,\n+\t\t...\n+    };\n+\n+    // add pie slice to canvas\n+    _pieSlices.Add(pieSlice);\n+    startAngle += sliceSize;\n+}\n+```\n+\n+## User Manipulation\n+\n+In order to support user manipulation of the rotary wheel, the parent grid housing the pie chart is given a rotate transform in which the `Angle` property will be updated when a `ManipulationDelta` event occurs. The angle of rotation is then calculated based on the touch point. \n+\n+```xml\n+<StackPanel x:Name=\"layoutRoot\" \n+            ManipulationMode=\"All\" \n+            ManipulationDelta=\"layoutRoot_ManipulationDelta\"\n+            ManipulationCompleted=\"layoutRoot_ManipulationCompleted\">\n+    <Grid x:Name=\"layoutSpinner\">\n+\t\t<!-- pie slices are programmatically added here -->\n+        <Grid.RenderTransform>\n+            <RotateTransform x:Name=\"gridRotateTransform\" Angle=\"{Binding Angle}\" />\n+        </Grid.RenderTransform>\n+    </Grid>\n+</StackPanel>\n+```\n+\n+## Animation Centering to Selected Slice\n+\n+Following the user interaction, the rotary wheel rotates itself to the center of the selected slice. This is accomplished through `Storyboard`.  As shown below, our `Storyboard` will target the `Angle` property of the `gridRotateTransform` control. ","path":"_posts/2015-09-09-Rotary-Wheel-Control-with-HeavenFresh.md","position":140,"original_position":140,"commit_id":"630b65046ab5c8306aeac7508c0c3c6f9eb682d7","original_commit_id":"630b65046ab5c8306aeac7508c0c3c6f9eb682d7","user":{"login":"jpoon","id":85374,"avatar_url":"https://avatars.githubusercontent.com/u/85374?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoon","html_url":"https://github.com/jpoon","followers_url":"https://api.github.com/users/jpoon/followers","following_url":"https://api.github.com/users/jpoon/following{/other_user}","gists_url":"https://api.github.com/users/jpoon/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoon/subscriptions","organizations_url":"https://api.github.com/users/jpoon/orgs","repos_url":"https://api.github.com/users/jpoon/repos","events_url":"https://api.github.com/users/jpoon/events{/privacy}","received_events_url":"https://api.github.com/users/jpoon/received_events","type":"User","site_admin":false},"body":"Done.\r\n\r\n> As an added effect, upon the completion of the user interaction, the rotary wheel will rotate itself to the center of the selected slice. Such animations are accomplished through [Storyboards](https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.animation.storyboard).  \r\n\r\n> Our `Storyboard` will target the `Angle` property of the `gridRotateTransform` object. As the `Angle` property is of type `Double`,  we apply a [DoubleAnimation](https://msdn.microsoft.com/en-us/library/system.windows.media.animation.doubleanimation(v=vs.95).aspx) to transition the property between two `Double` values over a specified duration.","created_at":"2015-09-14T21:23:32Z","updated_at":"2015-09-14T21:23:32Z","html_url":"https://github.com/CatalystCode/case-studies/pull/82#discussion_r39449154","pull_request_url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82","_links":{"self":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/comments/39449154"},"html":{"href":"https://github.com/CatalystCode/case-studies/pull/82#discussion_r39449154"},"pull_request":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82"}}},"pull_request":{"url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82","id":44630750,"html_url":"https://github.com/CatalystCode/case-studies/pull/82","diff_url":"https://github.com/CatalystCode/case-studies/pull/82.diff","patch_url":"https://github.com/CatalystCode/case-studies/pull/82.patch","issue_url":"https://api.github.com/repos/CatalystCode/case-studies/issues/82","number":82,"state":"open","locked":false,"title":"Rotary Wheel User Control with HeavenFresh","user":{"login":"jpoon","id":85374,"avatar_url":"https://avatars.githubusercontent.com/u/85374?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoon","html_url":"https://github.com/jpoon","followers_url":"https://api.github.com/users/jpoon/followers","following_url":"https://api.github.com/users/jpoon/following{/other_user}","gists_url":"https://api.github.com/users/jpoon/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoon/subscriptions","organizations_url":"https://api.github.com/users/jpoon/orgs","repos_url":"https://api.github.com/users/jpoon/repos","events_url":"https://api.github.com/users/jpoon/events{/privacy}","received_events_url":"https://api.github.com/users/jpoon/received_events","type":"User","site_admin":false},"body":"Looking for some reviewers, maybe @tylergibson or @felixrieseberg?","created_at":"2015-09-10T06:02:29Z","updated_at":"2015-09-14T21:23:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ee488a1092cc445a5d2ca7c55e5607e73f8887ad","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82/commits","review_comments_url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82/comments","review_comment_url":"https://api.github.com/repos/CatalystCode/case-studies/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CatalystCode/case-studies/issues/82/comments","statuses_url":"https://api.github.com/repos/CatalystCode/case-studies/statuses/630b65046ab5c8306aeac7508c0c3c6f9eb682d7","head":{"label":"jpoon:rotary-wheel-case-study","ref":"rotary-wheel-case-study","sha":"630b65046ab5c8306aeac7508c0c3c6f9eb682d7","user":{"login":"jpoon","id":85374,"avatar_url":"https://avatars.githubusercontent.com/u/85374?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoon","html_url":"https://github.com/jpoon","followers_url":"https://api.github.com/users/jpoon/followers","following_url":"https://api.github.com/users/jpoon/following{/other_user}","gists_url":"https://api.github.com/users/jpoon/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoon/subscriptions","organizations_url":"https://api.github.com/users/jpoon/orgs","repos_url":"https://api.github.com/users/jpoon/repos","events_url":"https://api.github.com/users/jpoon/events{/privacy}","received_events_url":"https://api.github.com/users/jpoon/received_events","type":"User","site_admin":false},"repo":{"id":41413945,"name":"case-studies","full_name":"jpoon/case-studies","owner":{"login":"jpoon","id":85374,"avatar_url":"https://avatars.githubusercontent.com/u/85374?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoon","html_url":"https://github.com/jpoon","followers_url":"https://api.github.com/users/jpoon/followers","following_url":"https://api.github.com/users/jpoon/following{/other_user}","gists_url":"https://api.github.com/users/jpoon/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoon/subscriptions","organizations_url":"https://api.github.com/users/jpoon/orgs","repos_url":"https://api.github.com/users/jpoon/repos","events_url":"https://api.github.com/users/jpoon/events{/privacy}","received_events_url":"https://api.github.com/users/jpoon/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jpoon/case-studies","description":"Case Studies published by Microsoft's Partner Catalyst Team","fork":true,"url":"https://api.github.com/repos/jpoon/case-studies","forks_url":"https://api.github.com/repos/jpoon/case-studies/forks","keys_url":"https://api.github.com/repos/jpoon/case-studies/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jpoon/case-studies/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jpoon/case-studies/teams","hooks_url":"https://api.github.com/repos/jpoon/case-studies/hooks","issue_events_url":"https://api.github.com/repos/jpoon/case-studies/issues/events{/number}","events_url":"https://api.github.com/repos/jpoon/case-studies/events","assignees_url":"https://api.github.com/repos/jpoon/case-studies/assignees{/user}","branches_url":"https://api.github.com/repos/jpoon/case-studies/branches{/branch}","tags_url":"https://api.github.com/repos/jpoon/case-studies/tags","blobs_url":"https://api.github.com/repos/jpoon/case-studies/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jpoon/case-studies/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jpoon/case-studies/git/refs{/sha}","trees_url":"https://api.github.com/repos/jpoon/case-studies/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jpoon/case-studies/statuses/{sha}","languages_url":"https://api.github.com/repos/jpoon/case-studies/languages","stargazers_url":"https://api.github.com/repos/jpoon/case-studies/stargazers","contributors_url":"https://api.github.com/repos/jpoon/case-studies/contributors","subscribers_url":"https://api.github.com/repos/jpoon/case-studies/subscribers","subscription_url":"https://api.github.com/repos/jpoon/case-studies/subscription","commits_url":"https://api.github.com/repos/jpoon/case-studies/commits{/sha}","git_commits_url":"https://api.github.com/repos/jpoon/case-studies/git/commits{/sha}","comments_url":"https://api.github.com/repos/jpoon/case-studies/comments{/number}","issue_comment_url":"https://api.github.com/repos/jpoon/case-studies/issues/comments{/number}","contents_url":"https://api.github.com/repos/jpoon/case-studies/contents/{+path}","compare_url":"https://api.github.com/repos/jpoon/case-studies/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jpoon/case-studies/merges","archive_url":"https://api.github.com/repos/jpoon/case-studies/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jpoon/case-studies/downloads","issues_url":"https://api.github.com/repos/jpoon/case-studies/issues{/number}","pulls_url":"https://api.github.com/repos/jpoon/case-studies/pulls{/number}","milestones_url":"https://api.github.com/repos/jpoon/case-studies/milestones{/number}","notifications_url":"https://api.github.com/repos/jpoon/case-studies/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jpoon/case-studies/labels{/name}","releases_url":"https://api.github.com/repos/jpoon/case-studies/releases{/id}","created_at":"2015-08-26T08:28:11Z","updated_at":"2015-08-26T08:28:12Z","pushed_at":"2015-09-11T17:57:09Z","git_url":"git://github.com/jpoon/case-studies.git","ssh_url":"git@github.com:jpoon/case-studies.git","clone_url":"https://github.com/jpoon/case-studies.git","svn_url":"https://github.com/jpoon/case-studies","homepage":"http://aka.ms/case-studies","size":22108,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"gh-pages"}},"base":{"label":"CatalystCode:gh-pages","ref":"gh-pages","sha":"c2369311cff00bf0e80216bc23a56d6649fd0caf","user":{"login":"CatalystCode","id":12663554,"avatar_url":"https://avatars.githubusercontent.com/u/12663554?v=3","gravatar_id":"","url":"https://api.github.com/users/CatalystCode","html_url":"https://github.com/CatalystCode","followers_url":"https://api.github.com/users/CatalystCode/followers","following_url":"https://api.github.com/users/CatalystCode/following{/other_user}","gists_url":"https://api.github.com/users/CatalystCode/gists{/gist_id}","starred_url":"https://api.github.com/users/CatalystCode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CatalystCode/subscriptions","organizations_url":"https://api.github.com/users/CatalystCode/orgs","repos_url":"https://api.github.com/users/CatalystCode/repos","events_url":"https://api.github.com/users/CatalystCode/events{/privacy}","received_events_url":"https://api.github.com/users/CatalystCode/received_events","type":"Organization","site_admin":false},"repo":{"id":39454207,"name":"case-studies","full_name":"CatalystCode/case-studies","owner":{"login":"CatalystCode","id":12663554,"avatar_url":"https://avatars.githubusercontent.com/u/12663554?v=3","gravatar_id":"","url":"https://api.github.com/users/CatalystCode","html_url":"https://github.com/CatalystCode","followers_url":"https://api.github.com/users/CatalystCode/followers","following_url":"https://api.github.com/users/CatalystCode/following{/other_user}","gists_url":"https://api.github.com/users/CatalystCode/gists{/gist_id}","starred_url":"https://api.github.com/users/CatalystCode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CatalystCode/subscriptions","organizations_url":"https://api.github.com/users/CatalystCode/orgs","repos_url":"https://api.github.com/users/CatalystCode/repos","events_url":"https://api.github.com/users/CatalystCode/events{/privacy}","received_events_url":"https://api.github.com/users/CatalystCode/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CatalystCode/case-studies","description":"Case Studies published by Microsoft's Partner Catalyst Team","fork":false,"url":"https://api.github.com/repos/CatalystCode/case-studies","forks_url":"https://api.github.com/repos/CatalystCode/case-studies/forks","keys_url":"https://api.github.com/repos/CatalystCode/case-studies/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CatalystCode/case-studies/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CatalystCode/case-studies/teams","hooks_url":"https://api.github.com/repos/CatalystCode/case-studies/hooks","issue_events_url":"https://api.github.com/repos/CatalystCode/case-studies/issues/events{/number}","events_url":"https://api.github.com/repos/CatalystCode/case-studies/events","assignees_url":"https://api.github.com/repos/CatalystCode/case-studies/assignees{/user}","branches_url":"https://api.github.com/repos/CatalystCode/case-studies/branches{/branch}","tags_url":"https://api.github.com/repos/CatalystCode/case-studies/tags","blobs_url":"https://api.github.com/repos/CatalystCode/case-studies/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CatalystCode/case-studies/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CatalystCode/case-studies/git/refs{/sha}","trees_url":"https://api.github.com/repos/CatalystCode/case-studies/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CatalystCode/case-studies/statuses/{sha}","languages_url":"https://api.github.com/repos/CatalystCode/case-studies/languages","stargazers_url":"https://api.github.com/repos/CatalystCode/case-studies/stargazers","contributors_url":"https://api.github.com/repos/CatalystCode/case-studies/contributors","subscribers_url":"https://api.github.com/repos/CatalystCode/case-studies/subscribers","subscription_url":"https://api.github.com/repos/CatalystCode/case-studies/subscription","commits_url":"https://api.github.com/repos/CatalystCode/case-studies/commits{/sha}","git_commits_url":"https://api.github.com/repos/CatalystCode/case-studies/git/commits{/sha}","comments_url":"https://api.github.com/repos/CatalystCode/case-studies/comments{/number}","issue_comment_url":"https://api.github.com/repos/CatalystCode/case-studies/issues/comments{/number}","contents_url":"https://api.github.com/repos/CatalystCode/case-studies/contents/{+path}","compare_url":"https://api.github.com/repos/CatalystCode/case-studies/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CatalystCode/case-studies/merges","archive_url":"https://api.github.com/repos/CatalystCode/case-studies/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CatalystCode/case-studies/downloads","issues_url":"https://api.github.com/repos/CatalystCode/case-studies/issues{/number}","pulls_url":"https://api.github.com/repos/CatalystCode/case-studies/pulls{/number}","milestones_url":"https://api.github.com/repos/CatalystCode/case-studies/milestones{/number}","notifications_url":"https://api.github.com/repos/CatalystCode/case-studies/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CatalystCode/case-studies/labels{/name}","releases_url":"https://api.github.com/repos/CatalystCode/case-studies/releases{/id}","created_at":"2015-07-21T15:37:31Z","updated_at":"2015-07-22T02:29:51Z","pushed_at":"2015-09-14T20:21:35Z","git_url":"git://github.com/CatalystCode/case-studies.git","ssh_url":"git@github.com:CatalystCode/case-studies.git","clone_url":"https://github.com/CatalystCode/case-studies.git","svn_url":"https://github.com/CatalystCode/case-studies","homepage":"http://aka.ms/case-studies","size":34563,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":25,"mirror_url":null,"open_issues_count":15,"forks":25,"open_issues":15,"watchers":0,"default_branch":"gh-pages"}},"_links":{"self":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82"},"html":{"href":"https://github.com/CatalystCode/case-studies/pull/82"},"issue":{"href":"https://api.github.com/repos/CatalystCode/case-studies/issues/82"},"comments":{"href":"https://api.github.com/repos/CatalystCode/case-studies/issues/82/comments"},"review_comments":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82/comments"},"review_comment":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CatalystCode/case-studies/pulls/82/commits"},"statuses":{"href":"https://api.github.com/repos/CatalystCode/case-studies/statuses/630b65046ab5c8306aeac7508c0c3c6f9eb682d7"}}}}