{"action":"created","comment":{"url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/comments/36676154","id":36676154,"diff_hunk":"@@ -0,0 +1,161 @@\n+var React = require('react');\n+var Tether = require('tether');\n+var PopoverBackground = require('./PopoverBackground');\n+\n+var Popover = React.createClass({\n+\n+  propTypes: {\n+    placement: React.PropTypes.oneOf(['right', 'bottom-right', 'left', 'bottom-left']),\n+    isOpen: React.PropTypes.bool,\n+    onRequestClose: React.PropTypes.func\n+  },\n+\n+  getDefaultProps: function () {\n+    return {\n+      placement: 'right',\n+      isOpen: false\n+    };\n+  },\n+\n+  componentWillUnmount: function () {\n+    this._hide();\n+    document.body.removeChild(this._containerDiv);\n+    document.body.removeChild(this._backgroundDiv);\n+  },\n+\n+  componentDidMount: function () {\n+    this._containerDiv = document.createElement('div');\n+    document.body.appendChild(this._containerDiv);\n+    this._backgroundDiv = document.createElement('div');\n+    this._backgroundDiv.style.display = 'none';\n+    document.body.appendChild(this._backgroundDiv);\n+    this._togglePopoverOverlay();\n+  },\n+\n+  componentDidUpdate: function () {\n+    this._togglePopoverOverlay();\n+  },\n+\n+  render: function () {\n+    return null;\n+  },\n+\n+  _togglePopoverOverlay: function () {\n+    if (this.props.isOpen) {\n+      this._show();\n+    } else {\n+      this._hide();\n+    }\n+  },\n+\n+  _hide: function () {\n+    this._hidePopoverOverlay();\n+    this._hidePopoverBackgroundOverlay();\n+  },\n+\n+  _hidePopoverOverlay: function () {\n+    this._removeDocumentListeners();\n+    this._containerDiv.className = this._containerDiv.className.replace( /(?:^|\\s)rs-popover(?!\\S)/g , '' );\n+    if (this._tether) {\n+      this._tether.destroy();\n+      this._tether = null;\n+    }\n+    if (this._popoverNode) {\n+      React.unmountComponentAtNode(this._containerDiv);\n+      this._popoverNode = null;\n+    }\n+  },\n+\n+  _hidePopoverBackgroundOverlay: function () {\n+    this._backgroundDiv.style.display = 'none';\n+    React.unmountComponentAtNode(this._backgroundDiv);\n+  },\n+\n+  _removeDocumentListeners: function () {\n+    document.removeEventListener('keyup', this._handleEscapePress, false);\n+  },\n+\n+  _show: function () {\n+    this._renderPopoverOverlay();\n+    this._listenForEscapePress();\n+  },\n+\n+  _renderPopoverOverlay: function () {\n+    var popover;\n+\n+    this._backgroundDiv.style.display = 'block';\n+    React.render(<PopoverBackground onRequestClose={this.props.onRequestClose} />, this._backgroundDiv);\n+    this._containerDiv.className += ' rs-popover';\n+\n+    popover = React.cloneElement(\n+      React.Children.only(this.props.children),\n+      {\n+        placement: this.props.placement\n+      }\n+    );\n+    this._popoverNode = React.render(popover, this._containerDiv);\n+    this._tether = this._createTether(this._getTetherConfig());\n+  },\n+\n+  // This is a seam for testing\n+  _createTether: function (tetherConfig) {\n+    return new Tether(tetherConfig);\n+  },\n+\n+  _getTetherConfig: function () {\n+    var tetherConfig;\n+\n+    switch (this.props.placement) {\n+      case 'left':\n+        tetherConfig = {\n+          attachment: 'top right',\n+          targetAttachment: 'middle left',\n+          offset: '38px 20px'","path":"src/Popover.jsx","position":113,"original_position":113,"commit_id":"4ddbb1da8d8f7354b9fc23d7ea9d84be768b6425","original_commit_id":"4ddbb1da8d8f7354b9fc23d7ea9d84be768b6425","user":{"login":"adampickeral","id":1210971,"avatar_url":"https://avatars.githubusercontent.com/u/1210971?v=3","gravatar_id":"","url":"https://api.github.com/users/adampickeral","html_url":"https://github.com/adampickeral","followers_url":"https://api.github.com/users/adampickeral/followers","following_url":"https://api.github.com/users/adampickeral/following{/other_user}","gists_url":"https://api.github.com/users/adampickeral/gists{/gist_id}","starred_url":"https://api.github.com/users/adampickeral/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adampickeral/subscriptions","organizations_url":"https://api.github.com/users/adampickeral/orgs","repos_url":"https://api.github.com/users/adampickeral/repos","events_url":"https://api.github.com/users/adampickeral/events{/privacy}","received_events_url":"https://api.github.com/users/adampickeral/received_events","type":"User","site_admin":false},"body":"it looks like we use some pretty magic numbers in reach for these kinds of offsets https://github.com/racker/reach/blob/master/cloudkick/webapp/site_media/js/ck/widgets/popover.js#L114\r\n\r\ni'm not sure where CSS for this would live actually. do we bundle it with canon-react? i think these offsets might be tied to the logic you're using to do the actual positioning, so it might not make sense to live in something more general, like canon.\r\n\r\nI'm into new waters here when it comes to positioning and figuring out the right placement (even though tether is handling most of the hard work), so I'm certainly open to suggestions","created_at":"2015-08-10T19:52:55Z","updated_at":"2015-08-10T19:52:55Z","html_url":"https://github.com/rackerlabs/canon-react/pull/27#discussion_r36676154","pull_request_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27","_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/comments/36676154"},"html":{"href":"https://github.com/rackerlabs/canon-react/pull/27#discussion_r36676154"},"pull_request":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27"}}},"pull_request":{"url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27","id":39018816,"html_url":"https://github.com/rackerlabs/canon-react/pull/27","diff_url":"https://github.com/rackerlabs/canon-react/pull/27.diff","patch_url":"https://github.com/rackerlabs/canon-react/pull/27.patch","issue_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/27","number":27,"state":"open","locked":false,"title":"Popover","user":{"login":"adampickeral","id":1210971,"avatar_url":"https://avatars.githubusercontent.com/u/1210971?v=3","gravatar_id":"","url":"https://api.github.com/users/adampickeral","html_url":"https://github.com/adampickeral","followers_url":"https://api.github.com/users/adampickeral/followers","following_url":"https://api.github.com/users/adampickeral/following{/other_user}","gists_url":"https://api.github.com/users/adampickeral/gists{/gist_id}","starred_url":"https://api.github.com/users/adampickeral/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adampickeral/subscriptions","organizations_url":"https://api.github.com/users/adampickeral/orgs","repos_url":"https://api.github.com/users/adampickeral/repos","events_url":"https://api.github.com/users/adampickeral/events{/privacy}","received_events_url":"https://api.github.com/users/adampickeral/received_events","type":"User","site_admin":false},"body":"![image](https://cloud.githubusercontent.com/assets/1210971/8464875/83d68ea2-2013-11e5-8d09-1d264a37dfd3.png)\r\n\r\nhttp://rackerlabs.github.io/canon/ui-components/#popover\r\n\r\n## Components\r\n`Popover`\r\n`PopoverOverlay`\r\n`PopoverBody`\r\n`PopoverFooter`\r\n\r\n### `Popover`\r\nThe `Popover` component controls the behavior of the popover itself (positioning, open/closed, request for close, etc.) The `Popover` has four properties:\r\n* `placement`\r\n* `isOpen`\r\n* `onRequestClose`\r\n* `target`\r\n\r\n###### `placement`\r\n`placement` defines the position of the popover in relation to its target. Values are one of `'right', 'bottom-right', 'left', 'bottom-left'\r\n\r\n###### `isOpen`\r\n`isOpen` accepts boolean values and defines whether or not the popover is open or closed. It is up to the parent component to decide whether or not a popover should be displayed. This is necessary to allow for such things as allowing the processing of a command to finish before closing a popover.\r\n\r\n###### `onRequestClose`\r\n`onRequestClose` is a callback that is used to notify a parent component that some action has occured requesting to close a popover. This could be the clicking of a cancel link on the popover. Events that the popover itself monitors and invokes the callback include the pressing of the Escape key and clicking off of the popover.\r\n\r\n###### `target`\r\n`target` is the id of the element at which the popover will be pointing.\r\n\r\n### `PopoverOverlay`\r\nThe `PopoverOverlay` class renders the outer markup of a popover, as well as the arrow of the popover. It accepts a `placement` prop (passed to it from the `Popover`) which is used to determine the position of the arrow relative to the target at  which the popover will be pointing. The values accepted are the same as those of the `PopoverTrigger`.\r\n\r\n### `PopoverBody` and `PopoverFooter`\r\nThese components should be used together when displaying a popover that will do some sort of form processing. If a popover is only being used to display information, these components aren't needed. The body and footer components simple wrap their children in the appropriate markup for a popover form. They don't do any special processing of the children to be rendered. Any change of state of buttons rendered in the footer is the responsibility of the consumer to update. This allows for greater flexibility of what the body and footer can be composed of.\r\n\r\n## Example\r\n###### Render the Trigger and the Popover\r\n```javascript\r\n  // Parent component rendering the popover and the trigger\r\n  {\r\n    showUpdatePopover: function () {\r\n      this.setState({shouldShowUpdateNamePopover: true})\r\n    },\r\n\r\n    requestCloseCallback: function () {\r\n      this.setState({\r\n        shouldShowUpdateNamePopover: this.getState().isUpdateNameProcessing\r\n      });\r\n    },\r\n\r\n    render: function () {\r\n      return (\r\n        <div>  \r\n          <Button id='target-element-id' onClick={this.showUpdatePopover}>Hello</Button>\r\n          <UpdateNamePopover placement='right' isOpen={this.getState().shouldShowUpdateNamePopover} onRequestClose={this.requestCloseCallback} target='target-element-id' />\r\n        </div>\r\n      );\r\n    }\r\n  }\r\n```\r\n\r\n###### Popover\r\n```javascript\r\nvar UpdateNamePopover = React.createClass({\r\n  render: function () {\r\n    return (\r\n      <Popover placement={this.props.placement} isOpen={this.props.isOpen} onRequestClose={this.props.onRequestClose} target={this.props.target}>\r\n        <PopoverOverlay>\r\n          <PopoverBody>\r\n            <form>\r\n             <label>Name</label>\r\n             <input type='text' />\r\n            </form>\r\n          </PopoverBody>\r\n          <PopoverFooter>\r\n            <Button type='primary' onClick={this._processSave}>Save</Button>\r\n            <Button type='link' onClick={this.props.onRequestClose}>Cancel</Button>\r\n            <ProcessingIndicator hidden={true} />\r\n          </PopoverFooter>\r\n        </PopoverOverlay>\r\n      </Popover>\r\n    );\r\n  },\r\n\r\n  _processSave: function () {\r\n    // set some state to toggle button states for processing of action\r\n    // perform some action, maybe through stores\r\n    // on successful action completion, invoke this.props.onRequestClose.\r\n    // OR, register for events in a store and update state appropriately\r\n  }\r\n});\r\n```","created_at":"2015-07-01T19:54:44Z","updated_at":"2015-08-10T19:52:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"59ffa4305e10d19aedc52ab82404c4da1d3d742f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27/commits","review_comments_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27/comments","review_comment_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/27/comments","statuses_url":"https://api.github.com/repos/rackerlabs/canon-react/statuses/4ddbb1da8d8f7354b9fc23d7ea9d84be768b6425","head":{"label":"rackerlabs:popover","ref":"popover","sha":"4ddbb1da8d8f7354b9fc23d7ea9d84be768b6425","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":31282707,"name":"canon-react","full_name":"rackerlabs/canon-react","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rackerlabs/canon-react","description":"React components for Rackspace's Canon framework","fork":false,"url":"https://api.github.com/repos/rackerlabs/canon-react","forks_url":"https://api.github.com/repos/rackerlabs/canon-react/forks","keys_url":"https://api.github.com/repos/rackerlabs/canon-react/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/canon-react/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/canon-react/teams","hooks_url":"https://api.github.com/repos/rackerlabs/canon-react/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/canon-react/events","assignees_url":"https://api.github.com/repos/rackerlabs/canon-react/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/canon-react/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/canon-react/tags","blobs_url":"https://api.github.com/repos/rackerlabs/canon-react/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/canon-react/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/canon-react/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/canon-react/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/canon-react/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/canon-react/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/canon-react/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/canon-react/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/canon-react/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/canon-react/subscription","commits_url":"https://api.github.com/repos/rackerlabs/canon-react/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/canon-react/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/canon-react/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/canon-react/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/canon-react/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/canon-react/merges","archive_url":"https://api.github.com/repos/rackerlabs/canon-react/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/canon-react/downloads","issues_url":"https://api.github.com/repos/rackerlabs/canon-react/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/canon-react/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/canon-react/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/canon-react/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/canon-react/releases{/id}","created_at":"2015-02-24T21:23:09Z","updated_at":"2015-06-09T18:06:37Z","pushed_at":"2015-08-10T18:24:59Z","git_url":"git://github.com/rackerlabs/canon-react.git","ssh_url":"git@github.com:rackerlabs/canon-react.git","clone_url":"https://github.com/rackerlabs/canon-react.git","svn_url":"https://github.com/rackerlabs/canon-react","homepage":"http://rackerlabs.github.io/canon-react/","size":696,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":14,"forks":0,"open_issues":14,"watchers":2,"default_branch":"master"}},"base":{"label":"rackerlabs:master","ref":"master","sha":"6aa8c63f6901f6c4cbbea84d1897dc597320440f","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":31282707,"name":"canon-react","full_name":"rackerlabs/canon-react","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rackerlabs/canon-react","description":"React components for Rackspace's Canon framework","fork":false,"url":"https://api.github.com/repos/rackerlabs/canon-react","forks_url":"https://api.github.com/repos/rackerlabs/canon-react/forks","keys_url":"https://api.github.com/repos/rackerlabs/canon-react/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/canon-react/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/canon-react/teams","hooks_url":"https://api.github.com/repos/rackerlabs/canon-react/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/canon-react/events","assignees_url":"https://api.github.com/repos/rackerlabs/canon-react/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/canon-react/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/canon-react/tags","blobs_url":"https://api.github.com/repos/rackerlabs/canon-react/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/canon-react/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/canon-react/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/canon-react/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/canon-react/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/canon-react/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/canon-react/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/canon-react/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/canon-react/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/canon-react/subscription","commits_url":"https://api.github.com/repos/rackerlabs/canon-react/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/canon-react/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/canon-react/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/canon-react/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/canon-react/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/canon-react/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/canon-react/merges","archive_url":"https://api.github.com/repos/rackerlabs/canon-react/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/canon-react/downloads","issues_url":"https://api.github.com/repos/rackerlabs/canon-react/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/canon-react/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/canon-react/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/canon-react/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/canon-react/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/canon-react/releases{/id}","created_at":"2015-02-24T21:23:09Z","updated_at":"2015-06-09T18:06:37Z","pushed_at":"2015-08-10T18:24:59Z","git_url":"git://github.com/rackerlabs/canon-react.git","ssh_url":"git@github.com:rackerlabs/canon-react.git","clone_url":"https://github.com/rackerlabs/canon-react.git","svn_url":"https://github.com/rackerlabs/canon-react","homepage":"http://rackerlabs.github.io/canon-react/","size":696,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":14,"forks":0,"open_issues":14,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27"},"html":{"href":"https://github.com/rackerlabs/canon-react/pull/27"},"issue":{"href":"https://api.github.com/repos/rackerlabs/canon-react/issues/27"},"comments":{"href":"https://api.github.com/repos/rackerlabs/canon-react/issues/27/comments"},"review_comments":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27/comments"},"review_comment":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rackerlabs/canon-react/pulls/27/commits"},"statuses":{"href":"https://api.github.com/repos/rackerlabs/canon-react/statuses/4ddbb1da8d8f7354b9fc23d7ea9d84be768b6425"}}}}