{"action":"created","comment":{"url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/comments/35457593","id":35457593,"diff_hunk":"@@ -0,0 +1,177 @@\n+import logging = require('../logging/logging');\n+\n+var log :logging.Log = new logging.Log('fancy-transformers');\n+\n+var takeByte_ = (buffer:ArrayBuffer) : number => {\n+  var bytes=new Uint8Array(buffer);\n+  return bytes[0];\n+}\n+\n+var dropByte_ = (buffer:ArrayBuffer) : ArrayBuffer => {\n+  var bytes=new Uint8Array(buffer)\n+  var result = new Uint8Array(buffer.byteLength-1);\n+  var fromIndex : number = 1;\n+  var toIndex : number = 0;\n+  while(toIndex < result.length) {\n+    result[toIndex] = bytes[fromIndex];\n+    toIndex=toIndex+1;\n+    fromIndex=fromIndex+1;\n+  }\n+\n+  return result.buffer;\n+}\n+\n+var encodeByte_ = (num:number) : ArrayBuffer => {\n+  var bytes = new Uint8Array(1);\n+  bytes[0]=num;\n+  return bytes.buffer;\n+}\n+\n+var split_ = (buffer:ArrayBuffer, firstLen:number) : Array<ArrayBuffer> => {\n+  var bytes=new Uint8Array(buffer)\n+  var lastLen : number = buffer.byteLength-firstLen;\n+  var first = new Uint8Array(firstLen);\n+  var last = new Uint8Array(lastLen);\n+  var fromIndex : number = 0;\n+  var toIndex : number = 0;\n+  while(toIndex < first.length) {\n+    first[toIndex] = bytes[fromIndex];\n+    toIndex=toIndex+1;\n+    fromIndex=fromIndex+1;\n+  }\n+\n+  toIndex=0;\n+  while(toIndex < last.length) {\n+    last[toIndex] = bytes[fromIndex];\n+    toIndex=toIndex+1;\n+    fromIndex=fromIndex+1;\n+  }\n+\n+  return [first.buffer, last.buffer];\n+}\n+\n+/* Takes a two byte (network byte order) representation of a number and returns\n+ * the number.\n+ */\n+ // TODO(bwiley): Byte order may be backward\n+ // TODO(bwiley): Fix type error\n+var decodeLength_ = (buffer:ArrayBuffer) : number => {\n+  var bytes = new Uint8Array(buffer);\n+  var result = (bytes[0] << 8) | bytes[1];\n+  return result;\n+}\n+\n+\n+class Fragment {\n+  public length : number;\n+  public id : ArrayBuffer;\n+  public index : number;\n+  public count : number;\n+  public payload : ArrayBuffer;\n+  public padding : ArrayBuffer;\n+\n+  public constructor(length:number, id:ArrayBuffer, index:number, count:number, payload:ArrayBuffer, padding:ArrayBuffer) {\n+    this.length=length;\n+    this.id=id;\n+    this.index=index;\n+    this.count=count;\n+    this.payload=payload;\n+    this.padding=padding;\n+  }\n+\n+  static randomId = () : ArrayBuffer => {\n+    var bytes = new Uint8Array(32);\n+    for (var i = 0; i < bytes.byteLength; i++) {\n+      bytes[i] = Math.floor(Math.random()*255);\n+    }\n+    return bytes.buffer;\n+  }\n+\n+  static decodeFragment = (buffer:ArrayBuffer) : Fragment => {\n+//    log.debug('Decode fragment %1 %2', buffer.byteLength, length);\n+    var parts = split_(buffer, 2);\n+    var lengthBytes = parts[0];\n+    var length = decodeLength_(lengthBytes);\n+    buffer = parts[1];\n+\n+    parts=split_(buffer, 32);\n+    var fragmentId=parts[0];\n+    buffer=parts[1];\n+\n+    var fragmentNumber=takeByte_(buffer);\n+    buffer=dropByte_(buffer);\n+\n+    var totalNumber=takeByte_(buffer);\n+    buffer=dropByte_(buffer);\n+\n+//    log.debug('Decoded fragment %1 %2 %3', fragmentId, fragmentNumber, totalNumber);\n+\n+    var payload : ArrayBuffer=null;\n+    var padding : ArrayBuffer=null;\n+\n+    if(buffer.byteLength > length) {\n+      parts=split_(buffer, length);\n+      payload=parts[0];\n+      padding=parts[1];\n+//      log.debug('shortened payoad %1 %2 %3', buffer.byteLength, length, payload.byteLength);\n+    } else if (buffer.byteLength == length) {\n+      payload=buffer;\n+      padding=new ArrayBuffer(0);\n+//      log.debug('perect payoad %1 %2 %3', buffer.byteLength, length, payload.byteLength);\n+    } else { // buffer.byteLength < length\n+      throw new Error(\"Short buffer\");\n+    }\n+\n+    var fragment=new Fragment(length, fragmentId, fragmentNumber, totalNumber, payload, padding);\n+//    log.info(\"Decoding %1 %2 %3\", fragment.id, fragment.index, fragment.count);\n+    return fragment;\n+  }\n+\n+  public encodeFragment = () : ArrayBuffer => {\n+//    log.info(\"Encoding %1 %2 %3\", this.id, this.index, this.count);\n+    return this.assemble_([this.encodeLength_(this.length), this.id, encodeByte_(this.index), encodeByte_(this.count), this.payload, this.padding]);\n+  }\n+\n+  /* Takes a number and returns a two byte (network byte order) representation\n+   * of this number.\n+   */\n+   // TODO(bwiley): Byte order may be backward\n+  private encodeLength_ = (len:number) : ArrayBuffer => {\n+    var bytes = new Uint8Array(2);\n+    bytes[0] = Math.floor(len >> 8);\n+    bytes[1] = Math.floor((len << 8) >> 8);\n+    return bytes.buffer;\n+  }\n+\n+  private assemble_ = (buffers:ArrayBuffer[]) : ArrayBuffer => {\n+    var total=0;\n+    for(var i=0; i<buffers.length; i++) {\n+      total=total+buffers[i].byteLength;\n+    }\n+\n+    var result = new Uint8Array(total);\n+    var toIndex=0;\n+    for(var i=0; i<buffers.length; i++) {\n+      var bytes=new Uint8Array(buffers[i]);\n+      for(var fromIndex=0; fromIndex<buffers[i].byteLength; fromIndex++) {\n+        result[toIndex]=bytes[fromIndex];\n+        toIndex=toIndex+1;","path":"src/fancy-transformers/fragment.ts","position":158,"original_position":158,"commit_id":"3f25d51065e0b6728094e85ae169b12c693b41ea","original_commit_id":"3f25d51065e0b6728094e85ae169b12c693b41ea","user":{"login":"mollyling","id":4954150,"avatar_url":"https://avatars.githubusercontent.com/u/4954150?v=3","gravatar_id":"","url":"https://api.github.com/users/mollyling","html_url":"https://github.com/mollyling","followers_url":"https://api.github.com/users/mollyling/followers","following_url":"https://api.github.com/users/mollyling/following{/other_user}","gists_url":"https://api.github.com/users/mollyling/gists{/gist_id}","starred_url":"https://api.github.com/users/mollyling/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mollyling/subscriptions","organizations_url":"https://api.github.com/users/mollyling/orgs","repos_url":"https://api.github.com/users/mollyling/repos","events_url":"https://api.github.com/users/mollyling/events{/privacy}","received_events_url":"https://api.github.com/users/mollyling/received_events","type":"User","site_admin":false},"body":"you can do fromIndex++, toIndex++ in the last clause of the for-loop header.  Also another good place for a general copy routine.","created_at":"2015-07-24T19:27:33Z","updated_at":"2015-07-24T19:27:33Z","html_url":"https://github.com/uProxy/uproxy-lib/pull/230#discussion_r35457593","pull_request_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230","_links":{"self":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/comments/35457593"},"html":{"href":"https://github.com/uProxy/uproxy-lib/pull/230#discussion_r35457593"},"pull_request":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230"}}},"pull_request":{"url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230","id":40805026,"html_url":"https://github.com/uProxy/uproxy-lib/pull/230","diff_url":"https://github.com/uProxy/uproxy-lib/pull/230.diff","patch_url":"https://github.com/uProxy/uproxy-lib/pull/230.patch","issue_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/230","number":230,"state":"open","locked":false,"title":"Added packet length transformers and changed Transformer API to use lists of ArrayBuffers.","user":{"login":"blanu","id":35673,"avatar_url":"https://avatars.githubusercontent.com/u/35673?v=3","gravatar_id":"","url":"https://api.github.com/users/blanu","html_url":"https://github.com/blanu","followers_url":"https://api.github.com/users/blanu/followers","following_url":"https://api.github.com/users/blanu/following{/other_user}","gists_url":"https://api.github.com/users/blanu/gists{/gist_id}","starred_url":"https://api.github.com/users/blanu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blanu/subscriptions","organizations_url":"https://api.github.com/users/blanu/orgs","repos_url":"https://api.github.com/users/blanu/repos","events_url":"https://api.github.com/users/blanu/events{/privacy}","received_events_url":"https://api.github.com/users/blanu/received_events","type":"User","site_admin":false},"body":"This is just a prototype. I have not written any unit tests. I have no checked for conformance to the style guide. I have not refactored the code to remove duplicated methods. I'm sending this patch in early to get some feedback and direction before I start cleaning up the code.\r\n\r\nI added several transformers to act as functional tests. I have the following functionality in the transformers:\r\n- add and remove fragmentation headers, without otherwise modifying the packet\r\n- always increase the size, adding padding\r\n- always decrease the size (causing fragmentation)\r\n- normalize all packets to the same size\r\n- randomize packet size within a specified range using a uniform distribution\r\n- randomize packet size using a multinomial distribution\r\n\r\nAdditionally, the Transformer interface has been changed so that transform and restore now return ArrayBuffer[] instead of ArrayBuffer. This is to allow for fragmentation and defragmentation.\n\n<!-- Reviewable:start -->\n[<img src=\"https://reviewable.io/review_button.png\" height=40 alt=\"Review on Reviewable\"/>](https://reviewable.io/reviews/uproxy/uproxy-lib/230)\n<!-- Reviewable:end -->\n","created_at":"2015-07-24T18:57:44Z","updated_at":"2015-07-24T19:27:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5cab53707dbca995cd95158b6262753411de104b","assignee":{"login":"mollyling","id":4954150,"avatar_url":"https://avatars.githubusercontent.com/u/4954150?v=3","gravatar_id":"","url":"https://api.github.com/users/mollyling","html_url":"https://github.com/mollyling","followers_url":"https://api.github.com/users/mollyling/followers","following_url":"https://api.github.com/users/mollyling/following{/other_user}","gists_url":"https://api.github.com/users/mollyling/gists{/gist_id}","starred_url":"https://api.github.com/users/mollyling/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mollyling/subscriptions","organizations_url":"https://api.github.com/users/mollyling/orgs","repos_url":"https://api.github.com/users/mollyling/repos","events_url":"https://api.github.com/users/mollyling/events{/privacy}","received_events_url":"https://api.github.com/users/mollyling/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230/commits","review_comments_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230/comments","review_comment_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/230/comments","statuses_url":"https://api.github.com/repos/uProxy/uproxy-lib/statuses/3f25d51065e0b6728094e85ae169b12c693b41ea","head":{"label":"uProxy:bwiley-packet-shaping","ref":"bwiley-packet-shaping","sha":"3f25d51065e0b6728094e85ae169b12c693b41ea","user":{"login":"uProxy","id":6548286,"avatar_url":"https://avatars.githubusercontent.com/u/6548286?v=3","gravatar_id":"","url":"https://api.github.com/users/uProxy","html_url":"https://github.com/uProxy","followers_url":"https://api.github.com/users/uProxy/followers","following_url":"https://api.github.com/users/uProxy/following{/other_user}","gists_url":"https://api.github.com/users/uProxy/gists{/gist_id}","starred_url":"https://api.github.com/users/uProxy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uProxy/subscriptions","organizations_url":"https://api.github.com/users/uProxy/orgs","repos_url":"https://api.github.com/users/uProxy/repos","events_url":"https://api.github.com/users/uProxy/events{/privacy}","received_events_url":"https://api.github.com/users/uProxy/received_events","type":"Organization","site_admin":false},"repo":{"id":18026324,"name":"uproxy-lib","full_name":"uProxy/uproxy-lib","owner":{"login":"uProxy","id":6548286,"avatar_url":"https://avatars.githubusercontent.com/u/6548286?v=3","gravatar_id":"","url":"https://api.github.com/users/uProxy","html_url":"https://github.com/uProxy","followers_url":"https://api.github.com/users/uProxy/followers","following_url":"https://api.github.com/users/uProxy/following{/other_user}","gists_url":"https://api.github.com/users/uProxy/gists{/gist_id}","starred_url":"https://api.github.com/users/uProxy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uProxy/subscriptions","organizations_url":"https://api.github.com/users/uProxy/orgs","repos_url":"https://api.github.com/users/uProxy/repos","events_url":"https://api.github.com/users/uProxy/events{/privacy}","received_events_url":"https://api.github.com/users/uProxy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uProxy/uproxy-lib","description":"SOCKS proxy and other utilities for uProxy.","fork":false,"url":"https://api.github.com/repos/uProxy/uproxy-lib","forks_url":"https://api.github.com/repos/uProxy/uproxy-lib/forks","keys_url":"https://api.github.com/repos/uProxy/uproxy-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uProxy/uproxy-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uProxy/uproxy-lib/teams","hooks_url":"https://api.github.com/repos/uProxy/uproxy-lib/hooks","issue_events_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/events{/number}","events_url":"https://api.github.com/repos/uProxy/uproxy-lib/events","assignees_url":"https://api.github.com/repos/uProxy/uproxy-lib/assignees{/user}","branches_url":"https://api.github.com/repos/uProxy/uproxy-lib/branches{/branch}","tags_url":"https://api.github.com/repos/uProxy/uproxy-lib/tags","blobs_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uProxy/uproxy-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/uProxy/uproxy-lib/languages","stargazers_url":"https://api.github.com/repos/uProxy/uproxy-lib/stargazers","contributors_url":"https://api.github.com/repos/uProxy/uproxy-lib/contributors","subscribers_url":"https://api.github.com/repos/uProxy/uproxy-lib/subscribers","subscription_url":"https://api.github.com/repos/uProxy/uproxy-lib/subscription","commits_url":"https://api.github.com/repos/uProxy/uproxy-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/uProxy/uproxy-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/uProxy/uproxy-lib/contents/{+path}","compare_url":"https://api.github.com/repos/uProxy/uproxy-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uProxy/uproxy-lib/merges","archive_url":"https://api.github.com/repos/uProxy/uproxy-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uProxy/uproxy-lib/downloads","issues_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues{/number}","pulls_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/uProxy/uproxy-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/uProxy/uproxy-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uProxy/uproxy-lib/labels{/name}","releases_url":"https://api.github.com/repos/uProxy/uproxy-lib/releases{/id}","created_at":"2014-03-23T04:17:00Z","updated_at":"2015-07-21T00:25:03Z","pushed_at":"2015-07-24T18:57:48Z","git_url":"git://github.com/uProxy/uproxy-lib.git","ssh_url":"git@github.com:uProxy/uproxy-lib.git","clone_url":"https://github.com/uProxy/uproxy-lib.git","svn_url":"https://github.com/uProxy/uproxy-lib","homepage":"","size":4197,"stargazers_count":8,"watchers_count":8,"language":"TypeScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":5,"forks":2,"open_issues":5,"watchers":8,"default_branch":"dev"}},"base":{"label":"uProxy:dev","ref":"dev","sha":"0bbc5de1f8009ffca23f17ebbeba7e683b7b4d61","user":{"login":"uProxy","id":6548286,"avatar_url":"https://avatars.githubusercontent.com/u/6548286?v=3","gravatar_id":"","url":"https://api.github.com/users/uProxy","html_url":"https://github.com/uProxy","followers_url":"https://api.github.com/users/uProxy/followers","following_url":"https://api.github.com/users/uProxy/following{/other_user}","gists_url":"https://api.github.com/users/uProxy/gists{/gist_id}","starred_url":"https://api.github.com/users/uProxy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uProxy/subscriptions","organizations_url":"https://api.github.com/users/uProxy/orgs","repos_url":"https://api.github.com/users/uProxy/repos","events_url":"https://api.github.com/users/uProxy/events{/privacy}","received_events_url":"https://api.github.com/users/uProxy/received_events","type":"Organization","site_admin":false},"repo":{"id":18026324,"name":"uproxy-lib","full_name":"uProxy/uproxy-lib","owner":{"login":"uProxy","id":6548286,"avatar_url":"https://avatars.githubusercontent.com/u/6548286?v=3","gravatar_id":"","url":"https://api.github.com/users/uProxy","html_url":"https://github.com/uProxy","followers_url":"https://api.github.com/users/uProxy/followers","following_url":"https://api.github.com/users/uProxy/following{/other_user}","gists_url":"https://api.github.com/users/uProxy/gists{/gist_id}","starred_url":"https://api.github.com/users/uProxy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uProxy/subscriptions","organizations_url":"https://api.github.com/users/uProxy/orgs","repos_url":"https://api.github.com/users/uProxy/repos","events_url":"https://api.github.com/users/uProxy/events{/privacy}","received_events_url":"https://api.github.com/users/uProxy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uProxy/uproxy-lib","description":"SOCKS proxy and other utilities for uProxy.","fork":false,"url":"https://api.github.com/repos/uProxy/uproxy-lib","forks_url":"https://api.github.com/repos/uProxy/uproxy-lib/forks","keys_url":"https://api.github.com/repos/uProxy/uproxy-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uProxy/uproxy-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uProxy/uproxy-lib/teams","hooks_url":"https://api.github.com/repos/uProxy/uproxy-lib/hooks","issue_events_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/events{/number}","events_url":"https://api.github.com/repos/uProxy/uproxy-lib/events","assignees_url":"https://api.github.com/repos/uProxy/uproxy-lib/assignees{/user}","branches_url":"https://api.github.com/repos/uProxy/uproxy-lib/branches{/branch}","tags_url":"https://api.github.com/repos/uProxy/uproxy-lib/tags","blobs_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uProxy/uproxy-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/uProxy/uproxy-lib/languages","stargazers_url":"https://api.github.com/repos/uProxy/uproxy-lib/stargazers","contributors_url":"https://api.github.com/repos/uProxy/uproxy-lib/contributors","subscribers_url":"https://api.github.com/repos/uProxy/uproxy-lib/subscribers","subscription_url":"https://api.github.com/repos/uProxy/uproxy-lib/subscription","commits_url":"https://api.github.com/repos/uProxy/uproxy-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/uProxy/uproxy-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/uProxy/uproxy-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/uProxy/uproxy-lib/contents/{+path}","compare_url":"https://api.github.com/repos/uProxy/uproxy-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uProxy/uproxy-lib/merges","archive_url":"https://api.github.com/repos/uProxy/uproxy-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uProxy/uproxy-lib/downloads","issues_url":"https://api.github.com/repos/uProxy/uproxy-lib/issues{/number}","pulls_url":"https://api.github.com/repos/uProxy/uproxy-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/uProxy/uproxy-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/uProxy/uproxy-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uProxy/uproxy-lib/labels{/name}","releases_url":"https://api.github.com/repos/uProxy/uproxy-lib/releases{/id}","created_at":"2014-03-23T04:17:00Z","updated_at":"2015-07-21T00:25:03Z","pushed_at":"2015-07-24T18:57:48Z","git_url":"git://github.com/uProxy/uproxy-lib.git","ssh_url":"git@github.com:uProxy/uproxy-lib.git","clone_url":"https://github.com/uProxy/uproxy-lib.git","svn_url":"https://github.com/uProxy/uproxy-lib","homepage":"","size":4197,"stargazers_count":8,"watchers_count":8,"language":"TypeScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":5,"forks":2,"open_issues":5,"watchers":8,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230"},"html":{"href":"https://github.com/uProxy/uproxy-lib/pull/230"},"issue":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/issues/230"},"comments":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/issues/230/comments"},"review_comments":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230/comments"},"review_comment":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/pulls/230/commits"},"statuses":{"href":"https://api.github.com/repos/uProxy/uproxy-lib/statuses/3f25d51065e0b6728094e85ae169b12c693b41ea"}}}}