From 791fae359862fadd342ffcd4eb41c52df0ae5bbc Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Mon, 23 Nov 2020 18:20:30 -0600 Subject: [PATCH] feat: build module for validating receipts --- .eslintrc.json | 3 +- .github/ISSUE_TEMPLATE/BUG_REPORT.md | 16 + .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 16 + .github/ISSUE_TEMPLATE/HELP.md | 16 + .github/ISSUE_TEMPLATE/config.yml | 1 + .gitignore | 2 + @types/tiny-json-http/index.d.ts | 15 + README.md | 115 +- app/constants.ts | 12 + app/index.test.ts | 7 - app/index.ts | 8 - app/underscore.test.ts | 96 + app/underscore.ts | 52 + app/verify_receipt.test.ts | 74 + app/verify_receipt.ts | 92 + .../apple_response/error.test.ts | 26 + app/verify_receipt/apple_response/error.ts | 53 + app/verify_receipt/apple_response/index.ts | 5 + .../apple_response/latest_receipt_info.ts | 18 + .../apple_response/pending_renewal_info.ts | 89 + app/verify_receipt/apple_response/receipt.ts | 127 + app/verify_receipt/apple_response/success.ts | 56 + .../auto_renewable_subscription/index.test.ts | 28 + .../auto_renewable_subscription/index.ts | 38 + .../subscription.test.ts | 397 +++ .../subscription.ts | 175 ++ .../transaction.test.ts | 312 ++ .../transactions.ts | 105 + app/verify_receipt/parse/error.test.ts | 141 + app/verify_receipt/parse/error.ts | 97 + .../parse/purchase/index.test.ts | 14 + app/verify_receipt/parse/purchase/index.ts | 20 + .../parse/purchase/transaction.test.ts | 131 + .../parse/purchase/transaction.ts | 54 + .../result/auto_renewable_subscription.ts | 184 ++ app/verify_receipt/parse/result/index.ts | 3 + .../parse/result/parsed_receipt.ts | 54 + app/verify_receipt/parse/result/purchase.ts | 28 + app/verify_receipt/parse/success.test.ts | 10 + app/verify_receipt/parse/success.ts | 22 + docs/api/assets/css/main.css | 2535 +---------------- docs/api/assets/js/main.js | 2331 +-------------- docs/api/assets/js/search.json | 36 +- docs/api/classes/appleerror.html | 364 +++ docs/api/classes/internalerror.html | 376 +++ .../enums/appleverifyreceipterrorcode.html | 381 +++ docs/api/globals.html | 748 ++++- docs/api/index.html | 748 ++++- .../appleinapppurchasetransaction.html | 616 ++++ .../interfaces/applependingrenewalinfo.html | 500 ++++ docs/api/interfaces/applereceipt.html | 625 ++++ .../appleverifyreceipterrorresponse.html | 262 ++ .../appleverifyreceiptsuccessfulresponse.html | 384 +++ .../interfaces/autorenewablesubscription.html | 567 ++++ docs/api/interfaces/parsedreceipt.html | 350 +++ docs/api/interfaces/productpurchase.html | 274 ++ .../productpurchasetransaction.html | 298 ++ .../verifyreceiptoptions.html} | 165 +- example/.nvmrc | 1 + example/README.md | 20 + example/app/index.ts | 29 + example/package.json | 18 + example/secrets.json.example | 4 + example/tsconfig.json | 18 + junit.xml | 7 - package-lock.json | 7 +- package.json | 7 +- samples/autorenewable_subscription.json | 18 + samples/autorenewable_subscription2.json | 18 + samples/bought_consumable.json | 306 ++ samples/bought_non_consumable.json | 319 +++ samples/consumable.json | 13 + samples/consumable2.json | 13 + ...auto_renewable_subscription_transaction.ts | 45 + samples/simple.json | 24 + samples/subscription_first_time_purchase.json | 106 + ...ption_multiple_subscription_purchases.json | 291 ++ samples/subscription_renewed.json | 354 +++ .../subscription_second_time_purchase.json | 125 + .../will_autorenew_pending_renewal_info.json | 6 + tsconfig.json | 2 + typedoc.json | 5 +- 82 files changed, 11076 insertions(+), 4952 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md create mode 100644 .github/ISSUE_TEMPLATE/HELP.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 @types/tiny-json-http/index.d.ts create mode 100644 app/constants.ts delete mode 100644 app/index.test.ts delete mode 100644 app/index.ts create mode 100644 app/underscore.test.ts create mode 100644 app/underscore.ts create mode 100644 app/verify_receipt.test.ts create mode 100644 app/verify_receipt.ts create mode 100644 app/verify_receipt/apple_response/error.test.ts create mode 100644 app/verify_receipt/apple_response/error.ts create mode 100644 app/verify_receipt/apple_response/index.ts create mode 100644 app/verify_receipt/apple_response/latest_receipt_info.ts create mode 100644 app/verify_receipt/apple_response/pending_renewal_info.ts create mode 100644 app/verify_receipt/apple_response/receipt.ts create mode 100644 app/verify_receipt/apple_response/success.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/index.test.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/index.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/subscription.test.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/subscription.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/transaction.test.ts create mode 100644 app/verify_receipt/parse/auto_renewable_subscription/transactions.ts create mode 100644 app/verify_receipt/parse/error.test.ts create mode 100644 app/verify_receipt/parse/error.ts create mode 100644 app/verify_receipt/parse/purchase/index.test.ts create mode 100644 app/verify_receipt/parse/purchase/index.ts create mode 100644 app/verify_receipt/parse/purchase/transaction.test.ts create mode 100644 app/verify_receipt/parse/purchase/transaction.ts create mode 100644 app/verify_receipt/parse/result/auto_renewable_subscription.ts create mode 100644 app/verify_receipt/parse/result/index.ts create mode 100644 app/verify_receipt/parse/result/parsed_receipt.ts create mode 100644 app/verify_receipt/parse/result/purchase.ts create mode 100644 app/verify_receipt/parse/success.test.ts create mode 100644 app/verify_receipt/parse/success.ts create mode 100644 docs/api/classes/appleerror.html create mode 100644 docs/api/classes/internalerror.html create mode 100644 docs/api/enums/appleverifyreceipterrorcode.html create mode 100644 docs/api/interfaces/appleinapppurchasetransaction.html create mode 100644 docs/api/interfaces/applependingrenewalinfo.html create mode 100644 docs/api/interfaces/applereceipt.html create mode 100644 docs/api/interfaces/appleverifyreceipterrorresponse.html create mode 100644 docs/api/interfaces/appleverifyreceiptsuccessfulresponse.html create mode 100644 docs/api/interfaces/autorenewablesubscription.html create mode 100644 docs/api/interfaces/parsedreceipt.html create mode 100644 docs/api/interfaces/productpurchase.html create mode 100644 docs/api/interfaces/productpurchasetransaction.html rename docs/api/{modules/_app_index_.html => interfaces/verifyreceiptoptions.html} (96%) create mode 100644 example/.nvmrc create mode 100644 example/README.md create mode 100644 example/app/index.ts create mode 100644 example/package.json create mode 100644 example/secrets.json.example create mode 100644 example/tsconfig.json delete mode 100644 junit.xml create mode 100644 samples/autorenewable_subscription.json create mode 100644 samples/autorenewable_subscription2.json create mode 100644 samples/bought_consumable.json create mode 100644 samples/bought_non_consumable.json create mode 100644 samples/consumable.json create mode 100644 samples/consumable2.json create mode 100644 samples/parsed/auto_renewable_subscription_transaction.ts create mode 100644 samples/simple.json create mode 100644 samples/subscription_first_time_purchase.json create mode 100644 samples/subscription_multiple_subscription_purchases.json create mode 100644 samples/subscription_renewed.json create mode 100644 samples/subscription_second_time_purchase.json create mode 100644 samples/will_autorenew_pending_renewal_info.json diff --git a/.eslintrc.json b/.eslintrc.json index a611c5e..80e2f4f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,7 +15,8 @@ "files": ["*.test.ts"], "rules": { "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/no-explicit-any": "off" + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-var-requires": "off" } } ] diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..717d6af --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,16 @@ +--- +name: 🐛 Bug Report +about: If something isn't working as expected +--- + + + +### New Issue Checklist + +- [ ] What version are you using? (Run `npm ls dollabill-apple` to get it): +- [ ] I read [the documentation](https://github.com/levibostian/dollabill-apple/) +- [ ] I searched for [existing GitHub issues](https://github.com/levibostian/dollabill-apple/issues) + +### Issue Description + + diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..5d171ca --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,16 @@ +--- +name: 💡 Feature request +about: If you have an idea or something to improve +--- + + + +### New Issue Checklist + +- [ ] What version are you using? (Run `npm ls dollabill-apple` to get it): +- [ ] I read [the documentation](https://github.com/levibostian/dollabill-apple/) to see if the project can already do what I am suggesting. +- [ ] I searched for [existing GitHub issues](https://github.com/levibostian/dollabill-apple/issues) to see if anyone else had the same idea. + +### What is the feature request you had in mind? + + diff --git a/.github/ISSUE_TEMPLATE/HELP.md b/.github/ISSUE_TEMPLATE/HELP.md new file mode 100644 index 0000000..20e1a17 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/HELP.md @@ -0,0 +1,16 @@ +--- +name: 😄 Help +about: You have a question about the project +--- + + + +### New Issue Checklist + +- [ ] What version are you using? (Run `npm ls dollabill-apple` to get it): +- [ ] I read [the documentation](https://github.com/levibostian/dollabill-apple/) to see if it could answer my question. +- [ ] I searched for [existing GitHub issues](https://github.com/levibostian/dollabill-apple/issues) to see if anyone else has asked the same question. + +### What's your question 😄 + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ec4bb38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8b46845..72c1ed6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ coverage/ dist/ +secrets.json +junit.xml # Logs logs diff --git a/@types/tiny-json-http/index.d.ts b/@types/tiny-json-http/index.d.ts new file mode 100644 index 0000000..49986d9 --- /dev/null +++ b/@types/tiny-json-http/index.d.ts @@ -0,0 +1,15 @@ +declare type Options = { + url: string + data?: any // form vars for tiny.post, tiny.put, tiny.patch, and tiny.delete otherwise querystring vars for tiny.get + headers?: any // key/value map used for headers (including support for uploading files with multipart/form-data) + buffer?: boolean // if set to true the response body is returned as a buffer + timeout?: number +} + +declare type Callback = (err?: Error, res: { headers: any; body: any }) => void + +export declare function post(options: Options): Promise +export declare function post(options: Options, callback: Callback): void + +export declare function get(options: Options): Promise +export declare function get(options: Options, callback: Callback): void diff --git a/README.md b/README.md index aa40cf2..5f88f8d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,112 @@ -# npm-module-blanky +# dolla bill -Opinionated boilerplate used to make and deploy npm modules. +Easily work with Apple in-app purchases. So you can more easily collect your "Dolla dolla bills, ya'll" -# Goals of this project +# Why use dolla bill? -* Contain configuration files to setup all tools I tend to use in my development flow. -* Clone, rename some files, and get developing! -* Start with zero dependencies. I try my best to keep all npm modules as slim as possible. +When you are accepting in-app purchases in an iOS mobile app, you need to verify the transaction and continuously update your customer's subscription status. This verification and parsing of the responses back from Apple is boilerplate. This small module exists to help you with these tasks. + +- [x] **No dependencies**. This module tries to be as small as possible. +- [x] **Fully tested**. Automated testing (with high test coverage) + QA testing gives you the confidence that the module will work well for you. +- [x] **Complete API documentation** to more easily use it in your code. +- [x] **Up-to-date** If and when Apple changes the way you perform verification or Apple adds more features to verification, update this module and your projects can take advantage of the changes quickly and easily. +- [x] **Typescript typings** This project is written in Typescript for that strict typing goodness. + +> Note: Technically there is [one dependency](https://github.com/brianleroux/tiny-json-http) but it's a _tiny wrapper around a built-in nodejs feature_. This module still remains super small with this. + +# Getting started + +```ts +import dollaBill from "dollabill" + +const receiptFromStoreKit = // The base64 encoded receipt data that StoreKit gave your app + +const appleResponse = await dollaBill.verifyReceipt({ + appPassword: process.env.APPLE_IN_APP_PURCHASE_PASSWORD, + receipt: receiptFromStoreKit +}) + +// If an error happens, it's fatal. It means that there is a bug with this library (create a GitHub issue with stacktrace and other info, please) or you the developer made a mistake when using this library. + +// It's recommended that you, the developer, views the error message and stacktrace to fix the issue. Note: The error here is not meant to be shown to your users. + +if (!appleResponse.isValid) { + // There was a problem. The request was valid and can be retried. + + // look at the error and act on it however you wish. + // It's recommended that you log the error and then return back a message to your users saying there was a problem. The error here is meant for the developer to see, not a good error to return back to the user. + appleResponse.error +} else { + // Time for you to update your database with the status of your customer and their subscription. + // This is easy because dolla bill parses the response from Apple to be easily readable. + // Check out the API documentation to learn about what `appleResponse` properties there are. +} +``` + +```ts +type Response = AppleResponse | AppleError + +enum AppleErrorType {} +// TODO + +type AppleError = { + code: number + type: AppleErrorType +} + +type AppleResponse = { + isValid: boolean + autoRenewableSubscription?: AutoRenewableSubscription // If your in-app purchase is for auto renewable subscriptions, go here. + decodedReceipt: Receipt + raw: any // just in case you need it, here is the raw JSON response from Apple. https://developer.apple.com/documentation/appstorereceipts/responsebody +} + +type AutoRenewableSubscription = { + transactions: Array + pendingRenewals: Array + isGracePeriod: bool + gracePeriod: GracePeriodInfo +} + +type GracePeriodInfo = { + // TODO + // make this up. it comes from: https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info +} + +type PendingRenewal = { + // TODO + // https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info +} + +type Transaction = { + // TODO + // https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info +} + +type Receipt = { + // TODO + // https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt +} +``` + +# Documentation + +// TODO + +## Contributors + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)) + + + + + + + + +

Levi Bostian

💻 📖 🚧
+ + + + + diff --git a/app/constants.ts b/app/constants.ts new file mode 100644 index 0000000..45b017a --- /dev/null +++ b/app/constants.ts @@ -0,0 +1,12 @@ +/** + * @internal + */ +export const bugReportLink = `https://github.com/levibostian/dollabill-apple/issues/new?template=BUG_REPORT.md` +/** + * @internal + */ +export const appleProductionVerifyReceiptEndpoint = "https://buy.itunes.apple.com/verifyReceipt" +/** + * @internal + */ +export const appleSandboxVerifyReceiptEndpoint = "https://sandbox.itunes.apple.com/verifyReceipt" diff --git a/app/index.test.ts b/app/index.test.ts deleted file mode 100644 index d1e7cdf..0000000 --- a/app/index.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { hello } from "." - -describe(`hello`, () => { - it(`given text expect result`, () => { - expect(hello("world")).toEqual("hello world") - }) -}) diff --git a/app/index.ts b/app/index.ts deleted file mode 100644 index 0a961eb..0000000 --- a/app/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Simple function that returns back "hello X" - * @param text The text to combine with "hello" - * @return combined text "hello {text}" - */ -export const hello = (text: string): string => { - return `hello ${text}` -} diff --git a/app/underscore.test.ts b/app/underscore.test.ts new file mode 100644 index 0000000..3670ddb --- /dev/null +++ b/app/underscore.test.ts @@ -0,0 +1,96 @@ +import _ from "./underscore" + +describe("array", () => { + describe("contains", () => { + it(`given empty array, expect false`, async () => { + const given: string[] = [] + + const actual = _.array.contains(given, (item) => item === "foo") + + expect(actual).toEqual(false) + }) + it(`given array without item, expect false`, async () => { + const given: string[] = ["bar"] + + const actual = _.array.contains(given, (item) => item === "foo") + + expect(actual).toEqual(false) + }) + it(`given array with item, expect true`, async () => { + const given: string[] = ["bar", "foo"] + + const actual = _.array.contains(given, (item) => item === "foo") + + expect(actual).toEqual(true) + }) + }) +}) + +describe("date", () => { + describe("sortOldToNew", () => { + it(`given empty array, expect empty array`, async () => { + const given: Date[] = [] + + given.sort(_.date.sortOldToNew) + + expect(given).toEqual([]) + }) + it(`given items already in order, expect unchanged`, async () => { + const given: Date[] = [new Date('2018-04-04T16:00:00.000Z'), new Date('2020-04-04T16:00:00.000Z')] + const expected = given + + given.sort(_.date.sortOldToNew) + + expect(given).toEqual(expected) + }) + it(`given items not in order, expect to sort`, async () => { + const given: Date[] = [new Date('2020-04-04T16:00:00.000Z'), new Date('2018-04-04T16:00:00.000Z')] + const expected = [given[1], given[0]] + + given.sort(_.date.sortOldToNew) + + expect(given).toEqual(expected) + }) + it(`given identical dates, expect unchanged`, async () => { + const given: Date[] = [new Date('2018-04-04T16:00:00.000Z'), new Date('2018-04-04T16:00:00.000Z')] + const expected = given + + given.sort(_.date.sortOldToNew) + + expect(given).toEqual(expected) + }) + }) + describe("sortNewToOld", () => { + it(`given empty array, expect empty array`, async () => { + const given: Date[] = [] + + given.sort(_.date.sortNewToOld) + + expect(given).toEqual([]) + }) + it(`given items already in order, expect unchanged`, async () => { + const given: Date[] = [new Date('2020-04-04T16:00:00.000Z'), new Date('2018-04-04T16:00:00.000Z')] + const expected = given + + given.sort(_.date.sortNewToOld) + + expect(given).toEqual(expected) + }) + it(`given items not in order, expect to sort`, async () => { + const given: Date[] = [new Date('2018-04-04T16:00:00.000Z'), new Date('2020-04-04T16:00:00.000Z')] + const expected = [given[1], given[0]] + + given.sort(_.date.sortNewToOld) + + expect(given).toEqual(expected) + }) + it(`given identical dates, expect unchanged`, async () => { + const given: Date[] = [new Date('2018-04-04T16:00:00.000Z'), new Date('2018-04-04T16:00:00.000Z')] + const expected = given + + given.sort(_.date.sortNewToOld) + + expect(given).toEqual(expected) + }) + }) +}) \ No newline at end of file diff --git a/app/underscore.ts b/app/underscore.ts new file mode 100644 index 0000000..57bcb4c --- /dev/null +++ b/app/underscore.ts @@ -0,0 +1,52 @@ +const _ = { + array: { + contains(array: T[], doesContain: (element: T) => boolean): boolean { + let result = false + + array.forEach((element) => { + if (doesContain(element)) { + result = true + } + }) + + return result + } + }, + date: { + /** + * Sort date array in order: [older date, newer date]. + * + * Use: + * ``` + * const dates: Date[] = [] + * dates.sort(_.date.sortOldToNew) + * + * const nestedDates: {date: Date}[] = [] + * nestedDates.sort((first, second) => _.date.sortOldToNew(first.date, second.date)) + * ``` + */ + sortOldToNew(first: Date, second: Date): number { + return first.getTime() - second.getTime() + }, + /** + * Sort date array in order: [newer date, older date]. + * + * Use: + * ``` + * const dates: Date[] = [] + * dates.sort(_.date.sortNewToOld) + * + * const nestedDates: {date: Date}[] = [] + * nestedDates.sort((first, second) => _.date.sortNewToOld(first.date, second.date)) + * ``` + */ + sortNewToOld(first: Date, second: Date): number { + return second.getTime() - first.getTime() + } + } +} + +/** + * @internal + */ +export default _ diff --git a/app/verify_receipt.test.ts b/app/verify_receipt.test.ts new file mode 100644 index 0000000..d7db6e0 --- /dev/null +++ b/app/verify_receipt.test.ts @@ -0,0 +1,74 @@ +import { verifyReceipt, isFailure } from "./verify_receipt" +import * as constants from "./constants" + +jest.mock('tiny-json-http') +import http from "tiny-json-http" +import { AppleVerifyReceiptErrorCode } from "./verify_receipt/apple_response" +import { AppleError } from "./verify_receipt/parse/error" + +describe("verifyReceipt", () => { + it(`given apple responds saying to use testing environment, expect to use testing environment in 2nd attempt`, async () => { + const postMock = jest.fn().mockResolvedValueOnce({ + status: AppleVerifyReceiptErrorCode.USE_TEST_ENVIRONMENT + }).mockResolvedValueOnce(require('../samples/simple')) + http.post = postMock + + await verifyReceipt("", "") + + expect(postMock.mock.calls).toHaveLength(2) + expect(postMock.mock.calls[0][0].url).toEqual(constants.appleProductionVerifyReceiptEndpoint) + expect(postMock.mock.calls[1][0].url).toEqual(constants.appleSandboxVerifyReceiptEndpoint) + }) + it(`given apple responds with non-200 response, expect receive error`, async () => { + const givenError = new Error("Non-200") + const postMock = jest.fn().mockRejectedValueOnce(givenError) + http.post = postMock + + const actual = await verifyReceipt("", "") + + expect(isFailure(actual)).toEqual(true) + expect(postMock.mock.calls).toHaveLength(1) + }) + it(`expect use production environment by default`, async () => { + const postMock = jest.fn().mockResolvedValueOnce(require('../samples/simple')) + http.post = postMock + + await verifyReceipt("", "") + + expect(postMock.mock.calls).toHaveLength(1) + expect(postMock.mock.calls[0][0].url).toEqual(constants.appleProductionVerifyReceiptEndpoint) + }) + it(`given an apple error response, expect receipt the error result`, async () => { + const postMock = jest.fn().mockResolvedValueOnce({ + status: AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET + }) + http.post = postMock + + const actual = await verifyReceipt("", "") + + expect(postMock.mock.calls).toHaveLength(1) + if (!isFailure(actual)) throw new Error('should be a failure') + expect((actual.error as AppleError).appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET) + }) + it(`given apple returns unknown error code, expect get an error result`, async () => { + const postMock = jest.fn().mockResolvedValueOnce({ + status: 21199 + }) + http.post = postMock + + const actual = await verifyReceipt("", "") + + expect(postMock.mock.calls).toHaveLength(1) + if (!isFailure(actual)) throw new Error('should be a failure') + expect((actual.error as AppleError).appleErrorCode).toEqual(21199) + }) + it(`given successful request, expect to get parsed successful result`, async () => { + const postMock = jest.fn().mockResolvedValueOnce(require("../samples/simple.json")) + http.post = postMock + + const actual = await verifyReceipt("", "") + + expect(postMock.mock.calls).toHaveLength(1) + expect(isFailure(actual)).toEqual(false) + }) +}) diff --git a/app/verify_receipt.ts b/app/verify_receipt.ts new file mode 100644 index 0000000..0929ee5 --- /dev/null +++ b/app/verify_receipt.ts @@ -0,0 +1,92 @@ +import http from "tiny-json-http" +import { + appleProductionVerifyReceiptEndpoint, + appleSandboxVerifyReceiptEndpoint +} from "./constants" +import { + AppleVerifyReceiptErrorCode, + isAppleResponseError +} from "./verify_receipt/apple_response/error" +import { AppleVerifyReceiptResponse } from "./verify_receipt/apple_response/success" +import { handleErrorResponse } from "./verify_receipt/parse/error" +import { ParsedReceipt } from "./verify_receipt/parse/result/parsed_receipt" +import { parseSuccess } from "./verify_receipt/parse/success" + +interface VerifyReceiptOptions { + production: boolean +} + +const runVerifyReceipt = async ( + receipt: string, + sharedSecret: string, + options: VerifyReceiptOptions +): Promise => { + let url = appleSandboxVerifyReceiptEndpoint + if (options.production) { + url = appleProductionVerifyReceiptEndpoint + } + + let verifyReceiptResponse: AppleVerifyReceiptResponse + try { + verifyReceiptResponse = await http.post({ + url, + data: { + "receipt-data": receipt, + password: sharedSecret + } + }) + } catch (httpError) { // https://github.com/brianleroux/tiny-json-http/blob/0c2b3372d8b9a838ac9a63645bf5212427c0ccf3/_write.js#L123-L126 + return { + error: httpError + } + } + + if (isAppleResponseError(verifyReceiptResponse)) { + if (verifyReceiptResponse.status == AppleVerifyReceiptErrorCode.USE_TEST_ENVIRONMENT) { + return runVerifyReceipt(receipt, sharedSecret, { production: false }) + } + + const parsedError = handleErrorResponse(verifyReceiptResponse) + + return { + error: parsedError + } + } else { + return parseSuccess(verifyReceiptResponse) + } +} + +/** + * Represents a failed attempt from {@link verifyReceipt}. + */ +export type VerifyReceiptFailure = { + error: Error +} +/** + * The response type of {@link verifyReceipt}. A failure or a success. + * + * Make sure to use {@link isFailure} after you get this response. + */ +export type VerifyReceiptResponse = ParsedReceipt | VerifyReceiptFailure + +/** + * Verify an in-app purchase receipt. This is a major feature of this library. + * + * This function will send the receipt to Apple's server and parse the result into something that is much more useful for you, the developer. This allow you to implement in-app purchases faster in your app with server-side verification. + */ +export const verifyReceipt = ( + receipt: string, + sharedSecret: string +): Promise => { + return runVerifyReceipt(receipt, sharedSecret, { production: true }) +} + +/** + * Determine if a {@link VerifyReceiptResponse} was a failed response or a success. + */ +export const isFailure = (response: VerifyReceiptResponse): response is VerifyReceiptFailure => { + return (response as VerifyReceiptFailure).error !== undefined +} + +export * from "./verify_receipt/parse/result" +export * from "./verify_receipt/apple_response" diff --git a/app/verify_receipt/apple_response/error.test.ts b/app/verify_receipt/apple_response/error.test.ts new file mode 100644 index 0000000..6e0913e --- /dev/null +++ b/app/verify_receipt/apple_response/error.test.ts @@ -0,0 +1,26 @@ +import { AppleVerifyReceiptErrorCode, isAppleErrorCode, isAppleResponseError } from "./error" +import { AppleVerifyReceiptSuccessfulStatus } from "./success" + +describe("isAppleErrorCode", () => { + it(`given not error, expect false`, async () => { + expect(isAppleErrorCode(AppleVerifyReceiptSuccessfulStatus.SUCCESS)).toEqual(false) + expect(isAppleErrorCode(AppleVerifyReceiptSuccessfulStatus.VALID_BUT_SUBSCRIPTION_EXPIRED)).toEqual(false) + }) + it(`given error, expect true`, async () => { + expect(isAppleErrorCode(AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET)).toEqual(true) + }) + it(`given random error code library not aware of`, async () => { + expect(isAppleErrorCode(21199)).toEqual(true) + }) +}) + +describe("isAppleResponseError", () => { + it(`given no receipt, expect false`, async () => { + expect(isAppleResponseError({ + status: AppleVerifyReceiptErrorCode.NOT_POST + })).toEqual(true) + }) + it(`given receipt, expect true`, async () => { + expect(isAppleResponseError(require('../../../samples/subscription_first_time_purchase.json'))).toEqual(false) + }) +}) \ No newline at end of file diff --git a/app/verify_receipt/apple_response/error.ts b/app/verify_receipt/apple_response/error.ts new file mode 100644 index 0000000..c0b5942 --- /dev/null +++ b/app/verify_receipt/apple_response/error.ts @@ -0,0 +1,53 @@ +import { AppleVerifyReceiptResponse, AppleVerifyReceiptSuccessfulStatus } from "./success" + +/** + * All of the statuses that are not successful. Apple was not able to provide back receipt information. + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/status) + * + * > Note: There may be many more error codes then these. These are ones that are documented but Apple says that there are also codes in the range 21100-21199 that could be returned. + */ +export enum AppleVerifyReceiptErrorCode { + NOT_POST = 21000, + SHOULD_NOT_HAPPEN = 21001, + INVALID_RECEIPT_OR_DOWN = 21002, + UNAUTHORIZED = 21003, + WRONG_SHARED_SECRET = 21004, + SERVICE_DOWN = 21005, + USE_TEST_ENVIRONMENT = 21007, + USE_PRODUCTION_ENVIRONMENT = 21008, + APPLE_INTERNAL_ERROR = 21009, + CUSTOMER_NOT_FOUND = 21010 +} + +/** + * The response body of a request that had an error. The receipt was not decoded and returned. + */ +export interface AppleVerifyReceiptErrorResponse { + /** + * > Note: Type here is `number` because the status can be more then the options included in {@link AppleVerifyReceiptErrorCode}. + * + * See {@link AppleVerifyReceiptErrorCode} for documented options. + */ + status: number +} + +/** + * @internal + */ +export const isAppleResponseError = ( + response: AppleVerifyReceiptResponse +): response is AppleVerifyReceiptErrorResponse => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (response as any).receipt === undefined +} + +/** + * @internal + */ +export const isAppleErrorCode = ( + code: number +): boolean => { + // Important that we only check if successful codes because there are a finite number of successful codes and unlimited error codes. + return !Object.values(AppleVerifyReceiptSuccessfulStatus).includes(code) +} diff --git a/app/verify_receipt/apple_response/index.ts b/app/verify_receipt/apple_response/index.ts new file mode 100644 index 0000000..aecfad7 --- /dev/null +++ b/app/verify_receipt/apple_response/index.ts @@ -0,0 +1,5 @@ +export * from "./error" +export * from "./latest_receipt_info" +export * from "./pending_renewal_info" +export * from "./receipt" +export * from "./success" diff --git a/app/verify_receipt/apple_response/latest_receipt_info.ts b/app/verify_receipt/apple_response/latest_receipt_info.ts new file mode 100644 index 0000000..b4e1cb3 --- /dev/null +++ b/app/verify_receipt/apple_response/latest_receipt_info.ts @@ -0,0 +1,18 @@ +import { AppleInAppPurchaseTransaction } from "./receipt" + +/** + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info) + */ +export type AppleLatestReceiptInfo = AppleInAppPurchaseTransaction & { + /** + * Indicates a subscription has been cancelled because of an upgrade. + * + * > Note: Only present for an upgrade transaction. + */ + is_upgraded?: "true" + offer_code_ref_name?: string + /** + * > Note: Only present for an auto-renewable subscription. + */ + subscription_group_identifier?: string +} diff --git a/app/verify_receipt/apple_response/pending_renewal_info.ts b/app/verify_receipt/apple_response/pending_renewal_info.ts new file mode 100644 index 0000000..c5b21b7 --- /dev/null +++ b/app/verify_receipt/apple_response/pending_renewal_info.ts @@ -0,0 +1,89 @@ +/** + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info) + */ +export interface ApplePendingRenewalInfo { + /** + * The product id the customer will downgrade/crossgrade to when the current subscription period is over. + * + * > Note: Present if the user is downgrading or crossgrading. + */ + auto_renew_product_id?: string + /** + * 1 - Subscription will auto-renew + * 0 - Customer turned off auto-renew + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/auto_renew_status) + */ + auto_renew_status: "1" | "0" + /** + * Reason subscription expired. + * + * 1 - Customer cancelled their subscription + * 2 - Billing error such as payment information not valid + * 3 - Customer did not agree to price increase + * 4 - Product not available for purchase + * 5 - Unknown error + * + * > Note: Present for a receipt that contains an expired auto-renewable subscription. + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/expiration_intent) + */ + expiration_intent?: "1" | "2" | "3" | "4" | "5" + /** + * When Apple will stop automatically retrying to renew the expired subscription. + * + * > Note: Present if in a grace period + */ + grace_period_expires_date?: string + /** + * When Apple will stop automatically retrying to renew the expired subscription. + * + * > Note: Present if in a grace period + */ + grace_period_expires_date_ms?: string + /** + * When Apple will stop automatically retrying to renew the expired subscription. + * + * > Note: Present if in a grace period + */ + grace_period_expires_date_pst?: string + /** + * If auto-renewable subscription is actively trying to be automatically renewed by Apple. Check the {@link expires_intent}, {@link expires_intent} to determine if Apple is trying to renew *before or after* the subscription has expired. If the subscription has expired, you are going to need to think through the logic of Grace Periods. Read more about Grace Periods to learn more about them. + * + * 1 - Apple is trying to renew the subscription. See {@link grace_period_expires_date} to determine when Apple will stop trying. + * 0 - Apple has stopped attempting to renew. + * + * > Note: Present if auto-renewable subscription has expired and Apple is or is not trying to renew it. + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/is_in_billing_retry_period) + */ + is_in_billing_retry_period?: "0" | "1" + /** + * > Note: Present if the customer redeemed [an offer code](https://developer.apple.com/app-store/subscriptions/#offer-codes). + * + * Resources: + * 1. [Overview of what offer codes are](https://developer.apple.com/app-store/subscriptions/#offer-codes) + * 2. [Set up offer codes](https://help.apple.com/app-store-connect/#/dev6a098e4b1) + * 3. [Implement offer codes in your app](https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_offer_codes_in_your_app) + */ + offer_code_ref_name?: string + /** + * The transaction ID that identifies a full payment history for a customer paying for a subscription through all of the renewals, upgrades/downgrades. + * + * [More details](https://developer.apple.com/documentation/appstorereceipts/original_transaction_id) + */ + original_transaction_id: string + /** + * 1 - customer accepted the price increase + * 0 - customer has not yet accepted the price increase + * + * > Note: Present if the customer was notified of price increase. When you enable a price increase for existing customers, Apple follows a schedule that it has set. [View the schedule here](https://help.apple.com/app-store-connect/#/devc9870599e) in the section "Increase the price of an auto-renewable subscription". + * + * See {@link expiration_intent} as the customer will have their subscription expire if they never accept the price increase. + */ + price_consent_status?: "0" | "1" + /** + * Product id this renewal information is referring to. + */ + product_id: string +} diff --git a/app/verify_receipt/apple_response/receipt.ts b/app/verify_receipt/apple_response/receipt.ts new file mode 100644 index 0000000..3bd2d82 --- /dev/null +++ b/app/verify_receipt/apple_response/receipt.ts @@ -0,0 +1,127 @@ +/** + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt/in_app) + */ +export interface AppleInAppPurchaseTransaction { + /** + * Date Apple issued a refund to customer. Refund could be because of customer asking for a refund or a subscription upgrade occurred. + * + * > Note: Only present if a refund was made. + */ + cancellation_date?: string + /** + * See {@link cancellation_date} + */ + cancellation_date_ms?: string + /** + * See {@link cancellation_date} + */ + cancellation_date_pst?: string + /** + * Reason for the refund issued for a customer asking to end their subscription immediately. + * + * 1 - Customer indicated they had a problem using your app and wanted a refund. + * 0 - Customer cancelled for another reason such as making purchase by mistake. + */ + cancellation_reason?: "0" | "1" + /** + * Time subscription expires or will renew. + * + * > Note: Only present if ths is an auto-renewable subscription purchase + */ + expires_date?: string + /** + * See {@link expires_date} + */ + expires_date_ms: string + /** + * See {@link expires_date} + */ + expires_date_pst: string + /** + * > Note: Only present if this is an auto-renewable subscription purchase + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/is_in_intro_offer_period) + */ + is_in_intro_offer_period?: "true" | "false" + /** + * > Note: Only present if this is an auto-renewable subscription purchase + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/is_trial_period) + */ + is_trial_period?: "true" | "false" + original_purchase_date: string + original_purchase_date_ms: string + original_purchase_date_pst: string + original_transaction_id: string + product_id: string + promotional_offer_id?: string + purchase_date: string + purchase_date_ms: string + purchase_date_pst: string + /** + * Number of consumable products purchased. + * + * > Note: This value is usually present with purchases that are not consumables but it's an optional field here in case Apple changes that in the future and only includes it for consumable purchases, only. + */ + quantity?: string + transaction_id: string + /** + * > Note: Only present for subscription purchases + */ + web_order_line_item_id?: string +} + +/** + * A JSON representation of the receipt that was sent for verification. + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt) + */ +export interface AppleReceipt { + adam_id: number + app_item_id: number + application_version: string + bundle_id: string + download_id: number + /** + * > Note: Only present if app was purchased through the Volume Purchase Program. + */ + expiration_date?: string + /** + * See {@link expiration_date}. + */ + expiration_date_ms?: string + /** + * See {@link expiration_date}. + */ + expiration_date_pst?: string + /** + * Transactions for non-consumable, non-renewing subscriptions, and auto-renewing subscriptions previously purchased by the customer. + * + * This response is similar but different then `latest_receipt_info` where that is used most often for auto-renewable subscription transactions to see if a subscription is up-to-date or not. + */ + in_app?: AppleInAppPurchaseTransaction[] + original_application_version: string + original_purchase_date: string + original_purchase_date_ms: string + original_purchase_date_pst: string + /** + * > Note: Only present if the app was ordered through pre-order. + */ + preorder_date?: string + /** + * See {@link preorder_date} + */ + preorder_date_ms?: string + /** + * See {@link preorder_date} + */ + preorder_date_pst?: string + receipt_creation_date: string + receipt_creation_date_ms: string + receipt_creation_date_pst: string + receipt_type: "Production" | "ProductionVPP" | "ProductionSandbox" | "ProductionVPPSandbox" + request_date: string + request_date_ms: string + request_date_pst: string + version_external_identifier: number +} diff --git a/app/verify_receipt/apple_response/success.ts b/app/verify_receipt/apple_response/success.ts new file mode 100644 index 0000000..4b305c7 --- /dev/null +++ b/app/verify_receipt/apple_response/success.ts @@ -0,0 +1,56 @@ +import { AppleVerifyReceiptErrorResponse } from "./error" +import { AppleLatestReceiptInfo } from "./latest_receipt_info" +import { ApplePendingRenewalInfo } from "./pending_renewal_info" +import { AppleReceipt } from "./receipt" + +/** + * All of the statuses that are successful. Apple is able to return back receipt information when any of these status codes occur. + * + * > Note: 0 means the receipt is valid. 21006 means it's valid, but the subscription is expired. You will still receive back a receipt decoded in the response with this status code. + * + * [Official Apple documentation](https://developer.apple.com/documentation/appstorereceipts/status) + */ +export enum AppleVerifyReceiptSuccessfulStatus { + SUCCESS = 0, + NOTING_PURCHASED = 2, // Not documented, but I guess it can happen: https://github.com/voltrue2/in-app-purchase/blob/e966ee1348bd4f67581779abeec59c4bbc2b2ebc/lib/apple.js#L15 + VALID_BUT_SUBSCRIPTION_EXPIRED = 21006 +} + +export interface AppleVerifyReceiptSuccessfulResponse { + /** + * The environment that Apple made the Receipt for. + */ + environment: "Sandbox" | "Production" + /** + * Base64 encoded string for the latest receipt from Apple. + * + * > Note: Only present if the receipt contains auto-renewable subscriptions. + */ + latest_receipt?: string + /** + * All in-app purchase transactions except transactions for consumable products marked as finished by your app. + * + * This is the preferred place to look for the status of subscriptions and non-consumables. The field is similar but different from the transactions list in `receipt > in_app`. This field is the *latest transactions up to this moment* while the `in_app` field contains the transactions for the given receipt that got sent to Apple to process, only. If the receipt you sent up to get verified is out-of-date then `in_app` will be out-of-date. + * + * > Note: This is only present if the customer has purchased auto-renewable subscriptions. + */ + latest_receipt_info?: AppleLatestReceiptInfo[] + /** + * All auto-renewable subscription status of their renewals. + * + * > Note: Only present if the receipt contains auto-renewable subscriptions. + */ + pending_renewal_info?: ApplePendingRenewalInfo[] + /** + * JSON version of the receipt that was sent to Apple for verifying. + */ + receipt: AppleReceipt + /** + * Determines if the receipt is a valid one, or there is some other result. Maybe the receipt is not valid, maybe you the developer made a mistake, maybe the Apple server encountered a problem. + */ + status: AppleVerifyReceiptSuccessfulStatus +} + +export type AppleVerifyReceiptResponse = + | AppleVerifyReceiptErrorResponse + | AppleVerifyReceiptSuccessfulResponse diff --git a/app/verify_receipt/parse/auto_renewable_subscription/index.test.ts b/app/verify_receipt/parse/auto_renewable_subscription/index.test.ts new file mode 100644 index 0000000..5644502 --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/index.test.ts @@ -0,0 +1,28 @@ +import { AppleVerifyReceiptSuccessfulResponse } from "../../apple_response" +import { parseSubscriptions } from "." + +describe("parseSubscriptions", () => { + it(`given no latest receipt info, expect empty`, async () => { + expect(parseSubscriptions(require("../../../../samples/simple.json"))).toEqual([]) + }) + it(`given subscription transactions, expect get parsed subscription responses`, async () => { + const actual = parseSubscriptions(require("../../../../samples/subscription_first_time_purchase.json")) + + expect(actual).toHaveLength(1) + expect(actual[0].allTransactions).toHaveLength(3) + }) + it(`given upgrade/downgrades, expect subscription maps to pending renewal info correctly`, async () => { + const actual = parseSubscriptions(require("../../../../samples/subscription_multiple_subscription_purchases.json")) + + expect(actual).toHaveLength(1) + expect(actual[0].currentProductId).toEqual("test_sub2") + expect(actual[0].willAutoRenew).toEqual(true) + }) + it(`given cannot find pending renewal info, expect no errors`, async () => { + const response: AppleVerifyReceiptSuccessfulResponse = require("../../../../samples/subscription_multiple_subscription_purchases.json") + delete response.pending_renewal_info + const actual = parseSubscriptions(response) + + expect(actual).toHaveLength(1) + }) +}) \ No newline at end of file diff --git a/app/verify_receipt/parse/auto_renewable_subscription/index.ts b/app/verify_receipt/parse/auto_renewable_subscription/index.ts new file mode 100644 index 0000000..3556a3e --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/index.ts @@ -0,0 +1,38 @@ +import { AppleVerifyReceiptSuccessfulResponse } from "../../apple_response/success" +import { + AutoRenewableSubscription, +} from "../result/auto_renewable_subscription" +import { ParsedTransactions } from "./transactions" +import { ParsedSubscription } from "./subscription" + +/** + * @internal + */ +export const parseSubscriptions = ( + response: AppleVerifyReceiptSuccessfulResponse +): AutoRenewableSubscription[] => { + if (!response.latest_receipt_info) return [] + + const parsedTransactions = new ParsedTransactions() + + response.latest_receipt_info + .filter((transaction) => ParsedTransactions.isAutoRenewableSubscriptionTransaction(transaction)) + .forEach((subscription) => parsedTransactions.addTransaction(subscription)) + + return Array.from(parsedTransactions.iterateParsedTransactions()).map((allTransactions) => { + const sampleTransaction = allTransactions[0] + const originalTransactionId = sampleTransaction.originalTransactionId + const isEligibleIntroductoryOffer = parsedTransactions.getIsEligibleIntroductoryOffer(sampleTransaction)! + + const renewalInfo = response.pending_renewal_info?.find( + (entry) => entry.original_transaction_id === originalTransactionId + ) + + return new ParsedSubscription( + originalTransactionId, + isEligibleIntroductoryOffer, + allTransactions, + renewalInfo + ).parseSubscription() + }) +} diff --git a/app/verify_receipt/parse/auto_renewable_subscription/subscription.test.ts b/app/verify_receipt/parse/auto_renewable_subscription/subscription.test.ts new file mode 100644 index 0000000..ebf3df4 --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/subscription.test.ts @@ -0,0 +1,397 @@ +import { ApplePendingRenewalInfo } from "../../apple_response" +import { ParsedSubscription } from "./subscription" +import parsedTransaction, { + parsedTransaction2 +} from "../../../../samples/parsed/auto_renewable_subscription_transaction" +import { AutoRenewableSubscriptionIssues } from "../result" + +const pendingRenewalInfo: ApplePendingRenewalInfo = require("../../../../samples/will_autorenew_pending_renewal_info.json") +const exampleDateMsString = "1605230970000" +const dateInPast = new Date("2000-04-04T16:00:00.000Z") +const dateInFuture = new Date(Date.now() + (30 * 60 * 1000)) // add 30 min + +describe("ParsedSubscription", () => { + describe("constructor", () => { + it(`given no transactions, expect throw`, async () => { + expect(() => { + new ParsedSubscription("", false, []) + }).toThrowErrorMatchingInlineSnapshot( + `"BUG! Please, file a bug report: https://github.com/levibostian/dollabill-apple/issues/new?template=BUG_REPORT.md. (It's assumed that a subscription is not created if there are no transactions recorded for it.)"` + ) + }) + it(`given transactions, expect sort`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction2, parsedTransaction]) + + expect(actual.allTransactions).toEqual([parsedTransaction, parsedTransaction2]) + }) + it(`given transactions, expect populate properties`, async () => { + const actual = new ParsedSubscription( + "1", + false, + [parsedTransaction2, parsedTransaction], + pendingRenewalInfo + ) + + expect(actual.allTransactions).toEqual([parsedTransaction, parsedTransaction2]) + expect(actual.latestExpireDateTransaction).toEqual(parsedTransaction) + expect(actual.renewalInfo).toEqual(pendingRenewalInfo) + }) + }) + describe("usedOfferCodes", () => { + it(`given no offer codes, expect empty`, async () => { + parsedTransaction.offerCodeRefName = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.usedOfferCodes()).toEqual([]) + }) + it(`given offer codes, expect get unique codes`, async () => { + parsedTransaction.offerCodeRefName = "code-1" + parsedTransaction2.offerCodeRefName = "code-1" + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.usedOfferCodes()).toEqual(["code-1"]) + }) + }) + describe("usedPromotionalOffers", () => { + it(`given no offer codes, expect empty`, async () => { + parsedTransaction.promotionalOfferId = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.usedPromotionalOffers()).toEqual([]) + }) + it(`given offer codes, expect get unique codes`, async () => { + parsedTransaction.promotionalOfferId = "code-1" + parsedTransaction2.promotionalOfferId = "code-1" + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.usedPromotionalOffers()).toEqual(["code-1"]) + }) + }) + describe("priceIncreaseAccepted", () => { + it(`given no renewal info, expect undefined`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.priceIncreaseAccepted()).toBeUndefined() + }) + it(`given no price consent info, expect undefined`, async () => { + pendingRenewalInfo.price_consent_status = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.priceIncreaseAccepted()).toBeUndefined() + }) + it(`given accepted price consent, expect true`, async () => { + pendingRenewalInfo.price_consent_status = "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.priceIncreaseAccepted()).toEqual(true) + }) + it(`given not accepted price consent, expect false`, async () => { + pendingRenewalInfo.price_consent_status = "0" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.priceIncreaseAccepted()).toEqual(false) + }) + }) + describe("issues", () => { + it(`given no price consent info, expect does not include not accepting price increase`, async () => { + pendingRenewalInfo.price_consent_status = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().notYetAcceptingPriceIncrease).toEqual(false) + }) + it(`given no pending renewal info, expect does not include not accepting price increase`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.issues().notYetAcceptingPriceIncrease).toEqual(false) + }) + it(`given user not yet consented to price increase, expect does include not accepting price increase`, async () => { + pendingRenewalInfo.price_consent_status = "0" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().notYetAcceptingPriceIncrease).toEqual(true) + }) + it(`given subscription expired from a billing issue, expect billing issue`, async () => { + pendingRenewalInfo.expiration_intent = "2" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().billingIssue).toEqual(true) + }) + it(`given no pending renewal info, expect no billing issue`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.issues().billingIssue).toEqual(false) + }) + it(`given is in grace period, expect billing issue`, async () => { + pendingRenewalInfo.grace_period_expires_date_ms = exampleDateMsString + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().billingIssue).toEqual(true) + }) + it(`given subscription active, expect no billing issue`, async () => { + pendingRenewalInfo.expiration_intent = undefined + pendingRenewalInfo.grace_period_expires_date_ms = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().billingIssue).toEqual(false) + }) + it(`given will not auto renew, expect will voluntary cancel`, async () => { + pendingRenewalInfo.auto_renew_status = "0" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().willVoluntaryCancel).toEqual(true) + }) + it(`given no pending renewal info, expect no will voluntary cancel`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.issues().willVoluntaryCancel).toEqual(false) + }) + it(`given will auto renew, expect no will voluntary cancel`, async () => { + pendingRenewalInfo.auto_renew_status = "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.issues().willVoluntaryCancel).toEqual(false) + }) + }) + describe("issuesStrings", () => { + it(`given all false, expect empty`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + const givenStatuses: AutoRenewableSubscriptionIssues = { + notYetAcceptingPriceIncrease: false, + billingIssue: false, + willVoluntaryCancel: false + } + + expect(actual.issuesStrings(givenStatuses)).toEqual([]) + }) + it(`given notYetAcceptingPriceIncrease, expect notYetAcceptingPriceIncrease`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + const givenStatuses: AutoRenewableSubscriptionIssues = { + notYetAcceptingPriceIncrease: true, + billingIssue: true, + willVoluntaryCancel: true + } + + expect(actual.issuesStrings(givenStatuses)).toMatchInlineSnapshot(` + Array [ + "not_yet_accepting_price_increase", + "billing_issue", + "will_voluntary_cancel", + ] + `) + }) + }) + describe("willAutoRenew", () => { + it(`given no pending renewal info, expect false`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.willAutoRenew()).toEqual(false) + }) + it(`given will not auto renew, expect false`, async () => { + pendingRenewalInfo.auto_renew_status = "0" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.willAutoRenew()).toEqual(false) + }) + it(`given will auto renew, expect true`, async () => { + pendingRenewalInfo.auto_renew_status = "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.willAutoRenew()).toEqual(true) + }) + }) + describe("gracePeriodExpireDate", () => { + it(`given no pending renewal info, expect undefined`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.gracePeriodExpireDate()).toBeUndefined() + }) + it(`given in grace period, expect get result`, async () => { + pendingRenewalInfo.grace_period_expires_date_ms = exampleDateMsString + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.gracePeriodExpireDate()).toEqual(new Date(parseInt(exampleDateMsString))) + }) + }) + describe("expireDate", () => { + it(`expect get result from latest transaction`, async () => { + parsedTransaction.expiresDate = dateInFuture + parsedTransaction2.expiresDate = dateInPast + const actual = new ParsedSubscription("1", false, [parsedTransaction2, parsedTransaction], pendingRenewalInfo) + + expect(actual.expireDate()).toEqual(dateInFuture) + }) + }) + describe("currentEndDate", () => { + it(`given customer got refund or upgraded, expect date`, async () => { + parsedTransaction.cancelledDate = dateInPast + parsedTransaction.expiresDate = dateInFuture + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.currentEndDate()).toEqual(dateInPast) + }) + it(`given customer in grace period, expect date`, async () => { + parsedTransaction.cancelledDate = undefined + parsedTransaction.expiresDate = dateInFuture + pendingRenewalInfo.grace_period_expires_date_ms = exampleDateMsString + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.currentEndDate()).toEqual(new Date(parseInt(exampleDateMsString))) + }) + it(`given customer not in grace period or cancelled, expect expire date`, async () => { + parsedTransaction.cancelledDate = undefined + parsedTransaction.expiresDate = dateInFuture + pendingRenewalInfo.grace_period_expires_date_ms = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.currentEndDate()).toEqual(dateInFuture) + }) + }) + describe("willDowngradeToProductId", () => { + it(`given no pending renewal info, expect undefined`, async () => { + const actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.willDowngradeToProductId()).toBeUndefined() + }) + it(`given will auto renew to another product, expect result`, async () => { + pendingRenewalInfo.auto_renew_product_id = "other-product" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.willDowngradeToProductId()).toEqual("other-product") + }) + }) + describe("isInBillingRetry", () => { + it(`given customer in active status, expect false`, async () => { + pendingRenewalInfo.is_in_billing_retry_period = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.isInBillingRetry()).toEqual(false) + }) + it(`given customer beyond billing retry period, expect false`, async () => { + pendingRenewalInfo.is_in_billing_retry_period = "0" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.isInBillingRetry()).toEqual(false) + }) + it(`given customer in billing retry period, expect true`, async () => { + pendingRenewalInfo.is_in_billing_retry_period = "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.isInBillingRetry()).toEqual(true) + }) + }) + describe("isEligibleIntroductoryOffer", () => { + it(`given in constructor, expect result`, async () => { + // Note: Putting both tests in this 1 function to make sure that I am only modifying 1 single thing for each test. I don't want any false positives by tests running in random order and changing the result. Having multiple tests in 1 test function is usually bad practice. It's done on purpose here. + let actual = new ParsedSubscription("1", false, [parsedTransaction]) + + expect(actual.parseSubscription().isEligibleIntroductoryOffer).toEqual(false) + + // Only thing changed for this test is what we pass into the constructor. + actual = new ParsedSubscription("1", true, [parsedTransaction]) + + expect(actual.parseSubscription().isEligibleIntroductoryOffer).toEqual(true) + }) + }) + describe("status", () => { + it(`given in billing retry and in grace period, expect in grace period`, async () => { + pendingRenewalInfo.grace_period_expires_date = exampleDateMsString + pendingRenewalInfo.is_in_billing_retry_period == "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("grace_period") + }) + it(`given not in grace period but in billing retry, expect in billing retry`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period == "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("billing_retry_period") + }) + it(`given not in grace period and not in billing retry and date expired, expect voluntary cancelled`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = undefined + parsedTransaction.cancelledDate = undefined + parsedTransaction.refundReason = undefined + parsedTransaction.expiresDate = dateInPast + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("voluntary_cancel") + }) + it(`given customer had billing issue, expect involuntary cancel`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = "2" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("involuntary_cancel") + }) + it(`given product not available for purchase, expect involuntary cancel`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = "4" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("involuntary_cancel") + }) + it(`given customer voluntarily cancelled, expect voluntary cancel`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = "1" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("voluntary_cancel") + }) + it(`given other expiration intent, expect other reason not active`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = "5" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("other_not_active") + }) + it(`given customer cancelled but did not upgrade, expect refund`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = undefined + parsedTransaction.cancelledDate = dateInPast + parsedTransaction.refundReason = "app_issue" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("refunded") + }) + it(`given customer cancelled and upgraded, expect upgrade`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = undefined + parsedTransaction.cancelledDate = dateInPast + parsedTransaction.refundReason = "upgrade" + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("upgraded") + }) + it(`given customer cancelled for other reason, expect other`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period = undefined + pendingRenewalInfo.expiration_intent = undefined + parsedTransaction.cancelledDate = dateInPast + parsedTransaction.refundReason = undefined + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("other_not_active") + }) + it(`given no issues detected, expect active`, async () => { + pendingRenewalInfo.grace_period_expires_date = undefined + pendingRenewalInfo.is_in_billing_retry_period == undefined + pendingRenewalInfo.expiration_intent = undefined + parsedTransaction.cancelledDate = undefined + parsedTransaction.refundReason = undefined + parsedTransaction.expiresDate = dateInFuture + const actual = new ParsedSubscription("1", false, [parsedTransaction], pendingRenewalInfo) + + expect(actual.status()).toEqual("active") + }) + }) +}) diff --git a/app/verify_receipt/parse/auto_renewable_subscription/subscription.ts b/app/verify_receipt/parse/auto_renewable_subscription/subscription.ts new file mode 100644 index 0000000..4cc7978 --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/subscription.ts @@ -0,0 +1,175 @@ +import _ from "../../../underscore" +import { ApplePendingRenewalInfo } from "../../apple_response/pending_renewal_info" +import { InternalError } from "../error" +import { + AutoRenewableSubscription, + AutoRenewableSubscriptionIssues, + AutoRenewableSubscriptionIssueString, + AutoRenewableSubscriptionStatus, + AutoRenewableSubscriptionTransaction +} from "../result/auto_renewable_subscription" + +/** + * Creates a parsed subscription from a collection of parsed transactions. + * + * @internal + */ +export class ParsedSubscription { + public allTransactions: AutoRenewableSubscriptionTransaction[] + public latestExpireDateTransaction: AutoRenewableSubscriptionTransaction + public renewalInfo?: ApplePendingRenewalInfo + + constructor( + public originalTransactionId: string, + public isEligibleIntroductoryOffer: boolean, + transactions: AutoRenewableSubscriptionTransaction[], // the transactions for the originalTransactionId. + renewalInfo?: ApplePendingRenewalInfo + ) { + if (transactions.length <= 0) + throw new InternalError( + "PrerequisiteNotMet", + "It's assumed that a subscription is not created if there are no transactions recorded for it." + ) + + this.allTransactions = transactions.sort((first, second) => + _.date.sortNewToOld(first.expiresDate, second.expiresDate) + ) + this.latestExpireDateTransaction = this.allTransactions[0] // there will be at least 1 transaction or there would not be an entry in the Map<>. + this.renewalInfo = renewalInfo + } + + parseSubscription(): AutoRenewableSubscription { + const issues = this.issues() + + return { + currentProductId: this.latestExpireDateTransaction.productId, + originalTransactionId: this.originalTransactionId, + subscriptionGroup: this.latestExpireDateTransaction.subscriptionGroupId, + isInFreeTrialPeriod: this.latestExpireDateTransaction.inTrialPeriod, + isEligibleIntroductoryOffer: this.isEligibleIntroductoryOffer, + currentEndDate: this.currentEndDate(), + status: this.status(), + usedOfferCodes: this.usedOfferCodes(), + usedPromotionalOffers: this.usedPromotionalOffers(), + allTransactions: this.allTransactions, + latestExpireDateTransaction: this.latestExpireDateTransaction, + willAutoRenew: this.willAutoRenew(), + willDowngradeToProductId: this.willDowngradeToProductId(), + issuesStrings: this.issuesStrings(issues), + issues, + priceIncreaseAccepted: this.priceIncreaseAccepted(), + gracePeriodExpireDate: this.gracePeriodExpireDate(), + cancelledDate: this.cancelledDate(), + expireDate: this.expireDate(), + isInBillingRetry: this.isInBillingRetry() + } + } + + usedOfferCodes(): string[] { + const set = new Set(this.allTransactions + .filter((transaction) => transaction.offerCodeRefName) + .map((transaction) => transaction.offerCodeRefName!)) + + return [...set] + } + + usedPromotionalOffers(): string[] { + const set = new Set(this.allTransactions + .filter((transaction) => transaction.promotionalOfferId) + .map((transaction) => transaction.promotionalOfferId!)) + + return [...set] + } + + priceIncreaseAccepted(): boolean | undefined { + let priceIncreaseAccepted: boolean | undefined + if (this.renewalInfo?.price_consent_status) { + priceIncreaseAccepted = this.renewalInfo.price_consent_status === "1" + } + + return priceIncreaseAccepted + } + + issues(): AutoRenewableSubscriptionIssues { + return { + notYetAcceptingPriceIncrease: this.priceIncreaseAccepted() === false, + billingIssue: this.renewalInfo?.expiration_intent === "2" || this.gracePeriodExpireDate() !== undefined, + willVoluntaryCancel: this.renewalInfo !== undefined && !this.willAutoRenew() + } + } + + issuesStrings(statuses: AutoRenewableSubscriptionIssues): AutoRenewableSubscriptionIssueString[] { + const strings: AutoRenewableSubscriptionIssueString[] = [] + + if (statuses.notYetAcceptingPriceIncrease) strings.push("not_yet_accepting_price_increase") + if (statuses.billingIssue) strings.push("billing_issue") + if (statuses.willVoluntaryCancel) strings.push("will_voluntary_cancel") + + return strings + } + + willAutoRenew(): boolean { + return this.renewalInfo?.auto_renew_status === "1" || false + } + + gracePeriodExpireDate(): Date | undefined { + if (this.renewalInfo?.grace_period_expires_date_ms) return new Date(parseInt(this.renewalInfo.grace_period_expires_date_ms!)) + + return undefined + } + + expireDate(): Date { + return this.latestExpireDateTransaction.expiresDate + } + + currentEndDate(): Date { + return this.cancelledDate() || this.gracePeriodExpireDate() || this.expireDate() + } + + willDowngradeToProductId(): string | undefined { + return this.renewalInfo?.auto_renew_product_id + } + + isInBillingRetry(): boolean { + return this.renewalInfo?.is_in_billing_retry_period === "1" || false + } + + cancelledDate(): Date | undefined { + return this.latestExpireDateTransaction.cancelledDate + } + + status(): AutoRenewableSubscriptionStatus { + const inGracePeriod = this.renewalInfo?.grace_period_expires_date !== undefined || false + if (inGracePeriod) return "grace_period" + + const isInBillingRetry = this.renewalInfo?.is_in_billing_retry_period === "1" || false + if (isInBillingRetry) return "billing_retry_period" + + if (this.renewalInfo?.expiration_intent !== undefined) { + const involuntaryCancelled = this.renewalInfo.expiration_intent === "2" || this.renewalInfo.expiration_intent === "4" + if (involuntaryCancelled) return "involuntary_cancel" + + const voluntaryCancelled = this.renewalInfo.expiration_intent === "1" || false + if (voluntaryCancelled) return "voluntary_cancel" + + return "other_not_active" + } + + if (this.latestExpireDateTransaction.cancelledDate !== undefined || this.latestExpireDateTransaction.refundReason !== undefined) { + const refunded = this.latestExpireDateTransaction.refundReason === "app_issue" || this.latestExpireDateTransaction.refundReason === "other" + if (refunded) return "refunded" + + const upgraded = this.latestExpireDateTransaction.refundReason === "upgrade" + if (upgraded) return "upgraded" + + return "other_not_active" + } + + // Note: this should be caught by the "expiration_intent" of the pending renewal object but just in case, we want to catch when the customer has gone beyond the billing retry period and there is still a billing issue. + if (this.latestExpireDateTransaction.expiresDate.getTime() < new Date().getTime()) { + return "voluntary_cancel" + } + + return "active" + } +} \ No newline at end of file diff --git a/app/verify_receipt/parse/auto_renewable_subscription/transaction.test.ts b/app/verify_receipt/parse/auto_renewable_subscription/transaction.test.ts new file mode 100644 index 0000000..95c5a87 --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/transaction.test.ts @@ -0,0 +1,312 @@ +import { AppleLatestReceiptInfo } from "../../apple_response" +import { ParsedTransactions } from "./transactions" + +let parsedTransactions: ParsedTransactions +let givenSubscription: AppleLatestReceiptInfo +let givenSubscription2: AppleLatestReceiptInfo +const givenProductPurchase = require("../../../../samples/consumable.json") +const exampleDateMsString = "1605230970000" + +beforeEach(() => { + parsedTransactions = new ParsedTransactions() + givenSubscription = require("../../../../samples/autorenewable_subscription.json") + givenSubscription2 = require("../../../../samples/autorenewable_subscription2.json") +}) + +describe("ParsedTransactions", () => { + describe("addTransaction", () => { + it(`given a transaction that's not an auto-renewable subscription, expect throw error`, async () => { + expect(() => { + parsedTransactions.addTransaction(givenProductPurchase) + }).toThrowErrorMatchingInlineSnapshot( + `"BUG! Please, file a bug report: https://github.com/levibostian/dollabill-apple/issues/new?template=BUG_REPORT.md. (Filter out all transactions that are *not* subscription transactions before calling this function.)"` + ) + }) + it(`given add transactions from multiple subscriptions, expect grouped by subscription`, async () => { + parsedTransactions.addTransaction(givenSubscription) + parsedTransactions.addTransaction(givenSubscription2) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)).not.toEqual( + parsedTransactions.getParsedTransactions(givenSubscription2) + ) + }) + it(`given add multiple transactions for same subscription, expect add transactions`, async () => { + parsedTransactions.addTransaction(givenSubscription) + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)).toHaveLength(2) + }) + }) + describe("isAutoRenewableSubscriptionTransaction", () => { + it(`given auto-renewable subscription, expect true`, async () => { + expect(ParsedTransactions.isAutoRenewableSubscriptionTransaction(givenSubscription)).toEqual( + true + ) + }) + it(`given product purchase, expect false`, async () => { + expect( + ParsedTransactions.isAutoRenewableSubscriptionTransaction(givenProductPurchase) + ).toEqual(false) + }) + }) + describe("updateIsEligibleIntroductoryOffer", () => { + // Tests that if we find it's not eligible, we never overwrite that value + it(`given transaction in trial period and a later transaction not in trial period, expect false`, async () => { + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "true" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(false) + + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(false) + }) + it(`given multiple transactions not in trial period or intro offer, expect true`, async () => { + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(true) + + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(true) + }) + it(`given transactions from same subscription groups not eligible, expect false`, async () => { + givenSubscription.is_in_intro_offer_period = "true" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(false) + }) + it(`given transactions from separate subscription groups, expect different unique results`, async () => { + givenSubscription.is_in_intro_offer_period = "true" + givenSubscription.is_trial_period = "false" + givenSubscription.subscription_group_identifier = "1" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(false) + + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + givenSubscription.subscription_group_identifier = "2" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(true) + }) + it(`given transaction, expect populate first result`, async () => { + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(true) + }) + it(`given second transaction, expect update with new result`, async () => { + givenSubscription.is_in_intro_offer_period = "false" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(true) + + givenSubscription.is_in_intro_offer_period = "true" + givenSubscription.is_trial_period = "false" + parsedTransactions.updateIsEligibleIntroductoryOffer(givenSubscription) + expect(parsedTransactions.getIsEligibleIntroductoryOffer(givenSubscription)).toEqual(false) + }) + }) + describe("refundReason", () => { + it(`given refunded transaction for upgrade, expect get upgrade refund reason`, async () => { + givenSubscription.cancellation_date_ms = exampleDateMsString + givenSubscription.is_upgraded = "true" + + expect(parsedTransactions.refundReason(givenSubscription)).toEqual("upgrade") + }) + it(`given refunded transaction for app issue, expect get refund reason`, async () => { + givenSubscription.cancellation_date_ms = exampleDateMsString + givenSubscription.is_upgraded = undefined + givenSubscription.cancellation_reason = "1" + + expect(parsedTransactions.refundReason(givenSubscription)).toEqual("app_issue") + }) + it(`given refunded transaction for other reason, expect get refund reason`, async () => { + givenSubscription.cancellation_date_ms = exampleDateMsString + givenSubscription.is_upgraded = undefined + givenSubscription.cancellation_reason = "0" + + expect(parsedTransactions.refundReason(givenSubscription)).toEqual("other") + }) + it(`given not refunded transaction, expect no refund date`, async () => { + givenSubscription.cancellation_date_ms = undefined + + expect(parsedTransactions.refundReason(givenSubscription)).toBeUndefined() + }) + }) + describe("isRenewOrRestore", () => { + it(`given matching transaction ids, expect false`, async () => { + givenSubscription.original_transaction_id = "123" + givenSubscription.transaction_id = "123" + + expect(parsedTransactions.isRenewOrRestore(givenSubscription)).toEqual(false) + }) + it(`given different transaction ids, expect true`, async () => { + givenSubscription.original_transaction_id = "123" + givenSubscription.transaction_id = "456" + + expect(parsedTransactions.isRenewOrRestore(givenSubscription)).toEqual(true) + }) + }) + describe("parseTransaction", () => { + it(`given transaction, expect all dates to be successfully parsed`, async () => { + givenSubscription.cancellation_date_ms = exampleDateMsString + givenSubscription.expires_date_ms = exampleDateMsString + givenSubscription.original_purchase_date_ms = exampleDateMsString + givenSubscription.purchase_date_ms = exampleDateMsString + + parsedTransactions.addTransaction(givenSubscription) + + const actual = parsedTransactions.getParsedTransactions(givenSubscription)![0] + + expect(actual.cancelledDate).toBeDefined() + expect(actual.expiresDate).toBeDefined() + expect(actual.originalPurchaseDate).toBeDefined() + expect(actual.purchaseDate).toBeDefined() + }) + it(`given in intro offer period, expect true`, async () => { + givenSubscription.is_in_intro_offer_period = "true" + + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)![0].inIntroPeriod).toEqual( + true + ) + }) + it(`given no intro offer period, expect undefined`, async () => { + givenSubscription.is_in_intro_offer_period = "false" + + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)![0].inIntroPeriod).toEqual( + false + ) + }) + it(`given in trial period, expect true`, async () => { + givenSubscription.is_trial_period = "true" + + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)![0].inTrialPeriod).toEqual( + true + ) + }) + it(`given is upgraded, expect true`, async () => { + givenSubscription.is_trial_period = "false" + + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)![0].inTrialPeriod).toEqual( + false + ) + }) + it(`given offer code, expect get code`, async () => { + givenSubscription.offer_code_ref_name = "offer-code-foo" + + parsedTransactions.addTransaction(givenSubscription) + + expect( + parsedTransactions.getParsedTransactions(givenSubscription)![0].offerCodeRefName + ).toEqual("offer-code-foo") + }) + it(`given not offer code, expect undefined`, async () => { + givenSubscription.offer_code_ref_name = undefined + + parsedTransactions.addTransaction(givenSubscription) + + expect( + parsedTransactions.getParsedTransactions(givenSubscription)![0].offerCodeRefName + ).toBeUndefined() + }) + it(`given subscriptionGroupId, expect get in result`, async () => { + givenSubscription.subscription_group_identifier = "foo" + + parsedTransactions.addTransaction(givenSubscription) + + expect( + parsedTransactions.getParsedTransactions(givenSubscription)![0].subscriptionGroupId + ).toEqual("foo") + }) + it(`given transactionId, expect get in result`, async () => { + givenSubscription.transaction_id = "bar" + + parsedTransactions.addTransaction(givenSubscription) + + expect(parsedTransactions.getParsedTransactions(givenSubscription)![0].transactionId).toEqual( + "bar" + ) + }) + it(`given webOrderLineItemId, expect get in result`, async () => { + givenSubscription.web_order_line_item_id = "bar" + + parsedTransactions.addTransaction(givenSubscription) + + expect( + parsedTransactions.getParsedTransactions(givenSubscription)![0].webOrderLineItemId + ).toEqual("bar") + }) + it(`given originalTransactionId, expect get in result`, async () => { + givenSubscription.original_transaction_id = "bar" + + parsedTransactions.addTransaction(givenSubscription) + + expect( + parsedTransactions.getParsedTransactions(givenSubscription)![0].originalTransactionId + ).toEqual("bar") + }) + it(`given transaction, expect parse`, async () => { + expect(parsedTransactions.parseTransaction(givenSubscription)).toMatchInlineSnapshot(` + Object { + "cancelledDate": 2020-11-13T01:29:30.000Z, + "expiresDate": 2020-11-13T01:29:30.000Z, + "inIntroPeriod": false, + "inTrialPeriod": false, + "isFirstSubscriptionPurchase": true, + "isRenewOrRestore": false, + "isUpgradeTransaction": false, + "offerCodeRefName": undefined, + "originalPurchaseDate": 2020-11-13T01:29:30.000Z, + "originalTransactionId": "bar", + "productId": "test_subscription", + "promotionalOfferId": undefined, + "purchaseDate": 2020-11-13T01:29:30.000Z, + "rawTransaction": Object { + "cancellation_date_ms": "1605230970000", + "cancellation_reason": "0", + "expires_date": "2020-11-13 01:12:23 Etc/GMT", + "expires_date_ms": "1605230970000", + "expires_date_pst": "2020-11-12 17:12:23 America/Los_Angeles", + "is_in_intro_offer_period": "false", + "is_trial_period": "false", + "is_upgraded": undefined, + "offer_code_ref_name": undefined, + "original_purchase_date": "2020-11-13 01:09:24 Etc/GMT", + "original_purchase_date_ms": "1605230970000", + "original_purchase_date_pst": "2020-11-12 17:09:24 America/Los_Angeles", + "original_transaction_id": "bar", + "product_id": "test_subscription", + "purchase_date": "2020-11-13 01:09:23 Etc/GMT", + "purchase_date_ms": "1605230970000", + "purchase_date_pst": "2020-11-12 17:09:23 America/Los_Angeles", + "quantity": "1", + "subscription_group_identifier": "foo", + "transaction_id": "bar", + "web_order_line_item_id": "bar", + }, + "refundReason": "other", + "subscriptionGroupId": "foo", + "transactionId": "bar", + "webOrderLineItemId": "bar", + } + `) + }) + }) +}) diff --git a/app/verify_receipt/parse/auto_renewable_subscription/transactions.ts b/app/verify_receipt/parse/auto_renewable_subscription/transactions.ts new file mode 100644 index 0000000..ee15ab9 --- /dev/null +++ b/app/verify_receipt/parse/auto_renewable_subscription/transactions.ts @@ -0,0 +1,105 @@ +import { AppleLatestReceiptInfo } from "../../apple_response/latest_receipt_info" +import { InternalError } from "../error" +import { + AutoRenewableSubscriptionRefundReason, + AutoRenewableSubscriptionTransaction +} from "../result/auto_renewable_subscription" + +/** + * Takes in a response from Apple transaction and produces a parsed transaction. Keeps track of all of them by grouping them together by subscription group. + * + * @internal + */ +export class ParsedTransactions { + + // key is `original_transaction_id` as that's the way to group subscriptions + private transactions: Map = new Map() + // key is `subscription_group_identifier` as we must determine if eligible for intro offer across multiple subscriptions. + // From "Determine Eligibility" section in: https://web.archive.org/web/20200908054522if_/https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_introductory_offers_in_your_app + private isEligibleIntroductoryOffer: Map = new Map() + + addTransaction(transaction: AppleLatestReceiptInfo): void { + if (!ParsedTransactions.isAutoRenewableSubscriptionTransaction(transaction)) + throw new InternalError( + "PrerequisiteNotMet", + `Filter out all transactions that are *not* subscription transactions before calling this function.` + ) + + const existingTransactions = this.getParsedTransactions(transaction) || [] + + existingTransactions.push(this.parseTransaction(transaction)) + + this.transactions.set(transaction.original_transaction_id, existingTransactions) + + this.updateIsEligibleIntroductoryOffer(transaction) + } + + iterateParsedTransactions(): IterableIterator { + return this.transactions.values() + } + + getParsedTransactions(transaction: AppleLatestReceiptInfo): AutoRenewableSubscriptionTransaction[] | undefined { + return this.transactions.get(transaction.original_transaction_id) + } + + getIsEligibleIntroductoryOffer(transaction: AppleLatestReceiptInfo | AutoRenewableSubscriptionTransaction): boolean { + const key = (transaction as AppleLatestReceiptInfo).subscription_group_identifier || (transaction as AutoRenewableSubscriptionTransaction).subscriptionGroupId + + return this.isEligibleIntroductoryOffer.get(key) || false + } + + static isAutoRenewableSubscriptionTransaction(transaction: AppleLatestReceiptInfo): boolean { + return transaction.expires_date !== undefined && transaction.expires_date !== null + } + + updateIsEligibleIntroductoryOffer(transaction: AppleLatestReceiptInfo): void { + const ifNotEligible = transaction.is_trial_period === "true" || transaction.is_in_intro_offer_period === "true" + const isEligible = !ifNotEligible + const id = transaction.subscription_group_identifier! + + const existingValue = this.isEligibleIntroductoryOffer.get(id) + if (existingValue !== undefined && existingValue === false) return // we never want to overwrite value that is false already. once it's not eligible, it's never eligible. + + this.isEligibleIntroductoryOffer.set(transaction.subscription_group_identifier!, isEligible) + } + + refundReason(transaction: AppleLatestReceiptInfo): AutoRenewableSubscriptionRefundReason | undefined { + if (!transaction.cancellation_date_ms) return undefined + + if (transaction.is_upgraded) return "upgrade" + else return transaction.cancellation_reason === "1" ? "app_issue" : "other" + } + + isRenewOrRestore(transaction: AppleLatestReceiptInfo): boolean { + return transaction.original_transaction_id !== transaction.transaction_id + } + + parseTransaction( + transaction: AppleLatestReceiptInfo + ): AutoRenewableSubscriptionTransaction { + const isRenewOrRestore = this.isRenewOrRestore(transaction) + + return { + productId: transaction.product_id, + cancelledDate: transaction.cancellation_date_ms + ? new Date(parseInt(transaction.cancellation_date_ms!)) + : undefined, + refundReason: this.refundReason(transaction), + expiresDate: new Date(parseInt(transaction.expires_date_ms!)), + inIntroPeriod: transaction.is_in_intro_offer_period === "true", + inTrialPeriod: transaction.is_trial_period === "true", + isUpgradeTransaction: transaction.is_upgraded === "true", + offerCodeRefName: transaction.offer_code_ref_name, + originalPurchaseDate: new Date(parseInt(transaction.original_purchase_date_ms)), + originalTransactionId: transaction.original_transaction_id, + promotionalOfferId: transaction.promotional_offer_id, + purchaseDate: new Date(parseInt(transaction.purchase_date_ms)), + subscriptionGroupId: transaction.subscription_group_identifier!, + transactionId: transaction.transaction_id, + webOrderLineItemId: transaction.web_order_line_item_id, + isRenewOrRestore, + isFirstSubscriptionPurchase: !isRenewOrRestore, + rawTransaction: transaction + } + } +} \ No newline at end of file diff --git a/app/verify_receipt/parse/error.test.ts b/app/verify_receipt/parse/error.test.ts new file mode 100644 index 0000000..0257b59 --- /dev/null +++ b/app/verify_receipt/parse/error.test.ts @@ -0,0 +1,141 @@ +import { AppleError, handleErrorResponse, InternalError } from "./error" +import * as constants from "../../constants" +import { AppleVerifyReceiptErrorCode } from "../apple_response" + +describe("InternalError", () => { + it(`given message, expect insert bug report link`, async () => { + const actual = new InternalError("name", "added-message") + + expect(actual.message.includes(constants.bugReportLink)).toEqual(true) + }) + it(`given message, expect add message`, async () => { + const actual = new InternalError("name", "added-message") + + expect(actual.message.includes("added-message")).toEqual(true) + }) + it(`given name, expect name equal`, async () => { + const actual = new InternalError("name", "added-message") + + expect(actual.name).toEqual("name") + }) + it(`given no stack, expect set default`, async () => { + const actual = new InternalError("name", "added-message") + + expect(actual.stack).toBeDefined() + }) + it(`given given error stack, expect get error stack`, async () => { + const stack = "fake-stack" + const givenError: Error = { + name: "foo", + message: "", + stack + } + + const actual = InternalError.fromError(givenError) + + expect(actual.stack).toEqual(stack) + }) +}) + +describe("AppleError", () => { + it(`expect includes error code`, async () => { + const actual = new AppleError("message", AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET) + expect( + actual.message.includes(AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET.toString()) + ).toEqual(true) + }) +}) + +describe("handleErrorResponse", () => { + it(`given successful response, expect throw internal error`, async () => { + expect(() => { + handleErrorResponse({ + status: 0 + }) + }).toThrow() + }) + it(`given random number, expect apple error`, async () => { + const code = 2020202 + + const actual = handleErrorResponse({ + status: code + }) as AppleError + + expect(actual.appleErrorCode).toEqual(code) + }) + it(`given NOT_POST, expect internal error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.NOT_POST + }) as InternalError + + expect(actual.name).toEqual("ShouldNotHappen") + }) + it(`given SHOULD_NOT_HAPPEN, expect internal error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.SHOULD_NOT_HAPPEN + }) as InternalError + + expect(actual.name).toEqual("ShouldNotHappen") + }) + it(`given INVALID_RECEIPT_OR_DOWN, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.INVALID_RECEIPT_OR_DOWN + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"The receipt you sent may be malformed. Your code may have modified the receipt or this is a bad request sent by someone possibly malicious. Make sure your apps work and besides that, ignore this. (error code: 21002)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.INVALID_RECEIPT_OR_DOWN) + }) + it(`given UNAUTHORIZED, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.UNAUTHORIZED + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"Apple said the request was unauthorized. Perhaps you provided the wrong shared secret? (error code: 21003)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.UNAUTHORIZED) + }) + it(`given WRONG_SHARED_SECRET, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"Apple said the shared secret that you provided does not match the shared secret on file for your account. Check it to make sure it's correct. (error code: 21004)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET) + }) + it(`given APPLE_INTERNAL_ERROR, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.APPLE_INTERNAL_ERROR + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"Unknown Apple error code. This might be an internal Apple error code or one that this library simply does not know about yet. (error code: 21009)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.APPLE_INTERNAL_ERROR) + }) + it(`given SERVICE_DOWN, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.SERVICE_DOWN + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"Sorry! Apple's service seems to be down. Try the request again later. That's all we know. (error code: 21005)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.SERVICE_DOWN) + }) + it(`given CUSTOMER_NOT_FOUND, expect apple error`, async () => { + const actual = handleErrorResponse({ + status: AppleVerifyReceiptErrorCode.CUSTOMER_NOT_FOUND + }) as AppleError + + expect(actual.message).toMatchInlineSnapshot( + `"Apple could not find the customer. The customer could have been deleted? (error code: 21010)"` + ) + expect(actual.appleErrorCode).toEqual(AppleVerifyReceiptErrorCode.CUSTOMER_NOT_FOUND) + }) +}) diff --git a/app/verify_receipt/parse/error.ts b/app/verify_receipt/parse/error.ts new file mode 100644 index 0000000..f03a3c1 --- /dev/null +++ b/app/verify_receipt/parse/error.ts @@ -0,0 +1,97 @@ +import { AppleVerifyReceiptErrorCode, isAppleErrorCode } from "../apple_response/error" +import { AppleVerifyReceiptErrorResponse } from "../apple_response/error" +import { bugReportLink } from "../../constants" + +/** + * Parses the HTTP response and returns back an Error meant for a developer's purpose. These errors below are meant to be more friendly to help the developer fix the issue. + * + * @internal + */ +export const handleErrorResponse = (response: AppleVerifyReceiptErrorResponse): Error => { + const code = response.status + + if (!isAppleErrorCode(code)) throw new InternalError("ShouldNotHappen", "Function should only be called with statuses that are errors.") + + switch (code) { + case AppleVerifyReceiptErrorCode.NOT_POST: + return new InternalError( + "ShouldNotHappen", + "Error should not happen. Apple expects a correctly formatted HTTP POST which, we perform on your behalf." + ) + case AppleVerifyReceiptErrorCode.SHOULD_NOT_HAPPEN: + return new InternalError( + "ShouldNotHappen", + "Apple's documentation says this response code is no longer being used. Should not happen." + ) + case AppleVerifyReceiptErrorCode.INVALID_RECEIPT_OR_DOWN: + return new AppleError( + "The receipt you sent may be malformed. Your code may have modified the receipt or this is a bad request sent by someone possibly malicious. Make sure your apps work and besides that, ignore this.", + code + ) + case AppleVerifyReceiptErrorCode.UNAUTHORIZED: + return new AppleError( + "Apple said the request was unauthorized. Perhaps you provided the wrong shared secret?", + code + ) + case AppleVerifyReceiptErrorCode.WRONG_SHARED_SECRET: + return new AppleError( + "Apple said the shared secret that you provided does not match the shared secret on file for your account. Check it to make sure it's correct.", + code + ) + case (AppleVerifyReceiptErrorCode.APPLE_INTERNAL_ERROR, + AppleVerifyReceiptErrorCode.SERVICE_DOWN): + return new AppleError( + `Sorry! Apple's service seems to be down. Try the request again later. That's all we know.`, + code + ) + case AppleVerifyReceiptErrorCode.CUSTOMER_NOT_FOUND: + return new AppleError( + "Apple could not find the customer. The customer could have been deleted?", + code + ) + } + + return new AppleError( + "Unknown Apple error code. This might be an internal Apple error code or one that this library simply does not know about yet.", + code + ) +} + +/** + * An error came back from Apple. Apple's server returns back an error code. This class is an Error wrapper for that code to be returned to the developer. + */ +export class AppleError extends Error { + constructor(message: string, public appleErrorCode: AppleVerifyReceiptErrorCode) { + super(`${message} (error code: ${appleErrorCode})`) + } +} + +/** + * An error happened in the library itself. This Error type should not be used by a developer using this library. If this error gets thrown, it means you should open a bug report so we can fix the library. + * + * Goals of this class: + * 1. Prompt the developer to file a bug report. + * 2. Include in this error all of the information from the given error so we can fix the issue. + */ +export class InternalError implements Error { + public name: string + public message: string + public stack: string + + constructor(name: string, message: string, stack?: string) { + this.stack = stack || new Error().stack! + + this.name = name + this.message = `BUG! Please, file a bug report: ${bugReportLink}. (${message})` + } + + static fromError(error: Error): InternalError { + const errorCopy = error + const stack = error.stack! + + // so when we do stringify(), we don't include the stack. + delete errorCopy.stack + + return new InternalError(error.name, JSON.stringify(errorCopy), stack) + } +} diff --git a/app/verify_receipt/parse/purchase/index.test.ts b/app/verify_receipt/parse/purchase/index.test.ts new file mode 100644 index 0000000..5f7e32d --- /dev/null +++ b/app/verify_receipt/parse/purchase/index.test.ts @@ -0,0 +1,14 @@ +import { parsePurchases } from "." + +describe("parsePurchases", () => { + it(`given no in app purchases`, async () => { + expect(parsePurchases(require("../../../../samples/simple.json"))).toEqual([]) + }) + it(`given subscription transactions, expect get parsed subscription responses`, async () => { + const actual = parsePurchases(require("../../../../samples/bought_consumable.json")) + + expect(actual).toHaveLength(1) + expect(actual[0].transactions).toHaveLength(1) + expect(actual[0].productId).toEqual("test_consumable") + }) +}) diff --git a/app/verify_receipt/parse/purchase/index.ts b/app/verify_receipt/parse/purchase/index.ts new file mode 100644 index 0000000..1f0a783 --- /dev/null +++ b/app/verify_receipt/parse/purchase/index.ts @@ -0,0 +1,20 @@ +import { AppleVerifyReceiptSuccessfulResponse } from "../../apple_response/success" +import { ProductPurchases } from "../result" +import { ParsedPurchases } from "./transaction" + +/** + * @internal + */ +export const parsePurchases = ( + response: AppleVerifyReceiptSuccessfulResponse +): ProductPurchases[] => { + if (!response.receipt.in_app) return [] + + const parsedPurchases = new ParsedPurchases() + + response.receipt.in_app + .filter((transaction) => ParsedPurchases.isPurchaseTransaction(transaction)) + .forEach((purchase) => parsedPurchases.addTransaction(purchase)) + + return parsedPurchases.parse() +} diff --git a/app/verify_receipt/parse/purchase/transaction.test.ts b/app/verify_receipt/parse/purchase/transaction.test.ts new file mode 100644 index 0000000..565b6a8 --- /dev/null +++ b/app/verify_receipt/parse/purchase/transaction.test.ts @@ -0,0 +1,131 @@ +import { AppleInAppPurchaseTransaction } from "../../apple_response" +import { ParsedPurchases } from "./transaction" + +let parsedPurchases: ParsedPurchases +let givenPurchase: AppleInAppPurchaseTransaction +let givenPurchase2: AppleInAppPurchaseTransaction + +beforeEach(() => { + parsedPurchases = new ParsedPurchases() + givenPurchase = require("../../../../samples/consumable.json") + givenPurchase2 = require("../../../../samples/consumable2.json") +}) + +describe("ParsedPurchases", () => { + describe("isPurchaseTransaction", () => { + it(`given purchase without expires date, expect true`, async () => { + expect( + ParsedPurchases.isPurchaseTransaction({ + expires_date: undefined + } as AppleInAppPurchaseTransaction) + ).toEqual(true) + }) + it(`given purchase with expires, expect false`, async () => { + expect( + ParsedPurchases.isPurchaseTransaction({ + expires_date: "2020-11-10" + } as AppleInAppPurchaseTransaction) + ).toEqual(false) + }) + }) + + describe("addTransaction", () => { + it(`given transaction that's not a purchase, expect throw`, async () => { + expect(() => { + parsedPurchases.addTransaction({ + expires_date: "2020-11-10" + } as AppleInAppPurchaseTransaction) + }).toThrowErrorMatchingInlineSnapshot( + `"BUG! Please, file a bug report: https://github.com/levibostian/dollabill-apple/issues/new?template=BUG_REPORT.md. (Filter out all transactions that are *not* product purchase transactions before calling this function.)"` + ) + }) + it(`given add transactions from multiple purchases, expect grouped by product`, async () => { + parsedPurchases.addTransaction(givenPurchase) + parsedPurchases.addTransaction(givenPurchase2) + + expect(Array.from(parsedPurchases.transactions.keys())).toHaveLength(2) + expect(parsedPurchases.transactions.get(givenPurchase.product_id)).not.toEqual( + parsedPurchases.transactions.get(givenPurchase2.product_id) + ) + }) + it(`given add multiple transactions for same subscription, expect add transactions`, async () => { + parsedPurchases.addTransaction(givenPurchase) + parsedPurchases.addTransaction(givenPurchase) + + expect(Array.from(parsedPurchases.transactions.keys())).toHaveLength(1) + expect(parsedPurchases.transactions.get(givenPurchase.product_id)).toHaveLength(2) + }) + it(`given purchase, expect parsed transaction`, async () => { + parsedPurchases.addTransaction(givenPurchase) + + expect(parsedPurchases.transactions.get(givenPurchase.product_id)![0]).toMatchInlineSnapshot(` + Object { + "purchaseDate": 2020-11-13T01:41:41.000Z, + "quantity": 1, + "rawTransaction": Object { + "is_trial_period": "false", + "original_purchase_date": "2020-11-13 01:41:41 Etc/GMT", + "original_purchase_date_ms": "1605231701000", + "original_purchase_date_pst": "2020-11-12 17:41:41 America/Los_Angeles", + "original_transaction_id": "1000000741427785", + "product_id": "test_consumable", + "purchase_date": "2020-11-13 01:41:41 Etc/GMT", + "purchase_date_ms": "1605231701000", + "purchase_date_pst": "2020-11-12 17:41:41 America/Los_Angeles", + "quantity": "1", + "transaction_id": "1000000741427785", + }, + "transactionId": "1000000741427785", + } + `) + }) + }) + + describe("parse", () => { + it(`given multiple purchases, expect sort by purchase date`, async () => { + parsedPurchases.addTransaction(givenPurchase) + givenPurchase2.product_id = givenPurchase.product_id // to make these 2 transactions be grouped together + parsedPurchases.addTransaction(givenPurchase2) + + const actual = parsedPurchases.parse() + + expect(actual).toHaveLength(1) + expect(givenPurchase.transaction_id).not.toEqual(givenPurchase2.transaction_id) // to assert these next lines mean something. + expect(actual[0].transactions[0].transactionId).toEqual(givenPurchase.transaction_id) + expect(actual[0].transactions[1].transactionId).toEqual(givenPurchase2.transaction_id) + }) + it(`given purchases, expect result`, async () => { + parsedPurchases.addTransaction(givenPurchase) + + const actual = parsedPurchases.parse() + + expect(actual).toMatchInlineSnapshot(` + Array [ + Object { + "productId": "test_consumable", + "transactions": Array [ + Object { + "purchaseDate": 2020-11-13T01:41:41.000Z, + "quantity": 1, + "rawTransaction": Object { + "is_trial_period": "false", + "original_purchase_date": "2020-11-13 01:41:41 Etc/GMT", + "original_purchase_date_ms": "1605231701000", + "original_purchase_date_pst": "2020-11-12 17:41:41 America/Los_Angeles", + "original_transaction_id": "1000000741427785", + "product_id": "test_consumable", + "purchase_date": "2020-11-13 01:41:41 Etc/GMT", + "purchase_date_ms": "1605231701000", + "purchase_date_pst": "2020-11-12 17:41:41 America/Los_Angeles", + "quantity": "1", + "transaction_id": "1000000741427785", + }, + "transactionId": "1000000741427785", + }, + ], + }, + ] + `) + }) + }) +}) diff --git a/app/verify_receipt/parse/purchase/transaction.ts b/app/verify_receipt/parse/purchase/transaction.ts new file mode 100644 index 0000000..97b3e8f --- /dev/null +++ b/app/verify_receipt/parse/purchase/transaction.ts @@ -0,0 +1,54 @@ +import _ from "../../../underscore" +import { InternalError } from "../error" +import { AppleInAppPurchaseTransaction } from "../../apple_response/receipt" +import { ProductPurchases, ProductPurchaseTransaction } from "../result/purchase" + +/** + * Takes in a response from Apple transaction and produces a parsed transaction. Keeps track of all of them by grouping them together by subscription group. + * + * @internal + */ +export class ParsedPurchases { + public transactions: Map = new Map() + + addTransaction(purchase: AppleInAppPurchaseTransaction): void { + if (!ParsedPurchases.isPurchaseTransaction(purchase)) + throw new InternalError( + "PrerequisiteNotMet", + `Filter out all transactions that are *not* product purchase transactions before calling this function.` + ) + + const existingTransactions = this.transactions.get(purchase.product_id) || [] + + existingTransactions.push(this.parseTransaction(purchase)) + + this.transactions.set(purchase.product_id, existingTransactions) + } + + static isPurchaseTransaction(transaction: AppleInAppPurchaseTransaction): boolean { + return transaction.expires_date === undefined || transaction.expires_date === null + } + + parse(): ProductPurchases[] { + return Array.from(this.transactions.keys()).map((key) => { + const transactions = this.transactions.get(key)! + transactions.sort((first, second) => + _.date.sortNewToOld(first.purchaseDate, second.purchaseDate) + ) + + return { + productId: key, + transactions + } + }) + } + + private parseTransaction(transaction: AppleInAppPurchaseTransaction): ProductPurchaseTransaction { + return { + quantity: parseInt(transaction.quantity!), + transactionId: transaction.transaction_id, + purchaseDate: new Date(parseInt(transaction.purchase_date_ms)), + rawTransaction: transaction + } + } +} diff --git a/app/verify_receipt/parse/result/auto_renewable_subscription.ts b/app/verify_receipt/parse/result/auto_renewable_subscription.ts new file mode 100644 index 0000000..c7ba7ac --- /dev/null +++ b/app/verify_receipt/parse/result/auto_renewable_subscription.ts @@ -0,0 +1,184 @@ +import { AppleLatestReceiptInfo } from "../../apple_response" + +export type AutoRenewableSubscriptionRefundReason = "upgrade" | "app_issue" | "other" + +/** + * Receipt for an auto-renewable subscription. + */ +export type AutoRenewableSubscriptionTransaction = { + productId: string + cancelledDate?: Date + refundReason?: AutoRenewableSubscriptionRefundReason + expiresDate: Date + inIntroPeriod: boolean + inTrialPeriod: boolean + isUpgradeTransaction: boolean + offerCodeRefName?: string + originalPurchaseDate: Date + originalTransactionId: string + promotionalOfferId?: string + purchaseDate: Date + subscriptionGroupId: string + transactionId: string + webOrderLineItemId?: string + /** + * [Learn more](https://developer.apple.com/documentation/appstorereceipts/original_transaction_id) + */ + isRenewOrRestore: boolean + /** + * [Learn more](https://developer.apple.com/documentation/appstorereceipts/original_transaction_id) + */ + isFirstSubscriptionPurchase: boolean + rawTransaction: AppleLatestReceiptInfo +} + +/** + * See {@link AutoRenewableSubscriptionActionableStatus} + */ +export type AutoRenewableSubscriptionIssueString = + | "not_yet_accepting_price_increase" + | "billing_issue" + | "will_voluntary_cancel" + +/** + * Options: + * 1. **not_yet_accepting_price_increase** - You have introduced a price increase. The customer has been notified about it but has not yet accepted it. This means the customer's subscription may be expired if they do not accept it. + * 3. **billing_issue** - the subscription expired because of a billing issue. + * 3. **will_voluntary_cancel** // time to send them UI saying to downgrade to try and keep them + */ +export interface AutoRenewableSubscriptionIssues { + notYetAcceptingPriceIncrease: boolean + billingIssue: boolean + willVoluntaryCancel: boolean +} + +/** + * Options: + * 1. **active** - when no issue is detected, the subscription is active. + * 2. **billing_retry_period** - when the subscription is beyond the grace period, but apple is still trying to restore the purchase. + * 2. **voluntary_cancel** - they cancelled the subscription. You should not give the customer any access to the paid content. + * 3. **grace_period** - There is a billing issue and Apple is attempting to automatically renew the subscription. Grace period means the customer has not cancelled or refunded. You have not yet lost them as a customer. Learn more about Grace Periods in the main docs for this project. + * + * > Tip: You can open the link `https://apps.apple.com/account/billing` to send the user to their payment details page in the App Store to update their payment information. + * + * 4. **involuntary_cancel** - the customer had a billing issue and their subscription is no longer active. Maybe you (1) did not enable the *Grace Period* feature in App Store Connect and the customer has encountered a billing issue or (2) you did enable the *Grace Period* feature but Apple has since given up on attempting to renew the subscription for the customer. You should no longer give the customer access to the paid content. + * 5. **refunded** - the customer contacted Apple support and asked for a refund of their purchase and received the partial or full refund. You should not give the customer any access to the paid content. You may optionally offer another subscription plan to them to switch to a different offer that meets their needs better. + * 6. **other_not_active** - attempt to be future-proof as much as possible. *active* is only if we confirm that there are not cancellations, no expiring, no billing issues, etc. But if Apple drops on us some random new feature or expiration intent that this library doesn't know how to parse yet (or this version you have installed doesn't yet) you will get in the catch-all *other_not_active*. + */ +export type AutoRenewableSubscriptionStatus = "active" | "billing_retry_period" | "grace_period" | "voluntary_cancel" | "upgraded" | "involuntary_cancel" | "refunded" | "other_not_active" + +/** + * Auto-renewable subscription. + * + * > Note: This is auto-renewable *only*. Non aut-renewable subscriptions are up to you to handle how long they last and prompting your customers to purchase again. + */ +export interface AutoRenewableSubscription { + /** + * The `product_id` of the subscription the customer is currently paying for or did pay for. If the user upgrades or downgrades their subscription in a subscription group, this value will change to the always be the most recent `product_id` that they chose. + */ + currentProductId: string + /** + * Used to identify a subscription. + * + * When a customer upgrades/downgrades/downgrades, gets a refund then this subscription will be cancelled and a new subscription will be created. This identifier will be used through all renews and restores of the subscription. Do not rely on the {@link currentProductId} or {@link subscriptionGroup} to identify a subscription as there could be multiple subscriptions with the same product id or subscription group id (Example: one subscription is active while another was cancelled). + */ + originalTransactionId: string + /** + * The subscription group of the subscription. + */ + subscriptionGroup: string + /** + * Indicates if the customer is currently in the free trial period of their subscription. + */ + isInFreeTrialPeriod: boolean + /** + * Determine if the customer is eligible for an introductory offer. New customers are always eligible but existing customers who have not yet redeemed an offer are also eligible. This field determines if the customer has ever redeemed an offer. + * + * [Learn more about how to implement intro offers in your app](https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_introductory_offers_in_your_app) + */ + isEligibleIntroductoryOffer: boolean + /** + * The current end date of this subscription. This is a date that is calculated for you by evaluating the expires date, if there was a cancellation stopping the subscription early, or if the subscription is in a grace period and you should extend access. + * + * This is the date that you can use to determine how long your customer should have access to the subscription content. + * + * > Note: This date can increase and decrease at anytime. The subscription can be cancelled immediately (through refund or upgrade/crossgrade), renewed, etc. Do not assume that it only increases. + */ + currentEndDate: Date + /** + * Status of the subscription. + * + * > Note: This value does *not* determine if the customer will renew or not. It is more designed to determine their paid status *at this moment*. See {@link actionableStatuses} to get info about the future of the subscription. + * + * See {@link giveAccessToContent} for a simple true/false if you should give the customer access to the paid content or not. + */ + status: AutoRenewableSubscriptionStatus + /** + * If the customer has redeemed an offer code, this field will be populated with the reference name that you set for the offer. + * + * You determine in App Store Connect is an offer code is available for new, active, or expired users. + */ + usedOfferCodes: string[] + /** + * + */ + usedPromotionalOffers: string[] + /** + * All transactions for this subscription. Ordered by *the expiration date* of the transaction with the latest expire date first in the list. This sort order is recommended by Apple as it's the method to use to determine the subscription periods of this subscription. + * + * See {@link latestExpireDateTransaction} + */ + allTransactions: AutoRenewableSubscriptionTransaction[] + /** + * For convenience, the first entry of {@link allTransactions}. + * + * See {@link allTransactions} + */ + latestExpireDateTransaction: AutoRenewableSubscriptionTransaction + /** + * If the customer is currently planning on automatically renewing their subscription. A customer at anytime may decide to go into their Apple account and setup their subscription to cancel after their current subscription period expires. + */ + willAutoRenew: boolean + /** + * If the customer decides to downgrade their subscription, this is the product id that they will change to when the current subscription period is over. + */ + willDowngradeToProductId?: string + /** + * Strings version of {@link actionableStatuses}. + */ + issuesStrings: AutoRenewableSubscriptionIssueString[] + /** + * Various statuses about this subscription beyond if the customer should be given access to the paid content or not (see {@link subscriptionPaidStatus}). These values are meant to be helpful in notifying your customer, if you choose to do so, to reduce losing customers. Maybe the customer is having a billing issue and they need to update their credit card, maybe you have introduced a pricing increase and the customer has not yet accepted it yet. There are many scenarios and it's up to you to decide what to act upon. + * + * See {@link actionableStatusesStrings} for a string version of this that can be stored in a database. + */ + issues: AutoRenewableSubscriptionIssues + /** + * If the customer has accepted the price increase yet. + * + * This value is populated if the customer has been notified of the increase. If it's undefined, the customer has not yet been notified. + */ + priceIncreaseAccepted?: boolean + /** + * The date that the grace period should end. If a user recovers their subscription billing before this date, the user's subscription will go uninterrupted. If they do not, they can still fix the issue after the date but the subscription will go through a recovery because the subscription will be restored. + * + * > Note: This field will not be populated if the customer is not in a grace period for this subscription. + */ + gracePeriodExpireDate?: Date + /** + * Date that the customer cancelled their subscription, if they did. + */ + cancelledDate?: Date + /** + * The date that the current subscription period will end if not renewed or later on restored. If the subscription is cancelled or goes into a grace period, this Date does not change. It only changes if the subscription gets renewed or restored. + * + * See {@link currentEndDate} for a Date that puts into effect if a subscription is cancelled or is in a grace period. + */ + expireDate: Date + /** + * If the user is in billing retry state. This starts after a billing issue has occurred and lasts as long as Apple wishes (documentation currently says "up to 60 days"). + * + * This field *can* be `true` even after the {@link gracePeriodExpireDate} as lapsed. The grace period time is much shorter: 6-16 days depending on the subscription date. + */ + isInBillingRetry: boolean +} diff --git a/app/verify_receipt/parse/result/index.ts b/app/verify_receipt/parse/result/index.ts new file mode 100644 index 0000000..37b6c34 --- /dev/null +++ b/app/verify_receipt/parse/result/index.ts @@ -0,0 +1,3 @@ +export * from "./auto_renewable_subscription" +export * from "./parsed_receipt" +export * from "./purchase" diff --git a/app/verify_receipt/parse/result/parsed_receipt.ts b/app/verify_receipt/parse/result/parsed_receipt.ts new file mode 100644 index 0000000..e21bb5e --- /dev/null +++ b/app/verify_receipt/parse/result/parsed_receipt.ts @@ -0,0 +1,54 @@ +import { AppleVerifyReceiptSuccessfulResponse } from "../../apple_response/success" +import { AutoRenewableSubscription } from "./auto_renewable_subscription" +import { ProductPurchases } from "./purchase" + +export interface ParsedReceipt { + /** + * The environment for which the receipt was generated. + * + * This value is important to notice so you can determine what transactions were made against a real credit card. + */ + environment: "Sandbox" | "Production" + /** + * Bundle ID of the app this purchase was made for. + */ + bundleId: string + /** + * Version of the app used to make this purchase. (`CFBundleVersion` in iOS or `CFBundleShortVersion` in macOS). + * + * > Note: In the sandbox environment, this value is always "1.0" + */ + appVersion: string + /** + * All of the auto-renewable subscriptions for the customer. There is an object for each subscription. If the user has upgraded/downgraded a subscription that's within the same subscription group, you will still only see 1 object with that upgrade/downgrade in. This array will contain 1 object for each subscription purchase the customer has made. + * + * Note: How is this determined? Each object in this array represents a unique `original_transaction_id` + */ + autoRenewableSubscriptions: AutoRenewableSubscription[] + /** + * Consumables, non-consumables, and non auto-renewable subscriptions. + * + * * Consumable: A product that is used once, after which it becomes depleted and must be purchased again. Example: Fish food for a fishing app. + * * Non-consumable: A product that is purchased once and does not expire or decrease with use. Example: Race track for a game app. + * * Non auto-renewable subscription: A subscription type where you are responsible for determining when it expires and you prompt the customer to make a new purchase. + * + * This list is a list of all purchased delivered by Apple. It is up to you to unlock content, keep track of that has already been redeemed or expired. Consider this simply a list of receipts you must read through to determine the customer's status. + * + * This list is sorted by *the purchase date* with the most recent purchase being first. + */ + productPurchases: ProductPurchases[] + /** + * The raw JSON response back from Apple. This exists in case this library has not been updated, something new gets released from Apple, and you need to access it. + * + * The Typescript typings below are for your convenience. If Apple updates the response when they come out with a new feature and this library has not been updated to include this change from Apple, know that you can treat this field like `any` and access any property that you wish. This is simply the full, unmodified, response from Apple. + */ + rawResponse: AppleVerifyReceiptSuccessfulResponse + /** + * The latest Base64 encoded app receipt. Only returned for receipts that contain auto-renewable subscriptions. + * + * You can optionally store this value in your database to conduct *status polling*. + * + * > Note: Only returned for receipts that contain auto-renewable subscriptions. + */ + latestReceipt?: string +} diff --git a/app/verify_receipt/parse/result/purchase.ts b/app/verify_receipt/parse/result/purchase.ts new file mode 100644 index 0000000..ce35b36 --- /dev/null +++ b/app/verify_receipt/parse/result/purchase.ts @@ -0,0 +1,28 @@ +import { AppleInAppPurchaseTransaction } from "../../apple_response"; + +export interface ProductPurchaseTransaction { + /** + * The quantity purchased for the transaction. Mostly used for consumables. + */ + quantity: number + /** + * A unique identifier for a purchase. + */ + transactionId: string + /** + * When the purchase was made. + */ + purchaseDate: Date + rawTransaction: AppleInAppPurchaseTransaction +} + +export interface ProductPurchases { + /** + * The product id of the product purchased. + */ + productId: string + /** + * All transactions for the given {@link productId}. + */ + transactions: ProductPurchaseTransaction[] +} diff --git a/app/verify_receipt/parse/success.test.ts b/app/verify_receipt/parse/success.test.ts new file mode 100644 index 0000000..8a502e9 --- /dev/null +++ b/app/verify_receipt/parse/success.test.ts @@ -0,0 +1,10 @@ +import { parseSuccess } from "./success" + +describe("parseSuccess", () => { + it(`given receipt with no purchases, expect result`, async () => { + const actual = parseSuccess(require("../../../samples/simple.json")) + + expect(actual.autoRenewableSubscriptions).toEqual([]) + expect(actual.productPurchases).toEqual([]) + }) +}) \ No newline at end of file diff --git a/app/verify_receipt/parse/success.ts b/app/verify_receipt/parse/success.ts new file mode 100644 index 0000000..91f818a --- /dev/null +++ b/app/verify_receipt/parse/success.ts @@ -0,0 +1,22 @@ +import { AppleVerifyReceiptSuccessfulResponse } from "../apple_response/success" +import { parseSubscriptions } from "./auto_renewable_subscription" +import { parsePurchases } from "./purchase" +import { ParsedReceipt } from "./result/parsed_receipt" + +/** + * @internal + */ +export const parseSuccess = (response: AppleVerifyReceiptSuccessfulResponse): ParsedReceipt => { + const subscriptions = parseSubscriptions(response) + const purchases = parsePurchases(response) + + return { + environment: response.environment, + bundleId: response.receipt.bundle_id, + appVersion: response.receipt.application_version, + autoRenewableSubscriptions: subscriptions, + productPurchases: purchases, + rawResponse: response, + latestReceipt: response.latest_receipt + } +} diff --git a/docs/api/assets/css/main.css b/docs/api/assets/css/main.css index 4366900..72e752d 100644 --- a/docs/api/assets/css/main.css +++ b/docs/api/assets/css/main.css @@ -1,2534 +1 @@ -/*! normalize.css v1.1.3 | MIT License | git.io/normalize */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} -audio:not([controls]) { - display: none; - height: 0; -} -[hidden] { - display: none; -} -html { - font-size: 100%; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; - font-family: sans-serif; -} -button, -input, -select, -textarea { - font-family: sans-serif; -} -body { - margin: 0; -} -a:focus { - outline: thin dotted; -} -a:active, -a:hover { - outline: 0; -} -h1 { - font-size: 2em; - margin: 0.67em 0; -} -h2 { - font-size: 1.5em; - margin: 0.83em 0; -} -h3 { - font-size: 1.17em; - margin: 1em 0; -} -h4, -.tsd-index-panel h3 { - font-size: 1em; - margin: 1.33em 0; -} -h5 { - font-size: 0.83em; - margin: 1.67em 0; -} -h6 { - font-size: 0.67em; - margin: 2.33em 0; -} -abbr[title] { - border-bottom: 1px dotted; -} -b, -strong { - font-weight: bold; -} -blockquote { - margin: 1em 40px; -} -dfn { - font-style: italic; -} -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} -mark { - background: #ff0; - color: #000; -} -p, -pre { - margin: 1em 0; -} -code, -kbd, -pre, -samp { - font-family: monospace, serif; - _font-family: "courier new", monospace; - font-size: 1em; -} -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} -q { - quotes: none; -} -q:before, -q:after { - content: ""; - content: none; -} -small { - font-size: 80%; -} -sub { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; - top: -0.5em; -} -sub { - bottom: -0.25em; -} -dl, -menu, -ol, -ul { - margin: 1em 0; -} -dd { - margin: 0 0 0 40px; -} -menu, -ol, -ul { - padding: 0 0 0 40px; -} -nav ul, -nav ol { - list-style: none; - list-style-image: none; -} -img { - border: 0; - -ms-interpolation-mode: bicubic; -} -svg:not(:root) { - overflow: hidden; -} -figure, -form { - margin: 0; -} -fieldset { - border: 1px solid silver; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} -legend { - border: 0; - padding: 0; - white-space: normal; - *margin-left: -7px; -} -button, -input, -select, -textarea { - font-size: 100%; - margin: 0; - vertical-align: baseline; - *vertical-align: middle; -} -button, -input { - line-height: normal; -} -button, -select { - text-transform: none; -} -button, -html input[type="button"] { - -webkit-appearance: button; - cursor: pointer; - *overflow: visible; -} -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; - *overflow: visible; -} -button[disabled], -html input[disabled] { - cursor: default; -} -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; - padding: 0; - *height: 13px; - *width: 13px; -} -input[type="search"] { - -webkit-appearance: textfield; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} -textarea { - overflow: auto; - vertical-align: top; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -.hljs { - display: inline-block; - padding: 0.5em; - background: #fff; - color: #000; -} -.hljs-comment, -.hljs-annotation, -.hljs-template_comment, -.diff .hljs-header, -.hljs-chunk, -.apache .hljs-cbracket { - color: green; -} -.hljs-keyword, -.hljs-id, -.hljs-built_in, -.css .smalltalk .hljs-class, -.hljs-winutils, -.bash .hljs-variable, -.tex .hljs-command, -.hljs-request, -.hljs-status, -.nginx .hljs-title { - color: blue; -} -.xml .hljs-tag { - color: blue; -} -.xml .hljs-tag .hljs-value { - color: blue; -} -.hljs-string, -.hljs-title, -.hljs-parent, -.hljs-tag .hljs-value, -.hljs-rules .hljs-value { - color: #a31515; -} -.ruby .hljs-symbol { - color: #a31515; -} -.ruby .hljs-symbol .hljs-string { - color: #a31515; -} -.hljs-template_tag, -.django .hljs-variable, -.hljs-addition, -.hljs-flow, -.hljs-stream, -.apache .hljs-tag, -.hljs-date, -.tex .hljs-formula, -.coffeescript .hljs-attribute { - color: #a31515; -} -.ruby .hljs-string, -.hljs-decorator, -.hljs-filter .hljs-argument, -.hljs-localvars, -.hljs-array, -.hljs-attr_selector, -.hljs-pseudo, -.hljs-pi, -.hljs-doctype, -.hljs-deletion, -.hljs-envvar, -.hljs-shebang, -.hljs-preprocessor, -.hljs-pragma, -.userType, -.apache .hljs-sqbracket, -.nginx .hljs-built_in, -.tex .hljs-special, -.hljs-prompt { - color: #2b91af; -} -.hljs-phpdoc, -.hljs-javadoc, -.hljs-xmlDocTag { - color: gray; -} -.vhdl .hljs-typename { - font-weight: bold; -} -.vhdl .hljs-string { - color: #666; -} -.vhdl .hljs-literal { - color: #a31515; -} -.vhdl .hljs-attribute { - color: #00b0e8; -} -.xml .hljs-attribute { - color: red; -} -ul.tsd-descriptions > li > :first-child, -.tsd-panel > :first-child, -.col > :first-child, -.col-11 > :first-child, -.col-10 > :first-child, -.col-9 > :first-child, -.col-8 > :first-child, -.col-7 > :first-child, -.col-6 > :first-child, -.col-5 > :first-child, -.col-4 > :first-child, -.col-3 > :first-child, -.col-2 > :first-child, -.col-1 > :first-child, -ul.tsd-descriptions > li > :first-child > :first-child, -.tsd-panel > :first-child > :first-child, -.col > :first-child > :first-child, -.col-11 > :first-child > :first-child, -.col-10 > :first-child > :first-child, -.col-9 > :first-child > :first-child, -.col-8 > :first-child > :first-child, -.col-7 > :first-child > :first-child, -.col-6 > :first-child > :first-child, -.col-5 > :first-child > :first-child, -.col-4 > :first-child > :first-child, -.col-3 > :first-child > :first-child, -.col-2 > :first-child > :first-child, -.col-1 > :first-child > :first-child, -ul.tsd-descriptions > li > :first-child > :first-child > :first-child, -.tsd-panel > :first-child > :first-child > :first-child, -.col > :first-child > :first-child > :first-child, -.col-11 > :first-child > :first-child > :first-child, -.col-10 > :first-child > :first-child > :first-child, -.col-9 > :first-child > :first-child > :first-child, -.col-8 > :first-child > :first-child > :first-child, -.col-7 > :first-child > :first-child > :first-child, -.col-6 > :first-child > :first-child > :first-child, -.col-5 > :first-child > :first-child > :first-child, -.col-4 > :first-child > :first-child > :first-child, -.col-3 > :first-child > :first-child > :first-child, -.col-2 > :first-child > :first-child > :first-child, -.col-1 > :first-child > :first-child > :first-child { - margin-top: 0; -} -ul.tsd-descriptions > li > :last-child, -.tsd-panel > :last-child, -.col > :last-child, -.col-11 > :last-child, -.col-10 > :last-child, -.col-9 > :last-child, -.col-8 > :last-child, -.col-7 > :last-child, -.col-6 > :last-child, -.col-5 > :last-child, -.col-4 > :last-child, -.col-3 > :last-child, -.col-2 > :last-child, -.col-1 > :last-child, -ul.tsd-descriptions > li > :last-child > :last-child, -.tsd-panel > :last-child > :last-child, -.col > :last-child > :last-child, -.col-11 > :last-child > :last-child, -.col-10 > :last-child > :last-child, -.col-9 > :last-child > :last-child, -.col-8 > :last-child > :last-child, -.col-7 > :last-child > :last-child, -.col-6 > :last-child > :last-child, -.col-5 > :last-child > :last-child, -.col-4 > :last-child > :last-child, -.col-3 > :last-child > :last-child, -.col-2 > :last-child > :last-child, -.col-1 > :last-child > :last-child, -ul.tsd-descriptions > li > :last-child > :last-child > :last-child, -.tsd-panel > :last-child > :last-child > :last-child, -.col > :last-child > :last-child > :last-child, -.col-11 > :last-child > :last-child > :last-child, -.col-10 > :last-child > :last-child > :last-child, -.col-9 > :last-child > :last-child > :last-child, -.col-8 > :last-child > :last-child > :last-child, -.col-7 > :last-child > :last-child > :last-child, -.col-6 > :last-child > :last-child > :last-child, -.col-5 > :last-child > :last-child > :last-child, -.col-4 > :last-child > :last-child > :last-child, -.col-3 > :last-child > :last-child > :last-child, -.col-2 > :last-child > :last-child > :last-child, -.col-1 > :last-child > :last-child > :last-child { - margin-bottom: 0; -} -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 40px; -} -@media (max-width: 640px) { - .container { - padding: 0 20px; - } -} -.container-main { - padding-bottom: 200px; -} -.row { - display: flex; - position: relative; - margin: 0 -10px; -} -.row:after { - visibility: hidden; - display: block; - content: ""; - clear: both; - height: 0; -} -.col, -.col-11, -.col-10, -.col-9, -.col-8, -.col-7, -.col-6, -.col-5, -.col-4, -.col-3, -.col-2, -.col-1 { - box-sizing: border-box; - float: left; - padding: 0 10px; -} -.col-1 { - width: 8.3333333333%; -} -.offset-1 { - margin-left: 8.3333333333%; -} -.col-2 { - width: 16.6666666667%; -} -.offset-2 { - margin-left: 16.6666666667%; -} -.col-3 { - width: 25%; -} -.offset-3 { - margin-left: 25%; -} -.col-4 { - width: 33.3333333333%; -} -.offset-4 { - margin-left: 33.3333333333%; -} -.col-5 { - width: 41.6666666667%; -} -.offset-5 { - margin-left: 41.6666666667%; -} -.col-6 { - width: 50%; -} -.offset-6 { - margin-left: 50%; -} -.col-7 { - width: 58.3333333333%; -} -.offset-7 { - margin-left: 58.3333333333%; -} -.col-8 { - width: 66.6666666667%; -} -.offset-8 { - margin-left: 66.6666666667%; -} -.col-9 { - width: 75%; -} -.offset-9 { - margin-left: 75%; -} -.col-10 { - width: 83.3333333333%; -} -.offset-10 { - margin-left: 83.3333333333%; -} -.col-11 { - width: 91.6666666667%; -} -.offset-11 { - margin-left: 91.6666666667%; -} -.tsd-kind-icon { - display: block; - position: relative; - padding-left: 20px; - text-indent: -20px; -} -.tsd-kind-icon:before { - content: ""; - display: inline-block; - vertical-align: middle; - width: 17px; - height: 17px; - margin: 0 3px 2px 0; - background-image: url(data:image/png;base64,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); -} -@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { - .tsd-kind-icon:before { - background-image: url(data:image/png;base64,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); - background-size: 238px 204px; - } -} -.tsd-signature.tsd-kind-icon:before { - background-position: 0 -153px; -} -.tsd-kind-object-literal > .tsd-kind-icon:before { - background-position: 0px -17px; -} -.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -17px; -} -.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -17px; -} -.tsd-kind-class > .tsd-kind-icon:before { - background-position: 0px -34px; -} -.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -34px; -} -.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -34px; -} -.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -51px; -} -.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -51px; -} -.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -51px; -} -.tsd-kind-interface > .tsd-kind-icon:before { - background-position: 0px -68px; -} -.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -68px; -} -.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -68px; -} -.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -85px; -} -.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -85px; -} -.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -85px; -} -.tsd-kind-namespace > .tsd-kind-icon:before { - background-position: 0px -102px; -} -.tsd-kind-namespace.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -102px; -} -.tsd-kind-namespace.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -102px; -} -.tsd-kind-module > .tsd-kind-icon:before { - background-position: 0px -102px; -} -.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -102px; -} -.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -102px; -} -.tsd-kind-enum > .tsd-kind-icon:before { - background-position: 0px -119px; -} -.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -119px; -} -.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -119px; -} -.tsd-kind-enum-member > .tsd-kind-icon:before { - background-position: 0px -136px; -} -.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -136px; -} -.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -136px; -} -.tsd-kind-signature > .tsd-kind-icon:before { - background-position: 0px -153px; -} -.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -153px; -} -.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -153px; -} -.tsd-kind-type-alias > .tsd-kind-icon:before { - background-position: 0px -170px; -} -.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -170px; -} -.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -170px; -} -.tsd-kind-type-alias.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -187px; -} -.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -187px; -} -.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -187px; -} -.tsd-kind-variable > .tsd-kind-icon:before { - background-position: -136px -0px; -} -.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -0px; -} -.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -0px; -} -.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -0px; -} -.tsd-kind-property > .tsd-kind-icon:before { - background-position: -136px -0px; -} -.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -0px; -} -.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -0px; -} -.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -0px; -} -.tsd-kind-get-signature > .tsd-kind-icon:before { - background-position: -136px -17px; -} -.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -17px; -} -.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -17px; -} -.tsd-kind-set-signature > .tsd-kind-icon:before { - background-position: -136px -34px; -} -.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -34px; -} -.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -34px; -} -.tsd-kind-accessor > .tsd-kind-icon:before { - background-position: -136px -51px; -} -.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -51px; -} -.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -51px; -} -.tsd-kind-function > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -68px; -} -.tsd-kind-method > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -68px; -} -.tsd-kind-call-signature > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -68px; -} -.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: -136px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -85px; -} -.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: -136px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -85px; -} -.tsd-kind-constructor > .tsd-kind-icon:before { - background-position: -136px -102px; -} -.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -102px; -} -.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -102px; -} -.tsd-kind-constructor-signature > .tsd-kind-icon:before { - background-position: -136px -102px; -} -.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -102px; -} -.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -102px; -} -.tsd-kind-index-signature > .tsd-kind-icon:before { - background-position: -136px -119px; -} -.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -119px; -} -.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -119px; -} -.tsd-kind-event > .tsd-kind-icon:before { - background-position: -136px -136px; -} -.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -136px; -} -.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -136px; -} -.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -136px; -} -.tsd-is-static > .tsd-kind-icon:before { - background-position: -136px -153px; -} -.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -153px; -} -.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -102px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -153px; -} -.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -153px; -} -.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -153px; -} -.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -153px; -} -.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -170px; -} -.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -170px; -} -.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -170px; -} -.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { - background-position: -136px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -221px -187px; -} -@keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } -} -@keyframes fade-in-delayed { - 0% { - opacity: 0; - } - 33% { - opacity: 0; - } - 100% { - opacity: 1; - } -} -@keyframes fade-out-delayed { - 0% { - opacity: 1; - visibility: visible; - } - 66% { - opacity: 0; - } - 100% { - opacity: 0; - } -} -@keyframes shift-to-left { - from { - transform: translate(0, 0); - } - to { - transform: translate(-25%, 0); - } -} -@keyframes unshift-to-left { - from { - transform: translate(-25%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } -} -body { - background: #fdfdfd; - font-family: "Segoe UI", sans-serif; - font-size: 16px; - color: #222; -} -a { - color: #4da6ff; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -code, -pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 14px; - background-color: rgba(0, 0, 0, 0.04); -} -pre { - padding: 10px; -} -pre code { - padding: 0; - font-size: 100%; - background-color: transparent; -} -.tsd-typography { - line-height: 1.333em; -} -.tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-typography h4, -.tsd-typography .tsd-index-panel h3, -.tsd-index-panel .tsd-typography h3, -.tsd-typography h5, -.tsd-typography h6 { - font-size: 1em; - margin: 0; -} -.tsd-typography h5, -.tsd-typography h6 { - font-weight: normal; -} -.tsd-typography p, -.tsd-typography ul, -.tsd-typography ol { - margin: 1em 0; -} -@media (min-width: 901px) and (max-width: 1024px) { - html.default .col-content { - width: 72%; - } - html.default .col-menu { - width: 28%; - } - html.default .tsd-navigation { - padding-left: 10px; - } -} -@media (max-width: 900px) { - html.default .col-content { - float: none; - width: 100%; - } - html.default .col-menu { - position: fixed !important; - overflow: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - width: 100%; - padding: 20px 20px 0 0; - max-width: 450px; - visibility: hidden; - background-color: #fff; - transform: translate(100%, 0); - } - html.default .col-menu > *:last-child { - padding-bottom: 20px; - } - html.default .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - html.default.to-has-menu .overlay { - animation: fade-in 0.4s; - } - html.default.to-has-menu header, - html.default.to-has-menu footer, - html.default.to-has-menu .col-content { - animation: shift-to-left 0.4s; - } - html.default.to-has-menu .col-menu { - animation: pop-in-from-right 0.4s; - } - html.default.from-has-menu .overlay { - animation: fade-out 0.4s; - } - html.default.from-has-menu header, - html.default.from-has-menu footer, - html.default.from-has-menu .col-content { - animation: unshift-to-left 0.4s; - } - html.default.from-has-menu .col-menu { - animation: pop-out-to-right 0.4s; - } - html.default.has-menu body { - overflow: hidden; - } - html.default.has-menu .overlay { - visibility: visible; - } - html.default.has-menu header, - html.default.has-menu footer, - html.default.has-menu .col-content { - transform: translate(-25%, 0); - } - html.default.has-menu .col-menu { - visibility: visible; - transform: translate(0, 0); - } -} -.tsd-page-title { - padding: 70px 0 20px 0; - margin: 0 0 40px 0; - background: #fff; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); -} -.tsd-page-title h1 { - margin: 0; -} -.tsd-breadcrumb { - margin: 0; - padding: 0; - color: #707070; -} -.tsd-breadcrumb a { - color: #707070; - text-decoration: none; -} -.tsd-breadcrumb a:hover { - text-decoration: underline; -} -.tsd-breadcrumb li { - display: inline; -} -.tsd-breadcrumb li:after { - content: " / "; -} -html.minimal .container { - margin: 0; -} -html.minimal .container-main { - padding-top: 50px; - padding-bottom: 0; -} -html.minimal .content-wrap { - padding-left: 300px; -} -html.minimal .tsd-navigation { - position: fixed !important; - overflow: auto; - -webkit-overflow-scrolling: touch; - box-sizing: border-box; - z-index: 1; - left: 0; - top: 40px; - bottom: 0; - width: 300px; - padding: 20px; - margin: 0; -} -html.minimal .tsd-member .tsd-member { - margin-left: 0; -} -html.minimal .tsd-page-toolbar { - position: fixed; - z-index: 2; -} -html.minimal #tsd-filter .tsd-filter-group { - right: 0; - transform: none; -} -html.minimal footer { - background-color: transparent; -} -html.minimal footer .container { - padding: 0; -} -html.minimal .tsd-generator { - padding: 0; -} -@media (max-width: 900px) { - html.minimal .tsd-navigation { - display: none; - } - html.minimal .content-wrap { - padding-left: 0; - } -} -dl.tsd-comment-tags { - overflow: hidden; -} -dl.tsd-comment-tags dt { - float: left; - padding: 1px 5px; - margin: 0 10px 0 0; - border-radius: 4px; - border: 1px solid #707070; - color: #707070; - font-size: 0.8em; - font-weight: normal; -} -dl.tsd-comment-tags dd { - margin: 0 0 10px 0; -} -dl.tsd-comment-tags dd:before, -dl.tsd-comment-tags dd:after { - display: table; - content: " "; -} -dl.tsd-comment-tags dd pre, -dl.tsd-comment-tags dd:after { - clear: both; -} -dl.tsd-comment-tags p { - margin: 0; -} -.tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; -} -.tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; -} -.toggle-protected .tsd-is-private { - display: none; -} -.toggle-public .tsd-is-private, -.toggle-public .tsd-is-protected, -.toggle-public .tsd-is-private-protected { - display: none; -} -.toggle-inherited .tsd-is-inherited { - display: none; -} -.toggle-only-exported .tsd-is-not-exported { - display: none; -} -.toggle-externals .tsd-is-external { - display: none; -} -#tsd-filter { - position: relative; - display: inline-block; - height: 40px; - vertical-align: bottom; -} -.no-filter #tsd-filter { - display: none; -} -#tsd-filter .tsd-filter-group { - display: inline-block; - height: 40px; - vertical-align: bottom; - white-space: nowrap; -} -#tsd-filter input { - display: none; -} -@media (max-width: 900px) { - #tsd-filter .tsd-filter-group { - display: block; - position: absolute; - top: 40px; - right: 20px; - height: auto; - background-color: #fff; - visibility: hidden; - transform: translate(50%, 0); - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); - } - .has-options #tsd-filter .tsd-filter-group { - visibility: visible; - } - .to-has-options #tsd-filter .tsd-filter-group { - animation: fade-in 0.2s; - } - .from-has-options #tsd-filter .tsd-filter-group { - animation: fade-out 0.2s; - } - #tsd-filter label, - #tsd-filter .tsd-select { - display: block; - padding-right: 20px; - } -} -footer { - border-top: 1px solid #eee; - background-color: #fff; -} -footer.with-border-bottom { - border-bottom: 1px solid #eee; -} -footer .tsd-legend-group { - font-size: 0; -} -footer .tsd-legend { - display: inline-block; - width: 25%; - padding: 0; - font-size: 16px; - list-style: none; - line-height: 1.333em; - vertical-align: top; -} -@media (max-width: 900px) { - footer .tsd-legend { - width: 50%; - } -} -.tsd-hierarchy { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-hierarchy .target { - font-weight: bold; -} -.tsd-index-panel .tsd-index-content { - margin-bottom: -30px !important; -} -.tsd-index-panel .tsd-index-section { - margin-bottom: 30px !important; -} -.tsd-index-panel h3 { - margin: 0 -20px 10px -20px; - padding: 0 20px 10px 20px; - border-bottom: 1px solid #eee; -} -.tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 3; - -moz-column-count: 3; - -ms-column-count: 3; - -o-column-count: 3; - column-count: 3; - -webkit-column-gap: 20px; - -moz-column-gap: 20px; - -ms-column-gap: 20px; - -o-column-gap: 20px; - column-gap: 20px; - padding: 0; - list-style: none; - line-height: 1.333em; -} -@media (max-width: 900px) { - .tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 1; - -moz-column-count: 1; - -ms-column-count: 1; - -o-column-count: 1; - column-count: 1; - } -} -@media (min-width: 901px) and (max-width: 1024px) { - .tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 2; - -moz-column-count: 2; - -ms-column-count: 2; - -o-column-count: 2; - column-count: 2; - } -} -.tsd-index-panel ul.tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; -} -.tsd-index-panel a, -.tsd-index-panel .tsd-parent-kind-module a { - color: #9600ff; -} -.tsd-index-panel .tsd-parent-kind-interface a { - color: #647f1b; -} -.tsd-index-panel .tsd-parent-kind-enum a { - color: #937210; -} -.tsd-index-panel .tsd-parent-kind-class a { - color: #0672de; -} -.tsd-index-panel .tsd-kind-module a { - color: #9600ff; -} -.tsd-index-panel .tsd-kind-interface a { - color: #647f1b; -} -.tsd-index-panel .tsd-kind-enum a { - color: #937210; -} -.tsd-index-panel .tsd-kind-class a { - color: #0672de; -} -.tsd-index-panel .tsd-is-private a { - color: #707070; -} -.tsd-flag { - display: inline-block; - padding: 1px 5px; - border-radius: 4px; - color: #fff; - background-color: #707070; - text-indent: 0; - font-size: 14px; - font-weight: normal; -} -.tsd-anchor { - position: absolute; - top: -100px; -} -.tsd-member { - position: relative; -} -.tsd-member .tsd-anchor + h3 { - margin-top: 0; - margin-bottom: 0; - border-bottom: none; -} -.tsd-navigation { - margin: 0 0 0 40px; -} -.tsd-navigation a { - display: block; - padding-top: 2px; - padding-bottom: 2px; - border-left: 2px solid transparent; - color: #222; - text-decoration: none; - transition: border-left-color 0.1s; -} -.tsd-navigation a:hover { - text-decoration: underline; -} -.tsd-navigation ul { - margin: 0; - padding: 0; - list-style: none; -} -.tsd-navigation li { - padding: 0; -} -.tsd-navigation.primary { - padding-bottom: 40px; -} -.tsd-navigation.primary a { - display: block; - padding-top: 6px; - padding-bottom: 6px; -} -.tsd-navigation.primary ul li a { - padding-left: 5px; -} -.tsd-navigation.primary ul li li a { - padding-left: 25px; -} -.tsd-navigation.primary ul li li li a { - padding-left: 45px; -} -.tsd-navigation.primary ul li li li li a { - padding-left: 65px; -} -.tsd-navigation.primary ul li li li li li a { - padding-left: 85px; -} -.tsd-navigation.primary ul li li li li li li a { - padding-left: 105px; -} -.tsd-navigation.primary > ul { - border-bottom: 1px solid #eee; -} -.tsd-navigation.primary li { - border-top: 1px solid #eee; -} -.tsd-navigation.primary li.current > a { - font-weight: bold; -} -.tsd-navigation.primary li.label span { - display: block; - padding: 20px 0 6px 5px; - color: #707070; -} -.tsd-navigation.primary li.globals + li > span, -.tsd-navigation.primary li.globals + li > a { - padding-top: 20px; -} -.tsd-navigation.secondary { - max-height: calc(100vh - 1rem - 40px); - overflow: auto; - position: -webkit-sticky; - position: sticky; - top: calc(0.5rem + 40px); - transition: 0.3s; -} -.tsd-navigation.secondary.tsd-navigation--toolbar-hide { - max-height: calc(100vh - 1rem); - top: 0.5rem; -} -.tsd-navigation.secondary ul { - transition: opacity 0.2s; -} -.tsd-navigation.secondary ul li a { - padding-left: 25px; -} -.tsd-navigation.secondary ul li li a { - padding-left: 45px; -} -.tsd-navigation.secondary ul li li li a { - padding-left: 65px; -} -.tsd-navigation.secondary ul li li li li a { - padding-left: 85px; -} -.tsd-navigation.secondary ul li li li li li a { - padding-left: 105px; -} -.tsd-navigation.secondary ul li li li li li li a { - padding-left: 125px; -} -.tsd-navigation.secondary ul.current a { - border-left-color: #eee; -} -.tsd-navigation.secondary li.focus > a, -.tsd-navigation.secondary ul.current li.focus > a { - border-left-color: #000; -} -.tsd-navigation.secondary li.current { - margin-top: 20px; - margin-bottom: 20px; - border-left-color: #eee; -} -.tsd-navigation.secondary li.current > a { - font-weight: bold; -} -@media (min-width: 901px) { - .menu-sticky-wrap { - position: static; - } -} -.tsd-panel { - margin: 20px 0; - padding: 20px; - background-color: #fff; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -.tsd-panel:empty { - display: none; -} -.tsd-panel > h1, -.tsd-panel > h2, -.tsd-panel > h3 { - margin: 1.5em -20px 10px -20px; - padding: 0 20px 10px 20px; - border-bottom: 1px solid #eee; -} -.tsd-panel > h1.tsd-before-signature, -.tsd-panel > h2.tsd-before-signature, -.tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: 0; -} -.tsd-panel table { - display: block; - width: 100%; - overflow: auto; - margin-top: 10px; - word-break: normal; - word-break: keep-all; -} -.tsd-panel table th { - font-weight: bold; -} -.tsd-panel table th, -.tsd-panel table td { - padding: 6px 13px; - border: 1px solid #ddd; -} -.tsd-panel table tr { - background-color: #fff; - border-top: 1px solid #ccc; -} -.tsd-panel table tr:nth-child(2n) { - background-color: #f8f8f8; -} -.tsd-panel-group { - margin: 60px 0; -} -.tsd-panel-group > h1, -.tsd-panel-group > h2, -.tsd-panel-group > h3 { - padding-left: 20px; - padding-right: 20px; -} -#tsd-search { - transition: background-color 0.2s; -} -#tsd-search .title { - position: relative; - z-index: 2; -} -#tsd-search .field { - position: absolute; - left: 0; - top: 0; - right: 40px; - height: 40px; -} -#tsd-search .field input { - box-sizing: border-box; - position: relative; - top: -50px; - z-index: 1; - width: 100%; - padding: 0 10px; - opacity: 0; - outline: 0; - border: 0; - background: transparent; - color: #222; -} -#tsd-search .field label { - position: absolute; - overflow: hidden; - right: -40px; -} -#tsd-search .field input, -#tsd-search .title { - transition: opacity 0.2s; -} -#tsd-search .results { - position: absolute; - visibility: hidden; - top: 40px; - width: 100%; - margin: 0; - padding: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -#tsd-search .results li { - padding: 0 10px; - background-color: #fdfdfd; -} -#tsd-search .results li:nth-child(even) { - background-color: #fff; -} -#tsd-search .results li.state { - display: none; -} -#tsd-search .results li.current, -#tsd-search .results li:hover { - background-color: #eee; -} -#tsd-search .results a { - display: block; -} -#tsd-search .results a:before { - top: 10px; -} -#tsd-search .results span.parent { - color: #707070; - font-weight: normal; -} -#tsd-search.has-focus { - background-color: #eee; -} -#tsd-search.has-focus .field input { - top: 0; - opacity: 1; -} -#tsd-search.has-focus .title { - z-index: 0; - opacity: 0; -} -#tsd-search.has-focus .results { - visibility: visible; -} -#tsd-search.loading .results li.state.loading { - display: block; -} -#tsd-search.failure .results li.state.failure { - display: block; -} -.tsd-signature { - margin: 0 0 1em 0; - padding: 10px; - border: 1px solid #eee; - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; -} -.tsd-signature.tsd-kind-icon { - padding-left: 30px; -} -.tsd-signature.tsd-kind-icon:before { - top: 10px; - left: 10px; -} -.tsd-panel > .tsd-signature { - margin-left: -20px; - margin-right: -20px; - border-width: 1px 0; -} -.tsd-panel > .tsd-signature.tsd-kind-icon { - padding-left: 40px; -} -.tsd-panel > .tsd-signature.tsd-kind-icon:before { - left: 20px; -} -.tsd-signature-symbol { - color: #707070; - font-weight: normal; -} -.tsd-signature-type { - font-style: italic; - font-weight: normal; -} -.tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - border: 1px solid #eee; -} -.tsd-signatures .tsd-signature { - margin: 0; - border-width: 1px 0 0 0; - transition: background-color 0.1s; -} -.tsd-signatures .tsd-signature:first-child { - border-top-width: 0; -} -.tsd-signatures .tsd-signature.current { - background-color: #eee; -} -.tsd-signatures.active > .tsd-signature { - cursor: pointer; -} -.tsd-panel > .tsd-signatures { - margin-left: -20px; - margin-right: -20px; - border-width: 1px 0; -} -.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { - padding-left: 40px; -} -.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { - left: 20px; -} -.tsd-panel > a.anchor + .tsd-signatures { - border-top-width: 0; - margin-top: -20px; -} -ul.tsd-descriptions { - position: relative; - overflow: hidden; - padding: 0; - list-style: none; -} -ul.tsd-descriptions.active > .tsd-description { - display: none; -} -ul.tsd-descriptions.active > .tsd-description.current { - display: block; -} -ul.tsd-descriptions.active > .tsd-description.fade-in { - animation: fade-in-delayed 0.3s; -} -ul.tsd-descriptions.active > .tsd-description.fade-out { - animation: fade-out-delayed 0.3s; - position: absolute; - display: block; - top: 0; - left: 0; - right: 0; - opacity: 0; - visibility: hidden; -} -ul.tsd-descriptions h4, -ul.tsd-descriptions .tsd-index-panel h3, -.tsd-index-panel ul.tsd-descriptions h3 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} -ul.tsd-parameters, -ul.tsd-type-parameters { - list-style: square; - margin: 0; - padding-left: 20px; -} -ul.tsd-parameters > li.tsd-parameter-signature, -ul.tsd-type-parameters > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; -} -ul.tsd-parameters h5, -ul.tsd-type-parameters h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} -ul.tsd-parameters .tsd-comment, -ul.tsd-type-parameters .tsd-comment { - margin-top: -0.5em; -} -.tsd-sources { - font-size: 14px; - color: #707070; - margin: 0 0 1em 0; -} -.tsd-sources a { - color: #707070; - text-decoration: underline; -} -.tsd-sources ul, -.tsd-sources p { - margin: 0 !important; -} -.tsd-sources ul { - list-style: none; - padding: 0; -} -.tsd-page-toolbar { - position: fixed; - z-index: 1; - top: 0; - left: 0; - width: 100%; - height: 40px; - color: #333; - background: #fff; - border-bottom: 1px solid #eee; - transition: transform 0.3s linear; -} -.tsd-page-toolbar a { - color: #333; - text-decoration: none; -} -.tsd-page-toolbar a.title { - font-weight: bold; -} -.tsd-page-toolbar a.title:hover { - text-decoration: underline; -} -.tsd-page-toolbar .table-wrap { - display: table; - width: 100%; - height: 40px; -} -.tsd-page-toolbar .table-cell { - display: table-cell; - position: relative; - white-space: nowrap; - line-height: 40px; -} -.tsd-page-toolbar .table-cell:first-child { - width: 100%; -} -.tsd-page-toolbar--hide { - transform: translateY(-100%); -} -.tsd-select .tsd-select-list li:before, -.tsd-select .tsd-select-label:before, -.tsd-widget:before { - content: ""; - display: inline-block; - width: 40px; - height: 40px; - margin: 0 -8px 0 0; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAoCAQAAAAlSeuiAAABp0lEQVR4Ae3aUa3jQAyF4QNhIBTCQiiEQlgIhRAGhTAQBkIgBEIgDITZZGXNjZTePiSWYqn/54dGfbAq+SiTutWXAgAAAAAAAAAAAAA8NCz1UFSD2lKDS5d3NVzZj/BVNasaLoRZRUmj2lLrVVHWMUntQ13Wj/i1pWa9lprX6xMRnH4dx6Rjsn26+v+12ms+EcB37P0r+qH+DNQGXgMFcHzbregQ78B8eQCTJk0e979ZW7PdA2O49ceDsYexKgUNoI3EKYDWL3D8miaPh/uXtl6BHqEHFQvgXau/FsCiIWAAbST2fpQRT0sl70j3z5ZiBdD7CG5WZX8kxwmgjbiP5GQA9/3O2XaxnnHi53AEE0AbRh+JQwC3/fzC4hcb6xPvS4i3QaMdwX+0utsRPEY6gm2wNhKHAG77eUi7SIcK4G4NY4GMIan2u2Cxqzncl5DUn7Q8ArjvZ8JFOsl/Ed0jyBom+BomQKSto+9PcblHMM4iuu4X0QQw5hrGQY/gUxFkjZuf4m4alXVU+1De/VhEn5CvDSB/RsBzqWgAAAAAAAAAAAAAAACAfyyYJ5nhVuwIAAAAAElFTkSuQmCC); - background-repeat: no-repeat; - text-indent: -1024px; - vertical-align: bottom; -} -@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { - .tsd-select .tsd-select-list li:before, - .tsd-select .tsd-select-label:before, - .tsd-widget:before { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAABQCAMAAAC+sjQXAAAAM1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjBUbJAAAAEXRSTlMA3/+/UCBw7xCPYIBAMM+vn1qYQ7QAAALCSURBVHgB7MGBAAAAAICg/akXqQIAAAAAAAAAAAAAAAAAAJids9mdE4bhoDNZCITP93/aSmhV/9uwPWyi8jtkblws2IxsYpz9LwSAaJW8AreE16PxOsMYE6Q4DiYKF7X+8ZHXc/E608xv5snEyIuZrVwMZjbnujR6T3gsXmcLOIRNzD+Ig2UuVtt2+NbAiX/wVLzOlviD9L2BOfGBlL/3D1I+uDjGBJArBPxU3x+K15kCQFo2s21JAOHrKpz4SPrWv4IKA+uFaR6vMwMcb+emA2DWEfDglrkLqEBOKVslA8Dx14oPMiV4CtywWxdQgAwkq2QE0uTXUwJGk2G9s3mTFNBzAkC7HKPsX72AEVjMnAWIpsPCRRjXdQxcjCYpoOcEgHY5Rtk/slWSgM3M2aSeeVgjAOeVpKcdgGMdNAXMuIAqOcZzqF8L+WcAsi8wkTeheCWMegL6mgCorHHyEJ5TVfxrLWDrTUjZdhnhjYqAnlN8TaoELOLVC0gucmoz/3RKcPs2jAs4+J5ET8AEZF+TSgGLeC1V8YuGQQU2IV1Asq9JCwE9XitZVPxr34bpJRj8PqsFLOK108W9aVrWZRrR7Sm2HL4JCToCujHZ6gUs4jUz0P1TEvD+U5wMa363YeziBODIq1YbJrsv9QKW8Ry1nNp+GAHvuingRTfmYcjBf0QpAS37bdUL6PFKtHJq63EsZ5cxcKMkDVIClu1dAK1PcJ5TFQ0M9wZKDCPs3BD7MIJGTs3WfiTfDVQYx5q5ZekCauTU3P5Q0ukGCgh49oFURdobWBY9N/CxEuwGjpGLuPhTdwH1x7HqDDxNgRP2zQ8lraFyF/yJ9vH6QGqtgSbBOU8/j2VORz+Wqfle2d5Ae4R+ML0z7Y+W4P7XHN3AU+tzyK/24EAGAAAAYJC/9T2+CgAAAAAAAAAAAAAAAAAAAADgJpfzHyIKFFBKAAAAAElFTkSuQmCC); - background-size: 320px 40px; - } -} -.tsd-widget { - display: inline-block; - overflow: hidden; - opacity: 0.6; - height: 40px; - transition: opacity 0.1s, background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-widget:hover { - opacity: 0.8; -} -.tsd-widget.active { - opacity: 1; - background-color: #eee; -} -.tsd-widget.no-caption { - width: 40px; -} -.tsd-widget.no-caption:before { - margin: 0; -} -.tsd-widget.search:before { - background-position: 0 0; -} -.tsd-widget.menu:before { - background-position: -40px 0; -} -.tsd-widget.options:before { - background-position: -80px 0; -} -.tsd-widget.options, -.tsd-widget.menu { - display: none; -} -@media (max-width: 900px) { - .tsd-widget.options, - .tsd-widget.menu { - display: inline-block; - } -} -input[type="checkbox"] + .tsd-widget:before { - background-position: -120px 0; -} -input[type="checkbox"]:checked + .tsd-widget:before { - background-position: -160px 0; -} -.tsd-select { - position: relative; - display: inline-block; - height: 40px; - transition: opacity 0.1s, background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-select .tsd-select-label { - opacity: 0.6; - transition: opacity 0.2s; -} -.tsd-select .tsd-select-label:before { - background-position: -240px 0; -} -.tsd-select.active .tsd-select-label { - opacity: 0.8; -} -.tsd-select.active .tsd-select-list { - visibility: visible; - opacity: 1; - transition-delay: 0s; -} -.tsd-select .tsd-select-list { - position: absolute; - visibility: hidden; - top: 40px; - left: 0; - margin: 0; - padding: 0; - opacity: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); - transition: visibility 0s 0.2s, opacity 0.2s; -} -.tsd-select .tsd-select-list li { - padding: 0 20px 0 0; - background-color: #fdfdfd; -} -.tsd-select .tsd-select-list li:before { - background-position: 40px 0; -} -.tsd-select .tsd-select-list li:nth-child(even) { - background-color: #fff; -} -.tsd-select .tsd-select-list li:hover { - background-color: #eee; -} -.tsd-select .tsd-select-list li.selected:before { - background-position: -200px 0; -} -@media (max-width: 900px) { - .tsd-select .tsd-select-list { - top: 0; - left: auto; - right: 100%; - margin-right: -5px; - } - .tsd-select .tsd-select-label:before { - background-position: -280px 0; - } -} -img { - max-width: 100%; -} +/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-family:sans-serif}button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4,.tsd-index-panel h3{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:80%}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure,form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button]{-webkit-appearance:button;cursor:pointer;*overflow:visible}input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}.hljs{display:inline-block;padding:.5em;background:#fff;color:#000}.hljs-comment,.hljs-annotation,.hljs-template_comment,.diff .hljs-header,.hljs-chunk,.apache .hljs-cbracket{color:green}.hljs-keyword,.hljs-id,.hljs-built_in,.css .smalltalk .hljs-class,.hljs-winutils,.bash .hljs-variable,.tex .hljs-command,.hljs-request,.hljs-status,.nginx .hljs-title{color:blue}.xml .hljs-tag{color:blue}.xml .hljs-tag .hljs-value{color:blue}.hljs-string,.hljs-title,.hljs-parent,.hljs-tag .hljs-value,.hljs-rules .hljs-value{color:#a31515}.ruby .hljs-symbol{color:#a31515}.ruby .hljs-symbol .hljs-string{color:#a31515}.hljs-template_tag,.django .hljs-variable,.hljs-addition,.hljs-flow,.hljs-stream,.apache .hljs-tag,.hljs-date,.tex .hljs-formula,.coffeescript .hljs-attribute{color:#a31515}.ruby .hljs-string,.hljs-decorator,.hljs-filter .hljs-argument,.hljs-localvars,.hljs-array,.hljs-attr_selector,.hljs-pseudo,.hljs-pi,.hljs-doctype,.hljs-deletion,.hljs-envvar,.hljs-shebang,.hljs-preprocessor,.hljs-pragma,.userType,.apache .hljs-sqbracket,.nginx .hljs-built_in,.tex .hljs-special,.hljs-prompt{color:#2b91af}.hljs-phpdoc,.hljs-javadoc,.hljs-xmlDocTag{color:gray}.vhdl .hljs-typename{font-weight:bold}.vhdl .hljs-string{color:#666}.vhdl .hljs-literal{color:#a31515}.vhdl .hljs-attribute{color:#00b0e8}.xml .hljs-attribute{color:red}ul.tsd-descriptions>li>:first-child,.tsd-panel>:first-child,.col>:first-child,.col-11>:first-child,.col-10>:first-child,.col-9>:first-child,.col-8>:first-child,.col-7>:first-child,.col-6>:first-child,.col-5>:first-child,.col-4>:first-child,.col-3>:first-child,.col-2>:first-child,.col-1>:first-child,ul.tsd-descriptions>li>:first-child>:first-child,.tsd-panel>:first-child>:first-child,.col>:first-child>:first-child,.col-11>:first-child>:first-child,.col-10>:first-child>:first-child,.col-9>:first-child>:first-child,.col-8>:first-child>:first-child,.col-7>:first-child>:first-child,.col-6>:first-child>:first-child,.col-5>:first-child>:first-child,.col-4>:first-child>:first-child,.col-3>:first-child>:first-child,.col-2>:first-child>:first-child,.col-1>:first-child>:first-child,ul.tsd-descriptions>li>:first-child>:first-child>:first-child,.tsd-panel>:first-child>:first-child>:first-child,.col>:first-child>:first-child>:first-child,.col-11>:first-child>:first-child>:first-child,.col-10>:first-child>:first-child>:first-child,.col-9>:first-child>:first-child>:first-child,.col-8>:first-child>:first-child>:first-child,.col-7>:first-child>:first-child>:first-child,.col-6>:first-child>:first-child>:first-child,.col-5>:first-child>:first-child>:first-child,.col-4>:first-child>:first-child>:first-child,.col-3>:first-child>:first-child>:first-child,.col-2>:first-child>:first-child>:first-child,.col-1>:first-child>:first-child>:first-child{margin-top:0}ul.tsd-descriptions>li>:last-child,.tsd-panel>:last-child,.col>:last-child,.col-11>:last-child,.col-10>:last-child,.col-9>:last-child,.col-8>:last-child,.col-7>:last-child,.col-6>:last-child,.col-5>:last-child,.col-4>:last-child,.col-3>:last-child,.col-2>:last-child,.col-1>:last-child,ul.tsd-descriptions>li>:last-child>:last-child,.tsd-panel>:last-child>:last-child,.col>:last-child>:last-child,.col-11>:last-child>:last-child,.col-10>:last-child>:last-child,.col-9>:last-child>:last-child,.col-8>:last-child>:last-child,.col-7>:last-child>:last-child,.col-6>:last-child>:last-child,.col-5>:last-child>:last-child,.col-4>:last-child>:last-child,.col-3>:last-child>:last-child,.col-2>:last-child>:last-child,.col-1>:last-child>:last-child,ul.tsd-descriptions>li>:last-child>:last-child>:last-child,.tsd-panel>:last-child>:last-child>:last-child,.col>:last-child>:last-child>:last-child,.col-11>:last-child>:last-child>:last-child,.col-10>:last-child>:last-child>:last-child,.col-9>:last-child>:last-child>:last-child,.col-8>:last-child>:last-child>:last-child,.col-7>:last-child>:last-child>:last-child,.col-6>:last-child>:last-child>:last-child,.col-5>:last-child>:last-child>:last-child,.col-4>:last-child>:last-child>:last-child,.col-3>:last-child>:last-child>:last-child,.col-2>:last-child>:last-child>:last-child,.col-1>:last-child>:last-child>:last-child{margin-bottom:0}.container{max-width:1200px;margin:0 auto;padding:0 40px}@media(max-width: 640px){.container{padding:0 20px}}.container-main{padding-bottom:200px}.row{display:flex;position:relative;margin:0 -10px}.row:after{visibility:hidden;display:block;content:"";clear:both;height:0}.col,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1{box-sizing:border-box;float:left;padding:0 10px}.col-1{width:8.3333333333%}.offset-1{margin-left:8.3333333333%}.col-2{width:16.6666666667%}.offset-2{margin-left:16.6666666667%}.col-3{width:25%}.offset-3{margin-left:25%}.col-4{width:33.3333333333%}.offset-4{margin-left:33.3333333333%}.col-5{width:41.6666666667%}.offset-5{margin-left:41.6666666667%}.col-6{width:50%}.offset-6{margin-left:50%}.col-7{width:58.3333333333%}.offset-7{margin-left:58.3333333333%}.col-8{width:66.6666666667%}.offset-8{margin-left:66.6666666667%}.col-9{width:75%}.offset-9{margin-left:75%}.col-10{width:83.3333333333%}.offset-10{margin-left:83.3333333333%}.col-11{width:91.6666666667%}.offset-11{margin-left:91.6666666667%}.tsd-kind-icon{display:block;position:relative;padding-left:20px;text-indent:-20px}.tsd-kind-icon:before{content:"";display:inline-block;vertical-align:middle;width:17px;height:17px;margin:0 3px 2px 0;background-image:url(data:image/png;base64,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)}@media(-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 144dpi){.tsd-kind-icon:before{background-image:url(data:image/png;base64,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);background-size:238px 204px}}.tsd-signature.tsd-kind-icon:before{background-position:0 -153px}.tsd-kind-object-literal>.tsd-kind-icon:before{background-position:0px -17px}.tsd-kind-object-literal.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -17px}.tsd-kind-object-literal.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -17px}.tsd-kind-class>.tsd-kind-icon:before{background-position:0px -34px}.tsd-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -34px}.tsd-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -34px}.tsd-kind-class.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -51px}.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -51px}.tsd-kind-class.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -51px}.tsd-kind-interface>.tsd-kind-icon:before{background-position:0px -68px}.tsd-kind-interface.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -68px}.tsd-kind-interface.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -68px}.tsd-kind-interface.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -85px}.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -85px}.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -85px}.tsd-kind-namespace>.tsd-kind-icon:before{background-position:0px -102px}.tsd-kind-namespace.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -102px}.tsd-kind-namespace.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -102px}.tsd-kind-module>.tsd-kind-icon:before{background-position:0px -102px}.tsd-kind-module.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -102px}.tsd-kind-module.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -102px}.tsd-kind-enum>.tsd-kind-icon:before{background-position:0px -119px}.tsd-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -119px}.tsd-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -119px}.tsd-kind-enum-member>.tsd-kind-icon:before{background-position:0px -136px}.tsd-kind-enum-member.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -136px}.tsd-kind-enum-member.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -136px}.tsd-kind-signature>.tsd-kind-icon:before{background-position:0px -153px}.tsd-kind-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -153px}.tsd-kind-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -153px}.tsd-kind-type-alias>.tsd-kind-icon:before{background-position:0px -170px}.tsd-kind-type-alias.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -170px}.tsd-kind-type-alias.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -170px}.tsd-kind-type-alias.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -187px}.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -187px}.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -187px}.tsd-kind-variable>.tsd-kind-icon:before{background-position:-136px -0px}.tsd-kind-variable.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -0px}.tsd-kind-variable.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -0px}.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -0px}.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -0px}.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -0px}.tsd-kind-property>.tsd-kind-icon:before{background-position:-136px -0px}.tsd-kind-property.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -0px}.tsd-kind-property.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -0px}.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -0px}.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -0px}.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -0px}.tsd-kind-get-signature>.tsd-kind-icon:before{background-position:-136px -17px}.tsd-kind-get-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -17px}.tsd-kind-get-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -17px}.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -17px}.tsd-kind-set-signature>.tsd-kind-icon:before{background-position:-136px -34px}.tsd-kind-set-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -34px}.tsd-kind-set-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -34px}.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -34px}.tsd-kind-accessor>.tsd-kind-icon:before{background-position:-136px -51px}.tsd-kind-accessor.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -51px}.tsd-kind-accessor.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -51px}.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -51px}.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -51px}.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -51px}.tsd-kind-function>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-function.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-function.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-method>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-method.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-method.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-call-signature>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-call-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-call-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-function.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:-136px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -85px}.tsd-kind-method.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:-136px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -85px}.tsd-kind-constructor>.tsd-kind-icon:before{background-position:-136px -102px}.tsd-kind-constructor.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -102px}.tsd-kind-constructor.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -102px}.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -102px}.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -102px}.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -102px}.tsd-kind-constructor-signature>.tsd-kind-icon:before{background-position:-136px -102px}.tsd-kind-constructor-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -102px}.tsd-kind-constructor-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -102px}.tsd-kind-index-signature>.tsd-kind-icon:before{background-position:-136px -119px}.tsd-kind-index-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -119px}.tsd-kind-index-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -119px}.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -119px}.tsd-kind-event>.tsd-kind-icon:before{background-position:-136px -136px}.tsd-kind-event.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -136px}.tsd-kind-event.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -136px}.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -136px}.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -136px}.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -136px}.tsd-is-static>.tsd-kind-icon:before{background-position:-136px -153px}.tsd-is-static.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -153px}.tsd-is-static.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -153px}.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -153px}.tsd-is-static.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -153px}.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -153px}.tsd-is-static.tsd-kind-function>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-function.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-function.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-method>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-method.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-method.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-call-signature>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-event>.tsd-kind-icon:before{background-position:-136px -187px}.tsd-is-static.tsd-kind-event.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -187px}.tsd-is-static.tsd-kind-event.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -187px}@keyframes fade-in{from{opacity:0}to{opacity:1}}@keyframes fade-out{from{opacity:1;visibility:visible}to{opacity:0}}@keyframes fade-in-delayed{0%{opacity:0}33%{opacity:0}100%{opacity:1}}@keyframes fade-out-delayed{0%{opacity:1;visibility:visible}66%{opacity:0}100%{opacity:0}}@keyframes shift-to-left{from{transform:translate(0, 0)}to{transform:translate(-25%, 0)}}@keyframes unshift-to-left{from{transform:translate(-25%, 0)}to{transform:translate(0, 0)}}@keyframes pop-in-from-right{from{transform:translate(100%, 0)}to{transform:translate(0, 0)}}@keyframes pop-out-to-right{from{transform:translate(0, 0);visibility:visible}to{transform:translate(100%, 0)}}body{background:#fdfdfd;font-family:"Segoe UI",sans-serif;font-size:16px;color:#222}a{color:#4da6ff;text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;padding:.2em;margin:0;font-size:14px;background-color:rgba(0,0,0,.04)}pre{padding:10px}pre code{padding:0;font-size:100%;background-color:transparent}.tsd-typography{line-height:1.333em}.tsd-typography ul{list-style:square;padding:0 0 0 20px;margin:0}.tsd-typography h4,.tsd-typography .tsd-index-panel h3,.tsd-index-panel .tsd-typography h3,.tsd-typography h5,.tsd-typography h6{font-size:1em;margin:0}.tsd-typography h5,.tsd-typography h6{font-weight:normal}.tsd-typography p,.tsd-typography ul,.tsd-typography ol{margin:1em 0}@media(min-width: 901px)and (max-width: 1024px){html.default .col-content{width:72%}html.default .col-menu{width:28%}html.default .tsd-navigation{padding-left:10px}}@media(max-width: 900px){html.default .col-content{float:none;width:100%}html.default .col-menu{position:fixed !important;overflow:auto;-webkit-overflow-scrolling:touch;z-index:1024;top:0 !important;bottom:0 !important;left:auto !important;right:0 !important;width:100%;padding:20px 20px 0 0;max-width:450px;visibility:hidden;background-color:#fff;transform:translate(100%, 0)}html.default .col-menu>*:last-child{padding-bottom:20px}html.default .overlay{content:"";display:block;position:fixed;z-index:1023;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.75);visibility:hidden}html.default.to-has-menu .overlay{animation:fade-in .4s}html.default.to-has-menu header,html.default.to-has-menu footer,html.default.to-has-menu .col-content{animation:shift-to-left .4s}html.default.to-has-menu .col-menu{animation:pop-in-from-right .4s}html.default.from-has-menu .overlay{animation:fade-out .4s}html.default.from-has-menu header,html.default.from-has-menu footer,html.default.from-has-menu .col-content{animation:unshift-to-left .4s}html.default.from-has-menu .col-menu{animation:pop-out-to-right .4s}html.default.has-menu body{overflow:hidden}html.default.has-menu .overlay{visibility:visible}html.default.has-menu header,html.default.has-menu footer,html.default.has-menu .col-content{transform:translate(-25%, 0)}html.default.has-menu .col-menu{visibility:visible;transform:translate(0, 0)}}.tsd-page-title{padding:70px 0 20px 0;margin:0 0 40px 0;background:#fff;box-shadow:0 0 5px rgba(0,0,0,.35)}.tsd-page-title h1{margin:0}.tsd-breadcrumb{margin:0;padding:0;color:#707070}.tsd-breadcrumb a{color:#707070;text-decoration:none}.tsd-breadcrumb a:hover{text-decoration:underline}.tsd-breadcrumb li{display:inline}.tsd-breadcrumb li:after{content:" / "}html.minimal .container{margin:0}html.minimal .container-main{padding-top:50px;padding-bottom:0}html.minimal .content-wrap{padding-left:300px}html.minimal .tsd-navigation{position:fixed !important;overflow:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box;z-index:1;left:0;top:40px;bottom:0;width:300px;padding:20px;margin:0}html.minimal .tsd-member .tsd-member{margin-left:0}html.minimal .tsd-page-toolbar{position:fixed;z-index:2}html.minimal #tsd-filter .tsd-filter-group{right:0;transform:none}html.minimal footer{background-color:transparent}html.minimal footer .container{padding:0}html.minimal .tsd-generator{padding:0}@media(max-width: 900px){html.minimal .tsd-navigation{display:none}html.minimal .content-wrap{padding-left:0}}dl.tsd-comment-tags{overflow:hidden}dl.tsd-comment-tags dt{float:left;padding:1px 5px;margin:0 10px 0 0;border-radius:4px;border:1px solid #707070;color:#707070;font-size:.8em;font-weight:normal}dl.tsd-comment-tags dd{margin:0 0 10px 0}dl.tsd-comment-tags dd:before,dl.tsd-comment-tags dd:after{display:table;content:" "}dl.tsd-comment-tags dd pre,dl.tsd-comment-tags dd:after{clear:both}dl.tsd-comment-tags p{margin:0}.tsd-panel.tsd-comment .lead{font-size:1.1em;line-height:1.333em;margin-bottom:2em}.tsd-panel.tsd-comment .lead:last-child{margin-bottom:0}.toggle-protected .tsd-is-private{display:none}.toggle-public .tsd-is-private,.toggle-public .tsd-is-protected,.toggle-public .tsd-is-private-protected{display:none}.toggle-inherited .tsd-is-inherited{display:none}.toggle-only-exported .tsd-is-not-exported{display:none}.toggle-externals .tsd-is-external{display:none}#tsd-filter{position:relative;display:inline-block;height:40px;vertical-align:bottom}.no-filter #tsd-filter{display:none}#tsd-filter .tsd-filter-group{display:inline-block;height:40px;vertical-align:bottom;white-space:nowrap}#tsd-filter input{display:none}@media(max-width: 900px){#tsd-filter .tsd-filter-group{display:block;position:absolute;top:40px;right:20px;height:auto;background-color:#fff;visibility:hidden;transform:translate(50%, 0);box-shadow:0 0 4px rgba(0,0,0,.25)}.has-options #tsd-filter .tsd-filter-group{visibility:visible}.to-has-options #tsd-filter .tsd-filter-group{animation:fade-in .2s}.from-has-options #tsd-filter .tsd-filter-group{animation:fade-out .2s}#tsd-filter label,#tsd-filter .tsd-select{display:block;padding-right:20px}}footer{border-top:1px solid #eee;background-color:#fff}footer.with-border-bottom{border-bottom:1px solid #eee}footer .tsd-legend-group{font-size:0}footer .tsd-legend{display:inline-block;width:25%;padding:0;font-size:16px;list-style:none;line-height:1.333em;vertical-align:top}@media(max-width: 900px){footer .tsd-legend{width:50%}}.tsd-hierarchy{list-style:square;padding:0 0 0 20px;margin:0}.tsd-hierarchy .target{font-weight:bold}.tsd-index-panel .tsd-index-content{margin-bottom:-30px !important}.tsd-index-panel .tsd-index-section{margin-bottom:30px !important}.tsd-index-panel h3{margin:0 -20px 10px -20px;padding:0 20px 10px 20px;border-bottom:1px solid #eee}.tsd-index-panel ul.tsd-index-list{-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3;-webkit-column-gap:20px;-moz-column-gap:20px;-ms-column-gap:20px;-o-column-gap:20px;column-gap:20px;padding:0;list-style:none;line-height:1.333em}@media(max-width: 900px){.tsd-index-panel ul.tsd-index-list{-webkit-column-count:1;-moz-column-count:1;-ms-column-count:1;-o-column-count:1;column-count:1}}@media(min-width: 901px)and (max-width: 1024px){.tsd-index-panel ul.tsd-index-list{-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}}.tsd-index-panel ul.tsd-index-list li{-webkit-page-break-inside:avoid;-moz-page-break-inside:avoid;-ms-page-break-inside:avoid;-o-page-break-inside:avoid;page-break-inside:avoid}.tsd-index-panel a,.tsd-index-panel .tsd-parent-kind-module a{color:#9600ff}.tsd-index-panel .tsd-parent-kind-interface a{color:#647f1b}.tsd-index-panel .tsd-parent-kind-enum a{color:#937210}.tsd-index-panel .tsd-parent-kind-class a{color:#0672de}.tsd-index-panel .tsd-kind-module a{color:#9600ff}.tsd-index-panel .tsd-kind-interface a{color:#647f1b}.tsd-index-panel .tsd-kind-enum a{color:#937210}.tsd-index-panel .tsd-kind-class a{color:#0672de}.tsd-index-panel .tsd-is-private a{color:#707070}.tsd-flag{display:inline-block;padding:1px 5px;border-radius:4px;color:#fff;background-color:#707070;text-indent:0;font-size:14px;font-weight:normal}.tsd-anchor{position:absolute;top:-100px}.tsd-member{position:relative}.tsd-member .tsd-anchor+h3{margin-top:0;margin-bottom:0;border-bottom:none}.tsd-navigation{margin:0 0 0 40px}.tsd-navigation a{display:block;padding-top:2px;padding-bottom:2px;border-left:2px solid transparent;color:#222;text-decoration:none;transition:border-left-color .1s}.tsd-navigation a:hover{text-decoration:underline}.tsd-navigation ul{margin:0;padding:0;list-style:none}.tsd-navigation li{padding:0}.tsd-navigation.primary{padding-bottom:40px}.tsd-navigation.primary a{display:block;padding-top:6px;padding-bottom:6px}.tsd-navigation.primary ul li a{padding-left:5px}.tsd-navigation.primary ul li li a{padding-left:25px}.tsd-navigation.primary ul li li li a{padding-left:45px}.tsd-navigation.primary ul li li li li a{padding-left:65px}.tsd-navigation.primary ul li li li li li a{padding-left:85px}.tsd-navigation.primary ul li li li li li li a{padding-left:105px}.tsd-navigation.primary>ul{border-bottom:1px solid #eee}.tsd-navigation.primary li{border-top:1px solid #eee}.tsd-navigation.primary li.current>a{font-weight:bold}.tsd-navigation.primary li.label span{display:block;padding:20px 0 6px 5px;color:#707070}.tsd-navigation.primary li.globals+li>span,.tsd-navigation.primary li.globals+li>a{padding-top:20px}.tsd-navigation.secondary{max-height:calc(100vh - 1rem - 40px);overflow:auto;position:-webkit-sticky;position:sticky;top:calc(.5rem + 40px);transition:.3s}.tsd-navigation.secondary.tsd-navigation--toolbar-hide{max-height:calc(100vh - 1rem);top:.5rem}.tsd-navigation.secondary ul{transition:opacity .2s}.tsd-navigation.secondary ul li a{padding-left:25px}.tsd-navigation.secondary ul li li a{padding-left:45px}.tsd-navigation.secondary ul li li li a{padding-left:65px}.tsd-navigation.secondary ul li li li li a{padding-left:85px}.tsd-navigation.secondary ul li li li li li a{padding-left:105px}.tsd-navigation.secondary ul li li li li li li a{padding-left:125px}.tsd-navigation.secondary ul.current a{border-left-color:#eee}.tsd-navigation.secondary li.focus>a,.tsd-navigation.secondary ul.current li.focus>a{border-left-color:#000}.tsd-navigation.secondary li.current{margin-top:20px;margin-bottom:20px;border-left-color:#eee}.tsd-navigation.secondary li.current>a{font-weight:bold}@media(min-width: 901px){.menu-sticky-wrap{position:static}}.tsd-panel{margin:20px 0;padding:20px;background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.25)}.tsd-panel:empty{display:none}.tsd-panel>h1,.tsd-panel>h2,.tsd-panel>h3{margin:1.5em -20px 10px -20px;padding:0 20px 10px 20px;border-bottom:1px solid #eee}.tsd-panel>h1.tsd-before-signature,.tsd-panel>h2.tsd-before-signature,.tsd-panel>h3.tsd-before-signature{margin-bottom:0;border-bottom:0}.tsd-panel table{display:block;width:100%;overflow:auto;margin-top:10px;word-break:normal;word-break:keep-all}.tsd-panel table th{font-weight:bold}.tsd-panel table th,.tsd-panel table td{padding:6px 13px;border:1px solid #ddd}.tsd-panel table tr{background-color:#fff;border-top:1px solid #ccc}.tsd-panel table tr:nth-child(2n){background-color:#f8f8f8}.tsd-panel-group{margin:60px 0}.tsd-panel-group>h1,.tsd-panel-group>h2,.tsd-panel-group>h3{padding-left:20px;padding-right:20px}#tsd-search{transition:background-color .2s}#tsd-search .title{position:relative;z-index:2}#tsd-search .field{position:absolute;left:0;top:0;right:40px;height:40px}#tsd-search .field input{box-sizing:border-box;position:relative;top:-50px;z-index:1;width:100%;padding:0 10px;opacity:0;outline:0;border:0;background:transparent;color:#222}#tsd-search .field label{position:absolute;overflow:hidden;right:-40px}#tsd-search .field input,#tsd-search .title{transition:opacity .2s}#tsd-search .results{position:absolute;visibility:hidden;top:40px;width:100%;margin:0;padding:0;list-style:none;box-shadow:0 0 4px rgba(0,0,0,.25)}#tsd-search .results li{padding:0 10px;background-color:#fdfdfd}#tsd-search .results li:nth-child(even){background-color:#fff}#tsd-search .results li.state{display:none}#tsd-search .results li.current,#tsd-search .results li:hover{background-color:#eee}#tsd-search .results a{display:block}#tsd-search .results a:before{top:10px}#tsd-search .results span.parent{color:#707070;font-weight:normal}#tsd-search.has-focus{background-color:#eee}#tsd-search.has-focus .field input{top:0;opacity:1}#tsd-search.has-focus .title{z-index:0;opacity:0}#tsd-search.has-focus .results{visibility:visible}#tsd-search.loading .results li.state.loading{display:block}#tsd-search.failure .results li.state.failure{display:block}.tsd-signature{margin:0 0 1em 0;padding:10px;border:1px solid #eee;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:14px;overflow-x:auto}.tsd-signature.tsd-kind-icon{padding-left:30px}.tsd-signature.tsd-kind-icon:before{top:10px;left:10px}.tsd-panel>.tsd-signature{margin-left:-20px;margin-right:-20px;border-width:1px 0}.tsd-panel>.tsd-signature.tsd-kind-icon{padding-left:40px}.tsd-panel>.tsd-signature.tsd-kind-icon:before{left:20px}.tsd-signature-symbol{color:#707070;font-weight:normal}.tsd-signature-type{font-style:italic;font-weight:normal}.tsd-signatures{padding:0;margin:0 0 1em 0;border:1px solid #eee}.tsd-signatures .tsd-signature{margin:0;border-width:1px 0 0 0;transition:background-color .1s}.tsd-signatures .tsd-signature:first-child{border-top-width:0}.tsd-signatures .tsd-signature.current{background-color:#eee}.tsd-signatures.active>.tsd-signature{cursor:pointer}.tsd-panel>.tsd-signatures{margin-left:-20px;margin-right:-20px;border-width:1px 0}.tsd-panel>.tsd-signatures .tsd-signature.tsd-kind-icon{padding-left:40px}.tsd-panel>.tsd-signatures .tsd-signature.tsd-kind-icon:before{left:20px}.tsd-panel>a.anchor+.tsd-signatures{border-top-width:0;margin-top:-20px}ul.tsd-descriptions{position:relative;overflow:hidden;padding:0;list-style:none}ul.tsd-descriptions.active>.tsd-description{display:none}ul.tsd-descriptions.active>.tsd-description.current{display:block}ul.tsd-descriptions.active>.tsd-description.fade-in{animation:fade-in-delayed .3s}ul.tsd-descriptions.active>.tsd-description.fade-out{animation:fade-out-delayed .3s;position:absolute;display:block;top:0;left:0;right:0;opacity:0;visibility:hidden}ul.tsd-descriptions h4,ul.tsd-descriptions .tsd-index-panel h3,.tsd-index-panel ul.tsd-descriptions h3{font-size:16px;margin:1em 0 .5em 0}ul.tsd-parameters,ul.tsd-type-parameters{list-style:square;margin:0;padding-left:20px}ul.tsd-parameters>li.tsd-parameter-signature,ul.tsd-type-parameters>li.tsd-parameter-signature{list-style:none;margin-left:-20px}ul.tsd-parameters h5,ul.tsd-type-parameters h5{font-size:16px;margin:1em 0 .5em 0}ul.tsd-parameters .tsd-comment,ul.tsd-type-parameters .tsd-comment{margin-top:-0.5em}.tsd-sources{font-size:14px;color:#707070;margin:0 0 1em 0}.tsd-sources a{color:#707070;text-decoration:underline}.tsd-sources ul,.tsd-sources p{margin:0 !important}.tsd-sources ul{list-style:none;padding:0}.tsd-page-toolbar{position:fixed;z-index:1;top:0;left:0;width:100%;height:40px;color:#333;background:#fff;border-bottom:1px solid #eee;transition:transform .3s linear}.tsd-page-toolbar a{color:#333;text-decoration:none}.tsd-page-toolbar a.title{font-weight:bold}.tsd-page-toolbar a.title:hover{text-decoration:underline}.tsd-page-toolbar .table-wrap{display:table;width:100%;height:40px}.tsd-page-toolbar .table-cell{display:table-cell;position:relative;white-space:nowrap;line-height:40px}.tsd-page-toolbar .table-cell:first-child{width:100%}.tsd-page-toolbar--hide{transform:translateY(-100%)}.tsd-select .tsd-select-list li:before,.tsd-select .tsd-select-label:before,.tsd-widget:before{content:"";display:inline-block;width:40px;height:40px;margin:0 -8px 0 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAoCAQAAAAlSeuiAAABp0lEQVR4Ae3aUa3jQAyF4QNhIBTCQiiEQlgIhRAGhTAQBkIgBEIgDITZZGXNjZTePiSWYqn/54dGfbAq+SiTutWXAgAAAAAAAAAAAAA8NCz1UFSD2lKDS5d3NVzZj/BVNasaLoRZRUmj2lLrVVHWMUntQ13Wj/i1pWa9lprX6xMRnH4dx6Rjsn26+v+12ms+EcB37P0r+qH+DNQGXgMFcHzbregQ78B8eQCTJk0e979ZW7PdA2O49ceDsYexKgUNoI3EKYDWL3D8miaPh/uXtl6BHqEHFQvgXau/FsCiIWAAbST2fpQRT0sl70j3z5ZiBdD7CG5WZX8kxwmgjbiP5GQA9/3O2XaxnnHi53AEE0AbRh+JQwC3/fzC4hcb6xPvS4i3QaMdwX+0utsRPEY6gm2wNhKHAG77eUi7SIcK4G4NY4GMIan2u2Cxqzncl5DUn7Q8ArjvZ8JFOsl/Ed0jyBom+BomQKSto+9PcblHMM4iuu4X0QQw5hrGQY/gUxFkjZuf4m4alXVU+1De/VhEn5CvDSB/RsBzqWgAAAAAAAAAAAAAAACAfyyYJ5nhVuwIAAAAAElFTkSuQmCC);background-repeat:no-repeat;text-indent:-1024px;vertical-align:bottom}@media(-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 144dpi){.tsd-select .tsd-select-list li:before,.tsd-select .tsd-select-label:before,.tsd-widget:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAABQCAMAAAC+sjQXAAAAM1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjBUbJAAAAEXRSTlMA3/+/UCBw7xCPYIBAMM+vn1qYQ7QAAALCSURBVHgB7MGBAAAAAICg/akXqQIAAAAAAAAAAAAAAAAAAJids9mdE4bhoDNZCITP93/aSmhV/9uwPWyi8jtkblws2IxsYpz9LwSAaJW8AreE16PxOsMYE6Q4DiYKF7X+8ZHXc/E608xv5snEyIuZrVwMZjbnujR6T3gsXmcLOIRNzD+Ig2UuVtt2+NbAiX/wVLzOlviD9L2BOfGBlL/3D1I+uDjGBJArBPxU3x+K15kCQFo2s21JAOHrKpz4SPrWv4IKA+uFaR6vMwMcb+emA2DWEfDglrkLqEBOKVslA8Dx14oPMiV4CtywWxdQgAwkq2QE0uTXUwJGk2G9s3mTFNBzAkC7HKPsX72AEVjMnAWIpsPCRRjXdQxcjCYpoOcEgHY5Rtk/slWSgM3M2aSeeVgjAOeVpKcdgGMdNAXMuIAqOcZzqF8L+WcAsi8wkTeheCWMegL6mgCorHHyEJ5TVfxrLWDrTUjZdhnhjYqAnlN8TaoELOLVC0gucmoz/3RKcPs2jAs4+J5ET8AEZF+TSgGLeC1V8YuGQQU2IV1Asq9JCwE9XitZVPxr34bpJRj8PqsFLOK108W9aVrWZRrR7Sm2HL4JCToCujHZ6gUs4jUz0P1TEvD+U5wMa363YeziBODIq1YbJrsv9QKW8Ry1nNp+GAHvuingRTfmYcjBf0QpAS37bdUL6PFKtHJq63EsZ5cxcKMkDVIClu1dAK1PcJ5TFQ0M9wZKDCPs3BD7MIJGTs3WfiTfDVQYx5q5ZekCauTU3P5Q0ukGCgh49oFURdobWBY9N/CxEuwGjpGLuPhTdwH1x7HqDDxNgRP2zQ8lraFyF/yJ9vH6QGqtgSbBOU8/j2VORz+Wqfle2d5Ae4R+ML0z7Y+W4P7XHN3AU+tzyK/24EAGAAAAYJC/9T2+CgAAAAAAAAAAAAAAAAAAAADgJpfzHyIKFFBKAAAAAElFTkSuQmCC);background-size:320px 40px}}.tsd-widget{display:inline-block;overflow:hidden;opacity:.6;height:40px;transition:opacity .1s,background-color .2s;vertical-align:bottom;cursor:pointer}.tsd-widget:hover{opacity:.8}.tsd-widget.active{opacity:1;background-color:#eee}.tsd-widget.no-caption{width:40px}.tsd-widget.no-caption:before{margin:0}.tsd-widget.search:before{background-position:0 0}.tsd-widget.menu:before{background-position:-40px 0}.tsd-widget.options:before{background-position:-80px 0}.tsd-widget.options,.tsd-widget.menu{display:none}@media(max-width: 900px){.tsd-widget.options,.tsd-widget.menu{display:inline-block}}input[type=checkbox]+.tsd-widget:before{background-position:-120px 0}input[type=checkbox]:checked+.tsd-widget:before{background-position:-160px 0}.tsd-select{position:relative;display:inline-block;height:40px;transition:opacity .1s,background-color .2s;vertical-align:bottom;cursor:pointer}.tsd-select .tsd-select-label{opacity:.6;transition:opacity .2s}.tsd-select .tsd-select-label:before{background-position:-240px 0}.tsd-select.active .tsd-select-label{opacity:.8}.tsd-select.active .tsd-select-list{visibility:visible;opacity:1;transition-delay:0s}.tsd-select .tsd-select-list{position:absolute;visibility:hidden;top:40px;left:0;margin:0;padding:0;opacity:0;list-style:none;box-shadow:0 0 4px rgba(0,0,0,.25);transition:visibility 0s .2s,opacity .2s}.tsd-select .tsd-select-list li{padding:0 20px 0 0;background-color:#fdfdfd}.tsd-select .tsd-select-list li:before{background-position:40px 0}.tsd-select .tsd-select-list li:nth-child(even){background-color:#fff}.tsd-select .tsd-select-list li:hover{background-color:#eee}.tsd-select .tsd-select-list li.selected:before{background-position:-200px 0}@media(max-width: 900px){.tsd-select .tsd-select-list{top:0;left:auto;right:100%;margin-right:-5px}.tsd-select .tsd-select-label:before{background-position:-280px 0}}img{max-width:100%} diff --git a/docs/api/assets/js/main.js b/docs/api/assets/js/main.js index 6be660f..c2190a9 100644 --- a/docs/api/assets/js/main.js +++ b/docs/api/assets/js/main.js @@ -1,2280 +1,51 @@ -!(function (e) { - var t = {} - function r(n) { - if (t[n]) return t[n].exports - var i = (t[n] = { i: n, l: !1, exports: {} }) - return e[n].call(i.exports, i, i.exports, r), (i.l = !0), i.exports - } - ;(r.m = e), - (r.c = t), - (r.d = function (e, t, n) { - r.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: n }) - }), - (r.r = function (e) { - "undefined" != typeof Symbol && - Symbol.toStringTag && - Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), - Object.defineProperty(e, "__esModule", { value: !0 }) - }), - (r.t = function (e, t) { - if ((1 & t && (e = r(e)), 8 & t)) return e - if (4 & t && "object" == typeof e && e && e.__esModule) return e - var n = Object.create(null) - if ( - (r.r(n), - Object.defineProperty(n, "default", { enumerable: !0, value: e }), - 2 & t && "string" != typeof e) - ) - for (var i in e) - r.d( - n, - i, - function (t) { - return e[t] - }.bind(null, i) - ) - return n - }), - (r.n = function (e) { - var t = - e && e.__esModule - ? function () { - return e.default - } - : function () { - return e - } - return r.d(t, "a", t), t - }), - (r.o = function (e, t) { - return Object.prototype.hasOwnProperty.call(e, t) - }), - (r.p = ""), - r((r.s = 2)) -})([ - function (e, t, r) { - var n, i - /** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - */ !(function () { - var s, - o, - a, - u, - l, - c, - h, - d, - f, - p, - y, - m, - v, - g, - x, - w, - L, - E, - b, - S, - k, - Q, - O, - P, - T, - _, - C = function (e) { - var t = new C.Builder() - return ( - t.pipeline.add(C.trimmer, C.stopWordFilter, C.stemmer), - t.searchPipeline.add(C.stemmer), - e.call(t, t), - t.build() - ) - } - ;(C.version = "2.3.9"), - /*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - */ (C.utils = {}), - (C.utils.warn = - ((s = this), - function (e) { - s.console && console.warn && console.warn(e) - })), - (C.utils.asString = function (e) { - return null == e ? "" : e.toString() - }), - (C.utils.clone = function (e) { - if (null == e) return e - for (var t = Object.create(null), r = Object.keys(e), n = 0; n < r.length; n++) { - var i = r[n], - s = e[i] - if (Array.isArray(s)) t[i] = s.slice() - else { - if ("string" != typeof s && "number" != typeof s && "boolean" != typeof s) - throw new TypeError("clone is not deep and does not support nested objects") - t[i] = s - } - } - return t - }), - (C.FieldRef = function (e, t, r) { - ;(this.docRef = e), (this.fieldName = t), (this._stringValue = r) - }), - (C.FieldRef.joiner = "/"), - (C.FieldRef.fromString = function (e) { - var t = e.indexOf(C.FieldRef.joiner) - if (-1 === t) throw "malformed field ref string" - var r = e.slice(0, t), - n = e.slice(t + 1) - return new C.FieldRef(n, r, e) - }), - (C.FieldRef.prototype.toString = function () { - return ( - null == this._stringValue && - (this._stringValue = this.fieldName + C.FieldRef.joiner + this.docRef), - this._stringValue - ) - }), - /*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - */ (C.Set = function (e) { - if (((this.elements = Object.create(null)), e)) { - this.length = e.length - for (var t = 0; t < this.length; t++) this.elements[e[t]] = !0 - } else this.length = 0 - }), - (C.Set.complete = { - intersect: function (e) { - return e - }, - union: function () { - return this - }, - contains: function () { - return !0 - } - }), - (C.Set.empty = { - intersect: function () { - return this - }, - union: function (e) { - return e - }, - contains: function () { - return !1 - } - }), - (C.Set.prototype.contains = function (e) { - return !!this.elements[e] - }), - (C.Set.prototype.intersect = function (e) { - var t, - r, - n, - i = [] - if (e === C.Set.complete) return this - if (e === C.Set.empty) return e - this.length < e.length ? ((t = this), (r = e)) : ((t = e), (r = this)), - (n = Object.keys(t.elements)) - for (var s = 0; s < n.length; s++) { - var o = n[s] - o in r.elements && i.push(o) - } - return new C.Set(i) - }), - (C.Set.prototype.union = function (e) { - return e === C.Set.complete - ? C.Set.complete - : e === C.Set.empty - ? this - : new C.Set(Object.keys(this.elements).concat(Object.keys(e.elements))) - }), - (C.idf = function (e, t) { - var r = 0 - for (var n in e) "_index" != n && (r += Object.keys(e[n]).length) - var i = (t - r + 0.5) / (r + 0.5) - return Math.log(1 + Math.abs(i)) - }), - (C.Token = function (e, t) { - ;(this.str = e || ""), (this.metadata = t || {}) - }), - (C.Token.prototype.toString = function () { - return this.str - }), - (C.Token.prototype.update = function (e) { - return (this.str = e(this.str, this.metadata)), this - }), - (C.Token.prototype.clone = function (e) { - return ( - (e = - e || - function (e) { - return e - }), - new C.Token(e(this.str, this.metadata), this.metadata) - ) - }), - /*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - */ (C.tokenizer = function (e, t) { - if (null == e || null == e) return [] - if (Array.isArray(e)) - return e.map(function (e) { - return new C.Token(C.utils.asString(e).toLowerCase(), C.utils.clone(t)) - }) - for ( - var r = e.toString().toLowerCase(), n = r.length, i = [], s = 0, o = 0; - s <= n; - s++ - ) { - var a = s - o - if (r.charAt(s).match(C.tokenizer.separator) || s == n) { - if (a > 0) { - var u = C.utils.clone(t) || {} - ;(u.position = [o, a]), (u.index = i.length), i.push(new C.Token(r.slice(o, s), u)) - } - o = s + 1 - } - } - return i - }), - (C.tokenizer.separator = /[\s\-]+/), - /*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - */ (C.Pipeline = function () { - this._stack = [] - }), - (C.Pipeline.registeredFunctions = Object.create(null)), - (C.Pipeline.registerFunction = function (e, t) { - t in this.registeredFunctions && - C.utils.warn("Overwriting existing registered function: " + t), - (e.label = t), - (C.Pipeline.registeredFunctions[e.label] = e) - }), - (C.Pipeline.warnIfFunctionNotRegistered = function (e) { - ;(e.label && e.label in this.registeredFunctions) || - C.utils.warn( - "Function is not registered with pipeline. This may cause problems when serialising the index.\n", - e - ) - }), - (C.Pipeline.load = function (e) { - var t = new C.Pipeline() - return ( - e.forEach(function (e) { - var r = C.Pipeline.registeredFunctions[e] - if (!r) throw new Error("Cannot load unregistered function: " + e) - t.add(r) - }), - t - ) - }), - (C.Pipeline.prototype.add = function () { - var e = Array.prototype.slice.call(arguments) - e.forEach(function (e) { - C.Pipeline.warnIfFunctionNotRegistered(e), this._stack.push(e) - }, this) - }), - (C.Pipeline.prototype.after = function (e, t) { - C.Pipeline.warnIfFunctionNotRegistered(t) - var r = this._stack.indexOf(e) - if (-1 == r) throw new Error("Cannot find existingFn") - ;(r += 1), this._stack.splice(r, 0, t) - }), - (C.Pipeline.prototype.before = function (e, t) { - C.Pipeline.warnIfFunctionNotRegistered(t) - var r = this._stack.indexOf(e) - if (-1 == r) throw new Error("Cannot find existingFn") - this._stack.splice(r, 0, t) - }), - (C.Pipeline.prototype.remove = function (e) { - var t = this._stack.indexOf(e) - ;-1 != t && this._stack.splice(t, 1) - }), - (C.Pipeline.prototype.run = function (e) { - for (var t = this._stack.length, r = 0; r < t; r++) { - for (var n = this._stack[r], i = [], s = 0; s < e.length; s++) { - var o = n(e[s], s, e) - if (null != o && "" !== o) - if (Array.isArray(o)) for (var a = 0; a < o.length; a++) i.push(o[a]) - else i.push(o) - } - e = i - } - return e - }), - (C.Pipeline.prototype.runString = function (e, t) { - var r = new C.Token(e, t) - return this.run([r]).map(function (e) { - return e.toString() - }) - }), - (C.Pipeline.prototype.reset = function () { - this._stack = [] - }), - (C.Pipeline.prototype.toJSON = function () { - return this._stack.map(function (e) { - return C.Pipeline.warnIfFunctionNotRegistered(e), e.label - }) - }), - /*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - */ (C.Vector = function (e) { - ;(this._magnitude = 0), (this.elements = e || []) - }), - (C.Vector.prototype.positionForIndex = function (e) { - if (0 == this.elements.length) return 0 - for ( - var t = 0, - r = this.elements.length / 2, - n = r - t, - i = Math.floor(n / 2), - s = this.elements[2 * i]; - n > 1 && (s < e && (t = i), s > e && (r = i), s != e); - - ) - (n = r - t), (i = t + Math.floor(n / 2)), (s = this.elements[2 * i]) - return s == e || s > e ? 2 * i : s < e ? 2 * (i + 1) : void 0 - }), - (C.Vector.prototype.insert = function (e, t) { - this.upsert(e, t, function () { - throw "duplicate index" - }) - }), - (C.Vector.prototype.upsert = function (e, t, r) { - this._magnitude = 0 - var n = this.positionForIndex(e) - this.elements[n] == e - ? (this.elements[n + 1] = r(this.elements[n + 1], t)) - : this.elements.splice(n, 0, e, t) - }), - (C.Vector.prototype.magnitude = function () { - if (this._magnitude) return this._magnitude - for (var e = 0, t = this.elements.length, r = 1; r < t; r += 2) { - var n = this.elements[r] - e += n * n - } - return (this._magnitude = Math.sqrt(e)) - }), - (C.Vector.prototype.dot = function (e) { - for ( - var t = 0, - r = this.elements, - n = e.elements, - i = r.length, - s = n.length, - o = 0, - a = 0, - u = 0, - l = 0; - u < i && l < s; - - ) - (o = r[u]) < (a = n[l]) - ? (u += 2) - : o > a - ? (l += 2) - : o == a && ((t += r[u + 1] * n[l + 1]), (u += 2), (l += 2)) - return t - }), - (C.Vector.prototype.similarity = function (e) { - return this.dot(e) / this.magnitude() || 0 - }), - (C.Vector.prototype.toArray = function () { - for ( - var e = new Array(this.elements.length / 2), t = 1, r = 0; - t < this.elements.length; - t += 2, r++ - ) - e[r] = this.elements[t] - return e - }), - (C.Vector.prototype.toJSON = function () { - return this.elements - }), - /*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ (C.stemmer = - ((o = { - ational: "ate", - tional: "tion", - enci: "ence", - anci: "ance", - izer: "ize", - bli: "ble", - alli: "al", - entli: "ent", - eli: "e", - ousli: "ous", - ization: "ize", - ation: "ate", - ator: "ate", - alism: "al", - iveness: "ive", - fulness: "ful", - ousness: "ous", - aliti: "al", - iviti: "ive", - biliti: "ble", - logi: "log" - }), - (a = { icate: "ic", ative: "", alize: "al", iciti: "ic", ical: "ic", ful: "", ness: "" }), - (u = "[aeiouy]"), - (l = "[^aeiou][^aeiouy]*"), - (c = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*")), - (h = new RegExp( - "^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*[aeiouy][aeiou]*[^aeiou][^aeiouy]*" - )), - (d = new RegExp( - "^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*([aeiouy][aeiou]*)?$" - )), - (f = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy]")), - (p = /^(.+?)(ss|i)es$/), - (y = /^(.+?)([^s])s$/), - (m = /^(.+?)eed$/), - (v = /^(.+?)(ed|ing)$/), - (g = /.$/), - (x = /(at|bl|iz)$/), - (w = new RegExp("([^aeiouylsz])\\1$")), - (L = new RegExp("^" + l + u + "[^aeiouwxy]$")), - (E = /^(.+?[^aeiou])y$/), - (b = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/), - (S = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/), - (k = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/), - (Q = /^(.+?)(s|t)(ion)$/), - (O = /^(.+?)e$/), - (P = /ll$/), - (T = new RegExp("^" + l + u + "[^aeiouwxy]$")), - (_ = function (e) { - var t, r, n, i, s, u, l - if (e.length < 3) return e - if ( - ("y" == (n = e.substr(0, 1)) && (e = n.toUpperCase() + e.substr(1)), - (s = y), - (i = p).test(e) - ? (e = e.replace(i, "$1$2")) - : s.test(e) && (e = e.replace(s, "$1$2")), - (s = v), - (i = m).test(e)) - ) { - var _ = i.exec(e) - ;(i = c).test(_[1]) && ((i = g), (e = e.replace(i, ""))) - } else - s.test(e) && - ((t = (_ = s.exec(e))[1]), - (s = f).test(t) && - ((u = w), - (l = L), - (s = x).test((e = t)) - ? (e += "e") - : u.test(e) - ? ((i = g), (e = e.replace(i, ""))) - : l.test(e) && (e += "e"))) - return ( - (i = E).test(e) && (e = (t = (_ = i.exec(e))[1]) + "i"), - (i = b).test(e) && - ((t = (_ = i.exec(e))[1]), (r = _[2]), (i = c).test(t) && (e = t + o[r])), - (i = S).test(e) && - ((t = (_ = i.exec(e))[1]), (r = _[2]), (i = c).test(t) && (e = t + a[r])), - (s = Q), - (i = k).test(e) - ? ((t = (_ = i.exec(e))[1]), (i = h).test(t) && (e = t)) - : s.test(e) && ((t = (_ = s.exec(e))[1] + _[2]), (s = h).test(t) && (e = t)), - (i = O).test(e) && - ((t = (_ = i.exec(e))[1]), - (s = d), - (u = T), - ((i = h).test(t) || (s.test(t) && !u.test(t))) && (e = t)), - (s = h), - (i = P).test(e) && s.test(e) && ((i = g), (e = e.replace(i, ""))), - "y" == n && (e = n.toLowerCase() + e.substr(1)), - e - ) - }), - function (e) { - return e.update(_) - })), - C.Pipeline.registerFunction(C.stemmer, "stemmer"), - /*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - */ (C.generateStopWordFilter = function (e) { - var t = e.reduce(function (e, t) { - return (e[t] = t), e - }, {}) - return function (e) { - if (e && t[e.toString()] !== e.toString()) return e - } - }), - (C.stopWordFilter = C.generateStopWordFilter([ - "a", - "able", - "about", - "across", - "after", - "all", - "almost", - "also", - "am", - "among", - "an", - "and", - "any", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "do", - "does", - "either", - "else", - "ever", - "every", - "for", - "from", - "get", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "in", - "into", - "is", - "it", - "its", - "just", - "least", - "let", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "only", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "where", - "which", - "while", - "who", - "whom", - "why", - "will", - "with", - "would", - "yet", - "you", - "your" - ])), - C.Pipeline.registerFunction(C.stopWordFilter, "stopWordFilter"), - /*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - */ (C.trimmer = function (e) { - return e.update(function (e) { - return e.replace(/^\W+/, "").replace(/\W+$/, "") - }) - }), - C.Pipeline.registerFunction(C.trimmer, "trimmer"), - /*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - */ (C.TokenSet = function () { - ;(this.final = !1), - (this.edges = {}), - (this.id = C.TokenSet._nextId), - (C.TokenSet._nextId += 1) - }), - (C.TokenSet._nextId = 1), - (C.TokenSet.fromArray = function (e) { - for (var t = new C.TokenSet.Builder(), r = 0, n = e.length; r < n; r++) t.insert(e[r]) - return t.finish(), t.root - }), - (C.TokenSet.fromClause = function (e) { - return "editDistance" in e - ? C.TokenSet.fromFuzzyString(e.term, e.editDistance) - : C.TokenSet.fromString(e.term) - }), - (C.TokenSet.fromFuzzyString = function (e, t) { - for (var r = new C.TokenSet(), n = [{ node: r, editsRemaining: t, str: e }]; n.length; ) { - var i = n.pop() - if (i.str.length > 0) { - var s, - o = i.str.charAt(0) - o in i.node.edges - ? (s = i.node.edges[o]) - : ((s = new C.TokenSet()), (i.node.edges[o] = s)), - 1 == i.str.length && (s.final = !0), - n.push({ node: s, editsRemaining: i.editsRemaining, str: i.str.slice(1) }) - } - if (0 != i.editsRemaining) { - if ("*" in i.node.edges) var a = i.node.edges["*"] - else { - a = new C.TokenSet() - i.node.edges["*"] = a - } - if ( - (0 == i.str.length && (a.final = !0), - n.push({ node: a, editsRemaining: i.editsRemaining - 1, str: i.str }), - i.str.length > 1 && - n.push({ - node: i.node, - editsRemaining: i.editsRemaining - 1, - str: i.str.slice(1) - }), - 1 == i.str.length && (i.node.final = !0), - i.str.length >= 1) - ) { - if ("*" in i.node.edges) var u = i.node.edges["*"] - else { - u = new C.TokenSet() - i.node.edges["*"] = u - } - 1 == i.str.length && (u.final = !0), - n.push({ node: u, editsRemaining: i.editsRemaining - 1, str: i.str.slice(1) }) - } - if (i.str.length > 1) { - var l, - c = i.str.charAt(0), - h = i.str.charAt(1) - h in i.node.edges - ? (l = i.node.edges[h]) - : ((l = new C.TokenSet()), (i.node.edges[h] = l)), - 1 == i.str.length && (l.final = !0), - n.push({ node: l, editsRemaining: i.editsRemaining - 1, str: c + i.str.slice(2) }) - } - } - } - return r - }), - (C.TokenSet.fromString = function (e) { - for (var t = new C.TokenSet(), r = t, n = 0, i = e.length; n < i; n++) { - var s = e[n], - o = n == i - 1 - if ("*" == s) (t.edges[s] = t), (t.final = o) - else { - var a = new C.TokenSet() - ;(a.final = o), (t.edges[s] = a), (t = a) - } - } - return r - }), - (C.TokenSet.prototype.toArray = function () { - for (var e = [], t = [{ prefix: "", node: this }]; t.length; ) { - var r = t.pop(), - n = Object.keys(r.node.edges), - i = n.length - r.node.final && (r.prefix.charAt(0), e.push(r.prefix)) - for (var s = 0; s < i; s++) { - var o = n[s] - t.push({ prefix: r.prefix.concat(o), node: r.node.edges[o] }) - } - } - return e - }), - (C.TokenSet.prototype.toString = function () { - if (this._str) return this._str - for ( - var e = this.final ? "1" : "0", t = Object.keys(this.edges).sort(), r = t.length, n = 0; - n < r; - n++ - ) { - var i = t[n] - e = e + i + this.edges[i].id - } - return e - }), - (C.TokenSet.prototype.intersect = function (e) { - for ( - var t = new C.TokenSet(), r = void 0, n = [{ qNode: e, output: t, node: this }]; - n.length; - - ) { - r = n.pop() - for ( - var i = Object.keys(r.qNode.edges), - s = i.length, - o = Object.keys(r.node.edges), - a = o.length, - u = 0; - u < s; - u++ - ) - for (var l = i[u], c = 0; c < a; c++) { - var h = o[c] - if (h == l || "*" == l) { - var d = r.node.edges[h], - f = r.qNode.edges[l], - p = d.final && f.final, - y = void 0 - h in r.output.edges - ? ((y = r.output.edges[h]).final = y.final || p) - : (((y = new C.TokenSet()).final = p), (r.output.edges[h] = y)), - n.push({ qNode: f, output: y, node: d }) - } - } - } - return t - }), - (C.TokenSet.Builder = function () { - ;(this.previousWord = ""), - (this.root = new C.TokenSet()), - (this.uncheckedNodes = []), - (this.minimizedNodes = {}) - }), - (C.TokenSet.Builder.prototype.insert = function (e) { - var t, - r = 0 - if (e < this.previousWord) throw new Error("Out of order word insertion") - for ( - var n = 0; - n < e.length && n < this.previousWord.length && e[n] == this.previousWord[n]; - n++ - ) - r++ - this.minimize(r), - (t = - 0 == this.uncheckedNodes.length - ? this.root - : this.uncheckedNodes[this.uncheckedNodes.length - 1].child) - for (n = r; n < e.length; n++) { - var i = new C.TokenSet(), - s = e[n] - ;(t.edges[s] = i), this.uncheckedNodes.push({ parent: t, char: s, child: i }), (t = i) - } - ;(t.final = !0), (this.previousWord = e) - }), - (C.TokenSet.Builder.prototype.finish = function () { - this.minimize(0) - }), - (C.TokenSet.Builder.prototype.minimize = function (e) { - for (var t = this.uncheckedNodes.length - 1; t >= e; t--) { - var r = this.uncheckedNodes[t], - n = r.child.toString() - n in this.minimizedNodes - ? (r.parent.edges[r.char] = this.minimizedNodes[n]) - : ((r.child._str = n), (this.minimizedNodes[n] = r.child)), - this.uncheckedNodes.pop() - } - }), - /*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - */ (C.Index = function (e) { - ;(this.invertedIndex = e.invertedIndex), - (this.fieldVectors = e.fieldVectors), - (this.tokenSet = e.tokenSet), - (this.fields = e.fields), - (this.pipeline = e.pipeline) - }), - (C.Index.prototype.search = function (e) { - return this.query(function (t) { - new C.QueryParser(e, t).parse() - }) - }), - (C.Index.prototype.query = function (e) { - for ( - var t = new C.Query(this.fields), - r = Object.create(null), - n = Object.create(null), - i = Object.create(null), - s = Object.create(null), - o = Object.create(null), - a = 0; - a < this.fields.length; - a++ - ) - n[this.fields[a]] = new C.Vector() - e.call(t, t) - for (a = 0; a < t.clauses.length; a++) { - var u = t.clauses[a], - l = null, - c = C.Set.empty - l = u.usePipeline ? this.pipeline.runString(u.term, { fields: u.fields }) : [u.term] - for (var h = 0; h < l.length; h++) { - var d = l[h] - u.term = d - var f = C.TokenSet.fromClause(u), - p = this.tokenSet.intersect(f).toArray() - if (0 === p.length && u.presence === C.Query.presence.REQUIRED) { - for (var y = 0; y < u.fields.length; y++) { - s[(R = u.fields[y])] = C.Set.empty - } - break - } - for (var m = 0; m < p.length; m++) { - var v = p[m], - g = this.invertedIndex[v], - x = g._index - for (y = 0; y < u.fields.length; y++) { - var w = g[(R = u.fields[y])], - L = Object.keys(w), - E = v + "/" + R, - b = new C.Set(L) - if ( - (u.presence == C.Query.presence.REQUIRED && - ((c = c.union(b)), void 0 === s[R] && (s[R] = C.Set.complete)), - u.presence != C.Query.presence.PROHIBITED) - ) { - if ( - (n[R].upsert(x, u.boost, function (e, t) { - return e + t - }), - !i[E]) - ) { - for (var S = 0; S < L.length; S++) { - var k, - Q = L[S], - O = new C.FieldRef(Q, R), - P = w[Q] - void 0 === (k = r[O]) ? (r[O] = new C.MatchData(v, R, P)) : k.add(v, R, P) - } - i[E] = !0 - } - } else void 0 === o[R] && (o[R] = C.Set.empty), (o[R] = o[R].union(b)) - } - } - } - if (u.presence === C.Query.presence.REQUIRED) - for (y = 0; y < u.fields.length; y++) { - s[(R = u.fields[y])] = s[R].intersect(c) - } - } - var T = C.Set.complete, - _ = C.Set.empty - for (a = 0; a < this.fields.length; a++) { - var R - s[(R = this.fields[a])] && (T = T.intersect(s[R])), o[R] && (_ = _.union(o[R])) - } - var I = Object.keys(r), - j = [], - F = Object.create(null) - if (t.isNegated()) { - I = Object.keys(this.fieldVectors) - for (a = 0; a < I.length; a++) { - O = I[a] - var N = C.FieldRef.fromString(O) - r[O] = new C.MatchData() - } - } - for (a = 0; a < I.length; a++) { - var D = (N = C.FieldRef.fromString(I[a])).docRef - if (T.contains(D) && !_.contains(D)) { - var A, - z = this.fieldVectors[N], - q = n[N.fieldName].similarity(z) - if (void 0 !== (A = F[D])) (A.score += q), A.matchData.combine(r[N]) - else { - var V = { ref: D, score: q, matchData: r[N] } - ;(F[D] = V), j.push(V) - } - } - } - return j.sort(function (e, t) { - return t.score - e.score - }) - }), - (C.Index.prototype.toJSON = function () { - var e = Object.keys(this.invertedIndex) - .sort() - .map(function (e) { - return [e, this.invertedIndex[e]] - }, this), - t = Object.keys(this.fieldVectors).map(function (e) { - return [e, this.fieldVectors[e].toJSON()] - }, this) - return { - version: C.version, - fields: this.fields, - fieldVectors: t, - invertedIndex: e, - pipeline: this.pipeline.toJSON() - } - }), - (C.Index.load = function (e) { - var t = {}, - r = {}, - n = e.fieldVectors, - i = Object.create(null), - s = e.invertedIndex, - o = new C.TokenSet.Builder(), - a = C.Pipeline.load(e.pipeline) - e.version != C.version && - C.utils.warn( - "Version mismatch when loading serialised index. Current version of lunr '" + - C.version + - "' does not match serialized index '" + - e.version + - "'" - ) - for (var u = 0; u < n.length; u++) { - var l = (h = n[u])[0], - c = h[1] - r[l] = new C.Vector(c) - } - for (u = 0; u < s.length; u++) { - var h, - d = (h = s[u])[0], - f = h[1] - o.insert(d), (i[d] = f) - } - return ( - o.finish(), - (t.fields = e.fields), - (t.fieldVectors = r), - (t.invertedIndex = i), - (t.tokenSet = o.root), - (t.pipeline = a), - new C.Index(t) - ) - }), - /*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - */ (C.Builder = function () { - ;(this._ref = "id"), - (this._fields = Object.create(null)), - (this._documents = Object.create(null)), - (this.invertedIndex = Object.create(null)), - (this.fieldTermFrequencies = {}), - (this.fieldLengths = {}), - (this.tokenizer = C.tokenizer), - (this.pipeline = new C.Pipeline()), - (this.searchPipeline = new C.Pipeline()), - (this.documentCount = 0), - (this._b = 0.75), - (this._k1 = 1.2), - (this.termIndex = 0), - (this.metadataWhitelist = []) - }), - (C.Builder.prototype.ref = function (e) { - this._ref = e - }), - (C.Builder.prototype.field = function (e, t) { - if (/\//.test(e)) throw new RangeError("Field '" + e + "' contains illegal character '/'") - this._fields[e] = t || {} - }), - (C.Builder.prototype.b = function (e) { - this._b = e < 0 ? 0 : e > 1 ? 1 : e - }), - (C.Builder.prototype.k1 = function (e) { - this._k1 = e - }), - (C.Builder.prototype.add = function (e, t) { - var r = e[this._ref], - n = Object.keys(this._fields) - ;(this._documents[r] = t || {}), (this.documentCount += 1) - for (var i = 0; i < n.length; i++) { - var s = n[i], - o = this._fields[s].extractor, - a = o ? o(e) : e[s], - u = this.tokenizer(a, { fields: [s] }), - l = this.pipeline.run(u), - c = new C.FieldRef(r, s), - h = Object.create(null) - ;(this.fieldTermFrequencies[c] = h), - (this.fieldLengths[c] = 0), - (this.fieldLengths[c] += l.length) - for (var d = 0; d < l.length; d++) { - var f = l[d] - if ((null == h[f] && (h[f] = 0), (h[f] += 1), null == this.invertedIndex[f])) { - var p = Object.create(null) - ;(p._index = this.termIndex), (this.termIndex += 1) - for (var y = 0; y < n.length; y++) p[n[y]] = Object.create(null) - this.invertedIndex[f] = p - } - null == this.invertedIndex[f][s][r] && - (this.invertedIndex[f][s][r] = Object.create(null)) - for (var m = 0; m < this.metadataWhitelist.length; m++) { - var v = this.metadataWhitelist[m], - g = f.metadata[v] - null == this.invertedIndex[f][s][r][v] && (this.invertedIndex[f][s][r][v] = []), - this.invertedIndex[f][s][r][v].push(g) - } - } - } - }), - (C.Builder.prototype.calculateAverageFieldLengths = function () { - for ( - var e = Object.keys(this.fieldLengths), t = e.length, r = {}, n = {}, i = 0; - i < t; - i++ - ) { - var s = C.FieldRef.fromString(e[i]), - o = s.fieldName - n[o] || (n[o] = 0), (n[o] += 1), r[o] || (r[o] = 0), (r[o] += this.fieldLengths[s]) - } - var a = Object.keys(this._fields) - for (i = 0; i < a.length; i++) { - var u = a[i] - r[u] = r[u] / n[u] - } - this.averageFieldLength = r - }), - (C.Builder.prototype.createFieldVectors = function () { - for ( - var e = {}, - t = Object.keys(this.fieldTermFrequencies), - r = t.length, - n = Object.create(null), - i = 0; - i < r; - i++ - ) { - for ( - var s = C.FieldRef.fromString(t[i]), - o = s.fieldName, - a = this.fieldLengths[s], - u = new C.Vector(), - l = this.fieldTermFrequencies[s], - c = Object.keys(l), - h = c.length, - d = this._fields[o].boost || 1, - f = this._documents[s.docRef].boost || 1, - p = 0; - p < h; - p++ - ) { - var y, - m, - v, - g = c[p], - x = l[g], - w = this.invertedIndex[g]._index - void 0 === n[g] - ? ((y = C.idf(this.invertedIndex[g], this.documentCount)), (n[g] = y)) - : (y = n[g]), - (m = - (y * ((this._k1 + 1) * x)) / - (this._k1 * (1 - this._b + this._b * (a / this.averageFieldLength[o])) + x)), - (m *= d), - (m *= f), - (v = Math.round(1e3 * m) / 1e3), - u.insert(w, v) - } - e[s] = u - } - this.fieldVectors = e - }), - (C.Builder.prototype.createTokenSet = function () { - this.tokenSet = C.TokenSet.fromArray(Object.keys(this.invertedIndex).sort()) - }), - (C.Builder.prototype.build = function () { - return ( - this.calculateAverageFieldLengths(), - this.createFieldVectors(), - this.createTokenSet(), - new C.Index({ - invertedIndex: this.invertedIndex, - fieldVectors: this.fieldVectors, - tokenSet: this.tokenSet, - fields: Object.keys(this._fields), - pipeline: this.searchPipeline - }) - ) - }), - (C.Builder.prototype.use = function (e) { - var t = Array.prototype.slice.call(arguments, 1) - t.unshift(this), e.apply(this, t) - }), - (C.MatchData = function (e, t, r) { - for (var n = Object.create(null), i = Object.keys(r || {}), s = 0; s < i.length; s++) { - var o = i[s] - n[o] = r[o].slice() - } - ;(this.metadata = Object.create(null)), - void 0 !== e && ((this.metadata[e] = Object.create(null)), (this.metadata[e][t] = n)) - }), - (C.MatchData.prototype.combine = function (e) { - for (var t = Object.keys(e.metadata), r = 0; r < t.length; r++) { - var n = t[r], - i = Object.keys(e.metadata[n]) - null == this.metadata[n] && (this.metadata[n] = Object.create(null)) - for (var s = 0; s < i.length; s++) { - var o = i[s], - a = Object.keys(e.metadata[n][o]) - null == this.metadata[n][o] && (this.metadata[n][o] = Object.create(null)) - for (var u = 0; u < a.length; u++) { - var l = a[u] - null == this.metadata[n][o][l] - ? (this.metadata[n][o][l] = e.metadata[n][o][l]) - : (this.metadata[n][o][l] = this.metadata[n][o][l].concat(e.metadata[n][o][l])) - } - } - } - }), - (C.MatchData.prototype.add = function (e, t, r) { - if (!(e in this.metadata)) - return (this.metadata[e] = Object.create(null)), void (this.metadata[e][t] = r) - if (t in this.metadata[e]) - for (var n = Object.keys(r), i = 0; i < n.length; i++) { - var s = n[i] - s in this.metadata[e][t] - ? (this.metadata[e][t][s] = this.metadata[e][t][s].concat(r[s])) - : (this.metadata[e][t][s] = r[s]) - } - else this.metadata[e][t] = r - }), - (C.Query = function (e) { - ;(this.clauses = []), (this.allFields = e) - }), - (C.Query.wildcard = new String("*")), - (C.Query.wildcard.NONE = 0), - (C.Query.wildcard.LEADING = 1), - (C.Query.wildcard.TRAILING = 2), - (C.Query.presence = { OPTIONAL: 1, REQUIRED: 2, PROHIBITED: 3 }), - (C.Query.prototype.clause = function (e) { - return ( - "fields" in e || (e.fields = this.allFields), - "boost" in e || (e.boost = 1), - "usePipeline" in e || (e.usePipeline = !0), - "wildcard" in e || (e.wildcard = C.Query.wildcard.NONE), - e.wildcard & C.Query.wildcard.LEADING && - e.term.charAt(0) != C.Query.wildcard && - (e.term = "*" + e.term), - e.wildcard & C.Query.wildcard.TRAILING && - e.term.slice(-1) != C.Query.wildcard && - (e.term = e.term + "*"), - "presence" in e || (e.presence = C.Query.presence.OPTIONAL), - this.clauses.push(e), - this - ) - }), - (C.Query.prototype.isNegated = function () { - for (var e = 0; e < this.clauses.length; e++) - if (this.clauses[e].presence != C.Query.presence.PROHIBITED) return !1 - return !0 - }), - (C.Query.prototype.term = function (e, t) { - if (Array.isArray(e)) - return ( - e.forEach(function (e) { - this.term(e, C.utils.clone(t)) - }, this), - this - ) - var r = t || {} - return (r.term = e.toString()), this.clause(r), this - }), - (C.QueryParseError = function (e, t, r) { - ;(this.name = "QueryParseError"), (this.message = e), (this.start = t), (this.end = r) - }), - (C.QueryParseError.prototype = new Error()), - (C.QueryLexer = function (e) { - ;(this.lexemes = []), - (this.str = e), - (this.length = e.length), - (this.pos = 0), - (this.start = 0), - (this.escapeCharPositions = []) - }), - (C.QueryLexer.prototype.run = function () { - for (var e = C.QueryLexer.lexText; e; ) e = e(this) - }), - (C.QueryLexer.prototype.sliceString = function () { - for ( - var e = [], t = this.start, r = this.pos, n = 0; - n < this.escapeCharPositions.length; - n++ - ) - (r = this.escapeCharPositions[n]), e.push(this.str.slice(t, r)), (t = r + 1) - return ( - e.push(this.str.slice(t, this.pos)), (this.escapeCharPositions.length = 0), e.join("") - ) - }), - (C.QueryLexer.prototype.emit = function (e) { - this.lexemes.push({ type: e, str: this.sliceString(), start: this.start, end: this.pos }), - (this.start = this.pos) - }), - (C.QueryLexer.prototype.escapeCharacter = function () { - this.escapeCharPositions.push(this.pos - 1), (this.pos += 1) - }), - (C.QueryLexer.prototype.next = function () { - if (this.pos >= this.length) return C.QueryLexer.EOS - var e = this.str.charAt(this.pos) - return (this.pos += 1), e - }), - (C.QueryLexer.prototype.width = function () { - return this.pos - this.start - }), - (C.QueryLexer.prototype.ignore = function () { - this.start == this.pos && (this.pos += 1), (this.start = this.pos) - }), - (C.QueryLexer.prototype.backup = function () { - this.pos -= 1 - }), - (C.QueryLexer.prototype.acceptDigitRun = function () { - var e, t - do { - t = (e = this.next()).charCodeAt(0) - } while (t > 47 && t < 58) - e != C.QueryLexer.EOS && this.backup() - }), - (C.QueryLexer.prototype.more = function () { - return this.pos < this.length - }), - (C.QueryLexer.EOS = "EOS"), - (C.QueryLexer.FIELD = "FIELD"), - (C.QueryLexer.TERM = "TERM"), - (C.QueryLexer.EDIT_DISTANCE = "EDIT_DISTANCE"), - (C.QueryLexer.BOOST = "BOOST"), - (C.QueryLexer.PRESENCE = "PRESENCE"), - (C.QueryLexer.lexField = function (e) { - return e.backup(), e.emit(C.QueryLexer.FIELD), e.ignore(), C.QueryLexer.lexText - }), - (C.QueryLexer.lexTerm = function (e) { - if ((e.width() > 1 && (e.backup(), e.emit(C.QueryLexer.TERM)), e.ignore(), e.more())) - return C.QueryLexer.lexText - }), - (C.QueryLexer.lexEditDistance = function (e) { - return ( - e.ignore(), e.acceptDigitRun(), e.emit(C.QueryLexer.EDIT_DISTANCE), C.QueryLexer.lexText - ) - }), - (C.QueryLexer.lexBoost = function (e) { - return e.ignore(), e.acceptDigitRun(), e.emit(C.QueryLexer.BOOST), C.QueryLexer.lexText - }), - (C.QueryLexer.lexEOS = function (e) { - e.width() > 0 && e.emit(C.QueryLexer.TERM) - }), - (C.QueryLexer.termSeparator = C.tokenizer.separator), - (C.QueryLexer.lexText = function (e) { - for (;;) { - var t = e.next() - if (t == C.QueryLexer.EOS) return C.QueryLexer.lexEOS - if (92 != t.charCodeAt(0)) { - if (":" == t) return C.QueryLexer.lexField - if ("~" == t) - return ( - e.backup(), - e.width() > 0 && e.emit(C.QueryLexer.TERM), - C.QueryLexer.lexEditDistance - ) - if ("^" == t) - return e.backup(), e.width() > 0 && e.emit(C.QueryLexer.TERM), C.QueryLexer.lexBoost - if ("+" == t && 1 === e.width()) - return e.emit(C.QueryLexer.PRESENCE), C.QueryLexer.lexText - if ("-" == t && 1 === e.width()) - return e.emit(C.QueryLexer.PRESENCE), C.QueryLexer.lexText - if (t.match(C.QueryLexer.termSeparator)) return C.QueryLexer.lexTerm - } else e.escapeCharacter() - } - }), - (C.QueryParser = function (e, t) { - ;(this.lexer = new C.QueryLexer(e)), - (this.query = t), - (this.currentClause = {}), - (this.lexemeIdx = 0) - }), - (C.QueryParser.prototype.parse = function () { - this.lexer.run(), (this.lexemes = this.lexer.lexemes) - for (var e = C.QueryParser.parseClause; e; ) e = e(this) - return this.query - }), - (C.QueryParser.prototype.peekLexeme = function () { - return this.lexemes[this.lexemeIdx] - }), - (C.QueryParser.prototype.consumeLexeme = function () { - var e = this.peekLexeme() - return (this.lexemeIdx += 1), e - }), - (C.QueryParser.prototype.nextClause = function () { - var e = this.currentClause - this.query.clause(e), (this.currentClause = {}) - }), - (C.QueryParser.parseClause = function (e) { - var t = e.peekLexeme() - if (null != t) - switch (t.type) { - case C.QueryLexer.PRESENCE: - return C.QueryParser.parsePresence - case C.QueryLexer.FIELD: - return C.QueryParser.parseField - case C.QueryLexer.TERM: - return C.QueryParser.parseTerm - default: - var r = "expected either a field or a term, found " + t.type - throw ( - (t.str.length >= 1 && (r += " with value '" + t.str + "'"), - new C.QueryParseError(r, t.start, t.end)) - ) - } - }), - (C.QueryParser.parsePresence = function (e) { - var t = e.consumeLexeme() - if (null != t) { - switch (t.str) { - case "-": - e.currentClause.presence = C.Query.presence.PROHIBITED - break - case "+": - e.currentClause.presence = C.Query.presence.REQUIRED - break - default: - var r = "unrecognised presence operator'" + t.str + "'" - throw new C.QueryParseError(r, t.start, t.end) - } - var n = e.peekLexeme() - if (null == n) { - r = "expecting term or field, found nothing" - throw new C.QueryParseError(r, t.start, t.end) - } - switch (n.type) { - case C.QueryLexer.FIELD: - return C.QueryParser.parseField - case C.QueryLexer.TERM: - return C.QueryParser.parseTerm - default: - r = "expecting term or field, found '" + n.type + "'" - throw new C.QueryParseError(r, n.start, n.end) - } - } - }), - (C.QueryParser.parseField = function (e) { - var t = e.consumeLexeme() - if (null != t) { - if (-1 == e.query.allFields.indexOf(t.str)) { - var r = e.query.allFields - .map(function (e) { - return "'" + e + "'" - }) - .join(", "), - n = "unrecognised field '" + t.str + "', possible fields: " + r - throw new C.QueryParseError(n, t.start, t.end) - } - e.currentClause.fields = [t.str] - var i = e.peekLexeme() - if (null == i) { - n = "expecting term, found nothing" - throw new C.QueryParseError(n, t.start, t.end) - } - switch (i.type) { - case C.QueryLexer.TERM: - return C.QueryParser.parseTerm - default: - n = "expecting term, found '" + i.type + "'" - throw new C.QueryParseError(n, i.start, i.end) - } - } - }), - (C.QueryParser.parseTerm = function (e) { - var t = e.consumeLexeme() - if (null != t) { - ;(e.currentClause.term = t.str.toLowerCase()), - -1 != t.str.indexOf("*") && (e.currentClause.usePipeline = !1) - var r = e.peekLexeme() - if (null != r) - switch (r.type) { - case C.QueryLexer.TERM: - return e.nextClause(), C.QueryParser.parseTerm - case C.QueryLexer.FIELD: - return e.nextClause(), C.QueryParser.parseField - case C.QueryLexer.EDIT_DISTANCE: - return C.QueryParser.parseEditDistance - case C.QueryLexer.BOOST: - return C.QueryParser.parseBoost - case C.QueryLexer.PRESENCE: - return e.nextClause(), C.QueryParser.parsePresence - default: - var n = "Unexpected lexeme type '" + r.type + "'" - throw new C.QueryParseError(n, r.start, r.end) - } - else e.nextClause() - } - }), - (C.QueryParser.parseEditDistance = function (e) { - var t = e.consumeLexeme() - if (null != t) { - var r = parseInt(t.str, 10) - if (isNaN(r)) { - var n = "edit distance must be numeric" - throw new C.QueryParseError(n, t.start, t.end) - } - e.currentClause.editDistance = r - var i = e.peekLexeme() - if (null != i) - switch (i.type) { - case C.QueryLexer.TERM: - return e.nextClause(), C.QueryParser.parseTerm - case C.QueryLexer.FIELD: - return e.nextClause(), C.QueryParser.parseField - case C.QueryLexer.EDIT_DISTANCE: - return C.QueryParser.parseEditDistance - case C.QueryLexer.BOOST: - return C.QueryParser.parseBoost - case C.QueryLexer.PRESENCE: - return e.nextClause(), C.QueryParser.parsePresence - default: - n = "Unexpected lexeme type '" + i.type + "'" - throw new C.QueryParseError(n, i.start, i.end) - } - else e.nextClause() - } - }), - (C.QueryParser.parseBoost = function (e) { - var t = e.consumeLexeme() - if (null != t) { - var r = parseInt(t.str, 10) - if (isNaN(r)) { - var n = "boost must be numeric" - throw new C.QueryParseError(n, t.start, t.end) - } - e.currentClause.boost = r - var i = e.peekLexeme() - if (null != i) - switch (i.type) { - case C.QueryLexer.TERM: - return e.nextClause(), C.QueryParser.parseTerm - case C.QueryLexer.FIELD: - return e.nextClause(), C.QueryParser.parseField - case C.QueryLexer.EDIT_DISTANCE: - return C.QueryParser.parseEditDistance - case C.QueryLexer.BOOST: - return C.QueryParser.parseBoost - case C.QueryLexer.PRESENCE: - return e.nextClause(), C.QueryParser.parsePresence - default: - n = "Unexpected lexeme type '" + i.type + "'" - throw new C.QueryParseError(n, i.start, i.end) - } - else e.nextClause() - } - }), - void 0 === - (i = - "function" == - typeof (n = function () { - return C - }) - ? n.call(t, r, t, e) - : n) || (e.exports = i) - })() - }, - function (e, t, r) {}, - function (e, t, r) { - "use strict" - r.r(t) - var n = [] - function i(e, t) { - n.push({ selector: t, constructor: e }) - } - var s, - o, - a = (function () { - function e() { - this.createComponents(document.body) - } - return ( - (e.prototype.createComponents = function (e) { - n.forEach(function (t) { - e.querySelectorAll(t.selector).forEach(function (e) { - e.dataset.hasInstance || - (new t.constructor({ el: e }), (e.dataset.hasInstance = String(!0))) - }) - }) - }), - e - ) - })(), - u = function (e) { - this.el = e.el - }, - l = r(0), - c = - ((s = function (e, t) { - return (s = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(e, t) - }), - function (e, t) { - function r() { - this.constructor = e - } - s(e, t), - (e.prototype = null === t ? Object.create(t) : ((r.prototype = t.prototype), new r())) - }) - !(function (e) { - ;(e[(e.Idle = 0)] = "Idle"), - (e[(e.Loading = 1)] = "Loading"), - (e[(e.Ready = 2)] = "Ready"), - (e[(e.Failure = 3)] = "Failure") - })(o || (o = {})) - var h = (function (e) { - function t(t) { - var r = e.call(this, t) || this - ;(r.query = ""), - (r.loadingState = o.Idle), - (r.hasFocus = !1), - (r.preventPress = !1), - (r.data = null), - (r.index = null), - (r.resultClicked = !1) - var n = document.querySelector("#tsd-search-field"), - i = document.querySelector(".results") - if (!n || !i) throw new Error("The input field or the result list wrapper are not found") - return ( - (r.field = n), (r.results = i), (r.base = r.el.dataset.base + "/"), r.bindEvents(), r - ) - } - return ( - c(t, e), - (t.prototype.loadIndex = function () { - var e = this - if (this.loadingState == o.Idle && !this.data) { - setTimeout(function () { - e.loadingState == o.Idle && e.setLoadingState(o.Loading) - }, 500) - var t = this.el.dataset.index - t - ? fetch(t) - .then(function (e) { - if (!e.ok) throw new Error("The search index is missing") - return e.json() - }) - .then(function (t) { - ;(e.data = t), (e.index = l.Index.load(t.index)), e.setLoadingState(o.Ready) - }) - .catch(function (t) { - console.error(t), e.setLoadingState(o.Failure) - }) - : this.setLoadingState(o.Failure) - } - }), - (t.prototype.updateResults = function () { - if ( - this.loadingState == o.Ready && - ((this.results.textContent = ""), this.query && this.index && this.data) - ) { - var e = this.index.search("*" + this.query + "*") - 0 === e.length && (e = this.index.search("*" + this.query + "~1*")) - for (var t = 0, r = Math.min(10, e.length); t < r; t++) { - var n = this.data.rows[Number(e[t].ref)], - i = n.name.replace(new RegExp(this.query, "i"), function (e) { - return "" + e + "" - }), - s = n.parent || "" - ;(s = s.replace(new RegExp(this.query, "i"), function (e) { - return "" + e + "" - })) && (i = '' + s + "." + i) - var a = document.createElement("li") - ;(a.classList.value = n.classes), - (a.innerHTML = - '\n ' + - i + - "\n "), - this.results.appendChild(a) - } - } - }), - (t.prototype.setLoadingState = function (e) { - this.loadingState != e && - (this.el.classList.remove(o[this.loadingState].toLowerCase()), - (this.loadingState = e), - this.el.classList.add(o[this.loadingState].toLowerCase()), - this.updateResults()) - }), - (t.prototype.setHasFocus = function (e) { - this.hasFocus != e && - ((this.hasFocus = e), - this.el.classList.toggle("has-focus"), - e ? (this.setQuery(""), (this.field.value = "")) : (this.field.value = this.query)) - }), - (t.prototype.setQuery = function (e) { - ;(this.query = e.trim()), this.updateResults() - }), - (t.prototype.setCurrentResult = function (e) { - var t = this.results.querySelector(".current") - if (t) { - var r = 1 == e ? t.nextElementSibling : t.previousElementSibling - r && (t.classList.remove("current"), r.classList.add("current")) - } else - (t = this.results.querySelector(1 == e ? "li:first-child" : "li:last-child")) && - t.classList.add("current") - }), - (t.prototype.gotoCurrentResult = function () { - var e = this.results.querySelector(".current") - if ((e || (e = this.results.querySelector("li:first-child")), e)) { - var t = e.querySelector("a") - t && (window.location.href = t.href), this.field.blur() - } - }), - (t.prototype.bindEvents = function () { - var e = this - this.results.addEventListener("mousedown", function () { - e.resultClicked = !0 - }), - this.results.addEventListener("mouseup", function () { - ;(e.resultClicked = !1), e.setHasFocus(!1) - }), - this.field.addEventListener("focusin", function () { - e.setHasFocus(!0), e.loadIndex() - }), - this.field.addEventListener("focusout", function () { - e.resultClicked - ? (e.resultClicked = !1) - : setTimeout(function () { - return e.setHasFocus(!1) - }, 100) - }), - this.field.addEventListener("input", function () { - e.setQuery(e.field.value) - }), - this.field.addEventListener("keydown", function (t) { - 13 == t.keyCode || 27 == t.keyCode || 38 == t.keyCode || 40 == t.keyCode - ? ((e.preventPress = !0), - t.preventDefault(), - 13 == t.keyCode - ? e.gotoCurrentResult() - : 27 == t.keyCode - ? e.field.blur() - : 38 == t.keyCode - ? e.setCurrentResult(-1) - : 40 == t.keyCode && e.setCurrentResult(1)) - : (e.preventPress = !1) - }), - this.field.addEventListener("keypress", function (t) { - e.preventPress && t.preventDefault() - }), - document.body.addEventListener("keydown", function (t) { - t.altKey || - t.ctrlKey || - t.metaKey || - (!e.hasFocus && t.keyCode > 47 && t.keyCode < 112 && e.field.focus()) - }) - }), - t - ) - })(u), - d = (function () { - function e() { - this.listeners = {} - } - return ( - (e.prototype.addEventListener = function (e, t) { - e in this.listeners || (this.listeners[e] = []), this.listeners[e].push(t) - }), - (e.prototype.removeEventListener = function (e, t) { - if (e in this.listeners) - for (var r = this.listeners[e], n = 0, i = r.length; n < i; n++) - if (r[n] === t) return void r.splice(n, 1) - }), - (e.prototype.dispatchEvent = function (e) { - if (!(e.type in this.listeners)) return !0 - for (var t = this.listeners[e.type].slice(), r = 0, n = t.length; r < n; r++) - t[r].call(this, e) - return !e.defaultPrevented - }), - e - ) - })(), - f = function (e, t) { - void 0 === t && (t = 100) - var r = Date.now() - return function () { - for (var n = [], i = 0; i < arguments.length; i++) n[i] = arguments[i] - r + t - Date.now() < 0 && (e.apply(void 0, n), (r = Date.now())) - } - }, - p = (function () { - var e = function (t, r) { - return (e = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(t, r) - } - return function (t, r) { - function n() { - this.constructor = t - } - e(t, r), - (t.prototype = null === r ? Object.create(r) : ((n.prototype = r.prototype), new n())) - } - })(), - y = (function (e) { - function t() { - var t = e.call(this) || this - return ( - (t.scrollTop = 0), - (t.lastY = 0), - (t.width = 0), - (t.height = 0), - (t.showToolbar = !0), - (t.toolbar = document.querySelector(".tsd-page-toolbar")), - (t.secondaryNav = document.querySelector(".tsd-navigation.secondary")), - window.addEventListener( - "scroll", - f(function () { - return t.onScroll() - }, 10) - ), - window.addEventListener( - "resize", - f(function () { - return t.onResize() - }, 10) - ), - t.onResize(), - t.onScroll(), - t - ) - } - return ( - p(t, e), - (t.prototype.triggerResize = function () { - var e = new CustomEvent("resize", { - detail: { width: this.width, height: this.height } - }) - this.dispatchEvent(e) - }), - (t.prototype.onResize = function () { - ;(this.width = window.innerWidth || 0), (this.height = window.innerHeight || 0) - var e = new CustomEvent("resize", { - detail: { width: this.width, height: this.height } - }) - this.dispatchEvent(e) - }), - (t.prototype.onScroll = function () { - this.scrollTop = window.scrollY || 0 - var e = new CustomEvent("scroll", { detail: { scrollTop: this.scrollTop } }) - this.dispatchEvent(e), this.hideShowToolbar() - }), - (t.prototype.hideShowToolbar = function () { - var e = this.showToolbar - ;(this.showToolbar = this.lastY >= this.scrollTop || 0 === this.scrollTop), - e !== this.showToolbar && - (this.toolbar.classList.toggle("tsd-page-toolbar--hide"), - this.secondaryNav.classList.toggle("tsd-navigation--toolbar-hide")), - (this.lastY = this.scrollTop) - }), - (t.instance = new t()), - t - ) - })(d), - m = (function () { - var e = function (t, r) { - return (e = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(t, r) - } - return function (t, r) { - function n() { - this.constructor = t - } - e(t, r), - (t.prototype = null === r ? Object.create(r) : ((n.prototype = r.prototype), new n())) - } - })(), - v = (function (e) { - function t(t) { - var r = e.call(this, t) || this - return ( - (r.anchors = []), - (r.index = -1), - y.instance.addEventListener("resize", function () { - return r.onResize() - }), - y.instance.addEventListener("scroll", function (e) { - return r.onScroll(e) - }), - r.createAnchors(), - r - ) - } - return ( - m(t, e), - (t.prototype.createAnchors = function () { - var e = this, - t = window.location.href - ;-1 != t.indexOf("#") && (t = t.substr(0, t.indexOf("#"))), - this.el.querySelectorAll("a").forEach(function (r) { - var n = r.href - if (-1 != n.indexOf("#") && n.substr(0, t.length) == t) { - var i = n.substr(n.indexOf("#") + 1), - s = document.querySelector("a.tsd-anchor[name=" + i + "]"), - o = r.parentNode - s && o && e.anchors.push({ link: o, anchor: s, position: 0 }) - } - }), - this.onResize() - }), - (t.prototype.onResize = function () { - for (var e, t = 0, r = this.anchors.length; t < r; t++) { - var n = (e = this.anchors[t]).anchor.getBoundingClientRect() - e.position = n.top + document.body.scrollTop - } - this.anchors.sort(function (e, t) { - return e.position - t.position - }) - var i = new CustomEvent("scroll", { detail: { scrollTop: y.instance.scrollTop } }) - this.onScroll(i) - }), - (t.prototype.onScroll = function (e) { - for ( - var t = e.detail.scrollTop + 5, r = this.anchors, n = r.length - 1, i = this.index; - i > -1 && r[i].position > t; - - ) - i -= 1 - for (; i < n && r[i + 1].position < t; ) i += 1 - this.index != i && - (this.index > -1 && this.anchors[this.index].link.classList.remove("focus"), - (this.index = i), - this.index > -1 && this.anchors[this.index].link.classList.add("focus")) - }), - t - ) - })(u), - g = (function () { - var e = function (t, r) { - return (e = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(t, r) - } - return function (t, r) { - function n() { - this.constructor = t - } - e(t, r), - (t.prototype = null === r ? Object.create(r) : ((n.prototype = r.prototype), new n())) - } - })(), - x = (function () { - function e(e, t) { - ;(this.signature = e), (this.description = t) - } - return ( - (e.prototype.addClass = function (e) { - return this.signature.classList.add(e), this.description.classList.add(e), this - }), - (e.prototype.removeClass = function (e) { - return this.signature.classList.remove(e), this.description.classList.remove(e), this - }), - e - ) - })(), - w = (function (e) { - function t(t) { - var r = e.call(this, t) || this - return ( - (r.groups = []), - (r.index = -1), - r.createGroups(), - r.container && - (r.el.classList.add("active"), - Array.from(r.el.children).forEach(function (e) { - e.addEventListener("touchstart", function (e) { - return r.onClick(e) - }), - e.addEventListener("click", function (e) { - return r.onClick(e) - }) - }), - r.container.classList.add("active"), - r.setIndex(0)), - r - ) - } - return ( - g(t, e), - (t.prototype.setIndex = function (e) { - if ( - (e < 0 && (e = 0), - e > this.groups.length - 1 && (e = this.groups.length - 1), - this.index != e) - ) { - var t = this.groups[e] - if (this.index > -1) { - var r = this.groups[this.index] - r.removeClass("current").addClass("fade-out"), - t.addClass("current"), - t.addClass("fade-in"), - y.instance.triggerResize(), - setTimeout(function () { - r.removeClass("fade-out"), t.removeClass("fade-in") - }, 300) - } else t.addClass("current"), y.instance.triggerResize() - this.index = e - } - }), - (t.prototype.createGroups = function () { - var e = this.el.children - if (!(e.length < 2)) { - this.container = this.el.nextElementSibling - var t = this.container.children - this.groups = [] - for (var r = 0; r < e.length; r++) this.groups.push(new x(e[r], t[r])) - } - }), - (t.prototype.onClick = function (e) { - var t = this - this.groups.forEach(function (r, n) { - r.signature === e.currentTarget && t.setIndex(n) - }) - }), - t - ) - })(u), - L = "mousedown", - E = "mousemove", - b = "mouseup", - S = { x: 0, y: 0 }, - k = !1, - Q = !1, - O = !1, - P = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) - document.documentElement.classList.add(P ? "is-mobile" : "not-mobile"), - P && - "ontouchstart" in document.documentElement && - (!0, (L = "touchstart"), (E = "touchmove"), (b = "touchend")), - document.addEventListener(L, function (e) { - ;(Q = !0), (O = !1) - var t = "touchstart" == L ? e.targetTouches[0] : e - ;(S.y = t.pageY || 0), (S.x = t.pageX || 0) - }), - document.addEventListener(E, function (e) { - if (Q && !O) { - var t = "touchstart" == L ? e.targetTouches[0] : e, - r = S.x - (t.pageX || 0), - n = S.y - (t.pageY || 0) - O = Math.sqrt(r * r + n * n) > 10 - } - }), - document.addEventListener(b, function () { - Q = !1 - }), - document.addEventListener("click", function (e) { - k && (e.preventDefault(), e.stopImmediatePropagation(), (k = !1)) - }) - var T = (function () { - var e = function (t, r) { - return (e = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(t, r) - } - return function (t, r) { - function n() { - this.constructor = t - } - e(t, r), - (t.prototype = null === r ? Object.create(r) : ((n.prototype = r.prototype), new n())) - } - })(), - _ = (function (e) { - function t(t) { - var r = e.call(this, t) || this - return ( - (r.className = r.el.dataset.toggle || ""), - r.el.addEventListener(b, function (e) { - return r.onPointerUp(e) - }), - r.el.addEventListener("click", function (e) { - return e.preventDefault() - }), - document.addEventListener(L, function (e) { - return r.onDocumentPointerDown(e) - }), - document.addEventListener(b, function (e) { - return r.onDocumentPointerUp(e) - }), - r - ) - } - return ( - T(t, e), - (t.prototype.setActive = function (e) { - if (this.active != e) { - ;(this.active = e), - document.documentElement.classList.toggle("has-" + this.className, e), - this.el.classList.toggle("active", e) - var t = (this.active ? "to-has-" : "from-has-") + this.className - document.documentElement.classList.add(t), - setTimeout(function () { - return document.documentElement.classList.remove(t) - }, 500) - } - }), - (t.prototype.onPointerUp = function (e) { - O || (this.setActive(!0), e.preventDefault()) - }), - (t.prototype.onDocumentPointerDown = function (e) { - if (this.active) { - if (e.target.closest(".col-menu, .tsd-filter-group")) return - this.setActive(!1) - } - }), - (t.prototype.onDocumentPointerUp = function (e) { - var t = this - if (!O && this.active && e.target.closest(".col-menu")) { - var r = e.target.closest("a") - if (r) { - var n = window.location.href - ;-1 != n.indexOf("#") && (n = n.substr(0, n.indexOf("#"))), - r.href.substr(0, n.length) == n && - setTimeout(function () { - return t.setActive(!1) - }, 250) - } - } - }), - t - ) - })(u), - C = (function () { - var e = function (t, r) { - return (e = - Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && - function (e, t) { - e.__proto__ = t - }) || - function (e, t) { - for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) - })(t, r) - } - return function (t, r) { - function n() { - this.constructor = t - } - e(t, r), - (t.prototype = null === r ? Object.create(r) : ((n.prototype = r.prototype), new n())) - } - })(), - R = (function () { - function e(e, t) { - ;(this.key = e), - (this.value = t), - (this.defaultValue = t), - this.initialize(), - window.localStorage[this.key] && - this.setValue(this.fromLocalStorage(window.localStorage[this.key])) - } - return ( - (e.prototype.initialize = function () {}), - (e.prototype.setValue = function (e) { - if (this.value != e) { - var t = this.value - ;(this.value = e), - (window.localStorage[this.key] = this.toLocalStorage(e)), - this.handleValueChange(t, e) - } - }), - e - ) - })(), - I = (function (e) { - function t() { - return (null !== e && e.apply(this, arguments)) || this - } - return ( - C(t, e), - (t.prototype.initialize = function () { - var e = this, - t = document.querySelector("#tsd-filter-" + this.key) - t && - ((this.checkbox = t), - this.checkbox.addEventListener("change", function () { - e.setValue(e.checkbox.checked) - })) - }), - (t.prototype.handleValueChange = function (e, t) { - this.checkbox && - ((this.checkbox.checked = this.value), - document.documentElement.classList.toggle( - "toggle-" + this.key, - this.value != this.defaultValue - )) - }), - (t.prototype.fromLocalStorage = function (e) { - return "true" == e - }), - (t.prototype.toLocalStorage = function (e) { - return e ? "true" : "false" - }), - t - ) - })(R), - j = (function (e) { - function t() { - return (null !== e && e.apply(this, arguments)) || this - } - return ( - C(t, e), - (t.prototype.initialize = function () { - var e = this - document.documentElement.classList.add("toggle-" + this.key + this.value) - var t = document.querySelector("#tsd-filter-" + this.key) - if (t) { - this.select = t - var r = function () { - e.select.classList.add("active") - } - this.select.addEventListener(L, r), - this.select.addEventListener("mouseover", r), - this.select.addEventListener("mouseleave", function () { - e.select.classList.remove("active") - }), - this.select.querySelectorAll("li").forEach(function (r) { - r.addEventListener(b, function (r) { - t.classList.remove("active"), e.setValue(r.target.dataset.value || "") - }) - }), - document.addEventListener(L, function (t) { - e.select.contains(t.target) || e.select.classList.remove("active") - }) - } - }), - (t.prototype.handleValueChange = function (e, t) { - this.select.querySelectorAll("li.selected").forEach(function (e) { - e.classList.remove("selected") - }) - var r = this.select.querySelector('li[data-value="' + t + '"]'), - n = this.select.querySelector(".tsd-select-label") - r && n && (r.classList.add("selected"), (n.textContent = r.textContent)), - document.documentElement.classList.remove("toggle-" + e), - document.documentElement.classList.add("toggle-" + t) - }), - (t.prototype.fromLocalStorage = function (e) { - return e - }), - (t.prototype.toLocalStorage = function (e) { - return e - }), - t - ) - })(R), - F = (function (e) { - function t(t) { - var r = e.call(this, t) || this - return ( - (r.optionVisibility = new j("visibility", "private")), - (r.optionInherited = new I("inherited", !0)), - (r.optionExternals = new I("externals", !0)), - (r.optionOnlyExported = new I("only-exported", !1)), - r - ) - } - return ( - C(t, e), - (t.isSupported = function () { - try { - return void 0 !== window.localStorage - } catch (e) { - return !1 - } - }), - t - ) - })(u) - r(1) - i(h, "#tsd-search"), - i(v, ".menu-highlight"), - i(w, ".tsd-signatures"), - i(_, "a[data-toggle]"), - F.isSupported() ? i(F, "#tsd-filter") : document.documentElement.classList.add("no-filter") - var N = new a() - Object.defineProperty(window, "app", { value: N }) - } -]) +!function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=2)}([function(e,t,r){var n,i; +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */!function(){var s,o,a,u,l,c,h,d,f,p,y,m,v,g,x,w,L,E,b,S,k,Q,O,P,T,_,C=function(e){var t=new C.Builder;return t.pipeline.add(C.trimmer,C.stopWordFilter,C.stemmer),t.searchPipeline.add(C.stemmer),e.call(t,t),t.build()};C.version="2.3.9" +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */,C.utils={},C.utils.warn=(s=this,function(e){s.console&&console.warn&&console.warn(e)}),C.utils.asString=function(e){return null==e?"":e.toString()},C.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),n=0;n0){var u=C.utils.clone(t)||{};u.position=[o,a],u.index=i.length,i.push(new C.Token(r.slice(o,s),u))}o=s+1}}return i},C.tokenizer.separator=/[\s\-]+/ +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */,C.Pipeline=function(){this._stack=[]},C.Pipeline.registeredFunctions=Object.create(null),C.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&C.utils.warn("Overwriting existing registered function: "+t),e.label=t,C.Pipeline.registeredFunctions[e.label]=e},C.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||C.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},C.Pipeline.load=function(e){var t=new C.Pipeline;return e.forEach((function(e){var r=C.Pipeline.registeredFunctions[e];if(!r)throw new Error("Cannot load unregistered function: "+e);t.add(r)})),t},C.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){C.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},C.Pipeline.prototype.after=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");r+=1,this._stack.splice(r,0,t)},C.Pipeline.prototype.before=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");this._stack.splice(r,0,t)},C.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},C.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=i),s!=e);)n=r-t,i=t+Math.floor(n/2),s=this.elements[2*i];return s==e||s>e?2*i:sa?l+=2:o==a&&(t+=r[u+1]*n[l+1],u+=2,l+=2);return t},C.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},C.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var s,o=i.str.charAt(0);o in i.node.edges?s=i.node.edges[o]:(s=new C.TokenSet,i.node.edges[o]=s),1==i.str.length&&(s.final=!0),n.push({node:s,editsRemaining:i.editsRemaining,str:i.str.slice(1)})}if(0!=i.editsRemaining){if("*"in i.node.edges)var a=i.node.edges["*"];else{a=new C.TokenSet;i.node.edges["*"]=a}if(0==i.str.length&&(a.final=!0),n.push({node:a,editsRemaining:i.editsRemaining-1,str:i.str}),i.str.length>1&&n.push({node:i.node,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)}),1==i.str.length&&(i.node.final=!0),i.str.length>=1){if("*"in i.node.edges)var u=i.node.edges["*"];else{u=new C.TokenSet;i.node.edges["*"]=u}1==i.str.length&&(u.final=!0),n.push({node:u,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)})}if(i.str.length>1){var l,c=i.str.charAt(0),h=i.str.charAt(1);h in i.node.edges?l=i.node.edges[h]:(l=new C.TokenSet,i.node.edges[h]=l),1==i.str.length&&(l.final=!0),n.push({node:l,editsRemaining:i.editsRemaining-1,str:c+i.str.slice(2)})}}}return r},C.TokenSet.fromString=function(e){for(var t=new C.TokenSet,r=t,n=0,i=e.length;n=e;t--){var r=this.uncheckedNodes[t],n=r.child.toString();n in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[n]:(r.child._str=n,this.minimizedNodes[n]=r.child),this.uncheckedNodes.pop()}} +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */,C.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},C.Index.prototype.search=function(e){return this.query((function(t){new C.QueryParser(e,t).parse()}))},C.Index.prototype.query=function(e){for(var t=new C.Query(this.fields),r=Object.create(null),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=0;a1?1:e},C.Builder.prototype.k1=function(e){this._k1=e},C.Builder.prototype.add=function(e,t){var r=e[this._ref],n=Object.keys(this._fields);this._documents[r]=t||{},this.documentCount+=1;for(var i=0;i=this.length)return C.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},C.QueryLexer.prototype.width=function(){return this.pos-this.start},C.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},C.QueryLexer.prototype.backup=function(){this.pos-=1},C.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=C.QueryLexer.EOS&&this.backup()},C.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(C.QueryLexer.TERM)),e.ignore(),e.more())return C.QueryLexer.lexText},C.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(C.QueryLexer.EDIT_DISTANCE),C.QueryLexer.lexText},C.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(C.QueryLexer.BOOST),C.QueryLexer.lexText},C.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(C.QueryLexer.TERM)},C.QueryLexer.termSeparator=C.tokenizer.separator,C.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==C.QueryLexer.EOS)return C.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return C.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(C.QueryLexer.TERM),C.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(C.QueryLexer.TERM),C.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(C.QueryLexer.PRESENCE),C.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(C.QueryLexer.PRESENCE),C.QueryLexer.lexText;if(t.match(C.QueryLexer.termSeparator))return C.QueryLexer.lexTerm}else e.escapeCharacter()}},C.QueryParser=function(e,t){this.lexer=new C.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},C.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=C.QueryParser.parseClause;e;)e=e(this);return this.query},C.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},C.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},C.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},C.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case C.QueryLexer.PRESENCE:return C.QueryParser.parsePresence;case C.QueryLexer.FIELD:return C.QueryParser.parseField;case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(r+=" with value '"+t.str+"'"),new C.QueryParseError(r,t.start,t.end)}},C.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=C.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=C.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+t.str+"'";throw new C.QueryParseError(r,t.start,t.end)}var n=e.peekLexeme();if(null==n){r="expecting term or field, found nothing";throw new C.QueryParseError(r,t.start,t.end)}switch(n.type){case C.QueryLexer.FIELD:return C.QueryParser.parseField;case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:r="expecting term or field, found '"+n.type+"'";throw new C.QueryParseError(r,n.start,n.end)}}},C.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var r=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),n="unrecognised field '"+t.str+"', possible fields: "+r;throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.fields=[t.str];var i=e.peekLexeme();if(null==i){n="expecting term, found nothing";throw new C.QueryParseError(n,t.start,t.end)}switch(i.type){case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:n="expecting term, found '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}}},C.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(null!=r)switch(r.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+r.type+"'";throw new C.QueryParseError(n,r.start,r.end)}else e.nextClause()}},C.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var n="edit distance must be numeric";throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.editDistance=r;var i=e.peekLexeme();if(null!=i)switch(i.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:n="Unexpected lexeme type '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}else e.nextClause()}},C.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var n="boost must be numeric";throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.boost=r;var i=e.peekLexeme();if(null!=i)switch(i.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:n="Unexpected lexeme type '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}else e.nextClause()}},void 0===(i="function"==typeof(n=function(){return C})?n.call(t,r,t,e):n)||(e.exports=i)}()},function(e,t,r){},function(e,t,r){"use strict";r.r(t);var n=[];function i(e,t){n.push({selector:t,constructor:e})}var s,o,a=function(){function e(){this.createComponents(document.body)}return e.prototype.createComponents=function(e){n.forEach((function(t){e.querySelectorAll(t.selector).forEach((function(e){e.dataset.hasInstance||(new t.constructor({el:e}),e.dataset.hasInstance=String(!0))}))}))},e}(),u=function(e){this.el=e.el},l=r(0),c=(s=function(e,t){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(e,t)},function(e,t){function r(){this.constructor=e}s(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)});!function(e){e[e.Idle=0]="Idle",e[e.Loading=1]="Loading",e[e.Ready=2]="Ready",e[e.Failure=3]="Failure"}(o||(o={}));var h=function(e){function t(t){var r=e.call(this,t)||this;r.query="",r.loadingState=o.Idle,r.hasFocus=!1,r.preventPress=!1,r.data=null,r.index=null,r.resultClicked=!1;var n=document.querySelector("#tsd-search-field"),i=document.querySelector(".results");if(!n||!i)throw new Error("The input field or the result list wrapper are not found");return r.field=n,r.results=i,r.base=r.el.dataset.base+"/",r.bindEvents(),r}return c(t,e),t.prototype.loadIndex=function(){var e=this;if(this.loadingState==o.Idle&&!this.data){setTimeout((function(){e.loadingState==o.Idle&&e.setLoadingState(o.Loading)}),500);var t=this.el.dataset.index;t?fetch(t).then((function(e){if(!e.ok)throw new Error("The search index is missing");return e.json()})).then((function(t){e.data=t,e.index=l.Index.load(t.index),e.setLoadingState(o.Ready)})).catch((function(t){console.error(t),e.setLoadingState(o.Failure)})):this.setLoadingState(o.Failure)}},t.prototype.updateResults=function(){if(this.loadingState==o.Ready&&(this.results.textContent="",this.query&&this.index&&this.data)){var e=this.index.search("*"+this.query+"*");0===e.length&&(e=this.index.search("*"+this.query+"~1*"));for(var t=0,r=Math.min(10,e.length);t"+e+""})),s=n.parent||"";(s=s.replace(new RegExp(this.query,"i"),(function(e){return""+e+""})))&&(i=''+s+"."+i);var a=document.createElement("li");a.classList.value=n.classes,a.innerHTML='\n '+i+"\n ",this.results.appendChild(a)}}},t.prototype.setLoadingState=function(e){this.loadingState!=e&&(this.el.classList.remove(o[this.loadingState].toLowerCase()),this.loadingState=e,this.el.classList.add(o[this.loadingState].toLowerCase()),this.updateResults())},t.prototype.setHasFocus=function(e){this.hasFocus!=e&&(this.hasFocus=e,this.el.classList.toggle("has-focus"),e?(this.setQuery(""),this.field.value=""):this.field.value=this.query)},t.prototype.setQuery=function(e){this.query=e.trim(),this.updateResults()},t.prototype.setCurrentResult=function(e){var t=this.results.querySelector(".current");if(t){var r=1==e?t.nextElementSibling:t.previousElementSibling;r&&(t.classList.remove("current"),r.classList.add("current"))}else(t=this.results.querySelector(1==e?"li:first-child":"li:last-child"))&&t.classList.add("current")},t.prototype.gotoCurrentResult=function(){var e=this.results.querySelector(".current");if(e||(e=this.results.querySelector("li:first-child")),e){var t=e.querySelector("a");t&&(window.location.href=t.href),this.field.blur()}},t.prototype.bindEvents=function(){var e=this;this.results.addEventListener("mousedown",(function(){e.resultClicked=!0})),this.results.addEventListener("mouseup",(function(){e.resultClicked=!1,e.setHasFocus(!1)})),this.field.addEventListener("focusin",(function(){e.setHasFocus(!0),e.loadIndex()})),this.field.addEventListener("focusout",(function(){e.resultClicked?e.resultClicked=!1:setTimeout((function(){return e.setHasFocus(!1)}),100)})),this.field.addEventListener("input",(function(){e.setQuery(e.field.value)})),this.field.addEventListener("keydown",(function(t){13==t.keyCode||27==t.keyCode||38==t.keyCode||40==t.keyCode?(e.preventPress=!0,t.preventDefault(),13==t.keyCode?e.gotoCurrentResult():27==t.keyCode?e.field.blur():38==t.keyCode?e.setCurrentResult(-1):40==t.keyCode&&e.setCurrentResult(1)):e.preventPress=!1})),this.field.addEventListener("keypress",(function(t){e.preventPress&&t.preventDefault()})),document.body.addEventListener("keydown",(function(t){t.altKey||t.ctrlKey||t.metaKey||!e.hasFocus&&t.keyCode>47&&t.keyCode<112&&e.field.focus()}))},t}(u),d=function(){function e(){this.listeners={}}return e.prototype.addEventListener=function(e,t){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push(t)},e.prototype.removeEventListener=function(e,t){if(e in this.listeners)for(var r=this.listeners[e],n=0,i=r.length;n=this.scrollTop||0===this.scrollTop,e!==this.showToolbar&&(this.toolbar.classList.toggle("tsd-page-toolbar--hide"),this.secondaryNav.classList.toggle("tsd-navigation--toolbar-hide")),this.lastY=this.scrollTop},t.instance=new t,t}(d),m=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),v=function(e){function t(t){var r=e.call(this,t)||this;return r.anchors=[],r.index=-1,y.instance.addEventListener("resize",(function(){return r.onResize()})),y.instance.addEventListener("scroll",(function(e){return r.onScroll(e)})),r.createAnchors(),r}return m(t,e),t.prototype.createAnchors=function(){var e=this,t=window.location.href;-1!=t.indexOf("#")&&(t=t.substr(0,t.indexOf("#"))),this.el.querySelectorAll("a").forEach((function(r){var n=r.href;if(-1!=n.indexOf("#")&&n.substr(0,t.length)==t){var i=n.substr(n.indexOf("#")+1),s=document.querySelector("a.tsd-anchor[name="+i+"]"),o=r.parentNode;s&&o&&e.anchors.push({link:o,anchor:s,position:0})}})),this.onResize()},t.prototype.onResize=function(){for(var e,t=0,r=this.anchors.length;t-1&&r[i].position>t;)i-=1;for(;i-1&&this.anchors[this.index].link.classList.remove("focus"),this.index=i,this.index>-1&&this.anchors[this.index].link.classList.add("focus"))},t}(u),g=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),x=function(){function e(e,t){this.signature=e,this.description=t}return e.prototype.addClass=function(e){return this.signature.classList.add(e),this.description.classList.add(e),this},e.prototype.removeClass=function(e){return this.signature.classList.remove(e),this.description.classList.remove(e),this},e}(),w=function(e){function t(t){var r=e.call(this,t)||this;return r.groups=[],r.index=-1,r.createGroups(),r.container&&(r.el.classList.add("active"),Array.from(r.el.children).forEach((function(e){e.addEventListener("touchstart",(function(e){return r.onClick(e)})),e.addEventListener("click",(function(e){return r.onClick(e)}))})),r.container.classList.add("active"),r.setIndex(0)),r}return g(t,e),t.prototype.setIndex=function(e){if(e<0&&(e=0),e>this.groups.length-1&&(e=this.groups.length-1),this.index!=e){var t=this.groups[e];if(this.index>-1){var r=this.groups[this.index];r.removeClass("current").addClass("fade-out"),t.addClass("current"),t.addClass("fade-in"),y.instance.triggerResize(),setTimeout((function(){r.removeClass("fade-out"),t.removeClass("fade-in")}),300)}else t.addClass("current"),y.instance.triggerResize();this.index=e}},t.prototype.createGroups=function(){var e=this.el.children;if(!(e.length<2)){this.container=this.el.nextElementSibling;var t=this.container.children;this.groups=[];for(var r=0;r10}})),document.addEventListener(b,(function(){Q=!1})),document.addEventListener("click",(function(e){k&&(e.preventDefault(),e.stopImmediatePropagation(),k=!1)}));var T=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),_=function(e){function t(t){var r=e.call(this,t)||this;return r.className=r.el.dataset.toggle||"",r.el.addEventListener(b,(function(e){return r.onPointerUp(e)})),r.el.addEventListener("click",(function(e){return e.preventDefault()})),document.addEventListener(L,(function(e){return r.onDocumentPointerDown(e)})),document.addEventListener(b,(function(e){return r.onDocumentPointerUp(e)})),r}return T(t,e),t.prototype.setActive=function(e){if(this.active!=e){this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);var t=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(t),setTimeout((function(){return document.documentElement.classList.remove(t)}),500)}},t.prototype.onPointerUp=function(e){O||(this.setActive(!0),e.preventDefault())},t.prototype.onDocumentPointerDown=function(e){if(this.active){if(e.target.closest(".col-menu, .tsd-filter-group"))return;this.setActive(!1)}},t.prototype.onDocumentPointerUp=function(e){var t=this;if(!O&&this.active&&e.target.closest(".col-menu")){var r=e.target.closest("a");if(r){var n=window.location.href;-1!=n.indexOf("#")&&(n=n.substr(0,n.indexOf("#"))),r.href.substr(0,n.length)==n&&setTimeout((function(){return t.setActive(!1)}),250)}}},t}(u),C=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),R=function(){function e(e,t){this.key=e,this.value=t,this.defaultValue=t,this.initialize(),window.localStorage[this.key]&&this.setValue(this.fromLocalStorage(window.localStorage[this.key]))}return e.prototype.initialize=function(){},e.prototype.setValue=function(e){if(this.value!=e){var t=this.value;this.value=e,window.localStorage[this.key]=this.toLocalStorage(e),this.handleValueChange(t,e)}},e}(),I=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return C(t,e),t.prototype.initialize=function(){var e=this,t=document.querySelector("#tsd-filter-"+this.key);t&&(this.checkbox=t,this.checkbox.addEventListener("change",(function(){e.setValue(e.checkbox.checked)})))},t.prototype.handleValueChange=function(e,t){this.checkbox&&(this.checkbox.checked=this.value,document.documentElement.classList.toggle("toggle-"+this.key,this.value!=this.defaultValue))},t.prototype.fromLocalStorage=function(e){return"true"==e},t.prototype.toLocalStorage=function(e){return e?"true":"false"},t}(R),j=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return C(t,e),t.prototype.initialize=function(){var e=this;document.documentElement.classList.add("toggle-"+this.key+this.value);var t=document.querySelector("#tsd-filter-"+this.key);if(t){this.select=t;var r=function(){e.select.classList.add("active")};this.select.addEventListener(L,r),this.select.addEventListener("mouseover",r),this.select.addEventListener("mouseleave",(function(){e.select.classList.remove("active")})),this.select.querySelectorAll("li").forEach((function(r){r.addEventListener(b,(function(r){t.classList.remove("active"),e.setValue(r.target.dataset.value||"")}))})),document.addEventListener(L,(function(t){e.select.contains(t.target)||e.select.classList.remove("active")}))}},t.prototype.handleValueChange=function(e,t){this.select.querySelectorAll("li.selected").forEach((function(e){e.classList.remove("selected")}));var r=this.select.querySelector('li[data-value="'+t+'"]'),n=this.select.querySelector(".tsd-select-label");r&&n&&(r.classList.add("selected"),n.textContent=r.textContent),document.documentElement.classList.remove("toggle-"+e),document.documentElement.classList.add("toggle-"+t)},t.prototype.fromLocalStorage=function(e){return e},t.prototype.toLocalStorage=function(e){return e},t}(R),F=function(e){function t(t){var r=e.call(this,t)||this;return r.optionVisibility=new j("visibility","private"),r.optionInherited=new I("inherited",!0),r.optionExternals=new I("externals",!0),r.optionOnlyExported=new I("only-exported",!1),r}return C(t,e),t.isSupported=function(){try{return void 0!==window.localStorage}catch(e){return!1}},t}(u);r(1);i(h,"#tsd-search"),i(v,".menu-highlight"),i(w,".tsd-signatures"),i(_,"a[data-toggle]"),F.isSupported()?i(F,"#tsd-filter"):document.documentElement.classList.add("no-filter");var N=new a;Object.defineProperty(window,"app",{value:N})}]); \ No newline at end of file diff --git a/docs/api/assets/js/search.json b/docs/api/assets/js/search.json index 386a3a9..4785944 100644 --- a/docs/api/assets/js/search.json +++ b/docs/api/assets/js/search.json @@ -1,35 +1 @@ -{ - "kinds": { "1": "Module", "64": "Function" }, - "rows": [ - { - "id": 0, - "kind": 1, - "name": "\"app/index\"", - "url": "modules/_app_index_.html", - "classes": "tsd-kind-module" - }, - { - "id": 1, - "kind": 64, - "name": "hello", - "url": "modules/_app_index_.html#hello", - "classes": "tsd-kind-function tsd-parent-kind-module", - "parent": "\"app/index\"" - } - ], - "index": { - "version": "2.3.9", - "fields": ["name", "parent"], - "fieldVectors": [ - ["name/0", [0, 1.823]], - ["parent/0", []], - ["name/1", [1, 6.931]], - ["parent/1", [0, 0.129]] - ], - "invertedIndex": [ - ["app/index", { "_index": 0, "name": { "0": {} }, "parent": { "1": {} } }], - ["hello", { "_index": 1, "name": { "1": {} }, "parent": {} }] - ], - "pipeline": [] - } -} +{"kinds":{"4":"Enumeration","16":"Enumeration member","32":"Variable","64":"Function","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","65536":"Type literal","2097152":"Object literal","4194304":"Type alias"},"rows":[{"id":0,"kind":2097152,"name":"_","url":"globals.html#_","classes":"tsd-kind-object-literal"},{"id":1,"kind":2097152,"name":"array","url":"globals.html#_.array","classes":"tsd-kind-object-literal tsd-parent-kind-object-literal","parent":"_"},{"id":2,"kind":64,"name":"contains","url":"globals.html#_.array.contains","classes":"tsd-kind-function tsd-parent-kind-object-literal tsd-has-type-parameter","parent":"_.array"},{"id":3,"kind":2097152,"name":"date","url":"globals.html#_.date","classes":"tsd-kind-object-literal tsd-parent-kind-object-literal","parent":"_"},{"id":4,"kind":64,"name":"sortOldToNew","url":"globals.html#_.date.sortoldtonew","classes":"tsd-kind-function tsd-parent-kind-object-literal","parent":"_.date"},{"id":5,"kind":64,"name":"sortNewToOld","url":"globals.html#_.date.sortnewtoold","classes":"tsd-kind-function tsd-parent-kind-object-literal","parent":"_.date"},{"id":6,"kind":256,"name":"AppleInAppPurchaseTransaction","url":"interfaces/appleinapppurchasetransaction.html","classes":"tsd-kind-interface"},{"id":7,"kind":1024,"name":"cancellation_date","url":"interfaces/appleinapppurchasetransaction.html#cancellation_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":8,"kind":1024,"name":"cancellation_date_ms","url":"interfaces/appleinapppurchasetransaction.html#cancellation_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":9,"kind":1024,"name":"cancellation_date_pst","url":"interfaces/appleinapppurchasetransaction.html#cancellation_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":10,"kind":1024,"name":"cancellation_reason","url":"interfaces/appleinapppurchasetransaction.html#cancellation_reason","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":11,"kind":1024,"name":"expires_date","url":"interfaces/appleinapppurchasetransaction.html#expires_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":12,"kind":1024,"name":"expires_date_ms","url":"interfaces/appleinapppurchasetransaction.html#expires_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":13,"kind":1024,"name":"expires_date_pst","url":"interfaces/appleinapppurchasetransaction.html#expires_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":14,"kind":1024,"name":"is_in_intro_offer_period","url":"interfaces/appleinapppurchasetransaction.html#is_in_intro_offer_period","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":15,"kind":1024,"name":"is_trial_period","url":"interfaces/appleinapppurchasetransaction.html#is_trial_period","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":16,"kind":1024,"name":"original_purchase_date","url":"interfaces/appleinapppurchasetransaction.html#original_purchase_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":17,"kind":1024,"name":"original_purchase_date_ms","url":"interfaces/appleinapppurchasetransaction.html#original_purchase_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":18,"kind":1024,"name":"original_purchase_date_pst","url":"interfaces/appleinapppurchasetransaction.html#original_purchase_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":19,"kind":1024,"name":"original_transaction_id","url":"interfaces/appleinapppurchasetransaction.html#original_transaction_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":20,"kind":1024,"name":"product_id","url":"interfaces/appleinapppurchasetransaction.html#product_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":21,"kind":1024,"name":"promotional_offer_id","url":"interfaces/appleinapppurchasetransaction.html#promotional_offer_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":22,"kind":1024,"name":"purchase_date","url":"interfaces/appleinapppurchasetransaction.html#purchase_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":23,"kind":1024,"name":"purchase_date_ms","url":"interfaces/appleinapppurchasetransaction.html#purchase_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":24,"kind":1024,"name":"purchase_date_pst","url":"interfaces/appleinapppurchasetransaction.html#purchase_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":25,"kind":1024,"name":"quantity","url":"interfaces/appleinapppurchasetransaction.html#quantity","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":26,"kind":1024,"name":"transaction_id","url":"interfaces/appleinapppurchasetransaction.html#transaction_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":27,"kind":1024,"name":"web_order_line_item_id","url":"interfaces/appleinapppurchasetransaction.html#web_order_line_item_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleInAppPurchaseTransaction"},{"id":28,"kind":256,"name":"AppleReceipt","url":"interfaces/applereceipt.html","classes":"tsd-kind-interface"},{"id":29,"kind":1024,"name":"adam_id","url":"interfaces/applereceipt.html#adam_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":30,"kind":1024,"name":"app_item_id","url":"interfaces/applereceipt.html#app_item_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":31,"kind":1024,"name":"application_version","url":"interfaces/applereceipt.html#application_version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":32,"kind":1024,"name":"bundle_id","url":"interfaces/applereceipt.html#bundle_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":33,"kind":1024,"name":"download_id","url":"interfaces/applereceipt.html#download_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":34,"kind":1024,"name":"expiration_date","url":"interfaces/applereceipt.html#expiration_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":35,"kind":1024,"name":"expiration_date_ms","url":"interfaces/applereceipt.html#expiration_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":36,"kind":1024,"name":"expiration_date_pst","url":"interfaces/applereceipt.html#expiration_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":37,"kind":1024,"name":"in_app","url":"interfaces/applereceipt.html#in_app","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":38,"kind":1024,"name":"original_application_version","url":"interfaces/applereceipt.html#original_application_version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":39,"kind":1024,"name":"original_purchase_date","url":"interfaces/applereceipt.html#original_purchase_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":40,"kind":1024,"name":"original_purchase_date_ms","url":"interfaces/applereceipt.html#original_purchase_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":41,"kind":1024,"name":"original_purchase_date_pst","url":"interfaces/applereceipt.html#original_purchase_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":42,"kind":1024,"name":"preorder_date","url":"interfaces/applereceipt.html#preorder_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":43,"kind":1024,"name":"preorder_date_ms","url":"interfaces/applereceipt.html#preorder_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":44,"kind":1024,"name":"preorder_date_pst","url":"interfaces/applereceipt.html#preorder_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":45,"kind":1024,"name":"receipt_creation_date","url":"interfaces/applereceipt.html#receipt_creation_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":46,"kind":1024,"name":"receipt_creation_date_ms","url":"interfaces/applereceipt.html#receipt_creation_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":47,"kind":1024,"name":"receipt_creation_date_pst","url":"interfaces/applereceipt.html#receipt_creation_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":48,"kind":1024,"name":"receipt_type","url":"interfaces/applereceipt.html#receipt_type","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":49,"kind":1024,"name":"request_date","url":"interfaces/applereceipt.html#request_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":50,"kind":1024,"name":"request_date_ms","url":"interfaces/applereceipt.html#request_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":51,"kind":1024,"name":"request_date_pst","url":"interfaces/applereceipt.html#request_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":52,"kind":1024,"name":"version_external_identifier","url":"interfaces/applereceipt.html#version_external_identifier","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleReceipt"},{"id":53,"kind":4194304,"name":"AppleLatestReceiptInfo","url":"globals.html#applelatestreceiptinfo","classes":"tsd-kind-type-alias"},{"id":54,"kind":256,"name":"ApplePendingRenewalInfo","url":"interfaces/applependingrenewalinfo.html","classes":"tsd-kind-interface"},{"id":55,"kind":1024,"name":"auto_renew_product_id","url":"interfaces/applependingrenewalinfo.html#auto_renew_product_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":56,"kind":1024,"name":"auto_renew_status","url":"interfaces/applependingrenewalinfo.html#auto_renew_status","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":57,"kind":1024,"name":"expiration_intent","url":"interfaces/applependingrenewalinfo.html#expiration_intent","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":58,"kind":1024,"name":"grace_period_expires_date","url":"interfaces/applependingrenewalinfo.html#grace_period_expires_date","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":59,"kind":1024,"name":"grace_period_expires_date_ms","url":"interfaces/applependingrenewalinfo.html#grace_period_expires_date_ms","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":60,"kind":1024,"name":"grace_period_expires_date_pst","url":"interfaces/applependingrenewalinfo.html#grace_period_expires_date_pst","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":61,"kind":1024,"name":"is_in_billing_retry_period","url":"interfaces/applependingrenewalinfo.html#is_in_billing_retry_period","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":62,"kind":1024,"name":"offer_code_ref_name","url":"interfaces/applependingrenewalinfo.html#offer_code_ref_name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":63,"kind":1024,"name":"original_transaction_id","url":"interfaces/applependingrenewalinfo.html#original_transaction_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":64,"kind":1024,"name":"price_consent_status","url":"interfaces/applependingrenewalinfo.html#price_consent_status","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":65,"kind":1024,"name":"product_id","url":"interfaces/applependingrenewalinfo.html#product_id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ApplePendingRenewalInfo"},{"id":66,"kind":256,"name":"AppleVerifyReceiptSuccessfulResponse","url":"interfaces/appleverifyreceiptsuccessfulresponse.html","classes":"tsd-kind-interface"},{"id":67,"kind":1024,"name":"environment","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#environment","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":68,"kind":1024,"name":"is-retryable","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#is_retryable","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":69,"kind":1024,"name":"latest_receipt","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#latest_receipt","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":70,"kind":1024,"name":"latest_receipt_info","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#latest_receipt_info","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":71,"kind":1024,"name":"pending_renewal_info","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#pending_renewal_info","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":72,"kind":1024,"name":"receipt","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#receipt","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":73,"kind":1024,"name":"status","url":"interfaces/appleverifyreceiptsuccessfulresponse.html#status","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptSuccessfulResponse"},{"id":74,"kind":4194304,"name":"AppleVerifyReceiptSuccessfulStatus","url":"globals.html#appleverifyreceiptsuccessfulstatus","classes":"tsd-kind-type-alias"},{"id":75,"kind":4194304,"name":"AppleVerifyReceiptResponse","url":"globals.html#appleverifyreceiptresponse","classes":"tsd-kind-type-alias"},{"id":76,"kind":4,"name":"AppleVerifyReceiptErrorCode","url":"enums/appleverifyreceipterrorcode.html","classes":"tsd-kind-enum"},{"id":77,"kind":16,"name":"NOT_POST","url":"enums/appleverifyreceipterrorcode.html#not_post","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":78,"kind":16,"name":"SHOULD_NOT_HAPPEN","url":"enums/appleverifyreceipterrorcode.html#should_not_happen","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":79,"kind":16,"name":"INVALID_RECEIPT_OR_DOWN","url":"enums/appleverifyreceipterrorcode.html#invalid_receipt_or_down","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":80,"kind":16,"name":"UNAUTHORIZED","url":"enums/appleverifyreceipterrorcode.html#unauthorized","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":81,"kind":16,"name":"WRONG_SHARED_SECRET","url":"enums/appleverifyreceipterrorcode.html#wrong_shared_secret","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":82,"kind":16,"name":"SERVICE_DOWN","url":"enums/appleverifyreceipterrorcode.html#service_down","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":83,"kind":16,"name":"USE_TEST_ENVIRONMENT","url":"enums/appleverifyreceipterrorcode.html#use_test_environment","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":84,"kind":16,"name":"USE_PRODUCTION_ENVIRONMENT","url":"enums/appleverifyreceipterrorcode.html#use_production_environment","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":85,"kind":16,"name":"APPLE_INTERNAL_ERROR","url":"enums/appleverifyreceipterrorcode.html#apple_internal_error","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":86,"kind":16,"name":"CUSTOMER_NOT_FOUND","url":"enums/appleverifyreceipterrorcode.html#customer_not_found","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"AppleVerifyReceiptErrorCode"},{"id":87,"kind":256,"name":"AppleVerifyReceiptErrorResponse","url":"interfaces/appleverifyreceipterrorresponse.html","classes":"tsd-kind-interface"},{"id":88,"kind":1024,"name":"status","url":"interfaces/appleverifyreceipterrorresponse.html#status","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AppleVerifyReceiptErrorResponse"},{"id":89,"kind":128,"name":"AppleError","url":"classes/appleerror.html","classes":"tsd-kind-class"},{"id":90,"kind":512,"name":"constructor","url":"classes/appleerror.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"AppleError"},{"id":91,"kind":1024,"name":"appleErrorCode","url":"classes/appleerror.html#appleerrorcode","classes":"tsd-kind-property tsd-parent-kind-class","parent":"AppleError"},{"id":92,"kind":1024,"name":"name","url":"classes/appleerror.html#name","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-inherited","parent":"AppleError"},{"id":93,"kind":1024,"name":"message","url":"classes/appleerror.html#message","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-inherited","parent":"AppleError"},{"id":94,"kind":1024,"name":"stack","url":"classes/appleerror.html#stack","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-inherited","parent":"AppleError"},{"id":95,"kind":1024,"name":"Error","url":"classes/appleerror.html#error","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-static","parent":"AppleError"},{"id":96,"kind":128,"name":"InternalError","url":"classes/internalerror.html","classes":"tsd-kind-class"},{"id":97,"kind":1024,"name":"name","url":"classes/internalerror.html#name","classes":"tsd-kind-property tsd-parent-kind-class","parent":"InternalError"},{"id":98,"kind":1024,"name":"message","url":"classes/internalerror.html#message","classes":"tsd-kind-property tsd-parent-kind-class","parent":"InternalError"},{"id":99,"kind":1024,"name":"stack","url":"classes/internalerror.html#stack","classes":"tsd-kind-property tsd-parent-kind-class","parent":"InternalError"},{"id":100,"kind":512,"name":"constructor","url":"classes/internalerror.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"InternalError"},{"id":101,"kind":2048,"name":"fromError","url":"classes/internalerror.html#fromerror","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"InternalError"},{"id":102,"kind":256,"name":"AutoRenewableSubscription","url":"interfaces/autorenewablesubscription.html","classes":"tsd-kind-interface"},{"id":103,"kind":1024,"name":"currentProductId","url":"interfaces/autorenewablesubscription.html#currentproductid","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":104,"kind":1024,"name":"originalTransactionId","url":"interfaces/autorenewablesubscription.html#originaltransactionid","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":105,"kind":1024,"name":"subscriptionGroup","url":"interfaces/autorenewablesubscription.html#subscriptiongroup","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":106,"kind":1024,"name":"isInFreeTrialPeriod","url":"interfaces/autorenewablesubscription.html#isinfreetrialperiod","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":107,"kind":1024,"name":"isEligibleIntroductoryOffer","url":"interfaces/autorenewablesubscription.html#iseligibleintroductoryoffer","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":108,"kind":1024,"name":"currentSubscriptionPeriodExpires","url":"interfaces/autorenewablesubscription.html#currentsubscriptionperiodexpires","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":109,"kind":1024,"name":"inactiveStatus","url":"interfaces/autorenewablesubscription.html#inactivestatus","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":110,"kind":1024,"name":"usedOfferCodes","url":"interfaces/autorenewablesubscription.html#usedoffercodes","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":111,"kind":1024,"name":"usedPromotionalOffers","url":"interfaces/autorenewablesubscription.html#usedpromotionaloffers","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":112,"kind":1024,"name":"allTransactions","url":"interfaces/autorenewablesubscription.html#alltransactions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":113,"kind":1024,"name":"mostRecentTransaction","url":"interfaces/autorenewablesubscription.html#mostrecenttransaction","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":114,"kind":1024,"name":"willAutoRenew","url":"interfaces/autorenewablesubscription.html#willautorenew","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":115,"kind":1024,"name":"willDowngradeToProductId","url":"interfaces/autorenewablesubscription.html#willdowngradetoproductid","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":116,"kind":1024,"name":"actionableStatuses","url":"interfaces/autorenewablesubscription.html#actionablestatuses","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":117,"kind":1024,"name":"priceIncreaseAccepted","url":"interfaces/autorenewablesubscription.html#priceincreaseaccepted","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":118,"kind":1024,"name":"gracePeriod","url":"interfaces/autorenewablesubscription.html#graceperiod","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"AutoRenewableSubscription"},{"id":119,"kind":4194304,"name":"AutoRenewableSubscriptionRefundReason","url":"globals.html#autorenewablesubscriptionrefundreason","classes":"tsd-kind-type-alias"},{"id":120,"kind":4194304,"name":"AutoRenewableSubscriptionTransaction","url":"globals.html#autorenewablesubscriptiontransaction","classes":"tsd-kind-type-alias"},{"id":121,"kind":65536,"name":"__type","url":"globals.html#autorenewablesubscriptiontransaction.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"AutoRenewableSubscriptionTransaction"},{"id":122,"kind":32,"name":"productId","url":"globals.html#autorenewablesubscriptiontransaction.__type.productid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":123,"kind":32,"name":"refundedDate","url":"globals.html#autorenewablesubscriptiontransaction.__type.refundeddate","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":124,"kind":32,"name":"refundReason","url":"globals.html#autorenewablesubscriptiontransaction.__type.refundreason","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":125,"kind":32,"name":"expiresDate","url":"globals.html#autorenewablesubscriptiontransaction.__type.expiresdate","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":126,"kind":32,"name":"inIntroPeriod","url":"globals.html#autorenewablesubscriptiontransaction.__type.inintroperiod","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":127,"kind":32,"name":"inTrialPeriod","url":"globals.html#autorenewablesubscriptiontransaction.__type.intrialperiod","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":128,"kind":32,"name":"isUpgradeTransaction","url":"globals.html#autorenewablesubscriptiontransaction.__type.isupgradetransaction","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":129,"kind":32,"name":"offerCodeRefName","url":"globals.html#autorenewablesubscriptiontransaction.__type.offercoderefname","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":130,"kind":32,"name":"originalPurchaseDate","url":"globals.html#autorenewablesubscriptiontransaction.__type.originalpurchasedate","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":131,"kind":32,"name":"originalTransactionId","url":"globals.html#autorenewablesubscriptiontransaction.__type.originaltransactionid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":132,"kind":32,"name":"promotionalOfferId","url":"globals.html#autorenewablesubscriptiontransaction.__type.promotionalofferid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":133,"kind":32,"name":"purchaseDate","url":"globals.html#autorenewablesubscriptiontransaction.__type.purchasedate","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":134,"kind":32,"name":"subscriptionGroupId","url":"globals.html#autorenewablesubscriptiontransaction.__type.subscriptiongroupid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":135,"kind":32,"name":"transactionId","url":"globals.html#autorenewablesubscriptiontransaction.__type.transactionid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":136,"kind":32,"name":"webOrderLineItemId","url":"globals.html#autorenewablesubscriptiontransaction.__type.weborderlineitemid","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"AutoRenewableSubscriptionTransaction.__type"},{"id":137,"kind":4194304,"name":"AutoRenewableSubscriptionActionableStatus","url":"globals.html#autorenewablesubscriptionactionablestatus","classes":"tsd-kind-type-alias"},{"id":138,"kind":4194304,"name":"AutoRenewableSubscriptionInactiveStatus","url":"globals.html#autorenewablesubscriptioninactivestatus","classes":"tsd-kind-type-alias"},{"id":139,"kind":256,"name":"ProductPurchaseTransaction","url":"interfaces/productpurchasetransaction.html","classes":"tsd-kind-interface"},{"id":140,"kind":1024,"name":"quantity","url":"interfaces/productpurchasetransaction.html#quantity","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProductPurchaseTransaction"},{"id":141,"kind":1024,"name":"transactionId","url":"interfaces/productpurchasetransaction.html#transactionid","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProductPurchaseTransaction"},{"id":142,"kind":1024,"name":"purchaseDate","url":"interfaces/productpurchasetransaction.html#purchasedate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProductPurchaseTransaction"},{"id":143,"kind":256,"name":"ProductPurchase","url":"interfaces/productpurchase.html","classes":"tsd-kind-interface"},{"id":144,"kind":1024,"name":"productId","url":"interfaces/productpurchase.html#productid","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProductPurchase"},{"id":145,"kind":1024,"name":"transactions","url":"interfaces/productpurchase.html#transactions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProductPurchase"},{"id":146,"kind":256,"name":"ParsedReceipt","url":"interfaces/parsedreceipt.html","classes":"tsd-kind-interface"},{"id":147,"kind":1024,"name":"environment","url":"interfaces/parsedreceipt.html#environment","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ParsedReceipt"},{"id":148,"kind":1024,"name":"auto_renewable_subscriptions","url":"interfaces/parsedreceipt.html#auto_renewable_subscriptions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ParsedReceipt"},{"id":149,"kind":1024,"name":"product_purchases","url":"interfaces/parsedreceipt.html#product_purchases","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ParsedReceipt"},{"id":150,"kind":1024,"name":"rawResponse","url":"interfaces/parsedreceipt.html#rawresponse","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ParsedReceipt"},{"id":151,"kind":1024,"name":"latestReceipt","url":"interfaces/parsedreceipt.html#latestreceipt","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ParsedReceipt"},{"id":152,"kind":64,"name":"parseSuccess","url":"globals.html#parsesuccess","classes":"tsd-kind-function"},{"id":153,"kind":256,"name":"VerifyReceiptOptions","url":"interfaces/verifyreceiptoptions.html","classes":"tsd-kind-interface"},{"id":154,"kind":1024,"name":"production","url":"interfaces/verifyreceiptoptions.html#production","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"VerifyReceiptOptions"},{"id":155,"kind":32,"name":"maxNumberHttpAttempts","url":"globals.html#maxnumberhttpattempts","classes":"tsd-kind-variable"},{"id":156,"kind":64,"name":"runVerifyReceipt","url":"globals.html#runverifyreceipt","classes":"tsd-kind-function"},{"id":157,"kind":4194304,"name":"VerifyReceiptFailure","url":"globals.html#verifyreceiptfailure","classes":"tsd-kind-type-alias"},{"id":158,"kind":65536,"name":"__type","url":"globals.html#verifyreceiptfailure.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"VerifyReceiptFailure"},{"id":159,"kind":32,"name":"error","url":"globals.html#verifyreceiptfailure.__type.error","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"VerifyReceiptFailure.__type"},{"id":160,"kind":4194304,"name":"VerifyReceiptResponse","url":"globals.html#verifyreceiptresponse","classes":"tsd-kind-type-alias"},{"id":161,"kind":64,"name":"verifyReceipt","url":"globals.html#verifyreceipt","classes":"tsd-kind-function"},{"id":162,"kind":64,"name":"isFailure","url":"globals.html#isfailure","classes":"tsd-kind-function"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,38.567]],["parent/0",[]],["name/1",[1,47.061]],["parent/1",[0,3.546]],["name/2",[2,47.061]],["parent/2",[3,4.327]],["name/3",[4,47.061]],["parent/3",[0,3.546]],["name/4",[5,47.061]],["parent/4",[6,3.856]],["name/5",[7,47.061]],["parent/5",[6,3.856]],["name/6",[8,19.913]],["parent/6",[]],["name/7",[9,47.061]],["parent/7",[8,1.831]],["name/8",[10,47.061]],["parent/8",[8,1.831]],["name/9",[11,47.061]],["parent/9",[8,1.831]],["name/10",[12,47.061]],["parent/10",[8,1.831]],["name/11",[13,47.061]],["parent/11",[8,1.831]],["name/12",[14,47.061]],["parent/12",[8,1.831]],["name/13",[15,47.061]],["parent/13",[8,1.831]],["name/14",[16,47.061]],["parent/14",[8,1.831]],["name/15",[17,47.061]],["parent/15",[8,1.831]],["name/16",[18,41.94]],["parent/16",[8,1.831]],["name/17",[19,41.94]],["parent/17",[8,1.831]],["name/18",[20,41.94]],["parent/18",[8,1.831]],["name/19",[21,41.94]],["parent/19",[8,1.831]],["name/20",[22,41.94]],["parent/20",[8,1.831]],["name/21",[23,47.061]],["parent/21",[8,1.831]],["name/22",[24,47.061]],["parent/22",[8,1.831]],["name/23",[25,47.061]],["parent/23",[8,1.831]],["name/24",[26,47.061]],["parent/24",[8,1.831]],["name/25",[27,41.94]],["parent/25",[8,1.831]],["name/26",[28,47.061]],["parent/26",[8,1.831]],["name/27",[29,47.061]],["parent/27",[8,1.831]],["name/28",[30,18.658]],["parent/28",[]],["name/29",[31,47.061]],["parent/29",[30,1.716]],["name/30",[32,47.061]],["parent/30",[30,1.716]],["name/31",[33,47.061]],["parent/31",[30,1.716]],["name/32",[34,47.061]],["parent/32",[30,1.716]],["name/33",[35,47.061]],["parent/33",[30,1.716]],["name/34",[36,47.061]],["parent/34",[30,1.716]],["name/35",[37,47.061]],["parent/35",[30,1.716]],["name/36",[38,47.061]],["parent/36",[30,1.716]],["name/37",[39,47.061]],["parent/37",[30,1.716]],["name/38",[40,47.061]],["parent/38",[30,1.716]],["name/39",[18,41.94]],["parent/39",[30,1.716]],["name/40",[19,41.94]],["parent/40",[30,1.716]],["name/41",[20,41.94]],["parent/41",[30,1.716]],["name/42",[41,47.061]],["parent/42",[30,1.716]],["name/43",[42,47.061]],["parent/43",[30,1.716]],["name/44",[43,47.061]],["parent/44",[30,1.716]],["name/45",[44,47.061]],["parent/45",[30,1.716]],["name/46",[45,47.061]],["parent/46",[30,1.716]],["name/47",[46,47.061]],["parent/47",[30,1.716]],["name/48",[47,47.061]],["parent/48",[30,1.716]],["name/49",[48,47.061]],["parent/49",[30,1.716]],["name/50",[49,47.061]],["parent/50",[30,1.716]],["name/51",[50,47.061]],["parent/51",[30,1.716]],["name/52",[51,47.061]],["parent/52",[30,1.716]],["name/53",[52,47.061]],["parent/53",[]],["name/54",[53,25.806]],["parent/54",[]],["name/55",[54,47.061]],["parent/55",[53,2.373]],["name/56",[55,47.061]],["parent/56",[53,2.373]],["name/57",[56,47.061]],["parent/57",[53,2.373]],["name/58",[57,47.061]],["parent/58",[53,2.373]],["name/59",[58,47.061]],["parent/59",[53,2.373]],["name/60",[59,47.061]],["parent/60",[53,2.373]],["name/61",[60,47.061]],["parent/61",[53,2.373]],["name/62",[61,47.061]],["parent/62",[53,2.373]],["name/63",[21,41.94]],["parent/63",[53,2.373]],["name/64",[62,47.061]],["parent/64",[53,2.373]],["name/65",[22,41.94]],["parent/65",[53,2.373]],["name/66",[63,29.672]],["parent/66",[]],["name/67",[64,41.94]],["parent/67",[63,2.728]],["name/68",[65,33.433,66,33.433]],["parent/68",[63,2.728]],["name/69",[67,47.061]],["parent/69",[63,2.728]],["name/70",[68,47.061]],["parent/70",[63,2.728]],["name/71",[69,47.061]],["parent/71",[63,2.728]],["name/72",[70,47.061]],["parent/72",[63,2.728]],["name/73",[71,41.94]],["parent/73",[63,2.728]],["name/74",[72,47.061]],["parent/74",[]],["name/75",[73,47.061]],["parent/75",[]],["name/76",[74,26.642]],["parent/76",[]],["name/77",[75,47.061]],["parent/77",[74,2.45]],["name/78",[76,47.061]],["parent/78",[74,2.45]],["name/79",[77,47.061]],["parent/79",[74,2.45]],["name/80",[78,47.061]],["parent/80",[74,2.45]],["name/81",[79,47.061]],["parent/81",[74,2.45]],["name/82",[80,47.061]],["parent/82",[74,2.45]],["name/83",[81,47.061]],["parent/83",[74,2.45]],["name/84",[82,47.061]],["parent/84",[74,2.45]],["name/85",[83,47.061]],["parent/85",[74,2.45]],["name/86",[84,47.061]],["parent/86",[74,2.45]],["name/87",[85,41.94]],["parent/87",[]],["name/88",[71,41.94]],["parent/88",[85,3.856]],["name/89",[86,30.927]],["parent/89",[]],["name/90",[87,41.94]],["parent/90",[86,2.844]],["name/91",[88,47.061]],["parent/91",[86,2.844]],["name/92",[89,41.94]],["parent/92",[86,2.844]],["name/93",[90,41.94]],["parent/93",[86,2.844]],["name/94",[91,41.94]],["parent/94",[86,2.844]],["name/95",[92,41.94]],["parent/95",[86,2.844]],["name/96",[93,32.361]],["parent/96",[]],["name/97",[89,41.94]],["parent/97",[93,2.976]],["name/98",[90,41.94]],["parent/98",[93,2.976]],["name/99",[91,41.94]],["parent/99",[93,2.976]],["name/100",[87,41.94]],["parent/100",[93,2.976]],["name/101",[94,47.061]],["parent/101",[93,2.976]],["name/102",[95,22.433]],["parent/102",[]],["name/103",[96,47.061]],["parent/103",[95,2.063]],["name/104",[97,41.94]],["parent/104",[95,2.063]],["name/105",[98,47.061]],["parent/105",[95,2.063]],["name/106",[99,47.061]],["parent/106",[95,2.063]],["name/107",[100,47.061]],["parent/107",[95,2.063]],["name/108",[101,47.061]],["parent/108",[95,2.063]],["name/109",[102,47.061]],["parent/109",[95,2.063]],["name/110",[103,47.061]],["parent/110",[95,2.063]],["name/111",[104,47.061]],["parent/111",[95,2.063]],["name/112",[105,47.061]],["parent/112",[95,2.063]],["name/113",[106,47.061]],["parent/113",[95,2.063]],["name/114",[107,47.061]],["parent/114",[95,2.063]],["name/115",[108,47.061]],["parent/115",[95,2.063]],["name/116",[109,47.061]],["parent/116",[95,2.063]],["name/117",[110,47.061]],["parent/117",[95,2.063]],["name/118",[111,47.061]],["parent/118",[95,2.063]],["name/119",[112,47.061]],["parent/119",[]],["name/120",[113,41.94]],["parent/120",[]],["name/121",[114,41.94]],["parent/121",[113,3.856]],["name/122",[115,41.94]],["parent/122",[116,2.175]],["name/123",[117,47.061]],["parent/123",[116,2.175]],["name/124",[118,47.061]],["parent/124",[116,2.175]],["name/125",[119,47.061]],["parent/125",[116,2.175]],["name/126",[120,47.061]],["parent/126",[116,2.175]],["name/127",[121,47.061]],["parent/127",[116,2.175]],["name/128",[122,47.061]],["parent/128",[116,2.175]],["name/129",[123,47.061]],["parent/129",[116,2.175]],["name/130",[124,47.061]],["parent/130",[116,2.175]],["name/131",[97,41.94]],["parent/131",[116,2.175]],["name/132",[125,47.061]],["parent/132",[116,2.175]],["name/133",[126,41.94]],["parent/133",[116,2.175]],["name/134",[127,47.061]],["parent/134",[116,2.175]],["name/135",[128,41.94]],["parent/135",[116,2.175]],["name/136",[129,47.061]],["parent/136",[116,2.175]],["name/137",[130,47.061]],["parent/137",[]],["name/138",[131,47.061]],["parent/138",[]],["name/139",[132,36.048]],["parent/139",[]],["name/140",[27,41.94]],["parent/140",[132,3.315]],["name/141",[128,41.94]],["parent/141",[132,3.315]],["name/142",[126,41.94]],["parent/142",[132,3.315]],["name/143",[133,38.567]],["parent/143",[]],["name/144",[115,41.94]],["parent/144",[133,3.546]],["name/145",[134,47.061]],["parent/145",[133,3.546]],["name/146",[135,32.361]],["parent/146",[]],["name/147",[64,41.94]],["parent/147",[135,2.976]],["name/148",[136,47.061]],["parent/148",[135,2.976]],["name/149",[137,47.061]],["parent/149",[135,2.976]],["name/150",[138,47.061]],["parent/150",[135,2.976]],["name/151",[139,47.061]],["parent/151",[135,2.976]],["name/152",[140,47.061]],["parent/152",[]],["name/153",[141,41.94]],["parent/153",[]],["name/154",[142,47.061]],["parent/154",[141,3.856]],["name/155",[143,47.061]],["parent/155",[]],["name/156",[144,47.061]],["parent/156",[]],["name/157",[145,41.94]],["parent/157",[]],["name/158",[114,41.94]],["parent/158",[145,3.856]],["name/159",[92,41.94]],["parent/159",[146,4.327]],["name/160",[147,47.061]],["parent/160",[]],["name/161",[148,47.061]],["parent/161",[]],["name/162",[149,47.061]],["parent/162",[]]],"invertedIndex":[["_",{"_index":0,"name":{"0":{}},"parent":{"1":{},"3":{}}}],["_.array",{"_index":3,"name":{},"parent":{"2":{}}}],["_.date",{"_index":6,"name":{},"parent":{"4":{},"5":{}}}],["__type",{"_index":114,"name":{"121":{},"158":{}},"parent":{}}],["actionablestatuses",{"_index":109,"name":{"116":{}},"parent":{}}],["adam_id",{"_index":31,"name":{"29":{}},"parent":{}}],["alltransactions",{"_index":105,"name":{"112":{}},"parent":{}}],["app_item_id",{"_index":32,"name":{"30":{}},"parent":{}}],["apple_internal_error",{"_index":83,"name":{"85":{}},"parent":{}}],["appleerror",{"_index":86,"name":{"89":{}},"parent":{"90":{},"91":{},"92":{},"93":{},"94":{},"95":{}}}],["appleerrorcode",{"_index":88,"name":{"91":{}},"parent":{}}],["appleinapppurchasetransaction",{"_index":8,"name":{"6":{}},"parent":{"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"21":{},"22":{},"23":{},"24":{},"25":{},"26":{},"27":{}}}],["applelatestreceiptinfo",{"_index":52,"name":{"53":{}},"parent":{}}],["applependingrenewalinfo",{"_index":53,"name":{"54":{}},"parent":{"55":{},"56":{},"57":{},"58":{},"59":{},"60":{},"61":{},"62":{},"63":{},"64":{},"65":{}}}],["applereceipt",{"_index":30,"name":{"28":{}},"parent":{"29":{},"30":{},"31":{},"32":{},"33":{},"34":{},"35":{},"36":{},"37":{},"38":{},"39":{},"40":{},"41":{},"42":{},"43":{},"44":{},"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"52":{}}}],["appleverifyreceipterrorcode",{"_index":74,"name":{"76":{}},"parent":{"77":{},"78":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{}}}],["appleverifyreceipterrorresponse",{"_index":85,"name":{"87":{}},"parent":{"88":{}}}],["appleverifyreceiptresponse",{"_index":73,"name":{"75":{}},"parent":{}}],["appleverifyreceiptsuccessfulresponse",{"_index":63,"name":{"66":{}},"parent":{"67":{},"68":{},"69":{},"70":{},"71":{},"72":{},"73":{}}}],["appleverifyreceiptsuccessfulstatus",{"_index":72,"name":{"74":{}},"parent":{}}],["application_version",{"_index":33,"name":{"31":{}},"parent":{}}],["array",{"_index":1,"name":{"1":{}},"parent":{}}],["auto_renew_product_id",{"_index":54,"name":{"55":{}},"parent":{}}],["auto_renew_status",{"_index":55,"name":{"56":{}},"parent":{}}],["auto_renewable_subscriptions",{"_index":136,"name":{"148":{}},"parent":{}}],["autorenewablesubscription",{"_index":95,"name":{"102":{}},"parent":{"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{}}}],["autorenewablesubscriptionactionablestatus",{"_index":130,"name":{"137":{}},"parent":{}}],["autorenewablesubscriptioninactivestatus",{"_index":131,"name":{"138":{}},"parent":{}}],["autorenewablesubscriptionrefundreason",{"_index":112,"name":{"119":{}},"parent":{}}],["autorenewablesubscriptiontransaction",{"_index":113,"name":{"120":{}},"parent":{"121":{}}}],["autorenewablesubscriptiontransaction.__type",{"_index":116,"name":{},"parent":{"122":{},"123":{},"124":{},"125":{},"126":{},"127":{},"128":{},"129":{},"130":{},"131":{},"132":{},"133":{},"134":{},"135":{},"136":{}}}],["bundle_id",{"_index":34,"name":{"32":{}},"parent":{}}],["cancellation_date",{"_index":9,"name":{"7":{}},"parent":{}}],["cancellation_date_ms",{"_index":10,"name":{"8":{}},"parent":{}}],["cancellation_date_pst",{"_index":11,"name":{"9":{}},"parent":{}}],["cancellation_reason",{"_index":12,"name":{"10":{}},"parent":{}}],["constructor",{"_index":87,"name":{"90":{},"100":{}},"parent":{}}],["contains",{"_index":2,"name":{"2":{}},"parent":{}}],["currentproductid",{"_index":96,"name":{"103":{}},"parent":{}}],["currentsubscriptionperiodexpires",{"_index":101,"name":{"108":{}},"parent":{}}],["customer_not_found",{"_index":84,"name":{"86":{}},"parent":{}}],["date",{"_index":4,"name":{"3":{}},"parent":{}}],["download_id",{"_index":35,"name":{"33":{}},"parent":{}}],["environment",{"_index":64,"name":{"67":{},"147":{}},"parent":{}}],["error",{"_index":92,"name":{"95":{},"159":{}},"parent":{}}],["expiration_date",{"_index":36,"name":{"34":{}},"parent":{}}],["expiration_date_ms",{"_index":37,"name":{"35":{}},"parent":{}}],["expiration_date_pst",{"_index":38,"name":{"36":{}},"parent":{}}],["expiration_intent",{"_index":56,"name":{"57":{}},"parent":{}}],["expires_date",{"_index":13,"name":{"11":{}},"parent":{}}],["expires_date_ms",{"_index":14,"name":{"12":{}},"parent":{}}],["expires_date_pst",{"_index":15,"name":{"13":{}},"parent":{}}],["expiresdate",{"_index":119,"name":{"125":{}},"parent":{}}],["fromerror",{"_index":94,"name":{"101":{}},"parent":{}}],["grace_period_expires_date",{"_index":57,"name":{"58":{}},"parent":{}}],["grace_period_expires_date_ms",{"_index":58,"name":{"59":{}},"parent":{}}],["grace_period_expires_date_pst",{"_index":59,"name":{"60":{}},"parent":{}}],["graceperiod",{"_index":111,"name":{"118":{}},"parent":{}}],["in_app",{"_index":39,"name":{"37":{}},"parent":{}}],["inactivestatus",{"_index":102,"name":{"109":{}},"parent":{}}],["inintroperiod",{"_index":120,"name":{"126":{}},"parent":{}}],["internalerror",{"_index":93,"name":{"96":{}},"parent":{"97":{},"98":{},"99":{},"100":{},"101":{}}}],["intrialperiod",{"_index":121,"name":{"127":{}},"parent":{}}],["invalid_receipt_or_down",{"_index":77,"name":{"79":{}},"parent":{}}],["is",{"_index":65,"name":{"68":{}},"parent":{}}],["is_in_billing_retry_period",{"_index":60,"name":{"61":{}},"parent":{}}],["is_in_intro_offer_period",{"_index":16,"name":{"14":{}},"parent":{}}],["is_trial_period",{"_index":17,"name":{"15":{}},"parent":{}}],["iseligibleintroductoryoffer",{"_index":100,"name":{"107":{}},"parent":{}}],["isfailure",{"_index":149,"name":{"162":{}},"parent":{}}],["isinfreetrialperiod",{"_index":99,"name":{"106":{}},"parent":{}}],["isupgradetransaction",{"_index":122,"name":{"128":{}},"parent":{}}],["latest_receipt",{"_index":67,"name":{"69":{}},"parent":{}}],["latest_receipt_info",{"_index":68,"name":{"70":{}},"parent":{}}],["latestreceipt",{"_index":139,"name":{"151":{}},"parent":{}}],["maxnumberhttpattempts",{"_index":143,"name":{"155":{}},"parent":{}}],["message",{"_index":90,"name":{"93":{},"98":{}},"parent":{}}],["mostrecenttransaction",{"_index":106,"name":{"113":{}},"parent":{}}],["name",{"_index":89,"name":{"92":{},"97":{}},"parent":{}}],["not_post",{"_index":75,"name":{"77":{}},"parent":{}}],["offer_code_ref_name",{"_index":61,"name":{"62":{}},"parent":{}}],["offercoderefname",{"_index":123,"name":{"129":{}},"parent":{}}],["original_application_version",{"_index":40,"name":{"38":{}},"parent":{}}],["original_purchase_date",{"_index":18,"name":{"16":{},"39":{}},"parent":{}}],["original_purchase_date_ms",{"_index":19,"name":{"17":{},"40":{}},"parent":{}}],["original_purchase_date_pst",{"_index":20,"name":{"18":{},"41":{}},"parent":{}}],["original_transaction_id",{"_index":21,"name":{"19":{},"63":{}},"parent":{}}],["originalpurchasedate",{"_index":124,"name":{"130":{}},"parent":{}}],["originaltransactionid",{"_index":97,"name":{"104":{},"131":{}},"parent":{}}],["parsedreceipt",{"_index":135,"name":{"146":{}},"parent":{"147":{},"148":{},"149":{},"150":{},"151":{}}}],["parsesuccess",{"_index":140,"name":{"152":{}},"parent":{}}],["pending_renewal_info",{"_index":69,"name":{"71":{}},"parent":{}}],["preorder_date",{"_index":41,"name":{"42":{}},"parent":{}}],["preorder_date_ms",{"_index":42,"name":{"43":{}},"parent":{}}],["preorder_date_pst",{"_index":43,"name":{"44":{}},"parent":{}}],["price_consent_status",{"_index":62,"name":{"64":{}},"parent":{}}],["priceincreaseaccepted",{"_index":110,"name":{"117":{}},"parent":{}}],["product_id",{"_index":22,"name":{"20":{},"65":{}},"parent":{}}],["product_purchases",{"_index":137,"name":{"149":{}},"parent":{}}],["productid",{"_index":115,"name":{"122":{},"144":{}},"parent":{}}],["production",{"_index":142,"name":{"154":{}},"parent":{}}],["productpurchase",{"_index":133,"name":{"143":{}},"parent":{"144":{},"145":{}}}],["productpurchasetransaction",{"_index":132,"name":{"139":{}},"parent":{"140":{},"141":{},"142":{}}}],["promotional_offer_id",{"_index":23,"name":{"21":{}},"parent":{}}],["promotionalofferid",{"_index":125,"name":{"132":{}},"parent":{}}],["purchase_date",{"_index":24,"name":{"22":{}},"parent":{}}],["purchase_date_ms",{"_index":25,"name":{"23":{}},"parent":{}}],["purchase_date_pst",{"_index":26,"name":{"24":{}},"parent":{}}],["purchasedate",{"_index":126,"name":{"133":{},"142":{}},"parent":{}}],["quantity",{"_index":27,"name":{"25":{},"140":{}},"parent":{}}],["rawresponse",{"_index":138,"name":{"150":{}},"parent":{}}],["receipt",{"_index":70,"name":{"72":{}},"parent":{}}],["receipt_creation_date",{"_index":44,"name":{"45":{}},"parent":{}}],["receipt_creation_date_ms",{"_index":45,"name":{"46":{}},"parent":{}}],["receipt_creation_date_pst",{"_index":46,"name":{"47":{}},"parent":{}}],["receipt_type",{"_index":47,"name":{"48":{}},"parent":{}}],["refundeddate",{"_index":117,"name":{"123":{}},"parent":{}}],["refundreason",{"_index":118,"name":{"124":{}},"parent":{}}],["request_date",{"_index":48,"name":{"49":{}},"parent":{}}],["request_date_ms",{"_index":49,"name":{"50":{}},"parent":{}}],["request_date_pst",{"_index":50,"name":{"51":{}},"parent":{}}],["retryable",{"_index":66,"name":{"68":{}},"parent":{}}],["runverifyreceipt",{"_index":144,"name":{"156":{}},"parent":{}}],["service_down",{"_index":80,"name":{"82":{}},"parent":{}}],["should_not_happen",{"_index":76,"name":{"78":{}},"parent":{}}],["sortnewtoold",{"_index":7,"name":{"5":{}},"parent":{}}],["sortoldtonew",{"_index":5,"name":{"4":{}},"parent":{}}],["stack",{"_index":91,"name":{"94":{},"99":{}},"parent":{}}],["status",{"_index":71,"name":{"73":{},"88":{}},"parent":{}}],["subscriptiongroup",{"_index":98,"name":{"105":{}},"parent":{}}],["subscriptiongroupid",{"_index":127,"name":{"134":{}},"parent":{}}],["transaction_id",{"_index":28,"name":{"26":{}},"parent":{}}],["transactionid",{"_index":128,"name":{"135":{},"141":{}},"parent":{}}],["transactions",{"_index":134,"name":{"145":{}},"parent":{}}],["unauthorized",{"_index":78,"name":{"80":{}},"parent":{}}],["use_production_environment",{"_index":82,"name":{"84":{}},"parent":{}}],["use_test_environment",{"_index":81,"name":{"83":{}},"parent":{}}],["usedoffercodes",{"_index":103,"name":{"110":{}},"parent":{}}],["usedpromotionaloffers",{"_index":104,"name":{"111":{}},"parent":{}}],["verifyreceipt",{"_index":148,"name":{"161":{}},"parent":{}}],["verifyreceiptfailure",{"_index":145,"name":{"157":{}},"parent":{"158":{}}}],["verifyreceiptfailure.__type",{"_index":146,"name":{},"parent":{"159":{}}}],["verifyreceiptoptions",{"_index":141,"name":{"153":{}},"parent":{"154":{}}}],["verifyreceiptresponse",{"_index":147,"name":{"160":{}},"parent":{}}],["version_external_identifier",{"_index":51,"name":{"52":{}},"parent":{}}],["web_order_line_item_id",{"_index":29,"name":{"27":{}},"parent":{}}],["weborderlineitemid",{"_index":129,"name":{"136":{}},"parent":{}}],["willautorenew",{"_index":107,"name":{"114":{}},"parent":{}}],["willdowngradetoproductid",{"_index":108,"name":{"115":{}},"parent":{}}],["wrong_shared_secret",{"_index":79,"name":{"81":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/api/classes/appleerror.html b/docs/api/classes/appleerror.html new file mode 100644 index 0000000..b49cab5 --- /dev/null +++ b/docs/api/classes/appleerror.html @@ -0,0 +1,364 @@ + + + + + + AppleError | dollabill-apple + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+ +
+
+
+
+
+

An error came back from Apple.

+
+
+
+
+

Hierarchy

+
    +
  • + Error +
      +
    • + AppleError +
    • +
    +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+ + +
+
+
+

Properties

+
+ +

appleErrorCode

+ + +
+
+ +

message

+
message: string
+ +
+
+ +

name

+
name: string
+ +
+
+ +

Optional stack

+
stack: undefined | string
+ +
+
+ +

Static Error

+
Error: ErrorConstructor
+ +
+
+
+
+

Legend

+
+
    +
  • Constructor
  • +
  • Property
  • +
+
    +
  • Static property
  • +
  • Static method
  • +
+
    +
  • Property
  • +
+
    +
  • Inherited property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+
+ + + \ No newline at end of file diff --git a/docs/api/classes/internalerror.html b/docs/api/classes/internalerror.html new file mode 100644 index 0000000..83bab5a --- /dev/null +++ b/docs/api/classes/internalerror.html @@ -0,0 +1,376 @@ + + + + + + InternalError | dollabill-apple + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+ +
+
+
+
+
+

Goals of this class:

+
    +
  1. Prompt the developer to file a bug report.
  2. +
  3. Include in this error all of the information from the given error so we can fix the issue.
  4. +
+
+
+
+
+

Hierarchy

+
    +
  • + InternalError +
  • +
+
+
+

Implements

+ +
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new InternalError(name: string, message: string, stack?: undefined | string): InternalError
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      name: string
      +
    • +
    • +
      message: string
      +
    • +
    • +
      Optional stack: undefined | string
      +
    • +
    +

    Returns InternalError

    +
  • +
+
+
+
+

Properties

+
+ +

message

+
message: string
+ +
+
+ +

name

+
name: string
+ +
+
+ +

stack

+
stack: string
+ +
+
+
+

Methods

+
+ +

Static fromError

+ +
    +
  • + +

    Parameters

    + +

    Returns InternalError

    +
  • +
+
+
+
+
+

Legend

+
+
    +
  • Constructor
  • +
  • Property
  • +
+
    +
  • Static property
  • +
  • Static method
  • +
+
    +
  • Property
  • +
+
    +
  • Inherited property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+
+ + + \ No newline at end of file diff --git a/docs/api/enums/appleverifyreceipterrorcode.html b/docs/api/enums/appleverifyreceipterrorcode.html new file mode 100644 index 0000000..9f0c5e9 --- /dev/null +++ b/docs/api/enums/appleverifyreceipterrorcode.html @@ -0,0 +1,381 @@ + + + + + + AppleVerifyReceiptErrorCode | dollabill-apple + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+ +
+
+
+
+
+

All of the statuses that are not successful. Apple was not able to provide back receipt information.

+
+

Official Apple documentation

+
+
+
+

Index

+
+ +
+
+
+

Enumeration members

+
+ +

APPLE_INTERNAL_ERROR

+
APPLE_INTERNAL_ERROR: = 21009
+ +
+
+ +

CUSTOMER_NOT_FOUND

+
CUSTOMER_NOT_FOUND: = 21010
+ +
+
+ +

INVALID_RECEIPT_OR_DOWN

+
INVALID_RECEIPT_OR_DOWN: = 21002
+ +
+
+ +

NOT_POST

+
NOT_POST: = 21000
+ +
+
+ +

SERVICE_DOWN

+
SERVICE_DOWN: = 21005
+ +
+
+ +

SHOULD_NOT_HAPPEN

+
SHOULD_NOT_HAPPEN: = 21001
+ +
+
+ +

UNAUTHORIZED

+
UNAUTHORIZED: = 21003
+ +
+
+ +

USE_PRODUCTION_ENVIRONMENT

+
USE_PRODUCTION_ENVIRONMENT: = 21008
+ +
+
+ +

USE_TEST_ENVIRONMENT

+
USE_TEST_ENVIRONMENT: = 21007
+ +
+
+ +

WRONG_SHARED_SECRET

+
WRONG_SHARED_SECRET: = 21004
+ +
+
+
+
+

Legend

+
+
    +
  • Constructor
  • +
  • Property
  • +
+
    +
  • Static property
  • +
  • Static method
  • +
+
    +
  • Property
  • +
+
    +
  • Inherited property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+
+ + + \ No newline at end of file diff --git a/docs/api/globals.html b/docs/api/globals.html index bdb6e0a..0096596 100644 --- a/docs/api/globals.html +++ b/docs/api/globals.html @@ -3,8 +3,8 @@ - npm-module-blanky | npm-module-blanky - + dollabill-apple | dollabill-apple + @@ -15,7 +15,7 @@
@@ -45,43 +45,763 @@
- -

npm-module-blanky

+
+

dolla bill

-

Opinionated boilerplate used to make and deploy npm modules.

- -

Goals of this project

+

Easily work with Apple in-app purchases. So you can more easily collect your "Dolla dolla bills, ya'll"

+
+

Why use dolla bill?

+

When you are accepting in-app purchases in an iOS mobile app, you need to verify the transaction and continuously update your customer's subscription status. This verification and parsing of the responses back from Apple is boilerplate. This small module exists to help you with these tasks.

    -
  • Contain configuration files to setup all tools I tend to use in my development flow.
  • -
  • Clone, rename some files, and get developing!
  • -
  • Start with zero dependencies. I try my best to keep all npm modules as slim as possible.
  • +
  • No dependencies. This module tries to be as small as possible.
  • +
  • Fully tested. Automated testing + QA testing gives you the confidence that the module will work well for you.
  • +
  • Complete API documentation to more easily use it in your code.
  • +
  • Up-to-date If and when Apple changes the way you perform verification or Apple adds more features to verification, update this module and your projects can take advantage of the changes quickly and easily.
  • +
  • Auto retry If there is a HTTP error, dolla bill will try again for you.
  • +
  • Typescript typings This project is written in Typescript for that strict typing goodness.
+
+

Note: Technically there is one dependency but it's a tiny wrapper around a built-in nodejs feature. This module still remains super small with this.

+
+ +

Getting started

+
+
import dollaBill from "dollabill"
+
+const receiptFromStoreKit = // The base64 encoded receipt data that StoreKit gave your app
+
+const appleResponse = await dollaBill.verifyReceipt({
+    appPassword: process.env.APPLE_IN_APP_PURCHASE_PASSWORD,
+    receipt: receiptFromStoreKit
+})
+
+// If an error happens, it's fatal. It means that there is a bug with this library (create a GitHub issue with stacktrace and other info, please) or you the developer made a mistake when using this library.
+
+// It's recommended that you, the developer, views the error message and stacktrace to fix the issue. Note: The error here is not meant to be shown to your users.
+
+if (!appleResponse.isValid) {
+    // There was a problem. The request was valid and can be retried.
+
+    // look at the error and act on it however you wish.
+    // It's recommended that you log the error and then return back a message to your users saying there was a problem. The error here is meant for the developer to see, not a good error to return back to the user.
+    appleResponse.error
+} else {
+    // Time for you to update your database with the status of your customer and their subscription.
+    // This is easy because dolla bill parses the response from Apple to be easily readable.
+    // Check out the API documentation to learn about what `appleResponse` properties there are.
+}
+
type Response = AppleResponse | AppleError
+
+enum AppleErrorType {}
+// TODO
+
+type AppleError = {
+  code: number
+  type: AppleErrorType
+}
+
+type AppleResponse = {
+  isValid: boolean
+  autoRenewableSubscription?: AutoRenewableSubscription // If your in-app purchase is for auto renewable subscriptions, go here.
+  decodedReceipt: Receipt
+  raw: any // just in case you need it, here is the raw JSON response from Apple. https://developer.apple.com/documentation/appstorereceipts/responsebody
+}
+
+type AutoRenewableSubscription = {
+  transactions: Array<Transaction>
+  pendingRenewals: Array<PendingRenewal>
+  isGracePeriod: bool
+  gracePeriod: GracePeriodInfo
+}
+
+type GracePeriodInfo = {
+  // TODO
+  // make this up. it comes from: https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info
+}
+
+type PendingRenewal = {
+  // TODO
+  // https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info
+}
+
+type Transaction = {
+  // TODO
+  // https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info
+}
+
+type Receipt = {
+  // TODO
+  // https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt
+}
+ +

Documentation

+
+

// TODO

+ +

Contributors

+
+

Thanks goes to these wonderful people (emoji key)

+ + + + + + + +

Levi Bostian

💻 📖 🚧
+ + +

Index

+
+

Type aliases

+
+ +

AppleLatestReceiptInfo

+
AppleLatestReceiptInfo: AppleInAppPurchaseTransaction & { is_upgraded?: undefined | "true"; offer_code_ref_name?: undefined | string; subscription_group_identifier?: undefined | string }
+ + +
+
+ +

AppleVerifyReceiptResponse

+ + +
+
+ +

AppleVerifyReceiptSuccessfulStatus

+
AppleVerifyReceiptSuccessfulStatus: 0 | 21006
+ +
+
+

All of the statuses that are successful. Apple is able to return back receipt information when any of these status codes occur.

+
+
+

Note: 0 means the receipt is valid. 21006 means it's valid, but the subscription is expired. You will still receive back a receipt decoded in the response with this status code.

+
+

Official Apple documentation

+
+
+
+ +

AutoRenewableSubscriptionActionableStatus

+
AutoRenewableSubscriptionActionableStatus: "not_yet_accepting_price_increase" | "cancelled" | "billing_issue" | "will_voluntary_cancel"
+ +
+
+

Options:

+
    +
  1. not_yet_accepting_price_increase - You have introduced a price increase. The customer has been notified about it but has not yet accepted it. This means the customer's subscription may be expired if they do not accept it.
  2. +
  3. cancelled - recently cancelled through Apple Support. good to message them to check out an alternative subscription we offer
  4. +
  5. billing_issue - the subscription expired because of a billing issue.
  6. +
  7. will_voluntary_cancel // time to send them UI saying to downgrade to try and keep them
  8. +
+
+
+
+
+ +

AutoRenewableSubscriptionInactiveStatus

+
AutoRenewableSubscriptionInactiveStatus: "voluntary_cancelled" | "in_grace_period" | "involuntary_cancelled" | "refunded"
+ +
+
+

Options: + 2. voluntary_cancel - they cancelled the subscription. You should not give the customer any access to the paid content. + 3. grace_period - There is a billing issue and Apple is attempting to automatically renew the subscription. Grace period means the customer has not cancelled or refunded. You have not yet lost them as a customer. Learn more about Grace Periods in the main docs for this project.

+
+
+

Tip: You can open the link https://apps.apple.com/account/billing to send the user to their payment details page in the App Store to update their payment information.

+
+
    +
  1. involuntary_cancel - the customer had a billing issue and their subscription is no longer active. Maybe you (1) did not enable the Grace Period feature in App Store Connect and the customer has encountered a billing issue or (2) you did enable the Grace Period feature but Apple has since given up on attempting to renew the subscription for the customer. You should no longer give the customer access to the paid content.
  2. +
  3. refunded - the customer contacted Apple support and asked for a refund of their purchase and received the partial or full refund. You should not give the customer any access to the paid content. You may optionally offer another subscription plan to them to switch to a different offer that meets their needs better.
  4. +
+
+
+
+ +

AutoRenewableSubscriptionRefundReason

+
AutoRenewableSubscriptionRefundReason: "upgrade" | "app_issue" | "other"
+ +
+
+ +

AutoRenewableSubscriptionTransaction

+
AutoRenewableSubscriptionTransaction: { expiresDate: Date; inIntroPeriod: boolean; inTrialPeriod: boolean; isUpgradeTransaction: boolean; offerCodeRefName?: undefined | string; originalPurchaseDate: Date; originalTransactionId: string; productId: string; promotionalOfferId?: undefined | string; purchaseDate: Date; refundReason?: AutoRenewableSubscriptionRefundReason; refundedDate?: Date; subscriptionGroupId: string; transactionId: string; webOrderLineItemId?: undefined | string }
+ +
+
+

Receipt for an auto-renewable subscription.

+
+
+
+

Type declaration

+
    +
  • +
    expiresDate: Date
    +
  • +
  • +
    inIntroPeriod: boolean
    +
  • +
  • +
    inTrialPeriod: boolean
    +
  • +
  • +
    isUpgradeTransaction: boolean
    +
  • +
  • +
    Optional offerCodeRefName?: undefined | string
    +
  • +
  • +
    originalPurchaseDate: Date
    +
  • +
  • +
    originalTransactionId: string
    +
  • +
  • +
    productId: string
    +
  • +
  • +
    Optional promotionalOfferId?: undefined | string
    +
  • +
  • +
    purchaseDate: Date
    +
  • +
  • +
    Optional refundReason?: AutoRenewableSubscriptionRefundReason
    +
  • +
  • +
    Optional refundedDate?: Date
    +
  • +
  • +
    subscriptionGroupId: string
    +
  • +
  • +
    transactionId: string
    +
  • +
  • +
    Optional webOrderLineItemId?: undefined | string
    +
  • +
+
+
+
+ +

VerifyReceiptFailure

+
VerifyReceiptFailure: { error: Error }
+ +
+

Type declaration

+ +
+
+
+ +

VerifyReceiptResponse

+
VerifyReceiptResponse: ParsedReceipt | VerifyReceiptFailure
+ +
+
+
+

Variables

+
+ +

Const maxNumberHttpAttempts

+
maxNumberHttpAttempts: 2 = 2
+ +
+
+
+

Functions

+
+ +

Const isFailure

+ + +
+
+ +

Const parseSuccess

+ + +
+
+ +

Const runVerifyReceipt

+ + +
+
+ +

Const verifyReceipt

+ + +
+
+
+

Object literals

+
+ +

Const _

+
_: object
+ +
+ +

array

+
array: object
+ +
+ +

contains

+
    +
  • contains<T>(array: T[], doesContain: (element: T) => boolean): boolean
  • +
+
    +
  • + +

    Type parameters

    +
      +
    • +

      T

      +
    • +
    +

    Parameters

    +
      +
    • +
      array: T[]
      +
    • +
    • +
      doesContain: (element: T) => boolean
      +
        +
      • +
          +
        • (element: T): boolean
        • +
        +
          +
        • +

          Parameters

          +
            +
          • +
            element: T
            +
          • +
          +

          Returns boolean

          +
        • +
        +
      • +
      +
    • +
    +

    Returns boolean

    +
  • +
+
+
+
+ +

date

+
date: object
+ +
+ +

sortNewToOld

+
    +
  • sortNewToOld(first: Date, second: Date): number
  • +
+
    +
  • + +
    +
    +

    Sort date array in order: [newer date, older date].

    +
    +

    Use:

    +
    const dates: Date[] = []
    +dates.sort(_.date.sortNewToOld)
    +
    +const nestedDates: {date: Date}[] = []
    +nestedDates.sort((first, second) => _.date.sortNewToOld(first.date, second.date))
    +
    +

    Parameters

    +
      +
    • +
      first: Date
      +
    • +
    • +
      second: Date
      +
    • +
    +

    Returns number

    +
  • +
+
+
+ +

sortOldToNew

+
    +
  • sortOldToNew(first: Date, second: Date): number
  • +
+
    +
  • + +
    +
    +

    Sort date array in order: [older date, newer date].

    +
    +

    Use:

    +
    const dates: Date[] = []
    +dates.sort(_.date.sortOldToNew)
    +
    +const nestedDates: {date: Date}[] = []
    +nestedDates.sort((first, second) => _.date.sortOldToNew(first.date, second.date))
    +
    +

    Parameters

    +
      +
    • +
      first: Date
      +
    • +
    • +
      second: Date
      +
    • +
    +

    Returns number

    +
  • +
+
+
+
+