{"action":"created","comment":{"url":"https://api.github.com/repos/nodejs/node/pulls/comments/185379820","pull_request_review_id":116755216,"id":185379820,"diff_hunk":"@@ -0,0 +1,491 @@\n+# Brotli\n+<!--introduced_in=REPLACEME-->\n+\n+> Stability: 1 - Experimental\n+\n+The `brotli` module provides compression functionality implemented using Brotli.\n+It can be accessed using:\n+\n+```js\n+const brotli = require('brotli');\n+```\n+\n+Compressing or decompressing a stream (such as a file) can be accomplished by\n+piping the source stream data through a `brotli` stream into a destination\n+stream:\n+\n+```js\n+const compress = new brotli.Compress();\n+const fs = require('fs');\n+const inp = fs.createReadStream('input.txt');\n+const out = fs.createWriteStream('input.txt.gz');\n+\n+inp.pipe(compress).pipe(out);\n+```\n+\n+It is also possible to compress or decompress data in a single step:\n+\n+```js\n+const input = '.................................';\n+brotli.compress(input, (err, buffer) => {\n+  if (!err) {\n+    console.log(buffer.toString('base64'));\n+  } else {\n+    // handle error\n+  }\n+});\n+\n+const buffer = Buffer.from('GyAA+CVcgowA4A==', 'base64');\n+brotli.decompress(buffer, (err, buffer) => {\n+  if (!err) {\n+    console.log(buffer.toString());\n+  } else {\n+    // handle error\n+  }\n+});\n+```\n+\n+## Threadpool Usage\n+\n+Note that all `brotli` APIs except those that are explicitly synchronous use\n+libuv's threadpool, which can have surprising and negative performance\n+implications for some applications, see the [`UV_THREADPOOL_SIZE`][]\n+documentation for more information.\n+\n+## Compressing HTTP requests and responses\n+\n+The `brotli` module can be used to implement support for the `br`\n+content-encoding mechanism defined by\n+[HTTP](https://tools.ietf.org/html/rfc7230#section-4.2).\n+\n+The HTTP [`Accept-Encoding`][] header is used within an HTTP request to identify\n+the compression encodings accepted by the client. The [`Content-Encoding`][]\n+header is used to identify the compression encodings actually applied to a\n+message.\n+\n+The examples given below are drastically simplified to show the basic concept.\n+Using `brotli` encoding can be expensive, and the results ought to be cached.\n+\n+```js\n+// client request example\n+const brotli = require('brotli');\n+const http = require('http');\n+const fs = require('fs');\n+const request = http.get({ host: 'example.com',\n+                           path: '/',\n+                           port: 80,\n+                           headers: { 'Accept-Encoding': 'br' } });\n+request.on('response', (response) => {\n+  const output = fs.createWriteStream('example.com_index.html');\n+\n+  switch (response.headers['content-encoding']) {\n+    case 'br':\n+      response.pipe(new brotli.Decompress()).pipe(output);\n+      break;\n+    default:\n+      response.pipe(output);\n+      break;\n+  }\n+});\n+```\n+\n+```js\n+// server example\n+// Running a brotli operation on every request is quite expensive.\n+// It would be much more efficient to cache the compressed buffer.\n+const brotli = require('brotli');\n+const http = require('http');\n+const fs = require('fs');\n+http.createServer((request, response) => {\n+  const raw = fs.createReadStream('index.html');\n+  const acceptEncoding = request.headers['accept-encoding'] || '';\n+\n+  // This is not a conformant accept-encoding parser.\n+  // See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3\n+  if (/\\bbr\\b/.test(acceptEncoding)) {\n+    response.writeHead(200, { 'Content-Encoding': 'br' });\n+\n+    // A quality of 4 is a good balance of speed and quality.\n+    // See https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html\n+    raw.pipe(new brotli.Compress({ quality: 4 })).pipe(response);\n+  } else {\n+    response.writeHead(200, {});\n+    raw.pipe(response);\n+  }\n+}).listen(1337);\n+```\n+\n+## Flushing\n+\n+Calling [`.flush()`][] on a compression stream will make `brotli` return as much\n+output as currently possible. This may come at the cost of degraded compression\n+quality, but can be useful when data needs to be available as soon as possible.\n+\n+In the following example, `flush()` is used to write a compressed partial\n+HTTP response to the client:\n+```js\n+const brotli = require('brotli');\n+const http = require('http');\n+\n+http.createServer((request, response) => {\n+  // For the sake of simplicity, the Accept-Encoding checks are omitted.\n+  response.writeHead(200, { 'content-encoding': 'br' });\n+  const output = new brotli.Compress();\n+  output.pipe(response);\n+\n+  setInterval(() => {\n+    output.write(`The current time is ${Date()}\\n`, () => {\n+      // The data has been passed to brotli, but the compression algorithm may\n+      // have decided to buffer the data for more efficient compression.\n+      // Calling .flush() will make the data available as soon as the client\n+      // is ready to receive it.\n+      output.flush();\n+    });\n+  }, 1000);\n+}).listen(1337);\n+```\n+\n+## Constants\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+<!--type=misc-->\n+\n+All of the constants defined in [`brotli/encode.h`][] and [`brotli/decode.h`][]\n+are also defined on [`brotli.constants`][]. In the normal course of\n+operations, it will not be necessary to use these constants. They are documented\n+so that their presence is not surprising.\n+\n+### Operations\n+\n+* `brotli.constants.BROTLI_OPERATION_PROCESS`\n+* `brotli.constants.BROTLI_OPERATION_FLUSH`\n+* `brotli.constants.BROTLI_OPERATION_FINISH`\n+\n+### Error Codes for Compression\n+\n+These also can be found in [`Compress.codes`][].\n+\n+* `brotli.constants.BROTLI_TRUE`\n+* `brotli.constants.BROTLI_FALSE`\n+\n+### Error Codes for Decompression\n+\n+These also can be found in [`Decompress.codes`][].\n+\n+Negative values are errors, positive values are used for special but normal\n+events.\n+\n+* `brotli.constants.BROTLI_DECODER_NO_ERROR`\n+* `brotli.constants.BROTLI_DECODER_SUCCESS`\n+* `brotli.constants.BROTLI_DECODER_NEEDS_MORE_INPUT`\n+* `brotli.constants.BROTLI_DECODER_NEEDS_MORE_OUTPUT`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_RESERVED`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_CL_SPACE`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_TRANSFORM`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_DICTIONARY`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_PADDING_1`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_PADDING_2`\n+* `brotli.constants.BROTLI_DECODER_ERROR_FORMAT_DISTANCE`\n+* `brotli.constants.BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET`\n+* `brotli.constants.BROTLI_DECODER_ERROR_INVALID_ARGUMENTS`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2`\n+* `brotli.constants.BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES`\n+* `brotli.constants.BROTLI_DECODER_ERROR_UNREACHABLE`\n+\n+### Chunk Sizes\n+\n+* `brotli.constants.BROTLI_MIN_CHUNK`\n+* `brotli.constants.BROTLI_MAX_CHUNK`\n+* `brotli.constants.BROTLI_DEFAULT_CHUNK`\n+\n+### Compression Mode\n+\n+* `brotli.constants.BROTLI_MODE_GENERIC`\n+* `brotli.constants.BROTLI_MODE_TEXT`\n+* `brotli.constants.BROTLI_MODE_FONT`\n+* `brotli.constants.BROTLI_DEFAULT_MODE`\n+\n+### Quality Levels\n+\n+* `brotli.constants.BROTLI_MIN_QUALITY`\n+* `brotli.constants.BROTLI_MAX_QUALITY`\n+* `brotli.constants.BROTLI_DEFAULT_QUALITY`\n+\n+### LGWIN Values\n+\n+* `brotli.constants.BROTLI_MIN_WINDOW_BITS`\n+* `brotli.constants.BROTLI_MAX_WINDOW_BITS`\n+* `brotli.constants.BROTLI_LARGE_MAX_WINDOW_BITS`\n+* `brotli.constants.BROTLI_DEFAULT_WINDOW`\n+\n+### LGBLOCK values\n+\n+* `brotli.constants.BROTLI_MIN_INPUT_BLOCK_BITS`\n+* `brotli.constants.BROTLI_MAX_INPUT_BLOCK_BITS`\n+\n+### NPOSTFIX values\n+\n+* `brotli.constants.BROTLI_MAX_NPOSTFIX`\n+\n+### Parameters\n+\n+* `brotli.constants.BROTLI_PARAM_MODE`\n+* `brotli.constants.BROTLI_PARAM_QUALITY`\n+* `brotli.constants.BROTLI_PARAM_LGWIN`\n+* `brotli.constants.BROTLI_PARAM_LGBLOCK`\n+* `brotli.constants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING`\n+* `brotli.constants.BROTLI_PARAM_SIZE_HINT`\n+* `brotli.constants.BROTLI_PARAM_LARGE_WINDOW`\n+* `brotli.constants.BROTLI_PARAM_NPOSTFIX`\n+* `brotli.constants.BROTLI_PARAM_NDIRECT`\n+* `brotli.constants.BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION`\n+* `brotli.constants.BROTLI_DECODER_PARAM_LARGE_WINDOW`\n+\n+## Options Object\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+<!--type=misc-->\n+\n+Each class takes an `options` object. All options are optional.\n+\n+Note that some options are only relevant when compressing or decompressing,\n+and invalid options are simply ignored.\n+\n+* `chunkSize` {integer}\n+  **Default:** `16 * 1024`\n+* `mode` {integer} (compression only)\n+  **Default:** `brotli.constants.BROTLI_DEFAULT_MODE`\n+* `quality` {integer} (compression only)\n+  **Default:** `brotli.constants.BROTLI_DEFAULT_QUALITY`\n+* `lgwin` {integer} (compression only)\n+  **Default:** `brotli.constants.BROTLI_DEFAULT_WINDOW`\n+* `lgblock` {integer} (compression only)\n+  **Default:** `0`\n+* `disableLiteralContextModeling` {boolean} (compression only)\n+  **Default:** `false`\n+* `sizeHint` {integer} (compression only)\n+  **Default:** `0`\n+* `npostfix` {integer} (compression only)\n+  **Default:** `0`\n+* `ndirect` {integer} (compression only)\n+  **Default:** `0`\n+* `disableRingBufferReallocation` {boolean} (decompression only)\n+  **Default:** `false`\n+* `largeWindow` {boolean}\n+  **Default:** `false`\n+* `info` {boolean} (If `true`, returns an object with `buffer` and `engine`)\n+\n+See [`brotli/encode.h`][] and [`brotli/decode.h`][] for more information on\n+these.\n+\n+## Class: brotli.Brotli\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Not exported by the `brotli` module. It is documented here because it is the\n+base class of the compression/decompression classes.\n+\n+### brotli.bytesWritten\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+* {number}\n+\n+The `brotli.bytesWritten` property specifies the number of bytes written to\n+the engine, before the bytes are processed (compressed or decompressed,\n+as appropriate for the derived class).\n+\n+### brotli.close([callback])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `callback` {Function}\n+\n+Close the underlying handle.\n+\n+### brotli.flush([callback])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `callback` {Function}\n+\n+Flush pending data. Don't call this frivolously, premature flushes negatively\n+impact the effectiveness of the compression algorithm.\n+\n+Calling this only flushes data from the internal `brotli` state, and does not\n+perform flushing of any kind on the streams level. Rather, it behaves like a\n+normal call to `.write()`, i.e. it will be queued up behind other pending\n+writes and will only produce output when data is being read from the stream.\n+\n+### brotli.reset()\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Reset the encoder/decoder to factory defaults. This will undo any\n+changes you have made via [`.setParameter()`][].\n+\n+### brotli.setParameter(param, value)\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `param` {number} a valid parameter from [Parameters][]\n+- `value` {number}\n+\n+Dynamically set a parameter.\n+\n+## Class: brotli.Compress\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Compression stream.\n+\n+### new brotli.Compress([options])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `options` {Object} an [options][] object.\n+\n+Initializes an encoder with the given [options][].\n+\n+### Class Property: Compress.codes\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Error codes for compression operations.\n+More info can be found at [Error Codes for Compression][].\n+\n+## Class: brotli.Decompress\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Decompression stream.\n+\n+### new brotli.Decompress([options])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `options` {Object} an [options][] object.\n+\n+Initializes an decoder with the given [options][].\n+\n+### Class Property: Decompress.codes\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+Error codes for decompression operations.\n+More info can be found at [Error Codes for Decompression][].\n+\n+## brotli.constants\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+* {Object}\n+\n+Provides an object enumerating Brotli-related constants.\n+More info can be found at [Constants][]\n+\n+## Convenience Methods\n+\n+<!--type=misc-->\n+\n+All of these take a [`Buffer`][], [`TypedArray`][], [`DataView`][],\n+[`ArrayBuffer`][] or string as the first argument, an optional second argument\n+to supply options to the `brotli` classes and will call the supplied callback\n+with `callback(error, result)`.\n+\n+Every method has a `*Sync` counterpart, which accepts the same arguments, but\n+without a callback.\n+\n+### brotli.compress(data[, options][, callback])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `data` {Buffer|TypedArray|DataView|ArrayBuffer|string}\n+- `options` {Object} an [options][] object.\n+- `callback` {Function}\n+\n+Compress a chunk of data.\n+If callback is omitted a {Promise} will be returned.\n+\n+### brotli.compressSync(data[, options])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `data` {Buffer|TypedArray|DataView|ArrayBuffer|string}\n+- `options` {Object} an [options][] object.\n+\n+Compress a chunk of data.\n+\n+### brotli.decompress(data[, options][, callback])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `data` {Buffer|TypedArray|DataView|ArrayBuffer|string}\n+- `options` {Object} an [options][] object.\n+\n+Decompress a chunk of data.\n+If callback is omitted a {Promise} will be returned.\n+\n+### brotli.decompressSync(data[, options])\n+<!-- YAML\n+added: REPLACEME\n+-->\n+\n+- `data` {Buffer|TypedArray|DataView|ArrayBuffer|string}\n+- `options` {Object} an [options][] object.\n+- `callback` {Function}\n+\n+Decompress a chunk of data.\n+\n+[`.flush()`]: #brotli_brotli_flush_callback\n+[`.setParameter()`]: #brotli_brotli_setparameter_param_value\n+[`Accept-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3\n+[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer\n+[`brotli.constants`]: #brotli_brotli_constants\n+[`brotli/decode.h`]: https://github.com/google/brotli/blob/v1.0.4/c/include/brotli/decode.h\n+[`brotli/encode.h`]: https://github.com/google/brotli/blob/v1.0.4/c/include/brotli/encode.h\n+[`Buffer`]: buffer.html#buffer_class_buffer\n+[`Compress.codes`]: #brotli_class_property_compress_codes\n+[Constants]: #brotli_constants\n+[`Content-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11\n+[`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView\n+[`Decompress.codes`]: #brotli_class_property_decompress_codes\n+[Error Codes for Compression]: #brotli_error_codes_for_compression\n+[Error Codes for Decompression]: #brotli_error_codes_for_decompression\n+[Parameters]: #brotli_parameters\n+[options]: #brotli_options_object","path":"doc/api/brotli.md","position":489,"original_position":489,"commit_id":"72c2d4e864ad70286a3a9ef1a2e9404113e71065","original_commit_id":"72c2d4e864ad70286a3a9ef1a2e9404113e71065","user":{"login":"vsemozhetbyt","id":10393198,"avatar_url":"https://avatars1.githubusercontent.com/u/10393198?v=4","gravatar_id":"","url":"https://api.github.com/users/vsemozhetbyt","html_url":"https://github.com/vsemozhetbyt","followers_url":"https://api.github.com/users/vsemozhetbyt/followers","following_url":"https://api.github.com/users/vsemozhetbyt/following{/other_user}","gists_url":"https://api.github.com/users/vsemozhetbyt/gists{/gist_id}","starred_url":"https://api.github.com/users/vsemozhetbyt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vsemozhetbyt/subscriptions","organizations_url":"https://api.github.com/users/vsemozhetbyt/orgs","repos_url":"https://api.github.com/users/vsemozhetbyt/repos","events_url":"https://api.github.com/users/vsemozhetbyt/events{/privacy}","received_events_url":"https://api.github.com/users/vsemozhetbyt/received_events","type":"User","site_admin":false},"body":"It seems the backticks should be left, otherwise, we have[ false linkification](https://github.com/Hackzzila/node/blob/72c2d4e864ad70286a3a9ef1a2e9404113e71065/doc/api/brotli.md#new-brotlicompressoptions) in the headings:","created_at":"2018-05-02T02:14:00Z","updated_at":"2018-05-02T02:14:00Z","html_url":"https://github.com/nodejs/node/pull/20458#discussion_r185379820","pull_request_url":"https://api.github.com/repos/nodejs/node/pulls/20458","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/nodejs/node/pulls/comments/185379820"},"html":{"href":"https://github.com/nodejs/node/pull/20458#discussion_r185379820"},"pull_request":{"href":"https://api.github.com/repos/nodejs/node/pulls/20458"}}},"pull_request":{"url":"https://api.github.com/repos/nodejs/node/pulls/20458","id":185282019,"html_url":"https://github.com/nodejs/node/pull/20458","diff_url":"https://github.com/nodejs/node/pull/20458.diff","patch_url":"https://github.com/nodejs/node/pull/20458.patch","issue_url":"https://api.github.com/repos/nodejs/node/issues/20458","number":20458,"state":"open","locked":false,"title":"brotli: add brotli support","user":{"login":"Hackzzila","id":11618364,"avatar_url":"https://avatars2.githubusercontent.com/u/11618364?v=4","gravatar_id":"","url":"https://api.github.com/users/Hackzzila","html_url":"https://github.com/Hackzzila","followers_url":"https://api.github.com/users/Hackzzila/followers","following_url":"https://api.github.com/users/Hackzzila/following{/other_user}","gists_url":"https://api.github.com/users/Hackzzila/gists{/gist_id}","starred_url":"https://api.github.com/users/Hackzzila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hackzzila/subscriptions","organizations_url":"https://api.github.com/users/Hackzzila/orgs","repos_url":"https://api.github.com/users/Hackzzila/repos","events_url":"https://api.github.com/users/Hackzzila/events{/privacy}","received_events_url":"https://api.github.com/users/Hackzzila/received_events","type":"User","site_admin":false},"body":"Fixes: https://github.com/nodejs/node/issues/18964\r\n\r\nAdds brotli support to core. The brotli module must be enabled with `--expose-brotli`. The api, and most of the source code, is almost identical to the zlib module.\r\n\r\nThere are a few things that need polishing but I thought I would open this up for discussion.\r\n\r\n/cc @MylesBorins\r\n\r\n##### Checklist\r\n- [x] `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes\r\n- [x] tests and/or benchmarks are included\r\n- [x] documentation is changed or added\r\n- [x] commit message follows [commit guidelines](https://github.com/nodejs/node/blob/master/doc/guides/contributing/pull-requests.md#commit-message-guidelines)\r\n","created_at":"2018-05-01T21:32:51Z","updated_at":"2018-05-02T02:14:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b64f714dafd92559c86f7eb9f9e77a749847d865","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":919814693,"url":"https://api.github.com/repos/nodejs/node/labels/brotli","name":"brotli","color":"bfdadc","default":false},{"id":169485478,"url":"https://api.github.com/repos/nodejs/node/labels/semver-minor","name":"semver-minor","color":"fef2c0","default":false},{"id":678967907,"url":"https://api.github.com/repos/nodejs/node/labels/tsc-review","name":"tsc-review","color":"006b75","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/nodejs/node/pulls/20458/commits","review_comments_url":"https://api.github.com/repos/nodejs/node/pulls/20458/comments","review_comment_url":"https://api.github.com/repos/nodejs/node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nodejs/node/issues/20458/comments","statuses_url":"https://api.github.com/repos/nodejs/node/statuses/72c2d4e864ad70286a3a9ef1a2e9404113e71065","head":{"label":"Hackzzila:brotli-dev","ref":"brotli-dev","sha":"72c2d4e864ad70286a3a9ef1a2e9404113e71065","user":{"login":"Hackzzila","id":11618364,"avatar_url":"https://avatars2.githubusercontent.com/u/11618364?v=4","gravatar_id":"","url":"https://api.github.com/users/Hackzzila","html_url":"https://github.com/Hackzzila","followers_url":"https://api.github.com/users/Hackzzila/followers","following_url":"https://api.github.com/users/Hackzzila/following{/other_user}","gists_url":"https://api.github.com/users/Hackzzila/gists{/gist_id}","starred_url":"https://api.github.com/users/Hackzzila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hackzzila/subscriptions","organizations_url":"https://api.github.com/users/Hackzzila/orgs","repos_url":"https://api.github.com/users/Hackzzila/repos","events_url":"https://api.github.com/users/Hackzzila/events{/privacy}","received_events_url":"https://api.github.com/users/Hackzzila/received_events","type":"User","site_admin":false},"repo":{"id":130912397,"name":"node","full_name":"Hackzzila/node","owner":{"login":"Hackzzila","id":11618364,"avatar_url":"https://avatars2.githubusercontent.com/u/11618364?v=4","gravatar_id":"","url":"https://api.github.com/users/Hackzzila","html_url":"https://github.com/Hackzzila","followers_url":"https://api.github.com/users/Hackzzila/followers","following_url":"https://api.github.com/users/Hackzzila/following{/other_user}","gists_url":"https://api.github.com/users/Hackzzila/gists{/gist_id}","starred_url":"https://api.github.com/users/Hackzzila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hackzzila/subscriptions","organizations_url":"https://api.github.com/users/Hackzzila/orgs","repos_url":"https://api.github.com/users/Hackzzila/repos","events_url":"https://api.github.com/users/Hackzzila/events{/privacy}","received_events_url":"https://api.github.com/users/Hackzzila/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Hackzzila/node","description":"Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:","fork":true,"url":"https://api.github.com/repos/Hackzzila/node","forks_url":"https://api.github.com/repos/Hackzzila/node/forks","keys_url":"https://api.github.com/repos/Hackzzila/node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Hackzzila/node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Hackzzila/node/teams","hooks_url":"https://api.github.com/repos/Hackzzila/node/hooks","issue_events_url":"https://api.github.com/repos/Hackzzila/node/issues/events{/number}","events_url":"https://api.github.com/repos/Hackzzila/node/events","assignees_url":"https://api.github.com/repos/Hackzzila/node/assignees{/user}","branches_url":"https://api.github.com/repos/Hackzzila/node/branches{/branch}","tags_url":"https://api.github.com/repos/Hackzzila/node/tags","blobs_url":"https://api.github.com/repos/Hackzzila/node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Hackzzila/node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Hackzzila/node/git/refs{/sha}","trees_url":"https://api.github.com/repos/Hackzzila/node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Hackzzila/node/statuses/{sha}","languages_url":"https://api.github.com/repos/Hackzzila/node/languages","stargazers_url":"https://api.github.com/repos/Hackzzila/node/stargazers","contributors_url":"https://api.github.com/repos/Hackzzila/node/contributors","subscribers_url":"https://api.github.com/repos/Hackzzila/node/subscribers","subscription_url":"https://api.github.com/repos/Hackzzila/node/subscription","commits_url":"https://api.github.com/repos/Hackzzila/node/commits{/sha}","git_commits_url":"https://api.github.com/repos/Hackzzila/node/git/commits{/sha}","comments_url":"https://api.github.com/repos/Hackzzila/node/comments{/number}","issue_comment_url":"https://api.github.com/repos/Hackzzila/node/issues/comments{/number}","contents_url":"https://api.github.com/repos/Hackzzila/node/contents/{+path}","compare_url":"https://api.github.com/repos/Hackzzila/node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Hackzzila/node/merges","archive_url":"https://api.github.com/repos/Hackzzila/node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Hackzzila/node/downloads","issues_url":"https://api.github.com/repos/Hackzzila/node/issues{/number}","pulls_url":"https://api.github.com/repos/Hackzzila/node/pulls{/number}","milestones_url":"https://api.github.com/repos/Hackzzila/node/milestones{/number}","notifications_url":"https://api.github.com/repos/Hackzzila/node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Hackzzila/node/labels{/name}","releases_url":"https://api.github.com/repos/Hackzzila/node/releases{/id}","deployments_url":"https://api.github.com/repos/Hackzzila/node/deployments","created_at":"2018-04-24T20:52:14Z","updated_at":"2018-04-24T20:52:34Z","pushed_at":"2018-05-02T02:03:31Z","git_url":"git://github.com/Hackzzila/node.git","ssh_url":"git@github.com:Hackzzila/node.git","clone_url":"https://github.com/Hackzzila/node.git","svn_url":"https://github.com/Hackzzila/node","homepage":"https://nodejs.org","size":376498,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"nodejs:master","ref":"master","sha":"d3abb60b050858af6d5dff7fdd67cf94c76936b8","user":{"login":"nodejs","id":9950313,"avatar_url":"https://avatars3.githubusercontent.com/u/9950313?v=4","gravatar_id":"","url":"https://api.github.com/users/nodejs","html_url":"https://github.com/nodejs","followers_url":"https://api.github.com/users/nodejs/followers","following_url":"https://api.github.com/users/nodejs/following{/other_user}","gists_url":"https://api.github.com/users/nodejs/gists{/gist_id}","starred_url":"https://api.github.com/users/nodejs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodejs/subscriptions","organizations_url":"https://api.github.com/users/nodejs/orgs","repos_url":"https://api.github.com/users/nodejs/repos","events_url":"https://api.github.com/users/nodejs/events{/privacy}","received_events_url":"https://api.github.com/users/nodejs/received_events","type":"Organization","site_admin":false},"repo":{"id":27193779,"name":"node","full_name":"nodejs/node","owner":{"login":"nodejs","id":9950313,"avatar_url":"https://avatars3.githubusercontent.com/u/9950313?v=4","gravatar_id":"","url":"https://api.github.com/users/nodejs","html_url":"https://github.com/nodejs","followers_url":"https://api.github.com/users/nodejs/followers","following_url":"https://api.github.com/users/nodejs/following{/other_user}","gists_url":"https://api.github.com/users/nodejs/gists{/gist_id}","starred_url":"https://api.github.com/users/nodejs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodejs/subscriptions","organizations_url":"https://api.github.com/users/nodejs/orgs","repos_url":"https://api.github.com/users/nodejs/repos","events_url":"https://api.github.com/users/nodejs/events{/privacy}","received_events_url":"https://api.github.com/users/nodejs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nodejs/node","description":"Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:","fork":false,"url":"https://api.github.com/repos/nodejs/node","forks_url":"https://api.github.com/repos/nodejs/node/forks","keys_url":"https://api.github.com/repos/nodejs/node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nodejs/node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nodejs/node/teams","hooks_url":"https://api.github.com/repos/nodejs/node/hooks","issue_events_url":"https://api.github.com/repos/nodejs/node/issues/events{/number}","events_url":"https://api.github.com/repos/nodejs/node/events","assignees_url":"https://api.github.com/repos/nodejs/node/assignees{/user}","branches_url":"https://api.github.com/repos/nodejs/node/branches{/branch}","tags_url":"https://api.github.com/repos/nodejs/node/tags","blobs_url":"https://api.github.com/repos/nodejs/node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nodejs/node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nodejs/node/git/refs{/sha}","trees_url":"https://api.github.com/repos/nodejs/node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nodejs/node/statuses/{sha}","languages_url":"https://api.github.com/repos/nodejs/node/languages","stargazers_url":"https://api.github.com/repos/nodejs/node/stargazers","contributors_url":"https://api.github.com/repos/nodejs/node/contributors","subscribers_url":"https://api.github.com/repos/nodejs/node/subscribers","subscription_url":"https://api.github.com/repos/nodejs/node/subscription","commits_url":"https://api.github.com/repos/nodejs/node/commits{/sha}","git_commits_url":"https://api.github.com/repos/nodejs/node/git/commits{/sha}","comments_url":"https://api.github.com/repos/nodejs/node/comments{/number}","issue_comment_url":"https://api.github.com/repos/nodejs/node/issues/comments{/number}","contents_url":"https://api.github.com/repos/nodejs/node/contents/{+path}","compare_url":"https://api.github.com/repos/nodejs/node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nodejs/node/merges","archive_url":"https://api.github.com/repos/nodejs/node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nodejs/node/downloads","issues_url":"https://api.github.com/repos/nodejs/node/issues{/number}","pulls_url":"https://api.github.com/repos/nodejs/node/pulls{/number}","milestones_url":"https://api.github.com/repos/nodejs/node/milestones{/number}","notifications_url":"https://api.github.com/repos/nodejs/node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nodejs/node/labels{/name}","releases_url":"https://api.github.com/repos/nodejs/node/releases{/id}","deployments_url":"https://api.github.com/repos/nodejs/node/deployments","created_at":"2014-11-26T19:57:11Z","updated_at":"2018-05-02T01:41:32Z","pushed_at":"2018-05-02T02:03:34Z","git_url":"git://github.com/nodejs/node.git","ssh_url":"git@github.com:nodejs/node.git","clone_url":"https://github.com/nodejs/node.git","svn_url":"https://github.com/nodejs/node","homepage":"https://nodejs.org","size":375791,"stargazers_count":48287,"watchers_count":48287,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10177,"mirror_url":null,"archived":false,"open_issues_count":740,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":10177,"open_issues":740,"watchers":48287,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nodejs/node/pulls/20458"},"html":{"href":"https://github.com/nodejs/node/pull/20458"},"issue":{"href":"https://api.github.com/repos/nodejs/node/issues/20458"},"comments":{"href":"https://api.github.com/repos/nodejs/node/issues/20458/comments"},"review_comments":{"href":"https://api.github.com/repos/nodejs/node/pulls/20458/comments"},"review_comment":{"href":"https://api.github.com/repos/nodejs/node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nodejs/node/pulls/20458/commits"},"statuses":{"href":"https://api.github.com/repos/nodejs/node/statuses/72c2d4e864ad70286a3a9ef1a2e9404113e71065"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"vsemozhetbyt"}}