{"action":"created","comment":{"url":"https://api.github.com/repos/iodide-project/iodide/pulls/comments/233910849","pull_request_review_id":175434545,"id":233910849,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMzkxMDg0OQ==","diff_hunk":"@@ -1,20 +1,49 @@\n+function hashCode(str) {\n+  // this is an implementation of java's hashcode method\n+  // https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript\n+  let hash = 0\n+  let chr\n+  if (str.length === 0) return hash;\n+  for (let i = 0; i < str.length; i++) {\n+    chr = str.charCodeAt(i);\n+    hash = ((hash << 5) - hash) + chr // eslint-disable-line\n+    hash |= 0 // eslint-disable-line\n+  }\n+  return hash.toString()\n+}\n+\n export function jsmdParser(fullJsmd) {\n   const jsmdLines = fullJsmd.split('\\n')\n   const chunks = []\n   let currentChunkLines = []\n   let currentEvalType = ''\n   let evalFlags = []\n   let currentChunkStartLine = 0\n+  let chunkContent = ''\n+\n+  const newChunkId = (str) => {\n+    const hash = hashCode(str)\n+    let hashNum = '0'\n+    for (const chunk of chunks) {\n+      const [prevHash, prevHashNum] = chunk.chunkId.split('_')\n+      if (hash === prevHash) {\n+        hashNum = (parseInt(prevHashNum, 10) + 1).toString()\n+      }\n+    }\n+    return `${hash}_${hashNum}`\n+  }\n \n   for (const [i, line] of jsmdLines.entries()) {\n     if (line.slice(0, 2) === '%%') {\n       // if there is any match, a new chunk has started\n       // push the current chunk (unless it's on line 0), then reset\n       if (i !== 0) {\n         // DON'T push a chunk if we're only on line 0\n+        chunkContent = currentChunkLines.join('\\n')","path":"src/actions/jsmd-parser.js","position":42,"original_position":42,"commit_id":"7593adcdd0d671c102878556561766fcf233ecd8","original_commit_id":"7593adcdd0d671c102878556561766fcf233ecd8","user":{"login":"wlach","id":20569,"node_id":"MDQ6VXNlcjIwNTY5","avatar_url":"https://avatars3.githubusercontent.com/u/20569?v=4","gravatar_id":"","url":"https://api.github.com/users/wlach","html_url":"https://github.com/wlach","followers_url":"https://api.github.com/users/wlach/followers","following_url":"https://api.github.com/users/wlach/following{/other_user}","gists_url":"https://api.github.com/users/wlach/gists{/gist_id}","starred_url":"https://api.github.com/users/wlach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wlach/subscriptions","organizations_url":"https://api.github.com/users/wlach/orgs","repos_url":"https://api.github.com/users/wlach/repos","events_url":"https://api.github.com/users/wlach/events{/privacy}","received_events_url":"https://api.github.com/users/wlach/received_events","type":"User","site_admin":false},"body":"I think it would be better to declare the chunkContent as `const` here, instead of up around line 22.","created_at":"2018-11-15T16:18:45Z","updated_at":"2018-11-15T16:30:15Z","html_url":"https://github.com/iodide-project/iodide/pull/1179#discussion_r233910849","pull_request_url":"https://api.github.com/repos/iodide-project/iodide/pulls/1179","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/comments/233910849"},"html":{"href":"https://github.com/iodide-project/iodide/pull/1179#discussion_r233910849"},"pull_request":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/1179"}}},"pull_request":{"url":"https://api.github.com/repos/iodide-project/iodide/pulls/1179","id":231024077,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMxMDI0MDc3","html_url":"https://github.com/iodide-project/iodide/pull/1179","diff_url":"https://github.com/iodide-project/iodide/pull/1179.diff","patch_url":"https://github.com/iodide-project/iodide/pull/1179.patch","issue_url":"https://api.github.com/repos/iodide-project/iodide/issues/1179","number":1179,"state":"open","locked":false,"title":"makes the css cell work again, and lays groundwork for #1174","user":{"login":"bcolloran","id":2380975,"node_id":"MDQ6VXNlcjIzODA5NzU=","avatar_url":"https://avatars2.githubusercontent.com/u/2380975?v=4","gravatar_id":"","url":"https://api.github.com/users/bcolloran","html_url":"https://github.com/bcolloran","followers_url":"https://api.github.com/users/bcolloran/followers","following_url":"https://api.github.com/users/bcolloran/following{/other_user}","gists_url":"https://api.github.com/users/bcolloran/gists{/gist_id}","starred_url":"https://api.github.com/users/bcolloran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcolloran/subscriptions","organizations_url":"https://api.github.com/users/bcolloran/orgs","repos_url":"https://api.github.com/users/bcolloran/repos","events_url":"https://api.github.com/users/bcolloran/events{/privacy}","received_events_url":"https://api.github.com/users/bcolloran/received_events","type":"User","site_admin":false},"body":"fixes #1158.\r\n\r\nthe stuff here with the chunkId based on a hash of the content will be useful for #1174. also, by making sure that each chunk to be rendered in the report has a (mostly) stable ID based on the hash of its contents, i think we can avoid some re-renders in react","created_at":"2018-11-15T00:00:26Z","updated_at":"2018-11-15T16:30:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"981fec6bb009605eb095f8d9a07bbe3d065f6c87","assignee":null,"assignees":[],"requested_reviewers":[{"login":"hamilton","id":95735,"node_id":"MDQ6VXNlcjk1NzM1","avatar_url":"https://avatars1.githubusercontent.com/u/95735?v=4","gravatar_id":"","url":"https://api.github.com/users/hamilton","html_url":"https://github.com/hamilton","followers_url":"https://api.github.com/users/hamilton/followers","following_url":"https://api.github.com/users/hamilton/following{/other_user}","gists_url":"https://api.github.com/users/hamilton/gists{/gist_id}","starred_url":"https://api.github.com/users/hamilton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hamilton/subscriptions","organizations_url":"https://api.github.com/users/hamilton/orgs","repos_url":"https://api.github.com/users/hamilton/repos","events_url":"https://api.github.com/users/hamilton/events{/privacy}","received_events_url":"https://api.github.com/users/hamilton/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/iodide-project/iodide/pulls/1179/commits","review_comments_url":"https://api.github.com/repos/iodide-project/iodide/pulls/1179/comments","review_comment_url":"https://api.github.com/repos/iodide-project/iodide/pulls/comments{/number}","comments_url":"https://api.github.com/repos/iodide-project/iodide/issues/1179/comments","statuses_url":"https://api.github.com/repos/iodide-project/iodide/statuses/7593adcdd0d671c102878556561766fcf233ecd8","head":{"label":"iodide-project:jsmd-css-cells","ref":"jsmd-css-cells","sha":"7593adcdd0d671c102878556561766fcf233ecd8","user":{"login":"iodide-project","id":36210752,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2MjEwNzUy","avatar_url":"https://avatars0.githubusercontent.com/u/36210752?v=4","gravatar_id":"","url":"https://api.github.com/users/iodide-project","html_url":"https://github.com/iodide-project","followers_url":"https://api.github.com/users/iodide-project/followers","following_url":"https://api.github.com/users/iodide-project/following{/other_user}","gists_url":"https://api.github.com/users/iodide-project/gists{/gist_id}","starred_url":"https://api.github.com/users/iodide-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iodide-project/subscriptions","organizations_url":"https://api.github.com/users/iodide-project/orgs","repos_url":"https://api.github.com/users/iodide-project/repos","events_url":"https://api.github.com/users/iodide-project/events{/privacy}","received_events_url":"https://api.github.com/users/iodide-project/received_events","type":"Organization","site_admin":false},"repo":{"id":99938998,"node_id":"MDEwOlJlcG9zaXRvcnk5OTkzODk5OA==","name":"iodide","full_name":"iodide-project/iodide","private":false,"owner":{"login":"iodide-project","id":36210752,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2MjEwNzUy","avatar_url":"https://avatars0.githubusercontent.com/u/36210752?v=4","gravatar_id":"","url":"https://api.github.com/users/iodide-project","html_url":"https://github.com/iodide-project","followers_url":"https://api.github.com/users/iodide-project/followers","following_url":"https://api.github.com/users/iodide-project/following{/other_user}","gists_url":"https://api.github.com/users/iodide-project/gists{/gist_id}","starred_url":"https://api.github.com/users/iodide-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iodide-project/subscriptions","organizations_url":"https://api.github.com/users/iodide-project/orgs","repos_url":"https://api.github.com/users/iodide-project/repos","events_url":"https://api.github.com/users/iodide-project/events{/privacy}","received_events_url":"https://api.github.com/users/iodide-project/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/iodide-project/iodide","description":"A frictionlessly portable interface for literate scientific computing in the browser","fork":false,"url":"https://api.github.com/repos/iodide-project/iodide","forks_url":"https://api.github.com/repos/iodide-project/iodide/forks","keys_url":"https://api.github.com/repos/iodide-project/iodide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/iodide-project/iodide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/iodide-project/iodide/teams","hooks_url":"https://api.github.com/repos/iodide-project/iodide/hooks","issue_events_url":"https://api.github.com/repos/iodide-project/iodide/issues/events{/number}","events_url":"https://api.github.com/repos/iodide-project/iodide/events","assignees_url":"https://api.github.com/repos/iodide-project/iodide/assignees{/user}","branches_url":"https://api.github.com/repos/iodide-project/iodide/branches{/branch}","tags_url":"https://api.github.com/repos/iodide-project/iodide/tags","blobs_url":"https://api.github.com/repos/iodide-project/iodide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/iodide-project/iodide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/iodide-project/iodide/git/refs{/sha}","trees_url":"https://api.github.com/repos/iodide-project/iodide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/iodide-project/iodide/statuses/{sha}","languages_url":"https://api.github.com/repos/iodide-project/iodide/languages","stargazers_url":"https://api.github.com/repos/iodide-project/iodide/stargazers","contributors_url":"https://api.github.com/repos/iodide-project/iodide/contributors","subscribers_url":"https://api.github.com/repos/iodide-project/iodide/subscribers","subscription_url":"https://api.github.com/repos/iodide-project/iodide/subscription","commits_url":"https://api.github.com/repos/iodide-project/iodide/commits{/sha}","git_commits_url":"https://api.github.com/repos/iodide-project/iodide/git/commits{/sha}","comments_url":"https://api.github.com/repos/iodide-project/iodide/comments{/number}","issue_comment_url":"https://api.github.com/repos/iodide-project/iodide/issues/comments{/number}","contents_url":"https://api.github.com/repos/iodide-project/iodide/contents/{+path}","compare_url":"https://api.github.com/repos/iodide-project/iodide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/iodide-project/iodide/merges","archive_url":"https://api.github.com/repos/iodide-project/iodide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/iodide-project/iodide/downloads","issues_url":"https://api.github.com/repos/iodide-project/iodide/issues{/number}","pulls_url":"https://api.github.com/repos/iodide-project/iodide/pulls{/number}","milestones_url":"https://api.github.com/repos/iodide-project/iodide/milestones{/number}","notifications_url":"https://api.github.com/repos/iodide-project/iodide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/iodide-project/iodide/labels{/name}","releases_url":"https://api.github.com/repos/iodide-project/iodide/releases{/id}","deployments_url":"https://api.github.com/repos/iodide-project/iodide/deployments","created_at":"2017-08-10T15:38:35Z","updated_at":"2018-11-15T12:51:00Z","pushed_at":"2018-11-15T02:49:44Z","git_url":"git://github.com/iodide-project/iodide.git","ssh_url":"git@github.com:iodide-project/iodide.git","clone_url":"https://github.com/iodide-project/iodide.git","svn_url":"https://github.com/iodide-project/iodide","homepage":"","size":18974,"stargazers_count":279,"watchers_count":279,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":44,"mirror_url":null,"archived":false,"open_issues_count":156,"license":{"key":"mpl-2.0","name":"Mozilla Public License 2.0","spdx_id":"MPL-2.0","url":"https://api.github.com/licenses/mpl-2.0","node_id":"MDc6TGljZW5zZTE0"},"forks":44,"open_issues":156,"watchers":279,"default_branch":"master"}},"base":{"label":"iodide-project:direct-jsmd-editing","ref":"direct-jsmd-editing","sha":"caf5f6dca35dc266c6fe27be1897c5e94ec03d24","user":{"login":"iodide-project","id":36210752,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2MjEwNzUy","avatar_url":"https://avatars0.githubusercontent.com/u/36210752?v=4","gravatar_id":"","url":"https://api.github.com/users/iodide-project","html_url":"https://github.com/iodide-project","followers_url":"https://api.github.com/users/iodide-project/followers","following_url":"https://api.github.com/users/iodide-project/following{/other_user}","gists_url":"https://api.github.com/users/iodide-project/gists{/gist_id}","starred_url":"https://api.github.com/users/iodide-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iodide-project/subscriptions","organizations_url":"https://api.github.com/users/iodide-project/orgs","repos_url":"https://api.github.com/users/iodide-project/repos","events_url":"https://api.github.com/users/iodide-project/events{/privacy}","received_events_url":"https://api.github.com/users/iodide-project/received_events","type":"Organization","site_admin":false},"repo":{"id":99938998,"node_id":"MDEwOlJlcG9zaXRvcnk5OTkzODk5OA==","name":"iodide","full_name":"iodide-project/iodide","private":false,"owner":{"login":"iodide-project","id":36210752,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2MjEwNzUy","avatar_url":"https://avatars0.githubusercontent.com/u/36210752?v=4","gravatar_id":"","url":"https://api.github.com/users/iodide-project","html_url":"https://github.com/iodide-project","followers_url":"https://api.github.com/users/iodide-project/followers","following_url":"https://api.github.com/users/iodide-project/following{/other_user}","gists_url":"https://api.github.com/users/iodide-project/gists{/gist_id}","starred_url":"https://api.github.com/users/iodide-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iodide-project/subscriptions","organizations_url":"https://api.github.com/users/iodide-project/orgs","repos_url":"https://api.github.com/users/iodide-project/repos","events_url":"https://api.github.com/users/iodide-project/events{/privacy}","received_events_url":"https://api.github.com/users/iodide-project/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/iodide-project/iodide","description":"A frictionlessly portable interface for literate scientific computing in the browser","fork":false,"url":"https://api.github.com/repos/iodide-project/iodide","forks_url":"https://api.github.com/repos/iodide-project/iodide/forks","keys_url":"https://api.github.com/repos/iodide-project/iodide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/iodide-project/iodide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/iodide-project/iodide/teams","hooks_url":"https://api.github.com/repos/iodide-project/iodide/hooks","issue_events_url":"https://api.github.com/repos/iodide-project/iodide/issues/events{/number}","events_url":"https://api.github.com/repos/iodide-project/iodide/events","assignees_url":"https://api.github.com/repos/iodide-project/iodide/assignees{/user}","branches_url":"https://api.github.com/repos/iodide-project/iodide/branches{/branch}","tags_url":"https://api.github.com/repos/iodide-project/iodide/tags","blobs_url":"https://api.github.com/repos/iodide-project/iodide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/iodide-project/iodide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/iodide-project/iodide/git/refs{/sha}","trees_url":"https://api.github.com/repos/iodide-project/iodide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/iodide-project/iodide/statuses/{sha}","languages_url":"https://api.github.com/repos/iodide-project/iodide/languages","stargazers_url":"https://api.github.com/repos/iodide-project/iodide/stargazers","contributors_url":"https://api.github.com/repos/iodide-project/iodide/contributors","subscribers_url":"https://api.github.com/repos/iodide-project/iodide/subscribers","subscription_url":"https://api.github.com/repos/iodide-project/iodide/subscription","commits_url":"https://api.github.com/repos/iodide-project/iodide/commits{/sha}","git_commits_url":"https://api.github.com/repos/iodide-project/iodide/git/commits{/sha}","comments_url":"https://api.github.com/repos/iodide-project/iodide/comments{/number}","issue_comment_url":"https://api.github.com/repos/iodide-project/iodide/issues/comments{/number}","contents_url":"https://api.github.com/repos/iodide-project/iodide/contents/{+path}","compare_url":"https://api.github.com/repos/iodide-project/iodide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/iodide-project/iodide/merges","archive_url":"https://api.github.com/repos/iodide-project/iodide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/iodide-project/iodide/downloads","issues_url":"https://api.github.com/repos/iodide-project/iodide/issues{/number}","pulls_url":"https://api.github.com/repos/iodide-project/iodide/pulls{/number}","milestones_url":"https://api.github.com/repos/iodide-project/iodide/milestones{/number}","notifications_url":"https://api.github.com/repos/iodide-project/iodide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/iodide-project/iodide/labels{/name}","releases_url":"https://api.github.com/repos/iodide-project/iodide/releases{/id}","deployments_url":"https://api.github.com/repos/iodide-project/iodide/deployments","created_at":"2017-08-10T15:38:35Z","updated_at":"2018-11-15T12:51:00Z","pushed_at":"2018-11-15T02:49:44Z","git_url":"git://github.com/iodide-project/iodide.git","ssh_url":"git@github.com:iodide-project/iodide.git","clone_url":"https://github.com/iodide-project/iodide.git","svn_url":"https://github.com/iodide-project/iodide","homepage":"","size":18974,"stargazers_count":279,"watchers_count":279,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":44,"mirror_url":null,"archived":false,"open_issues_count":156,"license":{"key":"mpl-2.0","name":"Mozilla Public License 2.0","spdx_id":"MPL-2.0","url":"https://api.github.com/licenses/mpl-2.0","node_id":"MDc6TGljZW5zZTE0"},"forks":44,"open_issues":156,"watchers":279,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/1179"},"html":{"href":"https://github.com/iodide-project/iodide/pull/1179"},"issue":{"href":"https://api.github.com/repos/iodide-project/iodide/issues/1179"},"comments":{"href":"https://api.github.com/repos/iodide-project/iodide/issues/1179/comments"},"review_comments":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/1179/comments"},"review_comment":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/iodide-project/iodide/pulls/1179/commits"},"statuses":{"href":"https://api.github.com/repos/iodide-project/iodide/statuses/7593adcdd0d671c102878556561766fcf233ecd8"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"wlach"}}