diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 64284b9..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "monthly" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 233227c..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: "Publish GitHub Action" - -on: - push: - branches: - - master - - main - -jobs: - publish: - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v3.5.2 - - - name: Publish - uses: tgymnich/publish-github-action@v1.2.2 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/node_modules/.bin/uuid b/node_modules/.bin/uuid new file mode 120000 index 0000000..588f70e --- /dev/null +++ b/node_modules/.bin/uuid @@ -0,0 +1 @@ +../uuid/dist/bin/uuid \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..a886b03 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,101 @@ +{ + "name": "psn-readme", + "version": "0.1.5", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@actions/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", + "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==", + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "node_modules/@actions/http-client": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz", + "integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==", + "dependencies": { + "tunnel": "^0.0.6" + } + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/psn-api": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/psn-api/-/psn-api-2.9.0.tgz", + "integrity": "sha512-3oxg2Qg3RaB2gFJ5TUtTNr5Y48bmtnRPwXgFWs+jELPB4Fbc7tKFDTS/FMCWrCb1HjUM1neJ58tf8g3aNcp86Q==", + "dependencies": { + "isomorphic-unfetch": "^3.1.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/node_modules/@actions/core/LICENSE.md b/node_modules/@actions/core/LICENSE.md new file mode 100644 index 0000000..dbae2ed --- /dev/null +++ b/node_modules/@actions/core/LICENSE.md @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright 2019 GitHub + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/@actions/core/README.md b/node_modules/@actions/core/README.md new file mode 100644 index 0000000..3c20c8e --- /dev/null +++ b/node_modules/@actions/core/README.md @@ -0,0 +1,335 @@ +# `@actions/core` + +> Core functions for setting results, logging, registering secrets and exporting variables across actions + +## Usage + +### Import the package + +```js +// javascript +const core = require('@actions/core'); + +// typescript +import * as core from '@actions/core'; +``` + +#### Inputs/Outputs + +Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` set to be false, the input should have a default value in `action.yml`. + +Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled. + +```js +const myInput = core.getInput('inputName', { required: true }); +const myBooleanInput = core.getBooleanInput('booleanInputName', { required: true }); +const myMultilineInput = core.getMultilineInput('multilineInputName', { required: true }); +core.setOutput('outputKey', 'outputVal'); +``` + +#### Exporting variables + +Since each step runs in a separate process, you can use `exportVariable` to add it to this step and future steps environment blocks. + +```js +core.exportVariable('envVar', 'Val'); +``` + +#### Setting a secret + +Setting a secret registers the secret with the runner to ensure it is masked in logs. + +```js +core.setSecret('myPassword'); +``` + +#### PATH Manipulation + +To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `addPath`. The runner will prepend the path given to the jobs PATH. + +```js +core.addPath('/path/to/mytool'); +``` + +#### Exit codes + +You should use this library to set the failing exit code for your action. If status is not set and the script runs to completion, that will lead to a success. + +```js +const core = require('@actions/core'); + +try { + // Do stuff +} +catch (err) { + // setFailed logs the message and sets a failing exit code + core.setFailed(`Action failed with error ${err}`); +} +``` + +Note that `setNeutral` is not yet implemented in actions V2 but equivalent functionality is being planned. + +#### Logging + +Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs). + +```js +const core = require('@actions/core'); + +const myInput = core.getInput('input'); +try { + core.debug('Inside try block'); + + if (!myInput) { + core.warning('myInput was not set'); + } + + if (core.isDebug()) { + // curl -v https://github.com + } else { + // curl https://github.com + } + + // Do stuff + core.info('Output to the actions build log') + + core.notice('This is a message that will also emit an annotation') +} +catch (err) { + core.error(`Error ${err}, action may still succeed though`); +} +``` + +This library can also wrap chunks of output in foldable groups. + +```js +const core = require('@actions/core') + +// Manually wrap output +core.startGroup('Do some function') +doSomeFunction() +core.endGroup() + +// Wrap an asynchronous function call +const result = await core.group('Do something async', async () => { + const response = await doSomeHTTPRequest() + return response +}) +``` + +#### Annotations + +This library has 3 methods that will produce [annotations](https://docs.github.com/en/rest/reference/checks#create-a-check-run). +```js +core.error('This is a bad error. This will also fail the build.') + +core.warning('Something went wrong, but it\'s not bad enough to fail the build.') + +core.notice('Something happened that you might want to know about.') +``` + +These will surface to the UI in the Actions page and on Pull Requests. They look something like this: + +![Annotations Image](../../docs/assets/annotations.png) + +These annotations can also be attached to particular lines and columns of your source files to show exactly where a problem is occuring. + +These options are: +```typescript +export interface AnnotationProperties { + /** + * A title for the annotation. + */ + title?: string + + /** + * The name of the file for which the annotation should be created. + */ + file?: string + + /** + * The start line for the annotation. + */ + startLine?: number + + /** + * The end line for the annotation. Defaults to `startLine` when `startLine` is provided. + */ + endLine?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + */ + startColumn?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + * Defaults to `startColumn` when `startColumn` is provided. + */ + endColumn?: number +} +``` + +#### Styling output + +Colored output is supported in the Action logs via standard [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). 3/4 bit, 8 bit and 24 bit colors are all supported. + +Foreground colors: + +```js +// 3/4 bit +core.info('\u001b[35mThis foreground will be magenta') + +// 8 bit +core.info('\u001b[38;5;6mThis foreground will be cyan') + +// 24 bit +core.info('\u001b[38;2;255;0;0mThis foreground will be bright red') +``` + +Background colors: + +```js +// 3/4 bit +core.info('\u001b[43mThis background will be yellow'); + +// 8 bit +core.info('\u001b[48;5;6mThis background will be cyan') + +// 24 bit +core.info('\u001b[48;2;255;0;0mThis background will be bright red') +``` + +Special styles: + +```js +core.info('\u001b[1mBold text') +core.info('\u001b[3mItalic text') +core.info('\u001b[4mUnderlined text') +``` + +ANSI escape codes can be combined with one another: + +```js +core.info('\u001b[31;46mRed foreground with a cyan background and \u001b[1mbold text at the end'); +``` + +> Note: Escape codes reset at the start of each line + +```js +core.info('\u001b[35mThis foreground will be magenta') +core.info('This foreground will reset to the default') +``` + +Manually typing escape codes can be a little difficult, but you can use third party modules such as [ansi-styles](https://github.com/chalk/ansi-styles). + +```js +const style = require('ansi-styles'); +core.info(style.color.ansi16m.hex('#abcdef') + 'Hello world!') +``` + +#### Action state + +You can use this library to save state and get state for sharing information between a given wrapper action: + +**action.yml**: + +```yaml +name: 'Wrapper action sample' +inputs: + name: + default: 'GitHub' +runs: + using: 'node12' + main: 'main.js' + post: 'cleanup.js' +``` + +In action's `main.js`: + +```js +const core = require('@actions/core'); + +core.saveState("pidToKill", 12345); +``` + +In action's `cleanup.js`: + +```js +const core = require('@actions/core'); + +var pid = core.getState("pidToKill"); + +process.kill(pid); +``` + +#### OIDC Token + +You can use these methods to interact with the GitHub OIDC provider and get a JWT ID token which would help to get access token from third party cloud providers. + +**Method Name**: getIDToken() + +**Inputs** + +audience : optional + +**Outputs** + +A [JWT](https://jwt.io/) ID Token + +In action's `main.ts`: +```js +const core = require('@actions/core'); +async function getIDTokenAction(): Promise { + + const audience = core.getInput('audience', {required: false}) + + const id_token1 = await core.getIDToken() // ID Token with default audience + const id_token2 = await core.getIDToken(audience) // ID token with custom audience + + // this id_token can be used to get access token from third party cloud providers +} +getIDTokenAction() +``` + +In action's `actions.yml`: + +```yaml +name: 'GetIDToken' +description: 'Get ID token from Github OIDC provider' +inputs: + audience: + description: 'Audience for which the ID token is intended for' + required: false +outputs: + id_token1: + description: 'ID token obtained from OIDC provider' + id_token2: + description: 'ID token obtained from OIDC provider' +runs: + using: 'node12' + main: 'dist/index.js' +``` + +#### Filesystem path helpers + +You can use these methods to manipulate file paths across operating systems. + +The `toPosixPath` function converts input paths to Posix-style (Linux) paths. +The `toWin32Path` function converts input paths to Windows-style paths. These +functions work independently of the underlying runner operating system. + +```js +toPosixPath('\\foo\\bar') // => /foo/bar +toWin32Path('/foo/bar') // => \foo\bar +``` + +The `toPlatformPath` function converts input paths to the expected value on the runner's operating system. + +```js +// On a Windows runner. +toPlatformPath('/foo/bar') // => \foo\bar + +// On a Linux runner. +toPlatformPath('\\foo\\bar') // => /foo/bar +``` diff --git a/node_modules/@actions/core/lib/command.d.ts b/node_modules/@actions/core/lib/command.d.ts new file mode 100644 index 0000000..53f8f4b --- /dev/null +++ b/node_modules/@actions/core/lib/command.d.ts @@ -0,0 +1,15 @@ +export interface CommandProperties { + [key: string]: any; +} +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +export declare function issueCommand(command: string, properties: CommandProperties, message: any): void; +export declare function issue(name: string, message?: string): void; diff --git a/node_modules/@actions/core/lib/command.js b/node_modules/@actions/core/lib/command.js new file mode 100644 index 0000000..0b28c66 --- /dev/null +++ b/node_modules/@actions/core/lib/command.js @@ -0,0 +1,92 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(require("os")); +const utils_1 = require("./utils"); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/command.js.map b/node_modules/@actions/core/lib/command.js.map new file mode 100644 index 0000000..51c7c63 --- /dev/null +++ b/node_modules/@actions/core/lib/command.js.map @@ -0,0 +1 @@ +{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAwB;AACxB,mCAAsC;AAWtC;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,OAAO,GAAG,EAAE;IAC9C,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAM;IACxB,OAAO,sBAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAM;IAC5B,OAAO,sBAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/core.d.ts b/node_modules/@actions/core/lib/core.d.ts new file mode 100644 index 0000000..1defb57 --- /dev/null +++ b/node_modules/@actions/core/lib/core.d.ts @@ -0,0 +1,198 @@ +/** + * Interface for getInput options + */ +export interface InputOptions { + /** Optional. Whether the input is required. If required and not present, will throw. Defaults to false */ + required?: boolean; + /** Optional. Whether leading/trailing whitespace will be trimmed for the input. Defaults to true */ + trimWhitespace?: boolean; +} +/** + * The code to exit an action + */ +export declare enum ExitCode { + /** + * A code indicating that the action was successful + */ + Success = 0, + /** + * A code indicating that the action was a failure + */ + Failure = 1 +} +/** + * Optional properties that can be sent with annotatation commands (notice, error, and warning) + * See: https://docs.github.com/en/rest/reference/checks#create-a-check-run for more information about annotations. + */ +export interface AnnotationProperties { + /** + * A title for the annotation. + */ + title?: string; + /** + * The path of the file for which the annotation should be created. + */ + file?: string; + /** + * The start line for the annotation. + */ + startLine?: number; + /** + * The end line for the annotation. Defaults to `startLine` when `startLine` is provided. + */ + endLine?: number; + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + */ + startColumn?: number; + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + * Defaults to `startColumn` when `startColumn` is provided. + */ + endColumn?: number; +} +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +export declare function exportVariable(name: string, val: any): void; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +export declare function setSecret(secret: string): void; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +export declare function addPath(inputPath: string): void; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +export declare function getInput(name: string, options?: InputOptions): string; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +export declare function getMultilineInput(name: string, options?: InputOptions): string[]; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +export declare function getBooleanInput(name: string, options?: InputOptions): boolean; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +export declare function setOutput(name: string, value: any): void; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +export declare function setCommandEcho(enabled: boolean): void; +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +export declare function setFailed(message: string | Error): void; +/** + * Gets whether Actions Step Debug is on or not + */ +export declare function isDebug(): boolean; +/** + * Writes debug message to user log + * @param message debug message + */ +export declare function debug(message: string): void; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +export declare function error(message: string | Error, properties?: AnnotationProperties): void; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +export declare function warning(message: string | Error, properties?: AnnotationProperties): void; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +export declare function notice(message: string | Error, properties?: AnnotationProperties): void; +/** + * Writes info to log with console.log. + * @param message info message + */ +export declare function info(message: string): void; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +export declare function startGroup(name: string): void; +/** + * End an output group. + */ +export declare function endGroup(): void; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +export declare function group(name: string, fn: () => Promise): Promise; +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +export declare function saveState(name: string, value: any): void; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +export declare function getState(name: string): string; +export declare function getIDToken(aud?: string): Promise; +/** + * Summary exports + */ +export { summary } from './summary'; +/** + * @deprecated use core.summary + */ +export { markdownSummary } from './summary'; +/** + * Path exports + */ +export { toPosixPath, toWin32Path, toPlatformPath } from './path-utils'; diff --git a/node_modules/@actions/core/lib/core.js b/node_modules/@actions/core/lib/core.js new file mode 100644 index 0000000..48df6ad --- /dev/null +++ b/node_modules/@actions/core/lib/core.js @@ -0,0 +1,336 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = require("./command"); +const file_command_1 = require("./file-command"); +const utils_1 = require("./utils"); +const os = __importStar(require("os")); +const path = __importStar(require("path")); +const oidc_utils_1 = require("./oidc-utils"); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); + } + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); + } + else { + command_1.issueCommand('add-path', {}, inputPath); + } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + } + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = require("./summary"); +Object.defineProperty(exports, "summary", { enumerable: true, get: function () { return summary_1.summary; } }); +/** + * @deprecated use core.summary + */ +var summary_2 = require("./summary"); +Object.defineProperty(exports, "markdownSummary", { enumerable: true, get: function () { return summary_2.markdownSummary; } }); +/** + * Path exports + */ +var path_utils_1 = require("./path-utils"); +Object.defineProperty(exports, "toPosixPath", { enumerable: true, get: function () { return path_utils_1.toPosixPath; } }); +Object.defineProperty(exports, "toWin32Path", { enumerable: true, get: function () { return path_utils_1.toWin32Path; } }); +Object.defineProperty(exports, "toPlatformPath", { enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }); +//# sourceMappingURL=core.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/core.js.map b/node_modules/@actions/core/lib/core.js.map new file mode 100644 index 0000000..99f7fd8 --- /dev/null +++ b/node_modules/@actions/core/lib/core.js.map @@ -0,0 +1 @@ +{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/file-command.d.ts b/node_modules/@actions/core/lib/file-command.d.ts new file mode 100644 index 0000000..2d1f2f4 --- /dev/null +++ b/node_modules/@actions/core/lib/file-command.d.ts @@ -0,0 +1,2 @@ +export declare function issueFileCommand(command: string, message: any): void; +export declare function prepareKeyValueMessage(key: string, value: any): string; diff --git a/node_modules/@actions/core/lib/file-command.js b/node_modules/@actions/core/lib/file-command.js new file mode 100644 index 0000000..2d0d738 --- /dev/null +++ b/node_modules/@actions/core/lib/file-command.js @@ -0,0 +1,58 @@ +"use strict"; +// For internal use, subject to change. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(require("fs")); +const os = __importStar(require("os")); +const uuid_1 = require("uuid"); +const utils_1 = require("./utils"); +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); +} +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; +} +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/file-command.js.map b/node_modules/@actions/core/lib/file-command.js.map new file mode 100644 index 0000000..b1a9d54 --- /dev/null +++ b/node_modules/@actions/core/lib/file-command.js.map @@ -0,0 +1 @@ +{"version":3,"file":"file-command.js","sourceRoot":"","sources":["../src/file-command.ts"],"names":[],"mappings":";AAAA,uCAAuC;;;;;;;;;;;;;;;;;;;;;;AAEvC,mCAAmC;AACnC,uDAAuD;AAEvD,uCAAwB;AACxB,uCAAwB;AACxB,+BAAiC;AACjC,mCAAsC;AAEtC,SAAgB,gBAAgB,CAAC,OAAe,EAAE,OAAY;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;IACjD,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CACb,wDAAwD,OAAO,EAAE,CAClE,CAAA;KACF;IACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;KACrD;IAED,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,sBAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;QACjE,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAA;AACJ,CAAC;AAdD,4CAcC;AAED,SAAgB,sBAAsB,CAAC,GAAW,EAAE,KAAU;IAC5D,MAAM,SAAS,GAAG,gBAAgB,SAAM,EAAE,EAAE,CAAA;IAC5C,MAAM,cAAc,GAAG,sBAAc,CAAC,KAAK,CAAC,CAAA;IAE5C,4EAA4E;IAC5E,6EAA6E;IAC7E,iBAAiB;IACjB,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAC3B,MAAM,IAAI,KAAK,CACb,4DAA4D,SAAS,GAAG,CACzE,CAAA;KACF;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CACb,6DAA6D,SAAS,GAAG,CAC1E,CAAA;KACF;IAED,OAAO,GAAG,GAAG,KAAK,SAAS,GAAG,EAAE,CAAC,GAAG,GAAG,cAAc,GAAG,EAAE,CAAC,GAAG,GAAG,SAAS,EAAE,CAAA;AAC9E,CAAC;AApBD,wDAoBC"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/oidc-utils.d.ts b/node_modules/@actions/core/lib/oidc-utils.d.ts new file mode 100644 index 0000000..657c7f4 --- /dev/null +++ b/node_modules/@actions/core/lib/oidc-utils.d.ts @@ -0,0 +1,7 @@ +export declare class OidcClient { + private static createHttpClient; + private static getRequestToken; + private static getIDTokenUrl; + private static getCall; + static getIDToken(audience?: string): Promise; +} diff --git a/node_modules/@actions/core/lib/oidc-utils.js b/node_modules/@actions/core/lib/oidc-utils.js new file mode 100644 index 0000000..f701277 --- /dev/null +++ b/node_modules/@actions/core/lib/oidc-utils.js @@ -0,0 +1,77 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.OidcClient = void 0; +const http_client_1 = require("@actions/http-client"); +const auth_1 = require("@actions/http-client/lib/auth"); +const core_1 = require("./core"); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } +} +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/oidc-utils.js.map b/node_modules/@actions/core/lib/oidc-utils.js.map new file mode 100644 index 0000000..284fa1d --- /dev/null +++ b/node_modules/@actions/core/lib/oidc-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"oidc-utils.js","sourceRoot":"","sources":["../src/oidc-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,sDAA+C;AAC/C,wDAAqE;AACrE,iCAAuC;AAKvC,MAAa,UAAU;IACb,MAAM,CAAC,gBAAgB,CAC7B,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,EAAE;QAEb,MAAM,cAAc,GAAmB;YACrC,YAAY,EAAE,UAAU;YACxB,UAAU,EAAE,QAAQ;SACrB,CAAA;QAED,OAAO,IAAI,wBAAU,CACnB,qBAAqB,EACrB,CAAC,IAAI,8BAAuB,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,EAC3D,cAAc,CACf,CAAA;IACH,CAAC;IAEO,MAAM,CAAC,eAAe;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC3D,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAA;SACF;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,MAAM,CAAC,aAAa;QAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC9D,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;SAC3E;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAEO,MAAM,CAAO,OAAO,CAAC,YAAoB;;;YAC/C,MAAM,UAAU,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAA;YAEhD,MAAM,GAAG,GAAG,MAAM,UAAU;iBACzB,OAAO,CAAgB,YAAY,CAAC;iBACpC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,MAAM,IAAI,KAAK,CACb;uBACa,KAAK,CAAC,UAAU;yBACd,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CACtC,CAAA;YACH,CAAC,CAAC,CAAA;YAEJ,MAAM,QAAQ,SAAG,GAAG,CAAC,MAAM,0CAAE,KAAK,CAAA;YAClC,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;aACjE;YACD,OAAO,QAAQ,CAAA;;KAChB;IAED,MAAM,CAAO,UAAU,CAAC,QAAiB;;YACvC,IAAI;gBACF,gDAAgD;gBAChD,IAAI,YAAY,GAAW,UAAU,CAAC,aAAa,EAAE,CAAA;gBACrD,IAAI,QAAQ,EAAE;oBACZ,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;oBACpD,YAAY,GAAG,GAAG,YAAY,aAAa,eAAe,EAAE,CAAA;iBAC7D;gBAED,YAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAA;gBAExC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;gBACvD,gBAAS,CAAC,QAAQ,CAAC,CAAA;gBACnB,OAAO,QAAQ,CAAA;aAChB;YAAC,OAAO,KAAK,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;aACnD;QACH,CAAC;KAAA;CACF;AAzED,gCAyEC"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/path-utils.d.ts b/node_modules/@actions/core/lib/path-utils.d.ts new file mode 100644 index 0000000..1fee9f3 --- /dev/null +++ b/node_modules/@actions/core/lib/path-utils.d.ts @@ -0,0 +1,25 @@ +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +export declare function toPosixPath(pth: string): string; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +export declare function toWin32Path(pth: string): string; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +export declare function toPlatformPath(pth: string): string; diff --git a/node_modules/@actions/core/lib/path-utils.js b/node_modules/@actions/core/lib/path-utils.js new file mode 100644 index 0000000..7251c82 --- /dev/null +++ b/node_modules/@actions/core/lib/path-utils.js @@ -0,0 +1,58 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(require("path")); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/path-utils.js.map b/node_modules/@actions/core/lib/path-utils.js.map new file mode 100644 index 0000000..7ab1cac --- /dev/null +++ b/node_modules/@actions/core/lib/path-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4B;AAE5B;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAClC,CAAC;AAFD,kCAEC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC;AAFD,kCAEC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,GAAW;IACxC,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC;AAFD,wCAEC"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/summary.d.ts b/node_modules/@actions/core/lib/summary.d.ts new file mode 100644 index 0000000..bb79255 --- /dev/null +++ b/node_modules/@actions/core/lib/summary.d.ts @@ -0,0 +1,202 @@ +export declare const SUMMARY_ENV_VAR = "GITHUB_STEP_SUMMARY"; +export declare const SUMMARY_DOCS_URL = "https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary"; +export declare type SummaryTableRow = (SummaryTableCell | string)[]; +export interface SummaryTableCell { + /** + * Cell content + */ + data: string; + /** + * Render cell as header + * (optional) default: false + */ + header?: boolean; + /** + * Number of columns the cell extends + * (optional) default: '1' + */ + colspan?: string; + /** + * Number of rows the cell extends + * (optional) default: '1' + */ + rowspan?: string; +} +export interface SummaryImageOptions { + /** + * The width of the image in pixels. Must be an integer without a unit. + * (optional) + */ + width?: string; + /** + * The height of the image in pixels. Must be an integer without a unit. + * (optional) + */ + height?: string; +} +export interface SummaryWriteOptions { + /** + * Replace all existing content in summary file with buffer contents + * (optional) default: false + */ + overwrite?: boolean; +} +declare class Summary { + private _buffer; + private _filePath?; + constructor(); + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ + private filePath; + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ + private wrap; + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options?: SummaryWriteOptions): Promise; + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear(): Promise; + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify(): string; + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer(): boolean; + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer(): Summary; + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text: string, addEOL?: boolean): Summary; + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL(): Summary; + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code: string, lang?: string): Summary; + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items: string[], ordered?: boolean): Summary; + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows: SummaryTableRow[]): Summary; + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label: string, content: string): Summary; + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src: string, alt: string, options?: SummaryImageOptions): Summary; + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text: string, level?: number | string): Summary; + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator(): Summary; + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak(): Summary; + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text: string, cite?: string): Summary; + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text: string, href: string): Summary; +} +/** + * @deprecated use `core.summary` + */ +export declare const markdownSummary: Summary; +export declare const summary: Summary; +export {}; diff --git a/node_modules/@actions/core/lib/summary.js b/node_modules/@actions/core/lib/summary.js new file mode 100644 index 0000000..04a335b --- /dev/null +++ b/node_modules/@actions/core/lib/summary.js @@ -0,0 +1,283 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = require("os"); +const fs_1 = require("fs"); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; + } + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); + } + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); + } + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; + } + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; + } + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; + } + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); + } +} +const _summary = new Summary(); +/** + * @deprecated use `core.summary` + */ +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/summary.js.map b/node_modules/@actions/core/lib/summary.js.map new file mode 100644 index 0000000..d598f26 --- /dev/null +++ b/node_modules/@actions/core/lib/summary.js.map @@ -0,0 +1 @@ +{"version":3,"file":"summary.js","sourceRoot":"","sources":["../src/summary.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/utils.d.ts b/node_modules/@actions/core/lib/utils.d.ts new file mode 100644 index 0000000..3b9e28d --- /dev/null +++ b/node_modules/@actions/core/lib/utils.d.ts @@ -0,0 +1,14 @@ +import { AnnotationProperties } from './core'; +import { CommandProperties } from './command'; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +export declare function toCommandValue(input: any): string; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +export declare function toCommandProperties(annotationProperties: AnnotationProperties): CommandProperties; diff --git a/node_modules/@actions/core/lib/utils.js b/node_modules/@actions/core/lib/utils.js new file mode 100644 index 0000000..9b5ca44 --- /dev/null +++ b/node_modules/@actions/core/lib/utils.js @@ -0,0 +1,40 @@ +"use strict"; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; + } + else if (typeof input === 'string' || input instanceof String) { + return input; + } + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; + } + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; +} +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/utils.js.map b/node_modules/@actions/core/lib/utils.js.map new file mode 100644 index 0000000..8211bb7 --- /dev/null +++ b/node_modules/@actions/core/lib/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA,mCAAmC;AACnC,uDAAuD;;;AAKvD;;;GAGG;AACH,SAAgB,cAAc,CAAC,KAAU;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;QACzC,OAAO,EAAE,CAAA;KACV;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,EAAE;QAC/D,OAAO,KAAe,CAAA;KACvB;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAPD,wCAOC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CACjC,oBAA0C;IAE1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,EAAE;QAC7C,OAAO,EAAE,CAAA;KACV;IAED,OAAO;QACL,KAAK,EAAE,oBAAoB,CAAC,KAAK;QACjC,IAAI,EAAE,oBAAoB,CAAC,IAAI;QAC/B,IAAI,EAAE,oBAAoB,CAAC,SAAS;QACpC,OAAO,EAAE,oBAAoB,CAAC,OAAO;QACrC,GAAG,EAAE,oBAAoB,CAAC,WAAW;QACrC,SAAS,EAAE,oBAAoB,CAAC,SAAS;KAC1C,CAAA;AACH,CAAC;AAfD,kDAeC"} \ No newline at end of file diff --git a/node_modules/@actions/core/package.json b/node_modules/@actions/core/package.json new file mode 100644 index 0000000..1f3824d --- /dev/null +++ b/node_modules/@actions/core/package.json @@ -0,0 +1,46 @@ +{ + "name": "@actions/core", + "version": "1.10.0", + "description": "Actions core lib", + "keywords": [ + "github", + "actions", + "core" + ], + "homepage": "https://github.com/actions/toolkit/tree/main/packages/core", + "license": "MIT", + "main": "lib/core.js", + "types": "lib/core.d.ts", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib", + "!.DS_Store" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/actions/toolkit.git", + "directory": "packages/core" + }, + "scripts": { + "audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json", + "test": "echo \"Error: run tests from root\" && exit 1", + "tsc": "tsc" + }, + "bugs": { + "url": "https://github.com/actions/toolkit/issues" + }, + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@types/node": "^12.0.2", + "@types/uuid": "^8.3.4" + } +} diff --git a/node_modules/@actions/http-client/LICENSE b/node_modules/@actions/http-client/LICENSE new file mode 100644 index 0000000..5823a51 --- /dev/null +++ b/node_modules/@actions/http-client/LICENSE @@ -0,0 +1,21 @@ +Actions Http Client for Node.js + +Copyright (c) GitHub, Inc. + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@actions/http-client/README.md b/node_modules/@actions/http-client/README.md new file mode 100644 index 0000000..7e06ade --- /dev/null +++ b/node_modules/@actions/http-client/README.md @@ -0,0 +1,73 @@ +# `@actions/http-client` + +A lightweight HTTP client optimized for building actions. + +## Features + + - HTTP client with TypeScript generics and async/await/Promises + - Typings included! + - [Proxy support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-self-hosted-runners#using-a-proxy-server-with-self-hosted-runners) just works with actions and the runner + - Targets ES2019 (runner runs actions with node 12+). Only supported on node 12+. + - Basic, Bearer and PAT Support out of the box. Extensible handlers for others. + - Redirects supported + +Features and releases [here](./RELEASES.md) + +## Install + +``` +npm install @actions/http-client --save +``` + +## Samples + +See the [tests](./__tests__) for detailed examples. + +## Errors + +### HTTP + +The HTTP client does not throw unless truly exceptional. + +* A request that successfully executes resulting in a 404, 500 etc... will return a response object with a status code and a body. +* Redirects (3xx) will be followed by default. + +See the [tests](./__tests__) for detailed examples. + +## Debugging + +To enable detailed console logging of all HTTP requests and responses, set the NODE_DEBUG environment varible: + +```shell +export NODE_DEBUG=http +``` + +## Node support + +The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+. + +## Support and Versioning + +We follow semver and will hold compatibility between major versions and increment the minor version with new features and capabilities (while holding compat). + +## Contributing + +We welcome PRs. Please create an issue and if applicable, a design before proceeding with code. + +once: + +``` +npm install +``` + +To build: + +``` +npm run build +``` + +To run all tests: + +``` +npm test +``` diff --git a/node_modules/@actions/http-client/lib/auth.d.ts b/node_modules/@actions/http-client/lib/auth.d.ts new file mode 100644 index 0000000..8cc9fc3 --- /dev/null +++ b/node_modules/@actions/http-client/lib/auth.d.ts @@ -0,0 +1,26 @@ +/// +import * as http from 'http'; +import * as ifm from './interfaces'; +import { HttpClientResponse } from './index'; +export declare class BasicCredentialHandler implements ifm.RequestHandler { + username: string; + password: string; + constructor(username: string, password: string); + prepareRequest(options: http.RequestOptions): void; + canHandleAuthentication(): boolean; + handleAuthentication(): Promise; +} +export declare class BearerCredentialHandler implements ifm.RequestHandler { + token: string; + constructor(token: string); + prepareRequest(options: http.RequestOptions): void; + canHandleAuthentication(): boolean; + handleAuthentication(): Promise; +} +export declare class PersonalAccessTokenCredentialHandler implements ifm.RequestHandler { + token: string; + constructor(token: string); + prepareRequest(options: http.RequestOptions): void; + canHandleAuthentication(): boolean; + handleAuthentication(): Promise; +} diff --git a/node_modules/@actions/http-client/lib/auth.js b/node_modules/@actions/http-client/lib/auth.js new file mode 100644 index 0000000..2c150a3 --- /dev/null +++ b/node_modules/@actions/http-client/lib/auth.js @@ -0,0 +1,81 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; +class BasicCredentialHandler { + constructor(username, password) { + this.username = username; + this.password = password; + } + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BasicCredentialHandler = BasicCredentialHandler; +class BearerCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Bearer ${this.token}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BearerCredentialHandler = BearerCredentialHandler; +class PersonalAccessTokenCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; +//# sourceMappingURL=auth.js.map \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/auth.js.map b/node_modules/@actions/http-client/lib/auth.js.map new file mode 100644 index 0000000..7d3a18a --- /dev/null +++ b/node_modules/@actions/http-client/lib/auth.js.map @@ -0,0 +1 @@ +{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,sBAAsB;IAIjC,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CACpC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA1BD,wDA0BC;AAED,MAAa,uBAAuB;IAGlC,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAA;IAC3D,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAxBD,0DAwBC;AAED,MAAa,oCAAoC;IAI/C,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,OAAO,IAAI,CAAC,KAAK,EAAE,CACpB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA3BD,oFA2BC"} \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/index.d.ts b/node_modules/@actions/http-client/lib/index.d.ts new file mode 100644 index 0000000..fe733d1 --- /dev/null +++ b/node_modules/@actions/http-client/lib/index.d.ts @@ -0,0 +1,123 @@ +/// +import * as http from 'http'; +import * as ifm from './interfaces'; +export declare enum HttpCodes { + OK = 200, + MultipleChoices = 300, + MovedPermanently = 301, + ResourceMoved = 302, + SeeOther = 303, + NotModified = 304, + UseProxy = 305, + SwitchProxy = 306, + TemporaryRedirect = 307, + PermanentRedirect = 308, + BadRequest = 400, + Unauthorized = 401, + PaymentRequired = 402, + Forbidden = 403, + NotFound = 404, + MethodNotAllowed = 405, + NotAcceptable = 406, + ProxyAuthenticationRequired = 407, + RequestTimeout = 408, + Conflict = 409, + Gone = 410, + TooManyRequests = 429, + InternalServerError = 500, + NotImplemented = 501, + BadGateway = 502, + ServiceUnavailable = 503, + GatewayTimeout = 504 +} +export declare enum Headers { + Accept = "accept", + ContentType = "content-type" +} +export declare enum MediaTypes { + ApplicationJson = "application/json" +} +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +export declare function getProxyUrl(serverUrl: string): string; +export declare class HttpClientError extends Error { + constructor(message: string, statusCode: number); + statusCode: number; + result?: any; +} +export declare class HttpClientResponse { + constructor(message: http.IncomingMessage); + message: http.IncomingMessage; + readBody(): Promise; +} +export declare function isHttps(requestUrl: string): boolean; +export declare class HttpClient { + userAgent: string | undefined; + handlers: ifm.RequestHandler[]; + requestOptions: ifm.RequestOptions | undefined; + private _ignoreSslError; + private _socketTimeout; + private _allowRedirects; + private _allowRedirectDowngrade; + private _maxRedirects; + private _allowRetries; + private _maxRetries; + private _agent; + private _proxyAgent; + private _keepAlive; + private _disposed; + constructor(userAgent?: string, handlers?: ifm.RequestHandler[], requestOptions?: ifm.RequestOptions); + options(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + get(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + del(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + post(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + patch(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + put(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + head(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + getJson(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise>; + postJson(requestUrl: string, obj: any, additionalHeaders?: http.OutgoingHttpHeaders): Promise>; + putJson(requestUrl: string, obj: any, additionalHeaders?: http.OutgoingHttpHeaders): Promise>; + patchJson(requestUrl: string, obj: any, additionalHeaders?: http.OutgoingHttpHeaders): Promise>; + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb: string, requestUrl: string, data: string | NodeJS.ReadableStream | null, headers?: http.OutgoingHttpHeaders): Promise; + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose(): void; + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info: ifm.RequestInfo, data: string | NodeJS.ReadableStream | null): Promise; + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info: ifm.RequestInfo, data: string | NodeJS.ReadableStream | null, onResult: (err?: Error, res?: HttpClientResponse) => void): void; + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl: string): http.Agent; + private _prepareRequest; + private _mergeHeaders; + private _getExistingOrDefaultHeader; + private _getAgent; + private _performExponentialBackoff; + private _processResponse; +} diff --git a/node_modules/@actions/http-client/lib/index.js b/node_modules/@actions/http-client/lib/index.js new file mode 100644 index 0000000..a1b7d03 --- /dev/null +++ b/node_modules/@actions/http-client/lib/index.js @@ -0,0 +1,605 @@ +"use strict"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; +const http = __importStar(require("http")); +const https = __importStar(require("https")); +const pm = __importStar(require("./proxy")); +const tunnel = __importStar(require("tunnel")); +var HttpCodes; +(function (HttpCodes) { + HttpCodes[HttpCodes["OK"] = 200] = "OK"; + HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; + HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; + HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; + HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; + HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; + HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; + HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; + HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; + HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; + HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; + HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; + HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; + HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; + HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; + HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; + HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; + HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; + HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; + HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; + HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; + HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; + HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; + HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; + HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; + HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; + HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; +})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); +var Headers; +(function (Headers) { + Headers["Accept"] = "accept"; + Headers["ContentType"] = "content-type"; +})(Headers = exports.Headers || (exports.Headers = {})); +var MediaTypes; +(function (MediaTypes) { + MediaTypes["ApplicationJson"] = "application/json"; +})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +function getProxyUrl(serverUrl) { + const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); + return proxyUrl ? proxyUrl.href : ''; +} +exports.getProxyUrl = getProxyUrl; +const HttpRedirectCodes = [ + HttpCodes.MovedPermanently, + HttpCodes.ResourceMoved, + HttpCodes.SeeOther, + HttpCodes.TemporaryRedirect, + HttpCodes.PermanentRedirect +]; +const HttpResponseRetryCodes = [ + HttpCodes.BadGateway, + HttpCodes.ServiceUnavailable, + HttpCodes.GatewayTimeout +]; +const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; +const ExponentialBackoffCeiling = 10; +const ExponentialBackoffTimeSlice = 5; +class HttpClientError extends Error { + constructor(message, statusCode) { + super(message); + this.name = 'HttpClientError'; + this.statusCode = statusCode; + Object.setPrototypeOf(this, HttpClientError.prototype); + } +} +exports.HttpClientError = HttpClientError; +class HttpClientResponse { + constructor(message) { + this.message = message; + } + readBody() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + let output = Buffer.alloc(0); + this.message.on('data', (chunk) => { + output = Buffer.concat([output, chunk]); + }); + this.message.on('end', () => { + resolve(output.toString()); + }); + })); + }); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + const parsedUrl = new URL(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + this._allowRedirectDowngrade = false; + this._maxRedirects = 50; + this._allowRetries = false; + this._maxRetries = 1; + this._keepAlive = false; + this._disposed = false; + this.userAgent = userAgent; + this.handlers = handlers || []; + this.requestOptions = requestOptions; + if (requestOptions) { + if (requestOptions.ignoreSslError != null) { + this._ignoreSslError = requestOptions.ignoreSslError; + } + this._socketTimeout = requestOptions.socketTimeout; + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + if (requestOptions.allowRedirectDowngrade != null) { + this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; + } + if (requestOptions.maxRedirects != null) { + this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); + } + if (requestOptions.keepAlive != null) { + this._keepAlive = requestOptions.keepAlive; + } + if (requestOptions.allowRetries != null) { + this._allowRetries = requestOptions.allowRetries; + } + if (requestOptions.maxRetries != null) { + this._maxRetries = requestOptions.maxRetries; + } + } + } + options(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); + }); + } + get(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('GET', requestUrl, null, additionalHeaders || {}); + }); + } + del(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('DELETE', requestUrl, null, additionalHeaders || {}); + }); + } + post(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('POST', requestUrl, data, additionalHeaders || {}); + }); + } + patch(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PATCH', requestUrl, data, additionalHeaders || {}); + }); + } + put(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PUT', requestUrl, data, additionalHeaders || {}); + }); + } + head(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('HEAD', requestUrl, null, additionalHeaders || {}); + }); + } + sendStream(verb, requestUrl, stream, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request(verb, requestUrl, stream, additionalHeaders); + }); + } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + getJson(requestUrl, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + const res = yield this.get(requestUrl, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + postJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.post(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + putJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.put(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + patchJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.patch(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb, requestUrl, data, headers) { + return __awaiter(this, void 0, void 0, function* () { + if (this._disposed) { + throw new Error('Client has already been disposed.'); + } + const parsedUrl = new URL(requestUrl); + let info = this._prepareRequest(verb, parsedUrl, headers); + // Only perform retries on reads since writes may not be idempotent. + const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) + ? this._maxRetries + 1 + : 1; + let numTries = 0; + let response; + do { + response = yield this.requestRaw(info, data); + // Check if it's an authentication challenge + if (response && + response.message && + response.message.statusCode === HttpCodes.Unauthorized) { + let authenticationHandler; + for (const handler of this.handlers) { + if (handler.canHandleAuthentication(response)) { + authenticationHandler = handler; + break; + } + } + if (authenticationHandler) { + return authenticationHandler.handleAuthentication(this, info, data); + } + else { + // We have received an unauthorized response but have no handlers to handle it. + // Let the response return to the caller. + return response; + } + } + let redirectsRemaining = this._maxRedirects; + while (response.message.statusCode && + HttpRedirectCodes.includes(response.message.statusCode) && + this._allowRedirects && + redirectsRemaining > 0) { + const redirectUrl = response.message.headers['location']; + if (!redirectUrl) { + // if there's no location to redirect to, we won't + break; + } + const parsedRedirectUrl = new URL(redirectUrl); + if (parsedUrl.protocol === 'https:' && + parsedUrl.protocol !== parsedRedirectUrl.protocol && + !this._allowRedirectDowngrade) { + throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + yield response.readBody(); + // strip authorization header if redirected to a different hostname + if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { + for (const header in headers) { + // header names are case insensitive + if (header.toLowerCase() === 'authorization') { + delete headers[header]; + } + } + } + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, parsedRedirectUrl, headers); + response = yield this.requestRaw(info, data); + redirectsRemaining--; + } + if (!response.message.statusCode || + !HttpResponseRetryCodes.includes(response.message.statusCode)) { + // If not a retry code, return immediately instead of retrying + return response; + } + numTries += 1; + if (numTries < maxTries) { + yield response.readBody(); + yield this._performExponentialBackoff(numTries); + } + } while (numTries < maxTries); + return response; + }); + } + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose() { + if (this._agent) { + this._agent.destroy(); + } + this._disposed = true; + } + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info, data) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + function callbackForResult(err, res) { + if (err) { + reject(err); + } + else if (!res) { + // If `err` is not passed, then `res` must be passed. + reject(new Error('Unknown error')); + } + else { + resolve(res); + } + } + this.requestRawWithCallback(info, data, callbackForResult); + }); + }); + } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info, data, onResult) { + if (typeof data === 'string') { + if (!info.options.headers) { + info.options.headers = {}; + } + info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + } + let callbackCalled = false; + function handleResult(err, res) { + if (!callbackCalled) { + callbackCalled = true; + onResult(err, res); + } + } + const req = info.httpModule.request(info.options, (msg) => { + const res = new HttpClientResponse(msg); + handleResult(undefined, res); + }); + let socket; + req.on('socket', sock => { + socket = sock; + }); + // If we ever get disconnected, we want the socket to timeout eventually + req.setTimeout(this._socketTimeout || 3 * 60000, () => { + if (socket) { + socket.end(); + } + handleResult(new Error(`Request timeout: ${info.options.path}`)); + }); + req.on('error', function (err) { + // err has statusCode property + // res should have headers + handleResult(err); + }); + if (data && typeof data === 'string') { + req.write(data, 'utf8'); + } + if (data && typeof data !== 'string') { + data.on('close', function () { + req.end(); + }); + data.pipe(req); + } + else { + req.end(); + } + } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl) { + const parsedUrl = new URL(serverUrl); + return this._getAgent(parsedUrl); + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = requestUrl; + const usingSsl = info.parsedUrl.protocol === 'https:'; + info.httpModule = usingSsl ? https : http; + const defaultPort = usingSsl ? 443 : 80; + info.options = {}; + info.options.host = info.parsedUrl.hostname; + info.options.port = info.parsedUrl.port + ? parseInt(info.parsedUrl.port) + : defaultPort; + info.options.path = + (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); + info.options.method = method; + info.options.headers = this._mergeHeaders(headers); + if (this.userAgent != null) { + info.options.headers['user-agent'] = this.userAgent; + } + info.options.agent = this._getAgent(info.parsedUrl); + // gives handlers an opportunity to participate + if (this.handlers) { + for (const handler of this.handlers) { + handler.prepareRequest(info.options); + } + } + return info; + } + _mergeHeaders(headers) { + if (this.requestOptions && this.requestOptions.headers) { + return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); + } + return lowercaseKeys(headers || {}); + } + _getExistingOrDefaultHeader(additionalHeaders, header, _default) { + let clientHeader; + if (this.requestOptions && this.requestOptions.headers) { + clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + _getAgent(parsedUrl) { + let agent; + const proxyUrl = pm.getProxyUrl(parsedUrl); + const useProxy = proxyUrl && proxyUrl.hostname; + if (this._keepAlive && useProxy) { + agent = this._proxyAgent; + } + if (this._keepAlive && !useProxy) { + agent = this._agent; + } + // if agent is already assigned use that agent. + if (agent) { + return agent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + let maxSockets = 100; + if (this.requestOptions) { + maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; + } + // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. + if (proxyUrl && proxyUrl.hostname) { + const agentOptions = { + maxSockets, + keepAlive: this._keepAlive, + proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { + proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` + })), { host: proxyUrl.hostname, port: proxyUrl.port }) + }; + let tunnelAgent; + const overHttps = proxyUrl.protocol === 'https:'; + if (usingSsl) { + tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; + } + else { + tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; + } + agent = tunnelAgent(agentOptions); + this._proxyAgent = agent; + } + // if reusing agent across request and tunneling agent isn't assigned create a new agent + if (this._keepAlive && !agent) { + const options = { keepAlive: this._keepAlive, maxSockets }; + agent = usingSsl ? new https.Agent(options) : new http.Agent(options); + this._agent = agent; + } + // if not using private agent and tunnel agent isn't setup then use global agent + if (!agent) { + agent = usingSsl ? https.globalAgent : http.globalAgent; + } + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + agent.options = Object.assign(agent.options || {}, { + rejectUnauthorized: false + }); + } + return agent; + } + _performExponentialBackoff(retryNumber) { + return __awaiter(this, void 0, void 0, function* () { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + }); + } + _processResponse(res, options) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + const statusCode = res.message.statusCode || 0; + const response = { + statusCode, + result: null, + headers: {} + }; + // not found leads to null obj returned + if (statusCode === HttpCodes.NotFound) { + resolve(response); + } + // get the result from the body + function dateTimeDeserializer(key, value) { + if (typeof value === 'string') { + const a = new Date(value); + if (!isNaN(a.valueOf())) { + return a; + } + } + return value; + } + let obj; + let contents; + try { + contents = yield res.readBody(); + if (contents && contents.length > 0) { + if (options && options.deserializeDates) { + obj = JSON.parse(contents, dateTimeDeserializer); + } + else { + obj = JSON.parse(contents); + } + response.result = obj; + } + response.headers = res.message.headers; + } + catch (err) { + // Invalid resource (contents not json); leaving result obj null + } + // note that 3xx redirects are handled by the http layer. + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + if (obj && obj.message) { + msg = obj.message; + } + else if (contents && contents.length > 0) { + // it may be the case that the exception is in the body message as string + msg = contents; + } + else { + msg = `Failed request: (${statusCode})`; + } + const err = new HttpClientError(msg, statusCode); + err.result = response.result; + reject(err); + } + else { + resolve(response); + } + })); + }); + } +} +exports.HttpClient = HttpClient; +const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/index.js.map b/node_modules/@actions/http-client/lib/index.js.map new file mode 100644 index 0000000..ca8ea41 --- /dev/null +++ b/node_modules/@actions/http-client/lib/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/interfaces.d.ts b/node_modules/@actions/http-client/lib/interfaces.d.ts new file mode 100644 index 0000000..54fd4a8 --- /dev/null +++ b/node_modules/@actions/http-client/lib/interfaces.d.ts @@ -0,0 +1,44 @@ +/// +import * as http from 'http'; +import * as https from 'https'; +import { HttpClientResponse } from './index'; +export interface HttpClient { + options(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + get(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + del(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + post(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + patch(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + put(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: http.OutgoingHttpHeaders): Promise; + request(verb: string, requestUrl: string, data: string | NodeJS.ReadableStream, headers: http.OutgoingHttpHeaders): Promise; + requestRaw(info: RequestInfo, data: string | NodeJS.ReadableStream): Promise; + requestRawWithCallback(info: RequestInfo, data: string | NodeJS.ReadableStream, onResult: (err?: Error, res?: HttpClientResponse) => void): void; +} +export interface RequestHandler { + prepareRequest(options: http.RequestOptions): void; + canHandleAuthentication(response: HttpClientResponse): boolean; + handleAuthentication(httpClient: HttpClient, requestInfo: RequestInfo, data: string | NodeJS.ReadableStream | null): Promise; +} +export interface RequestInfo { + options: http.RequestOptions; + parsedUrl: URL; + httpModule: typeof http | typeof https; +} +export interface RequestOptions { + headers?: http.OutgoingHttpHeaders; + socketTimeout?: number; + ignoreSslError?: boolean; + allowRedirects?: boolean; + allowRedirectDowngrade?: boolean; + maxRedirects?: number; + maxSockets?: number; + keepAlive?: boolean; + deserializeDates?: boolean; + allowRetries?: boolean; + maxRetries?: number; +} +export interface TypedResponse { + statusCode: number; + result: T | null; + headers: http.IncomingHttpHeaders; +} diff --git a/node_modules/@actions/http-client/lib/interfaces.js b/node_modules/@actions/http-client/lib/interfaces.js new file mode 100644 index 0000000..db91911 --- /dev/null +++ b/node_modules/@actions/http-client/lib/interfaces.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=interfaces.js.map \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/interfaces.js.map b/node_modules/@actions/http-client/lib/interfaces.js.map new file mode 100644 index 0000000..8fb5f7d --- /dev/null +++ b/node_modules/@actions/http-client/lib/interfaces.js.map @@ -0,0 +1 @@ +{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/proxy.d.ts b/node_modules/@actions/http-client/lib/proxy.d.ts new file mode 100644 index 0000000..4599865 --- /dev/null +++ b/node_modules/@actions/http-client/lib/proxy.d.ts @@ -0,0 +1,2 @@ +export declare function getProxyUrl(reqUrl: URL): URL | undefined; +export declare function checkBypass(reqUrl: URL): boolean; diff --git a/node_modules/@actions/http-client/lib/proxy.js b/node_modules/@actions/http-client/lib/proxy.js new file mode 100644 index 0000000..76abb72 --- /dev/null +++ b/node_modules/@actions/http-client/lib/proxy.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkBypass = exports.getProxyUrl = void 0; +function getProxyUrl(reqUrl) { + const usingSsl = reqUrl.protocol === 'https:'; + if (checkBypass(reqUrl)) { + return undefined; + } + const proxyVar = (() => { + if (usingSsl) { + return process.env['https_proxy'] || process.env['HTTPS_PROXY']; + } + else { + return process.env['http_proxy'] || process.env['HTTP_PROXY']; + } + })(); + if (proxyVar) { + return new URL(proxyVar); + } + else { + return undefined; + } +} +exports.getProxyUrl = getProxyUrl; +function checkBypass(reqUrl) { + if (!reqUrl.hostname) { + return false; + } + const reqHost = reqUrl.hostname; + if (isLoopbackAddress(reqHost)) { + return true; + } + const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; + if (!noProxy) { + return false; + } + // Determine the request port + let reqPort; + if (reqUrl.port) { + reqPort = Number(reqUrl.port); + } + else if (reqUrl.protocol === 'http:') { + reqPort = 80; + } + else if (reqUrl.protocol === 'https:') { + reqPort = 443; + } + // Format the request hostname and hostname with port + const upperReqHosts = [reqUrl.hostname.toUpperCase()]; + if (typeof reqPort === 'number') { + upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + } + // Compare request host against noproxy + for (const upperNoProxyItem of noProxy + .split(',') + .map(x => x.trim().toUpperCase()) + .filter(x => x)) { + if (upperNoProxyItem === '*' || + upperReqHosts.some(x => x === upperNoProxyItem || + x.endsWith(`.${upperNoProxyItem}`) || + (upperNoProxyItem.startsWith('.') && + x.endsWith(`${upperNoProxyItem}`)))) { + return true; + } + } + return false; +} +exports.checkBypass = checkBypass; +function isLoopbackAddress(host) { + const hostLower = host.toLowerCase(); + return (hostLower === 'localhost' || + hostLower.startsWith('127.') || + hostLower.startsWith('[::1]') || + hostLower.startsWith('[0:0:0:0:0:0:0:1]')); +} +//# sourceMappingURL=proxy.js.map \ No newline at end of file diff --git a/node_modules/@actions/http-client/lib/proxy.js.map b/node_modules/@actions/http-client/lib/proxy.js.map new file mode 100644 index 0000000..b820679 --- /dev/null +++ b/node_modules/@actions/http-client/lib/proxy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@actions/http-client/package.json b/node_modules/@actions/http-client/package.json new file mode 100644 index 0000000..7f5c8ec --- /dev/null +++ b/node_modules/@actions/http-client/package.json @@ -0,0 +1,48 @@ +{ + "name": "@actions/http-client", + "version": "2.1.0", + "description": "Actions Http Client", + "keywords": [ + "github", + "actions", + "http" + ], + "homepage": "https://github.com/actions/toolkit/tree/main/packages/http-client", + "license": "MIT", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib", + "!.DS_Store" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/actions/toolkit.git", + "directory": "packages/http-client" + }, + "scripts": { + "audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json", + "test": "echo \"Error: run tests from root\" && exit 1", + "build": "tsc", + "format": "prettier --write **/*.ts", + "format-check": "prettier --check **/*.ts", + "tsc": "tsc" + }, + "bugs": { + "url": "https://github.com/actions/toolkit/issues" + }, + "devDependencies": { + "@types/tunnel": "0.0.3", + "proxy": "^1.0.1" + }, + "dependencies": { + "tunnel": "^0.0.6" + } +} diff --git a/node_modules/isomorphic-unfetch/browser.js b/node_modules/isomorphic-unfetch/browser.js new file mode 100644 index 0000000..ed13eef --- /dev/null +++ b/node_modules/isomorphic-unfetch/browser.js @@ -0,0 +1 @@ +module.exports = self.fetch || (self.fetch = require('unfetch').default || require('unfetch')); diff --git a/node_modules/isomorphic-unfetch/index.d.ts b/node_modules/isomorphic-unfetch/index.d.ts new file mode 100644 index 0000000..39162e8 --- /dev/null +++ b/node_modules/isomorphic-unfetch/index.d.ts @@ -0,0 +1,19 @@ +import { + Body as NodeBody, + Headers as NodeHeaders, + Request as NodeRequest, + Response as NodeResponse, + RequestInit as NodeRequestInit +} from "node-fetch"; + +declare namespace unfetch { + export type IsomorphicHeaders = Headers | NodeHeaders; + export type IsomorphicBody = Body | NodeBody; + export type IsomorphicResponse = Response | NodeResponse; + export type IsomorphicRequest = Request | NodeRequest; + export type IsomorphicRequestInit = RequestInit | NodeRequestInit; +} + +declare const unfetch: typeof fetch; + +export default unfetch; diff --git a/node_modules/isomorphic-unfetch/index.js b/node_modules/isomorphic-unfetch/index.js new file mode 100644 index 0000000..dacdb66 --- /dev/null +++ b/node_modules/isomorphic-unfetch/index.js @@ -0,0 +1,6 @@ +function r(m){return m && m.default || m;} +module.exports = global.fetch = global.fetch || ( + typeof process=='undefined' ? r(require('unfetch')) : (function(url, opts) { + return r(require('node-fetch'))(String(url).replace(/^\/\//g,'https://'), opts); + }) +); diff --git a/node_modules/isomorphic-unfetch/package.json b/node_modules/isomorphic-unfetch/package.json new file mode 100644 index 0000000..03e53aa --- /dev/null +++ b/node_modules/isomorphic-unfetch/package.json @@ -0,0 +1,19 @@ +{ + "name": "isomorphic-unfetch", + "version": "3.1.0", + "description": "Switches between unfetch & node-fetch for client & server.", + "files": [ + "index.js", + "index.d.ts", + "browser.js" + ], + "license": "MIT", + "repository": "developit/unfetch", + "browser": "browser.js", + "main": "index.js", + "types": "index.d.ts", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } +} diff --git a/node_modules/isomorphic-unfetch/readme.md b/node_modules/isomorphic-unfetch/readme.md new file mode 100644 index 0000000..c190288 --- /dev/null +++ b/node_modules/isomorphic-unfetch/readme.md @@ -0,0 +1,53 @@ +# Isomorphic Unfetch + +Switches between [unfetch](https://github.com/developit/unfetch) & [node-fetch](https://github.com/bitinn/node-fetch) for client & server. + +## Install + +This project uses [node](http://nodejs.org) and [npm](https://npmjs.com). Go check them out if you don't have them locally installed. + +```sh +$ npm i isomorphic-unfetch +``` + +Then with a module bundler like [rollup](http://rollupjs.org/) or [webpack](https://webpack.js.org/), use as you would anything else: + +```javascript +// using ES6 modules +import fetch from 'isomorphic-unfetch' + +// using CommonJS modules +const fetch = require('isomorphic-unfetch') +``` + +## Usage + +As a [**ponyfill**](https://ponyfill.com): + +```js +import fetch from 'isomorphic-unfetch'; + +fetch('/foo.json') + .then( r => r.json() ) + .then( data => { + console.log(data); + }); +``` + +Globally, as a [**polyfill**](https://ponyfill.com/#polyfill): + +```js +import 'isomorphic-unfetch'; + +// "fetch" is now installed globally if it wasn't already available + +fetch('/foo.json') + .then( r => r.json() ) + .then( data => { + console.log(data); + }); +``` + +## License + +[MIT License](LICENSE.md) © [Jason Miller](https://jasonformat.com/) diff --git a/node_modules/node-fetch/LICENSE.md b/node_modules/node-fetch/LICENSE.md new file mode 100644 index 0000000..660ffec --- /dev/null +++ b/node_modules/node-fetch/LICENSE.md @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 David Frank + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/node-fetch/README.md b/node_modules/node-fetch/README.md new file mode 100644 index 0000000..4f87a59 --- /dev/null +++ b/node_modules/node-fetch/README.md @@ -0,0 +1,633 @@ +node-fetch +========== + +[![npm version][npm-image]][npm-url] +[![build status][travis-image]][travis-url] +[![coverage status][codecov-image]][codecov-url] +[![install size][install-size-image]][install-size-url] +[![Discord][discord-image]][discord-url] + +A light-weight module that brings `window.fetch` to Node.js + +(We are looking for [v2 maintainers and collaborators](https://github.com/bitinn/node-fetch/issues/567)) + +[![Backers][opencollective-image]][opencollective-url] + + + +- [Motivation](#motivation) +- [Features](#features) +- [Difference from client-side fetch](#difference-from-client-side-fetch) +- [Installation](#installation) +- [Loading and configuring the module](#loading-and-configuring-the-module) +- [Common Usage](#common-usage) + - [Plain text or HTML](#plain-text-or-html) + - [JSON](#json) + - [Simple Post](#simple-post) + - [Post with JSON](#post-with-json) + - [Post with form parameters](#post-with-form-parameters) + - [Handling exceptions](#handling-exceptions) + - [Handling client and server errors](#handling-client-and-server-errors) +- [Advanced Usage](#advanced-usage) + - [Streams](#streams) + - [Buffer](#buffer) + - [Accessing Headers and other Meta data](#accessing-headers-and-other-meta-data) + - [Extract Set-Cookie Header](#extract-set-cookie-header) + - [Post data using a file stream](#post-data-using-a-file-stream) + - [Post with form-data (detect multipart)](#post-with-form-data-detect-multipart) + - [Request cancellation with AbortSignal](#request-cancellation-with-abortsignal) +- [API](#api) + - [fetch(url[, options])](#fetchurl-options) + - [Options](#options) + - [Class: Request](#class-request) + - [Class: Response](#class-response) + - [Class: Headers](#class-headers) + - [Interface: Body](#interface-body) + - [Class: FetchError](#class-fetcherror) +- [License](#license) +- [Acknowledgement](#acknowledgement) + + + +## Motivation + +Instead of implementing `XMLHttpRequest` in Node.js to run browser-specific [Fetch polyfill](https://github.com/github/fetch), why not go from native `http` to `fetch` API directly? Hence, `node-fetch`, minimal code for a `window.fetch` compatible API on Node.js runtime. + +See Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) or Leonardo Quixada's [cross-fetch](https://github.com/lquixada/cross-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side). + +## Features + +- Stay consistent with `window.fetch` API. +- Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences. +- Use native promise but allow substituting it with [insert your favorite promise library]. +- Use native Node streams for body on both request and response. +- Decode content encoding (gzip/deflate) properly and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically. +- Useful extensions such as timeout, redirect limit, response size limit, [explicit errors](ERROR-HANDLING.md) for troubleshooting. + +## Difference from client-side fetch + +- See [Known Differences](LIMITS.md) for details. +- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue. +- Pull requests are welcomed too! + +## Installation + +Current stable release (`2.x`) + +```sh +$ npm install node-fetch +``` + +## Loading and configuring the module +We suggest you load the module via `require` until the stabilization of ES modules in node: +```js +const fetch = require('node-fetch'); +``` + +If you are using a Promise library other than native, set it through `fetch.Promise`: +```js +const Bluebird = require('bluebird'); + +fetch.Promise = Bluebird; +``` + +## Common Usage + +NOTE: The documentation below is up-to-date with `2.x` releases; see the [`1.x` readme](https://github.com/bitinn/node-fetch/blob/1.x/README.md), [changelog](https://github.com/bitinn/node-fetch/blob/1.x/CHANGELOG.md) and [2.x upgrade guide](UPGRADE-GUIDE.md) for the differences. + +#### Plain text or HTML +```js +fetch('https://github.com/') + .then(res => res.text()) + .then(body => console.log(body)); +``` + +#### JSON + +```js + +fetch('https://api.github.com/users/github') + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Simple Post +```js +fetch('https://httpbin.org/post', { method: 'POST', body: 'a=1' }) + .then(res => res.json()) // expecting a json response + .then(json => console.log(json)); +``` + +#### Post with JSON + +```js +const body = { a: 1 }; + +fetch('https://httpbin.org/post', { + method: 'post', + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Post with form parameters +`URLSearchParams` is available in Node.js as of v7.5.0. See [official documentation](https://nodejs.org/api/url.html#url_class_urlsearchparams) for more usage methods. + +NOTE: The `Content-Type` header is only set automatically to `x-www-form-urlencoded` when an instance of `URLSearchParams` is given as such: + +```js +const { URLSearchParams } = require('url'); + +const params = new URLSearchParams(); +params.append('a', 1); + +fetch('https://httpbin.org/post', { method: 'POST', body: params }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Handling exceptions +NOTE: 3xx-5xx responses are *NOT* exceptions and should be handled in `then()`; see the next section for more information. + +Adding a catch to the fetch promise chain will catch *all* exceptions, such as errors originating from node core libraries, network errors and operational errors, which are instances of FetchError. See the [error handling document](ERROR-HANDLING.md) for more details. + +```js +fetch('https://domain.invalid/') + .catch(err => console.error(err)); +``` + +#### Handling client and server errors +It is common to create a helper function to check that the response contains no client (4xx) or server (5xx) error responses: + +```js +function checkStatus(res) { + if (res.ok) { // res.status >= 200 && res.status < 300 + return res; + } else { + throw MyCustomError(res.statusText); + } +} + +fetch('https://httpbin.org/status/400') + .then(checkStatus) + .then(res => console.log('will not get here...')) +``` + +## Advanced Usage + +#### Streams +The "Node.js way" is to use streams when possible: + +```js +fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') + .then(res => { + const dest = fs.createWriteStream('./octocat.png'); + res.body.pipe(dest); + }); +``` + +In Node.js 14 you can also use async iterators to read `body`; however, be careful to catch +errors -- the longer a response runs, the more likely it is to encounter an error. + +```js +const fetch = require('node-fetch'); +const response = await fetch('https://httpbin.org/stream/3'); +try { + for await (const chunk of response.body) { + console.dir(JSON.parse(chunk.toString())); + } +} catch (err) { + console.error(err.stack); +} +``` + +In Node.js 12 you can also use async iterators to read `body`; however, async iterators with streams +did not mature until Node.js 14, so you need to do some extra work to ensure you handle errors +directly from the stream and wait on it response to fully close. + +```js +const fetch = require('node-fetch'); +const read = async body => { + let error; + body.on('error', err => { + error = err; + }); + for await (const chunk of body) { + console.dir(JSON.parse(chunk.toString())); + } + return new Promise((resolve, reject) => { + body.on('close', () => { + error ? reject(error) : resolve(); + }); + }); +}; +try { + const response = await fetch('https://httpbin.org/stream/3'); + await read(response.body); +} catch (err) { + console.error(err.stack); +} +``` + +#### Buffer +If you prefer to cache binary data in full, use buffer(). (NOTE: `buffer()` is a `node-fetch`-only API) + +```js +const fileType = require('file-type'); + +fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') + .then(res => res.buffer()) + .then(buffer => fileType(buffer)) + .then(type => { /* ... */ }); +``` + +#### Accessing Headers and other Meta data +```js +fetch('https://github.com/') + .then(res => { + console.log(res.ok); + console.log(res.status); + console.log(res.statusText); + console.log(res.headers.raw()); + console.log(res.headers.get('content-type')); + }); +``` + +#### Extract Set-Cookie Header + +Unlike browsers, you can access raw `Set-Cookie` headers manually using `Headers.raw()`. This is a `node-fetch` only API. + +```js +fetch(url).then(res => { + // returns an array of values, instead of a string of comma-separated values + console.log(res.headers.raw()['set-cookie']); +}); +``` + +#### Post data using a file stream + +```js +const { createReadStream } = require('fs'); + +const stream = createReadStream('input.txt'); + +fetch('https://httpbin.org/post', { method: 'POST', body: stream }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Post with form-data (detect multipart) + +```js +const FormData = require('form-data'); + +const form = new FormData(); +form.append('a', 1); + +fetch('https://httpbin.org/post', { method: 'POST', body: form }) + .then(res => res.json()) + .then(json => console.log(json)); + +// OR, using custom headers +// NOTE: getHeaders() is non-standard API + +const form = new FormData(); +form.append('a', 1); + +const options = { + method: 'POST', + body: form, + headers: form.getHeaders() +} + +fetch('https://httpbin.org/post', options) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Request cancellation with AbortSignal + +> NOTE: You may cancel streamed requests only on Node >= v8.0.0 + +You may cancel requests with `AbortController`. A suggested implementation is [`abort-controller`](https://www.npmjs.com/package/abort-controller). + +An example of timing out a request after 150ms could be achieved as the following: + +```js +import AbortController from 'abort-controller'; + +const controller = new AbortController(); +const timeout = setTimeout( + () => { controller.abort(); }, + 150, +); + +fetch(url, { signal: controller.signal }) + .then(res => res.json()) + .then( + data => { + useData(data) + }, + err => { + if (err.name === 'AbortError') { + // request was aborted + } + }, + ) + .finally(() => { + clearTimeout(timeout); + }); +``` + +See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples. + + +## API + +### fetch(url[, options]) + +- `url` A string representing the URL for fetching +- `options` [Options](#fetch-options) for the HTTP(S) request +- Returns: Promise<[Response](#class-response)> + +Perform an HTTP(S) fetch. + +`url` should be an absolute url, such as `https://example.com/`. A path-relative URL (`/file/under/root`) or protocol-relative URL (`//can-be-http-or-https.com/`) will result in a rejected `Promise`. + + +### Options + +The default values are shown after each option key. + +```js +{ + // These properties are part of the Fetch Standard + method: 'GET', + headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below) + body: null, // request body. can be null, a string, a Buffer, a Blob, or a Node.js Readable stream + redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect + signal: null, // pass an instance of AbortSignal to optionally abort requests + + // The following properties are node-fetch extensions + follow: 20, // maximum redirect count. 0 to not follow redirect + timeout: 0, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead. + compress: true, // support gzip/deflate content encoding. false to disable + size: 0, // maximum response body size in bytes. 0 to disable + agent: null // http(s).Agent instance or function that returns an instance (see below) +} +``` + +##### Default Headers + +If no values are set, the following request headers will be sent automatically: + +Header | Value +------------------- | -------------------------------------------------------- +`Accept-Encoding` | `gzip,deflate` _(when `options.compress === true`)_ +`Accept` | `*/*` +`Connection` | `close` _(when no `options.agent` is present)_ +`Content-Length` | _(automatically calculated, if possible)_ +`Transfer-Encoding` | `chunked` _(when `req.body` is a stream)_ +`User-Agent` | `node-fetch/1.0 (+https://github.com/bitinn/node-fetch)` + +Note: when `body` is a `Stream`, `Content-Length` is not set automatically. + +##### Custom Agent + +The `agent` option allows you to specify networking related options which are out of the scope of Fetch, including and not limited to the following: + +- Support self-signed certificate +- Use only IPv4 or IPv6 +- Custom DNS Lookup + +See [`http.Agent`](https://nodejs.org/api/http.html#http_new_agent_options) for more information. + +In addition, the `agent` option accepts a function that returns `http`(s)`.Agent` instance given current [URL](https://nodejs.org/api/url.html), this is useful during a redirection chain across HTTP and HTTPS protocol. + +```js +const httpAgent = new http.Agent({ + keepAlive: true +}); +const httpsAgent = new https.Agent({ + keepAlive: true +}); + +const options = { + agent: function (_parsedURL) { + if (_parsedURL.protocol == 'http:') { + return httpAgent; + } else { + return httpsAgent; + } + } +} +``` + + +### Class: Request + +An HTTP(S) request containing information about URL, method, headers, and the body. This class implements the [Body](#iface-body) interface. + +Due to the nature of Node.js, the following properties are not implemented at this moment: + +- `type` +- `destination` +- `referrer` +- `referrerPolicy` +- `mode` +- `credentials` +- `cache` +- `integrity` +- `keepalive` + +The following node-fetch extension properties are provided: + +- `follow` +- `compress` +- `counter` +- `agent` + +See [options](#fetch-options) for exact meaning of these extensions. + +#### new Request(input[, options]) + +*(spec-compliant)* + +- `input` A string representing a URL, or another `Request` (which will be cloned) +- `options` [Options][#fetch-options] for the HTTP(S) request + +Constructs a new `Request` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request). + +In most cases, directly `fetch(url, options)` is simpler than creating a `Request` object. + + +### Class: Response + +An HTTP(S) response. This class implements the [Body](#iface-body) interface. + +The following properties are not implemented in node-fetch at this moment: + +- `Response.error()` +- `Response.redirect()` +- `type` +- `trailer` + +#### new Response([body[, options]]) + +*(spec-compliant)* + +- `body` A `String` or [`Readable` stream][node-readable] +- `options` A [`ResponseInit`][response-init] options dictionary + +Constructs a new `Response` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response). + +Because Node.js does not implement service workers (for which this class was designed), one rarely has to construct a `Response` directly. + +#### response.ok + +*(spec-compliant)* + +Convenience property representing if the request ended normally. Will evaluate to true if the response status was greater than or equal to 200 but smaller than 300. + +#### response.redirected + +*(spec-compliant)* + +Convenience property representing if the request has been redirected at least once. Will evaluate to true if the internal redirect counter is greater than 0. + + +### Class: Headers + +This class allows manipulating and iterating over a set of HTTP headers. All methods specified in the [Fetch Standard][whatwg-fetch] are implemented. + +#### new Headers([init]) + +*(spec-compliant)* + +- `init` Optional argument to pre-fill the `Headers` object + +Construct a new `Headers` object. `init` can be either `null`, a `Headers` object, an key-value map object or any iterable object. + +```js +// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class + +const meta = { + 'Content-Type': 'text/xml', + 'Breaking-Bad': '<3' +}; +const headers = new Headers(meta); + +// The above is equivalent to +const meta = [ + [ 'Content-Type', 'text/xml' ], + [ 'Breaking-Bad', '<3' ] +]; +const headers = new Headers(meta); + +// You can in fact use any iterable objects, like a Map or even another Headers +const meta = new Map(); +meta.set('Content-Type', 'text/xml'); +meta.set('Breaking-Bad', '<3'); +const headers = new Headers(meta); +const copyOfHeaders = new Headers(headers); +``` + + +### Interface: Body + +`Body` is an abstract interface with methods that are applicable to both `Request` and `Response` classes. + +The following methods are not yet implemented in node-fetch at this moment: + +- `formData()` + +#### body.body + +*(deviation from spec)* + +* Node.js [`Readable` stream][node-readable] + +Data are encapsulated in the `Body` object. Note that while the [Fetch Standard][whatwg-fetch] requires the property to always be a WHATWG `ReadableStream`, in node-fetch it is a Node.js [`Readable` stream][node-readable]. + +#### body.bodyUsed + +*(spec-compliant)* + +* `Boolean` + +A boolean property for if this body has been consumed. Per the specs, a consumed body cannot be used again. + +#### body.arrayBuffer() +#### body.blob() +#### body.json() +#### body.text() + +*(spec-compliant)* + +* Returns: Promise + +Consume the body and return a promise that will resolve to one of these formats. + +#### body.buffer() + +*(node-fetch extension)* + +* Returns: Promise<Buffer> + +Consume the body and return a promise that will resolve to a Buffer. + +#### body.textConverted() + +*(node-fetch extension)* + +* Returns: Promise<String> + +Identical to `body.text()`, except instead of always converting to UTF-8, encoding sniffing will be performed and text converted to UTF-8 if possible. + +(This API requires an optional dependency of the npm package [encoding](https://www.npmjs.com/package/encoding), which you need to install manually. `webpack` users may see [a warning message](https://github.com/bitinn/node-fetch/issues/412#issuecomment-379007792) due to this optional dependency.) + + +### Class: FetchError + +*(node-fetch extension)* + +An operational error in the fetching process. See [ERROR-HANDLING.md][] for more info. + + +### Class: AbortError + +*(node-fetch extension)* + +An Error thrown when the request is aborted in response to an `AbortSignal`'s `abort` event. It has a `name` property of `AbortError`. See [ERROR-HANDLING.MD][] for more info. + +## Acknowledgement + +Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference. + +`node-fetch` v1 was maintained by [@bitinn](https://github.com/bitinn); v2 was maintained by [@TimothyGu](https://github.com/timothygu), [@bitinn](https://github.com/bitinn) and [@jimmywarting](https://github.com/jimmywarting); v2 readme is written by [@jkantr](https://github.com/jkantr). + +## License + +MIT + +[npm-image]: https://flat.badgen.net/npm/v/node-fetch +[npm-url]: https://www.npmjs.com/package/node-fetch +[travis-image]: https://flat.badgen.net/travis/bitinn/node-fetch +[travis-url]: https://travis-ci.org/bitinn/node-fetch +[codecov-image]: https://flat.badgen.net/codecov/c/github/bitinn/node-fetch/master +[codecov-url]: https://codecov.io/gh/bitinn/node-fetch +[install-size-image]: https://flat.badgen.net/packagephobia/install/node-fetch +[install-size-url]: https://packagephobia.now.sh/result?p=node-fetch +[discord-image]: https://img.shields.io/discord/619915844268326952?color=%237289DA&label=Discord&style=flat-square +[discord-url]: https://discord.gg/Zxbndcm +[opencollective-image]: https://opencollective.com/node-fetch/backers.svg +[opencollective-url]: https://opencollective.com/node-fetch +[whatwg-fetch]: https://fetch.spec.whatwg.org/ +[response-init]: https://fetch.spec.whatwg.org/#responseinit +[node-readable]: https://nodejs.org/api/stream.html#stream_readable_streams +[mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers +[LIMITS.md]: https://github.com/bitinn/node-fetch/blob/master/LIMITS.md +[ERROR-HANDLING.md]: https://github.com/bitinn/node-fetch/blob/master/ERROR-HANDLING.md +[UPGRADE-GUIDE.md]: https://github.com/bitinn/node-fetch/blob/master/UPGRADE-GUIDE.md diff --git a/node_modules/node-fetch/browser.js b/node_modules/node-fetch/browser.js new file mode 100644 index 0000000..ee86265 --- /dev/null +++ b/node_modules/node-fetch/browser.js @@ -0,0 +1,25 @@ +"use strict"; + +// ref: https://github.com/tc39/proposal-global +var getGlobal = function () { + // the only reliable means to get the global object is + // `Function('return this')()` + // However, this causes CSP violations in Chrome apps. + if (typeof self !== 'undefined') { return self; } + if (typeof window !== 'undefined') { return window; } + if (typeof global !== 'undefined') { return global; } + throw new Error('unable to locate global object'); +} + +var globalObject = getGlobal(); + +module.exports = exports = globalObject.fetch; + +// Needed for TypeScript and Webpack. +if (globalObject.fetch) { + exports.default = globalObject.fetch.bind(globalObject); +} + +exports.Headers = globalObject.Headers; +exports.Request = globalObject.Request; +exports.Response = globalObject.Response; diff --git a/node_modules/node-fetch/lib/index.es.js b/node_modules/node-fetch/lib/index.es.js new file mode 100644 index 0000000..79d717b --- /dev/null +++ b/node_modules/node-fetch/lib/index.es.js @@ -0,0 +1,1778 @@ +process.emitWarning("The .es.js file is deprecated. Use .mjs instead."); + +import Stream from 'stream'; +import http from 'http'; +import Url from 'url'; +import whatwgUrl from 'whatwg-url'; +import https from 'https'; +import zlib from 'zlib'; + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +export default fetch; +export { Headers, Request, Response, FetchError }; diff --git a/node_modules/node-fetch/lib/index.js b/node_modules/node-fetch/lib/index.js new file mode 100644 index 0000000..337d6e5 --- /dev/null +++ b/node_modules/node-fetch/lib/index.js @@ -0,0 +1,1787 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var Stream = _interopDefault(require('stream')); +var http = _interopDefault(require('http')); +var Url = _interopDefault(require('url')); +var whatwgUrl = _interopDefault(require('whatwg-url')); +var https = _interopDefault(require('https')); +var zlib = _interopDefault(require('zlib')); + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; diff --git a/node_modules/node-fetch/lib/index.mjs b/node_modules/node-fetch/lib/index.mjs new file mode 100644 index 0000000..ace669f --- /dev/null +++ b/node_modules/node-fetch/lib/index.mjs @@ -0,0 +1,1776 @@ +import Stream from 'stream'; +import http from 'http'; +import Url from 'url'; +import whatwgUrl from 'whatwg-url'; +import https from 'https'; +import zlib from 'zlib'; + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +export default fetch; +export { Headers, Request, Response, FetchError }; diff --git a/node_modules/node-fetch/package.json b/node_modules/node-fetch/package.json new file mode 100644 index 0000000..177e847 --- /dev/null +++ b/node_modules/node-fetch/package.json @@ -0,0 +1,89 @@ +{ + "name": "node-fetch", + "version": "2.6.9", + "description": "A light-weight module that brings window.fetch to node.js", + "main": "lib/index.js", + "browser": "./browser.js", + "module": "lib/index.mjs", + "files": [ + "lib/index.js", + "lib/index.mjs", + "lib/index.es.js", + "browser.js" + ], + "engines": { + "node": "4.x || >=6.0.0" + }, + "scripts": { + "build": "cross-env BABEL_ENV=rollup rollup -c", + "prepare": "npm run build", + "test": "cross-env BABEL_ENV=test mocha --require babel-register --throw-deprecation test/test.js", + "report": "cross-env BABEL_ENV=coverage nyc --reporter lcov --reporter text mocha -R spec test/test.js", + "coverage": "cross-env BABEL_ENV=coverage nyc --reporter json --reporter text mocha -R spec test/test.js && codecov -f coverage/coverage-final.json" + }, + "repository": { + "type": "git", + "url": "https://github.com/bitinn/node-fetch.git" + }, + "keywords": [ + "fetch", + "http", + "promise" + ], + "author": "David Frank", + "license": "MIT", + "bugs": { + "url": "https://github.com/bitinn/node-fetch/issues" + }, + "homepage": "https://github.com/bitinn/node-fetch", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + }, + "devDependencies": { + "@ungap/url-search-params": "^0.1.2", + "abort-controller": "^1.1.0", + "abortcontroller-polyfill": "^1.3.0", + "babel-core": "^6.26.3", + "babel-plugin-istanbul": "^4.1.6", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-polyfill": "^6.26.0", + "babel-preset-env": "1.4.0", + "babel-register": "^6.16.3", + "chai": "^3.5.0", + "chai-as-promised": "^7.1.1", + "chai-iterator": "^1.1.1", + "chai-string": "~1.3.0", + "codecov": "3.3.0", + "cross-env": "^5.2.0", + "form-data": "^2.3.3", + "is-builtin-module": "^1.0.0", + "mocha": "^5.0.0", + "nyc": "11.9.0", + "parted": "^0.1.1", + "promise": "^8.0.3", + "resumer": "0.0.0", + "rollup": "^0.63.4", + "rollup-plugin-babel": "^3.0.7", + "string-to-arraybuffer": "^1.0.2", + "teeny-request": "3.7.0" + }, + "release": { + "branches": [ + "+([0-9]).x", + "main", + "next", + { + "name": "beta", + "prerelease": true + } + ] + } +} diff --git a/node_modules/psn-api/LICENSE.md b/node_modules/psn-api/LICENSE.md new file mode 100644 index 0000000..2ebed16 --- /dev/null +++ b/node_modules/psn-api/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Wes Copeland. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/psn-api/README.md b/node_modules/psn-api/README.md new file mode 100644 index 0000000..3ff7142 --- /dev/null +++ b/node_modules/psn-api/README.md @@ -0,0 +1,178 @@ +

psn-api

+ +

+ +

+ A JavaScript library that lets you get trophy, user, and game data from the PlayStation Network. +

+

+ +

+ Documentation: Get Started +
+

+ +

+ + Styled with Prettier + + + + Semantic Release + + + + + + + + + +

+ +
+ +## Features + +✅  Modular by design, and supports tree-shaking. +✅  Aligns with the [community API documentation](https://andshrew.github.io/PlayStation-Trophies/#/). +✅  Supports Node environments (14 and above). +✅  Supports browsers. +✅  Ships with TypeScript support and types. +✅  Small, <5Kb. + +
+ +## Documentation + +Learn how to authenticate and start pulling data from the PlayStation Network on our documentation website. + +- [Get started](https://psn-api.achievements.app/get-started) +- [How to authenticate](https://psn-api.achievements.app/authentication/authenticating-manually) +- [Get all trophies for a game](https://psn-api.achievements.app/api-docs/title-trophies#gettitletrophies) +- [Search for a user](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) + +## Installation + +Run the following command: + +```bash +npm install psn-api +``` + +## How to obtain an authentication token + +To use any endpoint function in the API, you must first be authorized by PSN. Fortunately, this is a fairly straightforward process. + +1. In your web browser, visit [https://www.playstation.com/](https://www.playstation.com/), click the "Sign In" button, and log in with a PSN account. + +2. In the same browser (due to a persisted cookie), visit [https://ca.account.sony.com/api/v1/ssocookie](https://ca.account.sony.com/api/v1/ssocookie). You will see a JSON response that looks something like: + +```js +{ "npsso": "<64 character token>" } +``` + +Copy your NPSSO. **Do not expose it anywhere publicly, it is equivalent to your password.** + +If you see an error response, try using different browser. + +3. You can now obtain an authentication token using your NPSSO with the following function calls from this package. + +```ts +// This is the value you copied from the previous step. +const myNpsso = "<64 character token>"; + +// We'll exchange your NPSSO for a special access code. +const accessCode = await exchangeNpssoForCode(npsso); + +// We can use the access code to get your access token and refresh token. +const authorization = await exchangeCodeForAccessToken(accessCode); +``` + +4. You should now be all set to use any endpoint provided by this package. Each function requires as its first argument an object containing your access token. ex: + +```ts +const authorization = await exchangeCodeForAccessToken(accessCode); + +// This returns a list of all the games you've earned trophies for. +const trophyTitlesResponse = await getUserTitles( + { accessToken: authorization.accessToken }, + "me" +); +``` + +## API + +Click the function names to open their complete docs on the docs site. + +### Authentication + +- [`exchangeCodeForAccessToken()`](https://psn-api.achievements.app/api-docs/authentication#exchangecodeforaccesstoken) - Exchange your access code for access and refresh tokens. +- [`exchangeNpssoForCode()`](https://psn-api.achievements.app/api-docs/authentication#exchangenpssoforcode) - Exchange your NPSSO for an access code. +- [`exchangeRefreshTokenForAuthTokens()`](https://psn-api.achievements.app/api-docs/authentication#exchangerefreshtokenforauthtokens) - Get a new access token using your refresh token (bypassing the need to constantly auth with your NPSSO). + +### Search + +- [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) - Search the PSN API. This is a good way to find a user's `accountId` from their username. + +### Users + +- [`getProfileFromUserName()`](https://psn-api.achievements.app/api-docs/users#getprofilefromusername) - Get a user's legacy profile from the username. Often used to check for legacy presence. +- [`getProfileFromAccountId()`](https://psn-api.achievements.app/api-docs/users#getprofilefromaccountid) - Get a user's profile from the `accountId`. +- [`getUserFriendsAccountIds()`](https://psn-api.achievements.app/api-docs/users#getuserfriendsaccountids) - Get a list of `accountId` values present on a target account's friends list. + +### Trophies + +- [`getTitleTrophies()`](https://psn-api.achievements.app/api-docs/title-trophies#gettitletrophies) - Retrieve the individual trophy details of a single or all trophy groups for a title. +- [`getTitleTrophyGroups()`](https://psn-api.achievements.app/api-docs/title-trophies#gettitletrophygroups) - Get a list of trophy groups (typically the base set and DLCs) for a title. +- [`getUserTitles()`](https://psn-api.achievements.app/api-docs/user-trophies#getusertitles) - Retrieve a list of the titles associated with an account and a summary of trophies earned from them. +- [`getUserTrophiesEarnedForTitle()`](https://psn-api.achievements.app/api-docs/user-trophies#getusertrophiesearnedfortitle) - Retrieve the earned status of trophies for a user from either a single or all trophy groups in a title. +- [`getUserTrophyGroupEarningsForTitle()`](https://psn-api.achievements.app/api-docs/user-trophies#getusertrophygroupearningsfortitle) - Get a summary of trophies earned for a user broken down by trophy group within a title. +- [`getUserTrophyProfileSummary()`](https://psn-api.achievements.app/api-docs/user-trophies#getusertrophyprofilesummary) - Retrieve an overall summary of the number of trophies earned for a user broken down by type. +- [`getRecentlyPlayedGames()`](https://psn-api.achievements.app/api-docs/users#getrecentlyplayedgames) - Retrieve a list of recently played games for the user associated with the access token provided to this function. + +## Examples + +- [Build a user's complete trophy list and write it to a JSON file](https://psn-api.achievements.app/examples/user-trophy-list) + +## Projects Using psn-api + +- [PS5 MQTT](https://github.com/FunkeyFlo/ps5-mqtt) - Integrate your PlayStation 5 with Home Assistant. +- [evanshortiss/README.md](https://github.com/evanshortiss/evanshortiss) - Auto-updating GitHub bio with recently played games list. + +## Prior Art + +- [Tustin/psn-php](https://github.com/Tustin/psn-php) - A high-level PHP wrapper for the PSN API. +- [isFakeAccount/psnawp](https://github.com/isFakeAccount/psnawp) - A high-level Python wrapper for the PSN API. +- [andshrew/PlayStation-Trophies](https://github.com/andshrew/PlayStation-Trophies/) - an attempt at documenting the PSN API by capturing the requests made by the PlayStation website. + +## Disclaimer + +This project is not intended to be used for spam or abuse. Please use this project to elevate the PlayStation Network experience, not damage it. + +## Contributors + + + + + + + + + + + + + + + + + + + +
Wes Copeland
Wes Copeland

💻 💡 📖
xelnia
xelnia

🤔 📓
andshrew
andshrew

📖
Susan Ma
Susan Ma

📖
Travis Roy
Travis Roy

💻 💡 📖
Yetu
Yetu

💻
Yoshikage Kira
Yoshikage Kira

📖
Evan Shortiss
Evan Shortiss

💻 📖
+ + + + + diff --git a/node_modules/psn-api/dist/authenticate/AUTH_BASE_URL.d.ts b/node_modules/psn-api/dist/authenticate/AUTH_BASE_URL.d.ts new file mode 100644 index 0000000..8558e63 --- /dev/null +++ b/node_modules/psn-api/dist/authenticate/AUTH_BASE_URL.d.ts @@ -0,0 +1 @@ +export declare const AUTH_BASE_URL = "https://ca.account.sony.com/api/authz/v3/oauth"; diff --git a/node_modules/psn-api/dist/authenticate/exchangeCodeForAccessToken.d.ts b/node_modules/psn-api/dist/authenticate/exchangeCodeForAccessToken.d.ts new file mode 100644 index 0000000..b30fc93 --- /dev/null +++ b/node_modules/psn-api/dist/authenticate/exchangeCodeForAccessToken.d.ts @@ -0,0 +1,6 @@ +import type { AuthTokensResponse } from "../models"; +/** + * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`. + * @returns An object containing an access token, refresh token, and expiry times for both. + */ +export declare const exchangeCodeForAccessToken: (accessCode: string) => Promise; diff --git a/node_modules/psn-api/dist/authenticate/exchangeNpssoForCode.d.ts b/node_modules/psn-api/dist/authenticate/exchangeNpssoForCode.d.ts new file mode 100644 index 0000000..3fc495f --- /dev/null +++ b/node_modules/psn-api/dist/authenticate/exchangeNpssoForCode.d.ts @@ -0,0 +1,12 @@ +/** + * + * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie + * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`. + * @example + * ```ts + * const code = await exchangeNpssoForCode("myNpssoToken"); + * + * console.log(code) // --> "v3.XXXXXX" + * ``` + */ +export declare const exchangeNpssoForCode: (npssoToken: string) => Promise; diff --git a/node_modules/psn-api/dist/authenticate/exchangeRefreshTokenForAuthTokens.d.ts b/node_modules/psn-api/dist/authenticate/exchangeRefreshTokenForAuthTokens.d.ts new file mode 100644 index 0000000..3a3b306 --- /dev/null +++ b/node_modules/psn-api/dist/authenticate/exchangeRefreshTokenForAuthTokens.d.ts @@ -0,0 +1,2 @@ +import type { AuthTokensResponse } from "../models"; +export declare const exchangeRefreshTokenForAuthTokens: (refreshToken: string) => Promise; diff --git a/node_modules/psn-api/dist/authenticate/index.d.ts b/node_modules/psn-api/dist/authenticate/index.d.ts new file mode 100644 index 0000000..961eeec --- /dev/null +++ b/node_modules/psn-api/dist/authenticate/index.d.ts @@ -0,0 +1,3 @@ +export * from "./exchangeCodeForAccessToken"; +export * from "./exchangeNpssoForCode"; +export * from "./exchangeRefreshTokenForAuthTokens"; diff --git a/node_modules/psn-api/dist/graphql/GRAPHQL_BASE_URL.d.ts b/node_modules/psn-api/dist/graphql/GRAPHQL_BASE_URL.d.ts new file mode 100644 index 0000000..c0ecec6 --- /dev/null +++ b/node_modules/psn-api/dist/graphql/GRAPHQL_BASE_URL.d.ts @@ -0,0 +1 @@ +export declare const GRAPHQL_BASE_URL = "https://web.np.playstation.com/api/graphql/v1/op"; diff --git a/node_modules/psn-api/dist/graphql/getRecentlyPlayedGames.d.ts b/node_modules/psn-api/dist/graphql/getRecentlyPlayedGames.d.ts new file mode 100644 index 0000000..3a182a2 --- /dev/null +++ b/node_modules/psn-api/dist/graphql/getRecentlyPlayedGames.d.ts @@ -0,0 +1,15 @@ +import type { AllCallOptions, AuthorizationPayload, RecentlyPlayedGamesResponse } from "../models"; +type GetRecentlyPlayedGamesOptionsCategories = "ps4_game" | "ps5_native_game"; +type GetRecentlyPlayedGamesOptions = Pick & { + categories: GetRecentlyPlayedGamesOptionsCategories[]; +}; +/** + * A call to this function will retrieve recently played games for the user associated + * with the npsso token provided to this module during initialisation. + * + * This is useful if you want recent activity that isn't tied to trophy progress. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + */ +export declare const getRecentlyPlayedGames: (authorization: AuthorizationPayload, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/graphql/index.d.ts b/node_modules/psn-api/dist/graphql/index.d.ts new file mode 100644 index 0000000..d10bd8e --- /dev/null +++ b/node_modules/psn-api/dist/graphql/index.d.ts @@ -0,0 +1 @@ +export * from "./getRecentlyPlayedGames"; diff --git a/node_modules/psn-api/dist/graphql/operationHashes.d.ts b/node_modules/psn-api/dist/graphql/operationHashes.d.ts new file mode 100644 index 0000000..836a497 --- /dev/null +++ b/node_modules/psn-api/dist/graphql/operationHashes.d.ts @@ -0,0 +1,17 @@ +/** + * GraphQL endpoints work differently to others in the codebase. + * + * The hashes in this file are reverse engineered from app-.js file loaded by the page + * at https://library.playstation.com/recently-played. Following the code in that file leads + * to some Apollo GraphQL code related to persisted queries. This means the request needs to + * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink + * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging + * will surface the exact GraphQL query that's passed to the hash function on the page. + * + * Thankfully it's easier to figure out future endpoints and hashes by: + * + * 1. Visiting a page, e.g https://library.playstation.com/recently-played + * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op + * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters + */ +export declare const getUserGameListHash = "e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae"; diff --git a/node_modules/psn-api/dist/index.d.ts b/node_modules/psn-api/dist/index.d.ts new file mode 100644 index 0000000..b753952 --- /dev/null +++ b/node_modules/psn-api/dist/index.d.ts @@ -0,0 +1,7 @@ +export * from "./authenticate"; +export * from "./graphql"; +export * from "./models"; +export * from "./search"; +export * from "./trophy"; +export * from "./user"; +export * from "./utils/call"; diff --git a/node_modules/psn-api/dist/index.js b/node_modules/psn-api/dist/index.js new file mode 100644 index 0000000..c4cc058 --- /dev/null +++ b/node_modules/psn-api/dist/index.js @@ -0,0 +1,8 @@ + +'use strict' + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./psn-api.cjs.production.min.js') +} else { + module.exports = require('./psn-api.cjs.development.js') +} diff --git a/node_modules/psn-api/dist/models/all-call-options.model.d.ts b/node_modules/psn-api/dist/models/all-call-options.model.d.ts new file mode 100644 index 0000000..131ee51 --- /dev/null +++ b/node_modules/psn-api/dist/models/all-call-options.model.d.ts @@ -0,0 +1,16 @@ +import type { CallValidHeaders } from "./call-valid-headers.model"; +export interface AllCallOptions { + /** + * Not required unless the platform is PS3, PS4, or PS Vita. + * If one of these platforms, the value __must__ be `"trophy"`. + * + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + /** Limit the number of entities returned. */ + limit: number; + /** Return entity data from this result onwards. */ + offset: number; + headerOverrides: CallValidHeaders; +} diff --git a/node_modules/psn-api/dist/models/auth-tokens-response.model.d.ts b/node_modules/psn-api/dist/models/auth-tokens-response.model.d.ts new file mode 100644 index 0000000..e0f8701 --- /dev/null +++ b/node_modules/psn-api/dist/models/auth-tokens-response.model.d.ts @@ -0,0 +1,13 @@ +export interface AuthTokensResponse { + /** Used to retrieve data from the PSN API. */ + accessToken: string; + /** When the access token will expire. */ + expiresIn: number; + idToken: string; + /** Used to retrieve a new access token when it expires. */ + refreshToken: string; + /** When the refresh token will expire. */ + refreshTokenExpiresIn: number; + scope: string; + tokenType: string; +} diff --git a/node_modules/psn-api/dist/models/authorization-payload.model.d.ts b/node_modules/psn-api/dist/models/authorization-payload.model.d.ts new file mode 100644 index 0000000..3cb7249 --- /dev/null +++ b/node_modules/psn-api/dist/models/authorization-payload.model.d.ts @@ -0,0 +1,3 @@ +export interface AuthorizationPayload { + accessToken: string; +} diff --git a/node_modules/psn-api/dist/models/call-valid-headers.model.d.ts b/node_modules/psn-api/dist/models/call-valid-headers.model.d.ts new file mode 100644 index 0000000..fb2f9db --- /dev/null +++ b/node_modules/psn-api/dist/models/call-valid-headers.model.d.ts @@ -0,0 +1,3 @@ +export interface CallValidHeaders { + "Accept-Language": string; +} diff --git a/node_modules/psn-api/dist/models/get-user-friends-account-ids-response.model.d.ts b/node_modules/psn-api/dist/models/get-user-friends-account-ids-response.model.d.ts new file mode 100644 index 0000000..8135ee9 --- /dev/null +++ b/node_modules/psn-api/dist/models/get-user-friends-account-ids-response.model.d.ts @@ -0,0 +1,8 @@ +export interface GetUserFriendsAccountIdsResponse { + /** A list of `accountId` values corresponding to accounts on the target user's friend list. */ + friends: string[]; + /** The total number of friends the target user has on their friends list. */ + totalItemCount: number; + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/dist/models/index.d.ts b/node_modules/psn-api/dist/models/index.d.ts new file mode 100644 index 0000000..962c3af --- /dev/null +++ b/node_modules/psn-api/dist/models/index.d.ts @@ -0,0 +1,28 @@ +export * from "./all-call-options.model"; +export * from "./auth-tokens-response.model"; +export * from "./authorization-payload.model"; +export * from "./call-valid-headers.model"; +export * from "./get-user-friends-account-ids-response.model"; +export * from "./profile-from-account-id-response.model"; +export * from "./profile-from-user-name-response.model"; +export * from "./rarest-thin-trophy.model"; +export * from "./recently-played-games-response.model"; +export * from "./social-account-result.model"; +export * from "./title-platform.model"; +export * from "./title-thin-trophy.model"; +export * from "./title-trophies-response.model"; +export * from "./title-trophy-groups-response.model"; +export * from "./trophy.model"; +export * from "./trophy-counts.model"; +export * from "./trophy-group-earnings.model"; +export * from "./trophy-rarity.model"; +export * from "./trophy-title.model"; +export * from "./trophy-title.model"; +export * from "./trophy-type.model"; +export * from "./universal-search-domains.model"; +export * from "./universal-search-response.model"; +export * from "./user-thin-trophy.model"; +export * from "./user-titles-response.model"; +export * from "./user-trophies-earned-for-title-response.model"; +export * from "./user-trophy-group-earnings-for-title-response.model"; +export * from "./user-trophy-profile-summary-response.model"; diff --git a/node_modules/psn-api/dist/models/profile-from-account-id-response.model.d.ts b/node_modules/psn-api/dist/models/profile-from-account-id-response.model.d.ts new file mode 100644 index 0000000..86a4467 --- /dev/null +++ b/node_modules/psn-api/dist/models/profile-from-account-id-response.model.d.ts @@ -0,0 +1,21 @@ +export interface ProfileFromAccountIdResponse { + /** + * The account's online username. + * + * @example + * ```json + * "onlineId": "Hakoom" + * ``` + */ + onlineId: string; + aboutMe: string; + avatars: Array<{ + size: string; + url: string; + }>; + languages: string[]; + /** Whether or not the account is a PlayStation Plus subscriber. */ + isPlus: boolean; + isOfficiallyVerified: boolean; + isMe: boolean; +} diff --git a/node_modules/psn-api/dist/models/profile-from-user-name-response.model.d.ts b/node_modules/psn-api/dist/models/profile-from-user-name-response.model.d.ts new file mode 100644 index 0000000..357b515 --- /dev/null +++ b/node_modules/psn-api/dist/models/profile-from-user-name-response.model.d.ts @@ -0,0 +1,75 @@ +export interface ProfileFromUserNameResponse { + profile: { + /** + * The account's online username. + * + * @example + * ```json + * "onlineId": "Hakoom" + * ``` + */ + onlineId: string; + /** + * The account's internal ID value, which can be used for numerous + * calls to the PSN API. + * + * @example + * ```json + * "accountId": "962157895908076652" + * ``` + */ + accountId: string; + npId: string; + avatarUrls: Array<{ + size: string; + avatarUrl: string; + }>; + /** Whether or not the account is a PlayStation Plus subscriber. */ + plus: 0 | 1; + aboutMe: string; + languagesUsed: string[]; + /** + * The account's trophy level, progress towards the next level, + * and total number of trophies earned by type. + */ + trophySummary: { + level: number; + progress: number; + earnedTrophies: { + bronze: number; + silver: number; + gold: number; + platinum: number; + }; + }; + isOfficiallyVerified: boolean; + personalDetail: { + firstName: string; + lastName: string; + profilePictureUrls: Array<{ + size: string; + profilePictureUrl: string; + }>; + }; + personalDetailSharing: string; + personalDetailSharingRequestMessageFlag: boolean; + primaryOnlineStatus: string; + presences: Array<{ + onlineStatus: string; + hasBroadcastData: boolean; + lastOnlineDate: string; + }>; + friendRelation: string; + requestMessageFlag: boolean; + /** + * Whether or not the account is blocked by the retrieving authentication context. + * For example, if you are using psn-api with _your_ account's access token, and + * your account has blocked the account you're looking up, this will be `true`. + */ + blocking: boolean; + following: boolean; + consoleAvailability: { + availabilityStatus: string; + }; + }; +} diff --git a/node_modules/psn-api/dist/models/rarest-thin-trophy.model.d.ts b/node_modules/psn-api/dist/models/rarest-thin-trophy.model.d.ts new file mode 100644 index 0000000..37ada49 --- /dev/null +++ b/node_modules/psn-api/dist/models/rarest-thin-trophy.model.d.ts @@ -0,0 +1,2 @@ +import type { Trophy } from "./trophy.model"; +export type RarestThinTrophy = Pick; diff --git a/node_modules/psn-api/dist/models/recently-played-games-response.model.d.ts b/node_modules/psn-api/dist/models/recently-played-games-response.model.d.ts new file mode 100644 index 0000000..2aaa8a1 --- /dev/null +++ b/node_modules/psn-api/dist/models/recently-played-games-response.model.d.ts @@ -0,0 +1,60 @@ +import { TitlePlatform } from "./title-platform.model"; +export interface RecentlyPlayedGame { + /** GrahpQL object type/schema */ + __typename: "GameLibraryTitle"; + /** Contains a url to a game icon file. */ + image: { + __typename: "Media"; + url: string; + }; + /** + * Unclear what this represents, but if this is set to true then + * the productId property is not null. + */ + isActive: boolean | null; + /** + * An ISO date representing the last play date and time + * of the given title, e.g 2023-03-10T01:01:01.390000Z + */ + lastPlayedDateTime: string; + /** The name of the game */ + name: string; + /** + * The platform this game was last played on. This can be reported as + * "UNKNOWN". It appears that "UNKNOWN" is shown in certain scenarios + * when a user that isn't associated with the access token is sharing + * the same console as the user that is identified by the access token. + */ + platform: TitlePlatform | "UNKNOWN"; + /** + * ID of the product. Used in the PlayStation Store URL. Appears to only be + * set for certain PS4 games along with the entitlementId. + */ + productId: string | null; + /** + * Similar to productId. Used in URLs for the PlayStation Store, i.e + * store.playstation.com/en-ae/product/:entitlementId. Appears to only + * be set for certain entries on the PS4 platform along with productId. + */ + entitlementId: string | null; + /** + * ID of the product. Forms part of a PlayStation Store URL, e.g + * https://store.playstation.com/en-us/product/UP9000-$titleId-RATCHETCLANKRIFT + */ + titleId: string; + /** + * An ID for titles on the PlayStation store. It's used in the + * URL, i.e store.playstation.com/ko-kr/concept/:conceptId + */ + conceptId: string; + /** Unsure what data this can hold. Perhaps it's PS Now related? */ + subscriptionService: "NONE" | string; +} +export interface RecentlyPlayedGamesResponse { + data: { + gameLibraryTitlesRetrieve: { + __typename: "GameList"; + games: RecentlyPlayedGame[]; + }; + }; +} diff --git a/node_modules/psn-api/dist/models/social-account-result.model.d.ts b/node_modules/psn-api/dist/models/social-account-result.model.d.ts new file mode 100644 index 0000000..d9ccdef --- /dev/null +++ b/node_modules/psn-api/dist/models/social-account-result.model.d.ts @@ -0,0 +1,18 @@ +export interface SocialAccountResult { + id: string; + type: string; + score: number; + socialMetadata: { + accountId: string; + country: string; + language: string; + onlineId: string; + isPsPlus: boolean; + isOfficiallyVerified: boolean; + avatarUrl: string; + verifiedUserName: string; + highlights: { + onlineId: string[]; + }; + }; +} diff --git a/node_modules/psn-api/dist/models/title-platform.model.d.ts b/node_modules/psn-api/dist/models/title-platform.model.d.ts new file mode 100644 index 0000000..c7024af --- /dev/null +++ b/node_modules/psn-api/dist/models/title-platform.model.d.ts @@ -0,0 +1 @@ +export type TitlePlatform = "PS5" | "PS4" | "PS3" | "Vita"; diff --git a/node_modules/psn-api/dist/models/title-thin-trophy.model.d.ts b/node_modules/psn-api/dist/models/title-thin-trophy.model.d.ts new file mode 100644 index 0000000..ce917e1 --- /dev/null +++ b/node_modules/psn-api/dist/models/title-thin-trophy.model.d.ts @@ -0,0 +1,2 @@ +import type { Trophy } from "./trophy.model"; +export type TitleThinTrophy = Pick; diff --git a/node_modules/psn-api/dist/models/title-trophies-response.model.d.ts b/node_modules/psn-api/dist/models/title-trophies-response.model.d.ts new file mode 100644 index 0000000..e780886 --- /dev/null +++ b/node_modules/psn-api/dist/models/title-trophies-response.model.d.ts @@ -0,0 +1,13 @@ +import type { TitleThinTrophy } from "./title-thin-trophy.model"; +export interface TitleTrophiesResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + /** `true` if this title has additional trophy groups. This is commonly used for DLC, but some games add additional trophies as separate groups post-release (such as Astro's Playroom and Horizon Zero Dawn). */ + hasTrophyGroups: boolean; + /** Individual object for each trophy. */ + trophies: TitleThinTrophy[]; + /** Total trophies in the group (or total trophies for the title if `"all"` specified) */ + totalItemCount: number; + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/dist/models/title-trophy-groups-response.model.d.ts b/node_modules/psn-api/dist/models/title-trophy-groups-response.model.d.ts new file mode 100644 index 0000000..45f8886 --- /dev/null +++ b/node_modules/psn-api/dist/models/title-trophy-groups-response.model.d.ts @@ -0,0 +1,25 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroup } from "./trophy-group.model"; +export interface TitleTrophyGroupsResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + /** The title name that this trophy belongs to. */ + trophyTitleName: string; + /** URL of the icon for the trophy title. */ + trophyTitleIconUrl: string; + /** + * The platform this title belongs to. Some games have trophy sets which + * are shared between multiple platforms (eg. PS4,PSVITA). + * The platforms in these instances will be comma-separated. + */ + trophyTitlePlatform: string; + /** Total number of trophies for the title by type. */ + definedTrophies: TrophyCounts; + /** Individual entities for each trophy group associated with the given title. */ + trophyGroups: TrophyGroup[]; + /** + * The title description that this trophy belongs to. + * This is a legacy property that applies to PS3, PS4, and PS Vita titles only. + */ + trophyTitleDetail?: string; +} diff --git a/node_modules/psn-api/dist/models/trophy-counts.model.d.ts b/node_modules/psn-api/dist/models/trophy-counts.model.d.ts new file mode 100644 index 0000000..3cf1ec8 --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-counts.model.d.ts @@ -0,0 +1,10 @@ +export interface TrophyCounts { + /** Total count of bronze trophies. */ + bronze: number; + /** Total count of silver trophies. */ + silver: number; + /** Total count of gold trophies. */ + gold: number; + /** 1 if the group contains a platinum trophy. */ + platinum: 0 | 1; +} diff --git a/node_modules/psn-api/dist/models/trophy-group-earnings.model.d.ts b/node_modules/psn-api/dist/models/trophy-group-earnings.model.d.ts new file mode 100644 index 0000000..1086c48 --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-group-earnings.model.d.ts @@ -0,0 +1,21 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroup } from "./trophy-group.model"; +type FromTrophyGroup = Pick; +export interface TrophyGroupEarnings extends FromTrophyGroup { + /** + * The percentage completion of the trophy group by the user. + * @example `100` + * @example `20` + */ + progress: number; + /** The account's number of earned trophies for the trophy group by grade. */ + earnedTrophies: TrophyCounts; + /** + * An ISO 8601 string representing the date the + * group progress was updated (such as when a + * trophy was earned). + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; +} +export {}; diff --git a/node_modules/psn-api/dist/models/trophy-group.model.d.ts b/node_modules/psn-api/dist/models/trophy-group.model.d.ts new file mode 100644 index 0000000..36fa351 --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-group.model.d.ts @@ -0,0 +1,24 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +export interface TrophyGroup { + /** + * ID of the trophy group. + * + * A game's standard set of trophies will have a value of `"default"`, + * whereas additional groups (such as those added from DLC) will + * increment in values such as `"001"` and `"002"`. + * @example "default" + * @example "001" + */ + trophyGroupId: string; + /** + * Name of the trophy group. + * @example "ASTRO's PLAYROOM" + */ + trophyGroupName: string; + /** URL of the icon for the trophy group. */ + trophyGroupIconUrl: string; + /** Number of trophies for the trophy group by grade. */ + definedTrophies: TrophyCounts; + /** Description of the trophy group. This is a legacy property, only applying to PS3, PS4, and PS Vita titles. */ + trophyGroupDetail?: string; +} diff --git a/node_modules/psn-api/dist/models/trophy-rarity.model.d.ts b/node_modules/psn-api/dist/models/trophy-rarity.model.d.ts new file mode 100644 index 0000000..ec1989a --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-rarity.model.d.ts @@ -0,0 +1,6 @@ +export declare enum TrophyRarity { + UltraRare = 0, + VeryRare = 1, + Rare = 2, + Common = 3 +} diff --git a/node_modules/psn-api/dist/models/trophy-title.model.d.ts b/node_modules/psn-api/dist/models/trophy-title.model.d.ts new file mode 100644 index 0000000..d8d2c4f --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-title.model.d.ts @@ -0,0 +1,58 @@ +import type { TitlePlatform } from "./title-platform.model"; +import type { TrophyCounts } from "./trophy-counts.model"; +export interface TrophyTitle { + /** + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + /** + * Unique ID of the title. This is later required for requesting detailed + * trophy information for this title. + */ + npCommunicationId: string; + /** The current version of the trophy set. Some trophy sets receive updates. */ + trophySetVersion: string; + /** The game name. */ + trophyTitleName: string; + /** URL of the icon for the given title. */ + trophyTitleIconUrl: string; + /** + * The platform this title belongs to. Some games have trophy sets which are + * shared between multiple platforms (ie. PS4,PSVITA). The platforms will be + * comma-separated. + */ + trophyTitlePlatform: TitlePlatform | string; + /** + * `true` if the title has multiple groups of trophies beyond the `"default"` group. + */ + hasTrophyGroups: boolean; + /** Number of trophies for the title by type. */ + definedTrophies: TrophyCounts; + /** + * Percentage of trophies earned for the title by the user. + * @example 100 + * @example 25 + */ + progress: number; + /** Number of trophies for the title which have been earned by grade. */ + earnedTrophies: TrophyCounts; + /** + * `true` if the title has been hidden on the account's trophy list. + * This applies to the authenticating account only. + * The title will not be returned if it has been hidden on another account. + */ + hiddenFlag: boolean; + /** + * An ISO 8601 string representing the date the most + * recent trophy was earned for the title. + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; + /** + * The title description. + * This is a legacy property that applies to + * PS3, PS4, and PS Vita titles only. + */ + trophyTitleDetail?: string; +} diff --git a/node_modules/psn-api/dist/models/trophy-type.model.d.ts b/node_modules/psn-api/dist/models/trophy-type.model.d.ts new file mode 100644 index 0000000..4f8c1cd --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy-type.model.d.ts @@ -0,0 +1 @@ +export type TrophyType = "bronze" | "silver" | "gold" | "platinum"; diff --git a/node_modules/psn-api/dist/models/trophy.model.d.ts b/node_modules/psn-api/dist/models/trophy.model.d.ts new file mode 100644 index 0000000..f515c22 --- /dev/null +++ b/node_modules/psn-api/dist/models/trophy.model.d.ts @@ -0,0 +1,54 @@ +import type { TrophyRarity } from "./trophy-rarity.model"; +import type { TrophyType } from "./trophy-type.model"; +export interface Trophy { + /** Unique ID for this trophy (unique within the title and not just the group). */ + trophyId: number; + /** `true` if this is a secret trophy (ie. further details are not displayed by default unless earned). */ + trophyHidden: boolean; + /** Whether the trophy is bronze, silver, gold, or platinum. */ + trophyType: TrophyType; + /** `true` if this trophy has been earned. */ + earned?: boolean; + /** + * An ISO 8601 string representing the date the + * trophy was earned. Only truthy if `earned` is `true`. + * @example `"2021-08-15T21:22:08Z"` + */ + earnedDateTime?: string; + /** Description of the trophy. */ + trophyDetail?: string; + /** Percentage of all users who have earned the trophy. */ + trophyEarnedRate?: string; + /** + * ID of the trophy group this trophy belongs to. + * + * A game's standard set of trophies will have a value of `"default"`, + * whereas DLC increments in values such as `"001"` and `"002"`. + */ + trophyGroupId?: string; + /** URL for the graphic associated with the trophy. */ + trophyIconUrl?: string; + /** Name of the trophy. */ + trophyName?: string; + /** + * If the trophy tracks progress towards unlock, this is the total required to achieve the unlock. + * This is included on PS5 titles only, and only if the trophy itself tracks progress. + */ + trophyProgressTargetValue?: string; + /** Rarity of the trophy. */ + trophyRare?: TrophyRarity; + /** + * URL for the graphic associated with the reward. + * + * This is included on PS5 titles only, and is only returned if the + * trophy has a reward associated with it. + */ + trophyRewardImageUrl?: string; + /** + * Name of the reward that earning the trophy grants. + * + * This is included on PS5 titles only, and only if the trophy itself has + * a reward associated with it. + */ + trophyRewardName?: string; +} diff --git a/node_modules/psn-api/dist/models/universal-search-domain-response.model.d.ts b/node_modules/psn-api/dist/models/universal-search-domain-response.model.d.ts new file mode 100644 index 0000000..7ffc51e --- /dev/null +++ b/node_modules/psn-api/dist/models/universal-search-domain-response.model.d.ts @@ -0,0 +1,11 @@ +export interface UniversalSearchDomainResponse { + domain: string; + domainTitle: string; + domainTitleMessageId: string; + zeroState: boolean; + univexId: string; + facetOptions: unknown[]; + next: string; + totalResultCount: number; + results: T[]; +} diff --git a/node_modules/psn-api/dist/models/universal-search-domains.model.d.ts b/node_modules/psn-api/dist/models/universal-search-domains.model.d.ts new file mode 100644 index 0000000..ea13aef --- /dev/null +++ b/node_modules/psn-api/dist/models/universal-search-domains.model.d.ts @@ -0,0 +1 @@ +export type UniversalSearchDomains = "SocialAllAccounts"; diff --git a/node_modules/psn-api/dist/models/universal-search-response.model.d.ts b/node_modules/psn-api/dist/models/universal-search-response.model.d.ts new file mode 100644 index 0000000..2a4d361 --- /dev/null +++ b/node_modules/psn-api/dist/models/universal-search-response.model.d.ts @@ -0,0 +1,7 @@ +import type { UniversalSearchDomainResponse } from "./universal-search-domain-response.model"; +export interface UniversalSearchResponse { + prefix: string; + suggestions: string[]; + fallbackQueried: boolean; + domainResponses: UniversalSearchDomainResponse[]; +} diff --git a/node_modules/psn-api/dist/models/user-thin-trophy.model.d.ts b/node_modules/psn-api/dist/models/user-thin-trophy.model.d.ts new file mode 100644 index 0000000..86dcc46 --- /dev/null +++ b/node_modules/psn-api/dist/models/user-thin-trophy.model.d.ts @@ -0,0 +1,2 @@ +import type { Trophy } from "./trophy.model"; +export type UserThinTrophy = Pick; diff --git a/node_modules/psn-api/dist/models/user-titles-response.model.d.ts b/node_modules/psn-api/dist/models/user-titles-response.model.d.ts new file mode 100644 index 0000000..e8fa24b --- /dev/null +++ b/node_modules/psn-api/dist/models/user-titles-response.model.d.ts @@ -0,0 +1,9 @@ +import type { TrophyTitle } from "./trophy-title.model"; +export interface UserTitlesResponse { + /** The list of games played by the user. */ + trophyTitles: TrophyTitle[]; + /** The number of `TrophyTitle` entities returned from the PSN API. */ + totalItemCount: number; + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/dist/models/user-trophies-earned-for-title-response.model.d.ts b/node_modules/psn-api/dist/models/user-trophies-earned-for-title-response.model.d.ts new file mode 100644 index 0000000..9dd2c07 --- /dev/null +++ b/node_modules/psn-api/dist/models/user-trophies-earned-for-title-response.model.d.ts @@ -0,0 +1,26 @@ +import type { RarestThinTrophy } from "./rarest-thin-trophy.model"; +import type { UserThinTrophy } from "./user-thin-trophy.model"; +export interface UserTrophiesEarnedForTitleResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + /** `true` if this title has additional trophy groups beyond the required `"default"` group. */ + hasTrophyGroups: boolean; + /** + * An ISO 8601 string representing the date of the + * user's most recent trophy earned for the title. + * @example - `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; + /** Individual object for each trophy. */ + trophies: UserThinTrophy[]; + /** Total trophies in the group (or total trophies for the title if `"all"` is specified). */ + totalItemCount: number; + /** + * An array which contains the trophy where `earned` is `true` with the lowest `trophyEarnedRate`. + * If multiple trophies have the same `trophyEarnedRate`, the array contains those trophies instead of just a single trophy. + * It contains nothing if no trophies are earned. + */ + rarestTrophies?: RarestThinTrophy[]; + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/dist/models/user-trophy-group-earnings-for-title-response.model.d.ts b/node_modules/psn-api/dist/models/user-trophy-group-earnings-for-title-response.model.d.ts new file mode 100644 index 0000000..0cc3b2e --- /dev/null +++ b/node_modules/psn-api/dist/models/user-trophy-group-earnings-for-title-response.model.d.ts @@ -0,0 +1,25 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroupEarnings } from "./trophy-group-earnings.model"; +export interface UserTrophyGroupEarningsForTitleResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + /** + * `true` if the title has been hidden on the account's trophy list. + * This applies to the authenticating account only. + * The title will not be returned if it has been hidden on another account. + */ + hiddenFlag: boolean; + /** The account's percentage of trophies earned for the title. */ + progress: number; + /** The account's number of earned trophies for the title by grade. */ + earnedTrophies: TrophyCounts; + /** Individual object for each trophy group returned. */ + trophyGroups: TrophyGroupEarnings[]; + /** + * An ISO 8601 string representing the date the + * title progress was updated (such as when a + * trophy was earned for a group). + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; +} diff --git a/node_modules/psn-api/dist/models/user-trophy-profile-summary-response.model.d.ts b/node_modules/psn-api/dist/models/user-trophy-profile-summary-response.model.d.ts new file mode 100644 index 0000000..7bc3c05 --- /dev/null +++ b/node_modules/psn-api/dist/models/user-trophy-profile-summary-response.model.d.ts @@ -0,0 +1,28 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +export interface UserTrophyProfileSummaryResponse { + /** The ID of the account being accessed. */ + accountId: string; + /** The account's overall trophy level. */ + trophyLevel: string; + /** The account's percentage progress towards the next trophy level. */ + progress: number; + /** + * The tier this trophy level is in. + * + * | Tier | Grade | trophyLevel Ranges | + * | --- | --- | ---: | + * | 1 | Bronze | 1 - 99 | + * | 2 | Bronze | 100 - 199 | + * | 3 | Bronze | 200 - 299 | + * | 4 | Silver | 300 - 399 | + * | 5 | Silver | 400 - 499 | + * | 6 | Silver | 500 - 599 | + * | 7 | Gold | 600 - 699 | + * | 8 | Gold | 700 - 799 | + * | 9 | Gold | 800 - 998 | + * | 10 | Platinum | 999 | + */ + tier: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + /** The account's number of earned trophies by grade. */ + earnedTrophies: TrophyCounts; +} diff --git a/node_modules/psn-api/dist/psn-api.cjs.development.js b/node_modules/psn-api/dist/psn-api.cjs.development.js new file mode 100644 index 0000000..219aca5 --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.cjs.development.js @@ -0,0 +1,1179 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var fetch = require('isomorphic-unfetch'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch); + +function _regeneratorRuntime() { + _regeneratorRuntime = function () { + return exports; + }; + var exports = {}, + Op = Object.prototype, + hasOwn = Op.hasOwnProperty, + defineProperty = Object.defineProperty || function (obj, key, desc) { + obj[key] = desc.value; + }, + $Symbol = "function" == typeof Symbol ? Symbol : {}, + iteratorSymbol = $Symbol.iterator || "@@iterator", + asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", + toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + function define(obj, key, value) { + return Object.defineProperty(obj, key, { + value: value, + enumerable: !0, + configurable: !0, + writable: !0 + }), obj[key]; + } + try { + define({}, ""); + } catch (err) { + define = function (obj, key, value) { + return obj[key] = value; + }; + } + function wrap(innerFn, outerFn, self, tryLocsList) { + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, + generator = Object.create(protoGenerator.prototype), + context = new Context(tryLocsList || []); + return defineProperty(generator, "_invoke", { + value: makeInvokeMethod(innerFn, self, context) + }), generator; + } + function tryCatch(fn, obj, arg) { + try { + return { + type: "normal", + arg: fn.call(obj, arg) + }; + } catch (err) { + return { + type: "throw", + arg: err + }; + } + } + exports.wrap = wrap; + var ContinueSentinel = {}; + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + var IteratorPrototype = {}; + define(IteratorPrototype, iteratorSymbol, function () { + return this; + }); + var getProto = Object.getPrototypeOf, + NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + define(prototype, method, function (arg) { + return this._invoke(method, arg); + }); + }); + } + function AsyncIterator(generator, PromiseImpl) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if ("throw" !== record.type) { + var result = record.arg, + value = result.value; + return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }) : PromiseImpl.resolve(value).then(function (unwrapped) { + result.value = unwrapped, resolve(result); + }, function (error) { + return invoke("throw", error, resolve, reject); + }); + } + reject(record.arg); + } + var previousPromise; + defineProperty(this, "_invoke", { + value: function (method, arg) { + function callInvokeWithMethodAndArg() { + return new PromiseImpl(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + }); + } + function makeInvokeMethod(innerFn, self, context) { + var state = "suspendedStart"; + return function (method, arg) { + if ("executing" === state) throw new Error("Generator is already running"); + if ("completed" === state) { + if ("throw" === method) throw arg; + return doneResult(); + } + for (context.method = method, context.arg = arg;;) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } + if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { + if ("suspendedStart" === state) throw state = "completed", context.arg; + context.dispatchException(context.arg); + } else "return" === context.method && context.abrupt("return", context.arg); + state = "executing"; + var record = tryCatch(innerFn, self, context); + if ("normal" === record.type) { + if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; + return { + value: record.arg, + done: context.done + }; + } + "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); + } + }; + } + function maybeInvokeDelegate(delegate, context) { + var methodName = context.method, + method = delegate.iterator[methodName]; + if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; + var record = tryCatch(method, delegate.iterator, context.arg); + if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; + var info = record.arg; + return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); + } + function pushTryEntry(locs) { + var entry = { + tryLoc: locs[0] + }; + 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); + } + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal", delete record.arg, entry.completion = record; + } + function Context(tryLocsList) { + this.tryEntries = [{ + tryLoc: "root" + }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); + } + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) return iteratorMethod.call(iterable); + if ("function" == typeof iterable.next) return iterable; + if (!isNaN(iterable.length)) { + var i = -1, + next = function next() { + for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; + return next.value = undefined, next.done = !0, next; + }; + return next.next = next; + } + } + return { + next: doneResult + }; + } + function doneResult() { + return { + value: undefined, + done: !0 + }; + } + return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { + value: GeneratorFunctionPrototype, + configurable: !0 + }), defineProperty(GeneratorFunctionPrototype, "constructor", { + value: GeneratorFunction, + configurable: !0 + }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { + var ctor = "function" == typeof genFun && genFun.constructor; + return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); + }, exports.mark = function (genFun) { + return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; + }, exports.awrap = function (arg) { + return { + __await: arg + }; + }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { + return this; + }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { + void 0 === PromiseImpl && (PromiseImpl = Promise); + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); + return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { + return this; + }), define(Gp, "toString", function () { + return "[object Generator]"; + }), exports.keys = function (val) { + var object = Object(val), + keys = []; + for (var key in object) keys.push(key); + return keys.reverse(), function next() { + for (; keys.length;) { + var key = keys.pop(); + if (key in object) return next.value = key, next.done = !1, next; + } + return next.done = !0, next; + }; + }, exports.values = values, Context.prototype = { + constructor: Context, + reset: function (skipTempReset) { + if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); + }, + stop: function () { + this.done = !0; + var rootRecord = this.tryEntries[0].completion; + if ("throw" === rootRecord.type) throw rootRecord.arg; + return this.rval; + }, + dispatchException: function (exception) { + if (this.done) throw exception; + var context = this; + function handle(loc, caught) { + return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; + } + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i], + record = entry.completion; + if ("root" === entry.tryLoc) return handle("end"); + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"), + hasFinally = hasOwn.call(entry, "finallyLoc"); + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); + if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); + } else if (hasCatch) { + if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); + } else { + if (!hasFinally) throw new Error("try statement without catch or finally"); + if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); + } + } + } + }, + abrupt: function (type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); + var record = finallyEntry ? finallyEntry.completion : {}; + return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); + }, + complete: function (record, afterLoc) { + if ("throw" === record.type) throw record.arg; + return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; + }, + finish: function (finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; + } + }, + catch: function (tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if ("throw" === record.type) { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + throw new Error("illegal catch attempt"); + }, + delegateYield: function (iterable, resultName, nextLoc) { + return this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }, "next" === this.method && (this.arg = undefined), ContinueSentinel; + } + }, exports; +} +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} +function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + _next(undefined); + }); + }; +} +function _extends() { + _extends = Object.assign ? Object.assign.bind() : function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); +} +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + return target; +} + +var AUTH_BASE_URL = "https://ca.account.sony.com/api/authz/v3/oauth"; + +/** + * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`. + * @returns An object containing an access token, refresh token, and expiry times for both. + */ +var exchangeCodeForAccessToken = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(accessCode) { + var requestUrl, res, raw; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + requestUrl = AUTH_BASE_URL + "/token"; + _context.next = 3; + return fetch__default["default"](requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + code: accessCode, + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + grant_type: "authorization_code", + token_format: "jwt" + }).toString() + }); + case 3: + res = _context.sent; + _context.next = 6; + return res.json(); + case 6: + raw = _context.sent; + return _context.abrupt("return", { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }); + case 8: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeCodeForAccessToken(_x) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * + * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie + * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`. + * @example + * ```ts + * const code = await exchangeNpssoForCode("myNpssoToken"); + * + * console.log(code) // --> "v3.XXXXXX" + * ``` + */ +var exchangeNpssoForCode = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(npssoToken) { + var _responseHeaders$get; + var queryString, requestUrl, _yield$fetch, responseHeaders, redirectLocation, redirectParams; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + queryString = new URLSearchParams({ + access_type: "offline", + client_id: "09515159-7237-4370-9b40-3806e67c0891", + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + response_type: "code", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString(); + requestUrl = AUTH_BASE_URL + "/authorize?" + queryString; // This never returns a 200. As of Oct 10 2021, it seems to return a 302. + _context.next = 4; + return fetch__default["default"](requestUrl, { + headers: { + Cookie: "npsso=" + npssoToken + }, + redirect: "manual" + }); + case 4: + _yield$fetch = _context.sent; + responseHeaders = _yield$fetch.headers; + if (!(!responseHeaders.has("location") || !((_responseHeaders$get = responseHeaders.get("location")) != null && _responseHeaders$get.includes("?code=")))) { + _context.next = 8; + break; + } + throw new Error("\n There was a problem retrieving your PSN access code. Is your NPSSO code valid?\n To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie.\n "); + case 8: + redirectLocation = responseHeaders.get("location"); + redirectParams = new URLSearchParams(redirectLocation.split("redirect/")[1]); + return _context.abrupt("return", redirectParams.get("code")); + case 11: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeNpssoForCode(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var exchangeRefreshTokenForAuthTokens = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(refreshToken) { + var requestUrl, res, raw; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + requestUrl = AUTH_BASE_URL + "/token"; + _context.next = 3; + return fetch__default["default"](requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + refresh_token: refreshToken, + grant_type: "refresh_token", + token_format: "jwt", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString() + }); + case 3: + res = _context.sent; + _context.next = 6; + return res.json(); + case 6: + raw = _context.sent; + return _context.abrupt("return", { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }); + case 8: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeRefreshTokenForAuthTokens(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var call = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(config, authorization, bodyPayload) { + var _config$method; + var response; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return fetch__default["default"](config.url, { + method: (_config$method = config == null ? void 0 : config.method) != null ? _config$method : "GET", + headers: _extends({ + Authorization: "Bearer " + authorization.accessToken, + "Content-Type": "application/json" + }, config == null ? void 0 : config.headers), + body: JSON.stringify(bodyPayload) + }); + case 2: + response = _context.sent; + _context.next = 5; + return response.json(); + case 5: + return _context.abrupt("return", _context.sent); + case 6: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function call(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var GRAPHQL_BASE_URL = "https://web.np.playstation.com/api/graphql/v1/op"; + +/** + * GraphQL endpoints work differently to others in the codebase. + * + * The hashes in this file are reverse engineered from app-.js file loaded by the page + * at https://library.playstation.com/recently-played. Following the code in that file leads + * to some Apollo GraphQL code related to persisted queries. This means the request needs to + * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink + * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging + * will surface the exact GraphQL query that's passed to the hash function on the page. + * + * Thankfully it's easier to figure out future endpoints and hashes by: + * + * 1. Visiting a page, e.g https://library.playstation.com/recently-played + * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op + * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters + */ +// Hash is computed from the following query (without surrounding quotes): +// "query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\n __typename\n games {\n __typename\n conceptId\n entitlementId\n image {\n __typename\n url\n }\n isActive\n lastPlayedDateTime\n name\n platform\n productId\n subscriptionService\n titleId\n }\n }\n}\n" +var getUserGameListHash = "e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae"; + +/** + * A call to this function will retrieve recently played games for the user associated + * with the npsso token provided to this module during initialisation. + * + * This is useful if you want recent activity that isn't tied to trophy progress. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + */ +var getRecentlyPlayedGames = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, options) { + var _options, _options$limit, limit, _options$categories, categories, url, response; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + if (options === void 0) { + options = {}; + } + _options = options, _options$limit = _options.limit, limit = _options$limit === void 0 ? 50 : _options$limit, _options$categories = _options.categories, categories = _options$categories === void 0 ? ["ps4_game", "ps5_native_game"] : _options$categories; + url = new URL(GRAPHQL_BASE_URL); + url.searchParams.set("operationName", "getUserGameList"); + url.searchParams.set("variables", JSON.stringify({ + limit: limit, + categories: categories.join(",") + })); + url.searchParams.set("extensions", JSON.stringify({ + persistedQuery: { + version: 1, + sha256Hash: getUserGameListHash + } + })); + _context.next = 8; + return call({ + url: url.toString() + }, authorization); + case 8: + response = _context.sent; + if (!(!response.data || !response.data.gameLibraryTitlesRetrieve)) { + _context.next = 11; + break; + } + throw new Error(JSON.stringify(response)); + case 11: + return _context.abrupt("return", response); + case 12: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getRecentlyPlayedGames(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +exports.TrophyRarity = void 0; +(function (TrophyRarity) { + TrophyRarity[TrophyRarity["UltraRare"] = 0] = "UltraRare"; + TrophyRarity[TrophyRarity["VeryRare"] = 1] = "VeryRare"; + TrophyRarity[TrophyRarity["Rare"] = 2] = "Rare"; + TrophyRarity[TrophyRarity["Common"] = 3] = "Common"; +})(exports.TrophyRarity || (exports.TrophyRarity = {})); + +var _excluded = ["headerOverrides"]; +var buildRequestUrl = function buildRequestUrl(baseUrl, endpointUrl, options, args) { + if (options === void 0) { + options = {}; + } + if (args === void 0) { + args = {}; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick. + var _options = options, + pickedOptions = _objectWithoutPropertiesLoose(_options, _excluded); + var concatenated = baseUrl + "/" + endpointUrl; + var withoutDoubleSlashes = concatenated.replace(/([^:]\/)\/+/g, "$1"); + var withArgs = withoutDoubleSlashes; + var queryParamValues = {}; + for (var _i = 0, _Object$entries = Object.entries(_extends({}, args, pickedOptions)); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = _Object$entries[_i], + argKey = _Object$entries$_i[0], + argValue = _Object$entries$_i[1]; + if (withArgs.includes(":" + argKey)) { + withArgs = withArgs.replace(":" + argKey, String(argValue)); + } else if (argValue !== undefined) { + queryParamValues[argKey] = String(argValue); + } + } + var queryString = new URLSearchParams(queryParamValues).toString(); + return queryString.length > 0 ? withArgs + "?" + queryString : withArgs; +}; + +var SEARCH_BASE_URL = "https://m.np.playstation.com/api/search"; + +var makeUniversalSearch = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, searchTerm, domain) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(SEARCH_BASE_URL, "/v1/universalSearch"); + _context.next = 3; + return call({ + url: url, + method: "POST" + }, authorization, { + searchTerm: searchTerm, + domainRequests: [{ + domain: domain + }] + }); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function makeUniversalSearch(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var TROPHY_BASE_URL = "https://m.np.playstation.com/api/trophy"; + +/** + * A call to this function will retrieve the trophy list of a + * single - or all - trophy groups for a title. A title can have multiple + * groups of trophies (a `"default"` group which all titles have, and additional + * groups starting with the name `"001"` and incrementing for each additional group). To retrieve + * trophies from all groups within a title (ie. the full trophy set), then + * `trophyGroupId` should be set to `"all"`. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` parameter as `"trophy"`. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getTitleTrophies = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, npCommunicationId, trophyGroupId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", options, { + npCommunicationId: npCommunicationId, + trophyGroupId: trophyGroupId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getTitleTrophies(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A title may have multiple groups of trophies. This is most commonly + * seen in games which have DLC expansions where additional trophies are added. + * + * You can call this function for a specific title - using the + * unique `npCommunicationId` for the title - and you will receive a + * summary of all of the trophy groups associated with the title. + * This also includes a summary of the number of trophies for the + * title, broken down by group and grade (gold, silver, etc.). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getTitleTrophyGroups = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, npCommunicationId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/npCommunicationIds/:npCommunicationId/trophyGroups", options, { + npCommunicationId: npCommunicationId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getTitleTrophyGroups(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve a summarized list of titles played + * by a user, ordered by recent trophy unlocks. The maximum amount that can + * be returned by a single call is 800 (assuming a `limit` option of 800 is set). + * If the user has more titles than the given `limit` option, subsequent calls + * of this funciton must be made to fetch the complete list by paging via the + * `offset` option. + * + * The numeric `accountId` can be that of any PSN account for which the authenticating + * account has permissions to view the trophy list. When querying the titles + * associated with the authenticating account, the numeric `accountId` can be + * substituted with `"me"`. + * + * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()` + * function can be used. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * Included in the information returned is the titles' unique `npCommunicationId`. + * This is required to make use of subsequent functions for requesting more specific + * detail about a title's trophies. + * + * The results are presented in order of the `lastUpdatedDateTime` for the title, + * so the first result will be the title for which a trophy was most recently earned + * (or synced for the first time in the case of a game with 0% progress). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.limit Limit the number of titles returned. + * @param options.offset Return title data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTitles = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/trophyTitles", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTitles(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the earned status of trophies for a user + * from either a single - or all - trophy groups in a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, and + * additional groups starting with a name of `"001"` and incrementing for each + * additional group). To retrieve trophies from all groups within a title + * (ie. the full trophy set), then `trophyGroupId` should be set to `"all"`. + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophiesEarnedForTitle = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, npCommunicationId, trophyGroupId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", options, { + accountId: accountId, + npCommunicationId: npCommunicationId, + trophyGroupId: trophyGroupId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophiesEarnedForTitle(_x, _x2, _x3, _x4, _x5) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A request to this endpoint function will retrieve a summary of the trophies earned for + * a user broken down by trophy group within a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, + * and additional groups beginning with the name `"001"` and incrementing for + * each additional group). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function calls an endpoint that returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophyGroupEarningsForTitle = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, npCommunicationId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups", options, { + accountId: accountId, + npCommunicationId: npCommunicationId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophyGroupEarningsForTitle(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve an overall summary of the number of + * trophies earned for a user broken down by grade, as well as their current + * overall trophy level, progress towards the next level, and which tier their + * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophyProfileSummary = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/trophySummary", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophyProfileSummary(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var USER_BASE_URL = "https://m.np.playstation.com/api/userProfile/v1/internal/users"; + +/** + * A call to this function will retrieve some profile information of the accountId being requested. + * If the account's profile cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The accountId for the user you wish to retrieve a profile for. + */ +var getProfileFromAccountId = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(USER_BASE_URL, "/:accountId/profiles", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getProfileFromAccountId(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the profile of the username being requested. + * If the user cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * This is a legacy API endpoint function. If you are just trying to get a user's + * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) + * is recommended instead. This endpoint is here because it can return interesting + * presence information when the user is playing on a legacy console such as a PS3. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param userName The username for the user you wish to retrieve a profile for. + */ +var getProfileFromUserName = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, userName) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = "https://us-prof.np.community.playstation.net/userProfile/v1/users/" + userName + "/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability"; + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getProfileFromUserName(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the list of friended `accountId` values + * associated with the given `accountId` parameter. If the user cannot be found + * (either due to non-existence or privacy settings), an error will be thrown. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + */ +var getUserFriendsAccountIds = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(USER_BASE_URL, "/:accountId/friends", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserFriendsAccountIds(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +exports.call = call; +exports.exchangeCodeForAccessToken = exchangeCodeForAccessToken; +exports.exchangeNpssoForCode = exchangeNpssoForCode; +exports.exchangeRefreshTokenForAuthTokens = exchangeRefreshTokenForAuthTokens; +exports.getProfileFromAccountId = getProfileFromAccountId; +exports.getProfileFromUserName = getProfileFromUserName; +exports.getRecentlyPlayedGames = getRecentlyPlayedGames; +exports.getTitleTrophies = getTitleTrophies; +exports.getTitleTrophyGroups = getTitleTrophyGroups; +exports.getUserFriendsAccountIds = getUserFriendsAccountIds; +exports.getUserTitles = getUserTitles; +exports.getUserTrophiesEarnedForTitle = getUserTrophiesEarnedForTitle; +exports.getUserTrophyGroupEarningsForTitle = getUserTrophyGroupEarningsForTitle; +exports.getUserTrophyProfileSummary = getUserTrophyProfileSummary; +exports.makeUniversalSearch = makeUniversalSearch; +//# sourceMappingURL=psn-api.cjs.development.js.map diff --git a/node_modules/psn-api/dist/psn-api.cjs.development.js.map b/node_modules/psn-api/dist/psn-api.cjs.development.js.map new file mode 100644 index 0000000..e001c49 --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.cjs.development.js.map @@ -0,0 +1 @@ +{"version":3,"file":"psn-api.cjs.development.js","sources":["../src/authenticate/AUTH_BASE_URL.ts","../src/authenticate/exchangeCodeForAccessToken.ts","../src/authenticate/exchangeNpssoForCode.ts","../src/authenticate/exchangeRefreshTokenForAuthTokens.ts","../src/utils/call.ts","../src/graphql/GRAPHQL_BASE_URL.ts","../src/graphql/operationHashes.ts","../src/graphql/getRecentlyPlayedGames.ts","../src/models/trophy-rarity.model.ts","../src/utils/buildRequestUrl.ts","../src/search/SEARCH_BASE_URL.ts","../src/search/makeUniversalSearch.ts","../src/trophy/TROPHY_BASE_URL.ts","../src/trophy/title/getTitleTrophies.ts","../src/trophy/title/getTitleTrophyGroups.ts","../src/trophy/user/getUserTitles.ts","../src/trophy/user/getUserTrophiesEarnedForTitle.ts","../src/trophy/user/getUserTrophyGroupEarningsForTitle.ts","../src/trophy/user/getUserTrophyProfileSummary.ts","../src/user/USER_BASE_URL.ts","../src/user/getProfileFromAccountId.ts","../src/user/getProfileFromUserName.ts","../src/user/getUserFriendsAccountIds.ts"],"sourcesContent":["export const AUTH_BASE_URL = \"https://ca.account.sony.com/api/authz/v3/oauth\";\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`.\n * @returns An object containing an access token, refresh token, and expiry times for both.\n */\nexport const exchangeCodeForAccessToken = async (\n accessCode: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n code: accessCode,\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n grant_type: \"authorization_code\",\n token_format: \"jwt\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n *\n * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie\n * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`.\n * @example\n * ```ts\n * const code = await exchangeNpssoForCode(\"myNpssoToken\");\n *\n * console.log(code) // --> \"v3.XXXXXX\"\n * ```\n */\nexport const exchangeNpssoForCode = async (\n npssoToken: string\n): Promise => {\n const queryString = new URLSearchParams({\n access_type: \"offline\",\n client_id: \"09515159-7237-4370-9b40-3806e67c0891\",\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n response_type: \"code\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString();\n\n const requestUrl = `${AUTH_BASE_URL}/authorize?${queryString}`;\n\n // This never returns a 200. As of Oct 10 2021, it seems to return a 302.\n const { headers: responseHeaders } = await fetch(requestUrl, {\n headers: {\n Cookie: `npsso=${npssoToken}`\n },\n redirect: \"manual\"\n });\n\n // The access code itself is stored in a header on the response.\n // We'll perform a few validations to ensure it's actually there.\n if (\n !responseHeaders.has(\"location\") ||\n !responseHeaders.get(\"location\")?.includes(\"?code=\")\n ) {\n throw new Error(`\n There was a problem retrieving your PSN access code. Is your NPSSO code valid?\n To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie.\n `);\n }\n\n const redirectLocation = responseHeaders.get(\"location\") as string;\n const redirectParams = new URLSearchParams(\n redirectLocation.split(\"redirect/\")[1]\n );\n\n return redirectParams.get(\"code\") as string;\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\nexport const exchangeRefreshTokenForAuthTokens = async (\n refreshToken: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n refresh_token: refreshToken,\n grant_type: \"refresh_token\",\n token_format: \"jwt\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthorizationPayload, CallValidHeaders } from \"../models\";\n\nexport const call = async (\n config: {\n url: string;\n method?: \"GET\" | \"POST\";\n headers?: CallValidHeaders;\n },\n authorization: AuthorizationPayload,\n bodyPayload?: Record\n) => {\n const response = await fetch(config.url, {\n method: config?.method ?? \"GET\",\n headers: {\n Authorization: `Bearer ${authorization.accessToken}`,\n \"Content-Type\": \"application/json\",\n ...config?.headers\n },\n body: JSON.stringify(bodyPayload)\n });\n\n return (await response.json()) as T;\n};\n","export const GRAPHQL_BASE_URL =\n \"https://web.np.playstation.com/api/graphql/v1/op\";\n","/**\n * GraphQL endpoints work differently to others in the codebase.\n *\n * The hashes in this file are reverse engineered from app-.js file loaded by the page\n * at https://library.playstation.com/recently-played. Following the code in that file leads\n * to some Apollo GraphQL code related to persisted queries. This means the request needs to\n * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink\n * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging\n * will surface the exact GraphQL query that's passed to the hash function on the page.\n *\n * Thankfully it's easier to figure out future endpoints and hashes by:\n *\n * 1. Visiting a page, e.g https://library.playstation.com/recently-played\n * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op\n * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters\n */\n\n// Hash is computed from the following query (without surrounding quotes):\n// \"query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\\n __typename\\n games {\\n __typename\\n conceptId\\n entitlementId\\n image {\\n __typename\\n url\\n }\\n isActive\\n lastPlayedDateTime\\n name\\n platform\\n productId\\n subscriptionService\\n titleId\\n }\\n }\\n}\\n\"\nexport const getUserGameListHash =\n \"e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n RecentlyPlayedGamesResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\nimport { GRAPHQL_BASE_URL } from \"./GRAPHQL_BASE_URL\";\nimport { getUserGameListHash } from \"./operationHashes\";\n\ntype GetRecentlyPlayedGamesOptionsCategories = \"ps4_game\" | \"ps5_native_game\";\ntype GetRecentlyPlayedGamesOptions = Pick & {\n categories: GetRecentlyPlayedGamesOptionsCategories[];\n};\n\n/**\n * A call to this function will retrieve recently played games for the user associated\n * with the npsso token provided to this module during initialisation.\n *\n * This is useful if you want recent activity that isn't tied to trophy progress.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n */\nexport const getRecentlyPlayedGames = async (\n authorization: AuthorizationPayload,\n options: Partial = {}\n): Promise => {\n const { limit = 50, categories = [\"ps4_game\", \"ps5_native_game\"] } = options;\n\n const url = new URL(GRAPHQL_BASE_URL);\n\n url.searchParams.set(\"operationName\", \"getUserGameList\");\n url.searchParams.set(\n \"variables\",\n JSON.stringify({\n limit,\n categories: categories.join(\",\")\n })\n );\n url.searchParams.set(\n \"extensions\",\n JSON.stringify({\n persistedQuery: {\n version: 1,\n sha256Hash: getUserGameListHash\n }\n })\n );\n\n const response = await call(\n { url: url.toString() },\n authorization\n );\n\n // The GraphQL queries can return non-truthy values.\n if (!response.data || !response.data.gameLibraryTitlesRetrieve) {\n throw new Error(JSON.stringify(response));\n }\n\n return response;\n};\n","export enum TrophyRarity {\n UltraRare,\n VeryRare,\n Rare,\n Common\n}\n","import type { AllCallOptions } from \"../models\";\n\nexport const buildRequestUrl = (\n baseUrl: string,\n endpointUrl: string,\n options: Partial = {},\n args: Record = {}\n) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick.\n const { headerOverrides, ...pickedOptions } = options;\n\n const concatenated = `${baseUrl}/${endpointUrl}`;\n const withoutDoubleSlashes = concatenated.replace(/([^:]\\/)\\/+/g, \"$1\");\n\n let withArgs = withoutDoubleSlashes;\n const queryParamValues: Record = {};\n\n for (const [argKey, argValue] of Object.entries({\n ...args,\n ...pickedOptions\n })) {\n if (withArgs.includes(`:${argKey}`)) {\n withArgs = withArgs.replace(`:${argKey}`, String(argValue));\n } else if (argValue !== undefined) {\n queryParamValues[argKey] = String(argValue);\n }\n }\n\n const queryString = new URLSearchParams(queryParamValues).toString();\n return queryString.length > 0 ? `${withArgs}?${queryString}` : withArgs;\n};\n","export const SEARCH_BASE_URL = \"https://m.np.playstation.com/api/search\";\n","import type {\n AuthorizationPayload,\n SocialAccountResult,\n UniversalSearchDomains,\n UniversalSearchResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { SEARCH_BASE_URL } from \"./SEARCH_BASE_URL\";\n\nexport const makeUniversalSearch = async (\n authorization: AuthorizationPayload,\n searchTerm: string,\n domain: R\n) => {\n const url = buildRequestUrl(SEARCH_BASE_URL, \"/v1/universalSearch\");\n\n type AssertType = R extends \"SocialAllAccounts\"\n ? SocialAccountResult\n : unknown;\n\n return await call>>(\n { url, method: \"POST\" },\n authorization,\n {\n searchTerm,\n domainRequests: [\n {\n domain\n }\n ]\n }\n );\n};\n","export const TROPHY_BASE_URL = \"https://m.np.playstation.com/api/trophy\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophiesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophiesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"npServiceName\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve the trophy list of a\n * single - or all - trophy groups for a title. A title can have multiple\n * groups of trophies (a `\"default\"` group which all titles have, and additional\n * groups starting with the name `\"001\"` and incrementing for each additional group). To retrieve\n * trophies from all groups within a title (ie. the full trophy set), then\n * `trophyGroupId` should be set to `\"all\"`.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` parameter as `\"trophy\"`.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophies = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { npCommunicationId, trophyGroupId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophyGroupsResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophyGroupsOptions = Pick<\n AllCallOptions,\n \"npServiceName\" | \"headerOverrides\"\n>;\n\n/**\n * A title may have multiple groups of trophies. This is most commonly\n * seen in games which have DLC expansions where additional trophies are added.\n *\n * You can call this function for a specific title - using the\n * unique `npCommunicationId` for the title - and you will receive a\n * summary of all of the trophy groups associated with the title.\n * This also includes a summary of the number of trophies for the\n * title, broken down by group and grade (gold, silver, etc.).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophyGroups = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { npCommunicationId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTitlesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTitlesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve a summarized list of titles played\n * by a user, ordered by recent trophy unlocks. The maximum amount that can\n * be returned by a single call is 800 (assuming a `limit` option of 800 is set).\n * If the user has more titles than the given `limit` option, subsequent calls\n * of this funciton must be made to fetch the complete list by paging via the\n * `offset` option.\n *\n * The numeric `accountId` can be that of any PSN account for which the authenticating\n * account has permissions to view the trophy list. When querying the titles\n * associated with the authenticating account, the numeric `accountId` can be\n * substituted with `\"me\"`.\n *\n * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()`\n * function can be used.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * Included in the information returned is the titles' unique `npCommunicationId`.\n * This is required to make use of subsequent functions for requesting more specific\n * detail about a title's trophies.\n *\n * The results are presented in order of the `lastUpdatedDateTime` for the title,\n * so the first result will be the title for which a trophy was most recently earned\n * (or synced for the first time in the case of a game with 0% progress).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.limit Limit the number of titles returned.\n * @param options.offset Return title data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTitles = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophyTitles\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophiesEarnedForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophiesEarnedForTitleOptions = Pick<\n AllCallOptions,\n \"offset\" | \"npServiceName\" | \"limit\" | \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve the earned status of trophies for a user\n * from either a single - or all - trophy groups in a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have, and\n * additional groups starting with a name of `\"001\"` and incrementing for each\n * additional group). To retrieve trophies from all groups within a title\n * (ie. the full trophy set), then `trophyGroupId` should be set to `\"all\"`.\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophiesEarnedForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { accountId, npCommunicationId, trophyGroupId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n CallValidHeaders,\n UserTrophyGroupEarningsForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ninterface GetUserTrophyGroupEarningsForTitleOptions {\n /**\n * Not required unless the platform is PS3, PS4, or PS Vita.\n * If one of these platforms, the value __must__ be `\"trophy\"`.\n *\n * `\"trophy\"` for PS3, PS4, or PS Vita platforms.\n * `\"trophy2\"` for the PS5 platform.\n */\n npServiceName: \"trophy\" | \"trophy2\";\n\n /*\n * Override the headers in the request to the PSN API,\n * such as to change the language.\n */\n headerOverrides: CallValidHeaders;\n}\n\n/**\n * A request to this endpoint function will retrieve a summary of the trophies earned for\n * a user broken down by trophy group within a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have,\n * and additional groups beginning with the name `\"001\"` and incrementing for\n * each additional group).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function calls an endpoint that returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyGroupEarningsForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { accountId, npCommunicationId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophyProfileSummaryResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophyProfileSummaryOptions = Pick<\n AllCallOptions,\n \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve an overall summary of the number of\n * trophies earned for a user broken down by grade, as well as their current\n * overall trophy level, progress towards the next level, and which tier their\n * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyProfileSummary = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophySummary\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","export const USER_BASE_URL =\n \"https://m.np.playstation.com/api/userProfile/v1/internal/users\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n ProfileFromAccountIdResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetProfileFromAccountIdOptions = Pick;\n\n/**\n * A call to this function will retrieve some profile information of the accountId being requested.\n * If the account's profile cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The accountId for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromAccountId = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: GetProfileFromAccountIdOptions\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/profiles\", options, {\n accountId\n });\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n ProfileFromUserNameResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\n\n/**\n * A call to this function will retrieve the profile of the username being requested.\n * If the user cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * This is a legacy API endpoint function. If you are just trying to get a user's\n * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch)\n * is recommended instead. This endpoint is here because it can return interesting\n * presence information when the user is playing on a legacy console such as a PS3.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param userName The username for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromUserName = async (\n authorization: AuthorizationPayload,\n userName: string\n): Promise => {\n const url = `https://us-prof.np.community.playstation.net/userProfile/v1/users/${userName}/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability`;\n\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n GetUserFriendsAccountIdsResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetUserFriendsAccountIdsOptions = Pick;\n\n/**\n * A call to this function will retrieve the list of friended `accountId` values\n * associated with the given `accountId` parameter. If the user cannot be found\n * (either due to non-existence or privacy settings), an error will be thrown.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n */\nexport const getUserFriendsAccountIds = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/friends\", options, {\n accountId\n });\n\n const response = await call(\n { url },\n authorization\n );\n\n // If you are unable to access the user's friends list, a\n // \"Not permitted by access control\" error will be thrown.\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n"],"names":["AUTH_BASE_URL","exchangeCodeForAccessToken","accessCode","requestUrl","fetch","method","headers","Authorization","body","URLSearchParams","code","redirect_uri","grant_type","token_format","toString","res","json","raw","accessToken","access_token","expiresIn","expires_in","idToken","id_token","refreshToken","refresh_token","refreshTokenExpiresIn","refresh_token_expires_in","scope","tokenType","token_type","exchangeNpssoForCode","npssoToken","queryString","access_type","client_id","response_type","Cookie","redirect","responseHeaders","has","get","includes","Error","redirectLocation","redirectParams","split","exchangeRefreshTokenForAuthTokens","call","config","authorization","bodyPayload","url","JSON","stringify","response","GRAPHQL_BASE_URL","getUserGameListHash","getRecentlyPlayedGames","options","limit","categories","URL","searchParams","set","join","persistedQuery","version","sha256Hash","data","gameLibraryTitlesRetrieve","TrophyRarity","buildRequestUrl","baseUrl","endpointUrl","args","headerOverrides","pickedOptions","concatenated","withoutDoubleSlashes","replace","withArgs","queryParamValues","Object","entries","argKey","argValue","String","undefined","length","SEARCH_BASE_URL","makeUniversalSearch","searchTerm","domain","domainRequests","TROPHY_BASE_URL","getTitleTrophies","npCommunicationId","trophyGroupId","getTitleTrophyGroups","getUserTitles","accountId","getUserTrophiesEarnedForTitle","error","message","getUserTrophyGroupEarningsForTitle","getUserTrophyProfileSummary","USER_BASE_URL","getProfileFromAccountId","getProfileFromUserName","userName","getUserFriendsAccountIds"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/psn-api/dist/psn-api.cjs.production.min.js b/node_modules/psn-api/dist/psn-api.cjs.production.min.js new file mode 100644 index 0000000..ce959ff --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.cjs.production.min.js @@ -0,0 +1,2 @@ +"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var r=e(require("isomorphic-unfetch"));function t(){t=function(){return e};var e={},r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(e,r,t){e[r]=t.value},a="function"==typeof Symbol?Symbol:{},i=a.iterator||"@@iterator",c=a.asyncIterator||"@@asyncIterator",s=a.toStringTag||"@@toStringTag";function u(e,r,t){return Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}),e[r]}try{u({},"")}catch(e){u=function(e,r,t){return e[r]=t}}function p(e,r,t,n){var a=Object.create((r&&r.prototype instanceof f?r:f).prototype),i=new I(n||[]);return o(a,"_invoke",{value:k(e,t,i)}),a}function l(e,r,t){try{return{type:"normal",arg:e.call(r,t)}}catch(e){return{type:"throw",arg:e}}}e.wrap=p;var h={};function f(){}function d(){}function v(){}var y={};u(y,i,(function(){return this}));var m=Object.getPrototypeOf,g=m&&m(m(E([])));g&&g!==r&&n.call(g,i)&&(y=g);var w=v.prototype=f.prototype=Object.create(y);function x(e){["next","throw","return"].forEach((function(r){u(e,r,(function(e){return this._invoke(r,e)}))}))}function b(e,r){function t(o,a,i,c){var s=l(e[o],e,a);if("throw"!==s.type){var u=s.arg,p=u.value;return p&&"object"==typeof p&&n.call(p,"__await")?r.resolve(p.__await).then((function(e){t("next",e,i,c)}),(function(e){t("throw",e,i,c)})):r.resolve(p).then((function(e){u.value=e,i(u)}),(function(e){return t("throw",e,i,c)}))}c(s.arg)}var a;o(this,"_invoke",{value:function(e,n){function o(){return new r((function(r,o){t(e,n,r,o)}))}return a=a?a.then(o,o):o()}})}function k(e,r,t){var n="suspendedStart";return function(o,a){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw a;return{value:void 0,done:!0}}for(t.method=o,t.arg=a;;){var i=t.delegate;if(i){var c=T(i,t);if(c){if(c===h)continue;return c}}if("next"===t.method)t.sent=t._sent=t.arg;else if("throw"===t.method){if("suspendedStart"===n)throw n="completed",t.arg;t.dispatchException(t.arg)}else"return"===t.method&&t.abrupt("return",t.arg);n="executing";var s=l(e,r,t);if("normal"===s.type){if(n=t.done?"completed":"suspendedYield",s.arg===h)continue;return{value:s.arg,done:t.done}}"throw"===s.type&&(n="completed",t.method="throw",t.arg=s.arg)}}}function T(e,r){var t=r.method,n=e.iterator[t];if(void 0===n)return r.delegate=null,"throw"===t&&e.iterator.return&&(r.method="return",r.arg=void 0,T(e,r),"throw"===r.method)||"return"!==t&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+t+"' method")),h;var o=l(n,e.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,h;var a=o.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,h):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,h)}function _(e){var r={tryLoc:e[0]};1 in e&&(r.catchLoc=e[1]),2 in e&&(r.finallyLoc=e[2],r.afterLoc=e[3]),this.tryEntries.push(r)}function O(e){var r=e.completion||{};r.type="normal",delete r.arg,e.completion=r}function I(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(_,this),this.reset(!0)}function E(e){if(e){var r=e[i];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var t=-1,o=function r(){for(;++t=0;--o){var a=this.tryEntries[o],i=a.completion;if("root"===a.tryLoc)return t("end");if(a.tryLoc<=this.prev){var c=n.call(a,"catchLoc"),s=n.call(a,"finallyLoc");if(c&&s){if(this.prev=0;--t){var o=this.tryEntries[t];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--r){var t=this.tryEntries[r];if(t.finallyLoc===e)return this.complete(t.completion,t.afterLoc),O(t),h}},catch:function(e){for(var r=this.tryEntries.length-1;r>=0;--r){var t=this.tryEntries[r];if(t.tryLoc===e){var n=t.completion;if("throw"===n.type){var o=n.arg;O(t)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,t){return this.delegate={iterator:E(e),resultName:r,nextLoc:t},"next"===this.method&&(this.arg=void 0),h}},e}function n(e,r,t,n,o,a,i){try{var c=e[a](i),s=c.value}catch(e){return void t(e)}c.done?r(s):Promise.resolve(s).then(n,o)}function o(e){return function(){var r=this,t=arguments;return new Promise((function(o,a){var i=e.apply(r,t);function c(e){n(i,o,a,c,s,"next",e)}function s(e){n(i,o,a,c,s,"throw",e)}c(void 0)}))}}function a(){return a=Object.assign?Object.assign.bind():function(e){for(var r=1;r=0||(o[t]=e[t]);return o}(t,h),i=(e+"/"+r).replace(/([^:]\/)\/+/g,"$1"),c={},s=0,u=Object.entries(a({},n,o));s0?i+"?"+d:i},d=function(){var e=o(t().mark((function e(r,n,o){var a;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f("https://m.np.playstation.com/api/search","/v1/universalSearch"),e.next=3,p({url:a,method:"POST"},r,{searchTerm:n,domainRequests:[{domain:o}]});case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}(),v="https://m.np.playstation.com/api/trophy",y=function(){var e=o(t().mark((function e(r,n,o,a){var i;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return i=f(v,"/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies",a,{npCommunicationId:n,trophyGroupId:o}),e.next=3,p({url:i,headers:null==a?void 0:a.headerOverrides},r);case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)})));return function(r,t,n,o){return e.apply(this,arguments)}}(),m=function(){var e=o(t().mark((function e(r,n,o){var a;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f(v,"/v1/npCommunicationIds/:npCommunicationId/trophyGroups",o,{npCommunicationId:n}),e.next=3,p({url:a,headers:null==o?void 0:o.headerOverrides},r);case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}(),g=function(){var e=o(t().mark((function e(r,n,o){var a;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f(v,"/v1/users/:accountId/trophyTitles",o,{accountId:n}),e.next=3,p({url:a,headers:null==o?void 0:o.headerOverrides},r);case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}(),w=function(){var e=o(t().mark((function e(r,n,o,a,i){var c,s,u,l;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c=f(v,"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies",i,{accountId:n,npCommunicationId:o,trophyGroupId:a}),e.next=3,p({url:c,headers:null==i?void 0:i.headerOverrides},r);case 3:if(null==(s=e.sent)||!s.error){e.next=6;break}throw new Error(null!=(u=null==s||null==(l=s.error)?void 0:l.message)?u:"Unexpected Error");case 6:return e.abrupt("return",s);case 7:case"end":return e.stop()}}),e)})));return function(r,t,n,o,a){return e.apply(this,arguments)}}(),x=function(){var e=o(t().mark((function e(r,n,o,a){var i,c,s,u;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return i=f(v,"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups",a,{accountId:n,npCommunicationId:o}),e.next=3,p({url:i,headers:null==a?void 0:a.headerOverrides},r);case 3:if(null==(c=e.sent)||!c.error){e.next=6;break}throw new Error(null!=(s=null==c||null==(u=c.error)?void 0:u.message)?s:"Unexpected Error");case 6:return e.abrupt("return",c);case 7:case"end":return e.stop()}}),e)})));return function(r,t,n,o){return e.apply(this,arguments)}}(),b=function(){var e=o(t().mark((function e(r,n,o){var a;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f(v,"/v1/users/:accountId/trophySummary",o,{accountId:n}),e.next=3,p({url:a,headers:null==o?void 0:o.headerOverrides},r);case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}(),k="https://m.np.playstation.com/api/userProfile/v1/internal/users",T=function(){var e=o(t().mark((function e(r,n,o){var a,i,c,s;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f(k,"/:accountId/profiles",o,{accountId:n}),e.next=3,p({url:a},r);case 3:if(null==(i=e.sent)||!i.error){e.next=6;break}throw new Error(null!=(c=null==i||null==(s=i.error)?void 0:s.message)?c:"Unexpected Error");case 6:return e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}(),_=function(){var e=o(t().mark((function e(r,n){var o,a,i,c;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return o="https://us-prof.np.community.playstation.net/userProfile/v1/users/"+n+"/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability",e.next=3,p({url:o},r);case 3:if(null==(a=e.sent)||!a.error){e.next=6;break}throw new Error(null!=(i=null==a||null==(c=a.error)?void 0:c.message)?i:"Unexpected Error");case 6:return e.abrupt("return",a);case 7:case"end":return e.stop()}}),e)})));return function(r,t){return e.apply(this,arguments)}}(),O=function(){var e=o(t().mark((function e(r,n,o){var a,i,c,s;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=f(k,"/:accountId/friends",o,{accountId:n}),e.next=3,p({url:a},r);case 3:if(null==(i=e.sent)||!i.error){e.next=6;break}throw new Error(null!=(c=null==i||null==(s=i.error)?void 0:s.message)?c:"Unexpected Error");case 6:return e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})));return function(r,t,n){return e.apply(this,arguments)}}();exports.call=p,exports.exchangeCodeForAccessToken=c,exports.exchangeNpssoForCode=s,exports.exchangeRefreshTokenForAuthTokens=u,exports.getProfileFromAccountId=T,exports.getProfileFromUserName=_,exports.getRecentlyPlayedGames=l,exports.getTitleTrophies=y,exports.getTitleTrophyGroups=m,exports.getUserFriendsAccountIds=O,exports.getUserTitles=g,exports.getUserTrophiesEarnedForTitle=w,exports.getUserTrophyGroupEarningsForTitle=x,exports.getUserTrophyProfileSummary=b,exports.makeUniversalSearch=d; +//# sourceMappingURL=psn-api.cjs.production.min.js.map diff --git a/node_modules/psn-api/dist/psn-api.cjs.production.min.js.map b/node_modules/psn-api/dist/psn-api.cjs.production.min.js.map new file mode 100644 index 0000000..5235487 --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.cjs.production.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"psn-api.cjs.production.min.js","sources":["../src/authenticate/AUTH_BASE_URL.ts","../src/models/trophy-rarity.model.ts","../src/authenticate/exchangeCodeForAccessToken.ts","../src/authenticate/exchangeNpssoForCode.ts","../src/authenticate/exchangeRefreshTokenForAuthTokens.ts","../src/utils/call.ts","../src/graphql/getRecentlyPlayedGames.ts","../src/graphql/GRAPHQL_BASE_URL.ts","../src/graphql/operationHashes.ts","../src/utils/buildRequestUrl.ts","../src/search/makeUniversalSearch.ts","../src/search/SEARCH_BASE_URL.ts","../src/trophy/TROPHY_BASE_URL.ts","../src/trophy/title/getTitleTrophies.ts","../src/trophy/title/getTitleTrophyGroups.ts","../src/trophy/user/getUserTitles.ts","../src/trophy/user/getUserTrophiesEarnedForTitle.ts","../src/trophy/user/getUserTrophyGroupEarningsForTitle.ts","../src/trophy/user/getUserTrophyProfileSummary.ts","../src/user/USER_BASE_URL.ts","../src/user/getProfileFromAccountId.ts","../src/user/getProfileFromUserName.ts","../src/user/getUserFriendsAccountIds.ts"],"sourcesContent":["export const AUTH_BASE_URL = \"https://ca.account.sony.com/api/authz/v3/oauth\";\n","export enum TrophyRarity {\n UltraRare,\n VeryRare,\n Rare,\n Common\n}\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`.\n * @returns An object containing an access token, refresh token, and expiry times for both.\n */\nexport const exchangeCodeForAccessToken = async (\n accessCode: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n code: accessCode,\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n grant_type: \"authorization_code\",\n token_format: \"jwt\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n *\n * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie\n * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`.\n * @example\n * ```ts\n * const code = await exchangeNpssoForCode(\"myNpssoToken\");\n *\n * console.log(code) // --> \"v3.XXXXXX\"\n * ```\n */\nexport const exchangeNpssoForCode = async (\n npssoToken: string\n): Promise => {\n const queryString = new URLSearchParams({\n access_type: \"offline\",\n client_id: \"09515159-7237-4370-9b40-3806e67c0891\",\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n response_type: \"code\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString();\n\n const requestUrl = `${AUTH_BASE_URL}/authorize?${queryString}`;\n\n // This never returns a 200. As of Oct 10 2021, it seems to return a 302.\n const { headers: responseHeaders } = await fetch(requestUrl, {\n headers: {\n Cookie: `npsso=${npssoToken}`\n },\n redirect: \"manual\"\n });\n\n // The access code itself is stored in a header on the response.\n // We'll perform a few validations to ensure it's actually there.\n if (\n !responseHeaders.has(\"location\") ||\n !responseHeaders.get(\"location\")?.includes(\"?code=\")\n ) {\n throw new Error(`\n There was a problem retrieving your PSN access code. Is your NPSSO code valid?\n To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie.\n `);\n }\n\n const redirectLocation = responseHeaders.get(\"location\") as string;\n const redirectParams = new URLSearchParams(\n redirectLocation.split(\"redirect/\")[1]\n );\n\n return redirectParams.get(\"code\") as string;\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\nexport const exchangeRefreshTokenForAuthTokens = async (\n refreshToken: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n refresh_token: refreshToken,\n grant_type: \"refresh_token\",\n token_format: \"jwt\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthorizationPayload, CallValidHeaders } from \"../models\";\n\nexport const call = async (\n config: {\n url: string;\n method?: \"GET\" | \"POST\";\n headers?: CallValidHeaders;\n },\n authorization: AuthorizationPayload,\n bodyPayload?: Record\n) => {\n const response = await fetch(config.url, {\n method: config?.method ?? \"GET\",\n headers: {\n Authorization: `Bearer ${authorization.accessToken}`,\n \"Content-Type\": \"application/json\",\n ...config?.headers\n },\n body: JSON.stringify(bodyPayload)\n });\n\n return (await response.json()) as T;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n RecentlyPlayedGamesResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\nimport { GRAPHQL_BASE_URL } from \"./GRAPHQL_BASE_URL\";\nimport { getUserGameListHash } from \"./operationHashes\";\n\ntype GetRecentlyPlayedGamesOptionsCategories = \"ps4_game\" | \"ps5_native_game\";\ntype GetRecentlyPlayedGamesOptions = Pick & {\n categories: GetRecentlyPlayedGamesOptionsCategories[];\n};\n\n/**\n * A call to this function will retrieve recently played games for the user associated\n * with the npsso token provided to this module during initialisation.\n *\n * This is useful if you want recent activity that isn't tied to trophy progress.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n */\nexport const getRecentlyPlayedGames = async (\n authorization: AuthorizationPayload,\n options: Partial = {}\n): Promise => {\n const { limit = 50, categories = [\"ps4_game\", \"ps5_native_game\"] } = options;\n\n const url = new URL(GRAPHQL_BASE_URL);\n\n url.searchParams.set(\"operationName\", \"getUserGameList\");\n url.searchParams.set(\n \"variables\",\n JSON.stringify({\n limit,\n categories: categories.join(\",\")\n })\n );\n url.searchParams.set(\n \"extensions\",\n JSON.stringify({\n persistedQuery: {\n version: 1,\n sha256Hash: getUserGameListHash\n }\n })\n );\n\n const response = await call(\n { url: url.toString() },\n authorization\n );\n\n // The GraphQL queries can return non-truthy values.\n if (!response.data || !response.data.gameLibraryTitlesRetrieve) {\n throw new Error(JSON.stringify(response));\n }\n\n return response;\n};\n","export const GRAPHQL_BASE_URL =\n \"https://web.np.playstation.com/api/graphql/v1/op\";\n","/**\n * GraphQL endpoints work differently to others in the codebase.\n *\n * The hashes in this file are reverse engineered from app-.js file loaded by the page\n * at https://library.playstation.com/recently-played. Following the code in that file leads\n * to some Apollo GraphQL code related to persisted queries. This means the request needs to\n * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink\n * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging\n * will surface the exact GraphQL query that's passed to the hash function on the page.\n *\n * Thankfully it's easier to figure out future endpoints and hashes by:\n *\n * 1. Visiting a page, e.g https://library.playstation.com/recently-played\n * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op\n * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters\n */\n\n// Hash is computed from the following query (without surrounding quotes):\n// \"query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\\n __typename\\n games {\\n __typename\\n conceptId\\n entitlementId\\n image {\\n __typename\\n url\\n }\\n isActive\\n lastPlayedDateTime\\n name\\n platform\\n productId\\n subscriptionService\\n titleId\\n }\\n }\\n}\\n\"\nexport const getUserGameListHash =\n \"e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae\";\n","import type { AllCallOptions } from \"../models\";\n\nexport const buildRequestUrl = (\n baseUrl: string,\n endpointUrl: string,\n options: Partial = {},\n args: Record = {}\n) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick.\n const { headerOverrides, ...pickedOptions } = options;\n\n const concatenated = `${baseUrl}/${endpointUrl}`;\n const withoutDoubleSlashes = concatenated.replace(/([^:]\\/)\\/+/g, \"$1\");\n\n let withArgs = withoutDoubleSlashes;\n const queryParamValues: Record = {};\n\n for (const [argKey, argValue] of Object.entries({\n ...args,\n ...pickedOptions\n })) {\n if (withArgs.includes(`:${argKey}`)) {\n withArgs = withArgs.replace(`:${argKey}`, String(argValue));\n } else if (argValue !== undefined) {\n queryParamValues[argKey] = String(argValue);\n }\n }\n\n const queryString = new URLSearchParams(queryParamValues).toString();\n return queryString.length > 0 ? `${withArgs}?${queryString}` : withArgs;\n};\n","import type {\n AuthorizationPayload,\n SocialAccountResult,\n UniversalSearchDomains,\n UniversalSearchResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { SEARCH_BASE_URL } from \"./SEARCH_BASE_URL\";\n\nexport const makeUniversalSearch = async (\n authorization: AuthorizationPayload,\n searchTerm: string,\n domain: R\n) => {\n const url = buildRequestUrl(SEARCH_BASE_URL, \"/v1/universalSearch\");\n\n type AssertType = R extends \"SocialAllAccounts\"\n ? SocialAccountResult\n : unknown;\n\n return await call>>(\n { url, method: \"POST\" },\n authorization,\n {\n searchTerm,\n domainRequests: [\n {\n domain\n }\n ]\n }\n );\n};\n","export const SEARCH_BASE_URL = \"https://m.np.playstation.com/api/search\";\n","export const TROPHY_BASE_URL = \"https://m.np.playstation.com/api/trophy\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophiesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophiesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"npServiceName\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve the trophy list of a\n * single - or all - trophy groups for a title. A title can have multiple\n * groups of trophies (a `\"default\"` group which all titles have, and additional\n * groups starting with the name `\"001\"` and incrementing for each additional group). To retrieve\n * trophies from all groups within a title (ie. the full trophy set), then\n * `trophyGroupId` should be set to `\"all\"`.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` parameter as `\"trophy\"`.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophies = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { npCommunicationId, trophyGroupId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophyGroupsResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophyGroupsOptions = Pick<\n AllCallOptions,\n \"npServiceName\" | \"headerOverrides\"\n>;\n\n/**\n * A title may have multiple groups of trophies. This is most commonly\n * seen in games which have DLC expansions where additional trophies are added.\n *\n * You can call this function for a specific title - using the\n * unique `npCommunicationId` for the title - and you will receive a\n * summary of all of the trophy groups associated with the title.\n * This also includes a summary of the number of trophies for the\n * title, broken down by group and grade (gold, silver, etc.).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophyGroups = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { npCommunicationId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTitlesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTitlesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve a summarized list of titles played\n * by a user, ordered by recent trophy unlocks. The maximum amount that can\n * be returned by a single call is 800 (assuming a `limit` option of 800 is set).\n * If the user has more titles than the given `limit` option, subsequent calls\n * of this funciton must be made to fetch the complete list by paging via the\n * `offset` option.\n *\n * The numeric `accountId` can be that of any PSN account for which the authenticating\n * account has permissions to view the trophy list. When querying the titles\n * associated with the authenticating account, the numeric `accountId` can be\n * substituted with `\"me\"`.\n *\n * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()`\n * function can be used.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * Included in the information returned is the titles' unique `npCommunicationId`.\n * This is required to make use of subsequent functions for requesting more specific\n * detail about a title's trophies.\n *\n * The results are presented in order of the `lastUpdatedDateTime` for the title,\n * so the first result will be the title for which a trophy was most recently earned\n * (or synced for the first time in the case of a game with 0% progress).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.limit Limit the number of titles returned.\n * @param options.offset Return title data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTitles = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophyTitles\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophiesEarnedForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophiesEarnedForTitleOptions = Pick<\n AllCallOptions,\n \"offset\" | \"npServiceName\" | \"limit\" | \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve the earned status of trophies for a user\n * from either a single - or all - trophy groups in a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have, and\n * additional groups starting with a name of `\"001\"` and incrementing for each\n * additional group). To retrieve trophies from all groups within a title\n * (ie. the full trophy set), then `trophyGroupId` should be set to `\"all\"`.\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophiesEarnedForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { accountId, npCommunicationId, trophyGroupId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n CallValidHeaders,\n UserTrophyGroupEarningsForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ninterface GetUserTrophyGroupEarningsForTitleOptions {\n /**\n * Not required unless the platform is PS3, PS4, or PS Vita.\n * If one of these platforms, the value __must__ be `\"trophy\"`.\n *\n * `\"trophy\"` for PS3, PS4, or PS Vita platforms.\n * `\"trophy2\"` for the PS5 platform.\n */\n npServiceName: \"trophy\" | \"trophy2\";\n\n /*\n * Override the headers in the request to the PSN API,\n * such as to change the language.\n */\n headerOverrides: CallValidHeaders;\n}\n\n/**\n * A request to this endpoint function will retrieve a summary of the trophies earned for\n * a user broken down by trophy group within a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have,\n * and additional groups beginning with the name `\"001\"` and incrementing for\n * each additional group).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function calls an endpoint that returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyGroupEarningsForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { accountId, npCommunicationId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophyProfileSummaryResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophyProfileSummaryOptions = Pick<\n AllCallOptions,\n \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve an overall summary of the number of\n * trophies earned for a user broken down by grade, as well as their current\n * overall trophy level, progress towards the next level, and which tier their\n * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyProfileSummary = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophySummary\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","export const USER_BASE_URL =\n \"https://m.np.playstation.com/api/userProfile/v1/internal/users\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n ProfileFromAccountIdResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetProfileFromAccountIdOptions = Pick;\n\n/**\n * A call to this function will retrieve some profile information of the accountId being requested.\n * If the account's profile cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The accountId for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromAccountId = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: GetProfileFromAccountIdOptions\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/profiles\", options, {\n accountId\n });\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n ProfileFromUserNameResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\n\n/**\n * A call to this function will retrieve the profile of the username being requested.\n * If the user cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * This is a legacy API endpoint function. If you are just trying to get a user's\n * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch)\n * is recommended instead. This endpoint is here because it can return interesting\n * presence information when the user is playing on a legacy console such as a PS3.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param userName The username for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromUserName = async (\n authorization: AuthorizationPayload,\n userName: string\n): Promise => {\n const url = `https://us-prof.np.community.playstation.net/userProfile/v1/users/${userName}/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability`;\n\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n GetUserFriendsAccountIdsResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetUserFriendsAccountIdsOptions = Pick;\n\n/**\n * A call to this function will retrieve the list of friended `accountId` values\n * associated with the given `accountId` parameter. If the user cannot be found\n * (either due to non-existence or privacy settings), an error will be thrown.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n */\nexport const getUserFriendsAccountIds = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/friends\", options, {\n accountId\n });\n\n const response = await call(\n { url },\n authorization\n );\n\n // If you are unable to access the user's friends list, a\n // \"Not permitted by access control\" error will be thrown.\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n"],"names":["TrophyRarity","exchangeCodeForAccessToken","_ref","_asyncToGenerator","_regeneratorRuntime","mark","accessCode","res","raw","wrap","_context","prev","next","fetch","AUTH_BASE_URL","method","headers","Authorization","body","URLSearchParams","code","redirect_uri","grant_type","token_format","toString","sent","json","abrupt","accessToken","access_token","expiresIn","expires_in","idToken","id_token","refreshToken","refresh_token","refreshTokenExpiresIn","refresh_token_expires_in","scope","tokenType","token_type","stop","_callee","_x","apply","this","arguments","exchangeNpssoForCode","npssoToken","_responseHeaders$get","queryString","requestUrl","responseHeaders","redirectLocation","redirectParams","access_type","client_id","response_type","Cookie","redirect","has","get","includes","Error","split","exchangeRefreshTokenForAuthTokens","call","config","authorization","bodyPayload","_config$method","response","url","_extends","JSON","stringify","_x2","_x3","getRecentlyPlayedGames","options","_options","_options$limit","limit","_options$categories","categories","URL","searchParams","set","join","persistedQuery","version","sha256Hash","data","gameLibraryTitlesRetrieve","buildRequestUrl","baseUrl","endpointUrl","args","pickedOptions","_objectWithoutPropertiesLoose","_excluded","withArgs","replace","queryParamValues","Object","entries","_i","_Object$entries","length","_Object$entries$_i","argKey","argValue","String","undefined","makeUniversalSearch","searchTerm","domain","domainRequests","TROPHY_BASE_URL","getTitleTrophies","npCommunicationId","trophyGroupId","headerOverrides","_x4","getTitleTrophyGroups","getUserTitles","accountId","getUserTrophiesEarnedForTitle","_response$error$messa","_response$error","error","message","_x5","getUserTrophyGroupEarningsForTitle","getUserTrophyProfileSummary","USER_BASE_URL","getProfileFromAccountId","getProfileFromUserName","userName","getUserFriendsAccountIds"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/psn-api/dist/psn-api.esm.js b/node_modules/psn-api/dist/psn-api.esm.js new file mode 100644 index 0000000..ca944cc --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.esm.js @@ -0,0 +1,1157 @@ +import fetch from 'isomorphic-unfetch'; + +function _regeneratorRuntime() { + _regeneratorRuntime = function () { + return exports; + }; + var exports = {}, + Op = Object.prototype, + hasOwn = Op.hasOwnProperty, + defineProperty = Object.defineProperty || function (obj, key, desc) { + obj[key] = desc.value; + }, + $Symbol = "function" == typeof Symbol ? Symbol : {}, + iteratorSymbol = $Symbol.iterator || "@@iterator", + asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", + toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + function define(obj, key, value) { + return Object.defineProperty(obj, key, { + value: value, + enumerable: !0, + configurable: !0, + writable: !0 + }), obj[key]; + } + try { + define({}, ""); + } catch (err) { + define = function (obj, key, value) { + return obj[key] = value; + }; + } + function wrap(innerFn, outerFn, self, tryLocsList) { + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, + generator = Object.create(protoGenerator.prototype), + context = new Context(tryLocsList || []); + return defineProperty(generator, "_invoke", { + value: makeInvokeMethod(innerFn, self, context) + }), generator; + } + function tryCatch(fn, obj, arg) { + try { + return { + type: "normal", + arg: fn.call(obj, arg) + }; + } catch (err) { + return { + type: "throw", + arg: err + }; + } + } + exports.wrap = wrap; + var ContinueSentinel = {}; + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + var IteratorPrototype = {}; + define(IteratorPrototype, iteratorSymbol, function () { + return this; + }); + var getProto = Object.getPrototypeOf, + NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + define(prototype, method, function (arg) { + return this._invoke(method, arg); + }); + }); + } + function AsyncIterator(generator, PromiseImpl) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if ("throw" !== record.type) { + var result = record.arg, + value = result.value; + return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }) : PromiseImpl.resolve(value).then(function (unwrapped) { + result.value = unwrapped, resolve(result); + }, function (error) { + return invoke("throw", error, resolve, reject); + }); + } + reject(record.arg); + } + var previousPromise; + defineProperty(this, "_invoke", { + value: function (method, arg) { + function callInvokeWithMethodAndArg() { + return new PromiseImpl(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + }); + } + function makeInvokeMethod(innerFn, self, context) { + var state = "suspendedStart"; + return function (method, arg) { + if ("executing" === state) throw new Error("Generator is already running"); + if ("completed" === state) { + if ("throw" === method) throw arg; + return doneResult(); + } + for (context.method = method, context.arg = arg;;) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } + if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { + if ("suspendedStart" === state) throw state = "completed", context.arg; + context.dispatchException(context.arg); + } else "return" === context.method && context.abrupt("return", context.arg); + state = "executing"; + var record = tryCatch(innerFn, self, context); + if ("normal" === record.type) { + if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; + return { + value: record.arg, + done: context.done + }; + } + "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); + } + }; + } + function maybeInvokeDelegate(delegate, context) { + var methodName = context.method, + method = delegate.iterator[methodName]; + if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; + var record = tryCatch(method, delegate.iterator, context.arg); + if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; + var info = record.arg; + return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); + } + function pushTryEntry(locs) { + var entry = { + tryLoc: locs[0] + }; + 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); + } + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal", delete record.arg, entry.completion = record; + } + function Context(tryLocsList) { + this.tryEntries = [{ + tryLoc: "root" + }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); + } + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) return iteratorMethod.call(iterable); + if ("function" == typeof iterable.next) return iterable; + if (!isNaN(iterable.length)) { + var i = -1, + next = function next() { + for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; + return next.value = undefined, next.done = !0, next; + }; + return next.next = next; + } + } + return { + next: doneResult + }; + } + function doneResult() { + return { + value: undefined, + done: !0 + }; + } + return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { + value: GeneratorFunctionPrototype, + configurable: !0 + }), defineProperty(GeneratorFunctionPrototype, "constructor", { + value: GeneratorFunction, + configurable: !0 + }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { + var ctor = "function" == typeof genFun && genFun.constructor; + return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); + }, exports.mark = function (genFun) { + return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; + }, exports.awrap = function (arg) { + return { + __await: arg + }; + }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { + return this; + }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { + void 0 === PromiseImpl && (PromiseImpl = Promise); + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); + return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { + return this; + }), define(Gp, "toString", function () { + return "[object Generator]"; + }), exports.keys = function (val) { + var object = Object(val), + keys = []; + for (var key in object) keys.push(key); + return keys.reverse(), function next() { + for (; keys.length;) { + var key = keys.pop(); + if (key in object) return next.value = key, next.done = !1, next; + } + return next.done = !0, next; + }; + }, exports.values = values, Context.prototype = { + constructor: Context, + reset: function (skipTempReset) { + if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); + }, + stop: function () { + this.done = !0; + var rootRecord = this.tryEntries[0].completion; + if ("throw" === rootRecord.type) throw rootRecord.arg; + return this.rval; + }, + dispatchException: function (exception) { + if (this.done) throw exception; + var context = this; + function handle(loc, caught) { + return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; + } + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i], + record = entry.completion; + if ("root" === entry.tryLoc) return handle("end"); + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"), + hasFinally = hasOwn.call(entry, "finallyLoc"); + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); + if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); + } else if (hasCatch) { + if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); + } else { + if (!hasFinally) throw new Error("try statement without catch or finally"); + if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); + } + } + } + }, + abrupt: function (type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); + var record = finallyEntry ? finallyEntry.completion : {}; + return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); + }, + complete: function (record, afterLoc) { + if ("throw" === record.type) throw record.arg; + return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; + }, + finish: function (finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; + } + }, + catch: function (tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if ("throw" === record.type) { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + throw new Error("illegal catch attempt"); + }, + delegateYield: function (iterable, resultName, nextLoc) { + return this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }, "next" === this.method && (this.arg = undefined), ContinueSentinel; + } + }, exports; +} +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} +function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + _next(undefined); + }); + }; +} +function _extends() { + _extends = Object.assign ? Object.assign.bind() : function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); +} +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + return target; +} + +var AUTH_BASE_URL = "https://ca.account.sony.com/api/authz/v3/oauth"; + +/** + * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`. + * @returns An object containing an access token, refresh token, and expiry times for both. + */ +var exchangeCodeForAccessToken = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(accessCode) { + var requestUrl, res, raw; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + requestUrl = AUTH_BASE_URL + "/token"; + _context.next = 3; + return fetch(requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + code: accessCode, + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + grant_type: "authorization_code", + token_format: "jwt" + }).toString() + }); + case 3: + res = _context.sent; + _context.next = 6; + return res.json(); + case 6: + raw = _context.sent; + return _context.abrupt("return", { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }); + case 8: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeCodeForAccessToken(_x) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * + * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie + * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`. + * @example + * ```ts + * const code = await exchangeNpssoForCode("myNpssoToken"); + * + * console.log(code) // --> "v3.XXXXXX" + * ``` + */ +var exchangeNpssoForCode = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(npssoToken) { + var _responseHeaders$get; + var queryString, requestUrl, _yield$fetch, responseHeaders, redirectLocation, redirectParams; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + queryString = new URLSearchParams({ + access_type: "offline", + client_id: "09515159-7237-4370-9b40-3806e67c0891", + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + response_type: "code", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString(); + requestUrl = AUTH_BASE_URL + "/authorize?" + queryString; // This never returns a 200. As of Oct 10 2021, it seems to return a 302. + _context.next = 4; + return fetch(requestUrl, { + headers: { + Cookie: "npsso=" + npssoToken + }, + redirect: "manual" + }); + case 4: + _yield$fetch = _context.sent; + responseHeaders = _yield$fetch.headers; + if (!(!responseHeaders.has("location") || !((_responseHeaders$get = responseHeaders.get("location")) != null && _responseHeaders$get.includes("?code=")))) { + _context.next = 8; + break; + } + throw new Error("\n There was a problem retrieving your PSN access code. Is your NPSSO code valid?\n To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie.\n "); + case 8: + redirectLocation = responseHeaders.get("location"); + redirectParams = new URLSearchParams(redirectLocation.split("redirect/")[1]); + return _context.abrupt("return", redirectParams.get("code")); + case 11: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeNpssoForCode(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var exchangeRefreshTokenForAuthTokens = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(refreshToken) { + var requestUrl, res, raw; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + requestUrl = AUTH_BASE_URL + "/token"; + _context.next = 3; + return fetch(requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + refresh_token: refreshToken, + grant_type: "refresh_token", + token_format: "jwt", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString() + }); + case 3: + res = _context.sent; + _context.next = 6; + return res.json(); + case 6: + raw = _context.sent; + return _context.abrupt("return", { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }); + case 8: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function exchangeRefreshTokenForAuthTokens(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var call = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(config, authorization, bodyPayload) { + var _config$method; + var response; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return fetch(config.url, { + method: (_config$method = config == null ? void 0 : config.method) != null ? _config$method : "GET", + headers: _extends({ + Authorization: "Bearer " + authorization.accessToken, + "Content-Type": "application/json" + }, config == null ? void 0 : config.headers), + body: JSON.stringify(bodyPayload) + }); + case 2: + response = _context.sent; + _context.next = 5; + return response.json(); + case 5: + return _context.abrupt("return", _context.sent); + case 6: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function call(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var GRAPHQL_BASE_URL = "https://web.np.playstation.com/api/graphql/v1/op"; + +/** + * GraphQL endpoints work differently to others in the codebase. + * + * The hashes in this file are reverse engineered from app-.js file loaded by the page + * at https://library.playstation.com/recently-played. Following the code in that file leads + * to some Apollo GraphQL code related to persisted queries. This means the request needs to + * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink + * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging + * will surface the exact GraphQL query that's passed to the hash function on the page. + * + * Thankfully it's easier to figure out future endpoints and hashes by: + * + * 1. Visiting a page, e.g https://library.playstation.com/recently-played + * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op + * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters + */ +// Hash is computed from the following query (without surrounding quotes): +// "query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\n __typename\n games {\n __typename\n conceptId\n entitlementId\n image {\n __typename\n url\n }\n isActive\n lastPlayedDateTime\n name\n platform\n productId\n subscriptionService\n titleId\n }\n }\n}\n" +var getUserGameListHash = "e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae"; + +/** + * A call to this function will retrieve recently played games for the user associated + * with the npsso token provided to this module during initialisation. + * + * This is useful if you want recent activity that isn't tied to trophy progress. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + */ +var getRecentlyPlayedGames = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, options) { + var _options, _options$limit, limit, _options$categories, categories, url, response; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + if (options === void 0) { + options = {}; + } + _options = options, _options$limit = _options.limit, limit = _options$limit === void 0 ? 50 : _options$limit, _options$categories = _options.categories, categories = _options$categories === void 0 ? ["ps4_game", "ps5_native_game"] : _options$categories; + url = new URL(GRAPHQL_BASE_URL); + url.searchParams.set("operationName", "getUserGameList"); + url.searchParams.set("variables", JSON.stringify({ + limit: limit, + categories: categories.join(",") + })); + url.searchParams.set("extensions", JSON.stringify({ + persistedQuery: { + version: 1, + sha256Hash: getUserGameListHash + } + })); + _context.next = 8; + return call({ + url: url.toString() + }, authorization); + case 8: + response = _context.sent; + if (!(!response.data || !response.data.gameLibraryTitlesRetrieve)) { + _context.next = 11; + break; + } + throw new Error(JSON.stringify(response)); + case 11: + return _context.abrupt("return", response); + case 12: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getRecentlyPlayedGames(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +var TrophyRarity; +(function (TrophyRarity) { + TrophyRarity[TrophyRarity["UltraRare"] = 0] = "UltraRare"; + TrophyRarity[TrophyRarity["VeryRare"] = 1] = "VeryRare"; + TrophyRarity[TrophyRarity["Rare"] = 2] = "Rare"; + TrophyRarity[TrophyRarity["Common"] = 3] = "Common"; +})(TrophyRarity || (TrophyRarity = {})); + +var _excluded = ["headerOverrides"]; +var buildRequestUrl = function buildRequestUrl(baseUrl, endpointUrl, options, args) { + if (options === void 0) { + options = {}; + } + if (args === void 0) { + args = {}; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick. + var _options = options, + pickedOptions = _objectWithoutPropertiesLoose(_options, _excluded); + var concatenated = baseUrl + "/" + endpointUrl; + var withoutDoubleSlashes = concatenated.replace(/([^:]\/)\/+/g, "$1"); + var withArgs = withoutDoubleSlashes; + var queryParamValues = {}; + for (var _i = 0, _Object$entries = Object.entries(_extends({}, args, pickedOptions)); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = _Object$entries[_i], + argKey = _Object$entries$_i[0], + argValue = _Object$entries$_i[1]; + if (withArgs.includes(":" + argKey)) { + withArgs = withArgs.replace(":" + argKey, String(argValue)); + } else if (argValue !== undefined) { + queryParamValues[argKey] = String(argValue); + } + } + var queryString = new URLSearchParams(queryParamValues).toString(); + return queryString.length > 0 ? withArgs + "?" + queryString : withArgs; +}; + +var SEARCH_BASE_URL = "https://m.np.playstation.com/api/search"; + +var makeUniversalSearch = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, searchTerm, domain) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(SEARCH_BASE_URL, "/v1/universalSearch"); + _context.next = 3; + return call({ + url: url, + method: "POST" + }, authorization, { + searchTerm: searchTerm, + domainRequests: [{ + domain: domain + }] + }); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function makeUniversalSearch(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var TROPHY_BASE_URL = "https://m.np.playstation.com/api/trophy"; + +/** + * A call to this function will retrieve the trophy list of a + * single - or all - trophy groups for a title. A title can have multiple + * groups of trophies (a `"default"` group which all titles have, and additional + * groups starting with the name `"001"` and incrementing for each additional group). To retrieve + * trophies from all groups within a title (ie. the full trophy set), then + * `trophyGroupId` should be set to `"all"`. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` parameter as `"trophy"`. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getTitleTrophies = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, npCommunicationId, trophyGroupId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", options, { + npCommunicationId: npCommunicationId, + trophyGroupId: trophyGroupId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getTitleTrophies(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A title may have multiple groups of trophies. This is most commonly + * seen in games which have DLC expansions where additional trophies are added. + * + * You can call this function for a specific title - using the + * unique `npCommunicationId` for the title - and you will receive a + * summary of all of the trophy groups associated with the title. + * This also includes a summary of the number of trophies for the + * title, broken down by group and grade (gold, silver, etc.). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getTitleTrophyGroups = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, npCommunicationId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/npCommunicationIds/:npCommunicationId/trophyGroups", options, { + npCommunicationId: npCommunicationId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getTitleTrophyGroups(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve a summarized list of titles played + * by a user, ordered by recent trophy unlocks. The maximum amount that can + * be returned by a single call is 800 (assuming a `limit` option of 800 is set). + * If the user has more titles than the given `limit` option, subsequent calls + * of this funciton must be made to fetch the complete list by paging via the + * `offset` option. + * + * The numeric `accountId` can be that of any PSN account for which the authenticating + * account has permissions to view the trophy list. When querying the titles + * associated with the authenticating account, the numeric `accountId` can be + * substituted with `"me"`. + * + * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()` + * function can be used. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * Included in the information returned is the titles' unique `npCommunicationId`. + * This is required to make use of subsequent functions for requesting more specific + * detail about a title's trophies. + * + * The results are presented in order of the `lastUpdatedDateTime` for the title, + * so the first result will be the title for which a trophy was most recently earned + * (or synced for the first time in the case of a game with 0% progress). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.limit Limit the number of titles returned. + * @param options.offset Return title data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTitles = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/trophyTitles", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTitles(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the earned status of trophies for a user + * from either a single - or all - trophy groups in a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, and + * additional groups starting with a name of `"001"` and incrementing for each + * additional group). To retrieve trophies from all groups within a title + * (ie. the full trophy set), then `trophyGroupId` should be set to `"all"`. + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophiesEarnedForTitle = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, npCommunicationId, trophyGroupId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", options, { + accountId: accountId, + npCommunicationId: npCommunicationId, + trophyGroupId: trophyGroupId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophiesEarnedForTitle(_x, _x2, _x3, _x4, _x5) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A request to this endpoint function will retrieve a summary of the trophies earned for + * a user broken down by trophy group within a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, + * and additional groups beginning with the name `"001"` and incrementing for + * each additional group). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function calls an endpoint that returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophyGroupEarningsForTitle = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, npCommunicationId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups", options, { + accountId: accountId, + npCommunicationId: npCommunicationId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophyGroupEarningsForTitle(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve an overall summary of the number of + * trophies earned for a user broken down by grade, as well as their current + * overall trophy level, progress towards the next level, and which tier their + * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +var getUserTrophyProfileSummary = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(TROPHY_BASE_URL, "/v1/users/:accountId/trophySummary", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url, + headers: options == null ? void 0 : options.headerOverrides + }, authorization); + case 3: + return _context.abrupt("return", _context.sent); + case 4: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserTrophyProfileSummary(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +var USER_BASE_URL = "https://m.np.playstation.com/api/userProfile/v1/internal/users"; + +/** + * A call to this function will retrieve some profile information of the accountId being requested. + * If the account's profile cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The accountId for the user you wish to retrieve a profile for. + */ +var getProfileFromAccountId = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(USER_BASE_URL, "/:accountId/profiles", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getProfileFromAccountId(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the profile of the username being requested. + * If the user cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * This is a legacy API endpoint function. If you are just trying to get a user's + * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) + * is recommended instead. This endpoint is here because it can return interesting + * presence information when the user is playing on a legacy console such as a PS3. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param userName The username for the user you wish to retrieve a profile for. + */ +var getProfileFromUserName = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, userName) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = "https://us-prof.np.community.playstation.net/userProfile/v1/users/" + userName + "/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability"; + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getProfileFromUserName(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +/** + * A call to this function will retrieve the list of friended `accountId` values + * associated with the given `accountId` parameter. If the user cannot be found + * (either due to non-existence or privacy settings), an error will be thrown. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + */ +var getUserFriendsAccountIds = /*#__PURE__*/function () { + var _ref = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(authorization, accountId, options) { + var url, response, _response$error$messa, _response$error; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + url = buildRequestUrl(USER_BASE_URL, "/:accountId/friends", options, { + accountId: accountId + }); + _context.next = 3; + return call({ + url: url + }, authorization); + case 3: + response = _context.sent; + if (!(response != null && response.error)) { + _context.next = 6; + break; + } + throw new Error((_response$error$messa = response == null ? void 0 : (_response$error = response.error) == null ? void 0 : _response$error.message) != null ? _response$error$messa : "Unexpected Error"); + case 6: + return _context.abrupt("return", response); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function getUserFriendsAccountIds(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +export { TrophyRarity, call, exchangeCodeForAccessToken, exchangeNpssoForCode, exchangeRefreshTokenForAuthTokens, getProfileFromAccountId, getProfileFromUserName, getRecentlyPlayedGames, getTitleTrophies, getTitleTrophyGroups, getUserFriendsAccountIds, getUserTitles, getUserTrophiesEarnedForTitle, getUserTrophyGroupEarningsForTitle, getUserTrophyProfileSummary, makeUniversalSearch }; +//# sourceMappingURL=psn-api.esm.js.map diff --git a/node_modules/psn-api/dist/psn-api.esm.js.map b/node_modules/psn-api/dist/psn-api.esm.js.map new file mode 100644 index 0000000..f018c49 --- /dev/null +++ b/node_modules/psn-api/dist/psn-api.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"psn-api.esm.js","sources":["../src/authenticate/AUTH_BASE_URL.ts","../src/authenticate/exchangeCodeForAccessToken.ts","../src/authenticate/exchangeNpssoForCode.ts","../src/authenticate/exchangeRefreshTokenForAuthTokens.ts","../src/utils/call.ts","../src/graphql/GRAPHQL_BASE_URL.ts","../src/graphql/operationHashes.ts","../src/graphql/getRecentlyPlayedGames.ts","../src/models/trophy-rarity.model.ts","../src/utils/buildRequestUrl.ts","../src/search/SEARCH_BASE_URL.ts","../src/search/makeUniversalSearch.ts","../src/trophy/TROPHY_BASE_URL.ts","../src/trophy/title/getTitleTrophies.ts","../src/trophy/title/getTitleTrophyGroups.ts","../src/trophy/user/getUserTitles.ts","../src/trophy/user/getUserTrophiesEarnedForTitle.ts","../src/trophy/user/getUserTrophyGroupEarningsForTitle.ts","../src/trophy/user/getUserTrophyProfileSummary.ts","../src/user/USER_BASE_URL.ts","../src/user/getProfileFromAccountId.ts","../src/user/getProfileFromUserName.ts","../src/user/getUserFriendsAccountIds.ts"],"sourcesContent":["export const AUTH_BASE_URL = \"https://ca.account.sony.com/api/authz/v3/oauth\";\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`.\n * @returns An object containing an access token, refresh token, and expiry times for both.\n */\nexport const exchangeCodeForAccessToken = async (\n accessCode: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n code: accessCode,\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n grant_type: \"authorization_code\",\n token_format: \"jwt\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\n/**\n *\n * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie\n * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`.\n * @example\n * ```ts\n * const code = await exchangeNpssoForCode(\"myNpssoToken\");\n *\n * console.log(code) // --> \"v3.XXXXXX\"\n * ```\n */\nexport const exchangeNpssoForCode = async (\n npssoToken: string\n): Promise => {\n const queryString = new URLSearchParams({\n access_type: \"offline\",\n client_id: \"09515159-7237-4370-9b40-3806e67c0891\",\n redirect_uri: \"com.scee.psxandroid.scecompcall://redirect\",\n response_type: \"code\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString();\n\n const requestUrl = `${AUTH_BASE_URL}/authorize?${queryString}`;\n\n // This never returns a 200. As of Oct 10 2021, it seems to return a 302.\n const { headers: responseHeaders } = await fetch(requestUrl, {\n headers: {\n Cookie: `npsso=${npssoToken}`\n },\n redirect: \"manual\"\n });\n\n // The access code itself is stored in a header on the response.\n // We'll perform a few validations to ensure it's actually there.\n if (\n !responseHeaders.has(\"location\") ||\n !responseHeaders.get(\"location\")?.includes(\"?code=\")\n ) {\n throw new Error(`\n There was a problem retrieving your PSN access code. Is your NPSSO code valid?\n To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie.\n `);\n }\n\n const redirectLocation = responseHeaders.get(\"location\") as string;\n const redirectParams = new URLSearchParams(\n redirectLocation.split(\"redirect/\")[1]\n );\n\n return redirectParams.get(\"code\") as string;\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthTokensResponse } from \"../models\";\nimport { AUTH_BASE_URL } from \"./AUTH_BASE_URL\";\n\nexport const exchangeRefreshTokenForAuthTokens = async (\n refreshToken: string\n): Promise => {\n const requestUrl = `${AUTH_BASE_URL}/token`;\n\n const res = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization:\n \"Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=\"\n },\n body: new URLSearchParams({\n refresh_token: refreshToken,\n grant_type: \"refresh_token\",\n token_format: \"jwt\",\n scope: \"psn:mobile.v2.core psn:clientapp\"\n }).toString()\n });\n\n const raw = await res.json();\n\n return {\n accessToken: raw.access_token,\n expiresIn: raw.expires_in,\n idToken: raw.id_token,\n refreshToken: raw.refresh_token,\n refreshTokenExpiresIn: raw.refresh_token_expires_in,\n scope: raw.scope,\n tokenType: raw.token_type\n };\n};\n","import fetch from \"isomorphic-unfetch\";\n\nimport type { AuthorizationPayload, CallValidHeaders } from \"../models\";\n\nexport const call = async (\n config: {\n url: string;\n method?: \"GET\" | \"POST\";\n headers?: CallValidHeaders;\n },\n authorization: AuthorizationPayload,\n bodyPayload?: Record\n) => {\n const response = await fetch(config.url, {\n method: config?.method ?? \"GET\",\n headers: {\n Authorization: `Bearer ${authorization.accessToken}`,\n \"Content-Type\": \"application/json\",\n ...config?.headers\n },\n body: JSON.stringify(bodyPayload)\n });\n\n return (await response.json()) as T;\n};\n","export const GRAPHQL_BASE_URL =\n \"https://web.np.playstation.com/api/graphql/v1/op\";\n","/**\n * GraphQL endpoints work differently to others in the codebase.\n *\n * The hashes in this file are reverse engineered from app-.js file loaded by the page\n * at https://library.playstation.com/recently-played. Following the code in that file leads\n * to some Apollo GraphQL code related to persisted queries. This means the request needs to\n * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink\n * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging\n * will surface the exact GraphQL query that's passed to the hash function on the page.\n *\n * Thankfully it's easier to figure out future endpoints and hashes by:\n *\n * 1. Visiting a page, e.g https://library.playstation.com/recently-played\n * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op\n * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters\n */\n\n// Hash is computed from the following query (without surrounding quotes):\n// \"query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\\n __typename\\n games {\\n __typename\\n conceptId\\n entitlementId\\n image {\\n __typename\\n url\\n }\\n isActive\\n lastPlayedDateTime\\n name\\n platform\\n productId\\n subscriptionService\\n titleId\\n }\\n }\\n}\\n\"\nexport const getUserGameListHash =\n \"e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n RecentlyPlayedGamesResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\nimport { GRAPHQL_BASE_URL } from \"./GRAPHQL_BASE_URL\";\nimport { getUserGameListHash } from \"./operationHashes\";\n\ntype GetRecentlyPlayedGamesOptionsCategories = \"ps4_game\" | \"ps5_native_game\";\ntype GetRecentlyPlayedGamesOptions = Pick & {\n categories: GetRecentlyPlayedGamesOptionsCategories[];\n};\n\n/**\n * A call to this function will retrieve recently played games for the user associated\n * with the npsso token provided to this module during initialisation.\n *\n * This is useful if you want recent activity that isn't tied to trophy progress.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n */\nexport const getRecentlyPlayedGames = async (\n authorization: AuthorizationPayload,\n options: Partial = {}\n): Promise => {\n const { limit = 50, categories = [\"ps4_game\", \"ps5_native_game\"] } = options;\n\n const url = new URL(GRAPHQL_BASE_URL);\n\n url.searchParams.set(\"operationName\", \"getUserGameList\");\n url.searchParams.set(\n \"variables\",\n JSON.stringify({\n limit,\n categories: categories.join(\",\")\n })\n );\n url.searchParams.set(\n \"extensions\",\n JSON.stringify({\n persistedQuery: {\n version: 1,\n sha256Hash: getUserGameListHash\n }\n })\n );\n\n const response = await call(\n { url: url.toString() },\n authorization\n );\n\n // The GraphQL queries can return non-truthy values.\n if (!response.data || !response.data.gameLibraryTitlesRetrieve) {\n throw new Error(JSON.stringify(response));\n }\n\n return response;\n};\n","export enum TrophyRarity {\n UltraRare,\n VeryRare,\n Rare,\n Common\n}\n","import type { AllCallOptions } from \"../models\";\n\nexport const buildRequestUrl = (\n baseUrl: string,\n endpointUrl: string,\n options: Partial = {},\n args: Record = {}\n) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick.\n const { headerOverrides, ...pickedOptions } = options;\n\n const concatenated = `${baseUrl}/${endpointUrl}`;\n const withoutDoubleSlashes = concatenated.replace(/([^:]\\/)\\/+/g, \"$1\");\n\n let withArgs = withoutDoubleSlashes;\n const queryParamValues: Record = {};\n\n for (const [argKey, argValue] of Object.entries({\n ...args,\n ...pickedOptions\n })) {\n if (withArgs.includes(`:${argKey}`)) {\n withArgs = withArgs.replace(`:${argKey}`, String(argValue));\n } else if (argValue !== undefined) {\n queryParamValues[argKey] = String(argValue);\n }\n }\n\n const queryString = new URLSearchParams(queryParamValues).toString();\n return queryString.length > 0 ? `${withArgs}?${queryString}` : withArgs;\n};\n","export const SEARCH_BASE_URL = \"https://m.np.playstation.com/api/search\";\n","import type {\n AuthorizationPayload,\n SocialAccountResult,\n UniversalSearchDomains,\n UniversalSearchResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { SEARCH_BASE_URL } from \"./SEARCH_BASE_URL\";\n\nexport const makeUniversalSearch = async (\n authorization: AuthorizationPayload,\n searchTerm: string,\n domain: R\n) => {\n const url = buildRequestUrl(SEARCH_BASE_URL, \"/v1/universalSearch\");\n\n type AssertType = R extends \"SocialAllAccounts\"\n ? SocialAccountResult\n : unknown;\n\n return await call>>(\n { url, method: \"POST\" },\n authorization,\n {\n searchTerm,\n domainRequests: [\n {\n domain\n }\n ]\n }\n );\n};\n","export const TROPHY_BASE_URL = \"https://m.np.playstation.com/api/trophy\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophiesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophiesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"npServiceName\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve the trophy list of a\n * single - or all - trophy groups for a title. A title can have multiple\n * groups of trophies (a `\"default\"` group which all titles have, and additional\n * groups starting with the name `\"001\"` and incrementing for each additional group). To retrieve\n * trophies from all groups within a title (ie. the full trophy set), then\n * `trophyGroupId` should be set to `\"all\"`.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` parameter as `\"trophy\"`.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophies = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { npCommunicationId, trophyGroupId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n TitleTrophyGroupsResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetTitleTrophyGroupsOptions = Pick<\n AllCallOptions,\n \"npServiceName\" | \"headerOverrides\"\n>;\n\n/**\n * A title may have multiple groups of trophies. This is most commonly\n * seen in games which have DLC expansions where additional trophies are added.\n *\n * You can call this function for a specific title - using the\n * unique `npCommunicationId` for the title - and you will receive a\n * summary of all of the trophy groups associated with the title.\n * This also includes a summary of the number of trophies for the\n * title, broken down by group and grade (gold, silver, etc.).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getTitleTrophyGroups = async (\n authorization: AuthorizationPayload,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { npCommunicationId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTitlesResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTitlesOptions = Pick<\n AllCallOptions,\n \"headerOverrides\" | \"limit\" | \"offset\"\n>;\n\n/**\n * A call to this function will retrieve a summarized list of titles played\n * by a user, ordered by recent trophy unlocks. The maximum amount that can\n * be returned by a single call is 800 (assuming a `limit` option of 800 is set).\n * If the user has more titles than the given `limit` option, subsequent calls\n * of this funciton must be made to fetch the complete list by paging via the\n * `offset` option.\n *\n * The numeric `accountId` can be that of any PSN account for which the authenticating\n * account has permissions to view the trophy list. When querying the titles\n * associated with the authenticating account, the numeric `accountId` can be\n * substituted with `\"me\"`.\n *\n * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()`\n * function can be used.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * Included in the information returned is the titles' unique `npCommunicationId`.\n * This is required to make use of subsequent functions for requesting more specific\n * detail about a title's trophies.\n *\n * The results are presented in order of the `lastUpdatedDateTime` for the title,\n * so the first result will be the title for which a trophy was most recently earned\n * (or synced for the first time in the case of a game with 0% progress).\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.limit Limit the number of titles returned.\n * @param options.offset Return title data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTitles = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophyTitles\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophiesEarnedForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophiesEarnedForTitleOptions = Pick<\n AllCallOptions,\n \"offset\" | \"npServiceName\" | \"limit\" | \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve the earned status of trophies for a user\n * from either a single - or all - trophy groups in a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have, and\n * additional groups starting with a name of `\"001\"` and incrementing for each\n * additional group). To retrieve trophies from all groups within a title\n * (ie. the full trophy set), then `trophyGroupId` should be set to `\"all\"`.\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param trophyGroupId `\"all\"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC).\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.limit Limit the number of trophies returned.\n * @param options.offset Return trophy data from this result onwards.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophiesEarnedForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n trophyGroupId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies\",\n options,\n { accountId, npCommunicationId, trophyGroupId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n CallValidHeaders,\n UserTrophyGroupEarningsForTitleResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ninterface GetUserTrophyGroupEarningsForTitleOptions {\n /**\n * Not required unless the platform is PS3, PS4, or PS Vita.\n * If one of these platforms, the value __must__ be `\"trophy\"`.\n *\n * `\"trophy\"` for PS3, PS4, or PS Vita platforms.\n * `\"trophy2\"` for the PS5 platform.\n */\n npServiceName: \"trophy\" | \"trophy2\";\n\n /*\n * Override the headers in the request to the PSN API,\n * such as to change the language.\n */\n headerOverrides: CallValidHeaders;\n}\n\n/**\n * A request to this endpoint function will retrieve a summary of the trophies earned for\n * a user broken down by trophy group within a title. A title can have\n * multiple groups of trophies (a `\"default\"` group which all titles have,\n * and additional groups beginning with the name `\"001\"` and incrementing for\n * each additional group).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * This function calls an endpoint that returns the earned status of the\n * trophy only and no additional descriptive metadata (ie. trophy name,\n * trophy description). Use `getTitleTrophies()` to obtain this information.\n *\n * When the title platform is PS3, PS4 or PS Vita you __must__ specify the\n * `npServiceName` option as `\"trophy\"`.\n *\n * If you attempt to query a title which the user does not have associated\n * with their account (ie. the title has not been launched and allowed to\n * sync at least once) then a Resource Not Found error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param npCommunicationId Unique ID of the title.\n * @param options.npServiceName `\"trophy\"` for PS3, PS4, or PS Vita platforms. `\"trophy2\"` for the PS5 platform.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyGroupEarningsForTitle = async (\n authorization: AuthorizationPayload,\n accountId: string,\n npCommunicationId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups\",\n options,\n { accountId, npCommunicationId }\n );\n\n const response = await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n UserTrophyProfileSummaryResponse\n} from \"../../models\";\nimport { buildRequestUrl } from \"../../utils/buildRequestUrl\";\nimport { call } from \"../../utils/call\";\nimport { TROPHY_BASE_URL } from \"../TROPHY_BASE_URL\";\n\ntype GetUserTrophyProfileSummaryOptions = Pick<\n AllCallOptions,\n \"headerOverrides\"\n>;\n\n/**\n * A call to this function will retrieve an overall summary of the number of\n * trophies earned for a user broken down by grade, as well as their current\n * overall trophy level, progress towards the next level, and which tier their\n * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png).\n *\n * The numeric `accountId` can be that of any PSN account for which the\n * authenticating account has permissions to view the trophy list.\n * When querying the titles associated with the authenticating account, the\n * numeric `accountId` can be substituted with `\"me\"`.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language.\n */\nexport const getUserTrophyProfileSummary = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(\n TROPHY_BASE_URL,\n \"/v1/users/:accountId/trophySummary\",\n options,\n { accountId }\n );\n\n return await call(\n { url, headers: options?.headerOverrides },\n authorization\n );\n};\n","export const USER_BASE_URL =\n \"https://m.np.playstation.com/api/userProfile/v1/internal/users\";\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n ProfileFromAccountIdResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetProfileFromAccountIdOptions = Pick;\n\n/**\n * A call to this function will retrieve some profile information of the accountId being requested.\n * If the account's profile cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The accountId for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromAccountId = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: GetProfileFromAccountIdOptions\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/profiles\", options, {\n accountId\n });\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AuthorizationPayload,\n ProfileFromUserNameResponse\n} from \"../models\";\nimport { call } from \"../utils/call\";\n\n/**\n * A call to this function will retrieve the profile of the username being requested.\n * If the user cannot be found (either due to non-existence or privacy settings),\n * an error will be thrown.\n *\n * This is a legacy API endpoint function. If you are just trying to get a user's\n * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch)\n * is recommended instead. This endpoint is here because it can return interesting\n * presence information when the user is playing on a legacy console such as a PS3.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param userName The username for the user you wish to retrieve a profile for.\n */\nexport const getProfileFromUserName = async (\n authorization: AuthorizationPayload,\n userName: string\n): Promise => {\n const url = `https://us-prof.np.community.playstation.net/userProfile/v1/users/${userName}/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability`;\n\n const response = await call(\n { url },\n authorization\n );\n\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n","import type {\n AllCallOptions,\n AuthorizationPayload,\n GetUserFriendsAccountIdsResponse\n} from \"../models\";\nimport { buildRequestUrl } from \"../utils/buildRequestUrl\";\nimport { call } from \"../utils/call\";\nimport { USER_BASE_URL } from \"./USER_BASE_URL\";\n\ntype GetUserFriendsAccountIdsOptions = Pick;\n\n/**\n * A call to this function will retrieve the list of friended `accountId` values\n * associated with the given `accountId` parameter. If the user cannot be found\n * (either due to non-existence or privacy settings), an error will be thrown.\n *\n * To find a user's `accountId`, the `makeUniversalSearch()` function can be used.\n *\n * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`.\n * @param accountId The account whose trophy list is being accessed. Use `\"me\"` for the authenticating account.\n */\nexport const getUserFriendsAccountIds = async (\n authorization: AuthorizationPayload,\n accountId: string,\n options?: Partial\n): Promise => {\n const url = buildRequestUrl(USER_BASE_URL, \"/:accountId/friends\", options, {\n accountId\n });\n\n const response = await call(\n { url },\n authorization\n );\n\n // If you are unable to access the user's friends list, a\n // \"Not permitted by access control\" error will be thrown.\n if ((response as any)?.error) {\n throw new Error((response as any)?.error?.message ?? \"Unexpected Error\");\n }\n\n return response;\n};\n"],"names":["AUTH_BASE_URL","exchangeCodeForAccessToken","accessCode","requestUrl","fetch","method","headers","Authorization","body","URLSearchParams","code","redirect_uri","grant_type","token_format","toString","res","json","raw","accessToken","access_token","expiresIn","expires_in","idToken","id_token","refreshToken","refresh_token","refreshTokenExpiresIn","refresh_token_expires_in","scope","tokenType","token_type","exchangeNpssoForCode","npssoToken","queryString","access_type","client_id","response_type","Cookie","redirect","responseHeaders","has","get","includes","Error","redirectLocation","redirectParams","split","exchangeRefreshTokenForAuthTokens","call","config","authorization","bodyPayload","url","JSON","stringify","response","GRAPHQL_BASE_URL","getUserGameListHash","getRecentlyPlayedGames","options","limit","categories","URL","searchParams","set","join","persistedQuery","version","sha256Hash","data","gameLibraryTitlesRetrieve","TrophyRarity","buildRequestUrl","baseUrl","endpointUrl","args","headerOverrides","pickedOptions","concatenated","withoutDoubleSlashes","replace","withArgs","queryParamValues","Object","entries","argKey","argValue","String","undefined","length","SEARCH_BASE_URL","makeUniversalSearch","searchTerm","domain","domainRequests","TROPHY_BASE_URL","getTitleTrophies","npCommunicationId","trophyGroupId","getTitleTrophyGroups","getUserTitles","accountId","getUserTrophiesEarnedForTitle","error","message","getUserTrophyGroupEarningsForTitle","getUserTrophyProfileSummary","USER_BASE_URL","getProfileFromAccountId","getProfileFromUserName","userName","getUserFriendsAccountIds"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/psn-api/dist/search/SEARCH_BASE_URL.d.ts b/node_modules/psn-api/dist/search/SEARCH_BASE_URL.d.ts new file mode 100644 index 0000000..c863b67 --- /dev/null +++ b/node_modules/psn-api/dist/search/SEARCH_BASE_URL.d.ts @@ -0,0 +1 @@ +export declare const SEARCH_BASE_URL = "https://m.np.playstation.com/api/search"; diff --git a/node_modules/psn-api/dist/search/index.d.ts b/node_modules/psn-api/dist/search/index.d.ts new file mode 100644 index 0000000..37b7baa --- /dev/null +++ b/node_modules/psn-api/dist/search/index.d.ts @@ -0,0 +1 @@ +export * from "./makeUniversalSearch"; diff --git a/node_modules/psn-api/dist/search/makeUniversalSearch.d.ts b/node_modules/psn-api/dist/search/makeUniversalSearch.d.ts new file mode 100644 index 0000000..9f5d8de --- /dev/null +++ b/node_modules/psn-api/dist/search/makeUniversalSearch.d.ts @@ -0,0 +1,2 @@ +import type { AuthorizationPayload, SocialAccountResult, UniversalSearchResponse } from "../models"; +export declare const makeUniversalSearch: (authorization: AuthorizationPayload, searchTerm: string, domain: R) => Promise>; diff --git a/node_modules/psn-api/dist/test/generators/index.d.ts b/node_modules/psn-api/dist/test/generators/index.d.ts new file mode 100644 index 0000000..bf19ed4 --- /dev/null +++ b/node_modules/psn-api/dist/test/generators/index.d.ts @@ -0,0 +1,3 @@ +export * from "./title-platform.generator"; +export * from "./trophy-counts.generator"; +export * from "./trophy-title.generator"; diff --git a/node_modules/psn-api/dist/test/generators/title-platform.generator.d.ts b/node_modules/psn-api/dist/test/generators/title-platform.generator.d.ts new file mode 100644 index 0000000..9e9c1b0 --- /dev/null +++ b/node_modules/psn-api/dist/test/generators/title-platform.generator.d.ts @@ -0,0 +1 @@ +export declare const generateTitlePlatform: (givenTitlePlatform?: string) => string; diff --git a/node_modules/psn-api/dist/test/generators/trophy-counts.generator.d.ts b/node_modules/psn-api/dist/test/generators/trophy-counts.generator.d.ts new file mode 100644 index 0000000..ea48608 --- /dev/null +++ b/node_modules/psn-api/dist/test/generators/trophy-counts.generator.d.ts @@ -0,0 +1,2 @@ +import type { TrophyCounts } from "../../models"; +export declare const generateTrophyCounts: (trophyCountsProps?: Partial) => TrophyCounts; diff --git a/node_modules/psn-api/dist/test/generators/trophy-title.generator.d.ts b/node_modules/psn-api/dist/test/generators/trophy-title.generator.d.ts new file mode 100644 index 0000000..76aff1d --- /dev/null +++ b/node_modules/psn-api/dist/test/generators/trophy-title.generator.d.ts @@ -0,0 +1,2 @@ +import type { TrophyTitle } from "../../models"; +export declare const generateTrophyTitle: (trophyTitleProps?: Partial) => TrophyTitle; diff --git a/node_modules/psn-api/dist/trophy/TROPHY_BASE_URL.d.ts b/node_modules/psn-api/dist/trophy/TROPHY_BASE_URL.d.ts new file mode 100644 index 0000000..e51e8a6 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/TROPHY_BASE_URL.d.ts @@ -0,0 +1 @@ +export declare const TROPHY_BASE_URL = "https://m.np.playstation.com/api/trophy"; diff --git a/node_modules/psn-api/dist/trophy/index.d.ts b/node_modules/psn-api/dist/trophy/index.d.ts new file mode 100644 index 0000000..5efd344 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/index.d.ts @@ -0,0 +1,2 @@ +export * from "./title"; +export * from "./user"; diff --git a/node_modules/psn-api/dist/trophy/title/getTitleTrophies.d.ts b/node_modules/psn-api/dist/trophy/title/getTitleTrophies.d.ts new file mode 100644 index 0000000..3746789 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/title/getTitleTrophies.d.ts @@ -0,0 +1,23 @@ +import type { AllCallOptions, AuthorizationPayload, TitleTrophiesResponse } from "../../models"; +type GetTitleTrophiesOptions = Pick; +/** + * A call to this function will retrieve the trophy list of a + * single - or all - trophy groups for a title. A title can have multiple + * groups of trophies (a `"default"` group which all titles have, and additional + * groups starting with the name `"001"` and incrementing for each additional group). To retrieve + * trophies from all groups within a title (ie. the full trophy set), then + * `trophyGroupId` should be set to `"all"`. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` parameter as `"trophy"`. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getTitleTrophies: (authorization: AuthorizationPayload, npCommunicationId: string, trophyGroupId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/title/getTitleTrophyGroups.d.ts b/node_modules/psn-api/dist/trophy/title/getTitleTrophyGroups.d.ts new file mode 100644 index 0000000..a391531 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/title/getTitleTrophyGroups.d.ts @@ -0,0 +1,19 @@ +import type { AllCallOptions, AuthorizationPayload, TitleTrophyGroupsResponse } from "../../models"; +type GetTitleTrophyGroupsOptions = Pick; +/** + * A title may have multiple groups of trophies. This is most commonly + * seen in games which have DLC expansions where additional trophies are added. + * + * You can call this function for a specific title - using the + * unique `npCommunicationId` for the title - and you will receive a + * summary of all of the trophy groups associated with the title. + * This also includes a summary of the number of trophies for the + * title, broken down by group and grade (gold, silver, etc.). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getTitleTrophyGroups: (authorization: AuthorizationPayload, npCommunicationId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/title/index.d.ts b/node_modules/psn-api/dist/trophy/title/index.d.ts new file mode 100644 index 0000000..c6e9bdf --- /dev/null +++ b/node_modules/psn-api/dist/trophy/title/index.d.ts @@ -0,0 +1,2 @@ +export * from "./getTitleTrophies"; +export * from "./getTitleTrophyGroups"; diff --git a/node_modules/psn-api/dist/trophy/user/getUserTitles.d.ts b/node_modules/psn-api/dist/trophy/user/getUserTitles.d.ts new file mode 100644 index 0000000..37b3c78 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/user/getUserTitles.d.ts @@ -0,0 +1,36 @@ +import type { AllCallOptions, AuthorizationPayload, UserTitlesResponse } from "../../models"; +type GetUserTitlesOptions = Pick; +/** + * A call to this function will retrieve a summarized list of titles played + * by a user, ordered by recent trophy unlocks. The maximum amount that can + * be returned by a single call is 800 (assuming a `limit` option of 800 is set). + * If the user has more titles than the given `limit` option, subsequent calls + * of this funciton must be made to fetch the complete list by paging via the + * `offset` option. + * + * The numeric `accountId` can be that of any PSN account for which the authenticating + * account has permissions to view the trophy list. When querying the titles + * associated with the authenticating account, the numeric `accountId` can be + * substituted with `"me"`. + * + * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()` + * function can be used. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * Included in the information returned is the titles' unique `npCommunicationId`. + * This is required to make use of subsequent functions for requesting more specific + * detail about a title's trophies. + * + * The results are presented in order of the `lastUpdatedDateTime` for the title, + * so the first result will be the title for which a trophy was most recently earned + * (or synced for the first time in the case of a game with 0% progress). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.limit Limit the number of titles returned. + * @param options.offset Return title data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getUserTitles: (authorization: AuthorizationPayload, accountId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/user/getUserTrophiesEarnedForTitle.d.ts b/node_modules/psn-api/dist/trophy/user/getUserTrophiesEarnedForTitle.d.ts new file mode 100644 index 0000000..46d324b --- /dev/null +++ b/node_modules/psn-api/dist/trophy/user/getUserTrophiesEarnedForTitle.d.ts @@ -0,0 +1,39 @@ +import type { AllCallOptions, AuthorizationPayload, UserTrophiesEarnedForTitleResponse } from "../../models"; +type GetUserTrophiesEarnedForTitleOptions = Pick; +/** + * A call to this function will retrieve the earned status of trophies for a user + * from either a single - or all - trophy groups in a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, and + * additional groups starting with a name of `"001"` and incrementing for each + * additional group). To retrieve trophies from all groups within a title + * (ie. the full trophy set), then `trophyGroupId` should be set to `"all"`. + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getUserTrophiesEarnedForTitle: (authorization: AuthorizationPayload, accountId: string, npCommunicationId: string, trophyGroupId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/user/getUserTrophyGroupEarningsForTitle.d.ts b/node_modules/psn-api/dist/trophy/user/getUserTrophyGroupEarningsForTitle.d.ts new file mode 100644 index 0000000..f7283b9 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/user/getUserTrophyGroupEarningsForTitle.d.ts @@ -0,0 +1,45 @@ +import type { AuthorizationPayload, CallValidHeaders, UserTrophyGroupEarningsForTitleResponse } from "../../models"; +interface GetUserTrophyGroupEarningsForTitleOptions { + /** + * Not required unless the platform is PS3, PS4, or PS Vita. + * If one of these platforms, the value __must__ be `"trophy"`. + * + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + headerOverrides: CallValidHeaders; +} +/** + * A request to this endpoint function will retrieve a summary of the trophies earned for + * a user broken down by trophy group within a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, + * and additional groups beginning with the name `"001"` and incrementing for + * each additional group). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function calls an endpoint that returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getUserTrophyGroupEarningsForTitle: (authorization: AuthorizationPayload, accountId: string, npCommunicationId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/user/getUserTrophyProfileSummary.d.ts b/node_modules/psn-api/dist/trophy/user/getUserTrophyProfileSummary.d.ts new file mode 100644 index 0000000..49b6c8f --- /dev/null +++ b/node_modules/psn-api/dist/trophy/user/getUserTrophyProfileSummary.d.ts @@ -0,0 +1,21 @@ +import type { AllCallOptions, AuthorizationPayload, UserTrophyProfileSummaryResponse } from "../../models"; +type GetUserTrophyProfileSummaryOptions = Pick; +/** + * A call to this function will retrieve an overall summary of the number of + * trophies earned for a user broken down by grade, as well as their current + * overall trophy level, progress towards the next level, and which tier their + * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export declare const getUserTrophyProfileSummary: (authorization: AuthorizationPayload, accountId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/trophy/user/index.d.ts b/node_modules/psn-api/dist/trophy/user/index.d.ts new file mode 100644 index 0000000..9c4b446 --- /dev/null +++ b/node_modules/psn-api/dist/trophy/user/index.d.ts @@ -0,0 +1,4 @@ +export * from "./getUserTitles"; +export * from "./getUserTrophiesEarnedForTitle"; +export * from "./getUserTrophyGroupEarningsForTitle"; +export * from "./getUserTrophyProfileSummary"; diff --git a/node_modules/psn-api/dist/user/USER_BASE_URL.d.ts b/node_modules/psn-api/dist/user/USER_BASE_URL.d.ts new file mode 100644 index 0000000..f4a883b --- /dev/null +++ b/node_modules/psn-api/dist/user/USER_BASE_URL.d.ts @@ -0,0 +1 @@ +export declare const USER_BASE_URL = "https://m.np.playstation.com/api/userProfile/v1/internal/users"; diff --git a/node_modules/psn-api/dist/user/getProfileFromAccountId.d.ts b/node_modules/psn-api/dist/user/getProfileFromAccountId.d.ts new file mode 100644 index 0000000..5cb0234 --- /dev/null +++ b/node_modules/psn-api/dist/user/getProfileFromAccountId.d.ts @@ -0,0 +1,12 @@ +import type { AllCallOptions, AuthorizationPayload, ProfileFromAccountIdResponse } from "../models"; +type GetProfileFromAccountIdOptions = Pick; +/** + * A call to this function will retrieve some profile information of the accountId being requested. + * If the account's profile cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The accountId for the user you wish to retrieve a profile for. + */ +export declare const getProfileFromAccountId: (authorization: AuthorizationPayload, accountId: string, options?: GetProfileFromAccountIdOptions) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/user/getProfileFromUserName.d.ts b/node_modules/psn-api/dist/user/getProfileFromUserName.d.ts new file mode 100644 index 0000000..53f7897 --- /dev/null +++ b/node_modules/psn-api/dist/user/getProfileFromUserName.d.ts @@ -0,0 +1,15 @@ +import type { AuthorizationPayload, ProfileFromUserNameResponse } from "../models"; +/** + * A call to this function will retrieve the profile of the username being requested. + * If the user cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * This is a legacy API endpoint function. If you are just trying to get a user's + * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) + * is recommended instead. This endpoint is here because it can return interesting + * presence information when the user is playing on a legacy console such as a PS3. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param userName The username for the user you wish to retrieve a profile for. + */ +export declare const getProfileFromUserName: (authorization: AuthorizationPayload, userName: string) => Promise; diff --git a/node_modules/psn-api/dist/user/getUserFriendsAccountIds.d.ts b/node_modules/psn-api/dist/user/getUserFriendsAccountIds.d.ts new file mode 100644 index 0000000..b8dea9e --- /dev/null +++ b/node_modules/psn-api/dist/user/getUserFriendsAccountIds.d.ts @@ -0,0 +1,14 @@ +import type { AllCallOptions, AuthorizationPayload, GetUserFriendsAccountIdsResponse } from "../models"; +type GetUserFriendsAccountIdsOptions = Pick; +/** + * A call to this function will retrieve the list of friended `accountId` values + * associated with the given `accountId` parameter. If the user cannot be found + * (either due to non-existence or privacy settings), an error will be thrown. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + */ +export declare const getUserFriendsAccountIds: (authorization: AuthorizationPayload, accountId: string, options?: Partial) => Promise; +export {}; diff --git a/node_modules/psn-api/dist/user/index.d.ts b/node_modules/psn-api/dist/user/index.d.ts new file mode 100644 index 0000000..9c9cb27 --- /dev/null +++ b/node_modules/psn-api/dist/user/index.d.ts @@ -0,0 +1,3 @@ +export * from "./getProfileFromAccountId"; +export * from "./getProfileFromUserName"; +export * from "./getUserFriendsAccountIds"; diff --git a/node_modules/psn-api/dist/utils/buildRequestUrl.d.ts b/node_modules/psn-api/dist/utils/buildRequestUrl.d.ts new file mode 100644 index 0000000..619e1ba --- /dev/null +++ b/node_modules/psn-api/dist/utils/buildRequestUrl.d.ts @@ -0,0 +1,2 @@ +import type { AllCallOptions } from "../models"; +export declare const buildRequestUrl: (baseUrl: string, endpointUrl: string, options?: Partial, args?: Record) => string; diff --git a/node_modules/psn-api/dist/utils/call.d.ts b/node_modules/psn-api/dist/utils/call.d.ts new file mode 100644 index 0000000..a7185e7 --- /dev/null +++ b/node_modules/psn-api/dist/utils/call.d.ts @@ -0,0 +1,6 @@ +import type { AuthorizationPayload, CallValidHeaders } from "../models"; +export declare const call: (config: { + url: string; + method?: "GET" | "POST"; + headers?: CallValidHeaders; +}, authorization: AuthorizationPayload, bodyPayload?: Record) => Promise; diff --git a/node_modules/psn-api/package.json b/node_modules/psn-api/package.json new file mode 100644 index 0000000..77c525d --- /dev/null +++ b/node_modules/psn-api/package.json @@ -0,0 +1,117 @@ +{ + "name": "psn-api", + "description": "A well-tested library that lets you get trophy, user, and game data from the PlayStation Network.", + "keywords": [ + "psn", + "playstation", + "trophies", + "npsso", + "achievements", + "ps4", + "ps5" + ], + "version": "2.9.0", + "main": "dist/index.js", + "module": "dist/psn-api.esm.js", + "typings": "dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/psn-api.esm.js" + } + }, + "author": "Wes Copeland", + "license": "MIT", + "files": [ + "dist", + "src" + ], + "scripts": { + "dev": "dts watch", + "playground": "esrun --watch src/__playground.ts", + "build": "dts build", + "prepare": "dts build", + "format": "prettier --write . '**/*.{json,md,js,ts,tsx}'", + "format:write": "prettier --write . '**/*.{json,md,js,ts,tsx}'", + "format:check": "prettier --check . '**/*.{json,md,js,ts,tsx}'", + "lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .", + "lint:fix": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx . --fix", + "test": "jest --selectProjects UNIT", + "test:coverage": "jest --selectProjects UNIT --coverage", + "verify": "npm run format:check && npm run lint && npm run test:coverage && npm run build && npm run size", + "size": "size-limit", + "analyze": "size-limit --why", + "semantic-release": "semantic-release" + }, + "dependencies": { + "isomorphic-unfetch": "^3.1.0" + }, + "peerDependencies": {}, + "devDependencies": { + "@commitlint/cli": "^17.4.2", + "@commitlint/config-conventional": "^17.4.2", + "@digitak/esrun": "^3.2.19", + "@faker-js/faker": "^7.6.0", + "@size-limit/preset-small-lib": "^8.1.2", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.12", + "@typescript-eslint/eslint-plugin": "^5.50.0", + "@typescript-eslint/parser": "^5.50.0", + "cz-conventional-changelog": "^3.3.0", + "dotenv-flow-cli": "^1.0.0", + "dts-cli": "^1.6.3", + "eslint": "^8.33.0", + "eslint-config-prettier": "^8.6.0", + "eslint-import-resolver-typescript": "^3.5.3", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-simple-import-sort": "^8.0.0", + "eslint-plugin-sonarjs": "^0.16.0", + "eslint-plugin-unicorn": "^44.0.2", + "husky": "^4.3.8", + "jest": "^29.4.1", + "msw": "^1.1.0", + "prettier": "2.7.1", + "pretty-quick": "^3.1.3", + "semantic-release": "^19.0.5", + "size-limit": "^8.1.2", + "ts-jest": "^29.0.5", + "tslib": "^2.5.0", + "typescript": "^4.9.5" + }, + "size-limit": [ + { + "path": "dist/psn-api.cjs.production.min.js", + "limit": "10 KB", + "brotli": true + }, + { + "path": "dist/psn-api.esm.js", + "limit": "10 KB", + "brotli": true + } + ], + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged && npm run lint", + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" + } + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "release": { + "branches": [ + "master", + "next" + ] + }, + "repository": { + "type": "git", + "url": "https://github.com/achievements-app/psn-api.git" + }, + "resolutions": { + "rxjs": "^6.6.0" + } +} diff --git a/node_modules/psn-api/src/authenticate/AUTH_BASE_URL.ts b/node_modules/psn-api/src/authenticate/AUTH_BASE_URL.ts new file mode 100644 index 0000000..03f422b --- /dev/null +++ b/node_modules/psn-api/src/authenticate/AUTH_BASE_URL.ts @@ -0,0 +1 @@ +export const AUTH_BASE_URL = "https://ca.account.sony.com/api/authz/v3/oauth"; diff --git a/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.test.ts b/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.test.ts new file mode 100644 index 0000000..1d15b6d --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.test.ts @@ -0,0 +1,56 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { AuthTokensResponse } from "../models"; +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; +import { exchangeCodeForAccessToken } from "./exchangeCodeForAccessToken"; + +const server = setupServer(); + +describe("Function: exchangeCodeForAccessToken", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(exchangeCodeForAccessToken).toBeDefined(); + }); + + it("makes a call to exchange an access code for a set of OAuth tokens", async () => { + // ARRANGE + const mockAuthTokensResponse: AuthTokensResponse = { + accessToken: "mockAccessToken", + expiresIn: 3000, + idToken: "mockIdToken", + refreshToken: "mockRefreshToken", + refreshTokenExpiresIn: 9999, + scope: "mockScope", + tokenType: "bearer" + }; + + server.use( + rest.post(`${AUTH_BASE_URL}/token`, (_, res, ctx) => { + return res( + ctx.json({ + access_token: mockAuthTokensResponse.accessToken, + expires_in: mockAuthTokensResponse.expiresIn, + id_token: mockAuthTokensResponse.idToken, + refresh_token: mockAuthTokensResponse.refreshToken, + refresh_token_expires_in: + mockAuthTokensResponse.refreshTokenExpiresIn, + token_type: mockAuthTokensResponse.tokenType, + scope: mockAuthTokensResponse.scope + }) + ); + }) + ); + + // ACT + const tokenResponse = await exchangeCodeForAccessToken("mockAccessCode"); + + // ASSERT + expect(tokenResponse).toEqual(mockAuthTokensResponse); + }); +}); diff --git a/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.ts b/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.ts new file mode 100644 index 0000000..54ee59b --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeCodeForAccessToken.ts @@ -0,0 +1,41 @@ +import fetch from "isomorphic-unfetch"; + +import type { AuthTokensResponse } from "../models"; +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; + +/** + * @param accessCode Your access code, typically retrieved by using `exchangeNpssoForCode()`. + * @returns An object containing an access token, refresh token, and expiry times for both. + */ +export const exchangeCodeForAccessToken = async ( + accessCode: string +): Promise => { + const requestUrl = `${AUTH_BASE_URL}/token`; + + const res = await fetch(requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: + "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + code: accessCode, + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + grant_type: "authorization_code", + token_format: "jwt" + }).toString() + }); + + const raw = await res.json(); + + return { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }; +}; diff --git a/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.test.ts b/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.test.ts new file mode 100644 index 0000000..636131a --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.test.ts @@ -0,0 +1,52 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; +import { exchangeNpssoForCode } from "./exchangeNpssoForCode"; + +const server = setupServer(); + +describe("Function: exchangeNpssoForCode", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(exchangeNpssoForCode).toBeDefined(); + }); + + it("can make a call to exchange an NPSSO token for an access code", async () => { + // ARRANGE + const mockCode = "v3.ABCDEF"; + const mockLocationHeaderResponse = `com.playstation.PlayStationApp://redirect/?code=${mockCode}&cid=36e3823a-8049-4c36-9021-b154315ae2ad`; + + server.use( + rest.get(`${AUTH_BASE_URL}/authorize`, (_, res, ctx) => { + return res( + ctx.status(302), + ctx.set("Location", mockLocationHeaderResponse) + ); + }) + ); + + // ACT + const code = await exchangeNpssoForCode("mockNpsso"); + + // ASSERT + expect(code).toEqual(mockCode); + }); + + it("throws an error if we receive an unexpected response", async () => { + // ARRANGE + server.use( + rest.get(`${AUTH_BASE_URL}/authorize`, (_, res, ctx) => { + return res(ctx.json({})); + }) + ); + + // ASSERT + await expect(exchangeNpssoForCode("mockNpsso")).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.ts b/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.ts new file mode 100644 index 0000000..fa34042 --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeNpssoForCode.ts @@ -0,0 +1,55 @@ +import fetch from "isomorphic-unfetch"; + +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; + +/** + * + * @param npssoToken Your NPSSO token, retrieved from https://ca.account.sony.com/api/v1/ssocookie + * @returns An access code, which can be exchanged for an access token using `exchangeCodeForAccessToken`. + * @example + * ```ts + * const code = await exchangeNpssoForCode("myNpssoToken"); + * + * console.log(code) // --> "v3.XXXXXX" + * ``` + */ +export const exchangeNpssoForCode = async ( + npssoToken: string +): Promise => { + const queryString = new URLSearchParams({ + access_type: "offline", + client_id: "09515159-7237-4370-9b40-3806e67c0891", + redirect_uri: "com.scee.psxandroid.scecompcall://redirect", + response_type: "code", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString(); + + const requestUrl = `${AUTH_BASE_URL}/authorize?${queryString}`; + + // This never returns a 200. As of Oct 10 2021, it seems to return a 302. + const { headers: responseHeaders } = await fetch(requestUrl, { + headers: { + Cookie: `npsso=${npssoToken}` + }, + redirect: "manual" + }); + + // The access code itself is stored in a header on the response. + // We'll perform a few validations to ensure it's actually there. + if ( + !responseHeaders.has("location") || + !responseHeaders.get("location")?.includes("?code=") + ) { + throw new Error(` + There was a problem retrieving your PSN access code. Is your NPSSO code valid? + To get a new NPSSO code, visit https://ca.account.sony.com/api/v1/ssocookie. + `); + } + + const redirectLocation = responseHeaders.get("location") as string; + const redirectParams = new URLSearchParams( + redirectLocation.split("redirect/")[1] + ); + + return redirectParams.get("code") as string; +}; diff --git a/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.test.ts b/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.test.ts new file mode 100644 index 0000000..3c3d4c4 --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.test.ts @@ -0,0 +1,58 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { AuthTokensResponse } from "../models"; +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; +import { exchangeRefreshTokenForAuthTokens } from "./exchangeRefreshTokenForAuthTokens"; + +const server = setupServer(); + +describe("Function: exchangeRefreshTokenForAuthTokens", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(exchangeRefreshTokenForAuthTokens).toBeDefined(); + }); + + it("makes a call to exchange a refresh token for a set of OAuth tokens", async () => { + // ARRANGE + const mockAuthTokensResponse: AuthTokensResponse = { + accessToken: "mockAccessToken", + expiresIn: 3000, + idToken: "mockIdToken", + refreshToken: "mockRefreshToken", + refreshTokenExpiresIn: 9999, + scope: "mockScope", + tokenType: "bearer" + }; + + server.use( + rest.post(`${AUTH_BASE_URL}/token`, (_, res, ctx) => { + return res( + ctx.json({ + access_token: mockAuthTokensResponse.accessToken, + expires_in: mockAuthTokensResponse.expiresIn, + id_token: mockAuthTokensResponse.idToken, + refresh_token: mockAuthTokensResponse.refreshToken, + refresh_token_expires_in: + mockAuthTokensResponse.refreshTokenExpiresIn, + token_type: mockAuthTokensResponse.tokenType, + scope: mockAuthTokensResponse.scope + }) + ); + }) + ); + + // ACT + const tokenResponse = await exchangeRefreshTokenForAuthTokens( + "mockAccessCode" + ); + + // ASSERT + expect(tokenResponse).toEqual(mockAuthTokensResponse); + }); +}); diff --git a/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.ts b/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.ts new file mode 100644 index 0000000..4d7aadb --- /dev/null +++ b/node_modules/psn-api/src/authenticate/exchangeRefreshTokenForAuthTokens.ts @@ -0,0 +1,37 @@ +import fetch from "isomorphic-unfetch"; + +import type { AuthTokensResponse } from "../models"; +import { AUTH_BASE_URL } from "./AUTH_BASE_URL"; + +export const exchangeRefreshTokenForAuthTokens = async ( + refreshToken: string +): Promise => { + const requestUrl = `${AUTH_BASE_URL}/token`; + + const res = await fetch(requestUrl, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: + "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=" + }, + body: new URLSearchParams({ + refresh_token: refreshToken, + grant_type: "refresh_token", + token_format: "jwt", + scope: "psn:mobile.v2.core psn:clientapp" + }).toString() + }); + + const raw = await res.json(); + + return { + accessToken: raw.access_token, + expiresIn: raw.expires_in, + idToken: raw.id_token, + refreshToken: raw.refresh_token, + refreshTokenExpiresIn: raw.refresh_token_expires_in, + scope: raw.scope, + tokenType: raw.token_type + }; +}; diff --git a/node_modules/psn-api/src/authenticate/index.ts b/node_modules/psn-api/src/authenticate/index.ts new file mode 100644 index 0000000..140b3fb --- /dev/null +++ b/node_modules/psn-api/src/authenticate/index.ts @@ -0,0 +1,3 @@ +export * from "./exchangeCodeForAccessToken"; +export * from "./exchangeNpssoForCode"; +export * from "./exchangeRefreshTokenForAuthTokens"; diff --git a/node_modules/psn-api/src/graphql/GRAPHQL_BASE_URL.ts b/node_modules/psn-api/src/graphql/GRAPHQL_BASE_URL.ts new file mode 100644 index 0000000..a1f72a8 --- /dev/null +++ b/node_modules/psn-api/src/graphql/GRAPHQL_BASE_URL.ts @@ -0,0 +1,2 @@ +export const GRAPHQL_BASE_URL = + "https://web.np.playstation.com/api/graphql/v1/op"; diff --git a/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.test.ts b/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.test.ts new file mode 100644 index 0000000..38e8179 --- /dev/null +++ b/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.test.ts @@ -0,0 +1,136 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + RecentlyPlayedGamesResponse +} from "../models"; +import { getRecentlyPlayedGames } from "./getRecentlyPlayedGames"; +import { GRAPHQL_BASE_URL } from "./GRAPHQL_BASE_URL"; + +const server = setupServer(); +const accessToken = "mockAccessToken"; + +describe("Function: getRecentlyPlayedGames", () => { + // MSW Setup + beforeAll(() => + server.listen({ + onUnhandledRequest: "error" + }) + ); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getRecentlyPlayedGames).toBeDefined(); + }); + + it("retrieves games the user has played recently", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken + }; + + const mockResponse: RecentlyPlayedGamesResponse = { + data: { + gameLibraryTitlesRetrieve: { + __typename: "GameList", + games: [ + { + __typename: "GameLibraryTitle", + conceptId: "203715", + entitlementId: "EP2002-CUSA01433_00-ROCKETLEAGUEEU01", + image: { + __typename: "Media", + url: "https://image.api.playstation.com/gs2-sec/appkgo/prod/CUSA01433_00/7/i_5c5e430a49994f22df5fd81f446ead7b6ae45027af490b415fe4e744a9918e4c/i/icon0.png" + }, + isActive: true, + lastPlayedDateTime: "2023-03-10T01:01:01.390000Z", + name: "Rocket League®", + platform: "PS4", + productId: "EP2002-CUSA01433_00-ROCKETLEAGUEEU01", + subscriptionService: "NONE", + titleId: "CUSA01433_00" + }, + { + __typename: "GameLibraryTitle", + conceptId: "10004142", + entitlementId: null, + image: { + __typename: "Media", + url: "https://image.api.playstation.com/vulcan/ap/rnd/202208/2505/DE9sevLlnfHm7vLrRwDFEZpO.png" + }, + isActive: null, + lastPlayedDateTime: "2023-01-19T01:01:01.900000Z", + name: "CRISIS CORE –FINAL FANTASY VII– REUNION PS4 & PS5", + platform: "PS5", + productId: null, + subscriptionService: "NONE", + titleId: "PPSA07809_00" + } + ] + } + } + }; + + let headers!: Record; + let searchParams!: URLSearchParams; + + server.use( + rest.get(GRAPHQL_BASE_URL, (_, res, ctx) => { + headers = _.headers.raw(); + searchParams = _.url.searchParams; + + return res(ctx.json(mockResponse)); + }) + ); + + // ACT + const response = await getRecentlyPlayedGames(mockAuthorization, { + categories: ["ps4_game", "ps5_native_game"], + limit: 2 + }); + + // ASSERT + expect(response).toEqual(mockResponse); + expect(headers["authorization"]).toEqual(`Bearer ${accessToken}`); + expect(searchParams.get("operationName")).toEqual("getUserGameList"); + expect(searchParams.get("variables")).toEqual( + JSON.stringify({ limit: 2, categories: "ps4_game,ps5_native_game" }) + ); + expect(searchParams.get("extensions")).toEqual( + JSON.stringify({ + persistedQuery: { + version: 1, + sha256Hash: + "e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae" + } + }) + ); + }); + + it("throws an error if we receive a malformed response", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken + }; + + const mockResponse = { + // This response occurs if the query/hash is not what the server expected + message: + "Query 4e8add9915e3cb6870d778cff38e7f81899066f5603ced4c87d6d7c0abc99941 not whitelisted" + }; + + server.use( + rest.get(GRAPHQL_BASE_URL, (_, res, ctx) => { + return res(ctx.json(mockResponse)); + }) + ); + + // ASSERT + await expect(getRecentlyPlayedGames(mockAuthorization)).rejects.toThrow( + "Query 4e8add9915e3cb6870d778cff38e7f81899066f5603ced4c87d6d7c0abc99941 not whitelisted" + ); + }); +}); diff --git a/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.ts b/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.ts new file mode 100644 index 0000000..65dffb5 --- /dev/null +++ b/node_modules/psn-api/src/graphql/getRecentlyPlayedGames.ts @@ -0,0 +1,60 @@ +import type { + AllCallOptions, + AuthorizationPayload, + RecentlyPlayedGamesResponse +} from "../models"; +import { call } from "../utils/call"; +import { GRAPHQL_BASE_URL } from "./GRAPHQL_BASE_URL"; +import { getUserGameListHash } from "./operationHashes"; + +type GetRecentlyPlayedGamesOptionsCategories = "ps4_game" | "ps5_native_game"; +type GetRecentlyPlayedGamesOptions = Pick & { + categories: GetRecentlyPlayedGamesOptionsCategories[]; +}; + +/** + * A call to this function will retrieve recently played games for the user associated + * with the npsso token provided to this module during initialisation. + * + * This is useful if you want recent activity that isn't tied to trophy progress. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + */ +export const getRecentlyPlayedGames = async ( + authorization: AuthorizationPayload, + options: Partial = {} +): Promise => { + const { limit = 50, categories = ["ps4_game", "ps5_native_game"] } = options; + + const url = new URL(GRAPHQL_BASE_URL); + + url.searchParams.set("operationName", "getUserGameList"); + url.searchParams.set( + "variables", + JSON.stringify({ + limit, + categories: categories.join(",") + }) + ); + url.searchParams.set( + "extensions", + JSON.stringify({ + persistedQuery: { + version: 1, + sha256Hash: getUserGameListHash + } + }) + ); + + const response = await call( + { url: url.toString() }, + authorization + ); + + // The GraphQL queries can return non-truthy values. + if (!response.data || !response.data.gameLibraryTitlesRetrieve) { + throw new Error(JSON.stringify(response)); + } + + return response; +}; diff --git a/node_modules/psn-api/src/graphql/index.ts b/node_modules/psn-api/src/graphql/index.ts new file mode 100644 index 0000000..da84229 --- /dev/null +++ b/node_modules/psn-api/src/graphql/index.ts @@ -0,0 +1 @@ +export * from "./getRecentlyPlayedGames"; diff --git a/node_modules/psn-api/src/graphql/operationHashes.ts b/node_modules/psn-api/src/graphql/operationHashes.ts new file mode 100644 index 0000000..eade307 --- /dev/null +++ b/node_modules/psn-api/src/graphql/operationHashes.ts @@ -0,0 +1,21 @@ +/** + * GraphQL endpoints work differently to others in the codebase. + * + * The hashes in this file are reverse engineered from app-.js file loaded by the page + * at https://library.playstation.com/recently-played. Following the code in that file leads + * to some Apollo GraphQL code related to persisted queries. This means the request needs to + * contain a SHA256 hash of the GraphQL query being executed. Searching for PersistedQueryLink + * and createPersistedQueryLink_hashes, and an AST function in Sony's JS source and debugging + * will surface the exact GraphQL query that's passed to the hash function on the page. + * + * Thankfully it's easier to figure out future endpoints and hashes by: + * + * 1. Visiting a page, e.g https://library.playstation.com/recently-played + * 2. Using DevTools to find requests to https://web.np.playstation.com/api/graphql/v1/op + * 3. Decoding the URL parameters to find the correct SHA256 hash and some of the supported parameters + */ + +// Hash is computed from the following query (without surrounding quotes): +// "query getUserGameList($categories: String, $limit: Int, $orderBy: String, $subscriptionService: SubscriptionService) {\n gameLibraryTitlesRetrieve(categories: $categories, limit: $limit, orderBy: $orderBy, subscriptionService: $subscriptionService) {\n __typename\n games {\n __typename\n conceptId\n entitlementId\n image {\n __typename\n url\n }\n isActive\n lastPlayedDateTime\n name\n platform\n productId\n subscriptionService\n titleId\n }\n }\n}\n" +export const getUserGameListHash = + "e780a6d8b921ef0c59ec01ea5c5255671272ca0d819edb61320914cf7a78b3ae"; diff --git a/node_modules/psn-api/src/index.ts b/node_modules/psn-api/src/index.ts new file mode 100644 index 0000000..bad1a1c --- /dev/null +++ b/node_modules/psn-api/src/index.ts @@ -0,0 +1,7 @@ +export * from "./authenticate"; +export * from "./graphql"; +export * from "./models"; +export * from "./search"; +export * from "./trophy"; +export * from "./user"; +export * from "./utils/call"; diff --git a/node_modules/psn-api/src/models/all-call-options.model.ts b/node_modules/psn-api/src/models/all-call-options.model.ts new file mode 100644 index 0000000..d6ffaea --- /dev/null +++ b/node_modules/psn-api/src/models/all-call-options.model.ts @@ -0,0 +1,24 @@ +import type { CallValidHeaders } from "./call-valid-headers.model"; + +export interface AllCallOptions { + /** + * Not required unless the platform is PS3, PS4, or PS Vita. + * If one of these platforms, the value __must__ be `"trophy"`. + * + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + + /** Limit the number of entities returned. */ + limit: number; + + /** Return entity data from this result onwards. */ + offset: number; + + /* + * Override the headers in the request to the PSN API, + * such as to change the language. + */ + headerOverrides: CallValidHeaders; +} diff --git a/node_modules/psn-api/src/models/auth-tokens-response.model.ts b/node_modules/psn-api/src/models/auth-tokens-response.model.ts new file mode 100644 index 0000000..80f1868 --- /dev/null +++ b/node_modules/psn-api/src/models/auth-tokens-response.model.ts @@ -0,0 +1,18 @@ +export interface AuthTokensResponse { + /** Used to retrieve data from the PSN API. */ + accessToken: string; + + /** When the access token will expire. */ + expiresIn: number; + + idToken: string; + + /** Used to retrieve a new access token when it expires. */ + refreshToken: string; + + /** When the refresh token will expire. */ + refreshTokenExpiresIn: number; + + scope: string; + tokenType: string; +} diff --git a/node_modules/psn-api/src/models/authorization-payload.model.ts b/node_modules/psn-api/src/models/authorization-payload.model.ts new file mode 100644 index 0000000..091cc17 --- /dev/null +++ b/node_modules/psn-api/src/models/authorization-payload.model.ts @@ -0,0 +1,3 @@ +export interface AuthorizationPayload { + accessToken: string; +} diff --git a/node_modules/psn-api/src/models/call-valid-headers.model.ts b/node_modules/psn-api/src/models/call-valid-headers.model.ts new file mode 100644 index 0000000..5d9c2db --- /dev/null +++ b/node_modules/psn-api/src/models/call-valid-headers.model.ts @@ -0,0 +1,3 @@ +export interface CallValidHeaders { + "Accept-Language": string; +} diff --git a/node_modules/psn-api/src/models/get-user-friends-account-ids-response.model.ts b/node_modules/psn-api/src/models/get-user-friends-account-ids-response.model.ts new file mode 100644 index 0000000..243e6a7 --- /dev/null +++ b/node_modules/psn-api/src/models/get-user-friends-account-ids-response.model.ts @@ -0,0 +1,10 @@ +export interface GetUserFriendsAccountIdsResponse { + /** A list of `accountId` values corresponding to accounts on the target user's friend list. */ + friends: string[]; + + /** The total number of friends the target user has on their friends list. */ + totalItemCount: number; + + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/src/models/index.ts b/node_modules/psn-api/src/models/index.ts new file mode 100644 index 0000000..107dde4 --- /dev/null +++ b/node_modules/psn-api/src/models/index.ts @@ -0,0 +1,28 @@ +export * from "./all-call-options.model"; +export * from "./auth-tokens-response.model"; +export * from "./authorization-payload.model"; +export * from "./call-valid-headers.model"; +export * from "./get-user-friends-account-ids-response.model"; +export * from "./profile-from-account-id-response.model"; +export * from "./profile-from-user-name-response.model"; +export * from "./rarest-thin-trophy.model"; +export * from "./recently-played-games-response.model"; +export * from "./social-account-result.model"; +export * from "./title-platform.model"; +export * from "./title-thin-trophy.model"; +export * from "./title-trophies-response.model"; +export * from "./title-trophy-groups-response.model"; +export * from "./trophy.model"; +export * from "./trophy-counts.model"; +export * from "./trophy-group-earnings.model"; +export * from "./trophy-rarity.model"; +export * from "./trophy-title.model"; +export * from "./trophy-title.model"; +export * from "./trophy-type.model"; +export * from "./universal-search-domains.model"; +export * from "./universal-search-response.model"; +export * from "./user-thin-trophy.model"; +export * from "./user-titles-response.model"; +export * from "./user-trophies-earned-for-title-response.model"; +export * from "./user-trophy-group-earnings-for-title-response.model"; +export * from "./user-trophy-profile-summary-response.model"; diff --git a/node_modules/psn-api/src/models/profile-from-account-id-response.model.ts b/node_modules/psn-api/src/models/profile-from-account-id-response.model.ts new file mode 100644 index 0000000..004338a --- /dev/null +++ b/node_modules/psn-api/src/models/profile-from-account-id-response.model.ts @@ -0,0 +1,20 @@ +export interface ProfileFromAccountIdResponse { + /** + * The account's online username. + * + * @example + * ```json + * "onlineId": "Hakoom" + * ``` + */ + onlineId: string; + aboutMe: string; + avatars: Array<{ size: string; url: string }>; + + languages: string[]; + /** Whether or not the account is a PlayStation Plus subscriber. */ + isPlus: boolean; + + isOfficiallyVerified: boolean; + isMe: boolean; +} diff --git a/node_modules/psn-api/src/models/profile-from-user-name-response.model.ts b/node_modules/psn-api/src/models/profile-from-user-name-response.model.ts new file mode 100644 index 0000000..a97b509 --- /dev/null +++ b/node_modules/psn-api/src/models/profile-from-user-name-response.model.ts @@ -0,0 +1,78 @@ +export interface ProfileFromUserNameResponse { + profile: { + /** + * The account's online username. + * + * @example + * ```json + * "onlineId": "Hakoom" + * ``` + */ + onlineId: string; + + /** + * The account's internal ID value, which can be used for numerous + * calls to the PSN API. + * + * @example + * ```json + * "accountId": "962157895908076652" + * ``` + */ + accountId: string; + + npId: string; + avatarUrls: Array<{ size: string; avatarUrl: string }>; + + /** Whether or not the account is a PlayStation Plus subscriber. */ + plus: 0 | 1; + aboutMe: string; + languagesUsed: string[]; + + /** + * The account's trophy level, progress towards the next level, + * and total number of trophies earned by type. + */ + trophySummary: { + level: number; + progress: number; + earnedTrophies: { + bronze: number; + silver: number; + gold: number; + platinum: number; + }; + }; + + isOfficiallyVerified: boolean; + + personalDetail: { + firstName: string; + lastName: string; + profilePictureUrls: Array<{ size: string; profilePictureUrl: string }>; + }; + + personalDetailSharing: string; + personalDetailSharingRequestMessageFlag: boolean; + primaryOnlineStatus: string; + + presences: Array<{ + onlineStatus: string; + hasBroadcastData: boolean; + lastOnlineDate: string; + }>; + + friendRelation: string; + requestMessageFlag: boolean; + + /** + * Whether or not the account is blocked by the retrieving authentication context. + * For example, if you are using psn-api with _your_ account's access token, and + * your account has blocked the account you're looking up, this will be `true`. + */ + blocking: boolean; + + following: boolean; + consoleAvailability: { availabilityStatus: string }; + }; +} diff --git a/node_modules/psn-api/src/models/rarest-thin-trophy.model.ts b/node_modules/psn-api/src/models/rarest-thin-trophy.model.ts new file mode 100644 index 0000000..539db7a --- /dev/null +++ b/node_modules/psn-api/src/models/rarest-thin-trophy.model.ts @@ -0,0 +1,11 @@ +import type { Trophy } from "./trophy.model"; + +export type RarestThinTrophy = Pick< + Trophy, + | "trophyId" + | "trophyHidden" + | "earned" + | "trophyType" + | "trophyRare" + | "trophyEarnedRate" +>; diff --git a/node_modules/psn-api/src/models/recently-played-games-response.model.ts b/node_modules/psn-api/src/models/recently-played-games-response.model.ts new file mode 100644 index 0000000..022a431 --- /dev/null +++ b/node_modules/psn-api/src/models/recently-played-games-response.model.ts @@ -0,0 +1,72 @@ +import { TitlePlatform } from "./title-platform.model"; + +export interface RecentlyPlayedGame { + /** GrahpQL object type/schema */ + __typename: "GameLibraryTitle"; + + /** Contains a url to a game icon file. */ + image: { + __typename: "Media"; + url: string; + }; + + /** + * Unclear what this represents, but if this is set to true then + * the productId property is not null. + */ + isActive: boolean | null; + + /** + * An ISO date representing the last play date and time + * of the given title, e.g 2023-03-10T01:01:01.390000Z + */ + lastPlayedDateTime: string; + + /** The name of the game */ + name: string; + + /** + * The platform this game was last played on. This can be reported as + * "UNKNOWN". It appears that "UNKNOWN" is shown in certain scenarios + * when a user that isn't associated with the access token is sharing + * the same console as the user that is identified by the access token. + */ + platform: TitlePlatform | "UNKNOWN"; + + /** + * ID of the product. Used in the PlayStation Store URL. Appears to only be + * set for certain PS4 games along with the entitlementId. + */ + productId: string | null; + + /** + * Similar to productId. Used in URLs for the PlayStation Store, i.e + * store.playstation.com/en-ae/product/:entitlementId. Appears to only + * be set for certain entries on the PS4 platform along with productId. + */ + entitlementId: string | null; + + /** + * ID of the product. Forms part of a PlayStation Store URL, e.g + * https://store.playstation.com/en-us/product/UP9000-$titleId-RATCHETCLANKRIFT + */ + titleId: string; + + /** + * An ID for titles on the PlayStation store. It's used in the + * URL, i.e store.playstation.com/ko-kr/concept/:conceptId + */ + conceptId: string; + + /** Unsure what data this can hold. Perhaps it's PS Now related? */ + subscriptionService: "NONE" | string; +} + +export interface RecentlyPlayedGamesResponse { + data: { + gameLibraryTitlesRetrieve: { + __typename: "GameList"; + games: RecentlyPlayedGame[]; + }; + }; +} diff --git a/node_modules/psn-api/src/models/social-account-result.model.ts b/node_modules/psn-api/src/models/social-account-result.model.ts new file mode 100644 index 0000000..ee1306e --- /dev/null +++ b/node_modules/psn-api/src/models/social-account-result.model.ts @@ -0,0 +1,18 @@ +export interface SocialAccountResult { + id: string; + type: string; + score: number; + socialMetadata: { + accountId: string; + country: string; + language: string; + onlineId: string; + isPsPlus: boolean; + isOfficiallyVerified: boolean; + avatarUrl: string; + verifiedUserName: string; + highlights: { + onlineId: string[]; + }; + }; +} diff --git a/node_modules/psn-api/src/models/title-platform.model.ts b/node_modules/psn-api/src/models/title-platform.model.ts new file mode 100644 index 0000000..22e0d7f --- /dev/null +++ b/node_modules/psn-api/src/models/title-platform.model.ts @@ -0,0 +1 @@ +export type TitlePlatform = "PS5" | "PS4" | "PS3" | "Vita"; diff --git a/node_modules/psn-api/src/models/title-thin-trophy.model.ts b/node_modules/psn-api/src/models/title-thin-trophy.model.ts new file mode 100644 index 0000000..6947bf7 --- /dev/null +++ b/node_modules/psn-api/src/models/title-thin-trophy.model.ts @@ -0,0 +1,12 @@ +import type { Trophy } from "./trophy.model"; + +export type TitleThinTrophy = Pick< + Trophy, + | "trophyId" + | "trophyHidden" + | "trophyType" + | "trophyName" + | "trophyDetail" + | "trophyIconUrl" + | "trophyGroupId" +>; diff --git a/node_modules/psn-api/src/models/title-trophies-response.model.ts b/node_modules/psn-api/src/models/title-trophies-response.model.ts new file mode 100644 index 0000000..fbb1083 --- /dev/null +++ b/node_modules/psn-api/src/models/title-trophies-response.model.ts @@ -0,0 +1,18 @@ +import type { TitleThinTrophy } from "./title-thin-trophy.model"; + +export interface TitleTrophiesResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + + /** `true` if this title has additional trophy groups. This is commonly used for DLC, but some games add additional trophies as separate groups post-release (such as Astro's Playroom and Horizon Zero Dawn). */ + hasTrophyGroups: boolean; + + /** Individual object for each trophy. */ + trophies: TitleThinTrophy[]; + + /** Total trophies in the group (or total trophies for the title if `"all"` specified) */ + totalItemCount: number; + + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/src/models/title-trophy-groups-response.model.ts b/node_modules/psn-api/src/models/title-trophy-groups-response.model.ts new file mode 100644 index 0000000..7e7ffcd --- /dev/null +++ b/node_modules/psn-api/src/models/title-trophy-groups-response.model.ts @@ -0,0 +1,32 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroup } from "./trophy-group.model"; + +export interface TitleTrophyGroupsResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + + /** The title name that this trophy belongs to. */ + trophyTitleName: string; + + /** URL of the icon for the trophy title. */ + trophyTitleIconUrl: string; + + /** + * The platform this title belongs to. Some games have trophy sets which + * are shared between multiple platforms (eg. PS4,PSVITA). + * The platforms in these instances will be comma-separated. + */ + trophyTitlePlatform: string; + + /** Total number of trophies for the title by type. */ + definedTrophies: TrophyCounts; + + /** Individual entities for each trophy group associated with the given title. */ + trophyGroups: TrophyGroup[]; + + /** + * The title description that this trophy belongs to. + * This is a legacy property that applies to PS3, PS4, and PS Vita titles only. + */ + trophyTitleDetail?: string; +} diff --git a/node_modules/psn-api/src/models/trophy-counts.model.ts b/node_modules/psn-api/src/models/trophy-counts.model.ts new file mode 100644 index 0000000..588235f --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-counts.model.ts @@ -0,0 +1,13 @@ +export interface TrophyCounts { + /** Total count of bronze trophies. */ + bronze: number; + + /** Total count of silver trophies. */ + silver: number; + + /** Total count of gold trophies. */ + gold: number; + + /** 1 if the group contains a platinum trophy. */ + platinum: 0 | 1; +} diff --git a/node_modules/psn-api/src/models/trophy-group-earnings.model.ts b/node_modules/psn-api/src/models/trophy-group-earnings.model.ts new file mode 100644 index 0000000..210f604 --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-group-earnings.model.ts @@ -0,0 +1,24 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroup } from "./trophy-group.model"; + +type FromTrophyGroup = Pick; + +export interface TrophyGroupEarnings extends FromTrophyGroup { + /** + * The percentage completion of the trophy group by the user. + * @example `100` + * @example `20` + */ + progress: number; + + /** The account's number of earned trophies for the trophy group by grade. */ + earnedTrophies: TrophyCounts; + + /** + * An ISO 8601 string representing the date the + * group progress was updated (such as when a + * trophy was earned). + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; +} diff --git a/node_modules/psn-api/src/models/trophy-group.model.ts b/node_modules/psn-api/src/models/trophy-group.model.ts new file mode 100644 index 0000000..f5f09d1 --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-group.model.ts @@ -0,0 +1,29 @@ +import type { TrophyCounts } from "./trophy-counts.model"; + +export interface TrophyGroup { + /** + * ID of the trophy group. + * + * A game's standard set of trophies will have a value of `"default"`, + * whereas additional groups (such as those added from DLC) will + * increment in values such as `"001"` and `"002"`. + * @example "default" + * @example "001" + */ + trophyGroupId: string; + + /** + * Name of the trophy group. + * @example "ASTRO's PLAYROOM" + */ + trophyGroupName: string; + + /** URL of the icon for the trophy group. */ + trophyGroupIconUrl: string; + + /** Number of trophies for the trophy group by grade. */ + definedTrophies: TrophyCounts; + + /** Description of the trophy group. This is a legacy property, only applying to PS3, PS4, and PS Vita titles. */ + trophyGroupDetail?: string; +} diff --git a/node_modules/psn-api/src/models/trophy-rarity.model.ts b/node_modules/psn-api/src/models/trophy-rarity.model.ts new file mode 100644 index 0000000..5c511b5 --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-rarity.model.ts @@ -0,0 +1,6 @@ +export enum TrophyRarity { + UltraRare, + VeryRare, + Rare, + Common +} diff --git a/node_modules/psn-api/src/models/trophy-title.model.ts b/node_modules/psn-api/src/models/trophy-title.model.ts new file mode 100644 index 0000000..1f376f2 --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-title.model.ts @@ -0,0 +1,71 @@ +import type { TitlePlatform } from "./title-platform.model"; +import type { TrophyCounts } from "./trophy-counts.model"; + +export interface TrophyTitle { + /** + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + + /** + * Unique ID of the title. This is later required for requesting detailed + * trophy information for this title. + */ + npCommunicationId: string; + + /** The current version of the trophy set. Some trophy sets receive updates. */ + trophySetVersion: string; + + /** The game name. */ + trophyTitleName: string; + + /** URL of the icon for the given title. */ + trophyTitleIconUrl: string; + + /** + * The platform this title belongs to. Some games have trophy sets which are + * shared between multiple platforms (ie. PS4,PSVITA). The platforms will be + * comma-separated. + */ + trophyTitlePlatform: TitlePlatform | string; + + /** + * `true` if the title has multiple groups of trophies beyond the `"default"` group. + */ + hasTrophyGroups: boolean; + + /** Number of trophies for the title by type. */ + definedTrophies: TrophyCounts; + + /** + * Percentage of trophies earned for the title by the user. + * @example 100 + * @example 25 + */ + progress: number; + + /** Number of trophies for the title which have been earned by grade. */ + earnedTrophies: TrophyCounts; + + /** + * `true` if the title has been hidden on the account's trophy list. + * This applies to the authenticating account only. + * The title will not be returned if it has been hidden on another account. + */ + hiddenFlag: boolean; + + /** + * An ISO 8601 string representing the date the most + * recent trophy was earned for the title. + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; + + /** + * The title description. + * This is a legacy property that applies to + * PS3, PS4, and PS Vita titles only. + */ + trophyTitleDetail?: string; +} diff --git a/node_modules/psn-api/src/models/trophy-type.model.ts b/node_modules/psn-api/src/models/trophy-type.model.ts new file mode 100644 index 0000000..67b2e59 --- /dev/null +++ b/node_modules/psn-api/src/models/trophy-type.model.ts @@ -0,0 +1 @@ +export type TrophyType = "bronze" | "silver" | "gold" | "platinum"; diff --git a/node_modules/psn-api/src/models/trophy.model.ts b/node_modules/psn-api/src/models/trophy.model.ts new file mode 100644 index 0000000..e30caaf --- /dev/null +++ b/node_modules/psn-api/src/models/trophy.model.ts @@ -0,0 +1,68 @@ +import type { TrophyRarity } from "./trophy-rarity.model"; +import type { TrophyType } from "./trophy-type.model"; + +export interface Trophy { + /** Unique ID for this trophy (unique within the title and not just the group). */ + trophyId: number; + + /** `true` if this is a secret trophy (ie. further details are not displayed by default unless earned). */ + trophyHidden: boolean; + + /** Whether the trophy is bronze, silver, gold, or platinum. */ + trophyType: TrophyType; + + /** `true` if this trophy has been earned. */ + earned?: boolean; + + /** + * An ISO 8601 string representing the date the + * trophy was earned. Only truthy if `earned` is `true`. + * @example `"2021-08-15T21:22:08Z"` + */ + earnedDateTime?: string; + + /** Description of the trophy. */ + trophyDetail?: string; + + /** Percentage of all users who have earned the trophy. */ + trophyEarnedRate?: string; + + /** + * ID of the trophy group this trophy belongs to. + * + * A game's standard set of trophies will have a value of `"default"`, + * whereas DLC increments in values such as `"001"` and `"002"`. + */ + trophyGroupId?: string; + + /** URL for the graphic associated with the trophy. */ + trophyIconUrl?: string; + + /** Name of the trophy. */ + trophyName?: string; + + /** + * If the trophy tracks progress towards unlock, this is the total required to achieve the unlock. + * This is included on PS5 titles only, and only if the trophy itself tracks progress. + */ + trophyProgressTargetValue?: string; + + /** Rarity of the trophy. */ + trophyRare?: TrophyRarity; + + /** + * URL for the graphic associated with the reward. + * + * This is included on PS5 titles only, and is only returned if the + * trophy has a reward associated with it. + */ + trophyRewardImageUrl?: string; + + /** + * Name of the reward that earning the trophy grants. + * + * This is included on PS5 titles only, and only if the trophy itself has + * a reward associated with it. + */ + trophyRewardName?: string; +} diff --git a/node_modules/psn-api/src/models/universal-search-domain-response.model.ts b/node_modules/psn-api/src/models/universal-search-domain-response.model.ts new file mode 100644 index 0000000..5b2b3ec --- /dev/null +++ b/node_modules/psn-api/src/models/universal-search-domain-response.model.ts @@ -0,0 +1,11 @@ +export interface UniversalSearchDomainResponse { + domain: string; + domainTitle: string; + domainTitleMessageId: string; + zeroState: boolean; + univexId: string; + facetOptions: unknown[]; + next: string; + totalResultCount: number; + results: T[]; +} diff --git a/node_modules/psn-api/src/models/universal-search-domains.model.ts b/node_modules/psn-api/src/models/universal-search-domains.model.ts new file mode 100644 index 0000000..c0499bf --- /dev/null +++ b/node_modules/psn-api/src/models/universal-search-domains.model.ts @@ -0,0 +1 @@ +export type UniversalSearchDomains = "SocialAllAccounts"; diff --git a/node_modules/psn-api/src/models/universal-search-response.model.ts b/node_modules/psn-api/src/models/universal-search-response.model.ts new file mode 100644 index 0000000..dc0fe74 --- /dev/null +++ b/node_modules/psn-api/src/models/universal-search-response.model.ts @@ -0,0 +1,8 @@ +import type { UniversalSearchDomainResponse } from "./universal-search-domain-response.model"; + +export interface UniversalSearchResponse { + prefix: string; + suggestions: string[]; + fallbackQueried: boolean; + domainResponses: UniversalSearchDomainResponse[]; +} diff --git a/node_modules/psn-api/src/models/user-thin-trophy.model.ts b/node_modules/psn-api/src/models/user-thin-trophy.model.ts new file mode 100644 index 0000000..9e93ff9 --- /dev/null +++ b/node_modules/psn-api/src/models/user-thin-trophy.model.ts @@ -0,0 +1,15 @@ +import type { Trophy } from "./trophy.model"; + +export type UserThinTrophy = Pick< + Trophy, + | "trophyId" + | "trophyHidden" + | "earned" + | "earnedDateTime" + | "trophyType" + | "trophyRare" + | "trophyEarnedRate" + | "trophyProgressTargetValue" + | "trophyRewardImageUrl" + | "trophyRewardName" +>; diff --git a/node_modules/psn-api/src/models/user-titles-response.model.ts b/node_modules/psn-api/src/models/user-titles-response.model.ts new file mode 100644 index 0000000..3e60eb1 --- /dev/null +++ b/node_modules/psn-api/src/models/user-titles-response.model.ts @@ -0,0 +1,11 @@ +import type { TrophyTitle } from "./trophy-title.model"; + +export interface UserTitlesResponse { + /** The list of games played by the user. */ + trophyTitles: TrophyTitle[]; + + /** The number of `TrophyTitle` entities returned from the PSN API. */ + totalItemCount: number; + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/src/models/user-trophies-earned-for-title-response.model.ts b/node_modules/psn-api/src/models/user-trophies-earned-for-title-response.model.ts new file mode 100644 index 0000000..0af1066 --- /dev/null +++ b/node_modules/psn-api/src/models/user-trophies-earned-for-title-response.model.ts @@ -0,0 +1,33 @@ +import type { RarestThinTrophy } from "./rarest-thin-trophy.model"; +import type { UserThinTrophy } from "./user-thin-trophy.model"; + +export interface UserTrophiesEarnedForTitleResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + + /** `true` if this title has additional trophy groups beyond the required `"default"` group. */ + hasTrophyGroups: boolean; + + /** + * An ISO 8601 string representing the date of the + * user's most recent trophy earned for the title. + * @example - `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; + + /** Individual object for each trophy. */ + trophies: UserThinTrophy[]; + + /** Total trophies in the group (or total trophies for the title if `"all"` is specified). */ + totalItemCount: number; + + /** + * An array which contains the trophy where `earned` is `true` with the lowest `trophyEarnedRate`. + * If multiple trophies have the same `trophyEarnedRate`, the array contains those trophies instead of just a single trophy. + * It contains nothing if no trophies are earned. + */ + rarestTrophies?: RarestThinTrophy[]; + + nextOffset?: number; + previousOffset?: number; +} diff --git a/node_modules/psn-api/src/models/user-trophy-group-earnings-for-title-response.model.ts b/node_modules/psn-api/src/models/user-trophy-group-earnings-for-title-response.model.ts new file mode 100644 index 0000000..3051c04 --- /dev/null +++ b/node_modules/psn-api/src/models/user-trophy-group-earnings-for-title-response.model.ts @@ -0,0 +1,31 @@ +import type { TrophyCounts } from "./trophy-counts.model"; +import type { TrophyGroupEarnings } from "./trophy-group-earnings.model"; + +export interface UserTrophyGroupEarningsForTitleResponse { + /** The current version of the trophy set. Some trophy sets receive updates from the developer. */ + trophySetVersion: string; + + /** + * `true` if the title has been hidden on the account's trophy list. + * This applies to the authenticating account only. + * The title will not be returned if it has been hidden on another account. + */ + hiddenFlag: boolean; + + /** The account's percentage of trophies earned for the title. */ + progress: number; + + /** The account's number of earned trophies for the title by grade. */ + earnedTrophies: TrophyCounts; + + /** Individual object for each trophy group returned. */ + trophyGroups: TrophyGroupEarnings[]; + + /** + * An ISO 8601 string representing the date the + * title progress was updated (such as when a + * trophy was earned for a group). + * @example `"2021-08-15T21:22:08Z"` + */ + lastUpdatedDateTime: string; +} diff --git a/node_modules/psn-api/src/models/user-trophy-profile-summary-response.model.ts b/node_modules/psn-api/src/models/user-trophy-profile-summary-response.model.ts new file mode 100644 index 0000000..37a94ea --- /dev/null +++ b/node_modules/psn-api/src/models/user-trophy-profile-summary-response.model.ts @@ -0,0 +1,33 @@ +import type { TrophyCounts } from "./trophy-counts.model"; + +export interface UserTrophyProfileSummaryResponse { + /** The ID of the account being accessed. */ + accountId: string; + + /** The account's overall trophy level. */ + trophyLevel: string; + + /** The account's percentage progress towards the next trophy level. */ + progress: number; + + /** + * The tier this trophy level is in. + * + * | Tier | Grade | trophyLevel Ranges | + * | --- | --- | ---: | + * | 1 | Bronze | 1 - 99 | + * | 2 | Bronze | 100 - 199 | + * | 3 | Bronze | 200 - 299 | + * | 4 | Silver | 300 - 399 | + * | 5 | Silver | 400 - 499 | + * | 6 | Silver | 500 - 599 | + * | 7 | Gold | 600 - 699 | + * | 8 | Gold | 700 - 799 | + * | 9 | Gold | 800 - 998 | + * | 10 | Platinum | 999 | + */ + tier: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + + /** The account's number of earned trophies by grade. */ + earnedTrophies: TrophyCounts; +} diff --git a/node_modules/psn-api/src/search/SEARCH_BASE_URL.ts b/node_modules/psn-api/src/search/SEARCH_BASE_URL.ts new file mode 100644 index 0000000..88ddc73 --- /dev/null +++ b/node_modules/psn-api/src/search/SEARCH_BASE_URL.ts @@ -0,0 +1 @@ +export const SEARCH_BASE_URL = "https://m.np.playstation.com/api/search"; diff --git a/node_modules/psn-api/src/search/index.ts b/node_modules/psn-api/src/search/index.ts new file mode 100644 index 0000000..a110826 --- /dev/null +++ b/node_modules/psn-api/src/search/index.ts @@ -0,0 +1 @@ +export * from "./makeUniversalSearch"; diff --git a/node_modules/psn-api/src/search/makeUniversalSearch.test.ts b/node_modules/psn-api/src/search/makeUniversalSearch.test.ts new file mode 100644 index 0000000..61e553e --- /dev/null +++ b/node_modules/psn-api/src/search/makeUniversalSearch.test.ts @@ -0,0 +1,54 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + SocialAccountResult, + UniversalSearchResponse +} from "../models"; +import { makeUniversalSearch } from "./makeUniversalSearch"; +import { SEARCH_BASE_URL } from "./SEARCH_BASE_URL"; + +const server = setupServer(); + +describe("Function: makeUniversalSearch", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(makeUniversalSearch).toBeDefined(); + }); + + it("can make a call to Sony's universal search endpoint", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: UniversalSearchResponse = { + prefix: "mockPrefix", + suggestions: [], + fallbackQueried: false, + domainResponses: [] + }; + + server.use( + rest.post(`${SEARCH_BASE_URL}/v1/universalSearch`, (_, res, ctx) => { + return res(ctx.json(mockResponse)); + }) + ); + + // ACT + const response = await makeUniversalSearch( + mockAuthorization, + "xelnia", + "SocialAllAccounts" + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); +}); diff --git a/node_modules/psn-api/src/search/makeUniversalSearch.ts b/node_modules/psn-api/src/search/makeUniversalSearch.ts new file mode 100644 index 0000000..c1ad980 --- /dev/null +++ b/node_modules/psn-api/src/search/makeUniversalSearch.ts @@ -0,0 +1,34 @@ +import type { + AuthorizationPayload, + SocialAccountResult, + UniversalSearchDomains, + UniversalSearchResponse +} from "../models"; +import { buildRequestUrl } from "../utils/buildRequestUrl"; +import { call } from "../utils/call"; +import { SEARCH_BASE_URL } from "./SEARCH_BASE_URL"; + +export const makeUniversalSearch = async ( + authorization: AuthorizationPayload, + searchTerm: string, + domain: R +) => { + const url = buildRequestUrl(SEARCH_BASE_URL, "/v1/universalSearch"); + + type AssertType = R extends "SocialAllAccounts" + ? SocialAccountResult + : unknown; + + return await call>>( + { url, method: "POST" }, + authorization, + { + searchTerm, + domainRequests: [ + { + domain + } + ] + } + ); +}; diff --git a/node_modules/psn-api/src/test/.keep b/node_modules/psn-api/src/test/.keep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/psn-api/src/test/generators/index.ts b/node_modules/psn-api/src/test/generators/index.ts new file mode 100644 index 0000000..31c424e --- /dev/null +++ b/node_modules/psn-api/src/test/generators/index.ts @@ -0,0 +1,3 @@ +export * from "./title-platform.generator"; +export * from "./trophy-counts.generator"; +export * from "./trophy-title.generator"; diff --git a/node_modules/psn-api/src/test/generators/title-platform.generator.ts b/node_modules/psn-api/src/test/generators/title-platform.generator.ts new file mode 100644 index 0000000..e110059 --- /dev/null +++ b/node_modules/psn-api/src/test/generators/title-platform.generator.ts @@ -0,0 +1,10 @@ +import { faker } from "@faker-js/faker"; + +import type { TitlePlatform } from "../../models"; + +export const generateTitlePlatform = (givenTitlePlatform?: string) => { + return ( + givenTitlePlatform ?? + faker.helpers.arrayElement(["PS3", "PS4", "PS5", "Vita"]) + ); +}; diff --git a/node_modules/psn-api/src/test/generators/trophy-counts.generator.ts b/node_modules/psn-api/src/test/generators/trophy-counts.generator.ts new file mode 100644 index 0000000..b4c72ec --- /dev/null +++ b/node_modules/psn-api/src/test/generators/trophy-counts.generator.ts @@ -0,0 +1,15 @@ +import { faker } from "@faker-js/faker"; + +import type { TrophyCounts } from "../../models"; + +export const generateTrophyCounts = ( + trophyCountsProps?: Partial +): TrophyCounts => { + return { + bronze: faker.datatype.number({ min: 0, max: 1000 }), + silver: faker.datatype.number({ min: 0, max: 1000 }), + gold: faker.datatype.number({ min: 0, max: 1000 }), + platinum: faker.datatype.number({ min: 0, max: 1 }) as 0 | 1, + ...trophyCountsProps + }; +}; diff --git a/node_modules/psn-api/src/test/generators/trophy-title.generator.ts b/node_modules/psn-api/src/test/generators/trophy-title.generator.ts new file mode 100644 index 0000000..8fb0026 --- /dev/null +++ b/node_modules/psn-api/src/test/generators/trophy-title.generator.ts @@ -0,0 +1,33 @@ +import { faker } from "@faker-js/faker"; + +import type { TrophyTitle } from "../../models"; +import { generateTitlePlatform } from "./title-platform.generator"; +import { generateTrophyCounts } from "./trophy-counts.generator"; + +export const generateTrophyTitle = ( + trophyTitleProps?: Partial +): TrophyTitle => { + const trophyTitlePlatform = + trophyTitleProps?.trophyTitlePlatform ?? generateTitlePlatform(); + + const npServiceName = + trophyTitleProps?.npServiceName ?? trophyTitlePlatform === "PS5" + ? "trophy2" + : "trophy"; + + return { + npServiceName, + trophyTitlePlatform, + npCommunicationId: faker.random.alphaNumeric(10), + trophySetVersion: "1.00", + trophyTitleName: faker.random.words(3), + trophyTitleIconUrl: faker.internet.url(), + hasTrophyGroups: faker.datatype.boolean(), + definedTrophies: generateTrophyCounts(), + progress: faker.datatype.number({ min: 0, max: 100 }), + earnedTrophies: generateTrophyCounts(), + hiddenFlag: faker.datatype.boolean(), + lastUpdatedDateTime: faker.date.recent().toISOString(), + ...trophyTitleProps + }; +}; diff --git a/node_modules/psn-api/src/trophy/TROPHY_BASE_URL.ts b/node_modules/psn-api/src/trophy/TROPHY_BASE_URL.ts new file mode 100644 index 0000000..ceab205 --- /dev/null +++ b/node_modules/psn-api/src/trophy/TROPHY_BASE_URL.ts @@ -0,0 +1 @@ +export const TROPHY_BASE_URL = "https://m.np.playstation.com/api/trophy"; diff --git a/node_modules/psn-api/src/trophy/index.ts b/node_modules/psn-api/src/trophy/index.ts new file mode 100644 index 0000000..62cc8f5 --- /dev/null +++ b/node_modules/psn-api/src/trophy/index.ts @@ -0,0 +1,2 @@ +export * from "./title"; +export * from "./user"; diff --git a/node_modules/psn-api/src/trophy/title/getTitleTrophies.test.ts b/node_modules/psn-api/src/trophy/title/getTitleTrophies.test.ts new file mode 100644 index 0000000..d981e96 --- /dev/null +++ b/node_modules/psn-api/src/trophy/title/getTitleTrophies.test.ts @@ -0,0 +1,56 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { AuthorizationPayload, TitleTrophiesResponse } from "../../models"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getTitleTrophies } from "./getTitleTrophies"; + +const server = setupServer(); + +describe("Function: getTitleTrophies", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getTitleTrophies).toBeDefined(); + }); + + it("retrieves trophies for a given title", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockNpCommunicationId = "mockNpCommunicationId"; + const mockTrophyGroupId = "mockTrophyGroupId"; + + const mockResponse: TitleTrophiesResponse = { + trophySetVersion: "1.00", + hasTrophyGroups: false, + trophies: [], + totalItemCount: 0 + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/npCommunicationIds/${mockNpCommunicationId}/trophyGroups/${mockTrophyGroupId}/trophies`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getTitleTrophies( + mockAuthorization, + mockNpCommunicationId, + mockTrophyGroupId + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); +}); diff --git a/node_modules/psn-api/src/trophy/title/getTitleTrophies.ts b/node_modules/psn-api/src/trophy/title/getTitleTrophies.ts new file mode 100644 index 0000000..787436e --- /dev/null +++ b/node_modules/psn-api/src/trophy/title/getTitleTrophies.ts @@ -0,0 +1,51 @@ +import type { + AllCallOptions, + AuthorizationPayload, + TitleTrophiesResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +type GetTitleTrophiesOptions = Pick< + AllCallOptions, + "headerOverrides" | "limit" | "npServiceName" | "offset" +>; + +/** + * A call to this function will retrieve the trophy list of a + * single - or all - trophy groups for a title. A title can have multiple + * groups of trophies (a `"default"` group which all titles have, and additional + * groups starting with the name `"001"` and incrementing for each additional group). To retrieve + * trophies from all groups within a title (ie. the full trophy set), then + * `trophyGroupId` should be set to `"all"`. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` parameter as `"trophy"`. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getTitleTrophies = async ( + authorization: AuthorizationPayload, + npCommunicationId: string, + trophyGroupId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", + options, + { npCommunicationId, trophyGroupId } + ); + + return await call( + { url, headers: options?.headerOverrides }, + authorization + ); +}; diff --git a/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.test.ts b/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.test.ts new file mode 100644 index 0000000..f3263b1 --- /dev/null +++ b/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.test.ts @@ -0,0 +1,60 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + TitleTrophyGroupsResponse +} from "../../models"; +import { generateTrophyCounts } from "../../test/generators"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getTitleTrophyGroups } from "./getTitleTrophyGroups"; + +const server = setupServer(); + +describe("Function: getTitleTrophyGroups", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getTitleTrophyGroups).toBeDefined(); + }); + + it("retrieves trophy groups metadata for a given title", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockNpCommunicationId = "mockNpCommunicationId"; + + const mockResponse: TitleTrophyGroupsResponse = { + trophySetVersion: "1.00", + trophyTitleName: "mockTrophyTitleName", + trophyTitleIconUrl: "mockTrophyTitleIconUrl", + trophyTitlePlatform: "PS3", + definedTrophies: generateTrophyCounts(), + trophyGroups: [] + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/npCommunicationIds/${mockNpCommunicationId}/trophyGroups`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getTitleTrophyGroups( + mockAuthorization, + mockNpCommunicationId + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); +}); diff --git a/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.ts b/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.ts new file mode 100644 index 0000000..35ddbcd --- /dev/null +++ b/node_modules/psn-api/src/trophy/title/getTitleTrophyGroups.ts @@ -0,0 +1,46 @@ +import type { + AllCallOptions, + AuthorizationPayload, + TitleTrophyGroupsResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +type GetTitleTrophyGroupsOptions = Pick< + AllCallOptions, + "npServiceName" | "headerOverrides" +>; + +/** + * A title may have multiple groups of trophies. This is most commonly + * seen in games which have DLC expansions where additional trophies are added. + * + * You can call this function for a specific title - using the + * unique `npCommunicationId` for the title - and you will receive a + * summary of all of the trophy groups associated with the title. + * This also includes a summary of the number of trophies for the + * title, broken down by group and grade (gold, silver, etc.). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param npCommunicationId The unique ID of the game title you wish to retrieve the trophy groups list for. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getTitleTrophyGroups = async ( + authorization: AuthorizationPayload, + npCommunicationId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/npCommunicationIds/:npCommunicationId/trophyGroups", + options, + { npCommunicationId } + ); + + return await call( + { url, headers: options?.headerOverrides }, + authorization + ); +}; diff --git a/node_modules/psn-api/src/trophy/title/index.ts b/node_modules/psn-api/src/trophy/title/index.ts new file mode 100644 index 0000000..216a5c1 --- /dev/null +++ b/node_modules/psn-api/src/trophy/title/index.ts @@ -0,0 +1,2 @@ +export * from "./getTitleTrophies"; +export * from "./getTitleTrophyGroups"; diff --git a/node_modules/psn-api/src/trophy/user/getUserTitles.test.ts b/node_modules/psn-api/src/trophy/user/getUserTitles.test.ts new file mode 100644 index 0000000..47ad97f --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTitles.test.ts @@ -0,0 +1,50 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { AuthorizationPayload, UserTitlesResponse } from "../../models"; +import { generateTrophyTitle } from "../../test/generators"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getUserTitles } from "./getUserTitles"; + +const server = setupServer(); + +describe("Function: getUserTitles", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getUserTitles).toBeDefined(); + }); + + it("makes a call to get the list of trophy titles for a given user", async () => { + // ARRANGE + const mockAccountId = "mockAccountId"; + + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: UserTitlesResponse = { + trophyTitles: [generateTrophyTitle()], + totalItemCount: 1 + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/trophyTitles`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getUserTitles(mockAuthorization, mockAccountId); + + // ASSERT + expect(response).toEqual(mockResponse); + }); +}); diff --git a/node_modules/psn-api/src/trophy/user/getUserTitles.ts b/node_modules/psn-api/src/trophy/user/getUserTitles.ts new file mode 100644 index 0000000..95b7ad8 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTitles.ts @@ -0,0 +1,63 @@ +import type { + AllCallOptions, + AuthorizationPayload, + UserTitlesResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +type GetUserTitlesOptions = Pick< + AllCallOptions, + "headerOverrides" | "limit" | "offset" +>; + +/** + * A call to this function will retrieve a summarized list of titles played + * by a user, ordered by recent trophy unlocks. The maximum amount that can + * be returned by a single call is 800 (assuming a `limit` option of 800 is set). + * If the user has more titles than the given `limit` option, subsequent calls + * of this funciton must be made to fetch the complete list by paging via the + * `offset` option. + * + * The numeric `accountId` can be that of any PSN account for which the authenticating + * account has permissions to view the trophy list. When querying the titles + * associated with the authenticating account, the numeric `accountId` can be + * substituted with `"me"`. + * + * To fetch more detailed account progress for a title, the `getUserTrophiesEarnedForTitle()` + * function can be used. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * Included in the information returned is the titles' unique `npCommunicationId`. + * This is required to make use of subsequent functions for requesting more specific + * detail about a title's trophies. + * + * The results are presented in order of the `lastUpdatedDateTime` for the title, + * so the first result will be the title for which a trophy was most recently earned + * (or synced for the first time in the case of a game with 0% progress). + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.limit Limit the number of titles returned. + * @param options.offset Return title data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getUserTitles = async ( + authorization: AuthorizationPayload, + accountId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/users/:accountId/trophyTitles", + options, + { accountId } + ); + + return await call( + { url, headers: options?.headerOverrides }, + authorization + ); +}; diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.test.ts b/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.test.ts new file mode 100644 index 0000000..d376bf0 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.test.ts @@ -0,0 +1,100 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + UserTrophiesEarnedForTitleResponse +} from "../../models"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getUserTrophiesEarnedForTitle } from "./getUserTrophiesEarnedForTitle"; + +const server = setupServer(); + +describe("Function: getUserTrophiesEarnedForTitle", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getUserTrophiesEarnedForTitle).toBeDefined(); + }); + + it("retrieves trophies earned by a given user for a given title", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockAccountId = "mockAccountId"; + const mockNpCommunicationId = "mockNpCommunicationId"; + const mockTrophyGroupId = "mockTrophyGroupId"; + + const mockResponse: UserTrophiesEarnedForTitleResponse = { + trophySetVersion: "1.00", + hasTrophyGroups: false, + lastUpdatedDateTime: "mockLastUpdatedDateTime", + trophies: [], + totalItemCount: 0 + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/npCommunicationIds/${mockNpCommunicationId}/trophyGroups/${mockTrophyGroupId}/trophies`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getUserTrophiesEarnedForTitle( + mockAuthorization, + mockAccountId, + mockNpCommunicationId, + mockTrophyGroupId + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); + + it("throws an error if we receive a response containing an `error` object", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockAccountId = "mockAccountId"; + const mockNpCommunicationId = "mockNpCommunicationId"; + const mockTrophyGroupId = "mockTrophyGroupId"; + + const mockResponse = { + error: { + referenceId: "mockReferenceId", + code: "mockCode", + message: "Resource not found" + } + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/npCommunicationIds/${mockNpCommunicationId}/trophyGroups/${mockTrophyGroupId}/trophies`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ASSERT + await expect( + getUserTrophiesEarnedForTitle( + mockAuthorization, + mockAccountId, + mockNpCommunicationId, + mockTrophyGroupId + ) + ).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.ts b/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.ts new file mode 100644 index 0000000..43663c8 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophiesEarnedForTitle.ts @@ -0,0 +1,74 @@ +import type { + AllCallOptions, + AuthorizationPayload, + UserTrophiesEarnedForTitleResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +type GetUserTrophiesEarnedForTitleOptions = Pick< + AllCallOptions, + "offset" | "npServiceName" | "limit" | "headerOverrides" +>; + +/** + * A call to this function will retrieve the earned status of trophies for a user + * from either a single - or all - trophy groups in a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, and + * additional groups starting with a name of `"001"` and incrementing for each + * additional group). To retrieve trophies from all groups within a title + * (ie. the full trophy set), then `trophyGroupId` should be set to `"all"`. + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4, or PS Vita, you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param trophyGroupId `"all"` to return all trophies for the title, otherwise restrict results to a specific trophy group (such as a DLC). + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.limit Limit the number of trophies returned. + * @param options.offset Return trophy data from this result onwards. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getUserTrophiesEarnedForTitle = async ( + authorization: AuthorizationPayload, + accountId: string, + npCommunicationId: string, + trophyGroupId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups/:trophyGroupId/trophies", + options, + { accountId, npCommunicationId, trophyGroupId } + ); + + const response = await call( + { url, headers: options?.headerOverrides }, + authorization + ); + + if ((response as any)?.error) { + throw new Error((response as any)?.error?.message ?? "Unexpected Error"); + } + + return response; +}; diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.test.ts b/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.test.ts new file mode 100644 index 0000000..0bccb96 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.test.ts @@ -0,0 +1,98 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + UserTrophyGroupEarningsForTitleResponse +} from "../../models"; +import { generateTrophyCounts } from "../../test/generators"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getUserTrophyGroupEarningsForTitle } from "./getUserTrophyGroupEarningsForTitle"; + +const server = setupServer(); + +describe("Function: getUserTrophyGroupEarningsForTitle", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getUserTrophyGroupEarningsForTitle).toBeDefined(); + }); + + it("retrieves a summarized count of trophy earnings for a given user", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockAccountId = "mockAccountId"; + const mockNpCommunicationId = "mockNpCommunicationId"; + + const mockResponse: UserTrophyGroupEarningsForTitleResponse = { + trophySetVersion: "1.00", + hiddenFlag: false, + progress: 80, + earnedTrophies: generateTrophyCounts(), + trophyGroups: [], + lastUpdatedDateTime: "mockLastUpdatedDateTime" + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/npCommunicationIds/${mockNpCommunicationId}/trophyGroups`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getUserTrophyGroupEarningsForTitle( + mockAuthorization, + mockAccountId, + mockNpCommunicationId + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); + + it("throws an error if we receive a response containing an `error` object", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockAccountId = "mockAccountId"; + const mockNpCommunicationId = "mockNpCommunicationId"; + + const mockResponse = { + error: { + referenceId: "mockReferenceId", + code: "mockCode", + message: "Resource not found" + } + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/npCommunicationIds/${mockNpCommunicationId}/trophyGroups`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ASSERT + await expect( + getUserTrophyGroupEarningsForTitle( + mockAuthorization, + mockAccountId, + mockNpCommunicationId + ) + ).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.ts b/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.ts new file mode 100644 index 0000000..b9d4297 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophyGroupEarningsForTitle.ts @@ -0,0 +1,81 @@ +import type { + AuthorizationPayload, + CallValidHeaders, + UserTrophyGroupEarningsForTitleResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +interface GetUserTrophyGroupEarningsForTitleOptions { + /** + * Not required unless the platform is PS3, PS4, or PS Vita. + * If one of these platforms, the value __must__ be `"trophy"`. + * + * `"trophy"` for PS3, PS4, or PS Vita platforms. + * `"trophy2"` for the PS5 platform. + */ + npServiceName: "trophy" | "trophy2"; + + /* + * Override the headers in the request to the PSN API, + * such as to change the language. + */ + headerOverrides: CallValidHeaders; +} + +/** + * A request to this endpoint function will retrieve a summary of the trophies earned for + * a user broken down by trophy group within a title. A title can have + * multiple groups of trophies (a `"default"` group which all titles have, + * and additional groups beginning with the name `"001"` and incrementing for + * each additional group). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * This function calls an endpoint that returns the earned status of the + * trophy only and no additional descriptive metadata (ie. trophy name, + * trophy description). Use `getTitleTrophies()` to obtain this information. + * + * When the title platform is PS3, PS4 or PS Vita you __must__ specify the + * `npServiceName` option as `"trophy"`. + * + * If you attempt to query a title which the user does not have associated + * with their account (ie. the title has not been launched and allowed to + * sync at least once) then a Resource Not Found error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param npCommunicationId Unique ID of the title. + * @param options.npServiceName `"trophy"` for PS3, PS4, or PS Vita platforms. `"trophy2"` for the PS5 platform. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getUserTrophyGroupEarningsForTitle = async ( + authorization: AuthorizationPayload, + accountId: string, + npCommunicationId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/users/:accountId/npCommunicationIds/:npCommunicationId/trophyGroups", + options, + { accountId, npCommunicationId } + ); + + const response = await call( + { url, headers: options?.headerOverrides }, + authorization + ); + + if ((response as any)?.error) { + throw new Error((response as any)?.error?.message ?? "Unexpected Error"); + } + + return response; +}; diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.test.ts b/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.test.ts new file mode 100644 index 0000000..e7c7f7b --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.test.ts @@ -0,0 +1,59 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + UserTrophyProfileSummaryResponse +} from "../../models"; +import { generateTrophyCounts } from "../../test/generators"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; +import { getUserTrophyProfileSummary } from "./getUserTrophyProfileSummary"; + +const server = setupServer(); + +describe("Function: getUserTrophyProfileSummary", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getUserTrophyProfileSummary).toBeDefined(); + }); + + it("makes a call to retrieve a given user's trophy collection summary", async () => { + // ARRANGE + const mockAccountId = "mockAccountId"; + + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: UserTrophyProfileSummaryResponse = { + accountId: mockAccountId, + trophyLevel: "403", + progress: 80, + tier: 5, + earnedTrophies: generateTrophyCounts() + }; + + server.use( + rest.get( + `${TROPHY_BASE_URL}/v1/users/${mockAccountId}/trophySummary`, + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getUserTrophyProfileSummary( + mockAuthorization, + mockAccountId + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); +}); diff --git a/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.ts b/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.ts new file mode 100644 index 0000000..199936f --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/getUserTrophyProfileSummary.ts @@ -0,0 +1,48 @@ +import type { + AllCallOptions, + AuthorizationPayload, + UserTrophyProfileSummaryResponse +} from "../../models"; +import { buildRequestUrl } from "../../utils/buildRequestUrl"; +import { call } from "../../utils/call"; +import { TROPHY_BASE_URL } from "../TROPHY_BASE_URL"; + +type GetUserTrophyProfileSummaryOptions = Pick< + AllCallOptions, + "headerOverrides" +>; + +/** + * A call to this function will retrieve an overall summary of the number of + * trophies earned for a user broken down by grade, as well as their current + * overall trophy level, progress towards the next level, and which tier their + * current level falls in to. The tiers are based on the [level changes introduced in 2020](https://andshrew.github.io/PlayStation-Trophies/images/psn-trophy-tiers.png). + * + * The numeric `accountId` can be that of any PSN account for which the + * authenticating account has permissions to view the trophy list. + * When querying the titles associated with the authenticating account, the + * numeric `accountId` can be substituted with `"me"`. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + * @param options.headerOverrides Override the headers in the request to the PSN API, such as to change the language. + */ +export const getUserTrophyProfileSummary = async ( + authorization: AuthorizationPayload, + accountId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl( + TROPHY_BASE_URL, + "/v1/users/:accountId/trophySummary", + options, + { accountId } + ); + + return await call( + { url, headers: options?.headerOverrides }, + authorization + ); +}; diff --git a/node_modules/psn-api/src/trophy/user/index.ts b/node_modules/psn-api/src/trophy/user/index.ts new file mode 100644 index 0000000..ab8a7c0 --- /dev/null +++ b/node_modules/psn-api/src/trophy/user/index.ts @@ -0,0 +1,4 @@ +export * from "./getUserTitles"; +export * from "./getUserTrophiesEarnedForTitle"; +export * from "./getUserTrophyGroupEarningsForTitle"; +export * from "./getUserTrophyProfileSummary"; diff --git a/node_modules/psn-api/src/user/USER_BASE_URL.ts b/node_modules/psn-api/src/user/USER_BASE_URL.ts new file mode 100644 index 0000000..42f9a7d --- /dev/null +++ b/node_modules/psn-api/src/user/USER_BASE_URL.ts @@ -0,0 +1,2 @@ +export const USER_BASE_URL = + "https://m.np.playstation.com/api/userProfile/v1/internal/users"; diff --git a/node_modules/psn-api/src/user/getProfileFromAccountId.test.ts b/node_modules/psn-api/src/user/getProfileFromAccountId.test.ts new file mode 100644 index 0000000..de6ed11 --- /dev/null +++ b/node_modules/psn-api/src/user/getProfileFromAccountId.test.ts @@ -0,0 +1,85 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + ProfileFromAccountIdResponse +} from "../models"; +import { getProfileFromAccountId } from "./getProfileFromAccountId"; +import { USER_BASE_URL } from "./USER_BASE_URL"; + +const server = setupServer(); + +describe("Function: getProfileFromUserName", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getProfileFromAccountId).toBeDefined(); + }); + + it("retrieves the profile for a given username", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: ProfileFromAccountIdResponse = { + onlineId: "xelnia", + isPlus: true, + aboutMe: "", + languages: ["en"], + isOfficiallyVerified: false, + isMe: false, + avatars: [ + { + size: "s", + url: "asdf" + } + ] + }; + + server.use( + rest.get( + "https://m.np.playstation.com/api/userProfile/v1/internal/users/111222333444/profiles", + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getProfileFromAccountId( + mockAuthorization, + "111222333444" + ); + + // ASSERT + expect(response).toEqual(mockResponse); + }); + + it("throws an error if we receive a response containing an `error` object", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse = { + error: { code: 2_105_356, message: "User not found (user: 'xeln12ia')" } + }; + + server.use( + rest.get(`${USER_BASE_URL}/111222333444/profiles`, (_, res, ctx) => { + return res(ctx.json(mockResponse)); + }) + ); + + // ASSERT + await expect( + getProfileFromAccountId(mockAuthorization, "111222333444") + ).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/user/getProfileFromAccountId.ts b/node_modules/psn-api/src/user/getProfileFromAccountId.ts new file mode 100644 index 0000000..3bec4bd --- /dev/null +++ b/node_modules/psn-api/src/user/getProfileFromAccountId.ts @@ -0,0 +1,38 @@ +import type { + AllCallOptions, + AuthorizationPayload, + ProfileFromAccountIdResponse +} from "../models"; +import { buildRequestUrl } from "../utils/buildRequestUrl"; +import { call } from "../utils/call"; +import { USER_BASE_URL } from "./USER_BASE_URL"; + +type GetProfileFromAccountIdOptions = Pick; + +/** + * A call to this function will retrieve some profile information of the accountId being requested. + * If the account's profile cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The accountId for the user you wish to retrieve a profile for. + */ +export const getProfileFromAccountId = async ( + authorization: AuthorizationPayload, + accountId: string, + options?: GetProfileFromAccountIdOptions +): Promise => { + const url = buildRequestUrl(USER_BASE_URL, "/:accountId/profiles", options, { + accountId + }); + const response = await call( + { url }, + authorization + ); + + if ((response as any)?.error) { + throw new Error((response as any)?.error?.message ?? "Unexpected Error"); + } + + return response; +}; diff --git a/node_modules/psn-api/src/user/getProfileFromUserName.test.ts b/node_modules/psn-api/src/user/getProfileFromUserName.test.ts new file mode 100644 index 0000000..b7f56b5 --- /dev/null +++ b/node_modules/psn-api/src/user/getProfileFromUserName.test.ts @@ -0,0 +1,101 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + ProfileFromUserNameResponse +} from "../models"; +import { getProfileFromUserName } from "./getProfileFromUserName"; + +const server = setupServer(); + +describe("Function: getProfileFromUserName", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getProfileFromUserName).toBeDefined(); + }); + + it("retrieves the profile for a given username", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: ProfileFromUserNameResponse = { + profile: { + onlineId: "xelnia", + accountId: "asdf", + npId: "asdf", + avatarUrls: [], + plus: 1, + aboutMe: "", + languagesUsed: ["en"], + trophySummary: { + level: 421, + progress: 53, + earnedTrophies: { bronze: 1, silver: 2, gold: 3, platinum: 4 } + }, + isOfficiallyVerified: false, + personalDetail: { + firstName: "asdf", + lastName: "asdf", + profilePictureUrls: [] + }, + personalDetailSharing: "shared", + personalDetailSharingRequestMessageFlag: false, + primaryOnlineStatus: "offline", + presences: [], + friendRelation: "friend", + requestMessageFlag: false, + blocking: false, + following: true, + consoleAvailability: { availabilityStatus: "offline" } + } + }; + + server.use( + rest.get( + "https://us-prof.np.community.playstation.net/userProfile/v1/users/xelnia/profile2", + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ACT + const response = await getProfileFromUserName(mockAuthorization, "xelnia"); + + // ASSERT + expect(response).toEqual(mockResponse); + }); + + it("throws an error if we receive a response containing an `error` object", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse = { + error: { code: 2_105_356, message: "User not found (user: 'xeln12ia')" } + }; + + server.use( + rest.get( + "https://us-prof.np.community.playstation.net/userProfile/v1/users/xeln12ia/profile2", + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ASSERT + await expect( + getProfileFromUserName(mockAuthorization, "xeln12ia") + ).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/user/getProfileFromUserName.ts b/node_modules/psn-api/src/user/getProfileFromUserName.ts new file mode 100644 index 0000000..4b53edb --- /dev/null +++ b/node_modules/psn-api/src/user/getProfileFromUserName.ts @@ -0,0 +1,36 @@ +import type { + AuthorizationPayload, + ProfileFromUserNameResponse +} from "../models"; +import { call } from "../utils/call"; + +/** + * A call to this function will retrieve the profile of the username being requested. + * If the user cannot be found (either due to non-existence or privacy settings), + * an error will be thrown. + * + * This is a legacy API endpoint function. If you are just trying to get a user's + * account ID, [`makeUniversalSearch()`](https://psn-api.achievements.app/api-docs/universal-search#makeuniversalsearch) + * is recommended instead. This endpoint is here because it can return interesting + * presence information when the user is playing on a legacy console such as a PS3. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param userName The username for the user you wish to retrieve a profile for. + */ +export const getProfileFromUserName = async ( + authorization: AuthorizationPayload, + userName: string +): Promise => { + const url = `https://us-prof.np.community.playstation.net/userProfile/v1/users/${userName}/profile2?fields=npId,onlineId,accountId,avatarUrls,plus,aboutMe,languagesUsed,trophySummary(@default,level,progress,earnedTrophies),isOfficiallyVerified,personalDetail(@default,profilePictureUrls),personalDetailSharing,personalDetailSharingRequestMessageFlag,primaryOnlineStatus,presences(@default,@titleInfo,platform,lastOnlineDate,hasBroadcastData),requestMessageFlag,blocking,friendRelation,following,consoleAvailability`; + + const response = await call( + { url }, + authorization + ); + + if ((response as any)?.error) { + throw new Error((response as any)?.error?.message ?? "Unexpected Error"); + } + + return response; +}; diff --git a/node_modules/psn-api/src/user/getUserFriendsAccountIds.test.ts b/node_modules/psn-api/src/user/getUserFriendsAccountIds.test.ts new file mode 100644 index 0000000..2c3b13d --- /dev/null +++ b/node_modules/psn-api/src/user/getUserFriendsAccountIds.test.ts @@ -0,0 +1,76 @@ +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { + AuthorizationPayload, + GetUserFriendsAccountIdsResponse +} from "../models"; +import { getUserFriendsAccountIds } from "./getUserFriendsAccountIds"; +import { USER_BASE_URL } from "./USER_BASE_URL"; + +const server = setupServer(); + +describe("Function: getUserFriendsAccountIds", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(getUserFriendsAccountIds).toBeDefined(); + }); + + it("retrieves the friends list for a given account id", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse: GetUserFriendsAccountIdsResponse = { + friends: ["2984038888603282554", "8403439712302084350"], + totalItemCount: 2 + }; + + server.use( + rest.get(`${USER_BASE_URL}/me/friends`, (_, res, ctx) => { + return res(ctx.json(mockResponse)); + }) + ); + + // ACT + const response = await getUserFriendsAccountIds(mockAuthorization, "me"); + + // ASSERT + expect(response).toEqual(mockResponse); + }); + + it("throws an error if we receive a response containing an `error` object", async () => { + // ARRANGE + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockResponse = { + error: { + referenceId: "d71bd8ff-5f63-11ec-87da-d5dfd3bc6e67", + code: 2_281_604, + message: "Not Found" + } + }; + + server.use( + rest.get( + "https://m.np.playstation.com/api/userProfile/v1/internal/users/111222333444/friends", + (_, res, ctx) => { + return res(ctx.json(mockResponse)); + } + ) + ); + + // ASSERT + await expect( + getUserFriendsAccountIds(mockAuthorization, "111222333444") + ).rejects.toThrow(); + }); +}); diff --git a/node_modules/psn-api/src/user/getUserFriendsAccountIds.ts b/node_modules/psn-api/src/user/getUserFriendsAccountIds.ts new file mode 100644 index 0000000..379b099 --- /dev/null +++ b/node_modules/psn-api/src/user/getUserFriendsAccountIds.ts @@ -0,0 +1,43 @@ +import type { + AllCallOptions, + AuthorizationPayload, + GetUserFriendsAccountIdsResponse +} from "../models"; +import { buildRequestUrl } from "../utils/buildRequestUrl"; +import { call } from "../utils/call"; +import { USER_BASE_URL } from "./USER_BASE_URL"; + +type GetUserFriendsAccountIdsOptions = Pick; + +/** + * A call to this function will retrieve the list of friended `accountId` values + * associated with the given `accountId` parameter. If the user cannot be found + * (either due to non-existence or privacy settings), an error will be thrown. + * + * To find a user's `accountId`, the `makeUniversalSearch()` function can be used. + * + * @param authorization An object containing your access token, typically retrieved with `exchangeCodeForAccessToken()`. + * @param accountId The account whose trophy list is being accessed. Use `"me"` for the authenticating account. + */ +export const getUserFriendsAccountIds = async ( + authorization: AuthorizationPayload, + accountId: string, + options?: Partial +): Promise => { + const url = buildRequestUrl(USER_BASE_URL, "/:accountId/friends", options, { + accountId + }); + + const response = await call( + { url }, + authorization + ); + + // If you are unable to access the user's friends list, a + // "Not permitted by access control" error will be thrown. + if ((response as any)?.error) { + throw new Error((response as any)?.error?.message ?? "Unexpected Error"); + } + + return response; +}; diff --git a/node_modules/psn-api/src/user/index.ts b/node_modules/psn-api/src/user/index.ts new file mode 100644 index 0000000..606faa7 --- /dev/null +++ b/node_modules/psn-api/src/user/index.ts @@ -0,0 +1,3 @@ +export * from "./getProfileFromAccountId"; +export * from "./getProfileFromUserName"; +export * from "./getUserFriendsAccountIds"; diff --git a/node_modules/psn-api/src/utils/buildRequestUrl.test.ts b/node_modules/psn-api/src/utils/buildRequestUrl.test.ts new file mode 100644 index 0000000..a5c8086 --- /dev/null +++ b/node_modules/psn-api/src/utils/buildRequestUrl.test.ts @@ -0,0 +1,41 @@ +import { buildRequestUrl } from "./buildRequestUrl"; + +describe("Util: buildRequestUrl", () => { + it("is defined #sanity", () => { + // ASSERT + expect(buildRequestUrl).toBeDefined(); + }); + + it("returns a URL correctly", () => { + // ARRANGE + const baseUrl = "https://x.y.achievements.app/api/v1/"; + const endpointUrl = "/foo/bar/:baz"; + + const options = { + headerOverrides: { + "Accept-Language": "en-us" + }, + mockOption: "mockValue" + }; + + const args = { + baz: "myBazValue", + limit: 10, + offset: 2, + notDefined: undefined + }; + + // ACT + const requestUrl = buildRequestUrl( + baseUrl, + endpointUrl, + options, + args as any + ); + + // ASSERT + expect(requestUrl).toEqual( + "https://x.y.achievements.app/api/v1/foo/bar/myBazValue?limit=10&offset=2&mockOption=mockValue" + ); + }); +}); diff --git a/node_modules/psn-api/src/utils/buildRequestUrl.ts b/node_modules/psn-api/src/utils/buildRequestUrl.ts new file mode 100644 index 0000000..78b17e7 --- /dev/null +++ b/node_modules/psn-api/src/utils/buildRequestUrl.ts @@ -0,0 +1,31 @@ +import type { AllCallOptions } from "../models"; + +export const buildRequestUrl = ( + baseUrl: string, + endpointUrl: string, + options: Partial = {}, + args: Record = {} +) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This is an intentional pick. + const { headerOverrides, ...pickedOptions } = options; + + const concatenated = `${baseUrl}/${endpointUrl}`; + const withoutDoubleSlashes = concatenated.replace(/([^:]\/)\/+/g, "$1"); + + let withArgs = withoutDoubleSlashes; + const queryParamValues: Record = {}; + + for (const [argKey, argValue] of Object.entries({ + ...args, + ...pickedOptions + })) { + if (withArgs.includes(`:${argKey}`)) { + withArgs = withArgs.replace(`:${argKey}`, String(argValue)); + } else if (argValue !== undefined) { + queryParamValues[argKey] = String(argValue); + } + } + + const queryString = new URLSearchParams(queryParamValues).toString(); + return queryString.length > 0 ? `${withArgs}?${queryString}` : withArgs; +}; diff --git a/node_modules/psn-api/src/utils/call.test.ts b/node_modules/psn-api/src/utils/call.test.ts new file mode 100644 index 0000000..fd1dc18 --- /dev/null +++ b/node_modules/psn-api/src/utils/call.test.ts @@ -0,0 +1,119 @@ +/* eslint-disable sonarjs/no-duplicate-string */ + +import { rest } from "msw"; +import { setupServer } from "msw/node"; + +import type { AuthorizationPayload, CallValidHeaders } from "../models"; +import { call } from "./call"; + +const server = setupServer(); + +describe("Util: call", () => { + // MSW Setup + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it("is defined #sanity", () => { + // ASSERT + expect(call).toBeDefined(); + }); + + it("uses a GET request by default", async () => { + // ARRANGE + let receivedMethod = ""; + + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockRequestUrl = "https://abc.xyz/v1/endpoint"; + + server.use( + rest.get(mockRequestUrl, (req, res, ctx) => { + receivedMethod = req.method; + return res(ctx.json({ foo: "bar" })); + }) + ); + + // ACT + const response = await call({ url: mockRequestUrl }, mockAuthorization); + + // ASSERT + expect(response).toEqual({ foo: "bar" }); + expect(receivedMethod).toEqual("GET"); + }); + + it("can accept a custom method", async () => { + // ARRANGE + let receivedMethod = ""; + + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockRequestUrl = "https://abc.xyz/v1/endpoint"; + + server.use( + rest.post(mockRequestUrl, (req, res, ctx) => { + receivedMethod = req.method; + return res(ctx.json({ foo: "bar" })); + }) + ); + + // ACT + const response = await call( + { url: mockRequestUrl, method: "POST" }, + mockAuthorization + ); + + // ASSERT + expect(response).toEqual({ foo: "bar" }); + expect(receivedMethod).toEqual("POST"); + }); + + it("makes an authenticated fetch call with a given configuration", async () => { + // ARRANGE + let receivedMockHeader = false; + let receivedMockAuthorization = false; + + const mockAuthorization: AuthorizationPayload = { + accessToken: "mockAccessToken" + }; + + const mockHeaders: CallValidHeaders = { + "Accept-Language": "en-us" + }; + + const mockRequestUrl = "https://abc.xyz/v1/endpoint"; + + server.use( + rest.post(mockRequestUrl, (req, res, ctx) => { + receivedMockHeader = + req.headers.get("Accept-Language") === "en-us" ? true : false; + + receivedMockAuthorization = + req.headers.get("Authorization") === + `Bearer ${mockAuthorization.accessToken}` + ? true + : false; + + return res(ctx.json({ foo: "bar" })); + }) + ); + + // ACT + await call( + { + url: mockRequestUrl, + method: "POST", + headers: mockHeaders + }, + mockAuthorization + ); + + // ASSERT + expect(receivedMockHeader).toEqual(true); + expect(receivedMockAuthorization).toEqual(true); + }); +}); diff --git a/node_modules/psn-api/src/utils/call.ts b/node_modules/psn-api/src/utils/call.ts new file mode 100644 index 0000000..eb2f252 --- /dev/null +++ b/node_modules/psn-api/src/utils/call.ts @@ -0,0 +1,25 @@ +import fetch from "isomorphic-unfetch"; + +import type { AuthorizationPayload, CallValidHeaders } from "../models"; + +export const call = async ( + config: { + url: string; + method?: "GET" | "POST"; + headers?: CallValidHeaders; + }, + authorization: AuthorizationPayload, + bodyPayload?: Record +) => { + const response = await fetch(config.url, { + method: config?.method ?? "GET", + headers: { + Authorization: `Bearer ${authorization.accessToken}`, + "Content-Type": "application/json", + ...config?.headers + }, + body: JSON.stringify(bodyPayload) + }); + + return (await response.json()) as T; +}; diff --git a/node_modules/tr46/.npmignore b/node_modules/tr46/.npmignore new file mode 100644 index 0000000..96e9161 --- /dev/null +++ b/node_modules/tr46/.npmignore @@ -0,0 +1,4 @@ +scripts/ +test/ + +!lib/mapping_table.json diff --git a/node_modules/tr46/index.js b/node_modules/tr46/index.js new file mode 100644 index 0000000..9ce12ca --- /dev/null +++ b/node_modules/tr46/index.js @@ -0,0 +1,193 @@ +"use strict"; + +var punycode = require("punycode"); +var mappingTable = require("./lib/mappingTable.json"); + +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; + +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} + +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; + + while (start <= end) { + var mid = Math.floor((start + end) / 2); + + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } + + return null; +} + +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} + +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; + + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); + + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } + + processed += String.fromCodePoint(codePoint); + break; + } + } + + return { + string: processed, + error: hasError + }; +} + +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; + +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } + + var error = false; + + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } + + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } + + return { + label: label, + error: error + }; +} + +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); + + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } + } + + return { + string: labels.join("."), + error: result.error + }; +} + +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); + + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } + + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } + + if (result.error) return null; + return labels.join("."); +}; + +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); + + return { + domain: result.string, + error: result.error + }; +}; + +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; diff --git a/node_modules/tr46/lib/.gitkeep b/node_modules/tr46/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/tr46/lib/mappingTable.json b/node_modules/tr46/lib/mappingTable.json new file mode 100644 index 0000000..89cf19a --- /dev/null +++ b/node_modules/tr46/lib/mappingTable.json @@ -0,0 +1 @@ +[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"],[[47,47],"disallowed_STD3_valid"],[[48,57],"valid"],[[58,64],"disallowed_STD3_valid"],[[65,65],"mapped",[97]],[[66,66],"mapped",[98]],[[67,67],"mapped",[99]],[[68,68],"mapped",[100]],[[69,69],"mapped",[101]],[[70,70],"mapped",[102]],[[71,71],"mapped",[103]],[[72,72],"mapped",[104]],[[73,73],"mapped",[105]],[[74,74],"mapped",[106]],[[75,75],"mapped",[107]],[[76,76],"mapped",[108]],[[77,77],"mapped",[109]],[[78,78],"mapped",[110]],[[79,79],"mapped",[111]],[[80,80],"mapped",[112]],[[81,81],"mapped",[113]],[[82,82],"mapped",[114]],[[83,83],"mapped",[115]],[[84,84],"mapped",[116]],[[85,85],"mapped",[117]],[[86,86],"mapped",[118]],[[87,87],"mapped",[119]],[[88,88],"mapped",[120]],[[89,89],"mapped",[121]],[[90,90],"mapped",[122]],[[91,96],"disallowed_STD3_valid"],[[97,122],"valid"],[[123,127],"disallowed_STD3_valid"],[[128,159],"disallowed"],[[160,160],"disallowed_STD3_mapped",[32]],[[161,167],"valid",[],"NV8"],[[168,168],"disallowed_STD3_mapped",[32,776]],[[169,169],"valid",[],"NV8"],[[170,170],"mapped",[97]],[[171,172],"valid",[],"NV8"],[[173,173],"ignored"],[[174,174],"valid",[],"NV8"],[[175,175],"disallowed_STD3_mapped",[32,772]],[[176,177],"valid",[],"NV8"],[[178,178],"mapped",[50]],[[179,179],"mapped",[51]],[[180,180],"disallowed_STD3_mapped",[32,769]],[[181,181],"mapped",[956]],[[182,182],"valid",[],"NV8"],[[183,183],"valid"],[[184,184],"disallowed_STD3_mapped",[32,807]],[[185,185],"mapped",[49]],[[186,186],"mapped",[111]],[[187,187],"valid",[],"NV8"],[[188,188],"mapped",[49,8260,52]],[[189,189],"mapped",[49,8260,50]],[[190,190],"mapped",[51,8260,52]],[[191,191],"valid",[],"NV8"],[[192,192],"mapped",[224]],[[193,193],"mapped",[225]],[[194,194],"mapped",[226]],[[195,195],"mapped",[227]],[[196,196],"mapped",[228]],[[197,197],"mapped",[229]],[[198,198],"mapped",[230]],[[199,199],"mapped",[231]],[[200,200],"mapped",[232]],[[201,201],"mapped",[233]],[[202,202],"mapped",[234]],[[203,203],"mapped",[235]],[[204,204],"mapped",[236]],[[205,205],"mapped",[237]],[[206,206],"mapped",[238]],[[207,207],"mapped",[239]],[[208,208],"mapped",[240]],[[209,209],"mapped",[241]],[[210,210],"mapped",[242]],[[211,211],"mapped",[243]],[[212,212],"mapped",[244]],[[213,213],"mapped",[245]],[[214,214],"mapped",[246]],[[215,215],"valid",[],"NV8"],[[216,216],"mapped",[248]],[[217,217],"mapped",[249]],[[218,218],"mapped",[250]],[[219,219],"mapped",[251]],[[220,220],"mapped",[252]],[[221,221],"mapped",[253]],[[222,222],"mapped",[254]],[[223,223],"deviation",[115,115]],[[224,246],"valid"],[[247,247],"valid",[],"NV8"],[[248,255],"valid"],[[256,256],"mapped",[257]],[[257,257],"valid"],[[258,258],"mapped",[259]],[[259,259],"valid"],[[260,260],"mapped",[261]],[[261,261],"valid"],[[262,262],"mapped",[263]],[[263,263],"valid"],[[264,264],"mapped",[265]],[[265,265],"valid"],[[266,266],"mapped",[267]],[[267,267],"valid"],[[268,268],"mapped",[269]],[[269,269],"valid"],[[270,270],"mapped",[271]],[[271,271],"valid"],[[272,272],"mapped",[273]],[[273,273],"valid"],[[274,274],"mapped",[275]],[[275,275],"valid"],[[276,276],"mapped",[277]],[[277,277],"valid"],[[278,278],"mapped",[279]],[[279,279],"valid"],[[280,280],"mapped",[281]],[[281,281],"valid"],[[282,282],"mapped",[283]],[[283,283],"valid"],[[284,284],"mapped",[285]],[[285,285],"valid"],[[286,286],"mapped",[287]],[[287,287],"valid"],[[288,288],"mapped",[289]],[[289,289],"valid"],[[290,290],"mapped",[291]],[[291,291],"valid"],[[292,292],"mapped",[293]],[[293,293],"valid"],[[294,294],"mapped",[295]],[[295,295],"valid"],[[296,296],"mapped",[297]],[[297,297],"valid"],[[298,298],"mapped",[299]],[[299,299],"valid"],[[300,300],"mapped",[301]],[[301,301],"valid"],[[302,302],"mapped",[303]],[[303,303],"valid"],[[304,304],"mapped",[105,775]],[[305,305],"valid"],[[306,307],"mapped",[105,106]],[[308,308],"mapped",[309]],[[309,309],"valid"],[[310,310],"mapped",[311]],[[311,312],"valid"],[[313,313],"mapped",[314]],[[314,314],"valid"],[[315,315],"mapped",[316]],[[316,316],"valid"],[[317,317],"mapped",[318]],[[318,318],"valid"],[[319,320],"mapped",[108,183]],[[321,321],"mapped",[322]],[[322,322],"valid"],[[323,323],"mapped",[324]],[[324,324],"valid"],[[325,325],"mapped",[326]],[[326,326],"valid"],[[327,327],"mapped",[328]],[[328,328],"valid"],[[329,329],"mapped",[700,110]],[[330,330],"mapped",[331]],[[331,331],"valid"],[[332,332],"mapped",[333]],[[333,333],"valid"],[[334,334],"mapped",[335]],[[335,335],"valid"],[[336,336],"mapped",[337]],[[337,337],"valid"],[[338,338],"mapped",[339]],[[339,339],"valid"],[[340,340],"mapped",[341]],[[341,341],"valid"],[[342,342],"mapped",[343]],[[343,343],"valid"],[[344,344],"mapped",[345]],[[345,345],"valid"],[[346,346],"mapped",[347]],[[347,347],"valid"],[[348,348],"mapped",[349]],[[349,349],"valid"],[[350,350],"mapped",[351]],[[351,351],"valid"],[[352,352],"mapped",[353]],[[353,353],"valid"],[[354,354],"mapped",[355]],[[355,355],"valid"],[[356,356],"mapped",[357]],[[357,357],"valid"],[[358,358],"mapped",[359]],[[359,359],"valid"],[[360,360],"mapped",[361]],[[361,361],"valid"],[[362,362],"mapped",[363]],[[363,363],"valid"],[[364,364],"mapped",[365]],[[365,365],"valid"],[[366,366],"mapped",[367]],[[367,367],"valid"],[[368,368],"mapped",[369]],[[369,369],"valid"],[[370,370],"mapped",[371]],[[371,371],"valid"],[[372,372],"mapped",[373]],[[373,373],"valid"],[[374,374],"mapped",[375]],[[375,375],"valid"],[[376,376],"mapped",[255]],[[377,377],"mapped",[378]],[[378,378],"valid"],[[379,379],"mapped",[380]],[[380,380],"valid"],[[381,381],"mapped",[382]],[[382,382],"valid"],[[383,383],"mapped",[115]],[[384,384],"valid"],[[385,385],"mapped",[595]],[[386,386],"mapped",[387]],[[387,387],"valid"],[[388,388],"mapped",[389]],[[389,389],"valid"],[[390,390],"mapped",[596]],[[391,391],"mapped",[392]],[[392,392],"valid"],[[393,393],"mapped",[598]],[[394,394],"mapped",[599]],[[395,395],"mapped",[396]],[[396,397],"valid"],[[398,398],"mapped",[477]],[[399,399],"mapped",[601]],[[400,400],"mapped",[603]],[[401,401],"mapped",[402]],[[402,402],"valid"],[[403,403],"mapped",[608]],[[404,404],"mapped",[611]],[[405,405],"valid"],[[406,406],"mapped",[617]],[[407,407],"mapped",[616]],[[408,408],"mapped",[409]],[[409,411],"valid"],[[412,412],"mapped",[623]],[[413,413],"mapped",[626]],[[414,414],"valid"],[[415,415],"mapped",[629]],[[416,416],"mapped",[417]],[[417,417],"valid"],[[418,418],"mapped",[419]],[[419,419],"valid"],[[420,420],"mapped",[421]],[[421,421],"valid"],[[422,422],"mapped",[640]],[[423,423],"mapped",[424]],[[424,424],"valid"],[[425,425],"mapped",[643]],[[426,427],"valid"],[[428,428],"mapped",[429]],[[429,429],"valid"],[[430,430],"mapped",[648]],[[431,431],"mapped",[432]],[[432,432],"valid"],[[433,433],"mapped",[650]],[[434,434],"mapped",[651]],[[435,435],"mapped",[436]],[[436,436],"valid"],[[437,437],"mapped",[438]],[[438,438],"valid"],[[439,439],"mapped",[658]],[[440,440],"mapped",[441]],[[441,443],"valid"],[[444,444],"mapped",[445]],[[445,451],"valid"],[[452,454],"mapped",[100,382]],[[455,457],"mapped",[108,106]],[[458,460],"mapped",[110,106]],[[461,461],"mapped",[462]],[[462,462],"valid"],[[463,463],"mapped",[464]],[[464,464],"valid"],[[465,465],"mapped",[466]],[[466,466],"valid"],[[467,467],"mapped",[468]],[[468,468],"valid"],[[469,469],"mapped",[470]],[[470,470],"valid"],[[471,471],"mapped",[472]],[[472,472],"valid"],[[473,473],"mapped",[474]],[[474,474],"valid"],[[475,475],"mapped",[476]],[[476,477],"valid"],[[478,478],"mapped",[479]],[[479,479],"valid"],[[480,480],"mapped",[481]],[[481,481],"valid"],[[482,482],"mapped",[483]],[[483,483],"valid"],[[484,484],"mapped",[485]],[[485,485],"valid"],[[486,486],"mapped",[487]],[[487,487],"valid"],[[488,488],"mapped",[489]],[[489,489],"valid"],[[490,490],"mapped",[491]],[[491,491],"valid"],[[492,492],"mapped",[493]],[[493,493],"valid"],[[494,494],"mapped",[495]],[[495,496],"valid"],[[497,499],"mapped",[100,122]],[[500,500],"mapped",[501]],[[501,501],"valid"],[[502,502],"mapped",[405]],[[503,503],"mapped",[447]],[[504,504],"mapped",[505]],[[505,505],"valid"],[[506,506],"mapped",[507]],[[507,507],"valid"],[[508,508],"mapped",[509]],[[509,509],"valid"],[[510,510],"mapped",[511]],[[511,511],"valid"],[[512,512],"mapped",[513]],[[513,513],"valid"],[[514,514],"mapped",[515]],[[515,515],"valid"],[[516,516],"mapped",[517]],[[517,517],"valid"],[[518,518],"mapped",[519]],[[519,519],"valid"],[[520,520],"mapped",[521]],[[521,521],"valid"],[[522,522],"mapped",[523]],[[523,523],"valid"],[[524,524],"mapped",[525]],[[525,525],"valid"],[[526,526],"mapped",[527]],[[527,527],"valid"],[[528,528],"mapped",[529]],[[529,529],"valid"],[[530,530],"mapped",[531]],[[531,531],"valid"],[[532,532],"mapped",[533]],[[533,533],"valid"],[[534,534],"mapped",[535]],[[535,535],"valid"],[[536,536],"mapped",[537]],[[537,537],"valid"],[[538,538],"mapped",[539]],[[539,539],"valid"],[[540,540],"mapped",[541]],[[541,541],"valid"],[[542,542],"mapped",[543]],[[543,543],"valid"],[[544,544],"mapped",[414]],[[545,545],"valid"],[[546,546],"mapped",[547]],[[547,547],"valid"],[[548,548],"mapped",[549]],[[549,549],"valid"],[[550,550],"mapped",[551]],[[551,551],"valid"],[[552,552],"mapped",[553]],[[553,553],"valid"],[[554,554],"mapped",[555]],[[555,555],"valid"],[[556,556],"mapped",[557]],[[557,557],"valid"],[[558,558],"mapped",[559]],[[559,559],"valid"],[[560,560],"mapped",[561]],[[561,561],"valid"],[[562,562],"mapped",[563]],[[563,563],"valid"],[[564,566],"valid"],[[567,569],"valid"],[[570,570],"mapped",[11365]],[[571,571],"mapped",[572]],[[572,572],"valid"],[[573,573],"mapped",[410]],[[574,574],"mapped",[11366]],[[575,576],"valid"],[[577,577],"mapped",[578]],[[578,578],"valid"],[[579,579],"mapped",[384]],[[580,580],"mapped",[649]],[[581,581],"mapped",[652]],[[582,582],"mapped",[583]],[[583,583],"valid"],[[584,584],"mapped",[585]],[[585,585],"valid"],[[586,586],"mapped",[587]],[[587,587],"valid"],[[588,588],"mapped",[589]],[[589,589],"valid"],[[590,590],"mapped",[591]],[[591,591],"valid"],[[592,680],"valid"],[[681,685],"valid"],[[686,687],"valid"],[[688,688],"mapped",[104]],[[689,689],"mapped",[614]],[[690,690],"mapped",[106]],[[691,691],"mapped",[114]],[[692,692],"mapped",[633]],[[693,693],"mapped",[635]],[[694,694],"mapped",[641]],[[695,695],"mapped",[119]],[[696,696],"mapped",[121]],[[697,705],"valid"],[[706,709],"valid",[],"NV8"],[[710,721],"valid"],[[722,727],"valid",[],"NV8"],[[728,728],"disallowed_STD3_mapped",[32,774]],[[729,729],"disallowed_STD3_mapped",[32,775]],[[730,730],"disallowed_STD3_mapped",[32,778]],[[731,731],"disallowed_STD3_mapped",[32,808]],[[732,732],"disallowed_STD3_mapped",[32,771]],[[733,733],"disallowed_STD3_mapped",[32,779]],[[734,734],"valid",[],"NV8"],[[735,735],"valid",[],"NV8"],[[736,736],"mapped",[611]],[[737,737],"mapped",[108]],[[738,738],"mapped",[115]],[[739,739],"mapped",[120]],[[740,740],"mapped",[661]],[[741,745],"valid",[],"NV8"],[[746,747],"valid",[],"NV8"],[[748,748],"valid"],[[749,749],"valid",[],"NV8"],[[750,750],"valid"],[[751,767],"valid",[],"NV8"],[[768,831],"valid"],[[832,832],"mapped",[768]],[[833,833],"mapped",[769]],[[834,834],"valid"],[[835,835],"mapped",[787]],[[836,836],"mapped",[776,769]],[[837,837],"mapped",[953]],[[838,846],"valid"],[[847,847],"ignored"],[[848,855],"valid"],[[856,860],"valid"],[[861,863],"valid"],[[864,865],"valid"],[[866,866],"valid"],[[867,879],"valid"],[[880,880],"mapped",[881]],[[881,881],"valid"],[[882,882],"mapped",[883]],[[883,883],"valid"],[[884,884],"mapped",[697]],[[885,885],"valid"],[[886,886],"mapped",[887]],[[887,887],"valid"],[[888,889],"disallowed"],[[890,890],"disallowed_STD3_mapped",[32,953]],[[891,893],"valid"],[[894,894],"disallowed_STD3_mapped",[59]],[[895,895],"mapped",[1011]],[[896,899],"disallowed"],[[900,900],"disallowed_STD3_mapped",[32,769]],[[901,901],"disallowed_STD3_mapped",[32,776,769]],[[902,902],"mapped",[940]],[[903,903],"mapped",[183]],[[904,904],"mapped",[941]],[[905,905],"mapped",[942]],[[906,906],"mapped",[943]],[[907,907],"disallowed"],[[908,908],"mapped",[972]],[[909,909],"disallowed"],[[910,910],"mapped",[973]],[[911,911],"mapped",[974]],[[912,912],"valid"],[[913,913],"mapped",[945]],[[914,914],"mapped",[946]],[[915,915],"mapped",[947]],[[916,916],"mapped",[948]],[[917,917],"mapped",[949]],[[918,918],"mapped",[950]],[[919,919],"mapped",[951]],[[920,920],"mapped",[952]],[[921,921],"mapped",[953]],[[922,922],"mapped",[954]],[[923,923],"mapped",[955]],[[924,924],"mapped",[956]],[[925,925],"mapped",[957]],[[926,926],"mapped",[958]],[[927,927],"mapped",[959]],[[928,928],"mapped",[960]],[[929,929],"mapped",[961]],[[930,930],"disallowed"],[[931,931],"mapped",[963]],[[932,932],"mapped",[964]],[[933,933],"mapped",[965]],[[934,934],"mapped",[966]],[[935,935],"mapped",[967]],[[936,936],"mapped",[968]],[[937,937],"mapped",[969]],[[938,938],"mapped",[970]],[[939,939],"mapped",[971]],[[940,961],"valid"],[[962,962],"deviation",[963]],[[963,974],"valid"],[[975,975],"mapped",[983]],[[976,976],"mapped",[946]],[[977,977],"mapped",[952]],[[978,978],"mapped",[965]],[[979,979],"mapped",[973]],[[980,980],"mapped",[971]],[[981,981],"mapped",[966]],[[982,982],"mapped",[960]],[[983,983],"valid"],[[984,984],"mapped",[985]],[[985,985],"valid"],[[986,986],"mapped",[987]],[[987,987],"valid"],[[988,988],"mapped",[989]],[[989,989],"valid"],[[990,990],"mapped",[991]],[[991,991],"valid"],[[992,992],"mapped",[993]],[[993,993],"valid"],[[994,994],"mapped",[995]],[[995,995],"valid"],[[996,996],"mapped",[997]],[[997,997],"valid"],[[998,998],"mapped",[999]],[[999,999],"valid"],[[1000,1000],"mapped",[1001]],[[1001,1001],"valid"],[[1002,1002],"mapped",[1003]],[[1003,1003],"valid"],[[1004,1004],"mapped",[1005]],[[1005,1005],"valid"],[[1006,1006],"mapped",[1007]],[[1007,1007],"valid"],[[1008,1008],"mapped",[954]],[[1009,1009],"mapped",[961]],[[1010,1010],"mapped",[963]],[[1011,1011],"valid"],[[1012,1012],"mapped",[952]],[[1013,1013],"mapped",[949]],[[1014,1014],"valid",[],"NV8"],[[1015,1015],"mapped",[1016]],[[1016,1016],"valid"],[[1017,1017],"mapped",[963]],[[1018,1018],"mapped",[1019]],[[1019,1019],"valid"],[[1020,1020],"valid"],[[1021,1021],"mapped",[891]],[[1022,1022],"mapped",[892]],[[1023,1023],"mapped",[893]],[[1024,1024],"mapped",[1104]],[[1025,1025],"mapped",[1105]],[[1026,1026],"mapped",[1106]],[[1027,1027],"mapped",[1107]],[[1028,1028],"mapped",[1108]],[[1029,1029],"mapped",[1109]],[[1030,1030],"mapped",[1110]],[[1031,1031],"mapped",[1111]],[[1032,1032],"mapped",[1112]],[[1033,1033],"mapped",[1113]],[[1034,1034],"mapped",[1114]],[[1035,1035],"mapped",[1115]],[[1036,1036],"mapped",[1116]],[[1037,1037],"mapped",[1117]],[[1038,1038],"mapped",[1118]],[[1039,1039],"mapped",[1119]],[[1040,1040],"mapped",[1072]],[[1041,1041],"mapped",[1073]],[[1042,1042],"mapped",[1074]],[[1043,1043],"mapped",[1075]],[[1044,1044],"mapped",[1076]],[[1045,1045],"mapped",[1077]],[[1046,1046],"mapped",[1078]],[[1047,1047],"mapped",[1079]],[[1048,1048],"mapped",[1080]],[[1049,1049],"mapped",[1081]],[[1050,1050],"mapped",[1082]],[[1051,1051],"mapped",[1083]],[[1052,1052],"mapped",[1084]],[[1053,1053],"mapped",[1085]],[[1054,1054],"mapped",[1086]],[[1055,1055],"mapped",[1087]],[[1056,1056],"mapped",[1088]],[[1057,1057],"mapped",[1089]],[[1058,1058],"mapped",[1090]],[[1059,1059],"mapped",[1091]],[[1060,1060],"mapped",[1092]],[[1061,1061],"mapped",[1093]],[[1062,1062],"mapped",[1094]],[[1063,1063],"mapped",[1095]],[[1064,1064],"mapped",[1096]],[[1065,1065],"mapped",[1097]],[[1066,1066],"mapped",[1098]],[[1067,1067],"mapped",[1099]],[[1068,1068],"mapped",[1100]],[[1069,1069],"mapped",[1101]],[[1070,1070],"mapped",[1102]],[[1071,1071],"mapped",[1103]],[[1072,1103],"valid"],[[1104,1104],"valid"],[[1105,1116],"valid"],[[1117,1117],"valid"],[[1118,1119],"valid"],[[1120,1120],"mapped",[1121]],[[1121,1121],"valid"],[[1122,1122],"mapped",[1123]],[[1123,1123],"valid"],[[1124,1124],"mapped",[1125]],[[1125,1125],"valid"],[[1126,1126],"mapped",[1127]],[[1127,1127],"valid"],[[1128,1128],"mapped",[1129]],[[1129,1129],"valid"],[[1130,1130],"mapped",[1131]],[[1131,1131],"valid"],[[1132,1132],"mapped",[1133]],[[1133,1133],"valid"],[[1134,1134],"mapped",[1135]],[[1135,1135],"valid"],[[1136,1136],"mapped",[1137]],[[1137,1137],"valid"],[[1138,1138],"mapped",[1139]],[[1139,1139],"valid"],[[1140,1140],"mapped",[1141]],[[1141,1141],"valid"],[[1142,1142],"mapped",[1143]],[[1143,1143],"valid"],[[1144,1144],"mapped",[1145]],[[1145,1145],"valid"],[[1146,1146],"mapped",[1147]],[[1147,1147],"valid"],[[1148,1148],"mapped",[1149]],[[1149,1149],"valid"],[[1150,1150],"mapped",[1151]],[[1151,1151],"valid"],[[1152,1152],"mapped",[1153]],[[1153,1153],"valid"],[[1154,1154],"valid",[],"NV8"],[[1155,1158],"valid"],[[1159,1159],"valid"],[[1160,1161],"valid",[],"NV8"],[[1162,1162],"mapped",[1163]],[[1163,1163],"valid"],[[1164,1164],"mapped",[1165]],[[1165,1165],"valid"],[[1166,1166],"mapped",[1167]],[[1167,1167],"valid"],[[1168,1168],"mapped",[1169]],[[1169,1169],"valid"],[[1170,1170],"mapped",[1171]],[[1171,1171],"valid"],[[1172,1172],"mapped",[1173]],[[1173,1173],"valid"],[[1174,1174],"mapped",[1175]],[[1175,1175],"valid"],[[1176,1176],"mapped",[1177]],[[1177,1177],"valid"],[[1178,1178],"mapped",[1179]],[[1179,1179],"valid"],[[1180,1180],"mapped",[1181]],[[1181,1181],"valid"],[[1182,1182],"mapped",[1183]],[[1183,1183],"valid"],[[1184,1184],"mapped",[1185]],[[1185,1185],"valid"],[[1186,1186],"mapped",[1187]],[[1187,1187],"valid"],[[1188,1188],"mapped",[1189]],[[1189,1189],"valid"],[[1190,1190],"mapped",[1191]],[[1191,1191],"valid"],[[1192,1192],"mapped",[1193]],[[1193,1193],"valid"],[[1194,1194],"mapped",[1195]],[[1195,1195],"valid"],[[1196,1196],"mapped",[1197]],[[1197,1197],"valid"],[[1198,1198],"mapped",[1199]],[[1199,1199],"valid"],[[1200,1200],"mapped",[1201]],[[1201,1201],"valid"],[[1202,1202],"mapped",[1203]],[[1203,1203],"valid"],[[1204,1204],"mapped",[1205]],[[1205,1205],"valid"],[[1206,1206],"mapped",[1207]],[[1207,1207],"valid"],[[1208,1208],"mapped",[1209]],[[1209,1209],"valid"],[[1210,1210],"mapped",[1211]],[[1211,1211],"valid"],[[1212,1212],"mapped",[1213]],[[1213,1213],"valid"],[[1214,1214],"mapped",[1215]],[[1215,1215],"valid"],[[1216,1216],"disallowed"],[[1217,1217],"mapped",[1218]],[[1218,1218],"valid"],[[1219,1219],"mapped",[1220]],[[1220,1220],"valid"],[[1221,1221],"mapped",[1222]],[[1222,1222],"valid"],[[1223,1223],"mapped",[1224]],[[1224,1224],"valid"],[[1225,1225],"mapped",[1226]],[[1226,1226],"valid"],[[1227,1227],"mapped",[1228]],[[1228,1228],"valid"],[[1229,1229],"mapped",[1230]],[[1230,1230],"valid"],[[1231,1231],"valid"],[[1232,1232],"mapped",[1233]],[[1233,1233],"valid"],[[1234,1234],"mapped",[1235]],[[1235,1235],"valid"],[[1236,1236],"mapped",[1237]],[[1237,1237],"valid"],[[1238,1238],"mapped",[1239]],[[1239,1239],"valid"],[[1240,1240],"mapped",[1241]],[[1241,1241],"valid"],[[1242,1242],"mapped",[1243]],[[1243,1243],"valid"],[[1244,1244],"mapped",[1245]],[[1245,1245],"valid"],[[1246,1246],"mapped",[1247]],[[1247,1247],"valid"],[[1248,1248],"mapped",[1249]],[[1249,1249],"valid"],[[1250,1250],"mapped",[1251]],[[1251,1251],"valid"],[[1252,1252],"mapped",[1253]],[[1253,1253],"valid"],[[1254,1254],"mapped",[1255]],[[1255,1255],"valid"],[[1256,1256],"mapped",[1257]],[[1257,1257],"valid"],[[1258,1258],"mapped",[1259]],[[1259,1259],"valid"],[[1260,1260],"mapped",[1261]],[[1261,1261],"valid"],[[1262,1262],"mapped",[1263]],[[1263,1263],"valid"],[[1264,1264],"mapped",[1265]],[[1265,1265],"valid"],[[1266,1266],"mapped",[1267]],[[1267,1267],"valid"],[[1268,1268],"mapped",[1269]],[[1269,1269],"valid"],[[1270,1270],"mapped",[1271]],[[1271,1271],"valid"],[[1272,1272],"mapped",[1273]],[[1273,1273],"valid"],[[1274,1274],"mapped",[1275]],[[1275,1275],"valid"],[[1276,1276],"mapped",[1277]],[[1277,1277],"valid"],[[1278,1278],"mapped",[1279]],[[1279,1279],"valid"],[[1280,1280],"mapped",[1281]],[[1281,1281],"valid"],[[1282,1282],"mapped",[1283]],[[1283,1283],"valid"],[[1284,1284],"mapped",[1285]],[[1285,1285],"valid"],[[1286,1286],"mapped",[1287]],[[1287,1287],"valid"],[[1288,1288],"mapped",[1289]],[[1289,1289],"valid"],[[1290,1290],"mapped",[1291]],[[1291,1291],"valid"],[[1292,1292],"mapped",[1293]],[[1293,1293],"valid"],[[1294,1294],"mapped",[1295]],[[1295,1295],"valid"],[[1296,1296],"mapped",[1297]],[[1297,1297],"valid"],[[1298,1298],"mapped",[1299]],[[1299,1299],"valid"],[[1300,1300],"mapped",[1301]],[[1301,1301],"valid"],[[1302,1302],"mapped",[1303]],[[1303,1303],"valid"],[[1304,1304],"mapped",[1305]],[[1305,1305],"valid"],[[1306,1306],"mapped",[1307]],[[1307,1307],"valid"],[[1308,1308],"mapped",[1309]],[[1309,1309],"valid"],[[1310,1310],"mapped",[1311]],[[1311,1311],"valid"],[[1312,1312],"mapped",[1313]],[[1313,1313],"valid"],[[1314,1314],"mapped",[1315]],[[1315,1315],"valid"],[[1316,1316],"mapped",[1317]],[[1317,1317],"valid"],[[1318,1318],"mapped",[1319]],[[1319,1319],"valid"],[[1320,1320],"mapped",[1321]],[[1321,1321],"valid"],[[1322,1322],"mapped",[1323]],[[1323,1323],"valid"],[[1324,1324],"mapped",[1325]],[[1325,1325],"valid"],[[1326,1326],"mapped",[1327]],[[1327,1327],"valid"],[[1328,1328],"disallowed"],[[1329,1329],"mapped",[1377]],[[1330,1330],"mapped",[1378]],[[1331,1331],"mapped",[1379]],[[1332,1332],"mapped",[1380]],[[1333,1333],"mapped",[1381]],[[1334,1334],"mapped",[1382]],[[1335,1335],"mapped",[1383]],[[1336,1336],"mapped",[1384]],[[1337,1337],"mapped",[1385]],[[1338,1338],"mapped",[1386]],[[1339,1339],"mapped",[1387]],[[1340,1340],"mapped",[1388]],[[1341,1341],"mapped",[1389]],[[1342,1342],"mapped",[1390]],[[1343,1343],"mapped",[1391]],[[1344,1344],"mapped",[1392]],[[1345,1345],"mapped",[1393]],[[1346,1346],"mapped",[1394]],[[1347,1347],"mapped",[1395]],[[1348,1348],"mapped",[1396]],[[1349,1349],"mapped",[1397]],[[1350,1350],"mapped",[1398]],[[1351,1351],"mapped",[1399]],[[1352,1352],"mapped",[1400]],[[1353,1353],"mapped",[1401]],[[1354,1354],"mapped",[1402]],[[1355,1355],"mapped",[1403]],[[1356,1356],"mapped",[1404]],[[1357,1357],"mapped",[1405]],[[1358,1358],"mapped",[1406]],[[1359,1359],"mapped",[1407]],[[1360,1360],"mapped",[1408]],[[1361,1361],"mapped",[1409]],[[1362,1362],"mapped",[1410]],[[1363,1363],"mapped",[1411]],[[1364,1364],"mapped",[1412]],[[1365,1365],"mapped",[1413]],[[1366,1366],"mapped",[1414]],[[1367,1368],"disallowed"],[[1369,1369],"valid"],[[1370,1375],"valid",[],"NV8"],[[1376,1376],"disallowed"],[[1377,1414],"valid"],[[1415,1415],"mapped",[1381,1410]],[[1416,1416],"disallowed"],[[1417,1417],"valid",[],"NV8"],[[1418,1418],"valid",[],"NV8"],[[1419,1420],"disallowed"],[[1421,1422],"valid",[],"NV8"],[[1423,1423],"valid",[],"NV8"],[[1424,1424],"disallowed"],[[1425,1441],"valid"],[[1442,1442],"valid"],[[1443,1455],"valid"],[[1456,1465],"valid"],[[1466,1466],"valid"],[[1467,1469],"valid"],[[1470,1470],"valid",[],"NV8"],[[1471,1471],"valid"],[[1472,1472],"valid",[],"NV8"],[[1473,1474],"valid"],[[1475,1475],"valid",[],"NV8"],[[1476,1476],"valid"],[[1477,1477],"valid"],[[1478,1478],"valid",[],"NV8"],[[1479,1479],"valid"],[[1480,1487],"disallowed"],[[1488,1514],"valid"],[[1515,1519],"disallowed"],[[1520,1524],"valid"],[[1525,1535],"disallowed"],[[1536,1539],"disallowed"],[[1540,1540],"disallowed"],[[1541,1541],"disallowed"],[[1542,1546],"valid",[],"NV8"],[[1547,1547],"valid",[],"NV8"],[[1548,1548],"valid",[],"NV8"],[[1549,1551],"valid",[],"NV8"],[[1552,1557],"valid"],[[1558,1562],"valid"],[[1563,1563],"valid",[],"NV8"],[[1564,1564],"disallowed"],[[1565,1565],"disallowed"],[[1566,1566],"valid",[],"NV8"],[[1567,1567],"valid",[],"NV8"],[[1568,1568],"valid"],[[1569,1594],"valid"],[[1595,1599],"valid"],[[1600,1600],"valid",[],"NV8"],[[1601,1618],"valid"],[[1619,1621],"valid"],[[1622,1624],"valid"],[[1625,1630],"valid"],[[1631,1631],"valid"],[[1632,1641],"valid"],[[1642,1645],"valid",[],"NV8"],[[1646,1647],"valid"],[[1648,1652],"valid"],[[1653,1653],"mapped",[1575,1652]],[[1654,1654],"mapped",[1608,1652]],[[1655,1655],"mapped",[1735,1652]],[[1656,1656],"mapped",[1610,1652]],[[1657,1719],"valid"],[[1720,1721],"valid"],[[1722,1726],"valid"],[[1727,1727],"valid"],[[1728,1742],"valid"],[[1743,1743],"valid"],[[1744,1747],"valid"],[[1748,1748],"valid",[],"NV8"],[[1749,1756],"valid"],[[1757,1757],"disallowed"],[[1758,1758],"valid",[],"NV8"],[[1759,1768],"valid"],[[1769,1769],"valid",[],"NV8"],[[1770,1773],"valid"],[[1774,1775],"valid"],[[1776,1785],"valid"],[[1786,1790],"valid"],[[1791,1791],"valid"],[[1792,1805],"valid",[],"NV8"],[[1806,1806],"disallowed"],[[1807,1807],"disallowed"],[[1808,1836],"valid"],[[1837,1839],"valid"],[[1840,1866],"valid"],[[1867,1868],"disallowed"],[[1869,1871],"valid"],[[1872,1901],"valid"],[[1902,1919],"valid"],[[1920,1968],"valid"],[[1969,1969],"valid"],[[1970,1983],"disallowed"],[[1984,2037],"valid"],[[2038,2042],"valid",[],"NV8"],[[2043,2047],"disallowed"],[[2048,2093],"valid"],[[2094,2095],"disallowed"],[[2096,2110],"valid",[],"NV8"],[[2111,2111],"disallowed"],[[2112,2139],"valid"],[[2140,2141],"disallowed"],[[2142,2142],"valid",[],"NV8"],[[2143,2207],"disallowed"],[[2208,2208],"valid"],[[2209,2209],"valid"],[[2210,2220],"valid"],[[2221,2226],"valid"],[[2227,2228],"valid"],[[2229,2274],"disallowed"],[[2275,2275],"valid"],[[2276,2302],"valid"],[[2303,2303],"valid"],[[2304,2304],"valid"],[[2305,2307],"valid"],[[2308,2308],"valid"],[[2309,2361],"valid"],[[2362,2363],"valid"],[[2364,2381],"valid"],[[2382,2382],"valid"],[[2383,2383],"valid"],[[2384,2388],"valid"],[[2389,2389],"valid"],[[2390,2391],"valid"],[[2392,2392],"mapped",[2325,2364]],[[2393,2393],"mapped",[2326,2364]],[[2394,2394],"mapped",[2327,2364]],[[2395,2395],"mapped",[2332,2364]],[[2396,2396],"mapped",[2337,2364]],[[2397,2397],"mapped",[2338,2364]],[[2398,2398],"mapped",[2347,2364]],[[2399,2399],"mapped",[2351,2364]],[[2400,2403],"valid"],[[2404,2405],"valid",[],"NV8"],[[2406,2415],"valid"],[[2416,2416],"valid",[],"NV8"],[[2417,2418],"valid"],[[2419,2423],"valid"],[[2424,2424],"valid"],[[2425,2426],"valid"],[[2427,2428],"valid"],[[2429,2429],"valid"],[[2430,2431],"valid"],[[2432,2432],"valid"],[[2433,2435],"valid"],[[2436,2436],"disallowed"],[[2437,2444],"valid"],[[2445,2446],"disallowed"],[[2447,2448],"valid"],[[2449,2450],"disallowed"],[[2451,2472],"valid"],[[2473,2473],"disallowed"],[[2474,2480],"valid"],[[2481,2481],"disallowed"],[[2482,2482],"valid"],[[2483,2485],"disallowed"],[[2486,2489],"valid"],[[2490,2491],"disallowed"],[[2492,2492],"valid"],[[2493,2493],"valid"],[[2494,2500],"valid"],[[2501,2502],"disallowed"],[[2503,2504],"valid"],[[2505,2506],"disallowed"],[[2507,2509],"valid"],[[2510,2510],"valid"],[[2511,2518],"disallowed"],[[2519,2519],"valid"],[[2520,2523],"disallowed"],[[2524,2524],"mapped",[2465,2492]],[[2525,2525],"mapped",[2466,2492]],[[2526,2526],"disallowed"],[[2527,2527],"mapped",[2479,2492]],[[2528,2531],"valid"],[[2532,2533],"disallowed"],[[2534,2545],"valid"],[[2546,2554],"valid",[],"NV8"],[[2555,2555],"valid",[],"NV8"],[[2556,2560],"disallowed"],[[2561,2561],"valid"],[[2562,2562],"valid"],[[2563,2563],"valid"],[[2564,2564],"disallowed"],[[2565,2570],"valid"],[[2571,2574],"disallowed"],[[2575,2576],"valid"],[[2577,2578],"disallowed"],[[2579,2600],"valid"],[[2601,2601],"disallowed"],[[2602,2608],"valid"],[[2609,2609],"disallowed"],[[2610,2610],"valid"],[[2611,2611],"mapped",[2610,2620]],[[2612,2612],"disallowed"],[[2613,2613],"valid"],[[2614,2614],"mapped",[2616,2620]],[[2615,2615],"disallowed"],[[2616,2617],"valid"],[[2618,2619],"disallowed"],[[2620,2620],"valid"],[[2621,2621],"disallowed"],[[2622,2626],"valid"],[[2627,2630],"disallowed"],[[2631,2632],"valid"],[[2633,2634],"disallowed"],[[2635,2637],"valid"],[[2638,2640],"disallowed"],[[2641,2641],"valid"],[[2642,2648],"disallowed"],[[2649,2649],"mapped",[2582,2620]],[[2650,2650],"mapped",[2583,2620]],[[2651,2651],"mapped",[2588,2620]],[[2652,2652],"valid"],[[2653,2653],"disallowed"],[[2654,2654],"mapped",[2603,2620]],[[2655,2661],"disallowed"],[[2662,2676],"valid"],[[2677,2677],"valid"],[[2678,2688],"disallowed"],[[2689,2691],"valid"],[[2692,2692],"disallowed"],[[2693,2699],"valid"],[[2700,2700],"valid"],[[2701,2701],"valid"],[[2702,2702],"disallowed"],[[2703,2705],"valid"],[[2706,2706],"disallowed"],[[2707,2728],"valid"],[[2729,2729],"disallowed"],[[2730,2736],"valid"],[[2737,2737],"disallowed"],[[2738,2739],"valid"],[[2740,2740],"disallowed"],[[2741,2745],"valid"],[[2746,2747],"disallowed"],[[2748,2757],"valid"],[[2758,2758],"disallowed"],[[2759,2761],"valid"],[[2762,2762],"disallowed"],[[2763,2765],"valid"],[[2766,2767],"disallowed"],[[2768,2768],"valid"],[[2769,2783],"disallowed"],[[2784,2784],"valid"],[[2785,2787],"valid"],[[2788,2789],"disallowed"],[[2790,2799],"valid"],[[2800,2800],"valid",[],"NV8"],[[2801,2801],"valid",[],"NV8"],[[2802,2808],"disallowed"],[[2809,2809],"valid"],[[2810,2816],"disallowed"],[[2817,2819],"valid"],[[2820,2820],"disallowed"],[[2821,2828],"valid"],[[2829,2830],"disallowed"],[[2831,2832],"valid"],[[2833,2834],"disallowed"],[[2835,2856],"valid"],[[2857,2857],"disallowed"],[[2858,2864],"valid"],[[2865,2865],"disallowed"],[[2866,2867],"valid"],[[2868,2868],"disallowed"],[[2869,2869],"valid"],[[2870,2873],"valid"],[[2874,2875],"disallowed"],[[2876,2883],"valid"],[[2884,2884],"valid"],[[2885,2886],"disallowed"],[[2887,2888],"valid"],[[2889,2890],"disallowed"],[[2891,2893],"valid"],[[2894,2901],"disallowed"],[[2902,2903],"valid"],[[2904,2907],"disallowed"],[[2908,2908],"mapped",[2849,2876]],[[2909,2909],"mapped",[2850,2876]],[[2910,2910],"disallowed"],[[2911,2913],"valid"],[[2914,2915],"valid"],[[2916,2917],"disallowed"],[[2918,2927],"valid"],[[2928,2928],"valid",[],"NV8"],[[2929,2929],"valid"],[[2930,2935],"valid",[],"NV8"],[[2936,2945],"disallowed"],[[2946,2947],"valid"],[[2948,2948],"disallowed"],[[2949,2954],"valid"],[[2955,2957],"disallowed"],[[2958,2960],"valid"],[[2961,2961],"disallowed"],[[2962,2965],"valid"],[[2966,2968],"disallowed"],[[2969,2970],"valid"],[[2971,2971],"disallowed"],[[2972,2972],"valid"],[[2973,2973],"disallowed"],[[2974,2975],"valid"],[[2976,2978],"disallowed"],[[2979,2980],"valid"],[[2981,2983],"disallowed"],[[2984,2986],"valid"],[[2987,2989],"disallowed"],[[2990,2997],"valid"],[[2998,2998],"valid"],[[2999,3001],"valid"],[[3002,3005],"disallowed"],[[3006,3010],"valid"],[[3011,3013],"disallowed"],[[3014,3016],"valid"],[[3017,3017],"disallowed"],[[3018,3021],"valid"],[[3022,3023],"disallowed"],[[3024,3024],"valid"],[[3025,3030],"disallowed"],[[3031,3031],"valid"],[[3032,3045],"disallowed"],[[3046,3046],"valid"],[[3047,3055],"valid"],[[3056,3058],"valid",[],"NV8"],[[3059,3066],"valid",[],"NV8"],[[3067,3071],"disallowed"],[[3072,3072],"valid"],[[3073,3075],"valid"],[[3076,3076],"disallowed"],[[3077,3084],"valid"],[[3085,3085],"disallowed"],[[3086,3088],"valid"],[[3089,3089],"disallowed"],[[3090,3112],"valid"],[[3113,3113],"disallowed"],[[3114,3123],"valid"],[[3124,3124],"valid"],[[3125,3129],"valid"],[[3130,3132],"disallowed"],[[3133,3133],"valid"],[[3134,3140],"valid"],[[3141,3141],"disallowed"],[[3142,3144],"valid"],[[3145,3145],"disallowed"],[[3146,3149],"valid"],[[3150,3156],"disallowed"],[[3157,3158],"valid"],[[3159,3159],"disallowed"],[[3160,3161],"valid"],[[3162,3162],"valid"],[[3163,3167],"disallowed"],[[3168,3169],"valid"],[[3170,3171],"valid"],[[3172,3173],"disallowed"],[[3174,3183],"valid"],[[3184,3191],"disallowed"],[[3192,3199],"valid",[],"NV8"],[[3200,3200],"disallowed"],[[3201,3201],"valid"],[[3202,3203],"valid"],[[3204,3204],"disallowed"],[[3205,3212],"valid"],[[3213,3213],"disallowed"],[[3214,3216],"valid"],[[3217,3217],"disallowed"],[[3218,3240],"valid"],[[3241,3241],"disallowed"],[[3242,3251],"valid"],[[3252,3252],"disallowed"],[[3253,3257],"valid"],[[3258,3259],"disallowed"],[[3260,3261],"valid"],[[3262,3268],"valid"],[[3269,3269],"disallowed"],[[3270,3272],"valid"],[[3273,3273],"disallowed"],[[3274,3277],"valid"],[[3278,3284],"disallowed"],[[3285,3286],"valid"],[[3287,3293],"disallowed"],[[3294,3294],"valid"],[[3295,3295],"disallowed"],[[3296,3297],"valid"],[[3298,3299],"valid"],[[3300,3301],"disallowed"],[[3302,3311],"valid"],[[3312,3312],"disallowed"],[[3313,3314],"valid"],[[3315,3328],"disallowed"],[[3329,3329],"valid"],[[3330,3331],"valid"],[[3332,3332],"disallowed"],[[3333,3340],"valid"],[[3341,3341],"disallowed"],[[3342,3344],"valid"],[[3345,3345],"disallowed"],[[3346,3368],"valid"],[[3369,3369],"valid"],[[3370,3385],"valid"],[[3386,3386],"valid"],[[3387,3388],"disallowed"],[[3389,3389],"valid"],[[3390,3395],"valid"],[[3396,3396],"valid"],[[3397,3397],"disallowed"],[[3398,3400],"valid"],[[3401,3401],"disallowed"],[[3402,3405],"valid"],[[3406,3406],"valid"],[[3407,3414],"disallowed"],[[3415,3415],"valid"],[[3416,3422],"disallowed"],[[3423,3423],"valid"],[[3424,3425],"valid"],[[3426,3427],"valid"],[[3428,3429],"disallowed"],[[3430,3439],"valid"],[[3440,3445],"valid",[],"NV8"],[[3446,3448],"disallowed"],[[3449,3449],"valid",[],"NV8"],[[3450,3455],"valid"],[[3456,3457],"disallowed"],[[3458,3459],"valid"],[[3460,3460],"disallowed"],[[3461,3478],"valid"],[[3479,3481],"disallowed"],[[3482,3505],"valid"],[[3506,3506],"disallowed"],[[3507,3515],"valid"],[[3516,3516],"disallowed"],[[3517,3517],"valid"],[[3518,3519],"disallowed"],[[3520,3526],"valid"],[[3527,3529],"disallowed"],[[3530,3530],"valid"],[[3531,3534],"disallowed"],[[3535,3540],"valid"],[[3541,3541],"disallowed"],[[3542,3542],"valid"],[[3543,3543],"disallowed"],[[3544,3551],"valid"],[[3552,3557],"disallowed"],[[3558,3567],"valid"],[[3568,3569],"disallowed"],[[3570,3571],"valid"],[[3572,3572],"valid",[],"NV8"],[[3573,3584],"disallowed"],[[3585,3634],"valid"],[[3635,3635],"mapped",[3661,3634]],[[3636,3642],"valid"],[[3643,3646],"disallowed"],[[3647,3647],"valid",[],"NV8"],[[3648,3662],"valid"],[[3663,3663],"valid",[],"NV8"],[[3664,3673],"valid"],[[3674,3675],"valid",[],"NV8"],[[3676,3712],"disallowed"],[[3713,3714],"valid"],[[3715,3715],"disallowed"],[[3716,3716],"valid"],[[3717,3718],"disallowed"],[[3719,3720],"valid"],[[3721,3721],"disallowed"],[[3722,3722],"valid"],[[3723,3724],"disallowed"],[[3725,3725],"valid"],[[3726,3731],"disallowed"],[[3732,3735],"valid"],[[3736,3736],"disallowed"],[[3737,3743],"valid"],[[3744,3744],"disallowed"],[[3745,3747],"valid"],[[3748,3748],"disallowed"],[[3749,3749],"valid"],[[3750,3750],"disallowed"],[[3751,3751],"valid"],[[3752,3753],"disallowed"],[[3754,3755],"valid"],[[3756,3756],"disallowed"],[[3757,3762],"valid"],[[3763,3763],"mapped",[3789,3762]],[[3764,3769],"valid"],[[3770,3770],"disallowed"],[[3771,3773],"valid"],[[3774,3775],"disallowed"],[[3776,3780],"valid"],[[3781,3781],"disallowed"],[[3782,3782],"valid"],[[3783,3783],"disallowed"],[[3784,3789],"valid"],[[3790,3791],"disallowed"],[[3792,3801],"valid"],[[3802,3803],"disallowed"],[[3804,3804],"mapped",[3755,3737]],[[3805,3805],"mapped",[3755,3745]],[[3806,3807],"valid"],[[3808,3839],"disallowed"],[[3840,3840],"valid"],[[3841,3850],"valid",[],"NV8"],[[3851,3851],"valid"],[[3852,3852],"mapped",[3851]],[[3853,3863],"valid",[],"NV8"],[[3864,3865],"valid"],[[3866,3871],"valid",[],"NV8"],[[3872,3881],"valid"],[[3882,3892],"valid",[],"NV8"],[[3893,3893],"valid"],[[3894,3894],"valid",[],"NV8"],[[3895,3895],"valid"],[[3896,3896],"valid",[],"NV8"],[[3897,3897],"valid"],[[3898,3901],"valid",[],"NV8"],[[3902,3906],"valid"],[[3907,3907],"mapped",[3906,4023]],[[3908,3911],"valid"],[[3912,3912],"disallowed"],[[3913,3916],"valid"],[[3917,3917],"mapped",[3916,4023]],[[3918,3921],"valid"],[[3922,3922],"mapped",[3921,4023]],[[3923,3926],"valid"],[[3927,3927],"mapped",[3926,4023]],[[3928,3931],"valid"],[[3932,3932],"mapped",[3931,4023]],[[3933,3944],"valid"],[[3945,3945],"mapped",[3904,4021]],[[3946,3946],"valid"],[[3947,3948],"valid"],[[3949,3952],"disallowed"],[[3953,3954],"valid"],[[3955,3955],"mapped",[3953,3954]],[[3956,3956],"valid"],[[3957,3957],"mapped",[3953,3956]],[[3958,3958],"mapped",[4018,3968]],[[3959,3959],"mapped",[4018,3953,3968]],[[3960,3960],"mapped",[4019,3968]],[[3961,3961],"mapped",[4019,3953,3968]],[[3962,3968],"valid"],[[3969,3969],"mapped",[3953,3968]],[[3970,3972],"valid"],[[3973,3973],"valid",[],"NV8"],[[3974,3979],"valid"],[[3980,3983],"valid"],[[3984,3986],"valid"],[[3987,3987],"mapped",[3986,4023]],[[3988,3989],"valid"],[[3990,3990],"valid"],[[3991,3991],"valid"],[[3992,3992],"disallowed"],[[3993,3996],"valid"],[[3997,3997],"mapped",[3996,4023]],[[3998,4001],"valid"],[[4002,4002],"mapped",[4001,4023]],[[4003,4006],"valid"],[[4007,4007],"mapped",[4006,4023]],[[4008,4011],"valid"],[[4012,4012],"mapped",[4011,4023]],[[4013,4013],"valid"],[[4014,4016],"valid"],[[4017,4023],"valid"],[[4024,4024],"valid"],[[4025,4025],"mapped",[3984,4021]],[[4026,4028],"valid"],[[4029,4029],"disallowed"],[[4030,4037],"valid",[],"NV8"],[[4038,4038],"valid"],[[4039,4044],"valid",[],"NV8"],[[4045,4045],"disallowed"],[[4046,4046],"valid",[],"NV8"],[[4047,4047],"valid",[],"NV8"],[[4048,4049],"valid",[],"NV8"],[[4050,4052],"valid",[],"NV8"],[[4053,4056],"valid",[],"NV8"],[[4057,4058],"valid",[],"NV8"],[[4059,4095],"disallowed"],[[4096,4129],"valid"],[[4130,4130],"valid"],[[4131,4135],"valid"],[[4136,4136],"valid"],[[4137,4138],"valid"],[[4139,4139],"valid"],[[4140,4146],"valid"],[[4147,4149],"valid"],[[4150,4153],"valid"],[[4154,4159],"valid"],[[4160,4169],"valid"],[[4170,4175],"valid",[],"NV8"],[[4176,4185],"valid"],[[4186,4249],"valid"],[[4250,4253],"valid"],[[4254,4255],"valid",[],"NV8"],[[4256,4293],"disallowed"],[[4294,4294],"disallowed"],[[4295,4295],"mapped",[11559]],[[4296,4300],"disallowed"],[[4301,4301],"mapped",[11565]],[[4302,4303],"disallowed"],[[4304,4342],"valid"],[[4343,4344],"valid"],[[4345,4346],"valid"],[[4347,4347],"valid",[],"NV8"],[[4348,4348],"mapped",[4316]],[[4349,4351],"valid"],[[4352,4441],"valid",[],"NV8"],[[4442,4446],"valid",[],"NV8"],[[4447,4448],"disallowed"],[[4449,4514],"valid",[],"NV8"],[[4515,4519],"valid",[],"NV8"],[[4520,4601],"valid",[],"NV8"],[[4602,4607],"valid",[],"NV8"],[[4608,4614],"valid"],[[4615,4615],"valid"],[[4616,4678],"valid"],[[4679,4679],"valid"],[[4680,4680],"valid"],[[4681,4681],"disallowed"],[[4682,4685],"valid"],[[4686,4687],"disallowed"],[[4688,4694],"valid"],[[4695,4695],"disallowed"],[[4696,4696],"valid"],[[4697,4697],"disallowed"],[[4698,4701],"valid"],[[4702,4703],"disallowed"],[[4704,4742],"valid"],[[4743,4743],"valid"],[[4744,4744],"valid"],[[4745,4745],"disallowed"],[[4746,4749],"valid"],[[4750,4751],"disallowed"],[[4752,4782],"valid"],[[4783,4783],"valid"],[[4784,4784],"valid"],[[4785,4785],"disallowed"],[[4786,4789],"valid"],[[4790,4791],"disallowed"],[[4792,4798],"valid"],[[4799,4799],"disallowed"],[[4800,4800],"valid"],[[4801,4801],"disallowed"],[[4802,4805],"valid"],[[4806,4807],"disallowed"],[[4808,4814],"valid"],[[4815,4815],"valid"],[[4816,4822],"valid"],[[4823,4823],"disallowed"],[[4824,4846],"valid"],[[4847,4847],"valid"],[[4848,4878],"valid"],[[4879,4879],"valid"],[[4880,4880],"valid"],[[4881,4881],"disallowed"],[[4882,4885],"valid"],[[4886,4887],"disallowed"],[[4888,4894],"valid"],[[4895,4895],"valid"],[[4896,4934],"valid"],[[4935,4935],"valid"],[[4936,4954],"valid"],[[4955,4956],"disallowed"],[[4957,4958],"valid"],[[4959,4959],"valid"],[[4960,4960],"valid",[],"NV8"],[[4961,4988],"valid",[],"NV8"],[[4989,4991],"disallowed"],[[4992,5007],"valid"],[[5008,5017],"valid",[],"NV8"],[[5018,5023],"disallowed"],[[5024,5108],"valid"],[[5109,5109],"valid"],[[5110,5111],"disallowed"],[[5112,5112],"mapped",[5104]],[[5113,5113],"mapped",[5105]],[[5114,5114],"mapped",[5106]],[[5115,5115],"mapped",[5107]],[[5116,5116],"mapped",[5108]],[[5117,5117],"mapped",[5109]],[[5118,5119],"disallowed"],[[5120,5120],"valid",[],"NV8"],[[5121,5740],"valid"],[[5741,5742],"valid",[],"NV8"],[[5743,5750],"valid"],[[5751,5759],"valid"],[[5760,5760],"disallowed"],[[5761,5786],"valid"],[[5787,5788],"valid",[],"NV8"],[[5789,5791],"disallowed"],[[5792,5866],"valid"],[[5867,5872],"valid",[],"NV8"],[[5873,5880],"valid"],[[5881,5887],"disallowed"],[[5888,5900],"valid"],[[5901,5901],"disallowed"],[[5902,5908],"valid"],[[5909,5919],"disallowed"],[[5920,5940],"valid"],[[5941,5942],"valid",[],"NV8"],[[5943,5951],"disallowed"],[[5952,5971],"valid"],[[5972,5983],"disallowed"],[[5984,5996],"valid"],[[5997,5997],"disallowed"],[[5998,6000],"valid"],[[6001,6001],"disallowed"],[[6002,6003],"valid"],[[6004,6015],"disallowed"],[[6016,6067],"valid"],[[6068,6069],"disallowed"],[[6070,6099],"valid"],[[6100,6102],"valid",[],"NV8"],[[6103,6103],"valid"],[[6104,6107],"valid",[],"NV8"],[[6108,6108],"valid"],[[6109,6109],"valid"],[[6110,6111],"disallowed"],[[6112,6121],"valid"],[[6122,6127],"disallowed"],[[6128,6137],"valid",[],"NV8"],[[6138,6143],"disallowed"],[[6144,6149],"valid",[],"NV8"],[[6150,6150],"disallowed"],[[6151,6154],"valid",[],"NV8"],[[6155,6157],"ignored"],[[6158,6158],"disallowed"],[[6159,6159],"disallowed"],[[6160,6169],"valid"],[[6170,6175],"disallowed"],[[6176,6263],"valid"],[[6264,6271],"disallowed"],[[6272,6313],"valid"],[[6314,6314],"valid"],[[6315,6319],"disallowed"],[[6320,6389],"valid"],[[6390,6399],"disallowed"],[[6400,6428],"valid"],[[6429,6430],"valid"],[[6431,6431],"disallowed"],[[6432,6443],"valid"],[[6444,6447],"disallowed"],[[6448,6459],"valid"],[[6460,6463],"disallowed"],[[6464,6464],"valid",[],"NV8"],[[6465,6467],"disallowed"],[[6468,6469],"valid",[],"NV8"],[[6470,6509],"valid"],[[6510,6511],"disallowed"],[[6512,6516],"valid"],[[6517,6527],"disallowed"],[[6528,6569],"valid"],[[6570,6571],"valid"],[[6572,6575],"disallowed"],[[6576,6601],"valid"],[[6602,6607],"disallowed"],[[6608,6617],"valid"],[[6618,6618],"valid",[],"XV8"],[[6619,6621],"disallowed"],[[6622,6623],"valid",[],"NV8"],[[6624,6655],"valid",[],"NV8"],[[6656,6683],"valid"],[[6684,6685],"disallowed"],[[6686,6687],"valid",[],"NV8"],[[6688,6750],"valid"],[[6751,6751],"disallowed"],[[6752,6780],"valid"],[[6781,6782],"disallowed"],[[6783,6793],"valid"],[[6794,6799],"disallowed"],[[6800,6809],"valid"],[[6810,6815],"disallowed"],[[6816,6822],"valid",[],"NV8"],[[6823,6823],"valid"],[[6824,6829],"valid",[],"NV8"],[[6830,6831],"disallowed"],[[6832,6845],"valid"],[[6846,6846],"valid",[],"NV8"],[[6847,6911],"disallowed"],[[6912,6987],"valid"],[[6988,6991],"disallowed"],[[6992,7001],"valid"],[[7002,7018],"valid",[],"NV8"],[[7019,7027],"valid"],[[7028,7036],"valid",[],"NV8"],[[7037,7039],"disallowed"],[[7040,7082],"valid"],[[7083,7085],"valid"],[[7086,7097],"valid"],[[7098,7103],"valid"],[[7104,7155],"valid"],[[7156,7163],"disallowed"],[[7164,7167],"valid",[],"NV8"],[[7168,7223],"valid"],[[7224,7226],"disallowed"],[[7227,7231],"valid",[],"NV8"],[[7232,7241],"valid"],[[7242,7244],"disallowed"],[[7245,7293],"valid"],[[7294,7295],"valid",[],"NV8"],[[7296,7359],"disallowed"],[[7360,7367],"valid",[],"NV8"],[[7368,7375],"disallowed"],[[7376,7378],"valid"],[[7379,7379],"valid",[],"NV8"],[[7380,7410],"valid"],[[7411,7414],"valid"],[[7415,7415],"disallowed"],[[7416,7417],"valid"],[[7418,7423],"disallowed"],[[7424,7467],"valid"],[[7468,7468],"mapped",[97]],[[7469,7469],"mapped",[230]],[[7470,7470],"mapped",[98]],[[7471,7471],"valid"],[[7472,7472],"mapped",[100]],[[7473,7473],"mapped",[101]],[[7474,7474],"mapped",[477]],[[7475,7475],"mapped",[103]],[[7476,7476],"mapped",[104]],[[7477,7477],"mapped",[105]],[[7478,7478],"mapped",[106]],[[7479,7479],"mapped",[107]],[[7480,7480],"mapped",[108]],[[7481,7481],"mapped",[109]],[[7482,7482],"mapped",[110]],[[7483,7483],"valid"],[[7484,7484],"mapped",[111]],[[7485,7485],"mapped",[547]],[[7486,7486],"mapped",[112]],[[7487,7487],"mapped",[114]],[[7488,7488],"mapped",[116]],[[7489,7489],"mapped",[117]],[[7490,7490],"mapped",[119]],[[7491,7491],"mapped",[97]],[[7492,7492],"mapped",[592]],[[7493,7493],"mapped",[593]],[[7494,7494],"mapped",[7426]],[[7495,7495],"mapped",[98]],[[7496,7496],"mapped",[100]],[[7497,7497],"mapped",[101]],[[7498,7498],"mapped",[601]],[[7499,7499],"mapped",[603]],[[7500,7500],"mapped",[604]],[[7501,7501],"mapped",[103]],[[7502,7502],"valid"],[[7503,7503],"mapped",[107]],[[7504,7504],"mapped",[109]],[[7505,7505],"mapped",[331]],[[7506,7506],"mapped",[111]],[[7507,7507],"mapped",[596]],[[7508,7508],"mapped",[7446]],[[7509,7509],"mapped",[7447]],[[7510,7510],"mapped",[112]],[[7511,7511],"mapped",[116]],[[7512,7512],"mapped",[117]],[[7513,7513],"mapped",[7453]],[[7514,7514],"mapped",[623]],[[7515,7515],"mapped",[118]],[[7516,7516],"mapped",[7461]],[[7517,7517],"mapped",[946]],[[7518,7518],"mapped",[947]],[[7519,7519],"mapped",[948]],[[7520,7520],"mapped",[966]],[[7521,7521],"mapped",[967]],[[7522,7522],"mapped",[105]],[[7523,7523],"mapped",[114]],[[7524,7524],"mapped",[117]],[[7525,7525],"mapped",[118]],[[7526,7526],"mapped",[946]],[[7527,7527],"mapped",[947]],[[7528,7528],"mapped",[961]],[[7529,7529],"mapped",[966]],[[7530,7530],"mapped",[967]],[[7531,7531],"valid"],[[7532,7543],"valid"],[[7544,7544],"mapped",[1085]],[[7545,7578],"valid"],[[7579,7579],"mapped",[594]],[[7580,7580],"mapped",[99]],[[7581,7581],"mapped",[597]],[[7582,7582],"mapped",[240]],[[7583,7583],"mapped",[604]],[[7584,7584],"mapped",[102]],[[7585,7585],"mapped",[607]],[[7586,7586],"mapped",[609]],[[7587,7587],"mapped",[613]],[[7588,7588],"mapped",[616]],[[7589,7589],"mapped",[617]],[[7590,7590],"mapped",[618]],[[7591,7591],"mapped",[7547]],[[7592,7592],"mapped",[669]],[[7593,7593],"mapped",[621]],[[7594,7594],"mapped",[7557]],[[7595,7595],"mapped",[671]],[[7596,7596],"mapped",[625]],[[7597,7597],"mapped",[624]],[[7598,7598],"mapped",[626]],[[7599,7599],"mapped",[627]],[[7600,7600],"mapped",[628]],[[7601,7601],"mapped",[629]],[[7602,7602],"mapped",[632]],[[7603,7603],"mapped",[642]],[[7604,7604],"mapped",[643]],[[7605,7605],"mapped",[427]],[[7606,7606],"mapped",[649]],[[7607,7607],"mapped",[650]],[[7608,7608],"mapped",[7452]],[[7609,7609],"mapped",[651]],[[7610,7610],"mapped",[652]],[[7611,7611],"mapped",[122]],[[7612,7612],"mapped",[656]],[[7613,7613],"mapped",[657]],[[7614,7614],"mapped",[658]],[[7615,7615],"mapped",[952]],[[7616,7619],"valid"],[[7620,7626],"valid"],[[7627,7654],"valid"],[[7655,7669],"valid"],[[7670,7675],"disallowed"],[[7676,7676],"valid"],[[7677,7677],"valid"],[[7678,7679],"valid"],[[7680,7680],"mapped",[7681]],[[7681,7681],"valid"],[[7682,7682],"mapped",[7683]],[[7683,7683],"valid"],[[7684,7684],"mapped",[7685]],[[7685,7685],"valid"],[[7686,7686],"mapped",[7687]],[[7687,7687],"valid"],[[7688,7688],"mapped",[7689]],[[7689,7689],"valid"],[[7690,7690],"mapped",[7691]],[[7691,7691],"valid"],[[7692,7692],"mapped",[7693]],[[7693,7693],"valid"],[[7694,7694],"mapped",[7695]],[[7695,7695],"valid"],[[7696,7696],"mapped",[7697]],[[7697,7697],"valid"],[[7698,7698],"mapped",[7699]],[[7699,7699],"valid"],[[7700,7700],"mapped",[7701]],[[7701,7701],"valid"],[[7702,7702],"mapped",[7703]],[[7703,7703],"valid"],[[7704,7704],"mapped",[7705]],[[7705,7705],"valid"],[[7706,7706],"mapped",[7707]],[[7707,7707],"valid"],[[7708,7708],"mapped",[7709]],[[7709,7709],"valid"],[[7710,7710],"mapped",[7711]],[[7711,7711],"valid"],[[7712,7712],"mapped",[7713]],[[7713,7713],"valid"],[[7714,7714],"mapped",[7715]],[[7715,7715],"valid"],[[7716,7716],"mapped",[7717]],[[7717,7717],"valid"],[[7718,7718],"mapped",[7719]],[[7719,7719],"valid"],[[7720,7720],"mapped",[7721]],[[7721,7721],"valid"],[[7722,7722],"mapped",[7723]],[[7723,7723],"valid"],[[7724,7724],"mapped",[7725]],[[7725,7725],"valid"],[[7726,7726],"mapped",[7727]],[[7727,7727],"valid"],[[7728,7728],"mapped",[7729]],[[7729,7729],"valid"],[[7730,7730],"mapped",[7731]],[[7731,7731],"valid"],[[7732,7732],"mapped",[7733]],[[7733,7733],"valid"],[[7734,7734],"mapped",[7735]],[[7735,7735],"valid"],[[7736,7736],"mapped",[7737]],[[7737,7737],"valid"],[[7738,7738],"mapped",[7739]],[[7739,7739],"valid"],[[7740,7740],"mapped",[7741]],[[7741,7741],"valid"],[[7742,7742],"mapped",[7743]],[[7743,7743],"valid"],[[7744,7744],"mapped",[7745]],[[7745,7745],"valid"],[[7746,7746],"mapped",[7747]],[[7747,7747],"valid"],[[7748,7748],"mapped",[7749]],[[7749,7749],"valid"],[[7750,7750],"mapped",[7751]],[[7751,7751],"valid"],[[7752,7752],"mapped",[7753]],[[7753,7753],"valid"],[[7754,7754],"mapped",[7755]],[[7755,7755],"valid"],[[7756,7756],"mapped",[7757]],[[7757,7757],"valid"],[[7758,7758],"mapped",[7759]],[[7759,7759],"valid"],[[7760,7760],"mapped",[7761]],[[7761,7761],"valid"],[[7762,7762],"mapped",[7763]],[[7763,7763],"valid"],[[7764,7764],"mapped",[7765]],[[7765,7765],"valid"],[[7766,7766],"mapped",[7767]],[[7767,7767],"valid"],[[7768,7768],"mapped",[7769]],[[7769,7769],"valid"],[[7770,7770],"mapped",[7771]],[[7771,7771],"valid"],[[7772,7772],"mapped",[7773]],[[7773,7773],"valid"],[[7774,7774],"mapped",[7775]],[[7775,7775],"valid"],[[7776,7776],"mapped",[7777]],[[7777,7777],"valid"],[[7778,7778],"mapped",[7779]],[[7779,7779],"valid"],[[7780,7780],"mapped",[7781]],[[7781,7781],"valid"],[[7782,7782],"mapped",[7783]],[[7783,7783],"valid"],[[7784,7784],"mapped",[7785]],[[7785,7785],"valid"],[[7786,7786],"mapped",[7787]],[[7787,7787],"valid"],[[7788,7788],"mapped",[7789]],[[7789,7789],"valid"],[[7790,7790],"mapped",[7791]],[[7791,7791],"valid"],[[7792,7792],"mapped",[7793]],[[7793,7793],"valid"],[[7794,7794],"mapped",[7795]],[[7795,7795],"valid"],[[7796,7796],"mapped",[7797]],[[7797,7797],"valid"],[[7798,7798],"mapped",[7799]],[[7799,7799],"valid"],[[7800,7800],"mapped",[7801]],[[7801,7801],"valid"],[[7802,7802],"mapped",[7803]],[[7803,7803],"valid"],[[7804,7804],"mapped",[7805]],[[7805,7805],"valid"],[[7806,7806],"mapped",[7807]],[[7807,7807],"valid"],[[7808,7808],"mapped",[7809]],[[7809,7809],"valid"],[[7810,7810],"mapped",[7811]],[[7811,7811],"valid"],[[7812,7812],"mapped",[7813]],[[7813,7813],"valid"],[[7814,7814],"mapped",[7815]],[[7815,7815],"valid"],[[7816,7816],"mapped",[7817]],[[7817,7817],"valid"],[[7818,7818],"mapped",[7819]],[[7819,7819],"valid"],[[7820,7820],"mapped",[7821]],[[7821,7821],"valid"],[[7822,7822],"mapped",[7823]],[[7823,7823],"valid"],[[7824,7824],"mapped",[7825]],[[7825,7825],"valid"],[[7826,7826],"mapped",[7827]],[[7827,7827],"valid"],[[7828,7828],"mapped",[7829]],[[7829,7833],"valid"],[[7834,7834],"mapped",[97,702]],[[7835,7835],"mapped",[7777]],[[7836,7837],"valid"],[[7838,7838],"mapped",[115,115]],[[7839,7839],"valid"],[[7840,7840],"mapped",[7841]],[[7841,7841],"valid"],[[7842,7842],"mapped",[7843]],[[7843,7843],"valid"],[[7844,7844],"mapped",[7845]],[[7845,7845],"valid"],[[7846,7846],"mapped",[7847]],[[7847,7847],"valid"],[[7848,7848],"mapped",[7849]],[[7849,7849],"valid"],[[7850,7850],"mapped",[7851]],[[7851,7851],"valid"],[[7852,7852],"mapped",[7853]],[[7853,7853],"valid"],[[7854,7854],"mapped",[7855]],[[7855,7855],"valid"],[[7856,7856],"mapped",[7857]],[[7857,7857],"valid"],[[7858,7858],"mapped",[7859]],[[7859,7859],"valid"],[[7860,7860],"mapped",[7861]],[[7861,7861],"valid"],[[7862,7862],"mapped",[7863]],[[7863,7863],"valid"],[[7864,7864],"mapped",[7865]],[[7865,7865],"valid"],[[7866,7866],"mapped",[7867]],[[7867,7867],"valid"],[[7868,7868],"mapped",[7869]],[[7869,7869],"valid"],[[7870,7870],"mapped",[7871]],[[7871,7871],"valid"],[[7872,7872],"mapped",[7873]],[[7873,7873],"valid"],[[7874,7874],"mapped",[7875]],[[7875,7875],"valid"],[[7876,7876],"mapped",[7877]],[[7877,7877],"valid"],[[7878,7878],"mapped",[7879]],[[7879,7879],"valid"],[[7880,7880],"mapped",[7881]],[[7881,7881],"valid"],[[7882,7882],"mapped",[7883]],[[7883,7883],"valid"],[[7884,7884],"mapped",[7885]],[[7885,7885],"valid"],[[7886,7886],"mapped",[7887]],[[7887,7887],"valid"],[[7888,7888],"mapped",[7889]],[[7889,7889],"valid"],[[7890,7890],"mapped",[7891]],[[7891,7891],"valid"],[[7892,7892],"mapped",[7893]],[[7893,7893],"valid"],[[7894,7894],"mapped",[7895]],[[7895,7895],"valid"],[[7896,7896],"mapped",[7897]],[[7897,7897],"valid"],[[7898,7898],"mapped",[7899]],[[7899,7899],"valid"],[[7900,7900],"mapped",[7901]],[[7901,7901],"valid"],[[7902,7902],"mapped",[7903]],[[7903,7903],"valid"],[[7904,7904],"mapped",[7905]],[[7905,7905],"valid"],[[7906,7906],"mapped",[7907]],[[7907,7907],"valid"],[[7908,7908],"mapped",[7909]],[[7909,7909],"valid"],[[7910,7910],"mapped",[7911]],[[7911,7911],"valid"],[[7912,7912],"mapped",[7913]],[[7913,7913],"valid"],[[7914,7914],"mapped",[7915]],[[7915,7915],"valid"],[[7916,7916],"mapped",[7917]],[[7917,7917],"valid"],[[7918,7918],"mapped",[7919]],[[7919,7919],"valid"],[[7920,7920],"mapped",[7921]],[[7921,7921],"valid"],[[7922,7922],"mapped",[7923]],[[7923,7923],"valid"],[[7924,7924],"mapped",[7925]],[[7925,7925],"valid"],[[7926,7926],"mapped",[7927]],[[7927,7927],"valid"],[[7928,7928],"mapped",[7929]],[[7929,7929],"valid"],[[7930,7930],"mapped",[7931]],[[7931,7931],"valid"],[[7932,7932],"mapped",[7933]],[[7933,7933],"valid"],[[7934,7934],"mapped",[7935]],[[7935,7935],"valid"],[[7936,7943],"valid"],[[7944,7944],"mapped",[7936]],[[7945,7945],"mapped",[7937]],[[7946,7946],"mapped",[7938]],[[7947,7947],"mapped",[7939]],[[7948,7948],"mapped",[7940]],[[7949,7949],"mapped",[7941]],[[7950,7950],"mapped",[7942]],[[7951,7951],"mapped",[7943]],[[7952,7957],"valid"],[[7958,7959],"disallowed"],[[7960,7960],"mapped",[7952]],[[7961,7961],"mapped",[7953]],[[7962,7962],"mapped",[7954]],[[7963,7963],"mapped",[7955]],[[7964,7964],"mapped",[7956]],[[7965,7965],"mapped",[7957]],[[7966,7967],"disallowed"],[[7968,7975],"valid"],[[7976,7976],"mapped",[7968]],[[7977,7977],"mapped",[7969]],[[7978,7978],"mapped",[7970]],[[7979,7979],"mapped",[7971]],[[7980,7980],"mapped",[7972]],[[7981,7981],"mapped",[7973]],[[7982,7982],"mapped",[7974]],[[7983,7983],"mapped",[7975]],[[7984,7991],"valid"],[[7992,7992],"mapped",[7984]],[[7993,7993],"mapped",[7985]],[[7994,7994],"mapped",[7986]],[[7995,7995],"mapped",[7987]],[[7996,7996],"mapped",[7988]],[[7997,7997],"mapped",[7989]],[[7998,7998],"mapped",[7990]],[[7999,7999],"mapped",[7991]],[[8000,8005],"valid"],[[8006,8007],"disallowed"],[[8008,8008],"mapped",[8000]],[[8009,8009],"mapped",[8001]],[[8010,8010],"mapped",[8002]],[[8011,8011],"mapped",[8003]],[[8012,8012],"mapped",[8004]],[[8013,8013],"mapped",[8005]],[[8014,8015],"disallowed"],[[8016,8023],"valid"],[[8024,8024],"disallowed"],[[8025,8025],"mapped",[8017]],[[8026,8026],"disallowed"],[[8027,8027],"mapped",[8019]],[[8028,8028],"disallowed"],[[8029,8029],"mapped",[8021]],[[8030,8030],"disallowed"],[[8031,8031],"mapped",[8023]],[[8032,8039],"valid"],[[8040,8040],"mapped",[8032]],[[8041,8041],"mapped",[8033]],[[8042,8042],"mapped",[8034]],[[8043,8043],"mapped",[8035]],[[8044,8044],"mapped",[8036]],[[8045,8045],"mapped",[8037]],[[8046,8046],"mapped",[8038]],[[8047,8047],"mapped",[8039]],[[8048,8048],"valid"],[[8049,8049],"mapped",[940]],[[8050,8050],"valid"],[[8051,8051],"mapped",[941]],[[8052,8052],"valid"],[[8053,8053],"mapped",[942]],[[8054,8054],"valid"],[[8055,8055],"mapped",[943]],[[8056,8056],"valid"],[[8057,8057],"mapped",[972]],[[8058,8058],"valid"],[[8059,8059],"mapped",[973]],[[8060,8060],"valid"],[[8061,8061],"mapped",[974]],[[8062,8063],"disallowed"],[[8064,8064],"mapped",[7936,953]],[[8065,8065],"mapped",[7937,953]],[[8066,8066],"mapped",[7938,953]],[[8067,8067],"mapped",[7939,953]],[[8068,8068],"mapped",[7940,953]],[[8069,8069],"mapped",[7941,953]],[[8070,8070],"mapped",[7942,953]],[[8071,8071],"mapped",[7943,953]],[[8072,8072],"mapped",[7936,953]],[[8073,8073],"mapped",[7937,953]],[[8074,8074],"mapped",[7938,953]],[[8075,8075],"mapped",[7939,953]],[[8076,8076],"mapped",[7940,953]],[[8077,8077],"mapped",[7941,953]],[[8078,8078],"mapped",[7942,953]],[[8079,8079],"mapped",[7943,953]],[[8080,8080],"mapped",[7968,953]],[[8081,8081],"mapped",[7969,953]],[[8082,8082],"mapped",[7970,953]],[[8083,8083],"mapped",[7971,953]],[[8084,8084],"mapped",[7972,953]],[[8085,8085],"mapped",[7973,953]],[[8086,8086],"mapped",[7974,953]],[[8087,8087],"mapped",[7975,953]],[[8088,8088],"mapped",[7968,953]],[[8089,8089],"mapped",[7969,953]],[[8090,8090],"mapped",[7970,953]],[[8091,8091],"mapped",[7971,953]],[[8092,8092],"mapped",[7972,953]],[[8093,8093],"mapped",[7973,953]],[[8094,8094],"mapped",[7974,953]],[[8095,8095],"mapped",[7975,953]],[[8096,8096],"mapped",[8032,953]],[[8097,8097],"mapped",[8033,953]],[[8098,8098],"mapped",[8034,953]],[[8099,8099],"mapped",[8035,953]],[[8100,8100],"mapped",[8036,953]],[[8101,8101],"mapped",[8037,953]],[[8102,8102],"mapped",[8038,953]],[[8103,8103],"mapped",[8039,953]],[[8104,8104],"mapped",[8032,953]],[[8105,8105],"mapped",[8033,953]],[[8106,8106],"mapped",[8034,953]],[[8107,8107],"mapped",[8035,953]],[[8108,8108],"mapped",[8036,953]],[[8109,8109],"mapped",[8037,953]],[[8110,8110],"mapped",[8038,953]],[[8111,8111],"mapped",[8039,953]],[[8112,8113],"valid"],[[8114,8114],"mapped",[8048,953]],[[8115,8115],"mapped",[945,953]],[[8116,8116],"mapped",[940,953]],[[8117,8117],"disallowed"],[[8118,8118],"valid"],[[8119,8119],"mapped",[8118,953]],[[8120,8120],"mapped",[8112]],[[8121,8121],"mapped",[8113]],[[8122,8122],"mapped",[8048]],[[8123,8123],"mapped",[940]],[[8124,8124],"mapped",[945,953]],[[8125,8125],"disallowed_STD3_mapped",[32,787]],[[8126,8126],"mapped",[953]],[[8127,8127],"disallowed_STD3_mapped",[32,787]],[[8128,8128],"disallowed_STD3_mapped",[32,834]],[[8129,8129],"disallowed_STD3_mapped",[32,776,834]],[[8130,8130],"mapped",[8052,953]],[[8131,8131],"mapped",[951,953]],[[8132,8132],"mapped",[942,953]],[[8133,8133],"disallowed"],[[8134,8134],"valid"],[[8135,8135],"mapped",[8134,953]],[[8136,8136],"mapped",[8050]],[[8137,8137],"mapped",[941]],[[8138,8138],"mapped",[8052]],[[8139,8139],"mapped",[942]],[[8140,8140],"mapped",[951,953]],[[8141,8141],"disallowed_STD3_mapped",[32,787,768]],[[8142,8142],"disallowed_STD3_mapped",[32,787,769]],[[8143,8143],"disallowed_STD3_mapped",[32,787,834]],[[8144,8146],"valid"],[[8147,8147],"mapped",[912]],[[8148,8149],"disallowed"],[[8150,8151],"valid"],[[8152,8152],"mapped",[8144]],[[8153,8153],"mapped",[8145]],[[8154,8154],"mapped",[8054]],[[8155,8155],"mapped",[943]],[[8156,8156],"disallowed"],[[8157,8157],"disallowed_STD3_mapped",[32,788,768]],[[8158,8158],"disallowed_STD3_mapped",[32,788,769]],[[8159,8159],"disallowed_STD3_mapped",[32,788,834]],[[8160,8162],"valid"],[[8163,8163],"mapped",[944]],[[8164,8167],"valid"],[[8168,8168],"mapped",[8160]],[[8169,8169],"mapped",[8161]],[[8170,8170],"mapped",[8058]],[[8171,8171],"mapped",[973]],[[8172,8172],"mapped",[8165]],[[8173,8173],"disallowed_STD3_mapped",[32,776,768]],[[8174,8174],"disallowed_STD3_mapped",[32,776,769]],[[8175,8175],"disallowed_STD3_mapped",[96]],[[8176,8177],"disallowed"],[[8178,8178],"mapped",[8060,953]],[[8179,8179],"mapped",[969,953]],[[8180,8180],"mapped",[974,953]],[[8181,8181],"disallowed"],[[8182,8182],"valid"],[[8183,8183],"mapped",[8182,953]],[[8184,8184],"mapped",[8056]],[[8185,8185],"mapped",[972]],[[8186,8186],"mapped",[8060]],[[8187,8187],"mapped",[974]],[[8188,8188],"mapped",[969,953]],[[8189,8189],"disallowed_STD3_mapped",[32,769]],[[8190,8190],"disallowed_STD3_mapped",[32,788]],[[8191,8191],"disallowed"],[[8192,8202],"disallowed_STD3_mapped",[32]],[[8203,8203],"ignored"],[[8204,8205],"deviation",[]],[[8206,8207],"disallowed"],[[8208,8208],"valid",[],"NV8"],[[8209,8209],"mapped",[8208]],[[8210,8214],"valid",[],"NV8"],[[8215,8215],"disallowed_STD3_mapped",[32,819]],[[8216,8227],"valid",[],"NV8"],[[8228,8230],"disallowed"],[[8231,8231],"valid",[],"NV8"],[[8232,8238],"disallowed"],[[8239,8239],"disallowed_STD3_mapped",[32]],[[8240,8242],"valid",[],"NV8"],[[8243,8243],"mapped",[8242,8242]],[[8244,8244],"mapped",[8242,8242,8242]],[[8245,8245],"valid",[],"NV8"],[[8246,8246],"mapped",[8245,8245]],[[8247,8247],"mapped",[8245,8245,8245]],[[8248,8251],"valid",[],"NV8"],[[8252,8252],"disallowed_STD3_mapped",[33,33]],[[8253,8253],"valid",[],"NV8"],[[8254,8254],"disallowed_STD3_mapped",[32,773]],[[8255,8262],"valid",[],"NV8"],[[8263,8263],"disallowed_STD3_mapped",[63,63]],[[8264,8264],"disallowed_STD3_mapped",[63,33]],[[8265,8265],"disallowed_STD3_mapped",[33,63]],[[8266,8269],"valid",[],"NV8"],[[8270,8274],"valid",[],"NV8"],[[8275,8276],"valid",[],"NV8"],[[8277,8278],"valid",[],"NV8"],[[8279,8279],"mapped",[8242,8242,8242,8242]],[[8280,8286],"valid",[],"NV8"],[[8287,8287],"disallowed_STD3_mapped",[32]],[[8288,8288],"ignored"],[[8289,8291],"disallowed"],[[8292,8292],"ignored"],[[8293,8293],"disallowed"],[[8294,8297],"disallowed"],[[8298,8303],"disallowed"],[[8304,8304],"mapped",[48]],[[8305,8305],"mapped",[105]],[[8306,8307],"disallowed"],[[8308,8308],"mapped",[52]],[[8309,8309],"mapped",[53]],[[8310,8310],"mapped",[54]],[[8311,8311],"mapped",[55]],[[8312,8312],"mapped",[56]],[[8313,8313],"mapped",[57]],[[8314,8314],"disallowed_STD3_mapped",[43]],[[8315,8315],"mapped",[8722]],[[8316,8316],"disallowed_STD3_mapped",[61]],[[8317,8317],"disallowed_STD3_mapped",[40]],[[8318,8318],"disallowed_STD3_mapped",[41]],[[8319,8319],"mapped",[110]],[[8320,8320],"mapped",[48]],[[8321,8321],"mapped",[49]],[[8322,8322],"mapped",[50]],[[8323,8323],"mapped",[51]],[[8324,8324],"mapped",[52]],[[8325,8325],"mapped",[53]],[[8326,8326],"mapped",[54]],[[8327,8327],"mapped",[55]],[[8328,8328],"mapped",[56]],[[8329,8329],"mapped",[57]],[[8330,8330],"disallowed_STD3_mapped",[43]],[[8331,8331],"mapped",[8722]],[[8332,8332],"disallowed_STD3_mapped",[61]],[[8333,8333],"disallowed_STD3_mapped",[40]],[[8334,8334],"disallowed_STD3_mapped",[41]],[[8335,8335],"disallowed"],[[8336,8336],"mapped",[97]],[[8337,8337],"mapped",[101]],[[8338,8338],"mapped",[111]],[[8339,8339],"mapped",[120]],[[8340,8340],"mapped",[601]],[[8341,8341],"mapped",[104]],[[8342,8342],"mapped",[107]],[[8343,8343],"mapped",[108]],[[8344,8344],"mapped",[109]],[[8345,8345],"mapped",[110]],[[8346,8346],"mapped",[112]],[[8347,8347],"mapped",[115]],[[8348,8348],"mapped",[116]],[[8349,8351],"disallowed"],[[8352,8359],"valid",[],"NV8"],[[8360,8360],"mapped",[114,115]],[[8361,8362],"valid",[],"NV8"],[[8363,8363],"valid",[],"NV8"],[[8364,8364],"valid",[],"NV8"],[[8365,8367],"valid",[],"NV8"],[[8368,8369],"valid",[],"NV8"],[[8370,8373],"valid",[],"NV8"],[[8374,8376],"valid",[],"NV8"],[[8377,8377],"valid",[],"NV8"],[[8378,8378],"valid",[],"NV8"],[[8379,8381],"valid",[],"NV8"],[[8382,8382],"valid",[],"NV8"],[[8383,8399],"disallowed"],[[8400,8417],"valid",[],"NV8"],[[8418,8419],"valid",[],"NV8"],[[8420,8426],"valid",[],"NV8"],[[8427,8427],"valid",[],"NV8"],[[8428,8431],"valid",[],"NV8"],[[8432,8432],"valid",[],"NV8"],[[8433,8447],"disallowed"],[[8448,8448],"disallowed_STD3_mapped",[97,47,99]],[[8449,8449],"disallowed_STD3_mapped",[97,47,115]],[[8450,8450],"mapped",[99]],[[8451,8451],"mapped",[176,99]],[[8452,8452],"valid",[],"NV8"],[[8453,8453],"disallowed_STD3_mapped",[99,47,111]],[[8454,8454],"disallowed_STD3_mapped",[99,47,117]],[[8455,8455],"mapped",[603]],[[8456,8456],"valid",[],"NV8"],[[8457,8457],"mapped",[176,102]],[[8458,8458],"mapped",[103]],[[8459,8462],"mapped",[104]],[[8463,8463],"mapped",[295]],[[8464,8465],"mapped",[105]],[[8466,8467],"mapped",[108]],[[8468,8468],"valid",[],"NV8"],[[8469,8469],"mapped",[110]],[[8470,8470],"mapped",[110,111]],[[8471,8472],"valid",[],"NV8"],[[8473,8473],"mapped",[112]],[[8474,8474],"mapped",[113]],[[8475,8477],"mapped",[114]],[[8478,8479],"valid",[],"NV8"],[[8480,8480],"mapped",[115,109]],[[8481,8481],"mapped",[116,101,108]],[[8482,8482],"mapped",[116,109]],[[8483,8483],"valid",[],"NV8"],[[8484,8484],"mapped",[122]],[[8485,8485],"valid",[],"NV8"],[[8486,8486],"mapped",[969]],[[8487,8487],"valid",[],"NV8"],[[8488,8488],"mapped",[122]],[[8489,8489],"valid",[],"NV8"],[[8490,8490],"mapped",[107]],[[8491,8491],"mapped",[229]],[[8492,8492],"mapped",[98]],[[8493,8493],"mapped",[99]],[[8494,8494],"valid",[],"NV8"],[[8495,8496],"mapped",[101]],[[8497,8497],"mapped",[102]],[[8498,8498],"disallowed"],[[8499,8499],"mapped",[109]],[[8500,8500],"mapped",[111]],[[8501,8501],"mapped",[1488]],[[8502,8502],"mapped",[1489]],[[8503,8503],"mapped",[1490]],[[8504,8504],"mapped",[1491]],[[8505,8505],"mapped",[105]],[[8506,8506],"valid",[],"NV8"],[[8507,8507],"mapped",[102,97,120]],[[8508,8508],"mapped",[960]],[[8509,8510],"mapped",[947]],[[8511,8511],"mapped",[960]],[[8512,8512],"mapped",[8721]],[[8513,8516],"valid",[],"NV8"],[[8517,8518],"mapped",[100]],[[8519,8519],"mapped",[101]],[[8520,8520],"mapped",[105]],[[8521,8521],"mapped",[106]],[[8522,8523],"valid",[],"NV8"],[[8524,8524],"valid",[],"NV8"],[[8525,8525],"valid",[],"NV8"],[[8526,8526],"valid"],[[8527,8527],"valid",[],"NV8"],[[8528,8528],"mapped",[49,8260,55]],[[8529,8529],"mapped",[49,8260,57]],[[8530,8530],"mapped",[49,8260,49,48]],[[8531,8531],"mapped",[49,8260,51]],[[8532,8532],"mapped",[50,8260,51]],[[8533,8533],"mapped",[49,8260,53]],[[8534,8534],"mapped",[50,8260,53]],[[8535,8535],"mapped",[51,8260,53]],[[8536,8536],"mapped",[52,8260,53]],[[8537,8537],"mapped",[49,8260,54]],[[8538,8538],"mapped",[53,8260,54]],[[8539,8539],"mapped",[49,8260,56]],[[8540,8540],"mapped",[51,8260,56]],[[8541,8541],"mapped",[53,8260,56]],[[8542,8542],"mapped",[55,8260,56]],[[8543,8543],"mapped",[49,8260]],[[8544,8544],"mapped",[105]],[[8545,8545],"mapped",[105,105]],[[8546,8546],"mapped",[105,105,105]],[[8547,8547],"mapped",[105,118]],[[8548,8548],"mapped",[118]],[[8549,8549],"mapped",[118,105]],[[8550,8550],"mapped",[118,105,105]],[[8551,8551],"mapped",[118,105,105,105]],[[8552,8552],"mapped",[105,120]],[[8553,8553],"mapped",[120]],[[8554,8554],"mapped",[120,105]],[[8555,8555],"mapped",[120,105,105]],[[8556,8556],"mapped",[108]],[[8557,8557],"mapped",[99]],[[8558,8558],"mapped",[100]],[[8559,8559],"mapped",[109]],[[8560,8560],"mapped",[105]],[[8561,8561],"mapped",[105,105]],[[8562,8562],"mapped",[105,105,105]],[[8563,8563],"mapped",[105,118]],[[8564,8564],"mapped",[118]],[[8565,8565],"mapped",[118,105]],[[8566,8566],"mapped",[118,105,105]],[[8567,8567],"mapped",[118,105,105,105]],[[8568,8568],"mapped",[105,120]],[[8569,8569],"mapped",[120]],[[8570,8570],"mapped",[120,105]],[[8571,8571],"mapped",[120,105,105]],[[8572,8572],"mapped",[108]],[[8573,8573],"mapped",[99]],[[8574,8574],"mapped",[100]],[[8575,8575],"mapped",[109]],[[8576,8578],"valid",[],"NV8"],[[8579,8579],"disallowed"],[[8580,8580],"valid"],[[8581,8584],"valid",[],"NV8"],[[8585,8585],"mapped",[48,8260,51]],[[8586,8587],"valid",[],"NV8"],[[8588,8591],"disallowed"],[[8592,8682],"valid",[],"NV8"],[[8683,8691],"valid",[],"NV8"],[[8692,8703],"valid",[],"NV8"],[[8704,8747],"valid",[],"NV8"],[[8748,8748],"mapped",[8747,8747]],[[8749,8749],"mapped",[8747,8747,8747]],[[8750,8750],"valid",[],"NV8"],[[8751,8751],"mapped",[8750,8750]],[[8752,8752],"mapped",[8750,8750,8750]],[[8753,8799],"valid",[],"NV8"],[[8800,8800],"disallowed_STD3_valid"],[[8801,8813],"valid",[],"NV8"],[[8814,8815],"disallowed_STD3_valid"],[[8816,8945],"valid",[],"NV8"],[[8946,8959],"valid",[],"NV8"],[[8960,8960],"valid",[],"NV8"],[[8961,8961],"valid",[],"NV8"],[[8962,9000],"valid",[],"NV8"],[[9001,9001],"mapped",[12296]],[[9002,9002],"mapped",[12297]],[[9003,9082],"valid",[],"NV8"],[[9083,9083],"valid",[],"NV8"],[[9084,9084],"valid",[],"NV8"],[[9085,9114],"valid",[],"NV8"],[[9115,9166],"valid",[],"NV8"],[[9167,9168],"valid",[],"NV8"],[[9169,9179],"valid",[],"NV8"],[[9180,9191],"valid",[],"NV8"],[[9192,9192],"valid",[],"NV8"],[[9193,9203],"valid",[],"NV8"],[[9204,9210],"valid",[],"NV8"],[[9211,9215],"disallowed"],[[9216,9252],"valid",[],"NV8"],[[9253,9254],"valid",[],"NV8"],[[9255,9279],"disallowed"],[[9280,9290],"valid",[],"NV8"],[[9291,9311],"disallowed"],[[9312,9312],"mapped",[49]],[[9313,9313],"mapped",[50]],[[9314,9314],"mapped",[51]],[[9315,9315],"mapped",[52]],[[9316,9316],"mapped",[53]],[[9317,9317],"mapped",[54]],[[9318,9318],"mapped",[55]],[[9319,9319],"mapped",[56]],[[9320,9320],"mapped",[57]],[[9321,9321],"mapped",[49,48]],[[9322,9322],"mapped",[49,49]],[[9323,9323],"mapped",[49,50]],[[9324,9324],"mapped",[49,51]],[[9325,9325],"mapped",[49,52]],[[9326,9326],"mapped",[49,53]],[[9327,9327],"mapped",[49,54]],[[9328,9328],"mapped",[49,55]],[[9329,9329],"mapped",[49,56]],[[9330,9330],"mapped",[49,57]],[[9331,9331],"mapped",[50,48]],[[9332,9332],"disallowed_STD3_mapped",[40,49,41]],[[9333,9333],"disallowed_STD3_mapped",[40,50,41]],[[9334,9334],"disallowed_STD3_mapped",[40,51,41]],[[9335,9335],"disallowed_STD3_mapped",[40,52,41]],[[9336,9336],"disallowed_STD3_mapped",[40,53,41]],[[9337,9337],"disallowed_STD3_mapped",[40,54,41]],[[9338,9338],"disallowed_STD3_mapped",[40,55,41]],[[9339,9339],"disallowed_STD3_mapped",[40,56,41]],[[9340,9340],"disallowed_STD3_mapped",[40,57,41]],[[9341,9341],"disallowed_STD3_mapped",[40,49,48,41]],[[9342,9342],"disallowed_STD3_mapped",[40,49,49,41]],[[9343,9343],"disallowed_STD3_mapped",[40,49,50,41]],[[9344,9344],"disallowed_STD3_mapped",[40,49,51,41]],[[9345,9345],"disallowed_STD3_mapped",[40,49,52,41]],[[9346,9346],"disallowed_STD3_mapped",[40,49,53,41]],[[9347,9347],"disallowed_STD3_mapped",[40,49,54,41]],[[9348,9348],"disallowed_STD3_mapped",[40,49,55,41]],[[9349,9349],"disallowed_STD3_mapped",[40,49,56,41]],[[9350,9350],"disallowed_STD3_mapped",[40,49,57,41]],[[9351,9351],"disallowed_STD3_mapped",[40,50,48,41]],[[9352,9371],"disallowed"],[[9372,9372],"disallowed_STD3_mapped",[40,97,41]],[[9373,9373],"disallowed_STD3_mapped",[40,98,41]],[[9374,9374],"disallowed_STD3_mapped",[40,99,41]],[[9375,9375],"disallowed_STD3_mapped",[40,100,41]],[[9376,9376],"disallowed_STD3_mapped",[40,101,41]],[[9377,9377],"disallowed_STD3_mapped",[40,102,41]],[[9378,9378],"disallowed_STD3_mapped",[40,103,41]],[[9379,9379],"disallowed_STD3_mapped",[40,104,41]],[[9380,9380],"disallowed_STD3_mapped",[40,105,41]],[[9381,9381],"disallowed_STD3_mapped",[40,106,41]],[[9382,9382],"disallowed_STD3_mapped",[40,107,41]],[[9383,9383],"disallowed_STD3_mapped",[40,108,41]],[[9384,9384],"disallowed_STD3_mapped",[40,109,41]],[[9385,9385],"disallowed_STD3_mapped",[40,110,41]],[[9386,9386],"disallowed_STD3_mapped",[40,111,41]],[[9387,9387],"disallowed_STD3_mapped",[40,112,41]],[[9388,9388],"disallowed_STD3_mapped",[40,113,41]],[[9389,9389],"disallowed_STD3_mapped",[40,114,41]],[[9390,9390],"disallowed_STD3_mapped",[40,115,41]],[[9391,9391],"disallowed_STD3_mapped",[40,116,41]],[[9392,9392],"disallowed_STD3_mapped",[40,117,41]],[[9393,9393],"disallowed_STD3_mapped",[40,118,41]],[[9394,9394],"disallowed_STD3_mapped",[40,119,41]],[[9395,9395],"disallowed_STD3_mapped",[40,120,41]],[[9396,9396],"disallowed_STD3_mapped",[40,121,41]],[[9397,9397],"disallowed_STD3_mapped",[40,122,41]],[[9398,9398],"mapped",[97]],[[9399,9399],"mapped",[98]],[[9400,9400],"mapped",[99]],[[9401,9401],"mapped",[100]],[[9402,9402],"mapped",[101]],[[9403,9403],"mapped",[102]],[[9404,9404],"mapped",[103]],[[9405,9405],"mapped",[104]],[[9406,9406],"mapped",[105]],[[9407,9407],"mapped",[106]],[[9408,9408],"mapped",[107]],[[9409,9409],"mapped",[108]],[[9410,9410],"mapped",[109]],[[9411,9411],"mapped",[110]],[[9412,9412],"mapped",[111]],[[9413,9413],"mapped",[112]],[[9414,9414],"mapped",[113]],[[9415,9415],"mapped",[114]],[[9416,9416],"mapped",[115]],[[9417,9417],"mapped",[116]],[[9418,9418],"mapped",[117]],[[9419,9419],"mapped",[118]],[[9420,9420],"mapped",[119]],[[9421,9421],"mapped",[120]],[[9422,9422],"mapped",[121]],[[9423,9423],"mapped",[122]],[[9424,9424],"mapped",[97]],[[9425,9425],"mapped",[98]],[[9426,9426],"mapped",[99]],[[9427,9427],"mapped",[100]],[[9428,9428],"mapped",[101]],[[9429,9429],"mapped",[102]],[[9430,9430],"mapped",[103]],[[9431,9431],"mapped",[104]],[[9432,9432],"mapped",[105]],[[9433,9433],"mapped",[106]],[[9434,9434],"mapped",[107]],[[9435,9435],"mapped",[108]],[[9436,9436],"mapped",[109]],[[9437,9437],"mapped",[110]],[[9438,9438],"mapped",[111]],[[9439,9439],"mapped",[112]],[[9440,9440],"mapped",[113]],[[9441,9441],"mapped",[114]],[[9442,9442],"mapped",[115]],[[9443,9443],"mapped",[116]],[[9444,9444],"mapped",[117]],[[9445,9445],"mapped",[118]],[[9446,9446],"mapped",[119]],[[9447,9447],"mapped",[120]],[[9448,9448],"mapped",[121]],[[9449,9449],"mapped",[122]],[[9450,9450],"mapped",[48]],[[9451,9470],"valid",[],"NV8"],[[9471,9471],"valid",[],"NV8"],[[9472,9621],"valid",[],"NV8"],[[9622,9631],"valid",[],"NV8"],[[9632,9711],"valid",[],"NV8"],[[9712,9719],"valid",[],"NV8"],[[9720,9727],"valid",[],"NV8"],[[9728,9747],"valid",[],"NV8"],[[9748,9749],"valid",[],"NV8"],[[9750,9751],"valid",[],"NV8"],[[9752,9752],"valid",[],"NV8"],[[9753,9753],"valid",[],"NV8"],[[9754,9839],"valid",[],"NV8"],[[9840,9841],"valid",[],"NV8"],[[9842,9853],"valid",[],"NV8"],[[9854,9855],"valid",[],"NV8"],[[9856,9865],"valid",[],"NV8"],[[9866,9873],"valid",[],"NV8"],[[9874,9884],"valid",[],"NV8"],[[9885,9885],"valid",[],"NV8"],[[9886,9887],"valid",[],"NV8"],[[9888,9889],"valid",[],"NV8"],[[9890,9905],"valid",[],"NV8"],[[9906,9906],"valid",[],"NV8"],[[9907,9916],"valid",[],"NV8"],[[9917,9919],"valid",[],"NV8"],[[9920,9923],"valid",[],"NV8"],[[9924,9933],"valid",[],"NV8"],[[9934,9934],"valid",[],"NV8"],[[9935,9953],"valid",[],"NV8"],[[9954,9954],"valid",[],"NV8"],[[9955,9955],"valid",[],"NV8"],[[9956,9959],"valid",[],"NV8"],[[9960,9983],"valid",[],"NV8"],[[9984,9984],"valid",[],"NV8"],[[9985,9988],"valid",[],"NV8"],[[9989,9989],"valid",[],"NV8"],[[9990,9993],"valid",[],"NV8"],[[9994,9995],"valid",[],"NV8"],[[9996,10023],"valid",[],"NV8"],[[10024,10024],"valid",[],"NV8"],[[10025,10059],"valid",[],"NV8"],[[10060,10060],"valid",[],"NV8"],[[10061,10061],"valid",[],"NV8"],[[10062,10062],"valid",[],"NV8"],[[10063,10066],"valid",[],"NV8"],[[10067,10069],"valid",[],"NV8"],[[10070,10070],"valid",[],"NV8"],[[10071,10071],"valid",[],"NV8"],[[10072,10078],"valid",[],"NV8"],[[10079,10080],"valid",[],"NV8"],[[10081,10087],"valid",[],"NV8"],[[10088,10101],"valid",[],"NV8"],[[10102,10132],"valid",[],"NV8"],[[10133,10135],"valid",[],"NV8"],[[10136,10159],"valid",[],"NV8"],[[10160,10160],"valid",[],"NV8"],[[10161,10174],"valid",[],"NV8"],[[10175,10175],"valid",[],"NV8"],[[10176,10182],"valid",[],"NV8"],[[10183,10186],"valid",[],"NV8"],[[10187,10187],"valid",[],"NV8"],[[10188,10188],"valid",[],"NV8"],[[10189,10189],"valid",[],"NV8"],[[10190,10191],"valid",[],"NV8"],[[10192,10219],"valid",[],"NV8"],[[10220,10223],"valid",[],"NV8"],[[10224,10239],"valid",[],"NV8"],[[10240,10495],"valid",[],"NV8"],[[10496,10763],"valid",[],"NV8"],[[10764,10764],"mapped",[8747,8747,8747,8747]],[[10765,10867],"valid",[],"NV8"],[[10868,10868],"disallowed_STD3_mapped",[58,58,61]],[[10869,10869],"disallowed_STD3_mapped",[61,61]],[[10870,10870],"disallowed_STD3_mapped",[61,61,61]],[[10871,10971],"valid",[],"NV8"],[[10972,10972],"mapped",[10973,824]],[[10973,11007],"valid",[],"NV8"],[[11008,11021],"valid",[],"NV8"],[[11022,11027],"valid",[],"NV8"],[[11028,11034],"valid",[],"NV8"],[[11035,11039],"valid",[],"NV8"],[[11040,11043],"valid",[],"NV8"],[[11044,11084],"valid",[],"NV8"],[[11085,11087],"valid",[],"NV8"],[[11088,11092],"valid",[],"NV8"],[[11093,11097],"valid",[],"NV8"],[[11098,11123],"valid",[],"NV8"],[[11124,11125],"disallowed"],[[11126,11157],"valid",[],"NV8"],[[11158,11159],"disallowed"],[[11160,11193],"valid",[],"NV8"],[[11194,11196],"disallowed"],[[11197,11208],"valid",[],"NV8"],[[11209,11209],"disallowed"],[[11210,11217],"valid",[],"NV8"],[[11218,11243],"disallowed"],[[11244,11247],"valid",[],"NV8"],[[11248,11263],"disallowed"],[[11264,11264],"mapped",[11312]],[[11265,11265],"mapped",[11313]],[[11266,11266],"mapped",[11314]],[[11267,11267],"mapped",[11315]],[[11268,11268],"mapped",[11316]],[[11269,11269],"mapped",[11317]],[[11270,11270],"mapped",[11318]],[[11271,11271],"mapped",[11319]],[[11272,11272],"mapped",[11320]],[[11273,11273],"mapped",[11321]],[[11274,11274],"mapped",[11322]],[[11275,11275],"mapped",[11323]],[[11276,11276],"mapped",[11324]],[[11277,11277],"mapped",[11325]],[[11278,11278],"mapped",[11326]],[[11279,11279],"mapped",[11327]],[[11280,11280],"mapped",[11328]],[[11281,11281],"mapped",[11329]],[[11282,11282],"mapped",[11330]],[[11283,11283],"mapped",[11331]],[[11284,11284],"mapped",[11332]],[[11285,11285],"mapped",[11333]],[[11286,11286],"mapped",[11334]],[[11287,11287],"mapped",[11335]],[[11288,11288],"mapped",[11336]],[[11289,11289],"mapped",[11337]],[[11290,11290],"mapped",[11338]],[[11291,11291],"mapped",[11339]],[[11292,11292],"mapped",[11340]],[[11293,11293],"mapped",[11341]],[[11294,11294],"mapped",[11342]],[[11295,11295],"mapped",[11343]],[[11296,11296],"mapped",[11344]],[[11297,11297],"mapped",[11345]],[[11298,11298],"mapped",[11346]],[[11299,11299],"mapped",[11347]],[[11300,11300],"mapped",[11348]],[[11301,11301],"mapped",[11349]],[[11302,11302],"mapped",[11350]],[[11303,11303],"mapped",[11351]],[[11304,11304],"mapped",[11352]],[[11305,11305],"mapped",[11353]],[[11306,11306],"mapped",[11354]],[[11307,11307],"mapped",[11355]],[[11308,11308],"mapped",[11356]],[[11309,11309],"mapped",[11357]],[[11310,11310],"mapped",[11358]],[[11311,11311],"disallowed"],[[11312,11358],"valid"],[[11359,11359],"disallowed"],[[11360,11360],"mapped",[11361]],[[11361,11361],"valid"],[[11362,11362],"mapped",[619]],[[11363,11363],"mapped",[7549]],[[11364,11364],"mapped",[637]],[[11365,11366],"valid"],[[11367,11367],"mapped",[11368]],[[11368,11368],"valid"],[[11369,11369],"mapped",[11370]],[[11370,11370],"valid"],[[11371,11371],"mapped",[11372]],[[11372,11372],"valid"],[[11373,11373],"mapped",[593]],[[11374,11374],"mapped",[625]],[[11375,11375],"mapped",[592]],[[11376,11376],"mapped",[594]],[[11377,11377],"valid"],[[11378,11378],"mapped",[11379]],[[11379,11379],"valid"],[[11380,11380],"valid"],[[11381,11381],"mapped",[11382]],[[11382,11383],"valid"],[[11384,11387],"valid"],[[11388,11388],"mapped",[106]],[[11389,11389],"mapped",[118]],[[11390,11390],"mapped",[575]],[[11391,11391],"mapped",[576]],[[11392,11392],"mapped",[11393]],[[11393,11393],"valid"],[[11394,11394],"mapped",[11395]],[[11395,11395],"valid"],[[11396,11396],"mapped",[11397]],[[11397,11397],"valid"],[[11398,11398],"mapped",[11399]],[[11399,11399],"valid"],[[11400,11400],"mapped",[11401]],[[11401,11401],"valid"],[[11402,11402],"mapped",[11403]],[[11403,11403],"valid"],[[11404,11404],"mapped",[11405]],[[11405,11405],"valid"],[[11406,11406],"mapped",[11407]],[[11407,11407],"valid"],[[11408,11408],"mapped",[11409]],[[11409,11409],"valid"],[[11410,11410],"mapped",[11411]],[[11411,11411],"valid"],[[11412,11412],"mapped",[11413]],[[11413,11413],"valid"],[[11414,11414],"mapped",[11415]],[[11415,11415],"valid"],[[11416,11416],"mapped",[11417]],[[11417,11417],"valid"],[[11418,11418],"mapped",[11419]],[[11419,11419],"valid"],[[11420,11420],"mapped",[11421]],[[11421,11421],"valid"],[[11422,11422],"mapped",[11423]],[[11423,11423],"valid"],[[11424,11424],"mapped",[11425]],[[11425,11425],"valid"],[[11426,11426],"mapped",[11427]],[[11427,11427],"valid"],[[11428,11428],"mapped",[11429]],[[11429,11429],"valid"],[[11430,11430],"mapped",[11431]],[[11431,11431],"valid"],[[11432,11432],"mapped",[11433]],[[11433,11433],"valid"],[[11434,11434],"mapped",[11435]],[[11435,11435],"valid"],[[11436,11436],"mapped",[11437]],[[11437,11437],"valid"],[[11438,11438],"mapped",[11439]],[[11439,11439],"valid"],[[11440,11440],"mapped",[11441]],[[11441,11441],"valid"],[[11442,11442],"mapped",[11443]],[[11443,11443],"valid"],[[11444,11444],"mapped",[11445]],[[11445,11445],"valid"],[[11446,11446],"mapped",[11447]],[[11447,11447],"valid"],[[11448,11448],"mapped",[11449]],[[11449,11449],"valid"],[[11450,11450],"mapped",[11451]],[[11451,11451],"valid"],[[11452,11452],"mapped",[11453]],[[11453,11453],"valid"],[[11454,11454],"mapped",[11455]],[[11455,11455],"valid"],[[11456,11456],"mapped",[11457]],[[11457,11457],"valid"],[[11458,11458],"mapped",[11459]],[[11459,11459],"valid"],[[11460,11460],"mapped",[11461]],[[11461,11461],"valid"],[[11462,11462],"mapped",[11463]],[[11463,11463],"valid"],[[11464,11464],"mapped",[11465]],[[11465,11465],"valid"],[[11466,11466],"mapped",[11467]],[[11467,11467],"valid"],[[11468,11468],"mapped",[11469]],[[11469,11469],"valid"],[[11470,11470],"mapped",[11471]],[[11471,11471],"valid"],[[11472,11472],"mapped",[11473]],[[11473,11473],"valid"],[[11474,11474],"mapped",[11475]],[[11475,11475],"valid"],[[11476,11476],"mapped",[11477]],[[11477,11477],"valid"],[[11478,11478],"mapped",[11479]],[[11479,11479],"valid"],[[11480,11480],"mapped",[11481]],[[11481,11481],"valid"],[[11482,11482],"mapped",[11483]],[[11483,11483],"valid"],[[11484,11484],"mapped",[11485]],[[11485,11485],"valid"],[[11486,11486],"mapped",[11487]],[[11487,11487],"valid"],[[11488,11488],"mapped",[11489]],[[11489,11489],"valid"],[[11490,11490],"mapped",[11491]],[[11491,11492],"valid"],[[11493,11498],"valid",[],"NV8"],[[11499,11499],"mapped",[11500]],[[11500,11500],"valid"],[[11501,11501],"mapped",[11502]],[[11502,11505],"valid"],[[11506,11506],"mapped",[11507]],[[11507,11507],"valid"],[[11508,11512],"disallowed"],[[11513,11519],"valid",[],"NV8"],[[11520,11557],"valid"],[[11558,11558],"disallowed"],[[11559,11559],"valid"],[[11560,11564],"disallowed"],[[11565,11565],"valid"],[[11566,11567],"disallowed"],[[11568,11621],"valid"],[[11622,11623],"valid"],[[11624,11630],"disallowed"],[[11631,11631],"mapped",[11617]],[[11632,11632],"valid",[],"NV8"],[[11633,11646],"disallowed"],[[11647,11647],"valid"],[[11648,11670],"valid"],[[11671,11679],"disallowed"],[[11680,11686],"valid"],[[11687,11687],"disallowed"],[[11688,11694],"valid"],[[11695,11695],"disallowed"],[[11696,11702],"valid"],[[11703,11703],"disallowed"],[[11704,11710],"valid"],[[11711,11711],"disallowed"],[[11712,11718],"valid"],[[11719,11719],"disallowed"],[[11720,11726],"valid"],[[11727,11727],"disallowed"],[[11728,11734],"valid"],[[11735,11735],"disallowed"],[[11736,11742],"valid"],[[11743,11743],"disallowed"],[[11744,11775],"valid"],[[11776,11799],"valid",[],"NV8"],[[11800,11803],"valid",[],"NV8"],[[11804,11805],"valid",[],"NV8"],[[11806,11822],"valid",[],"NV8"],[[11823,11823],"valid"],[[11824,11824],"valid",[],"NV8"],[[11825,11825],"valid",[],"NV8"],[[11826,11835],"valid",[],"NV8"],[[11836,11842],"valid",[],"NV8"],[[11843,11903],"disallowed"],[[11904,11929],"valid",[],"NV8"],[[11930,11930],"disallowed"],[[11931,11934],"valid",[],"NV8"],[[11935,11935],"mapped",[27597]],[[11936,12018],"valid",[],"NV8"],[[12019,12019],"mapped",[40863]],[[12020,12031],"disallowed"],[[12032,12032],"mapped",[19968]],[[12033,12033],"mapped",[20008]],[[12034,12034],"mapped",[20022]],[[12035,12035],"mapped",[20031]],[[12036,12036],"mapped",[20057]],[[12037,12037],"mapped",[20101]],[[12038,12038],"mapped",[20108]],[[12039,12039],"mapped",[20128]],[[12040,12040],"mapped",[20154]],[[12041,12041],"mapped",[20799]],[[12042,12042],"mapped",[20837]],[[12043,12043],"mapped",[20843]],[[12044,12044],"mapped",[20866]],[[12045,12045],"mapped",[20886]],[[12046,12046],"mapped",[20907]],[[12047,12047],"mapped",[20960]],[[12048,12048],"mapped",[20981]],[[12049,12049],"mapped",[20992]],[[12050,12050],"mapped",[21147]],[[12051,12051],"mapped",[21241]],[[12052,12052],"mapped",[21269]],[[12053,12053],"mapped",[21274]],[[12054,12054],"mapped",[21304]],[[12055,12055],"mapped",[21313]],[[12056,12056],"mapped",[21340]],[[12057,12057],"mapped",[21353]],[[12058,12058],"mapped",[21378]],[[12059,12059],"mapped",[21430]],[[12060,12060],"mapped",[21448]],[[12061,12061],"mapped",[21475]],[[12062,12062],"mapped",[22231]],[[12063,12063],"mapped",[22303]],[[12064,12064],"mapped",[22763]],[[12065,12065],"mapped",[22786]],[[12066,12066],"mapped",[22794]],[[12067,12067],"mapped",[22805]],[[12068,12068],"mapped",[22823]],[[12069,12069],"mapped",[22899]],[[12070,12070],"mapped",[23376]],[[12071,12071],"mapped",[23424]],[[12072,12072],"mapped",[23544]],[[12073,12073],"mapped",[23567]],[[12074,12074],"mapped",[23586]],[[12075,12075],"mapped",[23608]],[[12076,12076],"mapped",[23662]],[[12077,12077],"mapped",[23665]],[[12078,12078],"mapped",[24027]],[[12079,12079],"mapped",[24037]],[[12080,12080],"mapped",[24049]],[[12081,12081],"mapped",[24062]],[[12082,12082],"mapped",[24178]],[[12083,12083],"mapped",[24186]],[[12084,12084],"mapped",[24191]],[[12085,12085],"mapped",[24308]],[[12086,12086],"mapped",[24318]],[[12087,12087],"mapped",[24331]],[[12088,12088],"mapped",[24339]],[[12089,12089],"mapped",[24400]],[[12090,12090],"mapped",[24417]],[[12091,12091],"mapped",[24435]],[[12092,12092],"mapped",[24515]],[[12093,12093],"mapped",[25096]],[[12094,12094],"mapped",[25142]],[[12095,12095],"mapped",[25163]],[[12096,12096],"mapped",[25903]],[[12097,12097],"mapped",[25908]],[[12098,12098],"mapped",[25991]],[[12099,12099],"mapped",[26007]],[[12100,12100],"mapped",[26020]],[[12101,12101],"mapped",[26041]],[[12102,12102],"mapped",[26080]],[[12103,12103],"mapped",[26085]],[[12104,12104],"mapped",[26352]],[[12105,12105],"mapped",[26376]],[[12106,12106],"mapped",[26408]],[[12107,12107],"mapped",[27424]],[[12108,12108],"mapped",[27490]],[[12109,12109],"mapped",[27513]],[[12110,12110],"mapped",[27571]],[[12111,12111],"mapped",[27595]],[[12112,12112],"mapped",[27604]],[[12113,12113],"mapped",[27611]],[[12114,12114],"mapped",[27663]],[[12115,12115],"mapped",[27668]],[[12116,12116],"mapped",[27700]],[[12117,12117],"mapped",[28779]],[[12118,12118],"mapped",[29226]],[[12119,12119],"mapped",[29238]],[[12120,12120],"mapped",[29243]],[[12121,12121],"mapped",[29247]],[[12122,12122],"mapped",[29255]],[[12123,12123],"mapped",[29273]],[[12124,12124],"mapped",[29275]],[[12125,12125],"mapped",[29356]],[[12126,12126],"mapped",[29572]],[[12127,12127],"mapped",[29577]],[[12128,12128],"mapped",[29916]],[[12129,12129],"mapped",[29926]],[[12130,12130],"mapped",[29976]],[[12131,12131],"mapped",[29983]],[[12132,12132],"mapped",[29992]],[[12133,12133],"mapped",[30000]],[[12134,12134],"mapped",[30091]],[[12135,12135],"mapped",[30098]],[[12136,12136],"mapped",[30326]],[[12137,12137],"mapped",[30333]],[[12138,12138],"mapped",[30382]],[[12139,12139],"mapped",[30399]],[[12140,12140],"mapped",[30446]],[[12141,12141],"mapped",[30683]],[[12142,12142],"mapped",[30690]],[[12143,12143],"mapped",[30707]],[[12144,12144],"mapped",[31034]],[[12145,12145],"mapped",[31160]],[[12146,12146],"mapped",[31166]],[[12147,12147],"mapped",[31348]],[[12148,12148],"mapped",[31435]],[[12149,12149],"mapped",[31481]],[[12150,12150],"mapped",[31859]],[[12151,12151],"mapped",[31992]],[[12152,12152],"mapped",[32566]],[[12153,12153],"mapped",[32593]],[[12154,12154],"mapped",[32650]],[[12155,12155],"mapped",[32701]],[[12156,12156],"mapped",[32769]],[[12157,12157],"mapped",[32780]],[[12158,12158],"mapped",[32786]],[[12159,12159],"mapped",[32819]],[[12160,12160],"mapped",[32895]],[[12161,12161],"mapped",[32905]],[[12162,12162],"mapped",[33251]],[[12163,12163],"mapped",[33258]],[[12164,12164],"mapped",[33267]],[[12165,12165],"mapped",[33276]],[[12166,12166],"mapped",[33292]],[[12167,12167],"mapped",[33307]],[[12168,12168],"mapped",[33311]],[[12169,12169],"mapped",[33390]],[[12170,12170],"mapped",[33394]],[[12171,12171],"mapped",[33400]],[[12172,12172],"mapped",[34381]],[[12173,12173],"mapped",[34411]],[[12174,12174],"mapped",[34880]],[[12175,12175],"mapped",[34892]],[[12176,12176],"mapped",[34915]],[[12177,12177],"mapped",[35198]],[[12178,12178],"mapped",[35211]],[[12179,12179],"mapped",[35282]],[[12180,12180],"mapped",[35328]],[[12181,12181],"mapped",[35895]],[[12182,12182],"mapped",[35910]],[[12183,12183],"mapped",[35925]],[[12184,12184],"mapped",[35960]],[[12185,12185],"mapped",[35997]],[[12186,12186],"mapped",[36196]],[[12187,12187],"mapped",[36208]],[[12188,12188],"mapped",[36275]],[[12189,12189],"mapped",[36523]],[[12190,12190],"mapped",[36554]],[[12191,12191],"mapped",[36763]],[[12192,12192],"mapped",[36784]],[[12193,12193],"mapped",[36789]],[[12194,12194],"mapped",[37009]],[[12195,12195],"mapped",[37193]],[[12196,12196],"mapped",[37318]],[[12197,12197],"mapped",[37324]],[[12198,12198],"mapped",[37329]],[[12199,12199],"mapped",[38263]],[[12200,12200],"mapped",[38272]],[[12201,12201],"mapped",[38428]],[[12202,12202],"mapped",[38582]],[[12203,12203],"mapped",[38585]],[[12204,12204],"mapped",[38632]],[[12205,12205],"mapped",[38737]],[[12206,12206],"mapped",[38750]],[[12207,12207],"mapped",[38754]],[[12208,12208],"mapped",[38761]],[[12209,12209],"mapped",[38859]],[[12210,12210],"mapped",[38893]],[[12211,12211],"mapped",[38899]],[[12212,12212],"mapped",[38913]],[[12213,12213],"mapped",[39080]],[[12214,12214],"mapped",[39131]],[[12215,12215],"mapped",[39135]],[[12216,12216],"mapped",[39318]],[[12217,12217],"mapped",[39321]],[[12218,12218],"mapped",[39340]],[[12219,12219],"mapped",[39592]],[[12220,12220],"mapped",[39640]],[[12221,12221],"mapped",[39647]],[[12222,12222],"mapped",[39717]],[[12223,12223],"mapped",[39727]],[[12224,12224],"mapped",[39730]],[[12225,12225],"mapped",[39740]],[[12226,12226],"mapped",[39770]],[[12227,12227],"mapped",[40165]],[[12228,12228],"mapped",[40565]],[[12229,12229],"mapped",[40575]],[[12230,12230],"mapped",[40613]],[[12231,12231],"mapped",[40635]],[[12232,12232],"mapped",[40643]],[[12233,12233],"mapped",[40653]],[[12234,12234],"mapped",[40657]],[[12235,12235],"mapped",[40697]],[[12236,12236],"mapped",[40701]],[[12237,12237],"mapped",[40718]],[[12238,12238],"mapped",[40723]],[[12239,12239],"mapped",[40736]],[[12240,12240],"mapped",[40763]],[[12241,12241],"mapped",[40778]],[[12242,12242],"mapped",[40786]],[[12243,12243],"mapped",[40845]],[[12244,12244],"mapped",[40860]],[[12245,12245],"mapped",[40864]],[[12246,12271],"disallowed"],[[12272,12283],"disallowed"],[[12284,12287],"disallowed"],[[12288,12288],"disallowed_STD3_mapped",[32]],[[12289,12289],"valid",[],"NV8"],[[12290,12290],"mapped",[46]],[[12291,12292],"valid",[],"NV8"],[[12293,12295],"valid"],[[12296,12329],"valid",[],"NV8"],[[12330,12333],"valid"],[[12334,12341],"valid",[],"NV8"],[[12342,12342],"mapped",[12306]],[[12343,12343],"valid",[],"NV8"],[[12344,12344],"mapped",[21313]],[[12345,12345],"mapped",[21316]],[[12346,12346],"mapped",[21317]],[[12347,12347],"valid",[],"NV8"],[[12348,12348],"valid"],[[12349,12349],"valid",[],"NV8"],[[12350,12350],"valid",[],"NV8"],[[12351,12351],"valid",[],"NV8"],[[12352,12352],"disallowed"],[[12353,12436],"valid"],[[12437,12438],"valid"],[[12439,12440],"disallowed"],[[12441,12442],"valid"],[[12443,12443],"disallowed_STD3_mapped",[32,12441]],[[12444,12444],"disallowed_STD3_mapped",[32,12442]],[[12445,12446],"valid"],[[12447,12447],"mapped",[12424,12426]],[[12448,12448],"valid",[],"NV8"],[[12449,12542],"valid"],[[12543,12543],"mapped",[12467,12488]],[[12544,12548],"disallowed"],[[12549,12588],"valid"],[[12589,12589],"valid"],[[12590,12592],"disallowed"],[[12593,12593],"mapped",[4352]],[[12594,12594],"mapped",[4353]],[[12595,12595],"mapped",[4522]],[[12596,12596],"mapped",[4354]],[[12597,12597],"mapped",[4524]],[[12598,12598],"mapped",[4525]],[[12599,12599],"mapped",[4355]],[[12600,12600],"mapped",[4356]],[[12601,12601],"mapped",[4357]],[[12602,12602],"mapped",[4528]],[[12603,12603],"mapped",[4529]],[[12604,12604],"mapped",[4530]],[[12605,12605],"mapped",[4531]],[[12606,12606],"mapped",[4532]],[[12607,12607],"mapped",[4533]],[[12608,12608],"mapped",[4378]],[[12609,12609],"mapped",[4358]],[[12610,12610],"mapped",[4359]],[[12611,12611],"mapped",[4360]],[[12612,12612],"mapped",[4385]],[[12613,12613],"mapped",[4361]],[[12614,12614],"mapped",[4362]],[[12615,12615],"mapped",[4363]],[[12616,12616],"mapped",[4364]],[[12617,12617],"mapped",[4365]],[[12618,12618],"mapped",[4366]],[[12619,12619],"mapped",[4367]],[[12620,12620],"mapped",[4368]],[[12621,12621],"mapped",[4369]],[[12622,12622],"mapped",[4370]],[[12623,12623],"mapped",[4449]],[[12624,12624],"mapped",[4450]],[[12625,12625],"mapped",[4451]],[[12626,12626],"mapped",[4452]],[[12627,12627],"mapped",[4453]],[[12628,12628],"mapped",[4454]],[[12629,12629],"mapped",[4455]],[[12630,12630],"mapped",[4456]],[[12631,12631],"mapped",[4457]],[[12632,12632],"mapped",[4458]],[[12633,12633],"mapped",[4459]],[[12634,12634],"mapped",[4460]],[[12635,12635],"mapped",[4461]],[[12636,12636],"mapped",[4462]],[[12637,12637],"mapped",[4463]],[[12638,12638],"mapped",[4464]],[[12639,12639],"mapped",[4465]],[[12640,12640],"mapped",[4466]],[[12641,12641],"mapped",[4467]],[[12642,12642],"mapped",[4468]],[[12643,12643],"mapped",[4469]],[[12644,12644],"disallowed"],[[12645,12645],"mapped",[4372]],[[12646,12646],"mapped",[4373]],[[12647,12647],"mapped",[4551]],[[12648,12648],"mapped",[4552]],[[12649,12649],"mapped",[4556]],[[12650,12650],"mapped",[4558]],[[12651,12651],"mapped",[4563]],[[12652,12652],"mapped",[4567]],[[12653,12653],"mapped",[4569]],[[12654,12654],"mapped",[4380]],[[12655,12655],"mapped",[4573]],[[12656,12656],"mapped",[4575]],[[12657,12657],"mapped",[4381]],[[12658,12658],"mapped",[4382]],[[12659,12659],"mapped",[4384]],[[12660,12660],"mapped",[4386]],[[12661,12661],"mapped",[4387]],[[12662,12662],"mapped",[4391]],[[12663,12663],"mapped",[4393]],[[12664,12664],"mapped",[4395]],[[12665,12665],"mapped",[4396]],[[12666,12666],"mapped",[4397]],[[12667,12667],"mapped",[4398]],[[12668,12668],"mapped",[4399]],[[12669,12669],"mapped",[4402]],[[12670,12670],"mapped",[4406]],[[12671,12671],"mapped",[4416]],[[12672,12672],"mapped",[4423]],[[12673,12673],"mapped",[4428]],[[12674,12674],"mapped",[4593]],[[12675,12675],"mapped",[4594]],[[12676,12676],"mapped",[4439]],[[12677,12677],"mapped",[4440]],[[12678,12678],"mapped",[4441]],[[12679,12679],"mapped",[4484]],[[12680,12680],"mapped",[4485]],[[12681,12681],"mapped",[4488]],[[12682,12682],"mapped",[4497]],[[12683,12683],"mapped",[4498]],[[12684,12684],"mapped",[4500]],[[12685,12685],"mapped",[4510]],[[12686,12686],"mapped",[4513]],[[12687,12687],"disallowed"],[[12688,12689],"valid",[],"NV8"],[[12690,12690],"mapped",[19968]],[[12691,12691],"mapped",[20108]],[[12692,12692],"mapped",[19977]],[[12693,12693],"mapped",[22235]],[[12694,12694],"mapped",[19978]],[[12695,12695],"mapped",[20013]],[[12696,12696],"mapped",[19979]],[[12697,12697],"mapped",[30002]],[[12698,12698],"mapped",[20057]],[[12699,12699],"mapped",[19993]],[[12700,12700],"mapped",[19969]],[[12701,12701],"mapped",[22825]],[[12702,12702],"mapped",[22320]],[[12703,12703],"mapped",[20154]],[[12704,12727],"valid"],[[12728,12730],"valid"],[[12731,12735],"disallowed"],[[12736,12751],"valid",[],"NV8"],[[12752,12771],"valid",[],"NV8"],[[12772,12783],"disallowed"],[[12784,12799],"valid"],[[12800,12800],"disallowed_STD3_mapped",[40,4352,41]],[[12801,12801],"disallowed_STD3_mapped",[40,4354,41]],[[12802,12802],"disallowed_STD3_mapped",[40,4355,41]],[[12803,12803],"disallowed_STD3_mapped",[40,4357,41]],[[12804,12804],"disallowed_STD3_mapped",[40,4358,41]],[[12805,12805],"disallowed_STD3_mapped",[40,4359,41]],[[12806,12806],"disallowed_STD3_mapped",[40,4361,41]],[[12807,12807],"disallowed_STD3_mapped",[40,4363,41]],[[12808,12808],"disallowed_STD3_mapped",[40,4364,41]],[[12809,12809],"disallowed_STD3_mapped",[40,4366,41]],[[12810,12810],"disallowed_STD3_mapped",[40,4367,41]],[[12811,12811],"disallowed_STD3_mapped",[40,4368,41]],[[12812,12812],"disallowed_STD3_mapped",[40,4369,41]],[[12813,12813],"disallowed_STD3_mapped",[40,4370,41]],[[12814,12814],"disallowed_STD3_mapped",[40,44032,41]],[[12815,12815],"disallowed_STD3_mapped",[40,45208,41]],[[12816,12816],"disallowed_STD3_mapped",[40,45796,41]],[[12817,12817],"disallowed_STD3_mapped",[40,46972,41]],[[12818,12818],"disallowed_STD3_mapped",[40,47560,41]],[[12819,12819],"disallowed_STD3_mapped",[40,48148,41]],[[12820,12820],"disallowed_STD3_mapped",[40,49324,41]],[[12821,12821],"disallowed_STD3_mapped",[40,50500,41]],[[12822,12822],"disallowed_STD3_mapped",[40,51088,41]],[[12823,12823],"disallowed_STD3_mapped",[40,52264,41]],[[12824,12824],"disallowed_STD3_mapped",[40,52852,41]],[[12825,12825],"disallowed_STD3_mapped",[40,53440,41]],[[12826,12826],"disallowed_STD3_mapped",[40,54028,41]],[[12827,12827],"disallowed_STD3_mapped",[40,54616,41]],[[12828,12828],"disallowed_STD3_mapped",[40,51452,41]],[[12829,12829],"disallowed_STD3_mapped",[40,50724,51204,41]],[[12830,12830],"disallowed_STD3_mapped",[40,50724,54980,41]],[[12831,12831],"disallowed"],[[12832,12832],"disallowed_STD3_mapped",[40,19968,41]],[[12833,12833],"disallowed_STD3_mapped",[40,20108,41]],[[12834,12834],"disallowed_STD3_mapped",[40,19977,41]],[[12835,12835],"disallowed_STD3_mapped",[40,22235,41]],[[12836,12836],"disallowed_STD3_mapped",[40,20116,41]],[[12837,12837],"disallowed_STD3_mapped",[40,20845,41]],[[12838,12838],"disallowed_STD3_mapped",[40,19971,41]],[[12839,12839],"disallowed_STD3_mapped",[40,20843,41]],[[12840,12840],"disallowed_STD3_mapped",[40,20061,41]],[[12841,12841],"disallowed_STD3_mapped",[40,21313,41]],[[12842,12842],"disallowed_STD3_mapped",[40,26376,41]],[[12843,12843],"disallowed_STD3_mapped",[40,28779,41]],[[12844,12844],"disallowed_STD3_mapped",[40,27700,41]],[[12845,12845],"disallowed_STD3_mapped",[40,26408,41]],[[12846,12846],"disallowed_STD3_mapped",[40,37329,41]],[[12847,12847],"disallowed_STD3_mapped",[40,22303,41]],[[12848,12848],"disallowed_STD3_mapped",[40,26085,41]],[[12849,12849],"disallowed_STD3_mapped",[40,26666,41]],[[12850,12850],"disallowed_STD3_mapped",[40,26377,41]],[[12851,12851],"disallowed_STD3_mapped",[40,31038,41]],[[12852,12852],"disallowed_STD3_mapped",[40,21517,41]],[[12853,12853],"disallowed_STD3_mapped",[40,29305,41]],[[12854,12854],"disallowed_STD3_mapped",[40,36001,41]],[[12855,12855],"disallowed_STD3_mapped",[40,31069,41]],[[12856,12856],"disallowed_STD3_mapped",[40,21172,41]],[[12857,12857],"disallowed_STD3_mapped",[40,20195,41]],[[12858,12858],"disallowed_STD3_mapped",[40,21628,41]],[[12859,12859],"disallowed_STD3_mapped",[40,23398,41]],[[12860,12860],"disallowed_STD3_mapped",[40,30435,41]],[[12861,12861],"disallowed_STD3_mapped",[40,20225,41]],[[12862,12862],"disallowed_STD3_mapped",[40,36039,41]],[[12863,12863],"disallowed_STD3_mapped",[40,21332,41]],[[12864,12864],"disallowed_STD3_mapped",[40,31085,41]],[[12865,12865],"disallowed_STD3_mapped",[40,20241,41]],[[12866,12866],"disallowed_STD3_mapped",[40,33258,41]],[[12867,12867],"disallowed_STD3_mapped",[40,33267,41]],[[12868,12868],"mapped",[21839]],[[12869,12869],"mapped",[24188]],[[12870,12870],"mapped",[25991]],[[12871,12871],"mapped",[31631]],[[12872,12879],"valid",[],"NV8"],[[12880,12880],"mapped",[112,116,101]],[[12881,12881],"mapped",[50,49]],[[12882,12882],"mapped",[50,50]],[[12883,12883],"mapped",[50,51]],[[12884,12884],"mapped",[50,52]],[[12885,12885],"mapped",[50,53]],[[12886,12886],"mapped",[50,54]],[[12887,12887],"mapped",[50,55]],[[12888,12888],"mapped",[50,56]],[[12889,12889],"mapped",[50,57]],[[12890,12890],"mapped",[51,48]],[[12891,12891],"mapped",[51,49]],[[12892,12892],"mapped",[51,50]],[[12893,12893],"mapped",[51,51]],[[12894,12894],"mapped",[51,52]],[[12895,12895],"mapped",[51,53]],[[12896,12896],"mapped",[4352]],[[12897,12897],"mapped",[4354]],[[12898,12898],"mapped",[4355]],[[12899,12899],"mapped",[4357]],[[12900,12900],"mapped",[4358]],[[12901,12901],"mapped",[4359]],[[12902,12902],"mapped",[4361]],[[12903,12903],"mapped",[4363]],[[12904,12904],"mapped",[4364]],[[12905,12905],"mapped",[4366]],[[12906,12906],"mapped",[4367]],[[12907,12907],"mapped",[4368]],[[12908,12908],"mapped",[4369]],[[12909,12909],"mapped",[4370]],[[12910,12910],"mapped",[44032]],[[12911,12911],"mapped",[45208]],[[12912,12912],"mapped",[45796]],[[12913,12913],"mapped",[46972]],[[12914,12914],"mapped",[47560]],[[12915,12915],"mapped",[48148]],[[12916,12916],"mapped",[49324]],[[12917,12917],"mapped",[50500]],[[12918,12918],"mapped",[51088]],[[12919,12919],"mapped",[52264]],[[12920,12920],"mapped",[52852]],[[12921,12921],"mapped",[53440]],[[12922,12922],"mapped",[54028]],[[12923,12923],"mapped",[54616]],[[12924,12924],"mapped",[52280,44256]],[[12925,12925],"mapped",[51452,51032]],[[12926,12926],"mapped",[50864]],[[12927,12927],"valid",[],"NV8"],[[12928,12928],"mapped",[19968]],[[12929,12929],"mapped",[20108]],[[12930,12930],"mapped",[19977]],[[12931,12931],"mapped",[22235]],[[12932,12932],"mapped",[20116]],[[12933,12933],"mapped",[20845]],[[12934,12934],"mapped",[19971]],[[12935,12935],"mapped",[20843]],[[12936,12936],"mapped",[20061]],[[12937,12937],"mapped",[21313]],[[12938,12938],"mapped",[26376]],[[12939,12939],"mapped",[28779]],[[12940,12940],"mapped",[27700]],[[12941,12941],"mapped",[26408]],[[12942,12942],"mapped",[37329]],[[12943,12943],"mapped",[22303]],[[12944,12944],"mapped",[26085]],[[12945,12945],"mapped",[26666]],[[12946,12946],"mapped",[26377]],[[12947,12947],"mapped",[31038]],[[12948,12948],"mapped",[21517]],[[12949,12949],"mapped",[29305]],[[12950,12950],"mapped",[36001]],[[12951,12951],"mapped",[31069]],[[12952,12952],"mapped",[21172]],[[12953,12953],"mapped",[31192]],[[12954,12954],"mapped",[30007]],[[12955,12955],"mapped",[22899]],[[12956,12956],"mapped",[36969]],[[12957,12957],"mapped",[20778]],[[12958,12958],"mapped",[21360]],[[12959,12959],"mapped",[27880]],[[12960,12960],"mapped",[38917]],[[12961,12961],"mapped",[20241]],[[12962,12962],"mapped",[20889]],[[12963,12963],"mapped",[27491]],[[12964,12964],"mapped",[19978]],[[12965,12965],"mapped",[20013]],[[12966,12966],"mapped",[19979]],[[12967,12967],"mapped",[24038]],[[12968,12968],"mapped",[21491]],[[12969,12969],"mapped",[21307]],[[12970,12970],"mapped",[23447]],[[12971,12971],"mapped",[23398]],[[12972,12972],"mapped",[30435]],[[12973,12973],"mapped",[20225]],[[12974,12974],"mapped",[36039]],[[12975,12975],"mapped",[21332]],[[12976,12976],"mapped",[22812]],[[12977,12977],"mapped",[51,54]],[[12978,12978],"mapped",[51,55]],[[12979,12979],"mapped",[51,56]],[[12980,12980],"mapped",[51,57]],[[12981,12981],"mapped",[52,48]],[[12982,12982],"mapped",[52,49]],[[12983,12983],"mapped",[52,50]],[[12984,12984],"mapped",[52,51]],[[12985,12985],"mapped",[52,52]],[[12986,12986],"mapped",[52,53]],[[12987,12987],"mapped",[52,54]],[[12988,12988],"mapped",[52,55]],[[12989,12989],"mapped",[52,56]],[[12990,12990],"mapped",[52,57]],[[12991,12991],"mapped",[53,48]],[[12992,12992],"mapped",[49,26376]],[[12993,12993],"mapped",[50,26376]],[[12994,12994],"mapped",[51,26376]],[[12995,12995],"mapped",[52,26376]],[[12996,12996],"mapped",[53,26376]],[[12997,12997],"mapped",[54,26376]],[[12998,12998],"mapped",[55,26376]],[[12999,12999],"mapped",[56,26376]],[[13000,13000],"mapped",[57,26376]],[[13001,13001],"mapped",[49,48,26376]],[[13002,13002],"mapped",[49,49,26376]],[[13003,13003],"mapped",[49,50,26376]],[[13004,13004],"mapped",[104,103]],[[13005,13005],"mapped",[101,114,103]],[[13006,13006],"mapped",[101,118]],[[13007,13007],"mapped",[108,116,100]],[[13008,13008],"mapped",[12450]],[[13009,13009],"mapped",[12452]],[[13010,13010],"mapped",[12454]],[[13011,13011],"mapped",[12456]],[[13012,13012],"mapped",[12458]],[[13013,13013],"mapped",[12459]],[[13014,13014],"mapped",[12461]],[[13015,13015],"mapped",[12463]],[[13016,13016],"mapped",[12465]],[[13017,13017],"mapped",[12467]],[[13018,13018],"mapped",[12469]],[[13019,13019],"mapped",[12471]],[[13020,13020],"mapped",[12473]],[[13021,13021],"mapped",[12475]],[[13022,13022],"mapped",[12477]],[[13023,13023],"mapped",[12479]],[[13024,13024],"mapped",[12481]],[[13025,13025],"mapped",[12484]],[[13026,13026],"mapped",[12486]],[[13027,13027],"mapped",[12488]],[[13028,13028],"mapped",[12490]],[[13029,13029],"mapped",[12491]],[[13030,13030],"mapped",[12492]],[[13031,13031],"mapped",[12493]],[[13032,13032],"mapped",[12494]],[[13033,13033],"mapped",[12495]],[[13034,13034],"mapped",[12498]],[[13035,13035],"mapped",[12501]],[[13036,13036],"mapped",[12504]],[[13037,13037],"mapped",[12507]],[[13038,13038],"mapped",[12510]],[[13039,13039],"mapped",[12511]],[[13040,13040],"mapped",[12512]],[[13041,13041],"mapped",[12513]],[[13042,13042],"mapped",[12514]],[[13043,13043],"mapped",[12516]],[[13044,13044],"mapped",[12518]],[[13045,13045],"mapped",[12520]],[[13046,13046],"mapped",[12521]],[[13047,13047],"mapped",[12522]],[[13048,13048],"mapped",[12523]],[[13049,13049],"mapped",[12524]],[[13050,13050],"mapped",[12525]],[[13051,13051],"mapped",[12527]],[[13052,13052],"mapped",[12528]],[[13053,13053],"mapped",[12529]],[[13054,13054],"mapped",[12530]],[[13055,13055],"disallowed"],[[13056,13056],"mapped",[12450,12497,12540,12488]],[[13057,13057],"mapped",[12450,12523,12501,12449]],[[13058,13058],"mapped",[12450,12531,12506,12450]],[[13059,13059],"mapped",[12450,12540,12523]],[[13060,13060],"mapped",[12452,12491,12531,12464]],[[13061,13061],"mapped",[12452,12531,12481]],[[13062,13062],"mapped",[12454,12457,12531]],[[13063,13063],"mapped",[12456,12473,12463,12540,12489]],[[13064,13064],"mapped",[12456,12540,12459,12540]],[[13065,13065],"mapped",[12458,12531,12473]],[[13066,13066],"mapped",[12458,12540,12512]],[[13067,13067],"mapped",[12459,12452,12522]],[[13068,13068],"mapped",[12459,12521,12483,12488]],[[13069,13069],"mapped",[12459,12525,12522,12540]],[[13070,13070],"mapped",[12460,12525,12531]],[[13071,13071],"mapped",[12460,12531,12510]],[[13072,13072],"mapped",[12462,12460]],[[13073,13073],"mapped",[12462,12491,12540]],[[13074,13074],"mapped",[12461,12517,12522,12540]],[[13075,13075],"mapped",[12462,12523,12480,12540]],[[13076,13076],"mapped",[12461,12525]],[[13077,13077],"mapped",[12461,12525,12464,12521,12512]],[[13078,13078],"mapped",[12461,12525,12513,12540,12488,12523]],[[13079,13079],"mapped",[12461,12525,12527,12483,12488]],[[13080,13080],"mapped",[12464,12521,12512]],[[13081,13081],"mapped",[12464,12521,12512,12488,12531]],[[13082,13082],"mapped",[12463,12523,12476,12452,12525]],[[13083,13083],"mapped",[12463,12525,12540,12493]],[[13084,13084],"mapped",[12465,12540,12473]],[[13085,13085],"mapped",[12467,12523,12490]],[[13086,13086],"mapped",[12467,12540,12509]],[[13087,13087],"mapped",[12469,12452,12463,12523]],[[13088,13088],"mapped",[12469,12531,12481,12540,12512]],[[13089,13089],"mapped",[12471,12522,12531,12464]],[[13090,13090],"mapped",[12475,12531,12481]],[[13091,13091],"mapped",[12475,12531,12488]],[[13092,13092],"mapped",[12480,12540,12473]],[[13093,13093],"mapped",[12487,12471]],[[13094,13094],"mapped",[12489,12523]],[[13095,13095],"mapped",[12488,12531]],[[13096,13096],"mapped",[12490,12494]],[[13097,13097],"mapped",[12494,12483,12488]],[[13098,13098],"mapped",[12495,12452,12484]],[[13099,13099],"mapped",[12497,12540,12475,12531,12488]],[[13100,13100],"mapped",[12497,12540,12484]],[[13101,13101],"mapped",[12496,12540,12524,12523]],[[13102,13102],"mapped",[12500,12450,12473,12488,12523]],[[13103,13103],"mapped",[12500,12463,12523]],[[13104,13104],"mapped",[12500,12467]],[[13105,13105],"mapped",[12499,12523]],[[13106,13106],"mapped",[12501,12449,12521,12483,12489]],[[13107,13107],"mapped",[12501,12451,12540,12488]],[[13108,13108],"mapped",[12502,12483,12471,12455,12523]],[[13109,13109],"mapped",[12501,12521,12531]],[[13110,13110],"mapped",[12504,12463,12479,12540,12523]],[[13111,13111],"mapped",[12506,12477]],[[13112,13112],"mapped",[12506,12491,12498]],[[13113,13113],"mapped",[12504,12523,12484]],[[13114,13114],"mapped",[12506,12531,12473]],[[13115,13115],"mapped",[12506,12540,12472]],[[13116,13116],"mapped",[12505,12540,12479]],[[13117,13117],"mapped",[12509,12452,12531,12488]],[[13118,13118],"mapped",[12508,12523,12488]],[[13119,13119],"mapped",[12507,12531]],[[13120,13120],"mapped",[12509,12531,12489]],[[13121,13121],"mapped",[12507,12540,12523]],[[13122,13122],"mapped",[12507,12540,12531]],[[13123,13123],"mapped",[12510,12452,12463,12525]],[[13124,13124],"mapped",[12510,12452,12523]],[[13125,13125],"mapped",[12510,12483,12495]],[[13126,13126],"mapped",[12510,12523,12463]],[[13127,13127],"mapped",[12510,12531,12471,12519,12531]],[[13128,13128],"mapped",[12511,12463,12525,12531]],[[13129,13129],"mapped",[12511,12522]],[[13130,13130],"mapped",[12511,12522,12496,12540,12523]],[[13131,13131],"mapped",[12513,12460]],[[13132,13132],"mapped",[12513,12460,12488,12531]],[[13133,13133],"mapped",[12513,12540,12488,12523]],[[13134,13134],"mapped",[12516,12540,12489]],[[13135,13135],"mapped",[12516,12540,12523]],[[13136,13136],"mapped",[12518,12450,12531]],[[13137,13137],"mapped",[12522,12483,12488,12523]],[[13138,13138],"mapped",[12522,12521]],[[13139,13139],"mapped",[12523,12500,12540]],[[13140,13140],"mapped",[12523,12540,12502,12523]],[[13141,13141],"mapped",[12524,12512]],[[13142,13142],"mapped",[12524,12531,12488,12466,12531]],[[13143,13143],"mapped",[12527,12483,12488]],[[13144,13144],"mapped",[48,28857]],[[13145,13145],"mapped",[49,28857]],[[13146,13146],"mapped",[50,28857]],[[13147,13147],"mapped",[51,28857]],[[13148,13148],"mapped",[52,28857]],[[13149,13149],"mapped",[53,28857]],[[13150,13150],"mapped",[54,28857]],[[13151,13151],"mapped",[55,28857]],[[13152,13152],"mapped",[56,28857]],[[13153,13153],"mapped",[57,28857]],[[13154,13154],"mapped",[49,48,28857]],[[13155,13155],"mapped",[49,49,28857]],[[13156,13156],"mapped",[49,50,28857]],[[13157,13157],"mapped",[49,51,28857]],[[13158,13158],"mapped",[49,52,28857]],[[13159,13159],"mapped",[49,53,28857]],[[13160,13160],"mapped",[49,54,28857]],[[13161,13161],"mapped",[49,55,28857]],[[13162,13162],"mapped",[49,56,28857]],[[13163,13163],"mapped",[49,57,28857]],[[13164,13164],"mapped",[50,48,28857]],[[13165,13165],"mapped",[50,49,28857]],[[13166,13166],"mapped",[50,50,28857]],[[13167,13167],"mapped",[50,51,28857]],[[13168,13168],"mapped",[50,52,28857]],[[13169,13169],"mapped",[104,112,97]],[[13170,13170],"mapped",[100,97]],[[13171,13171],"mapped",[97,117]],[[13172,13172],"mapped",[98,97,114]],[[13173,13173],"mapped",[111,118]],[[13174,13174],"mapped",[112,99]],[[13175,13175],"mapped",[100,109]],[[13176,13176],"mapped",[100,109,50]],[[13177,13177],"mapped",[100,109,51]],[[13178,13178],"mapped",[105,117]],[[13179,13179],"mapped",[24179,25104]],[[13180,13180],"mapped",[26157,21644]],[[13181,13181],"mapped",[22823,27491]],[[13182,13182],"mapped",[26126,27835]],[[13183,13183],"mapped",[26666,24335,20250,31038]],[[13184,13184],"mapped",[112,97]],[[13185,13185],"mapped",[110,97]],[[13186,13186],"mapped",[956,97]],[[13187,13187],"mapped",[109,97]],[[13188,13188],"mapped",[107,97]],[[13189,13189],"mapped",[107,98]],[[13190,13190],"mapped",[109,98]],[[13191,13191],"mapped",[103,98]],[[13192,13192],"mapped",[99,97,108]],[[13193,13193],"mapped",[107,99,97,108]],[[13194,13194],"mapped",[112,102]],[[13195,13195],"mapped",[110,102]],[[13196,13196],"mapped",[956,102]],[[13197,13197],"mapped",[956,103]],[[13198,13198],"mapped",[109,103]],[[13199,13199],"mapped",[107,103]],[[13200,13200],"mapped",[104,122]],[[13201,13201],"mapped",[107,104,122]],[[13202,13202],"mapped",[109,104,122]],[[13203,13203],"mapped",[103,104,122]],[[13204,13204],"mapped",[116,104,122]],[[13205,13205],"mapped",[956,108]],[[13206,13206],"mapped",[109,108]],[[13207,13207],"mapped",[100,108]],[[13208,13208],"mapped",[107,108]],[[13209,13209],"mapped",[102,109]],[[13210,13210],"mapped",[110,109]],[[13211,13211],"mapped",[956,109]],[[13212,13212],"mapped",[109,109]],[[13213,13213],"mapped",[99,109]],[[13214,13214],"mapped",[107,109]],[[13215,13215],"mapped",[109,109,50]],[[13216,13216],"mapped",[99,109,50]],[[13217,13217],"mapped",[109,50]],[[13218,13218],"mapped",[107,109,50]],[[13219,13219],"mapped",[109,109,51]],[[13220,13220],"mapped",[99,109,51]],[[13221,13221],"mapped",[109,51]],[[13222,13222],"mapped",[107,109,51]],[[13223,13223],"mapped",[109,8725,115]],[[13224,13224],"mapped",[109,8725,115,50]],[[13225,13225],"mapped",[112,97]],[[13226,13226],"mapped",[107,112,97]],[[13227,13227],"mapped",[109,112,97]],[[13228,13228],"mapped",[103,112,97]],[[13229,13229],"mapped",[114,97,100]],[[13230,13230],"mapped",[114,97,100,8725,115]],[[13231,13231],"mapped",[114,97,100,8725,115,50]],[[13232,13232],"mapped",[112,115]],[[13233,13233],"mapped",[110,115]],[[13234,13234],"mapped",[956,115]],[[13235,13235],"mapped",[109,115]],[[13236,13236],"mapped",[112,118]],[[13237,13237],"mapped",[110,118]],[[13238,13238],"mapped",[956,118]],[[13239,13239],"mapped",[109,118]],[[13240,13240],"mapped",[107,118]],[[13241,13241],"mapped",[109,118]],[[13242,13242],"mapped",[112,119]],[[13243,13243],"mapped",[110,119]],[[13244,13244],"mapped",[956,119]],[[13245,13245],"mapped",[109,119]],[[13246,13246],"mapped",[107,119]],[[13247,13247],"mapped",[109,119]],[[13248,13248],"mapped",[107,969]],[[13249,13249],"mapped",[109,969]],[[13250,13250],"disallowed"],[[13251,13251],"mapped",[98,113]],[[13252,13252],"mapped",[99,99]],[[13253,13253],"mapped",[99,100]],[[13254,13254],"mapped",[99,8725,107,103]],[[13255,13255],"disallowed"],[[13256,13256],"mapped",[100,98]],[[13257,13257],"mapped",[103,121]],[[13258,13258],"mapped",[104,97]],[[13259,13259],"mapped",[104,112]],[[13260,13260],"mapped",[105,110]],[[13261,13261],"mapped",[107,107]],[[13262,13262],"mapped",[107,109]],[[13263,13263],"mapped",[107,116]],[[13264,13264],"mapped",[108,109]],[[13265,13265],"mapped",[108,110]],[[13266,13266],"mapped",[108,111,103]],[[13267,13267],"mapped",[108,120]],[[13268,13268],"mapped",[109,98]],[[13269,13269],"mapped",[109,105,108]],[[13270,13270],"mapped",[109,111,108]],[[13271,13271],"mapped",[112,104]],[[13272,13272],"disallowed"],[[13273,13273],"mapped",[112,112,109]],[[13274,13274],"mapped",[112,114]],[[13275,13275],"mapped",[115,114]],[[13276,13276],"mapped",[115,118]],[[13277,13277],"mapped",[119,98]],[[13278,13278],"mapped",[118,8725,109]],[[13279,13279],"mapped",[97,8725,109]],[[13280,13280],"mapped",[49,26085]],[[13281,13281],"mapped",[50,26085]],[[13282,13282],"mapped",[51,26085]],[[13283,13283],"mapped",[52,26085]],[[13284,13284],"mapped",[53,26085]],[[13285,13285],"mapped",[54,26085]],[[13286,13286],"mapped",[55,26085]],[[13287,13287],"mapped",[56,26085]],[[13288,13288],"mapped",[57,26085]],[[13289,13289],"mapped",[49,48,26085]],[[13290,13290],"mapped",[49,49,26085]],[[13291,13291],"mapped",[49,50,26085]],[[13292,13292],"mapped",[49,51,26085]],[[13293,13293],"mapped",[49,52,26085]],[[13294,13294],"mapped",[49,53,26085]],[[13295,13295],"mapped",[49,54,26085]],[[13296,13296],"mapped",[49,55,26085]],[[13297,13297],"mapped",[49,56,26085]],[[13298,13298],"mapped",[49,57,26085]],[[13299,13299],"mapped",[50,48,26085]],[[13300,13300],"mapped",[50,49,26085]],[[13301,13301],"mapped",[50,50,26085]],[[13302,13302],"mapped",[50,51,26085]],[[13303,13303],"mapped",[50,52,26085]],[[13304,13304],"mapped",[50,53,26085]],[[13305,13305],"mapped",[50,54,26085]],[[13306,13306],"mapped",[50,55,26085]],[[13307,13307],"mapped",[50,56,26085]],[[13308,13308],"mapped",[50,57,26085]],[[13309,13309],"mapped",[51,48,26085]],[[13310,13310],"mapped",[51,49,26085]],[[13311,13311],"mapped",[103,97,108]],[[13312,19893],"valid"],[[19894,19903],"disallowed"],[[19904,19967],"valid",[],"NV8"],[[19968,40869],"valid"],[[40870,40891],"valid"],[[40892,40899],"valid"],[[40900,40907],"valid"],[[40908,40908],"valid"],[[40909,40917],"valid"],[[40918,40959],"disallowed"],[[40960,42124],"valid"],[[42125,42127],"disallowed"],[[42128,42145],"valid",[],"NV8"],[[42146,42147],"valid",[],"NV8"],[[42148,42163],"valid",[],"NV8"],[[42164,42164],"valid",[],"NV8"],[[42165,42176],"valid",[],"NV8"],[[42177,42177],"valid",[],"NV8"],[[42178,42180],"valid",[],"NV8"],[[42181,42181],"valid",[],"NV8"],[[42182,42182],"valid",[],"NV8"],[[42183,42191],"disallowed"],[[42192,42237],"valid"],[[42238,42239],"valid",[],"NV8"],[[42240,42508],"valid"],[[42509,42511],"valid",[],"NV8"],[[42512,42539],"valid"],[[42540,42559],"disallowed"],[[42560,42560],"mapped",[42561]],[[42561,42561],"valid"],[[42562,42562],"mapped",[42563]],[[42563,42563],"valid"],[[42564,42564],"mapped",[42565]],[[42565,42565],"valid"],[[42566,42566],"mapped",[42567]],[[42567,42567],"valid"],[[42568,42568],"mapped",[42569]],[[42569,42569],"valid"],[[42570,42570],"mapped",[42571]],[[42571,42571],"valid"],[[42572,42572],"mapped",[42573]],[[42573,42573],"valid"],[[42574,42574],"mapped",[42575]],[[42575,42575],"valid"],[[42576,42576],"mapped",[42577]],[[42577,42577],"valid"],[[42578,42578],"mapped",[42579]],[[42579,42579],"valid"],[[42580,42580],"mapped",[42581]],[[42581,42581],"valid"],[[42582,42582],"mapped",[42583]],[[42583,42583],"valid"],[[42584,42584],"mapped",[42585]],[[42585,42585],"valid"],[[42586,42586],"mapped",[42587]],[[42587,42587],"valid"],[[42588,42588],"mapped",[42589]],[[42589,42589],"valid"],[[42590,42590],"mapped",[42591]],[[42591,42591],"valid"],[[42592,42592],"mapped",[42593]],[[42593,42593],"valid"],[[42594,42594],"mapped",[42595]],[[42595,42595],"valid"],[[42596,42596],"mapped",[42597]],[[42597,42597],"valid"],[[42598,42598],"mapped",[42599]],[[42599,42599],"valid"],[[42600,42600],"mapped",[42601]],[[42601,42601],"valid"],[[42602,42602],"mapped",[42603]],[[42603,42603],"valid"],[[42604,42604],"mapped",[42605]],[[42605,42607],"valid"],[[42608,42611],"valid",[],"NV8"],[[42612,42619],"valid"],[[42620,42621],"valid"],[[42622,42622],"valid",[],"NV8"],[[42623,42623],"valid"],[[42624,42624],"mapped",[42625]],[[42625,42625],"valid"],[[42626,42626],"mapped",[42627]],[[42627,42627],"valid"],[[42628,42628],"mapped",[42629]],[[42629,42629],"valid"],[[42630,42630],"mapped",[42631]],[[42631,42631],"valid"],[[42632,42632],"mapped",[42633]],[[42633,42633],"valid"],[[42634,42634],"mapped",[42635]],[[42635,42635],"valid"],[[42636,42636],"mapped",[42637]],[[42637,42637],"valid"],[[42638,42638],"mapped",[42639]],[[42639,42639],"valid"],[[42640,42640],"mapped",[42641]],[[42641,42641],"valid"],[[42642,42642],"mapped",[42643]],[[42643,42643],"valid"],[[42644,42644],"mapped",[42645]],[[42645,42645],"valid"],[[42646,42646],"mapped",[42647]],[[42647,42647],"valid"],[[42648,42648],"mapped",[42649]],[[42649,42649],"valid"],[[42650,42650],"mapped",[42651]],[[42651,42651],"valid"],[[42652,42652],"mapped",[1098]],[[42653,42653],"mapped",[1100]],[[42654,42654],"valid"],[[42655,42655],"valid"],[[42656,42725],"valid"],[[42726,42735],"valid",[],"NV8"],[[42736,42737],"valid"],[[42738,42743],"valid",[],"NV8"],[[42744,42751],"disallowed"],[[42752,42774],"valid",[],"NV8"],[[42775,42778],"valid"],[[42779,42783],"valid"],[[42784,42785],"valid",[],"NV8"],[[42786,42786],"mapped",[42787]],[[42787,42787],"valid"],[[42788,42788],"mapped",[42789]],[[42789,42789],"valid"],[[42790,42790],"mapped",[42791]],[[42791,42791],"valid"],[[42792,42792],"mapped",[42793]],[[42793,42793],"valid"],[[42794,42794],"mapped",[42795]],[[42795,42795],"valid"],[[42796,42796],"mapped",[42797]],[[42797,42797],"valid"],[[42798,42798],"mapped",[42799]],[[42799,42801],"valid"],[[42802,42802],"mapped",[42803]],[[42803,42803],"valid"],[[42804,42804],"mapped",[42805]],[[42805,42805],"valid"],[[42806,42806],"mapped",[42807]],[[42807,42807],"valid"],[[42808,42808],"mapped",[42809]],[[42809,42809],"valid"],[[42810,42810],"mapped",[42811]],[[42811,42811],"valid"],[[42812,42812],"mapped",[42813]],[[42813,42813],"valid"],[[42814,42814],"mapped",[42815]],[[42815,42815],"valid"],[[42816,42816],"mapped",[42817]],[[42817,42817],"valid"],[[42818,42818],"mapped",[42819]],[[42819,42819],"valid"],[[42820,42820],"mapped",[42821]],[[42821,42821],"valid"],[[42822,42822],"mapped",[42823]],[[42823,42823],"valid"],[[42824,42824],"mapped",[42825]],[[42825,42825],"valid"],[[42826,42826],"mapped",[42827]],[[42827,42827],"valid"],[[42828,42828],"mapped",[42829]],[[42829,42829],"valid"],[[42830,42830],"mapped",[42831]],[[42831,42831],"valid"],[[42832,42832],"mapped",[42833]],[[42833,42833],"valid"],[[42834,42834],"mapped",[42835]],[[42835,42835],"valid"],[[42836,42836],"mapped",[42837]],[[42837,42837],"valid"],[[42838,42838],"mapped",[42839]],[[42839,42839],"valid"],[[42840,42840],"mapped",[42841]],[[42841,42841],"valid"],[[42842,42842],"mapped",[42843]],[[42843,42843],"valid"],[[42844,42844],"mapped",[42845]],[[42845,42845],"valid"],[[42846,42846],"mapped",[42847]],[[42847,42847],"valid"],[[42848,42848],"mapped",[42849]],[[42849,42849],"valid"],[[42850,42850],"mapped",[42851]],[[42851,42851],"valid"],[[42852,42852],"mapped",[42853]],[[42853,42853],"valid"],[[42854,42854],"mapped",[42855]],[[42855,42855],"valid"],[[42856,42856],"mapped",[42857]],[[42857,42857],"valid"],[[42858,42858],"mapped",[42859]],[[42859,42859],"valid"],[[42860,42860],"mapped",[42861]],[[42861,42861],"valid"],[[42862,42862],"mapped",[42863]],[[42863,42863],"valid"],[[42864,42864],"mapped",[42863]],[[42865,42872],"valid"],[[42873,42873],"mapped",[42874]],[[42874,42874],"valid"],[[42875,42875],"mapped",[42876]],[[42876,42876],"valid"],[[42877,42877],"mapped",[7545]],[[42878,42878],"mapped",[42879]],[[42879,42879],"valid"],[[42880,42880],"mapped",[42881]],[[42881,42881],"valid"],[[42882,42882],"mapped",[42883]],[[42883,42883],"valid"],[[42884,42884],"mapped",[42885]],[[42885,42885],"valid"],[[42886,42886],"mapped",[42887]],[[42887,42888],"valid"],[[42889,42890],"valid",[],"NV8"],[[42891,42891],"mapped",[42892]],[[42892,42892],"valid"],[[42893,42893],"mapped",[613]],[[42894,42894],"valid"],[[42895,42895],"valid"],[[42896,42896],"mapped",[42897]],[[42897,42897],"valid"],[[42898,42898],"mapped",[42899]],[[42899,42899],"valid"],[[42900,42901],"valid"],[[42902,42902],"mapped",[42903]],[[42903,42903],"valid"],[[42904,42904],"mapped",[42905]],[[42905,42905],"valid"],[[42906,42906],"mapped",[42907]],[[42907,42907],"valid"],[[42908,42908],"mapped",[42909]],[[42909,42909],"valid"],[[42910,42910],"mapped",[42911]],[[42911,42911],"valid"],[[42912,42912],"mapped",[42913]],[[42913,42913],"valid"],[[42914,42914],"mapped",[42915]],[[42915,42915],"valid"],[[42916,42916],"mapped",[42917]],[[42917,42917],"valid"],[[42918,42918],"mapped",[42919]],[[42919,42919],"valid"],[[42920,42920],"mapped",[42921]],[[42921,42921],"valid"],[[42922,42922],"mapped",[614]],[[42923,42923],"mapped",[604]],[[42924,42924],"mapped",[609]],[[42925,42925],"mapped",[620]],[[42926,42927],"disallowed"],[[42928,42928],"mapped",[670]],[[42929,42929],"mapped",[647]],[[42930,42930],"mapped",[669]],[[42931,42931],"mapped",[43859]],[[42932,42932],"mapped",[42933]],[[42933,42933],"valid"],[[42934,42934],"mapped",[42935]],[[42935,42935],"valid"],[[42936,42998],"disallowed"],[[42999,42999],"valid"],[[43000,43000],"mapped",[295]],[[43001,43001],"mapped",[339]],[[43002,43002],"valid"],[[43003,43007],"valid"],[[43008,43047],"valid"],[[43048,43051],"valid",[],"NV8"],[[43052,43055],"disallowed"],[[43056,43065],"valid",[],"NV8"],[[43066,43071],"disallowed"],[[43072,43123],"valid"],[[43124,43127],"valid",[],"NV8"],[[43128,43135],"disallowed"],[[43136,43204],"valid"],[[43205,43213],"disallowed"],[[43214,43215],"valid",[],"NV8"],[[43216,43225],"valid"],[[43226,43231],"disallowed"],[[43232,43255],"valid"],[[43256,43258],"valid",[],"NV8"],[[43259,43259],"valid"],[[43260,43260],"valid",[],"NV8"],[[43261,43261],"valid"],[[43262,43263],"disallowed"],[[43264,43309],"valid"],[[43310,43311],"valid",[],"NV8"],[[43312,43347],"valid"],[[43348,43358],"disallowed"],[[43359,43359],"valid",[],"NV8"],[[43360,43388],"valid",[],"NV8"],[[43389,43391],"disallowed"],[[43392,43456],"valid"],[[43457,43469],"valid",[],"NV8"],[[43470,43470],"disallowed"],[[43471,43481],"valid"],[[43482,43485],"disallowed"],[[43486,43487],"valid",[],"NV8"],[[43488,43518],"valid"],[[43519,43519],"disallowed"],[[43520,43574],"valid"],[[43575,43583],"disallowed"],[[43584,43597],"valid"],[[43598,43599],"disallowed"],[[43600,43609],"valid"],[[43610,43611],"disallowed"],[[43612,43615],"valid",[],"NV8"],[[43616,43638],"valid"],[[43639,43641],"valid",[],"NV8"],[[43642,43643],"valid"],[[43644,43647],"valid"],[[43648,43714],"valid"],[[43715,43738],"disallowed"],[[43739,43741],"valid"],[[43742,43743],"valid",[],"NV8"],[[43744,43759],"valid"],[[43760,43761],"valid",[],"NV8"],[[43762,43766],"valid"],[[43767,43776],"disallowed"],[[43777,43782],"valid"],[[43783,43784],"disallowed"],[[43785,43790],"valid"],[[43791,43792],"disallowed"],[[43793,43798],"valid"],[[43799,43807],"disallowed"],[[43808,43814],"valid"],[[43815,43815],"disallowed"],[[43816,43822],"valid"],[[43823,43823],"disallowed"],[[43824,43866],"valid"],[[43867,43867],"valid",[],"NV8"],[[43868,43868],"mapped",[42791]],[[43869,43869],"mapped",[43831]],[[43870,43870],"mapped",[619]],[[43871,43871],"mapped",[43858]],[[43872,43875],"valid"],[[43876,43877],"valid"],[[43878,43887],"disallowed"],[[43888,43888],"mapped",[5024]],[[43889,43889],"mapped",[5025]],[[43890,43890],"mapped",[5026]],[[43891,43891],"mapped",[5027]],[[43892,43892],"mapped",[5028]],[[43893,43893],"mapped",[5029]],[[43894,43894],"mapped",[5030]],[[43895,43895],"mapped",[5031]],[[43896,43896],"mapped",[5032]],[[43897,43897],"mapped",[5033]],[[43898,43898],"mapped",[5034]],[[43899,43899],"mapped",[5035]],[[43900,43900],"mapped",[5036]],[[43901,43901],"mapped",[5037]],[[43902,43902],"mapped",[5038]],[[43903,43903],"mapped",[5039]],[[43904,43904],"mapped",[5040]],[[43905,43905],"mapped",[5041]],[[43906,43906],"mapped",[5042]],[[43907,43907],"mapped",[5043]],[[43908,43908],"mapped",[5044]],[[43909,43909],"mapped",[5045]],[[43910,43910],"mapped",[5046]],[[43911,43911],"mapped",[5047]],[[43912,43912],"mapped",[5048]],[[43913,43913],"mapped",[5049]],[[43914,43914],"mapped",[5050]],[[43915,43915],"mapped",[5051]],[[43916,43916],"mapped",[5052]],[[43917,43917],"mapped",[5053]],[[43918,43918],"mapped",[5054]],[[43919,43919],"mapped",[5055]],[[43920,43920],"mapped",[5056]],[[43921,43921],"mapped",[5057]],[[43922,43922],"mapped",[5058]],[[43923,43923],"mapped",[5059]],[[43924,43924],"mapped",[5060]],[[43925,43925],"mapped",[5061]],[[43926,43926],"mapped",[5062]],[[43927,43927],"mapped",[5063]],[[43928,43928],"mapped",[5064]],[[43929,43929],"mapped",[5065]],[[43930,43930],"mapped",[5066]],[[43931,43931],"mapped",[5067]],[[43932,43932],"mapped",[5068]],[[43933,43933],"mapped",[5069]],[[43934,43934],"mapped",[5070]],[[43935,43935],"mapped",[5071]],[[43936,43936],"mapped",[5072]],[[43937,43937],"mapped",[5073]],[[43938,43938],"mapped",[5074]],[[43939,43939],"mapped",[5075]],[[43940,43940],"mapped",[5076]],[[43941,43941],"mapped",[5077]],[[43942,43942],"mapped",[5078]],[[43943,43943],"mapped",[5079]],[[43944,43944],"mapped",[5080]],[[43945,43945],"mapped",[5081]],[[43946,43946],"mapped",[5082]],[[43947,43947],"mapped",[5083]],[[43948,43948],"mapped",[5084]],[[43949,43949],"mapped",[5085]],[[43950,43950],"mapped",[5086]],[[43951,43951],"mapped",[5087]],[[43952,43952],"mapped",[5088]],[[43953,43953],"mapped",[5089]],[[43954,43954],"mapped",[5090]],[[43955,43955],"mapped",[5091]],[[43956,43956],"mapped",[5092]],[[43957,43957],"mapped",[5093]],[[43958,43958],"mapped",[5094]],[[43959,43959],"mapped",[5095]],[[43960,43960],"mapped",[5096]],[[43961,43961],"mapped",[5097]],[[43962,43962],"mapped",[5098]],[[43963,43963],"mapped",[5099]],[[43964,43964],"mapped",[5100]],[[43965,43965],"mapped",[5101]],[[43966,43966],"mapped",[5102]],[[43967,43967],"mapped",[5103]],[[43968,44010],"valid"],[[44011,44011],"valid",[],"NV8"],[[44012,44013],"valid"],[[44014,44015],"disallowed"],[[44016,44025],"valid"],[[44026,44031],"disallowed"],[[44032,55203],"valid"],[[55204,55215],"disallowed"],[[55216,55238],"valid",[],"NV8"],[[55239,55242],"disallowed"],[[55243,55291],"valid",[],"NV8"],[[55292,55295],"disallowed"],[[55296,57343],"disallowed"],[[57344,63743],"disallowed"],[[63744,63744],"mapped",[35912]],[[63745,63745],"mapped",[26356]],[[63746,63746],"mapped",[36554]],[[63747,63747],"mapped",[36040]],[[63748,63748],"mapped",[28369]],[[63749,63749],"mapped",[20018]],[[63750,63750],"mapped",[21477]],[[63751,63752],"mapped",[40860]],[[63753,63753],"mapped",[22865]],[[63754,63754],"mapped",[37329]],[[63755,63755],"mapped",[21895]],[[63756,63756],"mapped",[22856]],[[63757,63757],"mapped",[25078]],[[63758,63758],"mapped",[30313]],[[63759,63759],"mapped",[32645]],[[63760,63760],"mapped",[34367]],[[63761,63761],"mapped",[34746]],[[63762,63762],"mapped",[35064]],[[63763,63763],"mapped",[37007]],[[63764,63764],"mapped",[27138]],[[63765,63765],"mapped",[27931]],[[63766,63766],"mapped",[28889]],[[63767,63767],"mapped",[29662]],[[63768,63768],"mapped",[33853]],[[63769,63769],"mapped",[37226]],[[63770,63770],"mapped",[39409]],[[63771,63771],"mapped",[20098]],[[63772,63772],"mapped",[21365]],[[63773,63773],"mapped",[27396]],[[63774,63774],"mapped",[29211]],[[63775,63775],"mapped",[34349]],[[63776,63776],"mapped",[40478]],[[63777,63777],"mapped",[23888]],[[63778,63778],"mapped",[28651]],[[63779,63779],"mapped",[34253]],[[63780,63780],"mapped",[35172]],[[63781,63781],"mapped",[25289]],[[63782,63782],"mapped",[33240]],[[63783,63783],"mapped",[34847]],[[63784,63784],"mapped",[24266]],[[63785,63785],"mapped",[26391]],[[63786,63786],"mapped",[28010]],[[63787,63787],"mapped",[29436]],[[63788,63788],"mapped",[37070]],[[63789,63789],"mapped",[20358]],[[63790,63790],"mapped",[20919]],[[63791,63791],"mapped",[21214]],[[63792,63792],"mapped",[25796]],[[63793,63793],"mapped",[27347]],[[63794,63794],"mapped",[29200]],[[63795,63795],"mapped",[30439]],[[63796,63796],"mapped",[32769]],[[63797,63797],"mapped",[34310]],[[63798,63798],"mapped",[34396]],[[63799,63799],"mapped",[36335]],[[63800,63800],"mapped",[38706]],[[63801,63801],"mapped",[39791]],[[63802,63802],"mapped",[40442]],[[63803,63803],"mapped",[30860]],[[63804,63804],"mapped",[31103]],[[63805,63805],"mapped",[32160]],[[63806,63806],"mapped",[33737]],[[63807,63807],"mapped",[37636]],[[63808,63808],"mapped",[40575]],[[63809,63809],"mapped",[35542]],[[63810,63810],"mapped",[22751]],[[63811,63811],"mapped",[24324]],[[63812,63812],"mapped",[31840]],[[63813,63813],"mapped",[32894]],[[63814,63814],"mapped",[29282]],[[63815,63815],"mapped",[30922]],[[63816,63816],"mapped",[36034]],[[63817,63817],"mapped",[38647]],[[63818,63818],"mapped",[22744]],[[63819,63819],"mapped",[23650]],[[63820,63820],"mapped",[27155]],[[63821,63821],"mapped",[28122]],[[63822,63822],"mapped",[28431]],[[63823,63823],"mapped",[32047]],[[63824,63824],"mapped",[32311]],[[63825,63825],"mapped",[38475]],[[63826,63826],"mapped",[21202]],[[63827,63827],"mapped",[32907]],[[63828,63828],"mapped",[20956]],[[63829,63829],"mapped",[20940]],[[63830,63830],"mapped",[31260]],[[63831,63831],"mapped",[32190]],[[63832,63832],"mapped",[33777]],[[63833,63833],"mapped",[38517]],[[63834,63834],"mapped",[35712]],[[63835,63835],"mapped",[25295]],[[63836,63836],"mapped",[27138]],[[63837,63837],"mapped",[35582]],[[63838,63838],"mapped",[20025]],[[63839,63839],"mapped",[23527]],[[63840,63840],"mapped",[24594]],[[63841,63841],"mapped",[29575]],[[63842,63842],"mapped",[30064]],[[63843,63843],"mapped",[21271]],[[63844,63844],"mapped",[30971]],[[63845,63845],"mapped",[20415]],[[63846,63846],"mapped",[24489]],[[63847,63847],"mapped",[19981]],[[63848,63848],"mapped",[27852]],[[63849,63849],"mapped",[25976]],[[63850,63850],"mapped",[32034]],[[63851,63851],"mapped",[21443]],[[63852,63852],"mapped",[22622]],[[63853,63853],"mapped",[30465]],[[63854,63854],"mapped",[33865]],[[63855,63855],"mapped",[35498]],[[63856,63856],"mapped",[27578]],[[63857,63857],"mapped",[36784]],[[63858,63858],"mapped",[27784]],[[63859,63859],"mapped",[25342]],[[63860,63860],"mapped",[33509]],[[63861,63861],"mapped",[25504]],[[63862,63862],"mapped",[30053]],[[63863,63863],"mapped",[20142]],[[63864,63864],"mapped",[20841]],[[63865,63865],"mapped",[20937]],[[63866,63866],"mapped",[26753]],[[63867,63867],"mapped",[31975]],[[63868,63868],"mapped",[33391]],[[63869,63869],"mapped",[35538]],[[63870,63870],"mapped",[37327]],[[63871,63871],"mapped",[21237]],[[63872,63872],"mapped",[21570]],[[63873,63873],"mapped",[22899]],[[63874,63874],"mapped",[24300]],[[63875,63875],"mapped",[26053]],[[63876,63876],"mapped",[28670]],[[63877,63877],"mapped",[31018]],[[63878,63878],"mapped",[38317]],[[63879,63879],"mapped",[39530]],[[63880,63880],"mapped",[40599]],[[63881,63881],"mapped",[40654]],[[63882,63882],"mapped",[21147]],[[63883,63883],"mapped",[26310]],[[63884,63884],"mapped",[27511]],[[63885,63885],"mapped",[36706]],[[63886,63886],"mapped",[24180]],[[63887,63887],"mapped",[24976]],[[63888,63888],"mapped",[25088]],[[63889,63889],"mapped",[25754]],[[63890,63890],"mapped",[28451]],[[63891,63891],"mapped",[29001]],[[63892,63892],"mapped",[29833]],[[63893,63893],"mapped",[31178]],[[63894,63894],"mapped",[32244]],[[63895,63895],"mapped",[32879]],[[63896,63896],"mapped",[36646]],[[63897,63897],"mapped",[34030]],[[63898,63898],"mapped",[36899]],[[63899,63899],"mapped",[37706]],[[63900,63900],"mapped",[21015]],[[63901,63901],"mapped",[21155]],[[63902,63902],"mapped",[21693]],[[63903,63903],"mapped",[28872]],[[63904,63904],"mapped",[35010]],[[63905,63905],"mapped",[35498]],[[63906,63906],"mapped",[24265]],[[63907,63907],"mapped",[24565]],[[63908,63908],"mapped",[25467]],[[63909,63909],"mapped",[27566]],[[63910,63910],"mapped",[31806]],[[63911,63911],"mapped",[29557]],[[63912,63912],"mapped",[20196]],[[63913,63913],"mapped",[22265]],[[63914,63914],"mapped",[23527]],[[63915,63915],"mapped",[23994]],[[63916,63916],"mapped",[24604]],[[63917,63917],"mapped",[29618]],[[63918,63918],"mapped",[29801]],[[63919,63919],"mapped",[32666]],[[63920,63920],"mapped",[32838]],[[63921,63921],"mapped",[37428]],[[63922,63922],"mapped",[38646]],[[63923,63923],"mapped",[38728]],[[63924,63924],"mapped",[38936]],[[63925,63925],"mapped",[20363]],[[63926,63926],"mapped",[31150]],[[63927,63927],"mapped",[37300]],[[63928,63928],"mapped",[38584]],[[63929,63929],"mapped",[24801]],[[63930,63930],"mapped",[20102]],[[63931,63931],"mapped",[20698]],[[63932,63932],"mapped",[23534]],[[63933,63933],"mapped",[23615]],[[63934,63934],"mapped",[26009]],[[63935,63935],"mapped",[27138]],[[63936,63936],"mapped",[29134]],[[63937,63937],"mapped",[30274]],[[63938,63938],"mapped",[34044]],[[63939,63939],"mapped",[36988]],[[63940,63940],"mapped",[40845]],[[63941,63941],"mapped",[26248]],[[63942,63942],"mapped",[38446]],[[63943,63943],"mapped",[21129]],[[63944,63944],"mapped",[26491]],[[63945,63945],"mapped",[26611]],[[63946,63946],"mapped",[27969]],[[63947,63947],"mapped",[28316]],[[63948,63948],"mapped",[29705]],[[63949,63949],"mapped",[30041]],[[63950,63950],"mapped",[30827]],[[63951,63951],"mapped",[32016]],[[63952,63952],"mapped",[39006]],[[63953,63953],"mapped",[20845]],[[63954,63954],"mapped",[25134]],[[63955,63955],"mapped",[38520]],[[63956,63956],"mapped",[20523]],[[63957,63957],"mapped",[23833]],[[63958,63958],"mapped",[28138]],[[63959,63959],"mapped",[36650]],[[63960,63960],"mapped",[24459]],[[63961,63961],"mapped",[24900]],[[63962,63962],"mapped",[26647]],[[63963,63963],"mapped",[29575]],[[63964,63964],"mapped",[38534]],[[63965,63965],"mapped",[21033]],[[63966,63966],"mapped",[21519]],[[63967,63967],"mapped",[23653]],[[63968,63968],"mapped",[26131]],[[63969,63969],"mapped",[26446]],[[63970,63970],"mapped",[26792]],[[63971,63971],"mapped",[27877]],[[63972,63972],"mapped",[29702]],[[63973,63973],"mapped",[30178]],[[63974,63974],"mapped",[32633]],[[63975,63975],"mapped",[35023]],[[63976,63976],"mapped",[35041]],[[63977,63977],"mapped",[37324]],[[63978,63978],"mapped",[38626]],[[63979,63979],"mapped",[21311]],[[63980,63980],"mapped",[28346]],[[63981,63981],"mapped",[21533]],[[63982,63982],"mapped",[29136]],[[63983,63983],"mapped",[29848]],[[63984,63984],"mapped",[34298]],[[63985,63985],"mapped",[38563]],[[63986,63986],"mapped",[40023]],[[63987,63987],"mapped",[40607]],[[63988,63988],"mapped",[26519]],[[63989,63989],"mapped",[28107]],[[63990,63990],"mapped",[33256]],[[63991,63991],"mapped",[31435]],[[63992,63992],"mapped",[31520]],[[63993,63993],"mapped",[31890]],[[63994,63994],"mapped",[29376]],[[63995,63995],"mapped",[28825]],[[63996,63996],"mapped",[35672]],[[63997,63997],"mapped",[20160]],[[63998,63998],"mapped",[33590]],[[63999,63999],"mapped",[21050]],[[64000,64000],"mapped",[20999]],[[64001,64001],"mapped",[24230]],[[64002,64002],"mapped",[25299]],[[64003,64003],"mapped",[31958]],[[64004,64004],"mapped",[23429]],[[64005,64005],"mapped",[27934]],[[64006,64006],"mapped",[26292]],[[64007,64007],"mapped",[36667]],[[64008,64008],"mapped",[34892]],[[64009,64009],"mapped",[38477]],[[64010,64010],"mapped",[35211]],[[64011,64011],"mapped",[24275]],[[64012,64012],"mapped",[20800]],[[64013,64013],"mapped",[21952]],[[64014,64015],"valid"],[[64016,64016],"mapped",[22618]],[[64017,64017],"valid"],[[64018,64018],"mapped",[26228]],[[64019,64020],"valid"],[[64021,64021],"mapped",[20958]],[[64022,64022],"mapped",[29482]],[[64023,64023],"mapped",[30410]],[[64024,64024],"mapped",[31036]],[[64025,64025],"mapped",[31070]],[[64026,64026],"mapped",[31077]],[[64027,64027],"mapped",[31119]],[[64028,64028],"mapped",[38742]],[[64029,64029],"mapped",[31934]],[[64030,64030],"mapped",[32701]],[[64031,64031],"valid"],[[64032,64032],"mapped",[34322]],[[64033,64033],"valid"],[[64034,64034],"mapped",[35576]],[[64035,64036],"valid"],[[64037,64037],"mapped",[36920]],[[64038,64038],"mapped",[37117]],[[64039,64041],"valid"],[[64042,64042],"mapped",[39151]],[[64043,64043],"mapped",[39164]],[[64044,64044],"mapped",[39208]],[[64045,64045],"mapped",[40372]],[[64046,64046],"mapped",[37086]],[[64047,64047],"mapped",[38583]],[[64048,64048],"mapped",[20398]],[[64049,64049],"mapped",[20711]],[[64050,64050],"mapped",[20813]],[[64051,64051],"mapped",[21193]],[[64052,64052],"mapped",[21220]],[[64053,64053],"mapped",[21329]],[[64054,64054],"mapped",[21917]],[[64055,64055],"mapped",[22022]],[[64056,64056],"mapped",[22120]],[[64057,64057],"mapped",[22592]],[[64058,64058],"mapped",[22696]],[[64059,64059],"mapped",[23652]],[[64060,64060],"mapped",[23662]],[[64061,64061],"mapped",[24724]],[[64062,64062],"mapped",[24936]],[[64063,64063],"mapped",[24974]],[[64064,64064],"mapped",[25074]],[[64065,64065],"mapped",[25935]],[[64066,64066],"mapped",[26082]],[[64067,64067],"mapped",[26257]],[[64068,64068],"mapped",[26757]],[[64069,64069],"mapped",[28023]],[[64070,64070],"mapped",[28186]],[[64071,64071],"mapped",[28450]],[[64072,64072],"mapped",[29038]],[[64073,64073],"mapped",[29227]],[[64074,64074],"mapped",[29730]],[[64075,64075],"mapped",[30865]],[[64076,64076],"mapped",[31038]],[[64077,64077],"mapped",[31049]],[[64078,64078],"mapped",[31048]],[[64079,64079],"mapped",[31056]],[[64080,64080],"mapped",[31062]],[[64081,64081],"mapped",[31069]],[[64082,64082],"mapped",[31117]],[[64083,64083],"mapped",[31118]],[[64084,64084],"mapped",[31296]],[[64085,64085],"mapped",[31361]],[[64086,64086],"mapped",[31680]],[[64087,64087],"mapped",[32244]],[[64088,64088],"mapped",[32265]],[[64089,64089],"mapped",[32321]],[[64090,64090],"mapped",[32626]],[[64091,64091],"mapped",[32773]],[[64092,64092],"mapped",[33261]],[[64093,64094],"mapped",[33401]],[[64095,64095],"mapped",[33879]],[[64096,64096],"mapped",[35088]],[[64097,64097],"mapped",[35222]],[[64098,64098],"mapped",[35585]],[[64099,64099],"mapped",[35641]],[[64100,64100],"mapped",[36051]],[[64101,64101],"mapped",[36104]],[[64102,64102],"mapped",[36790]],[[64103,64103],"mapped",[36920]],[[64104,64104],"mapped",[38627]],[[64105,64105],"mapped",[38911]],[[64106,64106],"mapped",[38971]],[[64107,64107],"mapped",[24693]],[[64108,64108],"mapped",[148206]],[[64109,64109],"mapped",[33304]],[[64110,64111],"disallowed"],[[64112,64112],"mapped",[20006]],[[64113,64113],"mapped",[20917]],[[64114,64114],"mapped",[20840]],[[64115,64115],"mapped",[20352]],[[64116,64116],"mapped",[20805]],[[64117,64117],"mapped",[20864]],[[64118,64118],"mapped",[21191]],[[64119,64119],"mapped",[21242]],[[64120,64120],"mapped",[21917]],[[64121,64121],"mapped",[21845]],[[64122,64122],"mapped",[21913]],[[64123,64123],"mapped",[21986]],[[64124,64124],"mapped",[22618]],[[64125,64125],"mapped",[22707]],[[64126,64126],"mapped",[22852]],[[64127,64127],"mapped",[22868]],[[64128,64128],"mapped",[23138]],[[64129,64129],"mapped",[23336]],[[64130,64130],"mapped",[24274]],[[64131,64131],"mapped",[24281]],[[64132,64132],"mapped",[24425]],[[64133,64133],"mapped",[24493]],[[64134,64134],"mapped",[24792]],[[64135,64135],"mapped",[24910]],[[64136,64136],"mapped",[24840]],[[64137,64137],"mapped",[24974]],[[64138,64138],"mapped",[24928]],[[64139,64139],"mapped",[25074]],[[64140,64140],"mapped",[25140]],[[64141,64141],"mapped",[25540]],[[64142,64142],"mapped",[25628]],[[64143,64143],"mapped",[25682]],[[64144,64144],"mapped",[25942]],[[64145,64145],"mapped",[26228]],[[64146,64146],"mapped",[26391]],[[64147,64147],"mapped",[26395]],[[64148,64148],"mapped",[26454]],[[64149,64149],"mapped",[27513]],[[64150,64150],"mapped",[27578]],[[64151,64151],"mapped",[27969]],[[64152,64152],"mapped",[28379]],[[64153,64153],"mapped",[28363]],[[64154,64154],"mapped",[28450]],[[64155,64155],"mapped",[28702]],[[64156,64156],"mapped",[29038]],[[64157,64157],"mapped",[30631]],[[64158,64158],"mapped",[29237]],[[64159,64159],"mapped",[29359]],[[64160,64160],"mapped",[29482]],[[64161,64161],"mapped",[29809]],[[64162,64162],"mapped",[29958]],[[64163,64163],"mapped",[30011]],[[64164,64164],"mapped",[30237]],[[64165,64165],"mapped",[30239]],[[64166,64166],"mapped",[30410]],[[64167,64167],"mapped",[30427]],[[64168,64168],"mapped",[30452]],[[64169,64169],"mapped",[30538]],[[64170,64170],"mapped",[30528]],[[64171,64171],"mapped",[30924]],[[64172,64172],"mapped",[31409]],[[64173,64173],"mapped",[31680]],[[64174,64174],"mapped",[31867]],[[64175,64175],"mapped",[32091]],[[64176,64176],"mapped",[32244]],[[64177,64177],"mapped",[32574]],[[64178,64178],"mapped",[32773]],[[64179,64179],"mapped",[33618]],[[64180,64180],"mapped",[33775]],[[64181,64181],"mapped",[34681]],[[64182,64182],"mapped",[35137]],[[64183,64183],"mapped",[35206]],[[64184,64184],"mapped",[35222]],[[64185,64185],"mapped",[35519]],[[64186,64186],"mapped",[35576]],[[64187,64187],"mapped",[35531]],[[64188,64188],"mapped",[35585]],[[64189,64189],"mapped",[35582]],[[64190,64190],"mapped",[35565]],[[64191,64191],"mapped",[35641]],[[64192,64192],"mapped",[35722]],[[64193,64193],"mapped",[36104]],[[64194,64194],"mapped",[36664]],[[64195,64195],"mapped",[36978]],[[64196,64196],"mapped",[37273]],[[64197,64197],"mapped",[37494]],[[64198,64198],"mapped",[38524]],[[64199,64199],"mapped",[38627]],[[64200,64200],"mapped",[38742]],[[64201,64201],"mapped",[38875]],[[64202,64202],"mapped",[38911]],[[64203,64203],"mapped",[38923]],[[64204,64204],"mapped",[38971]],[[64205,64205],"mapped",[39698]],[[64206,64206],"mapped",[40860]],[[64207,64207],"mapped",[141386]],[[64208,64208],"mapped",[141380]],[[64209,64209],"mapped",[144341]],[[64210,64210],"mapped",[15261]],[[64211,64211],"mapped",[16408]],[[64212,64212],"mapped",[16441]],[[64213,64213],"mapped",[152137]],[[64214,64214],"mapped",[154832]],[[64215,64215],"mapped",[163539]],[[64216,64216],"mapped",[40771]],[[64217,64217],"mapped",[40846]],[[64218,64255],"disallowed"],[[64256,64256],"mapped",[102,102]],[[64257,64257],"mapped",[102,105]],[[64258,64258],"mapped",[102,108]],[[64259,64259],"mapped",[102,102,105]],[[64260,64260],"mapped",[102,102,108]],[[64261,64262],"mapped",[115,116]],[[64263,64274],"disallowed"],[[64275,64275],"mapped",[1396,1398]],[[64276,64276],"mapped",[1396,1381]],[[64277,64277],"mapped",[1396,1387]],[[64278,64278],"mapped",[1406,1398]],[[64279,64279],"mapped",[1396,1389]],[[64280,64284],"disallowed"],[[64285,64285],"mapped",[1497,1460]],[[64286,64286],"valid"],[[64287,64287],"mapped",[1522,1463]],[[64288,64288],"mapped",[1506]],[[64289,64289],"mapped",[1488]],[[64290,64290],"mapped",[1491]],[[64291,64291],"mapped",[1492]],[[64292,64292],"mapped",[1499]],[[64293,64293],"mapped",[1500]],[[64294,64294],"mapped",[1501]],[[64295,64295],"mapped",[1512]],[[64296,64296],"mapped",[1514]],[[64297,64297],"disallowed_STD3_mapped",[43]],[[64298,64298],"mapped",[1513,1473]],[[64299,64299],"mapped",[1513,1474]],[[64300,64300],"mapped",[1513,1468,1473]],[[64301,64301],"mapped",[1513,1468,1474]],[[64302,64302],"mapped",[1488,1463]],[[64303,64303],"mapped",[1488,1464]],[[64304,64304],"mapped",[1488,1468]],[[64305,64305],"mapped",[1489,1468]],[[64306,64306],"mapped",[1490,1468]],[[64307,64307],"mapped",[1491,1468]],[[64308,64308],"mapped",[1492,1468]],[[64309,64309],"mapped",[1493,1468]],[[64310,64310],"mapped",[1494,1468]],[[64311,64311],"disallowed"],[[64312,64312],"mapped",[1496,1468]],[[64313,64313],"mapped",[1497,1468]],[[64314,64314],"mapped",[1498,1468]],[[64315,64315],"mapped",[1499,1468]],[[64316,64316],"mapped",[1500,1468]],[[64317,64317],"disallowed"],[[64318,64318],"mapped",[1502,1468]],[[64319,64319],"disallowed"],[[64320,64320],"mapped",[1504,1468]],[[64321,64321],"mapped",[1505,1468]],[[64322,64322],"disallowed"],[[64323,64323],"mapped",[1507,1468]],[[64324,64324],"mapped",[1508,1468]],[[64325,64325],"disallowed"],[[64326,64326],"mapped",[1510,1468]],[[64327,64327],"mapped",[1511,1468]],[[64328,64328],"mapped",[1512,1468]],[[64329,64329],"mapped",[1513,1468]],[[64330,64330],"mapped",[1514,1468]],[[64331,64331],"mapped",[1493,1465]],[[64332,64332],"mapped",[1489,1471]],[[64333,64333],"mapped",[1499,1471]],[[64334,64334],"mapped",[1508,1471]],[[64335,64335],"mapped",[1488,1500]],[[64336,64337],"mapped",[1649]],[[64338,64341],"mapped",[1659]],[[64342,64345],"mapped",[1662]],[[64346,64349],"mapped",[1664]],[[64350,64353],"mapped",[1658]],[[64354,64357],"mapped",[1663]],[[64358,64361],"mapped",[1657]],[[64362,64365],"mapped",[1700]],[[64366,64369],"mapped",[1702]],[[64370,64373],"mapped",[1668]],[[64374,64377],"mapped",[1667]],[[64378,64381],"mapped",[1670]],[[64382,64385],"mapped",[1671]],[[64386,64387],"mapped",[1677]],[[64388,64389],"mapped",[1676]],[[64390,64391],"mapped",[1678]],[[64392,64393],"mapped",[1672]],[[64394,64395],"mapped",[1688]],[[64396,64397],"mapped",[1681]],[[64398,64401],"mapped",[1705]],[[64402,64405],"mapped",[1711]],[[64406,64409],"mapped",[1715]],[[64410,64413],"mapped",[1713]],[[64414,64415],"mapped",[1722]],[[64416,64419],"mapped",[1723]],[[64420,64421],"mapped",[1728]],[[64422,64425],"mapped",[1729]],[[64426,64429],"mapped",[1726]],[[64430,64431],"mapped",[1746]],[[64432,64433],"mapped",[1747]],[[64434,64449],"valid",[],"NV8"],[[64450,64466],"disallowed"],[[64467,64470],"mapped",[1709]],[[64471,64472],"mapped",[1735]],[[64473,64474],"mapped",[1734]],[[64475,64476],"mapped",[1736]],[[64477,64477],"mapped",[1735,1652]],[[64478,64479],"mapped",[1739]],[[64480,64481],"mapped",[1733]],[[64482,64483],"mapped",[1737]],[[64484,64487],"mapped",[1744]],[[64488,64489],"mapped",[1609]],[[64490,64491],"mapped",[1574,1575]],[[64492,64493],"mapped",[1574,1749]],[[64494,64495],"mapped",[1574,1608]],[[64496,64497],"mapped",[1574,1735]],[[64498,64499],"mapped",[1574,1734]],[[64500,64501],"mapped",[1574,1736]],[[64502,64504],"mapped",[1574,1744]],[[64505,64507],"mapped",[1574,1609]],[[64508,64511],"mapped",[1740]],[[64512,64512],"mapped",[1574,1580]],[[64513,64513],"mapped",[1574,1581]],[[64514,64514],"mapped",[1574,1605]],[[64515,64515],"mapped",[1574,1609]],[[64516,64516],"mapped",[1574,1610]],[[64517,64517],"mapped",[1576,1580]],[[64518,64518],"mapped",[1576,1581]],[[64519,64519],"mapped",[1576,1582]],[[64520,64520],"mapped",[1576,1605]],[[64521,64521],"mapped",[1576,1609]],[[64522,64522],"mapped",[1576,1610]],[[64523,64523],"mapped",[1578,1580]],[[64524,64524],"mapped",[1578,1581]],[[64525,64525],"mapped",[1578,1582]],[[64526,64526],"mapped",[1578,1605]],[[64527,64527],"mapped",[1578,1609]],[[64528,64528],"mapped",[1578,1610]],[[64529,64529],"mapped",[1579,1580]],[[64530,64530],"mapped",[1579,1605]],[[64531,64531],"mapped",[1579,1609]],[[64532,64532],"mapped",[1579,1610]],[[64533,64533],"mapped",[1580,1581]],[[64534,64534],"mapped",[1580,1605]],[[64535,64535],"mapped",[1581,1580]],[[64536,64536],"mapped",[1581,1605]],[[64537,64537],"mapped",[1582,1580]],[[64538,64538],"mapped",[1582,1581]],[[64539,64539],"mapped",[1582,1605]],[[64540,64540],"mapped",[1587,1580]],[[64541,64541],"mapped",[1587,1581]],[[64542,64542],"mapped",[1587,1582]],[[64543,64543],"mapped",[1587,1605]],[[64544,64544],"mapped",[1589,1581]],[[64545,64545],"mapped",[1589,1605]],[[64546,64546],"mapped",[1590,1580]],[[64547,64547],"mapped",[1590,1581]],[[64548,64548],"mapped",[1590,1582]],[[64549,64549],"mapped",[1590,1605]],[[64550,64550],"mapped",[1591,1581]],[[64551,64551],"mapped",[1591,1605]],[[64552,64552],"mapped",[1592,1605]],[[64553,64553],"mapped",[1593,1580]],[[64554,64554],"mapped",[1593,1605]],[[64555,64555],"mapped",[1594,1580]],[[64556,64556],"mapped",[1594,1605]],[[64557,64557],"mapped",[1601,1580]],[[64558,64558],"mapped",[1601,1581]],[[64559,64559],"mapped",[1601,1582]],[[64560,64560],"mapped",[1601,1605]],[[64561,64561],"mapped",[1601,1609]],[[64562,64562],"mapped",[1601,1610]],[[64563,64563],"mapped",[1602,1581]],[[64564,64564],"mapped",[1602,1605]],[[64565,64565],"mapped",[1602,1609]],[[64566,64566],"mapped",[1602,1610]],[[64567,64567],"mapped",[1603,1575]],[[64568,64568],"mapped",[1603,1580]],[[64569,64569],"mapped",[1603,1581]],[[64570,64570],"mapped",[1603,1582]],[[64571,64571],"mapped",[1603,1604]],[[64572,64572],"mapped",[1603,1605]],[[64573,64573],"mapped",[1603,1609]],[[64574,64574],"mapped",[1603,1610]],[[64575,64575],"mapped",[1604,1580]],[[64576,64576],"mapped",[1604,1581]],[[64577,64577],"mapped",[1604,1582]],[[64578,64578],"mapped",[1604,1605]],[[64579,64579],"mapped",[1604,1609]],[[64580,64580],"mapped",[1604,1610]],[[64581,64581],"mapped",[1605,1580]],[[64582,64582],"mapped",[1605,1581]],[[64583,64583],"mapped",[1605,1582]],[[64584,64584],"mapped",[1605,1605]],[[64585,64585],"mapped",[1605,1609]],[[64586,64586],"mapped",[1605,1610]],[[64587,64587],"mapped",[1606,1580]],[[64588,64588],"mapped",[1606,1581]],[[64589,64589],"mapped",[1606,1582]],[[64590,64590],"mapped",[1606,1605]],[[64591,64591],"mapped",[1606,1609]],[[64592,64592],"mapped",[1606,1610]],[[64593,64593],"mapped",[1607,1580]],[[64594,64594],"mapped",[1607,1605]],[[64595,64595],"mapped",[1607,1609]],[[64596,64596],"mapped",[1607,1610]],[[64597,64597],"mapped",[1610,1580]],[[64598,64598],"mapped",[1610,1581]],[[64599,64599],"mapped",[1610,1582]],[[64600,64600],"mapped",[1610,1605]],[[64601,64601],"mapped",[1610,1609]],[[64602,64602],"mapped",[1610,1610]],[[64603,64603],"mapped",[1584,1648]],[[64604,64604],"mapped",[1585,1648]],[[64605,64605],"mapped",[1609,1648]],[[64606,64606],"disallowed_STD3_mapped",[32,1612,1617]],[[64607,64607],"disallowed_STD3_mapped",[32,1613,1617]],[[64608,64608],"disallowed_STD3_mapped",[32,1614,1617]],[[64609,64609],"disallowed_STD3_mapped",[32,1615,1617]],[[64610,64610],"disallowed_STD3_mapped",[32,1616,1617]],[[64611,64611],"disallowed_STD3_mapped",[32,1617,1648]],[[64612,64612],"mapped",[1574,1585]],[[64613,64613],"mapped",[1574,1586]],[[64614,64614],"mapped",[1574,1605]],[[64615,64615],"mapped",[1574,1606]],[[64616,64616],"mapped",[1574,1609]],[[64617,64617],"mapped",[1574,1610]],[[64618,64618],"mapped",[1576,1585]],[[64619,64619],"mapped",[1576,1586]],[[64620,64620],"mapped",[1576,1605]],[[64621,64621],"mapped",[1576,1606]],[[64622,64622],"mapped",[1576,1609]],[[64623,64623],"mapped",[1576,1610]],[[64624,64624],"mapped",[1578,1585]],[[64625,64625],"mapped",[1578,1586]],[[64626,64626],"mapped",[1578,1605]],[[64627,64627],"mapped",[1578,1606]],[[64628,64628],"mapped",[1578,1609]],[[64629,64629],"mapped",[1578,1610]],[[64630,64630],"mapped",[1579,1585]],[[64631,64631],"mapped",[1579,1586]],[[64632,64632],"mapped",[1579,1605]],[[64633,64633],"mapped",[1579,1606]],[[64634,64634],"mapped",[1579,1609]],[[64635,64635],"mapped",[1579,1610]],[[64636,64636],"mapped",[1601,1609]],[[64637,64637],"mapped",[1601,1610]],[[64638,64638],"mapped",[1602,1609]],[[64639,64639],"mapped",[1602,1610]],[[64640,64640],"mapped",[1603,1575]],[[64641,64641],"mapped",[1603,1604]],[[64642,64642],"mapped",[1603,1605]],[[64643,64643],"mapped",[1603,1609]],[[64644,64644],"mapped",[1603,1610]],[[64645,64645],"mapped",[1604,1605]],[[64646,64646],"mapped",[1604,1609]],[[64647,64647],"mapped",[1604,1610]],[[64648,64648],"mapped",[1605,1575]],[[64649,64649],"mapped",[1605,1605]],[[64650,64650],"mapped",[1606,1585]],[[64651,64651],"mapped",[1606,1586]],[[64652,64652],"mapped",[1606,1605]],[[64653,64653],"mapped",[1606,1606]],[[64654,64654],"mapped",[1606,1609]],[[64655,64655],"mapped",[1606,1610]],[[64656,64656],"mapped",[1609,1648]],[[64657,64657],"mapped",[1610,1585]],[[64658,64658],"mapped",[1610,1586]],[[64659,64659],"mapped",[1610,1605]],[[64660,64660],"mapped",[1610,1606]],[[64661,64661],"mapped",[1610,1609]],[[64662,64662],"mapped",[1610,1610]],[[64663,64663],"mapped",[1574,1580]],[[64664,64664],"mapped",[1574,1581]],[[64665,64665],"mapped",[1574,1582]],[[64666,64666],"mapped",[1574,1605]],[[64667,64667],"mapped",[1574,1607]],[[64668,64668],"mapped",[1576,1580]],[[64669,64669],"mapped",[1576,1581]],[[64670,64670],"mapped",[1576,1582]],[[64671,64671],"mapped",[1576,1605]],[[64672,64672],"mapped",[1576,1607]],[[64673,64673],"mapped",[1578,1580]],[[64674,64674],"mapped",[1578,1581]],[[64675,64675],"mapped",[1578,1582]],[[64676,64676],"mapped",[1578,1605]],[[64677,64677],"mapped",[1578,1607]],[[64678,64678],"mapped",[1579,1605]],[[64679,64679],"mapped",[1580,1581]],[[64680,64680],"mapped",[1580,1605]],[[64681,64681],"mapped",[1581,1580]],[[64682,64682],"mapped",[1581,1605]],[[64683,64683],"mapped",[1582,1580]],[[64684,64684],"mapped",[1582,1605]],[[64685,64685],"mapped",[1587,1580]],[[64686,64686],"mapped",[1587,1581]],[[64687,64687],"mapped",[1587,1582]],[[64688,64688],"mapped",[1587,1605]],[[64689,64689],"mapped",[1589,1581]],[[64690,64690],"mapped",[1589,1582]],[[64691,64691],"mapped",[1589,1605]],[[64692,64692],"mapped",[1590,1580]],[[64693,64693],"mapped",[1590,1581]],[[64694,64694],"mapped",[1590,1582]],[[64695,64695],"mapped",[1590,1605]],[[64696,64696],"mapped",[1591,1581]],[[64697,64697],"mapped",[1592,1605]],[[64698,64698],"mapped",[1593,1580]],[[64699,64699],"mapped",[1593,1605]],[[64700,64700],"mapped",[1594,1580]],[[64701,64701],"mapped",[1594,1605]],[[64702,64702],"mapped",[1601,1580]],[[64703,64703],"mapped",[1601,1581]],[[64704,64704],"mapped",[1601,1582]],[[64705,64705],"mapped",[1601,1605]],[[64706,64706],"mapped",[1602,1581]],[[64707,64707],"mapped",[1602,1605]],[[64708,64708],"mapped",[1603,1580]],[[64709,64709],"mapped",[1603,1581]],[[64710,64710],"mapped",[1603,1582]],[[64711,64711],"mapped",[1603,1604]],[[64712,64712],"mapped",[1603,1605]],[[64713,64713],"mapped",[1604,1580]],[[64714,64714],"mapped",[1604,1581]],[[64715,64715],"mapped",[1604,1582]],[[64716,64716],"mapped",[1604,1605]],[[64717,64717],"mapped",[1604,1607]],[[64718,64718],"mapped",[1605,1580]],[[64719,64719],"mapped",[1605,1581]],[[64720,64720],"mapped",[1605,1582]],[[64721,64721],"mapped",[1605,1605]],[[64722,64722],"mapped",[1606,1580]],[[64723,64723],"mapped",[1606,1581]],[[64724,64724],"mapped",[1606,1582]],[[64725,64725],"mapped",[1606,1605]],[[64726,64726],"mapped",[1606,1607]],[[64727,64727],"mapped",[1607,1580]],[[64728,64728],"mapped",[1607,1605]],[[64729,64729],"mapped",[1607,1648]],[[64730,64730],"mapped",[1610,1580]],[[64731,64731],"mapped",[1610,1581]],[[64732,64732],"mapped",[1610,1582]],[[64733,64733],"mapped",[1610,1605]],[[64734,64734],"mapped",[1610,1607]],[[64735,64735],"mapped",[1574,1605]],[[64736,64736],"mapped",[1574,1607]],[[64737,64737],"mapped",[1576,1605]],[[64738,64738],"mapped",[1576,1607]],[[64739,64739],"mapped",[1578,1605]],[[64740,64740],"mapped",[1578,1607]],[[64741,64741],"mapped",[1579,1605]],[[64742,64742],"mapped",[1579,1607]],[[64743,64743],"mapped",[1587,1605]],[[64744,64744],"mapped",[1587,1607]],[[64745,64745],"mapped",[1588,1605]],[[64746,64746],"mapped",[1588,1607]],[[64747,64747],"mapped",[1603,1604]],[[64748,64748],"mapped",[1603,1605]],[[64749,64749],"mapped",[1604,1605]],[[64750,64750],"mapped",[1606,1605]],[[64751,64751],"mapped",[1606,1607]],[[64752,64752],"mapped",[1610,1605]],[[64753,64753],"mapped",[1610,1607]],[[64754,64754],"mapped",[1600,1614,1617]],[[64755,64755],"mapped",[1600,1615,1617]],[[64756,64756],"mapped",[1600,1616,1617]],[[64757,64757],"mapped",[1591,1609]],[[64758,64758],"mapped",[1591,1610]],[[64759,64759],"mapped",[1593,1609]],[[64760,64760],"mapped",[1593,1610]],[[64761,64761],"mapped",[1594,1609]],[[64762,64762],"mapped",[1594,1610]],[[64763,64763],"mapped",[1587,1609]],[[64764,64764],"mapped",[1587,1610]],[[64765,64765],"mapped",[1588,1609]],[[64766,64766],"mapped",[1588,1610]],[[64767,64767],"mapped",[1581,1609]],[[64768,64768],"mapped",[1581,1610]],[[64769,64769],"mapped",[1580,1609]],[[64770,64770],"mapped",[1580,1610]],[[64771,64771],"mapped",[1582,1609]],[[64772,64772],"mapped",[1582,1610]],[[64773,64773],"mapped",[1589,1609]],[[64774,64774],"mapped",[1589,1610]],[[64775,64775],"mapped",[1590,1609]],[[64776,64776],"mapped",[1590,1610]],[[64777,64777],"mapped",[1588,1580]],[[64778,64778],"mapped",[1588,1581]],[[64779,64779],"mapped",[1588,1582]],[[64780,64780],"mapped",[1588,1605]],[[64781,64781],"mapped",[1588,1585]],[[64782,64782],"mapped",[1587,1585]],[[64783,64783],"mapped",[1589,1585]],[[64784,64784],"mapped",[1590,1585]],[[64785,64785],"mapped",[1591,1609]],[[64786,64786],"mapped",[1591,1610]],[[64787,64787],"mapped",[1593,1609]],[[64788,64788],"mapped",[1593,1610]],[[64789,64789],"mapped",[1594,1609]],[[64790,64790],"mapped",[1594,1610]],[[64791,64791],"mapped",[1587,1609]],[[64792,64792],"mapped",[1587,1610]],[[64793,64793],"mapped",[1588,1609]],[[64794,64794],"mapped",[1588,1610]],[[64795,64795],"mapped",[1581,1609]],[[64796,64796],"mapped",[1581,1610]],[[64797,64797],"mapped",[1580,1609]],[[64798,64798],"mapped",[1580,1610]],[[64799,64799],"mapped",[1582,1609]],[[64800,64800],"mapped",[1582,1610]],[[64801,64801],"mapped",[1589,1609]],[[64802,64802],"mapped",[1589,1610]],[[64803,64803],"mapped",[1590,1609]],[[64804,64804],"mapped",[1590,1610]],[[64805,64805],"mapped",[1588,1580]],[[64806,64806],"mapped",[1588,1581]],[[64807,64807],"mapped",[1588,1582]],[[64808,64808],"mapped",[1588,1605]],[[64809,64809],"mapped",[1588,1585]],[[64810,64810],"mapped",[1587,1585]],[[64811,64811],"mapped",[1589,1585]],[[64812,64812],"mapped",[1590,1585]],[[64813,64813],"mapped",[1588,1580]],[[64814,64814],"mapped",[1588,1581]],[[64815,64815],"mapped",[1588,1582]],[[64816,64816],"mapped",[1588,1605]],[[64817,64817],"mapped",[1587,1607]],[[64818,64818],"mapped",[1588,1607]],[[64819,64819],"mapped",[1591,1605]],[[64820,64820],"mapped",[1587,1580]],[[64821,64821],"mapped",[1587,1581]],[[64822,64822],"mapped",[1587,1582]],[[64823,64823],"mapped",[1588,1580]],[[64824,64824],"mapped",[1588,1581]],[[64825,64825],"mapped",[1588,1582]],[[64826,64826],"mapped",[1591,1605]],[[64827,64827],"mapped",[1592,1605]],[[64828,64829],"mapped",[1575,1611]],[[64830,64831],"valid",[],"NV8"],[[64832,64847],"disallowed"],[[64848,64848],"mapped",[1578,1580,1605]],[[64849,64850],"mapped",[1578,1581,1580]],[[64851,64851],"mapped",[1578,1581,1605]],[[64852,64852],"mapped",[1578,1582,1605]],[[64853,64853],"mapped",[1578,1605,1580]],[[64854,64854],"mapped",[1578,1605,1581]],[[64855,64855],"mapped",[1578,1605,1582]],[[64856,64857],"mapped",[1580,1605,1581]],[[64858,64858],"mapped",[1581,1605,1610]],[[64859,64859],"mapped",[1581,1605,1609]],[[64860,64860],"mapped",[1587,1581,1580]],[[64861,64861],"mapped",[1587,1580,1581]],[[64862,64862],"mapped",[1587,1580,1609]],[[64863,64864],"mapped",[1587,1605,1581]],[[64865,64865],"mapped",[1587,1605,1580]],[[64866,64867],"mapped",[1587,1605,1605]],[[64868,64869],"mapped",[1589,1581,1581]],[[64870,64870],"mapped",[1589,1605,1605]],[[64871,64872],"mapped",[1588,1581,1605]],[[64873,64873],"mapped",[1588,1580,1610]],[[64874,64875],"mapped",[1588,1605,1582]],[[64876,64877],"mapped",[1588,1605,1605]],[[64878,64878],"mapped",[1590,1581,1609]],[[64879,64880],"mapped",[1590,1582,1605]],[[64881,64882],"mapped",[1591,1605,1581]],[[64883,64883],"mapped",[1591,1605,1605]],[[64884,64884],"mapped",[1591,1605,1610]],[[64885,64885],"mapped",[1593,1580,1605]],[[64886,64887],"mapped",[1593,1605,1605]],[[64888,64888],"mapped",[1593,1605,1609]],[[64889,64889],"mapped",[1594,1605,1605]],[[64890,64890],"mapped",[1594,1605,1610]],[[64891,64891],"mapped",[1594,1605,1609]],[[64892,64893],"mapped",[1601,1582,1605]],[[64894,64894],"mapped",[1602,1605,1581]],[[64895,64895],"mapped",[1602,1605,1605]],[[64896,64896],"mapped",[1604,1581,1605]],[[64897,64897],"mapped",[1604,1581,1610]],[[64898,64898],"mapped",[1604,1581,1609]],[[64899,64900],"mapped",[1604,1580,1580]],[[64901,64902],"mapped",[1604,1582,1605]],[[64903,64904],"mapped",[1604,1605,1581]],[[64905,64905],"mapped",[1605,1581,1580]],[[64906,64906],"mapped",[1605,1581,1605]],[[64907,64907],"mapped",[1605,1581,1610]],[[64908,64908],"mapped",[1605,1580,1581]],[[64909,64909],"mapped",[1605,1580,1605]],[[64910,64910],"mapped",[1605,1582,1580]],[[64911,64911],"mapped",[1605,1582,1605]],[[64912,64913],"disallowed"],[[64914,64914],"mapped",[1605,1580,1582]],[[64915,64915],"mapped",[1607,1605,1580]],[[64916,64916],"mapped",[1607,1605,1605]],[[64917,64917],"mapped",[1606,1581,1605]],[[64918,64918],"mapped",[1606,1581,1609]],[[64919,64920],"mapped",[1606,1580,1605]],[[64921,64921],"mapped",[1606,1580,1609]],[[64922,64922],"mapped",[1606,1605,1610]],[[64923,64923],"mapped",[1606,1605,1609]],[[64924,64925],"mapped",[1610,1605,1605]],[[64926,64926],"mapped",[1576,1582,1610]],[[64927,64927],"mapped",[1578,1580,1610]],[[64928,64928],"mapped",[1578,1580,1609]],[[64929,64929],"mapped",[1578,1582,1610]],[[64930,64930],"mapped",[1578,1582,1609]],[[64931,64931],"mapped",[1578,1605,1610]],[[64932,64932],"mapped",[1578,1605,1609]],[[64933,64933],"mapped",[1580,1605,1610]],[[64934,64934],"mapped",[1580,1581,1609]],[[64935,64935],"mapped",[1580,1605,1609]],[[64936,64936],"mapped",[1587,1582,1609]],[[64937,64937],"mapped",[1589,1581,1610]],[[64938,64938],"mapped",[1588,1581,1610]],[[64939,64939],"mapped",[1590,1581,1610]],[[64940,64940],"mapped",[1604,1580,1610]],[[64941,64941],"mapped",[1604,1605,1610]],[[64942,64942],"mapped",[1610,1581,1610]],[[64943,64943],"mapped",[1610,1580,1610]],[[64944,64944],"mapped",[1610,1605,1610]],[[64945,64945],"mapped",[1605,1605,1610]],[[64946,64946],"mapped",[1602,1605,1610]],[[64947,64947],"mapped",[1606,1581,1610]],[[64948,64948],"mapped",[1602,1605,1581]],[[64949,64949],"mapped",[1604,1581,1605]],[[64950,64950],"mapped",[1593,1605,1610]],[[64951,64951],"mapped",[1603,1605,1610]],[[64952,64952],"mapped",[1606,1580,1581]],[[64953,64953],"mapped",[1605,1582,1610]],[[64954,64954],"mapped",[1604,1580,1605]],[[64955,64955],"mapped",[1603,1605,1605]],[[64956,64956],"mapped",[1604,1580,1605]],[[64957,64957],"mapped",[1606,1580,1581]],[[64958,64958],"mapped",[1580,1581,1610]],[[64959,64959],"mapped",[1581,1580,1610]],[[64960,64960],"mapped",[1605,1580,1610]],[[64961,64961],"mapped",[1601,1605,1610]],[[64962,64962],"mapped",[1576,1581,1610]],[[64963,64963],"mapped",[1603,1605,1605]],[[64964,64964],"mapped",[1593,1580,1605]],[[64965,64965],"mapped",[1589,1605,1605]],[[64966,64966],"mapped",[1587,1582,1610]],[[64967,64967],"mapped",[1606,1580,1610]],[[64968,64975],"disallowed"],[[64976,65007],"disallowed"],[[65008,65008],"mapped",[1589,1604,1746]],[[65009,65009],"mapped",[1602,1604,1746]],[[65010,65010],"mapped",[1575,1604,1604,1607]],[[65011,65011],"mapped",[1575,1603,1576,1585]],[[65012,65012],"mapped",[1605,1581,1605,1583]],[[65013,65013],"mapped",[1589,1604,1593,1605]],[[65014,65014],"mapped",[1585,1587,1608,1604]],[[65015,65015],"mapped",[1593,1604,1610,1607]],[[65016,65016],"mapped",[1608,1587,1604,1605]],[[65017,65017],"mapped",[1589,1604,1609]],[[65018,65018],"disallowed_STD3_mapped",[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605]],[[65019,65019],"disallowed_STD3_mapped",[1580,1604,32,1580,1604,1575,1604,1607]],[[65020,65020],"mapped",[1585,1740,1575,1604]],[[65021,65021],"valid",[],"NV8"],[[65022,65023],"disallowed"],[[65024,65039],"ignored"],[[65040,65040],"disallowed_STD3_mapped",[44]],[[65041,65041],"mapped",[12289]],[[65042,65042],"disallowed"],[[65043,65043],"disallowed_STD3_mapped",[58]],[[65044,65044],"disallowed_STD3_mapped",[59]],[[65045,65045],"disallowed_STD3_mapped",[33]],[[65046,65046],"disallowed_STD3_mapped",[63]],[[65047,65047],"mapped",[12310]],[[65048,65048],"mapped",[12311]],[[65049,65049],"disallowed"],[[65050,65055],"disallowed"],[[65056,65059],"valid"],[[65060,65062],"valid"],[[65063,65069],"valid"],[[65070,65071],"valid"],[[65072,65072],"disallowed"],[[65073,65073],"mapped",[8212]],[[65074,65074],"mapped",[8211]],[[65075,65076],"disallowed_STD3_mapped",[95]],[[65077,65077],"disallowed_STD3_mapped",[40]],[[65078,65078],"disallowed_STD3_mapped",[41]],[[65079,65079],"disallowed_STD3_mapped",[123]],[[65080,65080],"disallowed_STD3_mapped",[125]],[[65081,65081],"mapped",[12308]],[[65082,65082],"mapped",[12309]],[[65083,65083],"mapped",[12304]],[[65084,65084],"mapped",[12305]],[[65085,65085],"mapped",[12298]],[[65086,65086],"mapped",[12299]],[[65087,65087],"mapped",[12296]],[[65088,65088],"mapped",[12297]],[[65089,65089],"mapped",[12300]],[[65090,65090],"mapped",[12301]],[[65091,65091],"mapped",[12302]],[[65092,65092],"mapped",[12303]],[[65093,65094],"valid",[],"NV8"],[[65095,65095],"disallowed_STD3_mapped",[91]],[[65096,65096],"disallowed_STD3_mapped",[93]],[[65097,65100],"disallowed_STD3_mapped",[32,773]],[[65101,65103],"disallowed_STD3_mapped",[95]],[[65104,65104],"disallowed_STD3_mapped",[44]],[[65105,65105],"mapped",[12289]],[[65106,65106],"disallowed"],[[65107,65107],"disallowed"],[[65108,65108],"disallowed_STD3_mapped",[59]],[[65109,65109],"disallowed_STD3_mapped",[58]],[[65110,65110],"disallowed_STD3_mapped",[63]],[[65111,65111],"disallowed_STD3_mapped",[33]],[[65112,65112],"mapped",[8212]],[[65113,65113],"disallowed_STD3_mapped",[40]],[[65114,65114],"disallowed_STD3_mapped",[41]],[[65115,65115],"disallowed_STD3_mapped",[123]],[[65116,65116],"disallowed_STD3_mapped",[125]],[[65117,65117],"mapped",[12308]],[[65118,65118],"mapped",[12309]],[[65119,65119],"disallowed_STD3_mapped",[35]],[[65120,65120],"disallowed_STD3_mapped",[38]],[[65121,65121],"disallowed_STD3_mapped",[42]],[[65122,65122],"disallowed_STD3_mapped",[43]],[[65123,65123],"mapped",[45]],[[65124,65124],"disallowed_STD3_mapped",[60]],[[65125,65125],"disallowed_STD3_mapped",[62]],[[65126,65126],"disallowed_STD3_mapped",[61]],[[65127,65127],"disallowed"],[[65128,65128],"disallowed_STD3_mapped",[92]],[[65129,65129],"disallowed_STD3_mapped",[36]],[[65130,65130],"disallowed_STD3_mapped",[37]],[[65131,65131],"disallowed_STD3_mapped",[64]],[[65132,65135],"disallowed"],[[65136,65136],"disallowed_STD3_mapped",[32,1611]],[[65137,65137],"mapped",[1600,1611]],[[65138,65138],"disallowed_STD3_mapped",[32,1612]],[[65139,65139],"valid"],[[65140,65140],"disallowed_STD3_mapped",[32,1613]],[[65141,65141],"disallowed"],[[65142,65142],"disallowed_STD3_mapped",[32,1614]],[[65143,65143],"mapped",[1600,1614]],[[65144,65144],"disallowed_STD3_mapped",[32,1615]],[[65145,65145],"mapped",[1600,1615]],[[65146,65146],"disallowed_STD3_mapped",[32,1616]],[[65147,65147],"mapped",[1600,1616]],[[65148,65148],"disallowed_STD3_mapped",[32,1617]],[[65149,65149],"mapped",[1600,1617]],[[65150,65150],"disallowed_STD3_mapped",[32,1618]],[[65151,65151],"mapped",[1600,1618]],[[65152,65152],"mapped",[1569]],[[65153,65154],"mapped",[1570]],[[65155,65156],"mapped",[1571]],[[65157,65158],"mapped",[1572]],[[65159,65160],"mapped",[1573]],[[65161,65164],"mapped",[1574]],[[65165,65166],"mapped",[1575]],[[65167,65170],"mapped",[1576]],[[65171,65172],"mapped",[1577]],[[65173,65176],"mapped",[1578]],[[65177,65180],"mapped",[1579]],[[65181,65184],"mapped",[1580]],[[65185,65188],"mapped",[1581]],[[65189,65192],"mapped",[1582]],[[65193,65194],"mapped",[1583]],[[65195,65196],"mapped",[1584]],[[65197,65198],"mapped",[1585]],[[65199,65200],"mapped",[1586]],[[65201,65204],"mapped",[1587]],[[65205,65208],"mapped",[1588]],[[65209,65212],"mapped",[1589]],[[65213,65216],"mapped",[1590]],[[65217,65220],"mapped",[1591]],[[65221,65224],"mapped",[1592]],[[65225,65228],"mapped",[1593]],[[65229,65232],"mapped",[1594]],[[65233,65236],"mapped",[1601]],[[65237,65240],"mapped",[1602]],[[65241,65244],"mapped",[1603]],[[65245,65248],"mapped",[1604]],[[65249,65252],"mapped",[1605]],[[65253,65256],"mapped",[1606]],[[65257,65260],"mapped",[1607]],[[65261,65262],"mapped",[1608]],[[65263,65264],"mapped",[1609]],[[65265,65268],"mapped",[1610]],[[65269,65270],"mapped",[1604,1570]],[[65271,65272],"mapped",[1604,1571]],[[65273,65274],"mapped",[1604,1573]],[[65275,65276],"mapped",[1604,1575]],[[65277,65278],"disallowed"],[[65279,65279],"ignored"],[[65280,65280],"disallowed"],[[65281,65281],"disallowed_STD3_mapped",[33]],[[65282,65282],"disallowed_STD3_mapped",[34]],[[65283,65283],"disallowed_STD3_mapped",[35]],[[65284,65284],"disallowed_STD3_mapped",[36]],[[65285,65285],"disallowed_STD3_mapped",[37]],[[65286,65286],"disallowed_STD3_mapped",[38]],[[65287,65287],"disallowed_STD3_mapped",[39]],[[65288,65288],"disallowed_STD3_mapped",[40]],[[65289,65289],"disallowed_STD3_mapped",[41]],[[65290,65290],"disallowed_STD3_mapped",[42]],[[65291,65291],"disallowed_STD3_mapped",[43]],[[65292,65292],"disallowed_STD3_mapped",[44]],[[65293,65293],"mapped",[45]],[[65294,65294],"mapped",[46]],[[65295,65295],"disallowed_STD3_mapped",[47]],[[65296,65296],"mapped",[48]],[[65297,65297],"mapped",[49]],[[65298,65298],"mapped",[50]],[[65299,65299],"mapped",[51]],[[65300,65300],"mapped",[52]],[[65301,65301],"mapped",[53]],[[65302,65302],"mapped",[54]],[[65303,65303],"mapped",[55]],[[65304,65304],"mapped",[56]],[[65305,65305],"mapped",[57]],[[65306,65306],"disallowed_STD3_mapped",[58]],[[65307,65307],"disallowed_STD3_mapped",[59]],[[65308,65308],"disallowed_STD3_mapped",[60]],[[65309,65309],"disallowed_STD3_mapped",[61]],[[65310,65310],"disallowed_STD3_mapped",[62]],[[65311,65311],"disallowed_STD3_mapped",[63]],[[65312,65312],"disallowed_STD3_mapped",[64]],[[65313,65313],"mapped",[97]],[[65314,65314],"mapped",[98]],[[65315,65315],"mapped",[99]],[[65316,65316],"mapped",[100]],[[65317,65317],"mapped",[101]],[[65318,65318],"mapped",[102]],[[65319,65319],"mapped",[103]],[[65320,65320],"mapped",[104]],[[65321,65321],"mapped",[105]],[[65322,65322],"mapped",[106]],[[65323,65323],"mapped",[107]],[[65324,65324],"mapped",[108]],[[65325,65325],"mapped",[109]],[[65326,65326],"mapped",[110]],[[65327,65327],"mapped",[111]],[[65328,65328],"mapped",[112]],[[65329,65329],"mapped",[113]],[[65330,65330],"mapped",[114]],[[65331,65331],"mapped",[115]],[[65332,65332],"mapped",[116]],[[65333,65333],"mapped",[117]],[[65334,65334],"mapped",[118]],[[65335,65335],"mapped",[119]],[[65336,65336],"mapped",[120]],[[65337,65337],"mapped",[121]],[[65338,65338],"mapped",[122]],[[65339,65339],"disallowed_STD3_mapped",[91]],[[65340,65340],"disallowed_STD3_mapped",[92]],[[65341,65341],"disallowed_STD3_mapped",[93]],[[65342,65342],"disallowed_STD3_mapped",[94]],[[65343,65343],"disallowed_STD3_mapped",[95]],[[65344,65344],"disallowed_STD3_mapped",[96]],[[65345,65345],"mapped",[97]],[[65346,65346],"mapped",[98]],[[65347,65347],"mapped",[99]],[[65348,65348],"mapped",[100]],[[65349,65349],"mapped",[101]],[[65350,65350],"mapped",[102]],[[65351,65351],"mapped",[103]],[[65352,65352],"mapped",[104]],[[65353,65353],"mapped",[105]],[[65354,65354],"mapped",[106]],[[65355,65355],"mapped",[107]],[[65356,65356],"mapped",[108]],[[65357,65357],"mapped",[109]],[[65358,65358],"mapped",[110]],[[65359,65359],"mapped",[111]],[[65360,65360],"mapped",[112]],[[65361,65361],"mapped",[113]],[[65362,65362],"mapped",[114]],[[65363,65363],"mapped",[115]],[[65364,65364],"mapped",[116]],[[65365,65365],"mapped",[117]],[[65366,65366],"mapped",[118]],[[65367,65367],"mapped",[119]],[[65368,65368],"mapped",[120]],[[65369,65369],"mapped",[121]],[[65370,65370],"mapped",[122]],[[65371,65371],"disallowed_STD3_mapped",[123]],[[65372,65372],"disallowed_STD3_mapped",[124]],[[65373,65373],"disallowed_STD3_mapped",[125]],[[65374,65374],"disallowed_STD3_mapped",[126]],[[65375,65375],"mapped",[10629]],[[65376,65376],"mapped",[10630]],[[65377,65377],"mapped",[46]],[[65378,65378],"mapped",[12300]],[[65379,65379],"mapped",[12301]],[[65380,65380],"mapped",[12289]],[[65381,65381],"mapped",[12539]],[[65382,65382],"mapped",[12530]],[[65383,65383],"mapped",[12449]],[[65384,65384],"mapped",[12451]],[[65385,65385],"mapped",[12453]],[[65386,65386],"mapped",[12455]],[[65387,65387],"mapped",[12457]],[[65388,65388],"mapped",[12515]],[[65389,65389],"mapped",[12517]],[[65390,65390],"mapped",[12519]],[[65391,65391],"mapped",[12483]],[[65392,65392],"mapped",[12540]],[[65393,65393],"mapped",[12450]],[[65394,65394],"mapped",[12452]],[[65395,65395],"mapped",[12454]],[[65396,65396],"mapped",[12456]],[[65397,65397],"mapped",[12458]],[[65398,65398],"mapped",[12459]],[[65399,65399],"mapped",[12461]],[[65400,65400],"mapped",[12463]],[[65401,65401],"mapped",[12465]],[[65402,65402],"mapped",[12467]],[[65403,65403],"mapped",[12469]],[[65404,65404],"mapped",[12471]],[[65405,65405],"mapped",[12473]],[[65406,65406],"mapped",[12475]],[[65407,65407],"mapped",[12477]],[[65408,65408],"mapped",[12479]],[[65409,65409],"mapped",[12481]],[[65410,65410],"mapped",[12484]],[[65411,65411],"mapped",[12486]],[[65412,65412],"mapped",[12488]],[[65413,65413],"mapped",[12490]],[[65414,65414],"mapped",[12491]],[[65415,65415],"mapped",[12492]],[[65416,65416],"mapped",[12493]],[[65417,65417],"mapped",[12494]],[[65418,65418],"mapped",[12495]],[[65419,65419],"mapped",[12498]],[[65420,65420],"mapped",[12501]],[[65421,65421],"mapped",[12504]],[[65422,65422],"mapped",[12507]],[[65423,65423],"mapped",[12510]],[[65424,65424],"mapped",[12511]],[[65425,65425],"mapped",[12512]],[[65426,65426],"mapped",[12513]],[[65427,65427],"mapped",[12514]],[[65428,65428],"mapped",[12516]],[[65429,65429],"mapped",[12518]],[[65430,65430],"mapped",[12520]],[[65431,65431],"mapped",[12521]],[[65432,65432],"mapped",[12522]],[[65433,65433],"mapped",[12523]],[[65434,65434],"mapped",[12524]],[[65435,65435],"mapped",[12525]],[[65436,65436],"mapped",[12527]],[[65437,65437],"mapped",[12531]],[[65438,65438],"mapped",[12441]],[[65439,65439],"mapped",[12442]],[[65440,65440],"disallowed"],[[65441,65441],"mapped",[4352]],[[65442,65442],"mapped",[4353]],[[65443,65443],"mapped",[4522]],[[65444,65444],"mapped",[4354]],[[65445,65445],"mapped",[4524]],[[65446,65446],"mapped",[4525]],[[65447,65447],"mapped",[4355]],[[65448,65448],"mapped",[4356]],[[65449,65449],"mapped",[4357]],[[65450,65450],"mapped",[4528]],[[65451,65451],"mapped",[4529]],[[65452,65452],"mapped",[4530]],[[65453,65453],"mapped",[4531]],[[65454,65454],"mapped",[4532]],[[65455,65455],"mapped",[4533]],[[65456,65456],"mapped",[4378]],[[65457,65457],"mapped",[4358]],[[65458,65458],"mapped",[4359]],[[65459,65459],"mapped",[4360]],[[65460,65460],"mapped",[4385]],[[65461,65461],"mapped",[4361]],[[65462,65462],"mapped",[4362]],[[65463,65463],"mapped",[4363]],[[65464,65464],"mapped",[4364]],[[65465,65465],"mapped",[4365]],[[65466,65466],"mapped",[4366]],[[65467,65467],"mapped",[4367]],[[65468,65468],"mapped",[4368]],[[65469,65469],"mapped",[4369]],[[65470,65470],"mapped",[4370]],[[65471,65473],"disallowed"],[[65474,65474],"mapped",[4449]],[[65475,65475],"mapped",[4450]],[[65476,65476],"mapped",[4451]],[[65477,65477],"mapped",[4452]],[[65478,65478],"mapped",[4453]],[[65479,65479],"mapped",[4454]],[[65480,65481],"disallowed"],[[65482,65482],"mapped",[4455]],[[65483,65483],"mapped",[4456]],[[65484,65484],"mapped",[4457]],[[65485,65485],"mapped",[4458]],[[65486,65486],"mapped",[4459]],[[65487,65487],"mapped",[4460]],[[65488,65489],"disallowed"],[[65490,65490],"mapped",[4461]],[[65491,65491],"mapped",[4462]],[[65492,65492],"mapped",[4463]],[[65493,65493],"mapped",[4464]],[[65494,65494],"mapped",[4465]],[[65495,65495],"mapped",[4466]],[[65496,65497],"disallowed"],[[65498,65498],"mapped",[4467]],[[65499,65499],"mapped",[4468]],[[65500,65500],"mapped",[4469]],[[65501,65503],"disallowed"],[[65504,65504],"mapped",[162]],[[65505,65505],"mapped",[163]],[[65506,65506],"mapped",[172]],[[65507,65507],"disallowed_STD3_mapped",[32,772]],[[65508,65508],"mapped",[166]],[[65509,65509],"mapped",[165]],[[65510,65510],"mapped",[8361]],[[65511,65511],"disallowed"],[[65512,65512],"mapped",[9474]],[[65513,65513],"mapped",[8592]],[[65514,65514],"mapped",[8593]],[[65515,65515],"mapped",[8594]],[[65516,65516],"mapped",[8595]],[[65517,65517],"mapped",[9632]],[[65518,65518],"mapped",[9675]],[[65519,65528],"disallowed"],[[65529,65531],"disallowed"],[[65532,65532],"disallowed"],[[65533,65533],"disallowed"],[[65534,65535],"disallowed"],[[65536,65547],"valid"],[[65548,65548],"disallowed"],[[65549,65574],"valid"],[[65575,65575],"disallowed"],[[65576,65594],"valid"],[[65595,65595],"disallowed"],[[65596,65597],"valid"],[[65598,65598],"disallowed"],[[65599,65613],"valid"],[[65614,65615],"disallowed"],[[65616,65629],"valid"],[[65630,65663],"disallowed"],[[65664,65786],"valid"],[[65787,65791],"disallowed"],[[65792,65794],"valid",[],"NV8"],[[65795,65798],"disallowed"],[[65799,65843],"valid",[],"NV8"],[[65844,65846],"disallowed"],[[65847,65855],"valid",[],"NV8"],[[65856,65930],"valid",[],"NV8"],[[65931,65932],"valid",[],"NV8"],[[65933,65935],"disallowed"],[[65936,65947],"valid",[],"NV8"],[[65948,65951],"disallowed"],[[65952,65952],"valid",[],"NV8"],[[65953,65999],"disallowed"],[[66000,66044],"valid",[],"NV8"],[[66045,66045],"valid"],[[66046,66175],"disallowed"],[[66176,66204],"valid"],[[66205,66207],"disallowed"],[[66208,66256],"valid"],[[66257,66271],"disallowed"],[[66272,66272],"valid"],[[66273,66299],"valid",[],"NV8"],[[66300,66303],"disallowed"],[[66304,66334],"valid"],[[66335,66335],"valid"],[[66336,66339],"valid",[],"NV8"],[[66340,66351],"disallowed"],[[66352,66368],"valid"],[[66369,66369],"valid",[],"NV8"],[[66370,66377],"valid"],[[66378,66378],"valid",[],"NV8"],[[66379,66383],"disallowed"],[[66384,66426],"valid"],[[66427,66431],"disallowed"],[[66432,66461],"valid"],[[66462,66462],"disallowed"],[[66463,66463],"valid",[],"NV8"],[[66464,66499],"valid"],[[66500,66503],"disallowed"],[[66504,66511],"valid"],[[66512,66517],"valid",[],"NV8"],[[66518,66559],"disallowed"],[[66560,66560],"mapped",[66600]],[[66561,66561],"mapped",[66601]],[[66562,66562],"mapped",[66602]],[[66563,66563],"mapped",[66603]],[[66564,66564],"mapped",[66604]],[[66565,66565],"mapped",[66605]],[[66566,66566],"mapped",[66606]],[[66567,66567],"mapped",[66607]],[[66568,66568],"mapped",[66608]],[[66569,66569],"mapped",[66609]],[[66570,66570],"mapped",[66610]],[[66571,66571],"mapped",[66611]],[[66572,66572],"mapped",[66612]],[[66573,66573],"mapped",[66613]],[[66574,66574],"mapped",[66614]],[[66575,66575],"mapped",[66615]],[[66576,66576],"mapped",[66616]],[[66577,66577],"mapped",[66617]],[[66578,66578],"mapped",[66618]],[[66579,66579],"mapped",[66619]],[[66580,66580],"mapped",[66620]],[[66581,66581],"mapped",[66621]],[[66582,66582],"mapped",[66622]],[[66583,66583],"mapped",[66623]],[[66584,66584],"mapped",[66624]],[[66585,66585],"mapped",[66625]],[[66586,66586],"mapped",[66626]],[[66587,66587],"mapped",[66627]],[[66588,66588],"mapped",[66628]],[[66589,66589],"mapped",[66629]],[[66590,66590],"mapped",[66630]],[[66591,66591],"mapped",[66631]],[[66592,66592],"mapped",[66632]],[[66593,66593],"mapped",[66633]],[[66594,66594],"mapped",[66634]],[[66595,66595],"mapped",[66635]],[[66596,66596],"mapped",[66636]],[[66597,66597],"mapped",[66637]],[[66598,66598],"mapped",[66638]],[[66599,66599],"mapped",[66639]],[[66600,66637],"valid"],[[66638,66717],"valid"],[[66718,66719],"disallowed"],[[66720,66729],"valid"],[[66730,66815],"disallowed"],[[66816,66855],"valid"],[[66856,66863],"disallowed"],[[66864,66915],"valid"],[[66916,66926],"disallowed"],[[66927,66927],"valid",[],"NV8"],[[66928,67071],"disallowed"],[[67072,67382],"valid"],[[67383,67391],"disallowed"],[[67392,67413],"valid"],[[67414,67423],"disallowed"],[[67424,67431],"valid"],[[67432,67583],"disallowed"],[[67584,67589],"valid"],[[67590,67591],"disallowed"],[[67592,67592],"valid"],[[67593,67593],"disallowed"],[[67594,67637],"valid"],[[67638,67638],"disallowed"],[[67639,67640],"valid"],[[67641,67643],"disallowed"],[[67644,67644],"valid"],[[67645,67646],"disallowed"],[[67647,67647],"valid"],[[67648,67669],"valid"],[[67670,67670],"disallowed"],[[67671,67679],"valid",[],"NV8"],[[67680,67702],"valid"],[[67703,67711],"valid",[],"NV8"],[[67712,67742],"valid"],[[67743,67750],"disallowed"],[[67751,67759],"valid",[],"NV8"],[[67760,67807],"disallowed"],[[67808,67826],"valid"],[[67827,67827],"disallowed"],[[67828,67829],"valid"],[[67830,67834],"disallowed"],[[67835,67839],"valid",[],"NV8"],[[67840,67861],"valid"],[[67862,67865],"valid",[],"NV8"],[[67866,67867],"valid",[],"NV8"],[[67868,67870],"disallowed"],[[67871,67871],"valid",[],"NV8"],[[67872,67897],"valid"],[[67898,67902],"disallowed"],[[67903,67903],"valid",[],"NV8"],[[67904,67967],"disallowed"],[[67968,68023],"valid"],[[68024,68027],"disallowed"],[[68028,68029],"valid",[],"NV8"],[[68030,68031],"valid"],[[68032,68047],"valid",[],"NV8"],[[68048,68049],"disallowed"],[[68050,68095],"valid",[],"NV8"],[[68096,68099],"valid"],[[68100,68100],"disallowed"],[[68101,68102],"valid"],[[68103,68107],"disallowed"],[[68108,68115],"valid"],[[68116,68116],"disallowed"],[[68117,68119],"valid"],[[68120,68120],"disallowed"],[[68121,68147],"valid"],[[68148,68151],"disallowed"],[[68152,68154],"valid"],[[68155,68158],"disallowed"],[[68159,68159],"valid"],[[68160,68167],"valid",[],"NV8"],[[68168,68175],"disallowed"],[[68176,68184],"valid",[],"NV8"],[[68185,68191],"disallowed"],[[68192,68220],"valid"],[[68221,68223],"valid",[],"NV8"],[[68224,68252],"valid"],[[68253,68255],"valid",[],"NV8"],[[68256,68287],"disallowed"],[[68288,68295],"valid"],[[68296,68296],"valid",[],"NV8"],[[68297,68326],"valid"],[[68327,68330],"disallowed"],[[68331,68342],"valid",[],"NV8"],[[68343,68351],"disallowed"],[[68352,68405],"valid"],[[68406,68408],"disallowed"],[[68409,68415],"valid",[],"NV8"],[[68416,68437],"valid"],[[68438,68439],"disallowed"],[[68440,68447],"valid",[],"NV8"],[[68448,68466],"valid"],[[68467,68471],"disallowed"],[[68472,68479],"valid",[],"NV8"],[[68480,68497],"valid"],[[68498,68504],"disallowed"],[[68505,68508],"valid",[],"NV8"],[[68509,68520],"disallowed"],[[68521,68527],"valid",[],"NV8"],[[68528,68607],"disallowed"],[[68608,68680],"valid"],[[68681,68735],"disallowed"],[[68736,68736],"mapped",[68800]],[[68737,68737],"mapped",[68801]],[[68738,68738],"mapped",[68802]],[[68739,68739],"mapped",[68803]],[[68740,68740],"mapped",[68804]],[[68741,68741],"mapped",[68805]],[[68742,68742],"mapped",[68806]],[[68743,68743],"mapped",[68807]],[[68744,68744],"mapped",[68808]],[[68745,68745],"mapped",[68809]],[[68746,68746],"mapped",[68810]],[[68747,68747],"mapped",[68811]],[[68748,68748],"mapped",[68812]],[[68749,68749],"mapped",[68813]],[[68750,68750],"mapped",[68814]],[[68751,68751],"mapped",[68815]],[[68752,68752],"mapped",[68816]],[[68753,68753],"mapped",[68817]],[[68754,68754],"mapped",[68818]],[[68755,68755],"mapped",[68819]],[[68756,68756],"mapped",[68820]],[[68757,68757],"mapped",[68821]],[[68758,68758],"mapped",[68822]],[[68759,68759],"mapped",[68823]],[[68760,68760],"mapped",[68824]],[[68761,68761],"mapped",[68825]],[[68762,68762],"mapped",[68826]],[[68763,68763],"mapped",[68827]],[[68764,68764],"mapped",[68828]],[[68765,68765],"mapped",[68829]],[[68766,68766],"mapped",[68830]],[[68767,68767],"mapped",[68831]],[[68768,68768],"mapped",[68832]],[[68769,68769],"mapped",[68833]],[[68770,68770],"mapped",[68834]],[[68771,68771],"mapped",[68835]],[[68772,68772],"mapped",[68836]],[[68773,68773],"mapped",[68837]],[[68774,68774],"mapped",[68838]],[[68775,68775],"mapped",[68839]],[[68776,68776],"mapped",[68840]],[[68777,68777],"mapped",[68841]],[[68778,68778],"mapped",[68842]],[[68779,68779],"mapped",[68843]],[[68780,68780],"mapped",[68844]],[[68781,68781],"mapped",[68845]],[[68782,68782],"mapped",[68846]],[[68783,68783],"mapped",[68847]],[[68784,68784],"mapped",[68848]],[[68785,68785],"mapped",[68849]],[[68786,68786],"mapped",[68850]],[[68787,68799],"disallowed"],[[68800,68850],"valid"],[[68851,68857],"disallowed"],[[68858,68863],"valid",[],"NV8"],[[68864,69215],"disallowed"],[[69216,69246],"valid",[],"NV8"],[[69247,69631],"disallowed"],[[69632,69702],"valid"],[[69703,69709],"valid",[],"NV8"],[[69710,69713],"disallowed"],[[69714,69733],"valid",[],"NV8"],[[69734,69743],"valid"],[[69744,69758],"disallowed"],[[69759,69759],"valid"],[[69760,69818],"valid"],[[69819,69820],"valid",[],"NV8"],[[69821,69821],"disallowed"],[[69822,69825],"valid",[],"NV8"],[[69826,69839],"disallowed"],[[69840,69864],"valid"],[[69865,69871],"disallowed"],[[69872,69881],"valid"],[[69882,69887],"disallowed"],[[69888,69940],"valid"],[[69941,69941],"disallowed"],[[69942,69951],"valid"],[[69952,69955],"valid",[],"NV8"],[[69956,69967],"disallowed"],[[69968,70003],"valid"],[[70004,70005],"valid",[],"NV8"],[[70006,70006],"valid"],[[70007,70015],"disallowed"],[[70016,70084],"valid"],[[70085,70088],"valid",[],"NV8"],[[70089,70089],"valid",[],"NV8"],[[70090,70092],"valid"],[[70093,70093],"valid",[],"NV8"],[[70094,70095],"disallowed"],[[70096,70105],"valid"],[[70106,70106],"valid"],[[70107,70107],"valid",[],"NV8"],[[70108,70108],"valid"],[[70109,70111],"valid",[],"NV8"],[[70112,70112],"disallowed"],[[70113,70132],"valid",[],"NV8"],[[70133,70143],"disallowed"],[[70144,70161],"valid"],[[70162,70162],"disallowed"],[[70163,70199],"valid"],[[70200,70205],"valid",[],"NV8"],[[70206,70271],"disallowed"],[[70272,70278],"valid"],[[70279,70279],"disallowed"],[[70280,70280],"valid"],[[70281,70281],"disallowed"],[[70282,70285],"valid"],[[70286,70286],"disallowed"],[[70287,70301],"valid"],[[70302,70302],"disallowed"],[[70303,70312],"valid"],[[70313,70313],"valid",[],"NV8"],[[70314,70319],"disallowed"],[[70320,70378],"valid"],[[70379,70383],"disallowed"],[[70384,70393],"valid"],[[70394,70399],"disallowed"],[[70400,70400],"valid"],[[70401,70403],"valid"],[[70404,70404],"disallowed"],[[70405,70412],"valid"],[[70413,70414],"disallowed"],[[70415,70416],"valid"],[[70417,70418],"disallowed"],[[70419,70440],"valid"],[[70441,70441],"disallowed"],[[70442,70448],"valid"],[[70449,70449],"disallowed"],[[70450,70451],"valid"],[[70452,70452],"disallowed"],[[70453,70457],"valid"],[[70458,70459],"disallowed"],[[70460,70468],"valid"],[[70469,70470],"disallowed"],[[70471,70472],"valid"],[[70473,70474],"disallowed"],[[70475,70477],"valid"],[[70478,70479],"disallowed"],[[70480,70480],"valid"],[[70481,70486],"disallowed"],[[70487,70487],"valid"],[[70488,70492],"disallowed"],[[70493,70499],"valid"],[[70500,70501],"disallowed"],[[70502,70508],"valid"],[[70509,70511],"disallowed"],[[70512,70516],"valid"],[[70517,70783],"disallowed"],[[70784,70853],"valid"],[[70854,70854],"valid",[],"NV8"],[[70855,70855],"valid"],[[70856,70863],"disallowed"],[[70864,70873],"valid"],[[70874,71039],"disallowed"],[[71040,71093],"valid"],[[71094,71095],"disallowed"],[[71096,71104],"valid"],[[71105,71113],"valid",[],"NV8"],[[71114,71127],"valid",[],"NV8"],[[71128,71133],"valid"],[[71134,71167],"disallowed"],[[71168,71232],"valid"],[[71233,71235],"valid",[],"NV8"],[[71236,71236],"valid"],[[71237,71247],"disallowed"],[[71248,71257],"valid"],[[71258,71295],"disallowed"],[[71296,71351],"valid"],[[71352,71359],"disallowed"],[[71360,71369],"valid"],[[71370,71423],"disallowed"],[[71424,71449],"valid"],[[71450,71452],"disallowed"],[[71453,71467],"valid"],[[71468,71471],"disallowed"],[[71472,71481],"valid"],[[71482,71487],"valid",[],"NV8"],[[71488,71839],"disallowed"],[[71840,71840],"mapped",[71872]],[[71841,71841],"mapped",[71873]],[[71842,71842],"mapped",[71874]],[[71843,71843],"mapped",[71875]],[[71844,71844],"mapped",[71876]],[[71845,71845],"mapped",[71877]],[[71846,71846],"mapped",[71878]],[[71847,71847],"mapped",[71879]],[[71848,71848],"mapped",[71880]],[[71849,71849],"mapped",[71881]],[[71850,71850],"mapped",[71882]],[[71851,71851],"mapped",[71883]],[[71852,71852],"mapped",[71884]],[[71853,71853],"mapped",[71885]],[[71854,71854],"mapped",[71886]],[[71855,71855],"mapped",[71887]],[[71856,71856],"mapped",[71888]],[[71857,71857],"mapped",[71889]],[[71858,71858],"mapped",[71890]],[[71859,71859],"mapped",[71891]],[[71860,71860],"mapped",[71892]],[[71861,71861],"mapped",[71893]],[[71862,71862],"mapped",[71894]],[[71863,71863],"mapped",[71895]],[[71864,71864],"mapped",[71896]],[[71865,71865],"mapped",[71897]],[[71866,71866],"mapped",[71898]],[[71867,71867],"mapped",[71899]],[[71868,71868],"mapped",[71900]],[[71869,71869],"mapped",[71901]],[[71870,71870],"mapped",[71902]],[[71871,71871],"mapped",[71903]],[[71872,71913],"valid"],[[71914,71922],"valid",[],"NV8"],[[71923,71934],"disallowed"],[[71935,71935],"valid"],[[71936,72383],"disallowed"],[[72384,72440],"valid"],[[72441,73727],"disallowed"],[[73728,74606],"valid"],[[74607,74648],"valid"],[[74649,74649],"valid"],[[74650,74751],"disallowed"],[[74752,74850],"valid",[],"NV8"],[[74851,74862],"valid",[],"NV8"],[[74863,74863],"disallowed"],[[74864,74867],"valid",[],"NV8"],[[74868,74868],"valid",[],"NV8"],[[74869,74879],"disallowed"],[[74880,75075],"valid"],[[75076,77823],"disallowed"],[[77824,78894],"valid"],[[78895,82943],"disallowed"],[[82944,83526],"valid"],[[83527,92159],"disallowed"],[[92160,92728],"valid"],[[92729,92735],"disallowed"],[[92736,92766],"valid"],[[92767,92767],"disallowed"],[[92768,92777],"valid"],[[92778,92781],"disallowed"],[[92782,92783],"valid",[],"NV8"],[[92784,92879],"disallowed"],[[92880,92909],"valid"],[[92910,92911],"disallowed"],[[92912,92916],"valid"],[[92917,92917],"valid",[],"NV8"],[[92918,92927],"disallowed"],[[92928,92982],"valid"],[[92983,92991],"valid",[],"NV8"],[[92992,92995],"valid"],[[92996,92997],"valid",[],"NV8"],[[92998,93007],"disallowed"],[[93008,93017],"valid"],[[93018,93018],"disallowed"],[[93019,93025],"valid",[],"NV8"],[[93026,93026],"disallowed"],[[93027,93047],"valid"],[[93048,93052],"disallowed"],[[93053,93071],"valid"],[[93072,93951],"disallowed"],[[93952,94020],"valid"],[[94021,94031],"disallowed"],[[94032,94078],"valid"],[[94079,94094],"disallowed"],[[94095,94111],"valid"],[[94112,110591],"disallowed"],[[110592,110593],"valid"],[[110594,113663],"disallowed"],[[113664,113770],"valid"],[[113771,113775],"disallowed"],[[113776,113788],"valid"],[[113789,113791],"disallowed"],[[113792,113800],"valid"],[[113801,113807],"disallowed"],[[113808,113817],"valid"],[[113818,113819],"disallowed"],[[113820,113820],"valid",[],"NV8"],[[113821,113822],"valid"],[[113823,113823],"valid",[],"NV8"],[[113824,113827],"ignored"],[[113828,118783],"disallowed"],[[118784,119029],"valid",[],"NV8"],[[119030,119039],"disallowed"],[[119040,119078],"valid",[],"NV8"],[[119079,119080],"disallowed"],[[119081,119081],"valid",[],"NV8"],[[119082,119133],"valid",[],"NV8"],[[119134,119134],"mapped",[119127,119141]],[[119135,119135],"mapped",[119128,119141]],[[119136,119136],"mapped",[119128,119141,119150]],[[119137,119137],"mapped",[119128,119141,119151]],[[119138,119138],"mapped",[119128,119141,119152]],[[119139,119139],"mapped",[119128,119141,119153]],[[119140,119140],"mapped",[119128,119141,119154]],[[119141,119154],"valid",[],"NV8"],[[119155,119162],"disallowed"],[[119163,119226],"valid",[],"NV8"],[[119227,119227],"mapped",[119225,119141]],[[119228,119228],"mapped",[119226,119141]],[[119229,119229],"mapped",[119225,119141,119150]],[[119230,119230],"mapped",[119226,119141,119150]],[[119231,119231],"mapped",[119225,119141,119151]],[[119232,119232],"mapped",[119226,119141,119151]],[[119233,119261],"valid",[],"NV8"],[[119262,119272],"valid",[],"NV8"],[[119273,119295],"disallowed"],[[119296,119365],"valid",[],"NV8"],[[119366,119551],"disallowed"],[[119552,119638],"valid",[],"NV8"],[[119639,119647],"disallowed"],[[119648,119665],"valid",[],"NV8"],[[119666,119807],"disallowed"],[[119808,119808],"mapped",[97]],[[119809,119809],"mapped",[98]],[[119810,119810],"mapped",[99]],[[119811,119811],"mapped",[100]],[[119812,119812],"mapped",[101]],[[119813,119813],"mapped",[102]],[[119814,119814],"mapped",[103]],[[119815,119815],"mapped",[104]],[[119816,119816],"mapped",[105]],[[119817,119817],"mapped",[106]],[[119818,119818],"mapped",[107]],[[119819,119819],"mapped",[108]],[[119820,119820],"mapped",[109]],[[119821,119821],"mapped",[110]],[[119822,119822],"mapped",[111]],[[119823,119823],"mapped",[112]],[[119824,119824],"mapped",[113]],[[119825,119825],"mapped",[114]],[[119826,119826],"mapped",[115]],[[119827,119827],"mapped",[116]],[[119828,119828],"mapped",[117]],[[119829,119829],"mapped",[118]],[[119830,119830],"mapped",[119]],[[119831,119831],"mapped",[120]],[[119832,119832],"mapped",[121]],[[119833,119833],"mapped",[122]],[[119834,119834],"mapped",[97]],[[119835,119835],"mapped",[98]],[[119836,119836],"mapped",[99]],[[119837,119837],"mapped",[100]],[[119838,119838],"mapped",[101]],[[119839,119839],"mapped",[102]],[[119840,119840],"mapped",[103]],[[119841,119841],"mapped",[104]],[[119842,119842],"mapped",[105]],[[119843,119843],"mapped",[106]],[[119844,119844],"mapped",[107]],[[119845,119845],"mapped",[108]],[[119846,119846],"mapped",[109]],[[119847,119847],"mapped",[110]],[[119848,119848],"mapped",[111]],[[119849,119849],"mapped",[112]],[[119850,119850],"mapped",[113]],[[119851,119851],"mapped",[114]],[[119852,119852],"mapped",[115]],[[119853,119853],"mapped",[116]],[[119854,119854],"mapped",[117]],[[119855,119855],"mapped",[118]],[[119856,119856],"mapped",[119]],[[119857,119857],"mapped",[120]],[[119858,119858],"mapped",[121]],[[119859,119859],"mapped",[122]],[[119860,119860],"mapped",[97]],[[119861,119861],"mapped",[98]],[[119862,119862],"mapped",[99]],[[119863,119863],"mapped",[100]],[[119864,119864],"mapped",[101]],[[119865,119865],"mapped",[102]],[[119866,119866],"mapped",[103]],[[119867,119867],"mapped",[104]],[[119868,119868],"mapped",[105]],[[119869,119869],"mapped",[106]],[[119870,119870],"mapped",[107]],[[119871,119871],"mapped",[108]],[[119872,119872],"mapped",[109]],[[119873,119873],"mapped",[110]],[[119874,119874],"mapped",[111]],[[119875,119875],"mapped",[112]],[[119876,119876],"mapped",[113]],[[119877,119877],"mapped",[114]],[[119878,119878],"mapped",[115]],[[119879,119879],"mapped",[116]],[[119880,119880],"mapped",[117]],[[119881,119881],"mapped",[118]],[[119882,119882],"mapped",[119]],[[119883,119883],"mapped",[120]],[[119884,119884],"mapped",[121]],[[119885,119885],"mapped",[122]],[[119886,119886],"mapped",[97]],[[119887,119887],"mapped",[98]],[[119888,119888],"mapped",[99]],[[119889,119889],"mapped",[100]],[[119890,119890],"mapped",[101]],[[119891,119891],"mapped",[102]],[[119892,119892],"mapped",[103]],[[119893,119893],"disallowed"],[[119894,119894],"mapped",[105]],[[119895,119895],"mapped",[106]],[[119896,119896],"mapped",[107]],[[119897,119897],"mapped",[108]],[[119898,119898],"mapped",[109]],[[119899,119899],"mapped",[110]],[[119900,119900],"mapped",[111]],[[119901,119901],"mapped",[112]],[[119902,119902],"mapped",[113]],[[119903,119903],"mapped",[114]],[[119904,119904],"mapped",[115]],[[119905,119905],"mapped",[116]],[[119906,119906],"mapped",[117]],[[119907,119907],"mapped",[118]],[[119908,119908],"mapped",[119]],[[119909,119909],"mapped",[120]],[[119910,119910],"mapped",[121]],[[119911,119911],"mapped",[122]],[[119912,119912],"mapped",[97]],[[119913,119913],"mapped",[98]],[[119914,119914],"mapped",[99]],[[119915,119915],"mapped",[100]],[[119916,119916],"mapped",[101]],[[119917,119917],"mapped",[102]],[[119918,119918],"mapped",[103]],[[119919,119919],"mapped",[104]],[[119920,119920],"mapped",[105]],[[119921,119921],"mapped",[106]],[[119922,119922],"mapped",[107]],[[119923,119923],"mapped",[108]],[[119924,119924],"mapped",[109]],[[119925,119925],"mapped",[110]],[[119926,119926],"mapped",[111]],[[119927,119927],"mapped",[112]],[[119928,119928],"mapped",[113]],[[119929,119929],"mapped",[114]],[[119930,119930],"mapped",[115]],[[119931,119931],"mapped",[116]],[[119932,119932],"mapped",[117]],[[119933,119933],"mapped",[118]],[[119934,119934],"mapped",[119]],[[119935,119935],"mapped",[120]],[[119936,119936],"mapped",[121]],[[119937,119937],"mapped",[122]],[[119938,119938],"mapped",[97]],[[119939,119939],"mapped",[98]],[[119940,119940],"mapped",[99]],[[119941,119941],"mapped",[100]],[[119942,119942],"mapped",[101]],[[119943,119943],"mapped",[102]],[[119944,119944],"mapped",[103]],[[119945,119945],"mapped",[104]],[[119946,119946],"mapped",[105]],[[119947,119947],"mapped",[106]],[[119948,119948],"mapped",[107]],[[119949,119949],"mapped",[108]],[[119950,119950],"mapped",[109]],[[119951,119951],"mapped",[110]],[[119952,119952],"mapped",[111]],[[119953,119953],"mapped",[112]],[[119954,119954],"mapped",[113]],[[119955,119955],"mapped",[114]],[[119956,119956],"mapped",[115]],[[119957,119957],"mapped",[116]],[[119958,119958],"mapped",[117]],[[119959,119959],"mapped",[118]],[[119960,119960],"mapped",[119]],[[119961,119961],"mapped",[120]],[[119962,119962],"mapped",[121]],[[119963,119963],"mapped",[122]],[[119964,119964],"mapped",[97]],[[119965,119965],"disallowed"],[[119966,119966],"mapped",[99]],[[119967,119967],"mapped",[100]],[[119968,119969],"disallowed"],[[119970,119970],"mapped",[103]],[[119971,119972],"disallowed"],[[119973,119973],"mapped",[106]],[[119974,119974],"mapped",[107]],[[119975,119976],"disallowed"],[[119977,119977],"mapped",[110]],[[119978,119978],"mapped",[111]],[[119979,119979],"mapped",[112]],[[119980,119980],"mapped",[113]],[[119981,119981],"disallowed"],[[119982,119982],"mapped",[115]],[[119983,119983],"mapped",[116]],[[119984,119984],"mapped",[117]],[[119985,119985],"mapped",[118]],[[119986,119986],"mapped",[119]],[[119987,119987],"mapped",[120]],[[119988,119988],"mapped",[121]],[[119989,119989],"mapped",[122]],[[119990,119990],"mapped",[97]],[[119991,119991],"mapped",[98]],[[119992,119992],"mapped",[99]],[[119993,119993],"mapped",[100]],[[119994,119994],"disallowed"],[[119995,119995],"mapped",[102]],[[119996,119996],"disallowed"],[[119997,119997],"mapped",[104]],[[119998,119998],"mapped",[105]],[[119999,119999],"mapped",[106]],[[120000,120000],"mapped",[107]],[[120001,120001],"mapped",[108]],[[120002,120002],"mapped",[109]],[[120003,120003],"mapped",[110]],[[120004,120004],"disallowed"],[[120005,120005],"mapped",[112]],[[120006,120006],"mapped",[113]],[[120007,120007],"mapped",[114]],[[120008,120008],"mapped",[115]],[[120009,120009],"mapped",[116]],[[120010,120010],"mapped",[117]],[[120011,120011],"mapped",[118]],[[120012,120012],"mapped",[119]],[[120013,120013],"mapped",[120]],[[120014,120014],"mapped",[121]],[[120015,120015],"mapped",[122]],[[120016,120016],"mapped",[97]],[[120017,120017],"mapped",[98]],[[120018,120018],"mapped",[99]],[[120019,120019],"mapped",[100]],[[120020,120020],"mapped",[101]],[[120021,120021],"mapped",[102]],[[120022,120022],"mapped",[103]],[[120023,120023],"mapped",[104]],[[120024,120024],"mapped",[105]],[[120025,120025],"mapped",[106]],[[120026,120026],"mapped",[107]],[[120027,120027],"mapped",[108]],[[120028,120028],"mapped",[109]],[[120029,120029],"mapped",[110]],[[120030,120030],"mapped",[111]],[[120031,120031],"mapped",[112]],[[120032,120032],"mapped",[113]],[[120033,120033],"mapped",[114]],[[120034,120034],"mapped",[115]],[[120035,120035],"mapped",[116]],[[120036,120036],"mapped",[117]],[[120037,120037],"mapped",[118]],[[120038,120038],"mapped",[119]],[[120039,120039],"mapped",[120]],[[120040,120040],"mapped",[121]],[[120041,120041],"mapped",[122]],[[120042,120042],"mapped",[97]],[[120043,120043],"mapped",[98]],[[120044,120044],"mapped",[99]],[[120045,120045],"mapped",[100]],[[120046,120046],"mapped",[101]],[[120047,120047],"mapped",[102]],[[120048,120048],"mapped",[103]],[[120049,120049],"mapped",[104]],[[120050,120050],"mapped",[105]],[[120051,120051],"mapped",[106]],[[120052,120052],"mapped",[107]],[[120053,120053],"mapped",[108]],[[120054,120054],"mapped",[109]],[[120055,120055],"mapped",[110]],[[120056,120056],"mapped",[111]],[[120057,120057],"mapped",[112]],[[120058,120058],"mapped",[113]],[[120059,120059],"mapped",[114]],[[120060,120060],"mapped",[115]],[[120061,120061],"mapped",[116]],[[120062,120062],"mapped",[117]],[[120063,120063],"mapped",[118]],[[120064,120064],"mapped",[119]],[[120065,120065],"mapped",[120]],[[120066,120066],"mapped",[121]],[[120067,120067],"mapped",[122]],[[120068,120068],"mapped",[97]],[[120069,120069],"mapped",[98]],[[120070,120070],"disallowed"],[[120071,120071],"mapped",[100]],[[120072,120072],"mapped",[101]],[[120073,120073],"mapped",[102]],[[120074,120074],"mapped",[103]],[[120075,120076],"disallowed"],[[120077,120077],"mapped",[106]],[[120078,120078],"mapped",[107]],[[120079,120079],"mapped",[108]],[[120080,120080],"mapped",[109]],[[120081,120081],"mapped",[110]],[[120082,120082],"mapped",[111]],[[120083,120083],"mapped",[112]],[[120084,120084],"mapped",[113]],[[120085,120085],"disallowed"],[[120086,120086],"mapped",[115]],[[120087,120087],"mapped",[116]],[[120088,120088],"mapped",[117]],[[120089,120089],"mapped",[118]],[[120090,120090],"mapped",[119]],[[120091,120091],"mapped",[120]],[[120092,120092],"mapped",[121]],[[120093,120093],"disallowed"],[[120094,120094],"mapped",[97]],[[120095,120095],"mapped",[98]],[[120096,120096],"mapped",[99]],[[120097,120097],"mapped",[100]],[[120098,120098],"mapped",[101]],[[120099,120099],"mapped",[102]],[[120100,120100],"mapped",[103]],[[120101,120101],"mapped",[104]],[[120102,120102],"mapped",[105]],[[120103,120103],"mapped",[106]],[[120104,120104],"mapped",[107]],[[120105,120105],"mapped",[108]],[[120106,120106],"mapped",[109]],[[120107,120107],"mapped",[110]],[[120108,120108],"mapped",[111]],[[120109,120109],"mapped",[112]],[[120110,120110],"mapped",[113]],[[120111,120111],"mapped",[114]],[[120112,120112],"mapped",[115]],[[120113,120113],"mapped",[116]],[[120114,120114],"mapped",[117]],[[120115,120115],"mapped",[118]],[[120116,120116],"mapped",[119]],[[120117,120117],"mapped",[120]],[[120118,120118],"mapped",[121]],[[120119,120119],"mapped",[122]],[[120120,120120],"mapped",[97]],[[120121,120121],"mapped",[98]],[[120122,120122],"disallowed"],[[120123,120123],"mapped",[100]],[[120124,120124],"mapped",[101]],[[120125,120125],"mapped",[102]],[[120126,120126],"mapped",[103]],[[120127,120127],"disallowed"],[[120128,120128],"mapped",[105]],[[120129,120129],"mapped",[106]],[[120130,120130],"mapped",[107]],[[120131,120131],"mapped",[108]],[[120132,120132],"mapped",[109]],[[120133,120133],"disallowed"],[[120134,120134],"mapped",[111]],[[120135,120137],"disallowed"],[[120138,120138],"mapped",[115]],[[120139,120139],"mapped",[116]],[[120140,120140],"mapped",[117]],[[120141,120141],"mapped",[118]],[[120142,120142],"mapped",[119]],[[120143,120143],"mapped",[120]],[[120144,120144],"mapped",[121]],[[120145,120145],"disallowed"],[[120146,120146],"mapped",[97]],[[120147,120147],"mapped",[98]],[[120148,120148],"mapped",[99]],[[120149,120149],"mapped",[100]],[[120150,120150],"mapped",[101]],[[120151,120151],"mapped",[102]],[[120152,120152],"mapped",[103]],[[120153,120153],"mapped",[104]],[[120154,120154],"mapped",[105]],[[120155,120155],"mapped",[106]],[[120156,120156],"mapped",[107]],[[120157,120157],"mapped",[108]],[[120158,120158],"mapped",[109]],[[120159,120159],"mapped",[110]],[[120160,120160],"mapped",[111]],[[120161,120161],"mapped",[112]],[[120162,120162],"mapped",[113]],[[120163,120163],"mapped",[114]],[[120164,120164],"mapped",[115]],[[120165,120165],"mapped",[116]],[[120166,120166],"mapped",[117]],[[120167,120167],"mapped",[118]],[[120168,120168],"mapped",[119]],[[120169,120169],"mapped",[120]],[[120170,120170],"mapped",[121]],[[120171,120171],"mapped",[122]],[[120172,120172],"mapped",[97]],[[120173,120173],"mapped",[98]],[[120174,120174],"mapped",[99]],[[120175,120175],"mapped",[100]],[[120176,120176],"mapped",[101]],[[120177,120177],"mapped",[102]],[[120178,120178],"mapped",[103]],[[120179,120179],"mapped",[104]],[[120180,120180],"mapped",[105]],[[120181,120181],"mapped",[106]],[[120182,120182],"mapped",[107]],[[120183,120183],"mapped",[108]],[[120184,120184],"mapped",[109]],[[120185,120185],"mapped",[110]],[[120186,120186],"mapped",[111]],[[120187,120187],"mapped",[112]],[[120188,120188],"mapped",[113]],[[120189,120189],"mapped",[114]],[[120190,120190],"mapped",[115]],[[120191,120191],"mapped",[116]],[[120192,120192],"mapped",[117]],[[120193,120193],"mapped",[118]],[[120194,120194],"mapped",[119]],[[120195,120195],"mapped",[120]],[[120196,120196],"mapped",[121]],[[120197,120197],"mapped",[122]],[[120198,120198],"mapped",[97]],[[120199,120199],"mapped",[98]],[[120200,120200],"mapped",[99]],[[120201,120201],"mapped",[100]],[[120202,120202],"mapped",[101]],[[120203,120203],"mapped",[102]],[[120204,120204],"mapped",[103]],[[120205,120205],"mapped",[104]],[[120206,120206],"mapped",[105]],[[120207,120207],"mapped",[106]],[[120208,120208],"mapped",[107]],[[120209,120209],"mapped",[108]],[[120210,120210],"mapped",[109]],[[120211,120211],"mapped",[110]],[[120212,120212],"mapped",[111]],[[120213,120213],"mapped",[112]],[[120214,120214],"mapped",[113]],[[120215,120215],"mapped",[114]],[[120216,120216],"mapped",[115]],[[120217,120217],"mapped",[116]],[[120218,120218],"mapped",[117]],[[120219,120219],"mapped",[118]],[[120220,120220],"mapped",[119]],[[120221,120221],"mapped",[120]],[[120222,120222],"mapped",[121]],[[120223,120223],"mapped",[122]],[[120224,120224],"mapped",[97]],[[120225,120225],"mapped",[98]],[[120226,120226],"mapped",[99]],[[120227,120227],"mapped",[100]],[[120228,120228],"mapped",[101]],[[120229,120229],"mapped",[102]],[[120230,120230],"mapped",[103]],[[120231,120231],"mapped",[104]],[[120232,120232],"mapped",[105]],[[120233,120233],"mapped",[106]],[[120234,120234],"mapped",[107]],[[120235,120235],"mapped",[108]],[[120236,120236],"mapped",[109]],[[120237,120237],"mapped",[110]],[[120238,120238],"mapped",[111]],[[120239,120239],"mapped",[112]],[[120240,120240],"mapped",[113]],[[120241,120241],"mapped",[114]],[[120242,120242],"mapped",[115]],[[120243,120243],"mapped",[116]],[[120244,120244],"mapped",[117]],[[120245,120245],"mapped",[118]],[[120246,120246],"mapped",[119]],[[120247,120247],"mapped",[120]],[[120248,120248],"mapped",[121]],[[120249,120249],"mapped",[122]],[[120250,120250],"mapped",[97]],[[120251,120251],"mapped",[98]],[[120252,120252],"mapped",[99]],[[120253,120253],"mapped",[100]],[[120254,120254],"mapped",[101]],[[120255,120255],"mapped",[102]],[[120256,120256],"mapped",[103]],[[120257,120257],"mapped",[104]],[[120258,120258],"mapped",[105]],[[120259,120259],"mapped",[106]],[[120260,120260],"mapped",[107]],[[120261,120261],"mapped",[108]],[[120262,120262],"mapped",[109]],[[120263,120263],"mapped",[110]],[[120264,120264],"mapped",[111]],[[120265,120265],"mapped",[112]],[[120266,120266],"mapped",[113]],[[120267,120267],"mapped",[114]],[[120268,120268],"mapped",[115]],[[120269,120269],"mapped",[116]],[[120270,120270],"mapped",[117]],[[120271,120271],"mapped",[118]],[[120272,120272],"mapped",[119]],[[120273,120273],"mapped",[120]],[[120274,120274],"mapped",[121]],[[120275,120275],"mapped",[122]],[[120276,120276],"mapped",[97]],[[120277,120277],"mapped",[98]],[[120278,120278],"mapped",[99]],[[120279,120279],"mapped",[100]],[[120280,120280],"mapped",[101]],[[120281,120281],"mapped",[102]],[[120282,120282],"mapped",[103]],[[120283,120283],"mapped",[104]],[[120284,120284],"mapped",[105]],[[120285,120285],"mapped",[106]],[[120286,120286],"mapped",[107]],[[120287,120287],"mapped",[108]],[[120288,120288],"mapped",[109]],[[120289,120289],"mapped",[110]],[[120290,120290],"mapped",[111]],[[120291,120291],"mapped",[112]],[[120292,120292],"mapped",[113]],[[120293,120293],"mapped",[114]],[[120294,120294],"mapped",[115]],[[120295,120295],"mapped",[116]],[[120296,120296],"mapped",[117]],[[120297,120297],"mapped",[118]],[[120298,120298],"mapped",[119]],[[120299,120299],"mapped",[120]],[[120300,120300],"mapped",[121]],[[120301,120301],"mapped",[122]],[[120302,120302],"mapped",[97]],[[120303,120303],"mapped",[98]],[[120304,120304],"mapped",[99]],[[120305,120305],"mapped",[100]],[[120306,120306],"mapped",[101]],[[120307,120307],"mapped",[102]],[[120308,120308],"mapped",[103]],[[120309,120309],"mapped",[104]],[[120310,120310],"mapped",[105]],[[120311,120311],"mapped",[106]],[[120312,120312],"mapped",[107]],[[120313,120313],"mapped",[108]],[[120314,120314],"mapped",[109]],[[120315,120315],"mapped",[110]],[[120316,120316],"mapped",[111]],[[120317,120317],"mapped",[112]],[[120318,120318],"mapped",[113]],[[120319,120319],"mapped",[114]],[[120320,120320],"mapped",[115]],[[120321,120321],"mapped",[116]],[[120322,120322],"mapped",[117]],[[120323,120323],"mapped",[118]],[[120324,120324],"mapped",[119]],[[120325,120325],"mapped",[120]],[[120326,120326],"mapped",[121]],[[120327,120327],"mapped",[122]],[[120328,120328],"mapped",[97]],[[120329,120329],"mapped",[98]],[[120330,120330],"mapped",[99]],[[120331,120331],"mapped",[100]],[[120332,120332],"mapped",[101]],[[120333,120333],"mapped",[102]],[[120334,120334],"mapped",[103]],[[120335,120335],"mapped",[104]],[[120336,120336],"mapped",[105]],[[120337,120337],"mapped",[106]],[[120338,120338],"mapped",[107]],[[120339,120339],"mapped",[108]],[[120340,120340],"mapped",[109]],[[120341,120341],"mapped",[110]],[[120342,120342],"mapped",[111]],[[120343,120343],"mapped",[112]],[[120344,120344],"mapped",[113]],[[120345,120345],"mapped",[114]],[[120346,120346],"mapped",[115]],[[120347,120347],"mapped",[116]],[[120348,120348],"mapped",[117]],[[120349,120349],"mapped",[118]],[[120350,120350],"mapped",[119]],[[120351,120351],"mapped",[120]],[[120352,120352],"mapped",[121]],[[120353,120353],"mapped",[122]],[[120354,120354],"mapped",[97]],[[120355,120355],"mapped",[98]],[[120356,120356],"mapped",[99]],[[120357,120357],"mapped",[100]],[[120358,120358],"mapped",[101]],[[120359,120359],"mapped",[102]],[[120360,120360],"mapped",[103]],[[120361,120361],"mapped",[104]],[[120362,120362],"mapped",[105]],[[120363,120363],"mapped",[106]],[[120364,120364],"mapped",[107]],[[120365,120365],"mapped",[108]],[[120366,120366],"mapped",[109]],[[120367,120367],"mapped",[110]],[[120368,120368],"mapped",[111]],[[120369,120369],"mapped",[112]],[[120370,120370],"mapped",[113]],[[120371,120371],"mapped",[114]],[[120372,120372],"mapped",[115]],[[120373,120373],"mapped",[116]],[[120374,120374],"mapped",[117]],[[120375,120375],"mapped",[118]],[[120376,120376],"mapped",[119]],[[120377,120377],"mapped",[120]],[[120378,120378],"mapped",[121]],[[120379,120379],"mapped",[122]],[[120380,120380],"mapped",[97]],[[120381,120381],"mapped",[98]],[[120382,120382],"mapped",[99]],[[120383,120383],"mapped",[100]],[[120384,120384],"mapped",[101]],[[120385,120385],"mapped",[102]],[[120386,120386],"mapped",[103]],[[120387,120387],"mapped",[104]],[[120388,120388],"mapped",[105]],[[120389,120389],"mapped",[106]],[[120390,120390],"mapped",[107]],[[120391,120391],"mapped",[108]],[[120392,120392],"mapped",[109]],[[120393,120393],"mapped",[110]],[[120394,120394],"mapped",[111]],[[120395,120395],"mapped",[112]],[[120396,120396],"mapped",[113]],[[120397,120397],"mapped",[114]],[[120398,120398],"mapped",[115]],[[120399,120399],"mapped",[116]],[[120400,120400],"mapped",[117]],[[120401,120401],"mapped",[118]],[[120402,120402],"mapped",[119]],[[120403,120403],"mapped",[120]],[[120404,120404],"mapped",[121]],[[120405,120405],"mapped",[122]],[[120406,120406],"mapped",[97]],[[120407,120407],"mapped",[98]],[[120408,120408],"mapped",[99]],[[120409,120409],"mapped",[100]],[[120410,120410],"mapped",[101]],[[120411,120411],"mapped",[102]],[[120412,120412],"mapped",[103]],[[120413,120413],"mapped",[104]],[[120414,120414],"mapped",[105]],[[120415,120415],"mapped",[106]],[[120416,120416],"mapped",[107]],[[120417,120417],"mapped",[108]],[[120418,120418],"mapped",[109]],[[120419,120419],"mapped",[110]],[[120420,120420],"mapped",[111]],[[120421,120421],"mapped",[112]],[[120422,120422],"mapped",[113]],[[120423,120423],"mapped",[114]],[[120424,120424],"mapped",[115]],[[120425,120425],"mapped",[116]],[[120426,120426],"mapped",[117]],[[120427,120427],"mapped",[118]],[[120428,120428],"mapped",[119]],[[120429,120429],"mapped",[120]],[[120430,120430],"mapped",[121]],[[120431,120431],"mapped",[122]],[[120432,120432],"mapped",[97]],[[120433,120433],"mapped",[98]],[[120434,120434],"mapped",[99]],[[120435,120435],"mapped",[100]],[[120436,120436],"mapped",[101]],[[120437,120437],"mapped",[102]],[[120438,120438],"mapped",[103]],[[120439,120439],"mapped",[104]],[[120440,120440],"mapped",[105]],[[120441,120441],"mapped",[106]],[[120442,120442],"mapped",[107]],[[120443,120443],"mapped",[108]],[[120444,120444],"mapped",[109]],[[120445,120445],"mapped",[110]],[[120446,120446],"mapped",[111]],[[120447,120447],"mapped",[112]],[[120448,120448],"mapped",[113]],[[120449,120449],"mapped",[114]],[[120450,120450],"mapped",[115]],[[120451,120451],"mapped",[116]],[[120452,120452],"mapped",[117]],[[120453,120453],"mapped",[118]],[[120454,120454],"mapped",[119]],[[120455,120455],"mapped",[120]],[[120456,120456],"mapped",[121]],[[120457,120457],"mapped",[122]],[[120458,120458],"mapped",[97]],[[120459,120459],"mapped",[98]],[[120460,120460],"mapped",[99]],[[120461,120461],"mapped",[100]],[[120462,120462],"mapped",[101]],[[120463,120463],"mapped",[102]],[[120464,120464],"mapped",[103]],[[120465,120465],"mapped",[104]],[[120466,120466],"mapped",[105]],[[120467,120467],"mapped",[106]],[[120468,120468],"mapped",[107]],[[120469,120469],"mapped",[108]],[[120470,120470],"mapped",[109]],[[120471,120471],"mapped",[110]],[[120472,120472],"mapped",[111]],[[120473,120473],"mapped",[112]],[[120474,120474],"mapped",[113]],[[120475,120475],"mapped",[114]],[[120476,120476],"mapped",[115]],[[120477,120477],"mapped",[116]],[[120478,120478],"mapped",[117]],[[120479,120479],"mapped",[118]],[[120480,120480],"mapped",[119]],[[120481,120481],"mapped",[120]],[[120482,120482],"mapped",[121]],[[120483,120483],"mapped",[122]],[[120484,120484],"mapped",[305]],[[120485,120485],"mapped",[567]],[[120486,120487],"disallowed"],[[120488,120488],"mapped",[945]],[[120489,120489],"mapped",[946]],[[120490,120490],"mapped",[947]],[[120491,120491],"mapped",[948]],[[120492,120492],"mapped",[949]],[[120493,120493],"mapped",[950]],[[120494,120494],"mapped",[951]],[[120495,120495],"mapped",[952]],[[120496,120496],"mapped",[953]],[[120497,120497],"mapped",[954]],[[120498,120498],"mapped",[955]],[[120499,120499],"mapped",[956]],[[120500,120500],"mapped",[957]],[[120501,120501],"mapped",[958]],[[120502,120502],"mapped",[959]],[[120503,120503],"mapped",[960]],[[120504,120504],"mapped",[961]],[[120505,120505],"mapped",[952]],[[120506,120506],"mapped",[963]],[[120507,120507],"mapped",[964]],[[120508,120508],"mapped",[965]],[[120509,120509],"mapped",[966]],[[120510,120510],"mapped",[967]],[[120511,120511],"mapped",[968]],[[120512,120512],"mapped",[969]],[[120513,120513],"mapped",[8711]],[[120514,120514],"mapped",[945]],[[120515,120515],"mapped",[946]],[[120516,120516],"mapped",[947]],[[120517,120517],"mapped",[948]],[[120518,120518],"mapped",[949]],[[120519,120519],"mapped",[950]],[[120520,120520],"mapped",[951]],[[120521,120521],"mapped",[952]],[[120522,120522],"mapped",[953]],[[120523,120523],"mapped",[954]],[[120524,120524],"mapped",[955]],[[120525,120525],"mapped",[956]],[[120526,120526],"mapped",[957]],[[120527,120527],"mapped",[958]],[[120528,120528],"mapped",[959]],[[120529,120529],"mapped",[960]],[[120530,120530],"mapped",[961]],[[120531,120532],"mapped",[963]],[[120533,120533],"mapped",[964]],[[120534,120534],"mapped",[965]],[[120535,120535],"mapped",[966]],[[120536,120536],"mapped",[967]],[[120537,120537],"mapped",[968]],[[120538,120538],"mapped",[969]],[[120539,120539],"mapped",[8706]],[[120540,120540],"mapped",[949]],[[120541,120541],"mapped",[952]],[[120542,120542],"mapped",[954]],[[120543,120543],"mapped",[966]],[[120544,120544],"mapped",[961]],[[120545,120545],"mapped",[960]],[[120546,120546],"mapped",[945]],[[120547,120547],"mapped",[946]],[[120548,120548],"mapped",[947]],[[120549,120549],"mapped",[948]],[[120550,120550],"mapped",[949]],[[120551,120551],"mapped",[950]],[[120552,120552],"mapped",[951]],[[120553,120553],"mapped",[952]],[[120554,120554],"mapped",[953]],[[120555,120555],"mapped",[954]],[[120556,120556],"mapped",[955]],[[120557,120557],"mapped",[956]],[[120558,120558],"mapped",[957]],[[120559,120559],"mapped",[958]],[[120560,120560],"mapped",[959]],[[120561,120561],"mapped",[960]],[[120562,120562],"mapped",[961]],[[120563,120563],"mapped",[952]],[[120564,120564],"mapped",[963]],[[120565,120565],"mapped",[964]],[[120566,120566],"mapped",[965]],[[120567,120567],"mapped",[966]],[[120568,120568],"mapped",[967]],[[120569,120569],"mapped",[968]],[[120570,120570],"mapped",[969]],[[120571,120571],"mapped",[8711]],[[120572,120572],"mapped",[945]],[[120573,120573],"mapped",[946]],[[120574,120574],"mapped",[947]],[[120575,120575],"mapped",[948]],[[120576,120576],"mapped",[949]],[[120577,120577],"mapped",[950]],[[120578,120578],"mapped",[951]],[[120579,120579],"mapped",[952]],[[120580,120580],"mapped",[953]],[[120581,120581],"mapped",[954]],[[120582,120582],"mapped",[955]],[[120583,120583],"mapped",[956]],[[120584,120584],"mapped",[957]],[[120585,120585],"mapped",[958]],[[120586,120586],"mapped",[959]],[[120587,120587],"mapped",[960]],[[120588,120588],"mapped",[961]],[[120589,120590],"mapped",[963]],[[120591,120591],"mapped",[964]],[[120592,120592],"mapped",[965]],[[120593,120593],"mapped",[966]],[[120594,120594],"mapped",[967]],[[120595,120595],"mapped",[968]],[[120596,120596],"mapped",[969]],[[120597,120597],"mapped",[8706]],[[120598,120598],"mapped",[949]],[[120599,120599],"mapped",[952]],[[120600,120600],"mapped",[954]],[[120601,120601],"mapped",[966]],[[120602,120602],"mapped",[961]],[[120603,120603],"mapped",[960]],[[120604,120604],"mapped",[945]],[[120605,120605],"mapped",[946]],[[120606,120606],"mapped",[947]],[[120607,120607],"mapped",[948]],[[120608,120608],"mapped",[949]],[[120609,120609],"mapped",[950]],[[120610,120610],"mapped",[951]],[[120611,120611],"mapped",[952]],[[120612,120612],"mapped",[953]],[[120613,120613],"mapped",[954]],[[120614,120614],"mapped",[955]],[[120615,120615],"mapped",[956]],[[120616,120616],"mapped",[957]],[[120617,120617],"mapped",[958]],[[120618,120618],"mapped",[959]],[[120619,120619],"mapped",[960]],[[120620,120620],"mapped",[961]],[[120621,120621],"mapped",[952]],[[120622,120622],"mapped",[963]],[[120623,120623],"mapped",[964]],[[120624,120624],"mapped",[965]],[[120625,120625],"mapped",[966]],[[120626,120626],"mapped",[967]],[[120627,120627],"mapped",[968]],[[120628,120628],"mapped",[969]],[[120629,120629],"mapped",[8711]],[[120630,120630],"mapped",[945]],[[120631,120631],"mapped",[946]],[[120632,120632],"mapped",[947]],[[120633,120633],"mapped",[948]],[[120634,120634],"mapped",[949]],[[120635,120635],"mapped",[950]],[[120636,120636],"mapped",[951]],[[120637,120637],"mapped",[952]],[[120638,120638],"mapped",[953]],[[120639,120639],"mapped",[954]],[[120640,120640],"mapped",[955]],[[120641,120641],"mapped",[956]],[[120642,120642],"mapped",[957]],[[120643,120643],"mapped",[958]],[[120644,120644],"mapped",[959]],[[120645,120645],"mapped",[960]],[[120646,120646],"mapped",[961]],[[120647,120648],"mapped",[963]],[[120649,120649],"mapped",[964]],[[120650,120650],"mapped",[965]],[[120651,120651],"mapped",[966]],[[120652,120652],"mapped",[967]],[[120653,120653],"mapped",[968]],[[120654,120654],"mapped",[969]],[[120655,120655],"mapped",[8706]],[[120656,120656],"mapped",[949]],[[120657,120657],"mapped",[952]],[[120658,120658],"mapped",[954]],[[120659,120659],"mapped",[966]],[[120660,120660],"mapped",[961]],[[120661,120661],"mapped",[960]],[[120662,120662],"mapped",[945]],[[120663,120663],"mapped",[946]],[[120664,120664],"mapped",[947]],[[120665,120665],"mapped",[948]],[[120666,120666],"mapped",[949]],[[120667,120667],"mapped",[950]],[[120668,120668],"mapped",[951]],[[120669,120669],"mapped",[952]],[[120670,120670],"mapped",[953]],[[120671,120671],"mapped",[954]],[[120672,120672],"mapped",[955]],[[120673,120673],"mapped",[956]],[[120674,120674],"mapped",[957]],[[120675,120675],"mapped",[958]],[[120676,120676],"mapped",[959]],[[120677,120677],"mapped",[960]],[[120678,120678],"mapped",[961]],[[120679,120679],"mapped",[952]],[[120680,120680],"mapped",[963]],[[120681,120681],"mapped",[964]],[[120682,120682],"mapped",[965]],[[120683,120683],"mapped",[966]],[[120684,120684],"mapped",[967]],[[120685,120685],"mapped",[968]],[[120686,120686],"mapped",[969]],[[120687,120687],"mapped",[8711]],[[120688,120688],"mapped",[945]],[[120689,120689],"mapped",[946]],[[120690,120690],"mapped",[947]],[[120691,120691],"mapped",[948]],[[120692,120692],"mapped",[949]],[[120693,120693],"mapped",[950]],[[120694,120694],"mapped",[951]],[[120695,120695],"mapped",[952]],[[120696,120696],"mapped",[953]],[[120697,120697],"mapped",[954]],[[120698,120698],"mapped",[955]],[[120699,120699],"mapped",[956]],[[120700,120700],"mapped",[957]],[[120701,120701],"mapped",[958]],[[120702,120702],"mapped",[959]],[[120703,120703],"mapped",[960]],[[120704,120704],"mapped",[961]],[[120705,120706],"mapped",[963]],[[120707,120707],"mapped",[964]],[[120708,120708],"mapped",[965]],[[120709,120709],"mapped",[966]],[[120710,120710],"mapped",[967]],[[120711,120711],"mapped",[968]],[[120712,120712],"mapped",[969]],[[120713,120713],"mapped",[8706]],[[120714,120714],"mapped",[949]],[[120715,120715],"mapped",[952]],[[120716,120716],"mapped",[954]],[[120717,120717],"mapped",[966]],[[120718,120718],"mapped",[961]],[[120719,120719],"mapped",[960]],[[120720,120720],"mapped",[945]],[[120721,120721],"mapped",[946]],[[120722,120722],"mapped",[947]],[[120723,120723],"mapped",[948]],[[120724,120724],"mapped",[949]],[[120725,120725],"mapped",[950]],[[120726,120726],"mapped",[951]],[[120727,120727],"mapped",[952]],[[120728,120728],"mapped",[953]],[[120729,120729],"mapped",[954]],[[120730,120730],"mapped",[955]],[[120731,120731],"mapped",[956]],[[120732,120732],"mapped",[957]],[[120733,120733],"mapped",[958]],[[120734,120734],"mapped",[959]],[[120735,120735],"mapped",[960]],[[120736,120736],"mapped",[961]],[[120737,120737],"mapped",[952]],[[120738,120738],"mapped",[963]],[[120739,120739],"mapped",[964]],[[120740,120740],"mapped",[965]],[[120741,120741],"mapped",[966]],[[120742,120742],"mapped",[967]],[[120743,120743],"mapped",[968]],[[120744,120744],"mapped",[969]],[[120745,120745],"mapped",[8711]],[[120746,120746],"mapped",[945]],[[120747,120747],"mapped",[946]],[[120748,120748],"mapped",[947]],[[120749,120749],"mapped",[948]],[[120750,120750],"mapped",[949]],[[120751,120751],"mapped",[950]],[[120752,120752],"mapped",[951]],[[120753,120753],"mapped",[952]],[[120754,120754],"mapped",[953]],[[120755,120755],"mapped",[954]],[[120756,120756],"mapped",[955]],[[120757,120757],"mapped",[956]],[[120758,120758],"mapped",[957]],[[120759,120759],"mapped",[958]],[[120760,120760],"mapped",[959]],[[120761,120761],"mapped",[960]],[[120762,120762],"mapped",[961]],[[120763,120764],"mapped",[963]],[[120765,120765],"mapped",[964]],[[120766,120766],"mapped",[965]],[[120767,120767],"mapped",[966]],[[120768,120768],"mapped",[967]],[[120769,120769],"mapped",[968]],[[120770,120770],"mapped",[969]],[[120771,120771],"mapped",[8706]],[[120772,120772],"mapped",[949]],[[120773,120773],"mapped",[952]],[[120774,120774],"mapped",[954]],[[120775,120775],"mapped",[966]],[[120776,120776],"mapped",[961]],[[120777,120777],"mapped",[960]],[[120778,120779],"mapped",[989]],[[120780,120781],"disallowed"],[[120782,120782],"mapped",[48]],[[120783,120783],"mapped",[49]],[[120784,120784],"mapped",[50]],[[120785,120785],"mapped",[51]],[[120786,120786],"mapped",[52]],[[120787,120787],"mapped",[53]],[[120788,120788],"mapped",[54]],[[120789,120789],"mapped",[55]],[[120790,120790],"mapped",[56]],[[120791,120791],"mapped",[57]],[[120792,120792],"mapped",[48]],[[120793,120793],"mapped",[49]],[[120794,120794],"mapped",[50]],[[120795,120795],"mapped",[51]],[[120796,120796],"mapped",[52]],[[120797,120797],"mapped",[53]],[[120798,120798],"mapped",[54]],[[120799,120799],"mapped",[55]],[[120800,120800],"mapped",[56]],[[120801,120801],"mapped",[57]],[[120802,120802],"mapped",[48]],[[120803,120803],"mapped",[49]],[[120804,120804],"mapped",[50]],[[120805,120805],"mapped",[51]],[[120806,120806],"mapped",[52]],[[120807,120807],"mapped",[53]],[[120808,120808],"mapped",[54]],[[120809,120809],"mapped",[55]],[[120810,120810],"mapped",[56]],[[120811,120811],"mapped",[57]],[[120812,120812],"mapped",[48]],[[120813,120813],"mapped",[49]],[[120814,120814],"mapped",[50]],[[120815,120815],"mapped",[51]],[[120816,120816],"mapped",[52]],[[120817,120817],"mapped",[53]],[[120818,120818],"mapped",[54]],[[120819,120819],"mapped",[55]],[[120820,120820],"mapped",[56]],[[120821,120821],"mapped",[57]],[[120822,120822],"mapped",[48]],[[120823,120823],"mapped",[49]],[[120824,120824],"mapped",[50]],[[120825,120825],"mapped",[51]],[[120826,120826],"mapped",[52]],[[120827,120827],"mapped",[53]],[[120828,120828],"mapped",[54]],[[120829,120829],"mapped",[55]],[[120830,120830],"mapped",[56]],[[120831,120831],"mapped",[57]],[[120832,121343],"valid",[],"NV8"],[[121344,121398],"valid"],[[121399,121402],"valid",[],"NV8"],[[121403,121452],"valid"],[[121453,121460],"valid",[],"NV8"],[[121461,121461],"valid"],[[121462,121475],"valid",[],"NV8"],[[121476,121476],"valid"],[[121477,121483],"valid",[],"NV8"],[[121484,121498],"disallowed"],[[121499,121503],"valid"],[[121504,121504],"disallowed"],[[121505,121519],"valid"],[[121520,124927],"disallowed"],[[124928,125124],"valid"],[[125125,125126],"disallowed"],[[125127,125135],"valid",[],"NV8"],[[125136,125142],"valid"],[[125143,126463],"disallowed"],[[126464,126464],"mapped",[1575]],[[126465,126465],"mapped",[1576]],[[126466,126466],"mapped",[1580]],[[126467,126467],"mapped",[1583]],[[126468,126468],"disallowed"],[[126469,126469],"mapped",[1608]],[[126470,126470],"mapped",[1586]],[[126471,126471],"mapped",[1581]],[[126472,126472],"mapped",[1591]],[[126473,126473],"mapped",[1610]],[[126474,126474],"mapped",[1603]],[[126475,126475],"mapped",[1604]],[[126476,126476],"mapped",[1605]],[[126477,126477],"mapped",[1606]],[[126478,126478],"mapped",[1587]],[[126479,126479],"mapped",[1593]],[[126480,126480],"mapped",[1601]],[[126481,126481],"mapped",[1589]],[[126482,126482],"mapped",[1602]],[[126483,126483],"mapped",[1585]],[[126484,126484],"mapped",[1588]],[[126485,126485],"mapped",[1578]],[[126486,126486],"mapped",[1579]],[[126487,126487],"mapped",[1582]],[[126488,126488],"mapped",[1584]],[[126489,126489],"mapped",[1590]],[[126490,126490],"mapped",[1592]],[[126491,126491],"mapped",[1594]],[[126492,126492],"mapped",[1646]],[[126493,126493],"mapped",[1722]],[[126494,126494],"mapped",[1697]],[[126495,126495],"mapped",[1647]],[[126496,126496],"disallowed"],[[126497,126497],"mapped",[1576]],[[126498,126498],"mapped",[1580]],[[126499,126499],"disallowed"],[[126500,126500],"mapped",[1607]],[[126501,126502],"disallowed"],[[126503,126503],"mapped",[1581]],[[126504,126504],"disallowed"],[[126505,126505],"mapped",[1610]],[[126506,126506],"mapped",[1603]],[[126507,126507],"mapped",[1604]],[[126508,126508],"mapped",[1605]],[[126509,126509],"mapped",[1606]],[[126510,126510],"mapped",[1587]],[[126511,126511],"mapped",[1593]],[[126512,126512],"mapped",[1601]],[[126513,126513],"mapped",[1589]],[[126514,126514],"mapped",[1602]],[[126515,126515],"disallowed"],[[126516,126516],"mapped",[1588]],[[126517,126517],"mapped",[1578]],[[126518,126518],"mapped",[1579]],[[126519,126519],"mapped",[1582]],[[126520,126520],"disallowed"],[[126521,126521],"mapped",[1590]],[[126522,126522],"disallowed"],[[126523,126523],"mapped",[1594]],[[126524,126529],"disallowed"],[[126530,126530],"mapped",[1580]],[[126531,126534],"disallowed"],[[126535,126535],"mapped",[1581]],[[126536,126536],"disallowed"],[[126537,126537],"mapped",[1610]],[[126538,126538],"disallowed"],[[126539,126539],"mapped",[1604]],[[126540,126540],"disallowed"],[[126541,126541],"mapped",[1606]],[[126542,126542],"mapped",[1587]],[[126543,126543],"mapped",[1593]],[[126544,126544],"disallowed"],[[126545,126545],"mapped",[1589]],[[126546,126546],"mapped",[1602]],[[126547,126547],"disallowed"],[[126548,126548],"mapped",[1588]],[[126549,126550],"disallowed"],[[126551,126551],"mapped",[1582]],[[126552,126552],"disallowed"],[[126553,126553],"mapped",[1590]],[[126554,126554],"disallowed"],[[126555,126555],"mapped",[1594]],[[126556,126556],"disallowed"],[[126557,126557],"mapped",[1722]],[[126558,126558],"disallowed"],[[126559,126559],"mapped",[1647]],[[126560,126560],"disallowed"],[[126561,126561],"mapped",[1576]],[[126562,126562],"mapped",[1580]],[[126563,126563],"disallowed"],[[126564,126564],"mapped",[1607]],[[126565,126566],"disallowed"],[[126567,126567],"mapped",[1581]],[[126568,126568],"mapped",[1591]],[[126569,126569],"mapped",[1610]],[[126570,126570],"mapped",[1603]],[[126571,126571],"disallowed"],[[126572,126572],"mapped",[1605]],[[126573,126573],"mapped",[1606]],[[126574,126574],"mapped",[1587]],[[126575,126575],"mapped",[1593]],[[126576,126576],"mapped",[1601]],[[126577,126577],"mapped",[1589]],[[126578,126578],"mapped",[1602]],[[126579,126579],"disallowed"],[[126580,126580],"mapped",[1588]],[[126581,126581],"mapped",[1578]],[[126582,126582],"mapped",[1579]],[[126583,126583],"mapped",[1582]],[[126584,126584],"disallowed"],[[126585,126585],"mapped",[1590]],[[126586,126586],"mapped",[1592]],[[126587,126587],"mapped",[1594]],[[126588,126588],"mapped",[1646]],[[126589,126589],"disallowed"],[[126590,126590],"mapped",[1697]],[[126591,126591],"disallowed"],[[126592,126592],"mapped",[1575]],[[126593,126593],"mapped",[1576]],[[126594,126594],"mapped",[1580]],[[126595,126595],"mapped",[1583]],[[126596,126596],"mapped",[1607]],[[126597,126597],"mapped",[1608]],[[126598,126598],"mapped",[1586]],[[126599,126599],"mapped",[1581]],[[126600,126600],"mapped",[1591]],[[126601,126601],"mapped",[1610]],[[126602,126602],"disallowed"],[[126603,126603],"mapped",[1604]],[[126604,126604],"mapped",[1605]],[[126605,126605],"mapped",[1606]],[[126606,126606],"mapped",[1587]],[[126607,126607],"mapped",[1593]],[[126608,126608],"mapped",[1601]],[[126609,126609],"mapped",[1589]],[[126610,126610],"mapped",[1602]],[[126611,126611],"mapped",[1585]],[[126612,126612],"mapped",[1588]],[[126613,126613],"mapped",[1578]],[[126614,126614],"mapped",[1579]],[[126615,126615],"mapped",[1582]],[[126616,126616],"mapped",[1584]],[[126617,126617],"mapped",[1590]],[[126618,126618],"mapped",[1592]],[[126619,126619],"mapped",[1594]],[[126620,126624],"disallowed"],[[126625,126625],"mapped",[1576]],[[126626,126626],"mapped",[1580]],[[126627,126627],"mapped",[1583]],[[126628,126628],"disallowed"],[[126629,126629],"mapped",[1608]],[[126630,126630],"mapped",[1586]],[[126631,126631],"mapped",[1581]],[[126632,126632],"mapped",[1591]],[[126633,126633],"mapped",[1610]],[[126634,126634],"disallowed"],[[126635,126635],"mapped",[1604]],[[126636,126636],"mapped",[1605]],[[126637,126637],"mapped",[1606]],[[126638,126638],"mapped",[1587]],[[126639,126639],"mapped",[1593]],[[126640,126640],"mapped",[1601]],[[126641,126641],"mapped",[1589]],[[126642,126642],"mapped",[1602]],[[126643,126643],"mapped",[1585]],[[126644,126644],"mapped",[1588]],[[126645,126645],"mapped",[1578]],[[126646,126646],"mapped",[1579]],[[126647,126647],"mapped",[1582]],[[126648,126648],"mapped",[1584]],[[126649,126649],"mapped",[1590]],[[126650,126650],"mapped",[1592]],[[126651,126651],"mapped",[1594]],[[126652,126703],"disallowed"],[[126704,126705],"valid",[],"NV8"],[[126706,126975],"disallowed"],[[126976,127019],"valid",[],"NV8"],[[127020,127023],"disallowed"],[[127024,127123],"valid",[],"NV8"],[[127124,127135],"disallowed"],[[127136,127150],"valid",[],"NV8"],[[127151,127152],"disallowed"],[[127153,127166],"valid",[],"NV8"],[[127167,127167],"valid",[],"NV8"],[[127168,127168],"disallowed"],[[127169,127183],"valid",[],"NV8"],[[127184,127184],"disallowed"],[[127185,127199],"valid",[],"NV8"],[[127200,127221],"valid",[],"NV8"],[[127222,127231],"disallowed"],[[127232,127232],"disallowed"],[[127233,127233],"disallowed_STD3_mapped",[48,44]],[[127234,127234],"disallowed_STD3_mapped",[49,44]],[[127235,127235],"disallowed_STD3_mapped",[50,44]],[[127236,127236],"disallowed_STD3_mapped",[51,44]],[[127237,127237],"disallowed_STD3_mapped",[52,44]],[[127238,127238],"disallowed_STD3_mapped",[53,44]],[[127239,127239],"disallowed_STD3_mapped",[54,44]],[[127240,127240],"disallowed_STD3_mapped",[55,44]],[[127241,127241],"disallowed_STD3_mapped",[56,44]],[[127242,127242],"disallowed_STD3_mapped",[57,44]],[[127243,127244],"valid",[],"NV8"],[[127245,127247],"disallowed"],[[127248,127248],"disallowed_STD3_mapped",[40,97,41]],[[127249,127249],"disallowed_STD3_mapped",[40,98,41]],[[127250,127250],"disallowed_STD3_mapped",[40,99,41]],[[127251,127251],"disallowed_STD3_mapped",[40,100,41]],[[127252,127252],"disallowed_STD3_mapped",[40,101,41]],[[127253,127253],"disallowed_STD3_mapped",[40,102,41]],[[127254,127254],"disallowed_STD3_mapped",[40,103,41]],[[127255,127255],"disallowed_STD3_mapped",[40,104,41]],[[127256,127256],"disallowed_STD3_mapped",[40,105,41]],[[127257,127257],"disallowed_STD3_mapped",[40,106,41]],[[127258,127258],"disallowed_STD3_mapped",[40,107,41]],[[127259,127259],"disallowed_STD3_mapped",[40,108,41]],[[127260,127260],"disallowed_STD3_mapped",[40,109,41]],[[127261,127261],"disallowed_STD3_mapped",[40,110,41]],[[127262,127262],"disallowed_STD3_mapped",[40,111,41]],[[127263,127263],"disallowed_STD3_mapped",[40,112,41]],[[127264,127264],"disallowed_STD3_mapped",[40,113,41]],[[127265,127265],"disallowed_STD3_mapped",[40,114,41]],[[127266,127266],"disallowed_STD3_mapped",[40,115,41]],[[127267,127267],"disallowed_STD3_mapped",[40,116,41]],[[127268,127268],"disallowed_STD3_mapped",[40,117,41]],[[127269,127269],"disallowed_STD3_mapped",[40,118,41]],[[127270,127270],"disallowed_STD3_mapped",[40,119,41]],[[127271,127271],"disallowed_STD3_mapped",[40,120,41]],[[127272,127272],"disallowed_STD3_mapped",[40,121,41]],[[127273,127273],"disallowed_STD3_mapped",[40,122,41]],[[127274,127274],"mapped",[12308,115,12309]],[[127275,127275],"mapped",[99]],[[127276,127276],"mapped",[114]],[[127277,127277],"mapped",[99,100]],[[127278,127278],"mapped",[119,122]],[[127279,127279],"disallowed"],[[127280,127280],"mapped",[97]],[[127281,127281],"mapped",[98]],[[127282,127282],"mapped",[99]],[[127283,127283],"mapped",[100]],[[127284,127284],"mapped",[101]],[[127285,127285],"mapped",[102]],[[127286,127286],"mapped",[103]],[[127287,127287],"mapped",[104]],[[127288,127288],"mapped",[105]],[[127289,127289],"mapped",[106]],[[127290,127290],"mapped",[107]],[[127291,127291],"mapped",[108]],[[127292,127292],"mapped",[109]],[[127293,127293],"mapped",[110]],[[127294,127294],"mapped",[111]],[[127295,127295],"mapped",[112]],[[127296,127296],"mapped",[113]],[[127297,127297],"mapped",[114]],[[127298,127298],"mapped",[115]],[[127299,127299],"mapped",[116]],[[127300,127300],"mapped",[117]],[[127301,127301],"mapped",[118]],[[127302,127302],"mapped",[119]],[[127303,127303],"mapped",[120]],[[127304,127304],"mapped",[121]],[[127305,127305],"mapped",[122]],[[127306,127306],"mapped",[104,118]],[[127307,127307],"mapped",[109,118]],[[127308,127308],"mapped",[115,100]],[[127309,127309],"mapped",[115,115]],[[127310,127310],"mapped",[112,112,118]],[[127311,127311],"mapped",[119,99]],[[127312,127318],"valid",[],"NV8"],[[127319,127319],"valid",[],"NV8"],[[127320,127326],"valid",[],"NV8"],[[127327,127327],"valid",[],"NV8"],[[127328,127337],"valid",[],"NV8"],[[127338,127338],"mapped",[109,99]],[[127339,127339],"mapped",[109,100]],[[127340,127343],"disallowed"],[[127344,127352],"valid",[],"NV8"],[[127353,127353],"valid",[],"NV8"],[[127354,127354],"valid",[],"NV8"],[[127355,127356],"valid",[],"NV8"],[[127357,127358],"valid",[],"NV8"],[[127359,127359],"valid",[],"NV8"],[[127360,127369],"valid",[],"NV8"],[[127370,127373],"valid",[],"NV8"],[[127374,127375],"valid",[],"NV8"],[[127376,127376],"mapped",[100,106]],[[127377,127386],"valid",[],"NV8"],[[127387,127461],"disallowed"],[[127462,127487],"valid",[],"NV8"],[[127488,127488],"mapped",[12411,12363]],[[127489,127489],"mapped",[12467,12467]],[[127490,127490],"mapped",[12469]],[[127491,127503],"disallowed"],[[127504,127504],"mapped",[25163]],[[127505,127505],"mapped",[23383]],[[127506,127506],"mapped",[21452]],[[127507,127507],"mapped",[12487]],[[127508,127508],"mapped",[20108]],[[127509,127509],"mapped",[22810]],[[127510,127510],"mapped",[35299]],[[127511,127511],"mapped",[22825]],[[127512,127512],"mapped",[20132]],[[127513,127513],"mapped",[26144]],[[127514,127514],"mapped",[28961]],[[127515,127515],"mapped",[26009]],[[127516,127516],"mapped",[21069]],[[127517,127517],"mapped",[24460]],[[127518,127518],"mapped",[20877]],[[127519,127519],"mapped",[26032]],[[127520,127520],"mapped",[21021]],[[127521,127521],"mapped",[32066]],[[127522,127522],"mapped",[29983]],[[127523,127523],"mapped",[36009]],[[127524,127524],"mapped",[22768]],[[127525,127525],"mapped",[21561]],[[127526,127526],"mapped",[28436]],[[127527,127527],"mapped",[25237]],[[127528,127528],"mapped",[25429]],[[127529,127529],"mapped",[19968]],[[127530,127530],"mapped",[19977]],[[127531,127531],"mapped",[36938]],[[127532,127532],"mapped",[24038]],[[127533,127533],"mapped",[20013]],[[127534,127534],"mapped",[21491]],[[127535,127535],"mapped",[25351]],[[127536,127536],"mapped",[36208]],[[127537,127537],"mapped",[25171]],[[127538,127538],"mapped",[31105]],[[127539,127539],"mapped",[31354]],[[127540,127540],"mapped",[21512]],[[127541,127541],"mapped",[28288]],[[127542,127542],"mapped",[26377]],[[127543,127543],"mapped",[26376]],[[127544,127544],"mapped",[30003]],[[127545,127545],"mapped",[21106]],[[127546,127546],"mapped",[21942]],[[127547,127551],"disallowed"],[[127552,127552],"mapped",[12308,26412,12309]],[[127553,127553],"mapped",[12308,19977,12309]],[[127554,127554],"mapped",[12308,20108,12309]],[[127555,127555],"mapped",[12308,23433,12309]],[[127556,127556],"mapped",[12308,28857,12309]],[[127557,127557],"mapped",[12308,25171,12309]],[[127558,127558],"mapped",[12308,30423,12309]],[[127559,127559],"mapped",[12308,21213,12309]],[[127560,127560],"mapped",[12308,25943,12309]],[[127561,127567],"disallowed"],[[127568,127568],"mapped",[24471]],[[127569,127569],"mapped",[21487]],[[127570,127743],"disallowed"],[[127744,127776],"valid",[],"NV8"],[[127777,127788],"valid",[],"NV8"],[[127789,127791],"valid",[],"NV8"],[[127792,127797],"valid",[],"NV8"],[[127798,127798],"valid",[],"NV8"],[[127799,127868],"valid",[],"NV8"],[[127869,127869],"valid",[],"NV8"],[[127870,127871],"valid",[],"NV8"],[[127872,127891],"valid",[],"NV8"],[[127892,127903],"valid",[],"NV8"],[[127904,127940],"valid",[],"NV8"],[[127941,127941],"valid",[],"NV8"],[[127942,127946],"valid",[],"NV8"],[[127947,127950],"valid",[],"NV8"],[[127951,127955],"valid",[],"NV8"],[[127956,127967],"valid",[],"NV8"],[[127968,127984],"valid",[],"NV8"],[[127985,127991],"valid",[],"NV8"],[[127992,127999],"valid",[],"NV8"],[[128000,128062],"valid",[],"NV8"],[[128063,128063],"valid",[],"NV8"],[[128064,128064],"valid",[],"NV8"],[[128065,128065],"valid",[],"NV8"],[[128066,128247],"valid",[],"NV8"],[[128248,128248],"valid",[],"NV8"],[[128249,128252],"valid",[],"NV8"],[[128253,128254],"valid",[],"NV8"],[[128255,128255],"valid",[],"NV8"],[[128256,128317],"valid",[],"NV8"],[[128318,128319],"valid",[],"NV8"],[[128320,128323],"valid",[],"NV8"],[[128324,128330],"valid",[],"NV8"],[[128331,128335],"valid",[],"NV8"],[[128336,128359],"valid",[],"NV8"],[[128360,128377],"valid",[],"NV8"],[[128378,128378],"disallowed"],[[128379,128419],"valid",[],"NV8"],[[128420,128420],"disallowed"],[[128421,128506],"valid",[],"NV8"],[[128507,128511],"valid",[],"NV8"],[[128512,128512],"valid",[],"NV8"],[[128513,128528],"valid",[],"NV8"],[[128529,128529],"valid",[],"NV8"],[[128530,128532],"valid",[],"NV8"],[[128533,128533],"valid",[],"NV8"],[[128534,128534],"valid",[],"NV8"],[[128535,128535],"valid",[],"NV8"],[[128536,128536],"valid",[],"NV8"],[[128537,128537],"valid",[],"NV8"],[[128538,128538],"valid",[],"NV8"],[[128539,128539],"valid",[],"NV8"],[[128540,128542],"valid",[],"NV8"],[[128543,128543],"valid",[],"NV8"],[[128544,128549],"valid",[],"NV8"],[[128550,128551],"valid",[],"NV8"],[[128552,128555],"valid",[],"NV8"],[[128556,128556],"valid",[],"NV8"],[[128557,128557],"valid",[],"NV8"],[[128558,128559],"valid",[],"NV8"],[[128560,128563],"valid",[],"NV8"],[[128564,128564],"valid",[],"NV8"],[[128565,128576],"valid",[],"NV8"],[[128577,128578],"valid",[],"NV8"],[[128579,128580],"valid",[],"NV8"],[[128581,128591],"valid",[],"NV8"],[[128592,128639],"valid",[],"NV8"],[[128640,128709],"valid",[],"NV8"],[[128710,128719],"valid",[],"NV8"],[[128720,128720],"valid",[],"NV8"],[[128721,128735],"disallowed"],[[128736,128748],"valid",[],"NV8"],[[128749,128751],"disallowed"],[[128752,128755],"valid",[],"NV8"],[[128756,128767],"disallowed"],[[128768,128883],"valid",[],"NV8"],[[128884,128895],"disallowed"],[[128896,128980],"valid",[],"NV8"],[[128981,129023],"disallowed"],[[129024,129035],"valid",[],"NV8"],[[129036,129039],"disallowed"],[[129040,129095],"valid",[],"NV8"],[[129096,129103],"disallowed"],[[129104,129113],"valid",[],"NV8"],[[129114,129119],"disallowed"],[[129120,129159],"valid",[],"NV8"],[[129160,129167],"disallowed"],[[129168,129197],"valid",[],"NV8"],[[129198,129295],"disallowed"],[[129296,129304],"valid",[],"NV8"],[[129305,129407],"disallowed"],[[129408,129412],"valid",[],"NV8"],[[129413,129471],"disallowed"],[[129472,129472],"valid",[],"NV8"],[[129473,131069],"disallowed"],[[131070,131071],"disallowed"],[[131072,173782],"valid"],[[173783,173823],"disallowed"],[[173824,177972],"valid"],[[177973,177983],"disallowed"],[[177984,178205],"valid"],[[178206,178207],"disallowed"],[[178208,183969],"valid"],[[183970,194559],"disallowed"],[[194560,194560],"mapped",[20029]],[[194561,194561],"mapped",[20024]],[[194562,194562],"mapped",[20033]],[[194563,194563],"mapped",[131362]],[[194564,194564],"mapped",[20320]],[[194565,194565],"mapped",[20398]],[[194566,194566],"mapped",[20411]],[[194567,194567],"mapped",[20482]],[[194568,194568],"mapped",[20602]],[[194569,194569],"mapped",[20633]],[[194570,194570],"mapped",[20711]],[[194571,194571],"mapped",[20687]],[[194572,194572],"mapped",[13470]],[[194573,194573],"mapped",[132666]],[[194574,194574],"mapped",[20813]],[[194575,194575],"mapped",[20820]],[[194576,194576],"mapped",[20836]],[[194577,194577],"mapped",[20855]],[[194578,194578],"mapped",[132380]],[[194579,194579],"mapped",[13497]],[[194580,194580],"mapped",[20839]],[[194581,194581],"mapped",[20877]],[[194582,194582],"mapped",[132427]],[[194583,194583],"mapped",[20887]],[[194584,194584],"mapped",[20900]],[[194585,194585],"mapped",[20172]],[[194586,194586],"mapped",[20908]],[[194587,194587],"mapped",[20917]],[[194588,194588],"mapped",[168415]],[[194589,194589],"mapped",[20981]],[[194590,194590],"mapped",[20995]],[[194591,194591],"mapped",[13535]],[[194592,194592],"mapped",[21051]],[[194593,194593],"mapped",[21062]],[[194594,194594],"mapped",[21106]],[[194595,194595],"mapped",[21111]],[[194596,194596],"mapped",[13589]],[[194597,194597],"mapped",[21191]],[[194598,194598],"mapped",[21193]],[[194599,194599],"mapped",[21220]],[[194600,194600],"mapped",[21242]],[[194601,194601],"mapped",[21253]],[[194602,194602],"mapped",[21254]],[[194603,194603],"mapped",[21271]],[[194604,194604],"mapped",[21321]],[[194605,194605],"mapped",[21329]],[[194606,194606],"mapped",[21338]],[[194607,194607],"mapped",[21363]],[[194608,194608],"mapped",[21373]],[[194609,194611],"mapped",[21375]],[[194612,194612],"mapped",[133676]],[[194613,194613],"mapped",[28784]],[[194614,194614],"mapped",[21450]],[[194615,194615],"mapped",[21471]],[[194616,194616],"mapped",[133987]],[[194617,194617],"mapped",[21483]],[[194618,194618],"mapped",[21489]],[[194619,194619],"mapped",[21510]],[[194620,194620],"mapped",[21662]],[[194621,194621],"mapped",[21560]],[[194622,194622],"mapped",[21576]],[[194623,194623],"mapped",[21608]],[[194624,194624],"mapped",[21666]],[[194625,194625],"mapped",[21750]],[[194626,194626],"mapped",[21776]],[[194627,194627],"mapped",[21843]],[[194628,194628],"mapped",[21859]],[[194629,194630],"mapped",[21892]],[[194631,194631],"mapped",[21913]],[[194632,194632],"mapped",[21931]],[[194633,194633],"mapped",[21939]],[[194634,194634],"mapped",[21954]],[[194635,194635],"mapped",[22294]],[[194636,194636],"mapped",[22022]],[[194637,194637],"mapped",[22295]],[[194638,194638],"mapped",[22097]],[[194639,194639],"mapped",[22132]],[[194640,194640],"mapped",[20999]],[[194641,194641],"mapped",[22766]],[[194642,194642],"mapped",[22478]],[[194643,194643],"mapped",[22516]],[[194644,194644],"mapped",[22541]],[[194645,194645],"mapped",[22411]],[[194646,194646],"mapped",[22578]],[[194647,194647],"mapped",[22577]],[[194648,194648],"mapped",[22700]],[[194649,194649],"mapped",[136420]],[[194650,194650],"mapped",[22770]],[[194651,194651],"mapped",[22775]],[[194652,194652],"mapped",[22790]],[[194653,194653],"mapped",[22810]],[[194654,194654],"mapped",[22818]],[[194655,194655],"mapped",[22882]],[[194656,194656],"mapped",[136872]],[[194657,194657],"mapped",[136938]],[[194658,194658],"mapped",[23020]],[[194659,194659],"mapped",[23067]],[[194660,194660],"mapped",[23079]],[[194661,194661],"mapped",[23000]],[[194662,194662],"mapped",[23142]],[[194663,194663],"mapped",[14062]],[[194664,194664],"disallowed"],[[194665,194665],"mapped",[23304]],[[194666,194667],"mapped",[23358]],[[194668,194668],"mapped",[137672]],[[194669,194669],"mapped",[23491]],[[194670,194670],"mapped",[23512]],[[194671,194671],"mapped",[23527]],[[194672,194672],"mapped",[23539]],[[194673,194673],"mapped",[138008]],[[194674,194674],"mapped",[23551]],[[194675,194675],"mapped",[23558]],[[194676,194676],"disallowed"],[[194677,194677],"mapped",[23586]],[[194678,194678],"mapped",[14209]],[[194679,194679],"mapped",[23648]],[[194680,194680],"mapped",[23662]],[[194681,194681],"mapped",[23744]],[[194682,194682],"mapped",[23693]],[[194683,194683],"mapped",[138724]],[[194684,194684],"mapped",[23875]],[[194685,194685],"mapped",[138726]],[[194686,194686],"mapped",[23918]],[[194687,194687],"mapped",[23915]],[[194688,194688],"mapped",[23932]],[[194689,194689],"mapped",[24033]],[[194690,194690],"mapped",[24034]],[[194691,194691],"mapped",[14383]],[[194692,194692],"mapped",[24061]],[[194693,194693],"mapped",[24104]],[[194694,194694],"mapped",[24125]],[[194695,194695],"mapped",[24169]],[[194696,194696],"mapped",[14434]],[[194697,194697],"mapped",[139651]],[[194698,194698],"mapped",[14460]],[[194699,194699],"mapped",[24240]],[[194700,194700],"mapped",[24243]],[[194701,194701],"mapped",[24246]],[[194702,194702],"mapped",[24266]],[[194703,194703],"mapped",[172946]],[[194704,194704],"mapped",[24318]],[[194705,194706],"mapped",[140081]],[[194707,194707],"mapped",[33281]],[[194708,194709],"mapped",[24354]],[[194710,194710],"mapped",[14535]],[[194711,194711],"mapped",[144056]],[[194712,194712],"mapped",[156122]],[[194713,194713],"mapped",[24418]],[[194714,194714],"mapped",[24427]],[[194715,194715],"mapped",[14563]],[[194716,194716],"mapped",[24474]],[[194717,194717],"mapped",[24525]],[[194718,194718],"mapped",[24535]],[[194719,194719],"mapped",[24569]],[[194720,194720],"mapped",[24705]],[[194721,194721],"mapped",[14650]],[[194722,194722],"mapped",[14620]],[[194723,194723],"mapped",[24724]],[[194724,194724],"mapped",[141012]],[[194725,194725],"mapped",[24775]],[[194726,194726],"mapped",[24904]],[[194727,194727],"mapped",[24908]],[[194728,194728],"mapped",[24910]],[[194729,194729],"mapped",[24908]],[[194730,194730],"mapped",[24954]],[[194731,194731],"mapped",[24974]],[[194732,194732],"mapped",[25010]],[[194733,194733],"mapped",[24996]],[[194734,194734],"mapped",[25007]],[[194735,194735],"mapped",[25054]],[[194736,194736],"mapped",[25074]],[[194737,194737],"mapped",[25078]],[[194738,194738],"mapped",[25104]],[[194739,194739],"mapped",[25115]],[[194740,194740],"mapped",[25181]],[[194741,194741],"mapped",[25265]],[[194742,194742],"mapped",[25300]],[[194743,194743],"mapped",[25424]],[[194744,194744],"mapped",[142092]],[[194745,194745],"mapped",[25405]],[[194746,194746],"mapped",[25340]],[[194747,194747],"mapped",[25448]],[[194748,194748],"mapped",[25475]],[[194749,194749],"mapped",[25572]],[[194750,194750],"mapped",[142321]],[[194751,194751],"mapped",[25634]],[[194752,194752],"mapped",[25541]],[[194753,194753],"mapped",[25513]],[[194754,194754],"mapped",[14894]],[[194755,194755],"mapped",[25705]],[[194756,194756],"mapped",[25726]],[[194757,194757],"mapped",[25757]],[[194758,194758],"mapped",[25719]],[[194759,194759],"mapped",[14956]],[[194760,194760],"mapped",[25935]],[[194761,194761],"mapped",[25964]],[[194762,194762],"mapped",[143370]],[[194763,194763],"mapped",[26083]],[[194764,194764],"mapped",[26360]],[[194765,194765],"mapped",[26185]],[[194766,194766],"mapped",[15129]],[[194767,194767],"mapped",[26257]],[[194768,194768],"mapped",[15112]],[[194769,194769],"mapped",[15076]],[[194770,194770],"mapped",[20882]],[[194771,194771],"mapped",[20885]],[[194772,194772],"mapped",[26368]],[[194773,194773],"mapped",[26268]],[[194774,194774],"mapped",[32941]],[[194775,194775],"mapped",[17369]],[[194776,194776],"mapped",[26391]],[[194777,194777],"mapped",[26395]],[[194778,194778],"mapped",[26401]],[[194779,194779],"mapped",[26462]],[[194780,194780],"mapped",[26451]],[[194781,194781],"mapped",[144323]],[[194782,194782],"mapped",[15177]],[[194783,194783],"mapped",[26618]],[[194784,194784],"mapped",[26501]],[[194785,194785],"mapped",[26706]],[[194786,194786],"mapped",[26757]],[[194787,194787],"mapped",[144493]],[[194788,194788],"mapped",[26766]],[[194789,194789],"mapped",[26655]],[[194790,194790],"mapped",[26900]],[[194791,194791],"mapped",[15261]],[[194792,194792],"mapped",[26946]],[[194793,194793],"mapped",[27043]],[[194794,194794],"mapped",[27114]],[[194795,194795],"mapped",[27304]],[[194796,194796],"mapped",[145059]],[[194797,194797],"mapped",[27355]],[[194798,194798],"mapped",[15384]],[[194799,194799],"mapped",[27425]],[[194800,194800],"mapped",[145575]],[[194801,194801],"mapped",[27476]],[[194802,194802],"mapped",[15438]],[[194803,194803],"mapped",[27506]],[[194804,194804],"mapped",[27551]],[[194805,194805],"mapped",[27578]],[[194806,194806],"mapped",[27579]],[[194807,194807],"mapped",[146061]],[[194808,194808],"mapped",[138507]],[[194809,194809],"mapped",[146170]],[[194810,194810],"mapped",[27726]],[[194811,194811],"mapped",[146620]],[[194812,194812],"mapped",[27839]],[[194813,194813],"mapped",[27853]],[[194814,194814],"mapped",[27751]],[[194815,194815],"mapped",[27926]],[[194816,194816],"mapped",[27966]],[[194817,194817],"mapped",[28023]],[[194818,194818],"mapped",[27969]],[[194819,194819],"mapped",[28009]],[[194820,194820],"mapped",[28024]],[[194821,194821],"mapped",[28037]],[[194822,194822],"mapped",[146718]],[[194823,194823],"mapped",[27956]],[[194824,194824],"mapped",[28207]],[[194825,194825],"mapped",[28270]],[[194826,194826],"mapped",[15667]],[[194827,194827],"mapped",[28363]],[[194828,194828],"mapped",[28359]],[[194829,194829],"mapped",[147153]],[[194830,194830],"mapped",[28153]],[[194831,194831],"mapped",[28526]],[[194832,194832],"mapped",[147294]],[[194833,194833],"mapped",[147342]],[[194834,194834],"mapped",[28614]],[[194835,194835],"mapped",[28729]],[[194836,194836],"mapped",[28702]],[[194837,194837],"mapped",[28699]],[[194838,194838],"mapped",[15766]],[[194839,194839],"mapped",[28746]],[[194840,194840],"mapped",[28797]],[[194841,194841],"mapped",[28791]],[[194842,194842],"mapped",[28845]],[[194843,194843],"mapped",[132389]],[[194844,194844],"mapped",[28997]],[[194845,194845],"mapped",[148067]],[[194846,194846],"mapped",[29084]],[[194847,194847],"disallowed"],[[194848,194848],"mapped",[29224]],[[194849,194849],"mapped",[29237]],[[194850,194850],"mapped",[29264]],[[194851,194851],"mapped",[149000]],[[194852,194852],"mapped",[29312]],[[194853,194853],"mapped",[29333]],[[194854,194854],"mapped",[149301]],[[194855,194855],"mapped",[149524]],[[194856,194856],"mapped",[29562]],[[194857,194857],"mapped",[29579]],[[194858,194858],"mapped",[16044]],[[194859,194859],"mapped",[29605]],[[194860,194861],"mapped",[16056]],[[194862,194862],"mapped",[29767]],[[194863,194863],"mapped",[29788]],[[194864,194864],"mapped",[29809]],[[194865,194865],"mapped",[29829]],[[194866,194866],"mapped",[29898]],[[194867,194867],"mapped",[16155]],[[194868,194868],"mapped",[29988]],[[194869,194869],"mapped",[150582]],[[194870,194870],"mapped",[30014]],[[194871,194871],"mapped",[150674]],[[194872,194872],"mapped",[30064]],[[194873,194873],"mapped",[139679]],[[194874,194874],"mapped",[30224]],[[194875,194875],"mapped",[151457]],[[194876,194876],"mapped",[151480]],[[194877,194877],"mapped",[151620]],[[194878,194878],"mapped",[16380]],[[194879,194879],"mapped",[16392]],[[194880,194880],"mapped",[30452]],[[194881,194881],"mapped",[151795]],[[194882,194882],"mapped",[151794]],[[194883,194883],"mapped",[151833]],[[194884,194884],"mapped",[151859]],[[194885,194885],"mapped",[30494]],[[194886,194887],"mapped",[30495]],[[194888,194888],"mapped",[30538]],[[194889,194889],"mapped",[16441]],[[194890,194890],"mapped",[30603]],[[194891,194891],"mapped",[16454]],[[194892,194892],"mapped",[16534]],[[194893,194893],"mapped",[152605]],[[194894,194894],"mapped",[30798]],[[194895,194895],"mapped",[30860]],[[194896,194896],"mapped",[30924]],[[194897,194897],"mapped",[16611]],[[194898,194898],"mapped",[153126]],[[194899,194899],"mapped",[31062]],[[194900,194900],"mapped",[153242]],[[194901,194901],"mapped",[153285]],[[194902,194902],"mapped",[31119]],[[194903,194903],"mapped",[31211]],[[194904,194904],"mapped",[16687]],[[194905,194905],"mapped",[31296]],[[194906,194906],"mapped",[31306]],[[194907,194907],"mapped",[31311]],[[194908,194908],"mapped",[153980]],[[194909,194910],"mapped",[154279]],[[194911,194911],"disallowed"],[[194912,194912],"mapped",[16898]],[[194913,194913],"mapped",[154539]],[[194914,194914],"mapped",[31686]],[[194915,194915],"mapped",[31689]],[[194916,194916],"mapped",[16935]],[[194917,194917],"mapped",[154752]],[[194918,194918],"mapped",[31954]],[[194919,194919],"mapped",[17056]],[[194920,194920],"mapped",[31976]],[[194921,194921],"mapped",[31971]],[[194922,194922],"mapped",[32000]],[[194923,194923],"mapped",[155526]],[[194924,194924],"mapped",[32099]],[[194925,194925],"mapped",[17153]],[[194926,194926],"mapped",[32199]],[[194927,194927],"mapped",[32258]],[[194928,194928],"mapped",[32325]],[[194929,194929],"mapped",[17204]],[[194930,194930],"mapped",[156200]],[[194931,194931],"mapped",[156231]],[[194932,194932],"mapped",[17241]],[[194933,194933],"mapped",[156377]],[[194934,194934],"mapped",[32634]],[[194935,194935],"mapped",[156478]],[[194936,194936],"mapped",[32661]],[[194937,194937],"mapped",[32762]],[[194938,194938],"mapped",[32773]],[[194939,194939],"mapped",[156890]],[[194940,194940],"mapped",[156963]],[[194941,194941],"mapped",[32864]],[[194942,194942],"mapped",[157096]],[[194943,194943],"mapped",[32880]],[[194944,194944],"mapped",[144223]],[[194945,194945],"mapped",[17365]],[[194946,194946],"mapped",[32946]],[[194947,194947],"mapped",[33027]],[[194948,194948],"mapped",[17419]],[[194949,194949],"mapped",[33086]],[[194950,194950],"mapped",[23221]],[[194951,194951],"mapped",[157607]],[[194952,194952],"mapped",[157621]],[[194953,194953],"mapped",[144275]],[[194954,194954],"mapped",[144284]],[[194955,194955],"mapped",[33281]],[[194956,194956],"mapped",[33284]],[[194957,194957],"mapped",[36766]],[[194958,194958],"mapped",[17515]],[[194959,194959],"mapped",[33425]],[[194960,194960],"mapped",[33419]],[[194961,194961],"mapped",[33437]],[[194962,194962],"mapped",[21171]],[[194963,194963],"mapped",[33457]],[[194964,194964],"mapped",[33459]],[[194965,194965],"mapped",[33469]],[[194966,194966],"mapped",[33510]],[[194967,194967],"mapped",[158524]],[[194968,194968],"mapped",[33509]],[[194969,194969],"mapped",[33565]],[[194970,194970],"mapped",[33635]],[[194971,194971],"mapped",[33709]],[[194972,194972],"mapped",[33571]],[[194973,194973],"mapped",[33725]],[[194974,194974],"mapped",[33767]],[[194975,194975],"mapped",[33879]],[[194976,194976],"mapped",[33619]],[[194977,194977],"mapped",[33738]],[[194978,194978],"mapped",[33740]],[[194979,194979],"mapped",[33756]],[[194980,194980],"mapped",[158774]],[[194981,194981],"mapped",[159083]],[[194982,194982],"mapped",[158933]],[[194983,194983],"mapped",[17707]],[[194984,194984],"mapped",[34033]],[[194985,194985],"mapped",[34035]],[[194986,194986],"mapped",[34070]],[[194987,194987],"mapped",[160714]],[[194988,194988],"mapped",[34148]],[[194989,194989],"mapped",[159532]],[[194990,194990],"mapped",[17757]],[[194991,194991],"mapped",[17761]],[[194992,194992],"mapped",[159665]],[[194993,194993],"mapped",[159954]],[[194994,194994],"mapped",[17771]],[[194995,194995],"mapped",[34384]],[[194996,194996],"mapped",[34396]],[[194997,194997],"mapped",[34407]],[[194998,194998],"mapped",[34409]],[[194999,194999],"mapped",[34473]],[[195000,195000],"mapped",[34440]],[[195001,195001],"mapped",[34574]],[[195002,195002],"mapped",[34530]],[[195003,195003],"mapped",[34681]],[[195004,195004],"mapped",[34600]],[[195005,195005],"mapped",[34667]],[[195006,195006],"mapped",[34694]],[[195007,195007],"disallowed"],[[195008,195008],"mapped",[34785]],[[195009,195009],"mapped",[34817]],[[195010,195010],"mapped",[17913]],[[195011,195011],"mapped",[34912]],[[195012,195012],"mapped",[34915]],[[195013,195013],"mapped",[161383]],[[195014,195014],"mapped",[35031]],[[195015,195015],"mapped",[35038]],[[195016,195016],"mapped",[17973]],[[195017,195017],"mapped",[35066]],[[195018,195018],"mapped",[13499]],[[195019,195019],"mapped",[161966]],[[195020,195020],"mapped",[162150]],[[195021,195021],"mapped",[18110]],[[195022,195022],"mapped",[18119]],[[195023,195023],"mapped",[35488]],[[195024,195024],"mapped",[35565]],[[195025,195025],"mapped",[35722]],[[195026,195026],"mapped",[35925]],[[195027,195027],"mapped",[162984]],[[195028,195028],"mapped",[36011]],[[195029,195029],"mapped",[36033]],[[195030,195030],"mapped",[36123]],[[195031,195031],"mapped",[36215]],[[195032,195032],"mapped",[163631]],[[195033,195033],"mapped",[133124]],[[195034,195034],"mapped",[36299]],[[195035,195035],"mapped",[36284]],[[195036,195036],"mapped",[36336]],[[195037,195037],"mapped",[133342]],[[195038,195038],"mapped",[36564]],[[195039,195039],"mapped",[36664]],[[195040,195040],"mapped",[165330]],[[195041,195041],"mapped",[165357]],[[195042,195042],"mapped",[37012]],[[195043,195043],"mapped",[37105]],[[195044,195044],"mapped",[37137]],[[195045,195045],"mapped",[165678]],[[195046,195046],"mapped",[37147]],[[195047,195047],"mapped",[37432]],[[195048,195048],"mapped",[37591]],[[195049,195049],"mapped",[37592]],[[195050,195050],"mapped",[37500]],[[195051,195051],"mapped",[37881]],[[195052,195052],"mapped",[37909]],[[195053,195053],"mapped",[166906]],[[195054,195054],"mapped",[38283]],[[195055,195055],"mapped",[18837]],[[195056,195056],"mapped",[38327]],[[195057,195057],"mapped",[167287]],[[195058,195058],"mapped",[18918]],[[195059,195059],"mapped",[38595]],[[195060,195060],"mapped",[23986]],[[195061,195061],"mapped",[38691]],[[195062,195062],"mapped",[168261]],[[195063,195063],"mapped",[168474]],[[195064,195064],"mapped",[19054]],[[195065,195065],"mapped",[19062]],[[195066,195066],"mapped",[38880]],[[195067,195067],"mapped",[168970]],[[195068,195068],"mapped",[19122]],[[195069,195069],"mapped",[169110]],[[195070,195071],"mapped",[38923]],[[195072,195072],"mapped",[38953]],[[195073,195073],"mapped",[169398]],[[195074,195074],"mapped",[39138]],[[195075,195075],"mapped",[19251]],[[195076,195076],"mapped",[39209]],[[195077,195077],"mapped",[39335]],[[195078,195078],"mapped",[39362]],[[195079,195079],"mapped",[39422]],[[195080,195080],"mapped",[19406]],[[195081,195081],"mapped",[170800]],[[195082,195082],"mapped",[39698]],[[195083,195083],"mapped",[40000]],[[195084,195084],"mapped",[40189]],[[195085,195085],"mapped",[19662]],[[195086,195086],"mapped",[19693]],[[195087,195087],"mapped",[40295]],[[195088,195088],"mapped",[172238]],[[195089,195089],"mapped",[19704]],[[195090,195090],"mapped",[172293]],[[195091,195091],"mapped",[172558]],[[195092,195092],"mapped",[172689]],[[195093,195093],"mapped",[40635]],[[195094,195094],"mapped",[19798]],[[195095,195095],"mapped",[40697]],[[195096,195096],"mapped",[40702]],[[195097,195097],"mapped",[40709]],[[195098,195098],"mapped",[40719]],[[195099,195099],"mapped",[40726]],[[195100,195100],"mapped",[40763]],[[195101,195101],"mapped",[173568]],[[195102,196605],"disallowed"],[[196606,196607],"disallowed"],[[196608,262141],"disallowed"],[[262142,262143],"disallowed"],[[262144,327677],"disallowed"],[[327678,327679],"disallowed"],[[327680,393213],"disallowed"],[[393214,393215],"disallowed"],[[393216,458749],"disallowed"],[[458750,458751],"disallowed"],[[458752,524285],"disallowed"],[[524286,524287],"disallowed"],[[524288,589821],"disallowed"],[[589822,589823],"disallowed"],[[589824,655357],"disallowed"],[[655358,655359],"disallowed"],[[655360,720893],"disallowed"],[[720894,720895],"disallowed"],[[720896,786429],"disallowed"],[[786430,786431],"disallowed"],[[786432,851965],"disallowed"],[[851966,851967],"disallowed"],[[851968,917501],"disallowed"],[[917502,917503],"disallowed"],[[917504,917504],"disallowed"],[[917505,917505],"disallowed"],[[917506,917535],"disallowed"],[[917536,917631],"disallowed"],[[917632,917759],"disallowed"],[[917760,917999],"ignored"],[[918000,983037],"disallowed"],[[983038,983039],"disallowed"],[[983040,1048573],"disallowed"],[[1048574,1048575],"disallowed"],[[1048576,1114109],"disallowed"],[[1114110,1114111],"disallowed"]] \ No newline at end of file diff --git a/node_modules/tr46/package.json b/node_modules/tr46/package.json new file mode 100644 index 0000000..b6826da --- /dev/null +++ b/node_modules/tr46/package.json @@ -0,0 +1,31 @@ +{ + "name": "tr46", + "version": "0.0.3", + "description": "An implementation of the Unicode TR46 spec", + "main": "index.js", + "scripts": { + "test": "mocha", + "pretest": "node scripts/getLatestUnicodeTests.js", + "prepublish": "node scripts/generateMappingTable.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Sebmaster/tr46.js.git" + }, + "keywords": [ + "unicode", + "tr46", + "url", + "whatwg" + ], + "author": "Sebastian Mayr ", + "license": "MIT", + "bugs": { + "url": "https://github.com/Sebmaster/tr46.js/issues" + }, + "homepage": "https://github.com/Sebmaster/tr46.js#readme", + "devDependencies": { + "mocha": "^2.2.5", + "request": "^2.57.0" + } +} diff --git a/node_modules/tunnel/.idea/encodings.xml b/node_modules/tunnel/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/node_modules/tunnel/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/node_modules/tunnel/.idea/modules.xml b/node_modules/tunnel/.idea/modules.xml new file mode 100644 index 0000000..27bf888 --- /dev/null +++ b/node_modules/tunnel/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/node_modules/tunnel/.idea/node-tunnel.iml b/node_modules/tunnel/.idea/node-tunnel.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/node_modules/tunnel/.idea/node-tunnel.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/tunnel/.idea/vcs.xml b/node_modules/tunnel/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/node_modules/tunnel/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/node_modules/tunnel/.idea/workspace.xml b/node_modules/tunnel/.idea/workspace.xml new file mode 100644 index 0000000..1a318c8 --- /dev/null +++ b/node_modules/tunnel/.idea/workspace.xml @@ -0,0 +1,797 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + max + onconne + + + + + + + + + + + + + false + + false + false + true + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +