{"action":"created","comment":{"url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/comments/124632381","pull_request_review_id":46868781,"id":124632381,"diff_hunk":"@@ -0,0 +1,700 @@\n+/**\n+ * data_service_client.js\n+ *\n+ * This file is distributed under the MIT License. See LICENSE for details.\n+ *\n+ * AUTHORS: Artiom Baloian <artiom.baloian@nyu.edu>\n+ *\n+ * Description:\n+ * File provides functions in order to create Client object and establish\n+ * communications between Client - Content Provider (CP) and Client - Caches.\n+ * (Send a content request, generate ticket bundle, send a ticket lottery)\n+ *\n+ */\n+\n+\n+/**\n+ * Client requests data from Content Provider (CP).\n+ * Actually, client requests data from CP, but CP instead of response\n+ * requested data it generates/processes tickets bundle, which Client needs\n+ * in order to request and get real data from Caches.\n+ *\n+ * Function consist of three parts:\n+ * 1. Create client object, for more details please have a look at\n+ *    ClientData constructor in \"client_data.js\" file.\n+ * 2. Request data from Content Provider (CP) which responds with a ticket\n+ *    bundle.\n+ * 3. Request data from Caches by passing ticket bundle which is generated\n+ *    by Content Provider.\n+ */\n+function RequestFromContentProvider() {\n+  /**\n+   * Create and initialize the main object of client. It contains all necessary\n+   * information in order to make request from content provider.\n+   */\n+  var client = new ClientData();\n+\n+  var request_content_trials = 1;\n+  var request_content_succeeded = false;\n+\n+  /**\n+   * Sequence number for the request, increases by one for each request.\n+   * This is going to be ContentRequest object's request_sequence value.\n+   */\n+  var request_sequence = 0;\n+\n+  /**\n+   * Currently CONTENT_REQUEST_TRIALS constant value is 3, which means that\n+   * client can try to connect (if it fails) to CP no more than three times.\n+   */\n+  while (request_content_trials <= CONTENT_REQUEST_TRIALS) {\n+    request_sequence++;\n+\n+    // Send content request to CP over HTTPS connection.\n+    const error_msg = SendRequest(client, request_sequence,\n+        function(tkts_bundle) {\n+          /**\n+           * Now the client will start communication with the selected set of\n+           * caches to retrieve the data blocks.\n+           *\n+           * Establish a connection with caches and request content,\n+           * compute hash encryption puzzle and generate ticket lottery two.\n+           */\n+           RequestFromCaches(client, tkts_bundle);\n+        });\n+\n+    if (error_msg != 0) {\n+      CacheCashError(CONTENT_REQUEST_ERROR,\n+                     \"Sending content request message failed\");\n+       return;\n+    } else {\n+      request_content_succeeded = true;\n+      break;\n+    }\n+  }\n+\n+  /**\n+   * Max number of trials reached while the client is not able to get valid\n+   * tickets bundles for his content request.\n+   */\n+  if (request_content_succeeded != true) {\n+    CacheCashError(CONTENT_REQUEST_TRIALS_EXCEEDED_ERROR,\n+                   \"Max number of trials reached\");\n+  }\n+}\n+\n+\n+\n+/**\n+ * Send client's content request message to the Content Provider via\n+ * HTTP connection. As a response CP sends tickets bundle.\n+ * Function also verifies the batch signature over the received tickets bundle.\n+ *\n+ * Arguments:\n+ * - client: It contains all information, which used to make a content request.\n+ * - request_sequence: Sequence number for the request.\n+ * - callback: Callback function runs RequestFromCaches() function.\n+ *\n+ * Returns error code.\n+ */\n+function SendRequest(client, request_sequence, callback) {\n+\n+  console.log(\"Sending content request message started...\");\n+\n+  // Tickets bundle sent by the CP as a response to the content request.\n+  var tkts_bundle = new TicketsBundle();\n+\n+  var content_request = new ContentRequest(client, request_sequence);\n+\n+  const json_cr = content_request.SerializeToJSON();\n+  const server_url = 'http://' + (client.cp_url + \"/content_request\");\n+\n+  var request = new XMLHttpRequest();\n+  if (request) {\n+    request.open('POST', server_url, true);\n+    request.setRequestHeader('Content-Type', 'text/plain');\n+    request.send(json_cr);\n+    request.onreadystatechange =\n+      function () {\n+        if (request.readyState === XMLHttpRequest.DONE &&\n+            request.status === 200) {\n+          const json_tkts_bundle = JSON.parse(request.responseText);\n+          if (json_tkts_bundle === undefined) {\n+            CacheCashError(TICKETS_BUNDLE_MSG_ERROR, \"undefined tickets bundle\");\n+          }\n+          const tktr_type = json_tkts_bundle[\"type\"];\n+          if (tktr_type != MessageType.TICKETS_BUNDLE) {\n+            CacheCashError(CACEHCASH_INVALID_MSG_TYPE_ERROR,\n+                           \"Invalid type of tickets bundle message\");\n+\n+          }\n+\n+          tkts_bundle.DeserializeFromJSON(json_tkts_bundle);\n+\n+          // Initialize Client's CP public key.\n+          CopyPublicKey(client.cp_public_key, tkts_bundle.tktrs[0].cp_pubkey);\n+\n+          const error_msg = VerifyBatchSignature(tkts_bundle, client.cp_public_key);\n+          if (error_msg != 0) {\n+            CacheCashError(BATCH_SIG_VER_ERROR, \"Verifying batch signature failed\");\n+            return error_msg;\n+          }\n+          console.log(\"Tickets bundle message has been processed...\\n\");\n+\n+          /**\n+           * If callback exist execute it.\n+           * This callback is RequestFromCaches() function.\n+           */\n+          if (callback)\n+            callback(tkts_bundle);\n+          } else {\n+            CacheCashError(REQUEST_HANDLE_ERROR, \"Request handle error\");\n+          }\n+      };\n+  }\n+\n+  return 0;\n+}\n+\n+\n+\n+/**\n+ * TODO function needs to be redesigned later.\n+ * Request data from Caches.\n+ *\n+ * Description:\n+ * Function establishes a connection with caches and request content,\n+ * computes hash encryption puzzle and generates ticket lottery two.\n+ * Function creates a new socket for each connection.\n+ *\n+ * We use thread for handling data block request. It consists of two parts,\n+ * before and after computing the hash encryption puzzle.\n+ *\n+ * Arguments:\n+ * - client: ClientData.\n+ * - tkts_bundle: TicketsBundle received from CP.\n+ */\n+function RequestFromCaches(client, tkts_bundle) {\n+\n+  /**\n+   * The structure that will hold the retrieved data blocks.\n+   */\n+  var data_blocks = new Array(client.blocks);\n+  for (var i = 0; i < client.blocks; i++) {\n+    data_blocks[i] = new DataBlock();\n+    data_blocks[i].block_index = client.blocks_indices[i];\n+  }\n+\n+  /**\n+   * The needed arguments to be passed for each service session at the\n+   * client's side. It is going to contain almost all needed data by client\n+   * in order to make a content request from Caches.\n+   */\n+  var data_block_request = new Array(client.blocks);\n+  for (var i = 0; i < client.blocks; i++) {\n+    data_block_request[i] =\n+                new ClientDatablockRequest(client, tkts_bundle, data_blocks, i);\n+  }\n+\n+  /**\n+   * Handle data block request responded by cache.\n+   *\n+   * eachSeries() function signature.\n+   * eachSeries(coll, iteratee, callback(opt))\n+   * - coll: A collection to iterate over.\n+   * - iteratee: An async function to apply to each item in coll.\n+   * - callbackopt: A callback which is called when all iteratee functions have\n+   *                finished.\n+   */\n+  cc_lib.async.eachSeries(data_block_request,\n+     // The second argument of eachSeries() function.\n+     function(item, next_it) {\n+       HandleDataBlockResponsePartOne(item,\n+                                      function() {\n+                                        next_it();\n+                                      });\n+     },\n+     // Third argument of eachSeries() function.\n+     function() {","path":"javascript_client/data_service_client.js","position":218,"original_position":218,"commit_id":"428d696f64da7bd460db976dd890a13bbaa1be10","original_commit_id":"428d696f64da7bd460db976dd890a13bbaa1be10","user":{"login":"lukpueh","id":589324,"avatar_url":"https://avatars1.githubusercontent.com/u/589324?v=3","gravatar_id":"","url":"https://api.github.com/users/lukpueh","html_url":"https://github.com/lukpueh","followers_url":"https://api.github.com/users/lukpueh/followers","following_url":"https://api.github.com/users/lukpueh/following{/other_user}","gists_url":"https://api.github.com/users/lukpueh/gists{/gist_id}","starred_url":"https://api.github.com/users/lukpueh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukpueh/subscriptions","organizations_url":"https://api.github.com/users/lukpueh/orgs","repos_url":"https://api.github.com/users/lukpueh/repos","events_url":"https://api.github.com/users/lukpueh/events{/privacy}","received_events_url":"https://api.github.com/users/lukpueh/received_events","type":"User","site_admin":false},"body":"For instance, there are scenarios in your code where your callbacks (of callbacks of callbacks) return before calling `next_it()`.\r\nIf I understand `async` correctly, this would have as a consequence that this function here (third argument of `eachSeries()` is never called. Correct me if I'm wrong.","created_at":"2017-06-28T19:21:30Z","updated_at":"2017-06-28T19:56:16Z","html_url":"https://github.com/Cache-Cash/CacheCash/pull/96#discussion_r124632381","pull_request_url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96","_links":{"self":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/comments/124632381"},"html":{"href":"https://github.com/Cache-Cash/CacheCash/pull/96#discussion_r124632381"},"pull_request":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96"}}},"pull_request":{"url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96","id":122686198,"html_url":"https://github.com/Cache-Cash/CacheCash/pull/96","diff_url":"https://github.com/Cache-Cash/CacheCash/pull/96.diff","patch_url":"https://github.com/Cache-Cash/CacheCash/pull/96.patch","issue_url":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/96","number":96,"state":"open","locked":false,"title":"Move JS code into the browser environment (this is for review)","user":{"login":"baloyan","id":17729542,"avatar_url":"https://avatars2.githubusercontent.com/u/17729542?v=3","gravatar_id":"","url":"https://api.github.com/users/baloyan","html_url":"https://github.com/baloyan","followers_url":"https://api.github.com/users/baloyan/followers","following_url":"https://api.github.com/users/baloyan/following{/other_user}","gists_url":"https://api.github.com/users/baloyan/gists{/gist_id}","starred_url":"https://api.github.com/users/baloyan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baloyan/subscriptions","organizations_url":"https://api.github.com/users/baloyan/orgs","repos_url":"https://api.github.com/users/baloyan/repos","events_url":"https://api.github.com/users/baloyan/events{/privacy}","received_events_url":"https://api.github.com/users/baloyan/received_events","type":"User","site_admin":false},"body":"File provides error status of various functionalities used in CacheCash\r\n- [x] cachecash_error.js\r\n\r\nIncludes all the objects needed by the Client. Also file provides functions, which initialize these objects.\r\n- [x] client_data.js\r\n\r\nAn instance of the client requests content from a content provider, but instead of serving the content directly, the content provider returns a ticket bundle, which the client uses to retrieve the content from multiple caches.\r\n- [x] client.js\r\n\r\nA file provides CacheCash project's constant values.\r\n- [x] constants.js\r\n\r\nIncludes all the crypto related functions needed in CacheCash.\r\n- [x] crypto.js\r\n\r\nFile provides functions in order to create Client object and establish communications between Client - Content Provider (CP) and Client - Caches. (Send a content request, generate ticket bundle, send a ticket lottery)\r\n- [ ] data_service_client.js\r\n\r\nFile provides CacheCash's message types.\r\n- [ ] message_types.js\r\n\r\nFile provides data structures, which are needed by Client in order to make a requests from Content Provider and Caches.\r\n- [ ] objects.js\r\n\r\nIncludes all the utility functions that are used by several modules and not falling under specific module to place them there.\r\n- [ ] utils.js\r\n\r\nFile provides all the crypto related verification functions.\r\n- [ ] verify.js\r\n\r\nFile provides a dictionary, which  contains an initial input data of client.\r\n- [ ] input.js\r\n\r\nFile provides CacheCach project's Javascript requirement libraries.\r\n- [x] requirements.js\r\n\r\nAdded package.json file.\r\n- [x] package.json\r\n\r\nAlso added Access-Control-Allow-Origin: * response in C++ side and change TicketsBundle response part.\r\n\r\n`client.js` does not exist anymore, it was removed, based on PR review comment related modification.","created_at":"2017-05-26T17:23:49Z","updated_at":"2017-06-28T19:56:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"64ace9f8109740e4a7f90d2593a2e9b119a3a66f","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96/commits","review_comments_url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96/comments","review_comment_url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/96/comments","statuses_url":"https://api.github.com/repos/Cache-Cash/CacheCash/statuses/428d696f64da7bd460db976dd890a13bbaa1be10","head":{"label":"baloyan:browser_environment_client","ref":"browser_environment_client","sha":"428d696f64da7bd460db976dd890a13bbaa1be10","user":{"login":"baloyan","id":17729542,"avatar_url":"https://avatars2.githubusercontent.com/u/17729542?v=3","gravatar_id":"","url":"https://api.github.com/users/baloyan","html_url":"https://github.com/baloyan","followers_url":"https://api.github.com/users/baloyan/followers","following_url":"https://api.github.com/users/baloyan/following{/other_user}","gists_url":"https://api.github.com/users/baloyan/gists{/gist_id}","starred_url":"https://api.github.com/users/baloyan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baloyan/subscriptions","organizations_url":"https://api.github.com/users/baloyan/orgs","repos_url":"https://api.github.com/users/baloyan/repos","events_url":"https://api.github.com/users/baloyan/events{/privacy}","received_events_url":"https://api.github.com/users/baloyan/received_events","type":"User","site_admin":false},"repo":{"id":86866275,"name":"CacheCash","full_name":"baloyan/CacheCash","owner":{"login":"baloyan","id":17729542,"avatar_url":"https://avatars2.githubusercontent.com/u/17729542?v=3","gravatar_id":"","url":"https://api.github.com/users/baloyan","html_url":"https://github.com/baloyan","followers_url":"https://api.github.com/users/baloyan/followers","following_url":"https://api.github.com/users/baloyan/following{/other_user}","gists_url":"https://api.github.com/users/baloyan/gists{/gist_id}","starred_url":"https://api.github.com/users/baloyan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baloyan/subscriptions","organizations_url":"https://api.github.com/users/baloyan/orgs","repos_url":"https://api.github.com/users/baloyan/repos","events_url":"https://api.github.com/users/baloyan/events{/privacy}","received_events_url":"https://api.github.com/users/baloyan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/baloyan/CacheCash","description":null,"fork":true,"url":"https://api.github.com/repos/baloyan/CacheCash","forks_url":"https://api.github.com/repos/baloyan/CacheCash/forks","keys_url":"https://api.github.com/repos/baloyan/CacheCash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/baloyan/CacheCash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/baloyan/CacheCash/teams","hooks_url":"https://api.github.com/repos/baloyan/CacheCash/hooks","issue_events_url":"https://api.github.com/repos/baloyan/CacheCash/issues/events{/number}","events_url":"https://api.github.com/repos/baloyan/CacheCash/events","assignees_url":"https://api.github.com/repos/baloyan/CacheCash/assignees{/user}","branches_url":"https://api.github.com/repos/baloyan/CacheCash/branches{/branch}","tags_url":"https://api.github.com/repos/baloyan/CacheCash/tags","blobs_url":"https://api.github.com/repos/baloyan/CacheCash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/baloyan/CacheCash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/baloyan/CacheCash/git/refs{/sha}","trees_url":"https://api.github.com/repos/baloyan/CacheCash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/baloyan/CacheCash/statuses/{sha}","languages_url":"https://api.github.com/repos/baloyan/CacheCash/languages","stargazers_url":"https://api.github.com/repos/baloyan/CacheCash/stargazers","contributors_url":"https://api.github.com/repos/baloyan/CacheCash/contributors","subscribers_url":"https://api.github.com/repos/baloyan/CacheCash/subscribers","subscription_url":"https://api.github.com/repos/baloyan/CacheCash/subscription","commits_url":"https://api.github.com/repos/baloyan/CacheCash/commits{/sha}","git_commits_url":"https://api.github.com/repos/baloyan/CacheCash/git/commits{/sha}","comments_url":"https://api.github.com/repos/baloyan/CacheCash/comments{/number}","issue_comment_url":"https://api.github.com/repos/baloyan/CacheCash/issues/comments{/number}","contents_url":"https://api.github.com/repos/baloyan/CacheCash/contents/{+path}","compare_url":"https://api.github.com/repos/baloyan/CacheCash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/baloyan/CacheCash/merges","archive_url":"https://api.github.com/repos/baloyan/CacheCash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/baloyan/CacheCash/downloads","issues_url":"https://api.github.com/repos/baloyan/CacheCash/issues{/number}","pulls_url":"https://api.github.com/repos/baloyan/CacheCash/pulls{/number}","milestones_url":"https://api.github.com/repos/baloyan/CacheCash/milestones{/number}","notifications_url":"https://api.github.com/repos/baloyan/CacheCash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/baloyan/CacheCash/labels{/name}","releases_url":"https://api.github.com/repos/baloyan/CacheCash/releases{/id}","deployments_url":"https://api.github.com/repos/baloyan/CacheCash/deployments","created_at":"2017-03-31T22:52:47Z","updated_at":"2017-03-31T22:52:49Z","pushed_at":"2017-06-28T19:29:49Z","git_url":"git://github.com/baloyan/CacheCash.git","ssh_url":"git@github.com:baloyan/CacheCash.git","clone_url":"https://github.com/baloyan/CacheCash.git","svn_url":"https://github.com/baloyan/CacheCash","homepage":null,"size":2904,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Cache-Cash:test_1","ref":"test_1","sha":"702659cce02546eba2ee3c2444a15bd5ecb30b2d","user":{"login":"Cache-Cash","id":28986978,"avatar_url":"https://avatars2.githubusercontent.com/u/28986978?v=3","gravatar_id":"","url":"https://api.github.com/users/Cache-Cash","html_url":"https://github.com/Cache-Cash","followers_url":"https://api.github.com/users/Cache-Cash/followers","following_url":"https://api.github.com/users/Cache-Cash/following{/other_user}","gists_url":"https://api.github.com/users/Cache-Cash/gists{/gist_id}","starred_url":"https://api.github.com/users/Cache-Cash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cache-Cash/subscriptions","organizations_url":"https://api.github.com/users/Cache-Cash/orgs","repos_url":"https://api.github.com/users/Cache-Cash/repos","events_url":"https://api.github.com/users/Cache-Cash/events{/privacy}","received_events_url":"https://api.github.com/users/Cache-Cash/received_events","type":"Organization","site_admin":false},"repo":{"id":52488620,"name":"CacheCash","full_name":"Cache-Cash/CacheCash","owner":{"login":"Cache-Cash","id":28986978,"avatar_url":"https://avatars2.githubusercontent.com/u/28986978?v=3","gravatar_id":"","url":"https://api.github.com/users/Cache-Cash","html_url":"https://github.com/Cache-Cash","followers_url":"https://api.github.com/users/Cache-Cash/followers","following_url":"https://api.github.com/users/Cache-Cash/following{/other_user}","gists_url":"https://api.github.com/users/Cache-Cash/gists{/gist_id}","starred_url":"https://api.github.com/users/Cache-Cash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cache-Cash/subscriptions","organizations_url":"https://api.github.com/users/Cache-Cash/orgs","repos_url":"https://api.github.com/users/Cache-Cash/repos","events_url":"https://api.github.com/users/Cache-Cash/events{/privacy}","received_events_url":"https://api.github.com/users/Cache-Cash/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Cache-Cash/CacheCash","description":null,"fork":false,"url":"https://api.github.com/repos/Cache-Cash/CacheCash","forks_url":"https://api.github.com/repos/Cache-Cash/CacheCash/forks","keys_url":"https://api.github.com/repos/Cache-Cash/CacheCash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Cache-Cash/CacheCash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Cache-Cash/CacheCash/teams","hooks_url":"https://api.github.com/repos/Cache-Cash/CacheCash/hooks","issue_events_url":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/events{/number}","events_url":"https://api.github.com/repos/Cache-Cash/CacheCash/events","assignees_url":"https://api.github.com/repos/Cache-Cash/CacheCash/assignees{/user}","branches_url":"https://api.github.com/repos/Cache-Cash/CacheCash/branches{/branch}","tags_url":"https://api.github.com/repos/Cache-Cash/CacheCash/tags","blobs_url":"https://api.github.com/repos/Cache-Cash/CacheCash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Cache-Cash/CacheCash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Cache-Cash/CacheCash/git/refs{/sha}","trees_url":"https://api.github.com/repos/Cache-Cash/CacheCash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Cache-Cash/CacheCash/statuses/{sha}","languages_url":"https://api.github.com/repos/Cache-Cash/CacheCash/languages","stargazers_url":"https://api.github.com/repos/Cache-Cash/CacheCash/stargazers","contributors_url":"https://api.github.com/repos/Cache-Cash/CacheCash/contributors","subscribers_url":"https://api.github.com/repos/Cache-Cash/CacheCash/subscribers","subscription_url":"https://api.github.com/repos/Cache-Cash/CacheCash/subscription","commits_url":"https://api.github.com/repos/Cache-Cash/CacheCash/commits{/sha}","git_commits_url":"https://api.github.com/repos/Cache-Cash/CacheCash/git/commits{/sha}","comments_url":"https://api.github.com/repos/Cache-Cash/CacheCash/comments{/number}","issue_comment_url":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/comments{/number}","contents_url":"https://api.github.com/repos/Cache-Cash/CacheCash/contents/{+path}","compare_url":"https://api.github.com/repos/Cache-Cash/CacheCash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Cache-Cash/CacheCash/merges","archive_url":"https://api.github.com/repos/Cache-Cash/CacheCash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Cache-Cash/CacheCash/downloads","issues_url":"https://api.github.com/repos/Cache-Cash/CacheCash/issues{/number}","pulls_url":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls{/number}","milestones_url":"https://api.github.com/repos/Cache-Cash/CacheCash/milestones{/number}","notifications_url":"https://api.github.com/repos/Cache-Cash/CacheCash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Cache-Cash/CacheCash/labels{/name}","releases_url":"https://api.github.com/repos/Cache-Cash/CacheCash/releases{/id}","deployments_url":"https://api.github.com/repos/Cache-Cash/CacheCash/deployments","created_at":"2016-02-25T01:53:34Z","updated_at":"2017-05-31T01:11:24Z","pushed_at":"2017-06-28T15:44:19Z","git_url":"git://github.com/Cache-Cash/CacheCash.git","ssh_url":"git@github.com:Cache-Cash/CacheCash.git","clone_url":"https://github.com/Cache-Cash/CacheCash.git","svn_url":"https://github.com/Cache-Cash/CacheCash","homepage":null,"size":2958,"stargazers_count":1,"watchers_count":1,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":42,"forks":4,"open_issues":42,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96"},"html":{"href":"https://github.com/Cache-Cash/CacheCash/pull/96"},"issue":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/96"},"comments":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/issues/96/comments"},"review_comments":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96/comments"},"review_comment":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/pulls/96/commits"},"statuses":{"href":"https://api.github.com/repos/Cache-Cash/CacheCash/statuses/428d696f64da7bd460db976dd890a13bbaa1be10"}}}}
{"actor":{"display_login":"lukpueh"}}