diff --git "a/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9" "b/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9" deleted file mode 100644 index 7657d42..0000000 --- "a/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9" +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. Do not rely on good formatting of values -// for AssertionError messages in browsers. - -import { bold, gray, green, red, stripColor, white } from "../fmt/colors.ts"; -import { diff, DiffResult, DiffType } from "./_diff.ts"; - -const CAN_NOT_DISPLAY = "[Cannot display]"; - -interface Constructor { - // deno-lint-ignore no-explicit-any - new (...args: any[]): any; -} - -export class AssertionError extends Error { - constructor(message: string) { - super(message); - this.name = "AssertionError"; - } -} - -/** - * Converts the input into a string. Objects, Sets and Maps are sorted so as to - * make tests less flaky - * @param v Value to be formatted - */ -export function _format(v: unknown): string { - return globalThis.Deno - ? Deno.inspect(v, { - depth: Infinity, - sorted: true, - trailingComma: true, - compact: false, - iterableLimit: Infinity, - }) - : `"${String(v).replace(/(?=["\\])/g, "\\")}"`; -} - -/** - * Colors the output of assertion diffs - * @param diffType Difference type, either added or removed - */ -function createColor(diffType: DiffType): (s: string) => string { - switch (diffType) { - case DiffType.added: - return (s: string): string => green(bold(s)); - case DiffType.removed: - return (s: string): string => red(bold(s)); - default: - return white; - } -} - -/** - * Prefixes `+` or `-` in diff output - * @param diffType Difference type, either added or removed - */ -function createSign(diffType: DiffType): string { - switch (diffType) { - case DiffType.added: - return "+ "; - case DiffType.removed: - return "- "; - default: - return " "; - } -} - -function buildMessage(diffResult: ReadonlyArray>): string[] { - const messages: string[] = []; - messages.push(""); - messages.push(""); - messages.push( - ` ${gray(bold("[Diff]"))} ${red(bold("Actual"))} / ${ - green(bold("Expected")) - }`, - ); - messages.push(""); - messages.push(""); - diffResult.forEach((result: DiffResult): void => { - const c = createColor(result.type); - messages.push(c(`${createSign(result.type)}${result.value}`)); - }); - messages.push(""); - - return messages; -} - -function isKeyedCollection(x: unknown): x is Set { - return [Symbol.iterator, "size"].every((k) => k in (x as Set)); -} - -/** - * Deep equality comparison used in assertions - * @param c actual value - * @param d expected value - */ -export function equal(c: unknown, d: unknown): boolean { - const seen = new Map(); - return (function compare(a: unknown, b: unknown): boolean { - // Have to render RegExp & Date for string comparison - // unless it's mistreated as object - if ( - a && - b && - ((a instanceof RegExp && b instanceof RegExp) || - (a instanceof URL && b instanceof URL)) - ) { - return String(a) === String(b); - } - if (a instanceof Date && b instanceof Date) { - const aTime = a.getTime(); - const bTime = b.getTime(); - // Check for NaN equality manually since NaN is not - // equal to itself. - if (Number.isNaN(aTime) && Number.isNaN(bTime)) { - return true; - } - return a.getTime() === b.getTime(); - } - if (Object.is(a, b)) { - return true; - } - if (a && typeof a === "object" && b && typeof b === "object") { - if (seen.get(a) === b) { - return true; - } - if (Object.keys(a || {}).length !== Object.keys(b || {}).length) { - return false; - } - if (isKeyedCollection(a) && isKeyedCollection(b)) { - if (a.size !== b.size) { - return false; - } - - let unmatchedEntries = a.size; - - for (const [aKey, aValue] of a.entries()) { - for (const [bKey, bValue] of b.entries()) { - /* Given that Map keys can be references, we need - * to ensure that they are also deeply equal */ - if ( - (aKey === aValue && bKey === bValue && compare(aKey, bKey)) || - (compare(aKey, bKey) && compare(aValue, bValue)) - ) { - unmatchedEntries--; - } - } - } - - return unmatchedEntries === 0; - } - const merged = { ...a, ...b }; - for ( - const key of [ - ...Object.getOwnPropertyNames(merged), - ...Object.getOwnPropertySymbols(merged), - ] - ) { - type Key = keyof typeof merged; - if (!compare(a && a[key as Key], b && b[key as Key])) { - return false; - } - } - seen.set(a, b); - return true; - } - return false; - })(c, d); -} - -/** Make an assertion, error will be thrown if `expr` does not have truthy value. */ -export function assert(expr: unknown, msg = ""): asserts expr { - if (!expr) { - throw new AssertionError(msg); - } -} - -/** - * Make an assertion that `actual` and `expected` are equal, deeply. If not - * deeply equal, then throw. - * - * Type parameter can be specified to ensure values under comparison have the same type. - * For example: - *```ts - *assertEquals(1, 2) - *``` - */ -export function assertEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void; -export function assertEquals(actual: T, expected: T, msg?: string): void; -export function assertEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void { - if (equal(actual, expected)) { - return; - } - let message = ""; - const actualString = _format(actual); - const expectedString = _format(expected); - try { - const diffResult = diff( - actualString.split("\n"), - expectedString.split("\n"), - ); - const diffMsg = buildMessage(diffResult).join("\n"); - message = `Values are not equal:\n${diffMsg}`; - } catch { - message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`; - } - if (msg) { - message = msg; - } - throw new AssertionError(message); -} - -/** - * Make an assertion that `actual` and `expected` are not equal, deeply. - * If not then throw. - * - * Type parameter can be specified to ensure values under comparison have the same type. - * For example: - *```ts - *assertNotEquals(1, 2) - *``` - */ -export function assertNotEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void; -export function assertNotEquals(actual: T, expected: T, msg?: string): void; -export function assertNotEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void { - if (!equal(actual, expected)) { - return; - } - let actualString: string; - let expectedString: string; - try { - actualString = String(actual); - } catch { - actualString = "[Cannot display]"; - } - try { - expectedString = String(expected); - } catch { - expectedString = "[Cannot display]"; - } - if (!msg) { - msg = `actual: ${actualString} expected: ${expectedString}`; - } - throw new AssertionError(msg); -} - -/** - * Make an assertion that `actual` and `expected` are strictly equal. If - * not then throw. - * ```ts - * assertStrictEquals(1, 2) - * ``` - */ -export function assertStrictEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void; -export function assertStrictEquals( - actual: T, - expected: T, - msg?: string, -): void; -export function assertStrictEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void { - if (actual === expected) { - return; - } - - let message: string; - - if (msg) { - message = msg; - } else { - const actualString = _format(actual); - const expectedString = _format(expected); - - if (actualString === expectedString) { - const withOffset = actualString - .split("\n") - .map((l) => ` ${l}`) - .join("\n"); - message = - `Values have the same structure but are not reference-equal:\n\n${ - red(withOffset) - }\n`; - } else { - try { - const diffResult = diff( - actualString.split("\n"), - expectedString.split("\n"), - ); - const diffMsg = buildMessage(diffResult).join("\n"); - message = `Values are not strictly equal:\n${diffMsg}`; - } catch { - message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`; - } - } - } - - throw new AssertionError(message); -} - -/** - * Make an assertion that `actual` and `expected` are not strictly equal. - * If the values are strictly equal then throw. - * ```ts - * assertNotStrictEquals(1, 1) - * ``` - */ -export function assertNotStrictEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void; -export function assertNotStrictEquals( - actual: T, - expected: T, - msg?: string, -): void; -export function assertNotStrictEquals( - actual: unknown, - expected: unknown, - msg?: string, -): void { - if (actual !== expected) { - return; - } - - throw new AssertionError( - msg ?? `Expected "actual" to be strictly unequal to: ${_format(actual)}\n`, - ); -} - -/** - * Make an assertion that actual is not null or undefined. If not - * then thrown. - */ -export function assertExists( - actual: unknown, - msg?: string, -): void { - if (actual === undefined || actual === null) { - if (!msg) { - msg = - `actual: "${actual}" expected to match anything but null or undefined`; - } - throw new AssertionError(msg); - } -} - -/** - * Make an assertion that actual includes expected. If not - * then thrown. - */ -export function assertStringIncludes( - actual: string, - expected: string, - msg?: string, -): void { - if (!actual.includes(expected)) { - if (!msg) { - msg = `actual: "${actual}" expected to contain: "${expected}"`; - } - throw new AssertionError(msg); - } -} - -/** - * Make an assertion that `actual` includes the `expected` values. - * If not then an error will be thrown. - * - * Type parameter can be specified to ensure values under comparison have the same type. - * For example: - *```ts - *assertArrayIncludes([1, 2], [2]) - *``` - */ -export function assertArrayIncludes( - actual: ArrayLike, - expected: ArrayLike, - msg?: string, -): void; -export function assertArrayIncludes( - actual: ArrayLike, - expected: ArrayLike, - msg?: string, -): void; -export function assertArrayIncludes( - actual: ArrayLike, - expected: ArrayLike, - msg?: string, -): void { - const missing: unknown[] = []; - for (let i = 0; i < expected.length; i++) { - let found = false; - for (let j = 0; j < actual.length; j++) { - if (equal(expected[i], actual[j])) { - found = true; - break; - } - } - if (!found) { - missing.push(expected[i]); - } - } - if (missing.length === 0) { - return; - } - if (!msg) { - msg = `actual: "${_format(actual)}" expected to include: "${ - _format(expected) - }"\nmissing: ${_format(missing)}`; - } - throw new AssertionError(msg); -} - -/** - * Make an assertion that `actual` match RegExp `expected`. If not - * then thrown - */ -export function assertMatch( - actual: string, - expected: RegExp, - msg?: string, -): void { - if (!expected.test(actual)) { - if (!msg) { - msg = `actual: "${actual}" expected to match: "${expected}"`; - } - throw new AssertionError(msg); - } -} - -/** - * Make an assertion that `actual` not match RegExp `expected`. If match - * then thrown - */ -export function assertNotMatch( - actual: string, - expected: RegExp, - msg?: string, -): void { - if (expected.test(actual)) { - if (!msg) { - msg = `actual: "${actual}" expected to not match: "${expected}"`; - } - throw new AssertionError(msg); - } -} - -/** - * Make an assertion that `actual` object is a subset of `expected` object, deeply. - * If not, then throw. - */ -export function assertObjectMatch( - actual: Record, - expected: Record, -): void { - type loose = Record; - const seen = new WeakMap(); - return assertEquals( - (function filter(a: loose, b: loose): loose { - // Prevent infinite loop with circular references with same filter - if ((seen.has(a)) && (seen.get(a) === b)) { - return a; - } - seen.set(a, b); - // Filter keys and symbols which are present in both actual and expected - const filtered = {} as loose; - const entries = [ - ...Object.getOwnPropertyNames(a), - ...Object.getOwnPropertySymbols(a), - ] - .filter((key) => key in b) - .map((key) => [key, a[key as string]]) as Array<[string, unknown]>; - // Build filtered object and filter recursively on nested objects references - for (const [key, value] of entries) { - if (typeof value === "object") { - const subset = (b as loose)[key]; - if ((typeof subset === "object") && (subset)) { - filtered[key] = filter(value as loose, subset as loose); - continue; - } - } - filtered[key] = value; - } - return filtered; - })(actual, expected), - expected, - ); -} - -/** - * Forcefully throws a failed assertion - */ -export function fail(msg?: string): void { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`); -} - -/** - * Executes a function, expecting it to throw. If it does not, then it - * throws. An error class and a string that should be included in the - * error message can also be asserted. - */ -export function assertThrows( - fn: () => T, - ErrorClass?: Constructor, - msgIncludes = "", - msg?: string, -): Error { - let doesThrow = false; - let error = null; - try { - fn(); - } catch (e) { - if (e instanceof Error === false) { - throw new AssertionError("A non-Error object was thrown."); - } - if (ErrorClass && !(e instanceof ErrorClass)) { - msg = - `Expected error to be instance of "${ErrorClass.name}", but was "${e.constructor.name}"${ - msg ? `: ${msg}` : "." - }`; - throw new AssertionError(msg); - } - if ( - msgIncludes && - !stripColor(e.message).includes(stripColor(msgIncludes)) - ) { - msg = - `Expected error message to include "${msgIncludes}", but got "${e.message}"${ - msg ? `: ${msg}` : "." - }`; - throw new AssertionError(msg); - } - doesThrow = true; - error = e; - } - if (!doesThrow) { - msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - return error; -} - -/** - * Executes a function which returns a promise, expecting it to throw or reject. - * If it does not, then it throws. An error class and a string that should be - * included in the error message can also be asserted. - */ -export async function assertThrowsAsync( - fn: () => Promise, - ErrorClass?: Constructor, - msgIncludes = "", - msg?: string, -): Promise { - let doesThrow = false; - let error = null; - try { - await fn(); - } catch (e) { - if (e instanceof Error === false) { - throw new AssertionError("A non-Error object was thrown or rejected."); - } - if (ErrorClass && !(e instanceof ErrorClass)) { - msg = - `Expected error to be instance of "${ErrorClass.name}", but got "${e.name}"${ - msg ? `: ${msg}` : "." - }`; - throw new AssertionError(msg); - } - if ( - msgIncludes && - !stripColor(e.message).includes(stripColor(msgIncludes)) - ) { - msg = - `Expected error message to include "${msgIncludes}", but got "${e.message}"${ - msg ? `: ${msg}` : "." - }`; - throw new AssertionError(msg); - } - doesThrow = true; - error = e; - } - if (!doesThrow) { - msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - return error; -} - -/** Use this to stub out methods that will throw when invoked. */ -export function unimplemented(msg?: string): never { - throw new AssertionError(msg || "unimplemented"); -} - -/** Use this to assert unreachable code. */ -export function unreachable(): never { - throw new AssertionError("unreachable"); -} diff --git "a/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.metadata.json" "b/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.metadata.json" deleted file mode 100644 index b026e91..0000000 --- "a/.\\.cache/deps/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.metadata.json" +++ /dev/null @@ -1,27 +0,0 @@ -{ - "headers": { - "x-cache": "Hit from cloudfront", - "last-modified": "Tue, 09 Mar 2021 20:51:37 GMT", - "cache-control": "public, max-age=31536000, immutable", - "age": "1137010", - "accept-ranges": "bytes", - "x-amz-version-id": "QQviodBEowgXWHuH1TLYJlVV7Ut.ZGFX", - "server": "deno/asia-southeast1-a", - "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", - "date": "Sun, 09 Oct 2022 06:32:40 GMT", - "access-control-allow-origin": "*", - "content-type": "application/typescript; charset=utf-8", - "x-amz-replication-status": "FAILED", - "via": "1.1 16074517396ff3ce754e4ac422c346c8.cloudfront.net (CloudFront)", - "x-amz-cf-pop": "SIN52-P1", - "x-amz-cf-id": "cup4KSozQRwMJeKCbi0ANqSPnuNhD_62fXhwFz44y1vIBcnJhdH3bw==", - "content-length": "15918", - "vary": "Accept-Encoding, Origin", - "etag": "\"8e6a8028df051e57f66135aca5bc9261\"" - }, - "url": "https://deno.land/std@0.90.0/testing/asserts.ts", - "now": { - "secs_since_epoch": 1666434170, - "nanos_since_epoch": 349336000 - } -} \ No newline at end of file diff --git "a/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54" "b/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54" deleted file mode 100644 index 45bd7b2..0000000 --- "a/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54" +++ /dev/null @@ -1,930 +0,0 @@ -export class Tx { - type: number; - sender: string; - contractCall?: TxContractCall; - transferStx?: TxTransfer; - deployContract?: TxDeployContract; - - constructor(type: number, sender: string) { - this.type = type; - this.sender = sender; - } - - static transferSTX(amount: number, recipient: string, sender: string) { - let tx = new Tx(1, sender); - tx.transferStx = { - recipient, - amount, - }; - return tx; - } - - static contractCall( - contract: string, - method: string, - args: Array, - sender: string, - ) { - let tx = new Tx(2, sender); - tx.contractCall = { - contract, - method, - args, - }; - return tx; - } - - static deployContract(name: string, code: string, sender: string) { - let tx = new Tx(3, sender); - tx.deployContract = { - name, - code, - }; - return tx; - } -} - -export interface TxContractCall { - contract: string; - method: string; - args: Array; -} - -export interface TxDeployContract { - code: string; - name: string; -} - -export interface TxTransfer { - amount: number; - recipient: string; -} - -export interface TxReceipt { - result: string; - events: Array; -} - -export interface Block { - height: number; - receipts: Array; -} - -export interface Account { - address: string; - balance: number; - name: string; -} - -export interface Chain { - sessionId: number; -} - -export interface ReadOnlyFn { - session_id: number; - result: string; - events: Array; -} - -export interface EmptyBlock { - session_id: number; - block_height: number; -} - -export interface AssetsMaps { - session_id: number; - assets: { - [name: string]: { - [owner: string]: number; - }; - }; -} - -export class Chain { - sessionId: number; - blockHeight: number = 1; - - constructor(sessionId: number) { - this.sessionId = sessionId; - } - - mineBlock(transactions: Array): Block { - // @ts-ignore - let result = JSON.parse(Deno.core.opSync("api/v1/mine_block", { - sessionId: this.sessionId, - transactions: transactions, - })); - this.blockHeight = result.block_height; - let block: Block = { - height: result.block_height, - receipts: result.receipts, - }; - return block; - } - - mineEmptyBlock(count: number): EmptyBlock { - let result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/mine_empty_blocks", { - sessionId: this.sessionId, - count: count, - }), - ); - this.blockHeight = result.block_height; - let emptyBlock: EmptyBlock = { - session_id: result.session_id, - block_height: result.block_height, - }; - return emptyBlock; - } - - mineEmptyBlockUntil(targetBlockHeight: number): EmptyBlock { - let count = targetBlockHeight - this.blockHeight; - if (count < 0) { - throw new Error( - `Chain tip cannot be moved from ${this.blockHeight} to ${targetBlockHeight}`, - ); - } - return this.mineEmptyBlock(count); - } - - callReadOnlyFn( - contract: string, - method: string, - args: Array, - sender: string, - ): ReadOnlyFn { - let result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/call_read_only_fn", { - sessionId: this.sessionId, - contract: contract, - method: method, - args: args, - sender: sender, - }), - ); - let readOnlyFn: ReadOnlyFn = { - session_id: result.session_id, - result: result.result, - events: result.events, - }; - return readOnlyFn; - } - - getAssetsMaps(): AssetsMaps { - let result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/get_assets_maps", { - sessionId: this.sessionId, - }), - ); - let assetsMaps: AssetsMaps = { - session_id: result.session_id, - assets: result.assets, - }; - return assetsMaps; - } -} - -type PreDeploymentFunction = ( - chain: Chain, - accounts: Map, -) => void | Promise; - -type TestFunction = ( - chain: Chain, - accounts: Map, - contracts: Map, -) => void | Promise; -type PreSetupFunction = () => Array; - -interface UnitTestOptions { - name: string; - only?: true; - ignore?: true; - deploymentPath?: string; - preDeployment?: PreDeploymentFunction; - fn: TestFunction; -} - -export interface Contract { - contract_id: string; - source: string; - contract_interface: any; -} - -export interface StacksNode { - url: string; -} - -type ScriptFunction = ( - accounts: Map, - contracts: Map, - node: StacksNode, -) => void | Promise; - -interface ScriptOptions { - fn: ScriptFunction; -} - -export class Clarinet { - static test(options: UnitTestOptions) { - // @ts-ignore - Deno.test({ - name: options.name, - only: options.only, - ignore: options.ignore, - async fn() { - let hasPreDeploymentSteps = options.preDeployment !== undefined; - - let result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/new_session", { - name: options.name, - loadDeployment: !hasPreDeploymentSteps, - deploymentPath: options.deploymentPath, - }), - ); - - if (options.preDeployment) { - let chain = new Chain(result["session_id"]); - let accounts: Map = new Map(); - for (let account of result["accounts"]) { - accounts.set(account.name, account); - } - await options.preDeployment(chain, accounts); - - result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/load_deployment", { - sessionId: chain.sessionId, - deploymentPath: options.deploymentPath, - }), - ); - } - - let chain = new Chain(result["session_id"]); - let accounts: Map = new Map(); - for (let account of result["accounts"]) { - accounts.set(account.name, account); - } - let contracts: Map = new Map(); - for (let contract of result["contracts"]) { - contracts.set(contract.contract_id, contract); - } - await options.fn(chain, accounts, contracts); - - // @ts-ignore - JSON.parse(Deno.core.opSync("api/v1/terminate_session", { - sessionId: chain.sessionId, - })); - }, - }); - } - - static run(options: ScriptOptions) { - // @ts-ignore - Deno.test({ - name: "running script", - async fn() { - let result = JSON.parse( - // @ts-ignore - Deno.core.opSync("api/v1/new_session", { - name: "running script", - loadDeployment: true, - deploymentPath: undefined, - }), - ); - let accounts: Map = new Map(); - for (let account of result["accounts"]) { - accounts.set(account.name, account); - } - let contracts: Map = new Map(); - for (let contract of result["contracts"]) { - contracts.set(contract.contract_id, contract); - } - let stacks_node: StacksNode = { - url: result["stacks_node_url"], - }; - await options.fn(accounts, contracts, stacks_node); - }, - }); - } -} - -export namespace types { - const byteToHex: any = []; - for (let n = 0; n <= 0xff; ++n) { - const hexOctet = n.toString(16).padStart(2, "0"); - byteToHex.push(hexOctet); - } - - function serializeTuple(input: Object) { - let items: Array = []; - for (var [key, value] of Object.entries(input)) { - if (typeof value === "object") { - items.push(`${key}: { ${serializeTuple(value)} }`); - } else if (Array.isArray(value)) { - // todo(ludo): not supported, should panic - } else { - items.push(`${key}: ${value}`); - } - } - return items.join(", "); - } - - function isObject(obj: any) { - return typeof obj === "object" && !Array.isArray(obj); - } - - export function ok(val: string) { - return `(ok ${val})`; - } - - export function err(val: string) { - return `(err ${val})`; - } - - export function some(val: string) { - return `(some ${val})`; - } - - export function none() { - return `none`; - } - - export function bool(val: boolean) { - return `${val}`; - } - - export function int(val: number | bigint) { - return `${val}`; - } - - export function uint(val: number | bigint) { - return `u${val}`; - } - - export function ascii(val: string) { - return JSON.stringify(val); - } - - export function utf8(val: string) { - return `u${JSON.stringify(val)}`; - } - - export function buff(val: ArrayBuffer | string) { - const buff = typeof val == "string" - ? new TextEncoder().encode(val) - : new Uint8Array(val); - - const hexOctets = new Array(buff.length); - - for (let i = 0; i < buff.length; ++i) { - hexOctets[i] = byteToHex[buff[i]]; - } - - return `0x${hexOctets.join("")}`; - } - - export function list(val: Array) { - return `(list ${val.join(" ")})`; - } - - export function principal(val: string) { - return `'${val}`; - } - - export function tuple(val: Object) { - return `{ ${serializeTuple(val)} }`; - } -} - -declare global { - interface String { - expectOk(): String; - expectErr(): String; - expectSome(): String; - expectNone(): void; - expectBool(value: boolean): boolean; - expectUint(value: number | bigint): bigint; - expectInt(value: number | bigint): bigint; - expectBuff(value: ArrayBuffer): ArrayBuffer; - expectAscii(value: String): String; - expectUtf8(value: String): String; - expectPrincipal(value: String): String; - expectList(): Array; - expectTuple(): Record; - } - - interface Array { - expectSTXTransferEvent( - amount: Number | bigint, - sender: String, - recipient: String, - ): Object; - expectFungibleTokenTransferEvent( - amount: Number | bigint, - sender: String, - recipient: String, - assetId: String, - ): Object; - expectFungibleTokenMintEvent( - amount: Number | bigint, - recipient: String, - assetId: String, - ): Object; - expectFungibleTokenBurnEvent( - amount: Number | bigint, - sender: String, - assetId: String, - ): Object; - expectPrintEvent( - contract_identifier: string, - value: string, - ): Object; - expectNonFungibleTokenTransferEvent( - tokenId: String, - sender: String, - recipient: String, - assetAddress: String, - assetId: String, - ): Object; - expectNonFungibleTokenMintEvent( - tokenId: String, - recipient: String, - assetAddress: String, - assetId: String, - ): Object; - expectNonFungibleTokenBurnEvent( - tokenId: String, - sender: String, - assetAddress: String, - assetId: String, - ): Object; - // expectEvent(sel: (e: Object) => Object): Object; - } -} - -function consume(src: String, expectation: String, wrapped: boolean) { - let dst = (" " + src).slice(1); - let size = expectation.length; - if (!wrapped && src !== expectation) { - throw new Error( - `Expected ${green(expectation.toString())}, got ${red(src.toString())}`, - ); - } - if (wrapped) { - size += 2; - } - if (dst.length < size) { - throw new Error( - `Expected ${green(expectation.toString())}, got ${red(src.toString())}`, - ); - } - if (wrapped) { - dst = dst.substring(1, dst.length - 1); - } - let res = dst.slice(0, expectation.length); - if (res !== expectation) { - throw new Error( - `Expected ${green(expectation.toString())}, got ${red(src.toString())}`, - ); - } - let leftPad = 0; - if (dst.charAt(expectation.length) === " ") { - leftPad = 1; - } - let remainder = dst.substring(expectation.length + leftPad); - return remainder; -} - -String.prototype.expectOk = function () { - return consume(this, "ok", true); -}; - -String.prototype.expectErr = function () { - return consume(this, "err", true); -}; - -String.prototype.expectSome = function () { - return consume(this, "some", true); -}; - -String.prototype.expectNone = function () { - return consume(this, "none", false); -}; - -String.prototype.expectBool = function (value: boolean) { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return value; -}; - -String.prototype.expectUint = function (value: number | bigint): bigint { - try { - consume(this, `u${value}`, false); - } catch (error) { - throw error; - } - return BigInt(value); -}; - -String.prototype.expectInt = function (value: number | bigint): bigint { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return BigInt(value); -}; - -String.prototype.expectBuff = function (value: ArrayBuffer) { - let buffer = types.buff(value); - if (this !== buffer) { - throw new Error(`Expected ${green(buffer)}, got ${red(this.toString())}`); - } - return value; -}; - -String.prototype.expectAscii = function (value: string) { - try { - consume(this, `"${value}"`, false); - } catch (error) { - throw error; - } - return value; -}; - -String.prototype.expectUtf8 = function (value: string) { - try { - consume(this, `u"${value}"`, false); - } catch (error) { - throw error; - } - return value; -}; - -String.prototype.expectPrincipal = function (value: string) { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return value; -}; - -String.prototype.expectList = function () { - if (this.charAt(0) !== "[" || this.charAt(this.length - 1) !== "]") { - throw new Error( - `Expected ${green("(list ...)")}, got ${red(this.toString())}`, - ); - } - - let stack = []; - let elements = []; - let start = 1; - for (var i = 0; i < this.length; i++) { - if (this.charAt(i) === "," && stack.length == 1) { - elements.push(this.substring(start, i)); - start = i + 2; - } - if (["(", "[", "{"].includes(this.charAt(i))) { - stack.push(this.charAt(i)); - } - if (this.charAt(i) === ")" && stack[stack.length - 1] === "(") { - stack.pop(); - } - if (this.charAt(i) === "}" && stack[stack.length - 1] === "{") { - stack.pop(); - } - if (this.charAt(i) === "]" && stack[stack.length - 1] === "[") { - stack.pop(); - } - } - let remainder = this.substring(start, this.length - 1); - if (remainder.length > 0) { - elements.push(remainder); - } - return elements; -}; - -String.prototype.expectTuple = function () { - if (this.charAt(0) !== "{" || this.charAt(this.length - 1) !== "}") { - throw new Error( - `Expected ${green("(tuple ...)")}, got ${red(this.toString())}`, - ); - } - - let start = 1; - let stack = []; - let elements = []; - for (var i = 0; i < this.length; i++) { - if (this.charAt(i) === "," && stack.length == 1) { - elements.push(this.substring(start, i)); - start = i + 2; - } - if (["(", "[", "{"].includes(this.charAt(i))) { - stack.push(this.charAt(i)); - } - if (this.charAt(i) === ")" && stack[stack.length - 1] === "(") { - stack.pop(); - } - if (this.charAt(i) === "}" && stack[stack.length - 1] === "{") { - stack.pop(); - } - if (this.charAt(i) === "]" && stack[stack.length - 1] === "[") { - stack.pop(); - } - } - let remainder = this.substring(start, this.length - 1); - if (remainder.length > 0) { - elements.push(remainder); - } - - let tuple: Record = {}; - for (let element of elements) { - for (var i = 0; i < element.length; i++) { - if (element.charAt(i) === ":") { - let key: string = element.substring(0, i); - let value: string = element.substring(i + 2, element.length); - tuple[key] = value; - break; - } - } - } - - return tuple; -}; - -Array.prototype.expectSTXTransferEvent = function ( - amount: Number | bigint, - sender: String, - recipient: String, -) { - for (let event of this) { - try { - let e: any = {}; - e["amount"] = event.stx_transfer_event.amount.expectInt(amount); - e["sender"] = event.stx_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.stx_transfer_event.recipient.expectPrincipal( - recipient, - ); - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected STXTransferEvent`); -}; - -Array.prototype.expectFungibleTokenTransferEvent = function ( - amount: Number, - sender: String, - recipient: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - e["amount"] = event.ft_transfer_event.amount.expectInt(amount); - e["sender"] = event.ft_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.ft_transfer_event.recipient.expectPrincipal( - recipient, - ); - if (event.ft_transfer_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_transfer_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error( - `Unable to retrieve expected FungibleTokenTransferEvent(${amount}, ${sender}, ${recipient}, ${assetId})\n${ - JSON.stringify(this) - }`, - ); -}; - -Array.prototype.expectFungibleTokenMintEvent = function ( - amount: Number | bigint, - recipient: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - e["amount"] = event.ft_mint_event.amount.expectInt(amount); - e["recipient"] = event.ft_mint_event.recipient.expectPrincipal(recipient); - if (event.ft_mint_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_mint_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected FungibleTokenMintEvent`); -}; - -Array.prototype.expectFungibleTokenBurnEvent = function ( - amount: Number | bigint, - sender: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - e["amount"] = event.ft_burn_event.amount.expectInt(amount); - e["sender"] = event.ft_burn_event.sender.expectPrincipal(sender); - if (event.ft_burn_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_burn_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected FungibleTokenBurnEvent`); -}; - -Array.prototype.expectPrintEvent = function ( - contract_identifier: string, - value: string, -) { - for (let event of this) { - try { - let e: any = {}; - e["contract_identifier"] = event.contract_event.contract_identifier - .expectPrincipal( - contract_identifier, - ); - - if (event.contract_event.topic.endsWith("print")) { - e["topic"] = event.contract_event.topic; - } else { - continue; - } - - if (event.contract_event.value.endsWith(value)) { - e["value"] = event.contract_event.value; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected PrintEvent`); -}; -// Array.prototype.expectEvent = function(sel: (e: Object) => Object) { -// for (let event of this) { -// try { -// sel(event); -// return event as Object; -// } catch (error) { -// continue; -// } -// } -// throw new Error(`Unable to retrieve expected PrintEvent`); -// } -Array.prototype.expectNonFungibleTokenTransferEvent = function ( - tokenId: String, - sender: String, - recipient: String, - assetAddress: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - if (event.nft_transfer_event.value === tokenId) { - e["tokenId"] = event.nft_transfer_event.value; - } else { - continue; - } - e["sender"] = event.nft_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.nft_transfer_event.recipient.expectPrincipal( - recipient, - ); - if ( - event.nft_transfer_event.asset_identifier === - `${assetAddress}::${assetId}` - ) { - e["assetId"] = event.nft_transfer_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenTransferEvent`); -}; - -Array.prototype.expectNonFungibleTokenMintEvent = function ( - tokenId: String, - recipient: String, - assetAddress: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - if (event.nft_mint_event.value === tokenId) { - e["tokenId"] = event.nft_mint_event.value; - } else { - continue; - } - e["recipient"] = event.nft_mint_event.recipient.expectPrincipal( - recipient, - ); - if ( - event.nft_mint_event.asset_identifier === `${assetAddress}::${assetId}` - ) { - e["assetId"] = event.nft_mint_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenMintEvent`); -}; - -Array.prototype.expectNonFungibleTokenBurnEvent = function ( - tokenId: String, - sender: String, - assetAddress: String, - assetId: String, -) { - for (let event of this) { - try { - let e: any = {}; - if (event.nft_burn_event.value === tokenId) { - e["tokenId"] = event.nft_burn_event.value; - } else { - continue; - } - e["sender"] = event.nft_burn_event.sender.expectPrincipal(sender); - if ( - event.nft_burn_event.asset_identifier === `${assetAddress}::${assetId}` - ) { - e["assetId"] = event.nft_burn_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenBurnEvent`); -}; - -const noColor = globalThis.Deno?.noColor ?? true; - -interface Code { - open: string; - close: string; - regexp: RegExp; -} - -let enabled = !noColor; - -function code(open: number[], close: number): Code { - return { - open: `\x1b[${open.join(";")}m`, - close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g"), - }; -} - -function run(str: string, code: Code): string { - return enabled - ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` - : str; -} - -export function red(str: string): string { - return run(str, code([31], 39)); -} - -export function green(str: string): string { - return run(str, code([32], 39)); -} diff --git "a/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.metadata.json" "b/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.metadata.json" deleted file mode 100644 index 119f077..0000000 --- "a/.\\.cache/deps/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.metadata.json" +++ /dev/null @@ -1,27 +0,0 @@ -{ - "headers": { - "last-modified": "Sat, 08 Oct 2022 16:33:01 GMT", - "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", - "content-length": "22514", - "server": "deno/asia-southeast1-a", - "x-amz-cf-id": "cyZOp3MnwRzi2QvqCsAu3eQCn1CBgZzIVgy9TdMDCuVi94Xw8tlFfA==", - "etag": "\"c7c259520f5cc5747ec5076b8bb7daf0\"", - "x-amz-cf-pop": "SIN52-P1", - "x-amz-replication-status": "COMPLETED", - "cache-control": "public, max-age=31536000, immutable", - "x-amz-version-id": "9Xz24YLsKxzQ7DI7YgdrvY_CNSjrcVap", - "age": "861837", - "date": "Wed, 12 Oct 2022 10:58:54 GMT", - "via": "1.1 16074517396ff3ce754e4ac422c346c8.cloudfront.net (CloudFront)", - "access-control-allow-origin": "*", - "x-cache": "Hit from cloudfront", - "content-type": "application/typescript; charset=utf-8", - "vary": "Accept-Encoding, Origin", - "accept-ranges": "bytes" - }, - "url": "https://deno.land/x/clarinet@v1.0.2/index.ts", - "now": { - "secs_since_epoch": 1666434170, - "nanos_since_epoch": 330218000 - } -} \ No newline at end of file diff --git "a/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4" "b/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4" deleted file mode 100644 index 7d659ac..0000000 --- "a/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4" +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -interface FarthestPoint { - y: number; - id: number; -} - -export enum DiffType { - removed = "removed", - common = "common", - added = "added", -} - -export interface DiffResult { - type: DiffType; - value: T; -} - -const REMOVED = 1; -const COMMON = 2; -const ADDED = 3; - -function createCommon(A: T[], B: T[], reverse?: boolean): T[] { - const common = []; - if (A.length === 0 || B.length === 0) return []; - for (let i = 0; i < Math.min(A.length, B.length); i += 1) { - if ( - A[reverse ? A.length - i - 1 : i] === B[reverse ? B.length - i - 1 : i] - ) { - common.push(A[reverse ? A.length - i - 1 : i]); - } else { - return common; - } - } - return common; -} - -/** - * Renders the differences between the actual and expected values - * @param A Actual value - * @param B Expected value - */ -export function diff(A: T[], B: T[]): Array> { - const prefixCommon = createCommon(A, B); - const suffixCommon = createCommon( - A.slice(prefixCommon.length), - B.slice(prefixCommon.length), - true, - ).reverse(); - A = suffixCommon.length - ? A.slice(prefixCommon.length, -suffixCommon.length) - : A.slice(prefixCommon.length); - B = suffixCommon.length - ? B.slice(prefixCommon.length, -suffixCommon.length) - : B.slice(prefixCommon.length); - const swapped = B.length > A.length; - [A, B] = swapped ? [B, A] : [A, B]; - const M = A.length; - const N = B.length; - if (!M && !N && !suffixCommon.length && !prefixCommon.length) return []; - if (!N) { - return [ - ...prefixCommon.map( - (c): DiffResult => ({ type: DiffType.common, value: c }), - ), - ...A.map( - (a): DiffResult => ({ - type: swapped ? DiffType.added : DiffType.removed, - value: a, - }), - ), - ...suffixCommon.map( - (c): DiffResult => ({ type: DiffType.common, value: c }), - ), - ]; - } - const offset = N; - const delta = M - N; - const size = M + N + 1; - const fp = new Array(size).fill({ y: -1 }); - /** - * INFO: - * This buffer is used to save memory and improve performance. - * The first half is used to save route and last half is used to save diff - * type. - * This is because, when I kept new uint8array area to save type,performance - * worsened. - */ - const routes = new Uint32Array((M * N + size + 1) * 2); - const diffTypesPtrOffset = routes.length / 2; - let ptr = 0; - let p = -1; - - function backTrace( - A: T[], - B: T[], - current: FarthestPoint, - swapped: boolean, - ): Array<{ - type: DiffType; - value: T; - }> { - const M = A.length; - const N = B.length; - const result = []; - let a = M - 1; - let b = N - 1; - let j = routes[current.id]; - let type = routes[current.id + diffTypesPtrOffset]; - while (true) { - if (!j && !type) break; - const prev = j; - if (type === REMOVED) { - result.unshift({ - type: swapped ? DiffType.removed : DiffType.added, - value: B[b], - }); - b -= 1; - } else if (type === ADDED) { - result.unshift({ - type: swapped ? DiffType.added : DiffType.removed, - value: A[a], - }); - a -= 1; - } else { - result.unshift({ type: DiffType.common, value: A[a] }); - a -= 1; - b -= 1; - } - j = routes[prev]; - type = routes[prev + diffTypesPtrOffset]; - } - return result; - } - - function createFP( - slide: FarthestPoint, - down: FarthestPoint, - k: number, - M: number, - ): FarthestPoint { - if (slide && slide.y === -1 && down && down.y === -1) { - return { y: 0, id: 0 }; - } - if ( - (down && down.y === -1) || - k === M || - (slide && slide.y) > (down && down.y) + 1 - ) { - const prev = slide.id; - ptr++; - routes[ptr] = prev; - routes[ptr + diffTypesPtrOffset] = ADDED; - return { y: slide.y, id: ptr }; - } else { - const prev = down.id; - ptr++; - routes[ptr] = prev; - routes[ptr + diffTypesPtrOffset] = REMOVED; - return { y: down.y + 1, id: ptr }; - } - } - - function snake( - k: number, - slide: FarthestPoint, - down: FarthestPoint, - _offset: number, - A: T[], - B: T[], - ): FarthestPoint { - const M = A.length; - const N = B.length; - if (k < -N || M < k) return { y: -1, id: -1 }; - const fp = createFP(slide, down, k, M); - while (fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]) { - const prev = fp.id; - ptr++; - fp.id = ptr; - fp.y += 1; - routes[ptr] = prev; - routes[ptr + diffTypesPtrOffset] = COMMON; - } - return fp; - } - - while (fp[delta + offset].y < N) { - p = p + 1; - for (let k = -p; k < delta; ++k) { - fp[k + offset] = snake( - k, - fp[k - 1 + offset], - fp[k + 1 + offset], - offset, - A, - B, - ); - } - for (let k = delta + p; k > delta; --k) { - fp[k + offset] = snake( - k, - fp[k - 1 + offset], - fp[k + 1 + offset], - offset, - A, - B, - ); - } - fp[delta + offset] = snake( - delta, - fp[delta - 1 + offset], - fp[delta + 1 + offset], - offset, - A, - B, - ); - } - return [ - ...prefixCommon.map( - (c): DiffResult => ({ type: DiffType.common, value: c }), - ), - ...backTrace(A, B, fp[delta + offset], swapped), - ...suffixCommon.map( - (c): DiffResult => ({ type: DiffType.common, value: c }), - ), - ]; -} diff --git "a/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.metadata.json" "b/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.metadata.json" deleted file mode 100644 index 6e92308..0000000 --- "a/.\\.cache/deps/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.metadata.json" +++ /dev/null @@ -1,27 +0,0 @@ -{ - "headers": { - "access-control-allow-origin": "*", - "cache-control": "public, max-age=31536000, immutable", - "x-amz-replication-status": "FAILED", - "date": "Tue, 06 Sep 2022 09:49:37 GMT", - "etag": "\"8bbb088bc30795a6cd6fcfed40215aea\"", - "content-type": "application/typescript; charset=utf-8", - "x-amz-cf-pop": "SIN52-P1", - "x-amz-version-id": "FrMfK5wXDicXK1HncSFcPESiVr7SNOSg", - "content-length": "5587", - "x-amz-cf-id": "ceb2U1a5nxwoVqmPJcwk21tbmD7zZyoa8iEXwEhQI3IdyMKcLMya4g==", - "server": "deno/asia-southeast1-a", - "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", - "x-cache": "Hit from cloudfront", - "age": "3976394", - "vary": "Accept-Encoding, Origin", - "via": "1.1 16074517396ff3ce754e4ac422c346c8.cloudfront.net (CloudFront)", - "accept-ranges": "bytes", - "last-modified": "Tue, 09 Mar 2021 20:51:37 GMT" - }, - "url": "https://deno.land/std@0.90.0/testing/_diff.ts", - "now": { - "secs_since_epoch": 1666434170, - "nanos_since_epoch": 442025000 - } -} \ No newline at end of file diff --git "a/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180" "b/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180" deleted file mode 100644 index f283bd2..0000000 --- "a/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180" +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// A module to print ANSI terminal colors. Inspired by chalk, kleur, and colors -// on npm. -// -// ``` -// import { bgBlue, red, bold } from "https://deno.land/std/fmt/colors.ts"; -// console.log(bgBlue(red(bold("Hello world!")))); -// ``` -// -// This module supports `NO_COLOR` environmental variable disabling any coloring -// if `NO_COLOR` is set. -// -// This module is browser compatible. - -const noColor = globalThis.Deno?.noColor ?? true; - -interface Code { - open: string; - close: string; - regexp: RegExp; -} - -/** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */ -interface Rgb { - r: number; - g: number; - b: number; -} - -let enabled = !noColor; - -/** - * Set changing text color to enabled or disabled - * @param value - */ -export function setColorEnabled(value: boolean): void { - if (noColor) { - return; - } - - enabled = value; -} - -/** Get whether text color change is enabled or disabled. */ -export function getColorEnabled(): boolean { - return enabled; -} - -/** - * Builds color code - * @param open - * @param close - */ -function code(open: number[], close: number): Code { - return { - open: `\x1b[${open.join(";")}m`, - close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g"), - }; -} - -/** - * Applies color and background based on color code and its associated text - * @param str text to apply color settings to - * @param code color code to apply - */ -function run(str: string, code: Code): string { - return enabled - ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` - : str; -} - -/** - * Reset the text modified - * @param str text to reset - */ -export function reset(str: string): string { - return run(str, code([0], 0)); -} - -/** - * Make the text bold. - * @param str text to make bold - */ -export function bold(str: string): string { - return run(str, code([1], 22)); -} - -/** - * The text emits only a small amount of light. - * @param str text to dim - */ -export function dim(str: string): string { - return run(str, code([2], 22)); -} - -/** - * Make the text italic. - * @param str text to make italic - */ -export function italic(str: string): string { - return run(str, code([3], 23)); -} - -/** - * Make the text underline. - * @param str text to underline - */ -export function underline(str: string): string { - return run(str, code([4], 24)); -} - -/** - * Invert background color and text color. - * @param str text to invert its color - */ -export function inverse(str: string): string { - return run(str, code([7], 27)); -} - -/** - * Make the text hidden. - * @param str text to hide - */ -export function hidden(str: string): string { - return run(str, code([8], 28)); -} - -/** - * Put horizontal line through the center of the text. - * @param str text to strike through - */ -export function strikethrough(str: string): string { - return run(str, code([9], 29)); -} - -/** - * Set text color to black. - * @param str text to make black - */ -export function black(str: string): string { - return run(str, code([30], 39)); -} - -/** - * Set text color to red. - * @param str text to make red - */ -export function red(str: string): string { - return run(str, code([31], 39)); -} - -/** - * Set text color to green. - * @param str text to make green - */ -export function green(str: string): string { - return run(str, code([32], 39)); -} - -/** - * Set text color to yellow. - * @param str text to make yellow - */ -export function yellow(str: string): string { - return run(str, code([33], 39)); -} - -/** - * Set text color to blue. - * @param str text to make blue - */ -export function blue(str: string): string { - return run(str, code([34], 39)); -} - -/** - * Set text color to magenta. - * @param str text to make magenta - */ -export function magenta(str: string): string { - return run(str, code([35], 39)); -} - -/** - * Set text color to cyan. - * @param str text to make cyan - */ -export function cyan(str: string): string { - return run(str, code([36], 39)); -} - -/** - * Set text color to white. - * @param str text to make white - */ -export function white(str: string): string { - return run(str, code([37], 39)); -} - -/** - * Set text color to gray. - * @param str text to make gray - */ -export function gray(str: string): string { - return brightBlack(str); -} - -/** - * Set text color to bright black. - * @param str text to make bright-black - */ -export function brightBlack(str: string): string { - return run(str, code([90], 39)); -} - -/** - * Set text color to bright red. - * @param str text to make bright-red - */ -export function brightRed(str: string): string { - return run(str, code([91], 39)); -} - -/** - * Set text color to bright green. - * @param str text to make bright-green - */ -export function brightGreen(str: string): string { - return run(str, code([92], 39)); -} - -/** - * Set text color to bright yellow. - * @param str text to make bright-yellow - */ -export function brightYellow(str: string): string { - return run(str, code([93], 39)); -} - -/** - * Set text color to bright blue. - * @param str text to make bright-blue - */ -export function brightBlue(str: string): string { - return run(str, code([94], 39)); -} - -/** - * Set text color to bright magenta. - * @param str text to make bright-magenta - */ -export function brightMagenta(str: string): string { - return run(str, code([95], 39)); -} - -/** - * Set text color to bright cyan. - * @param str text to make bright-cyan - */ -export function brightCyan(str: string): string { - return run(str, code([96], 39)); -} - -/** - * Set text color to bright white. - * @param str text to make bright-white - */ -export function brightWhite(str: string): string { - return run(str, code([97], 39)); -} - -/** - * Set background color to black. - * @param str text to make its background black - */ -export function bgBlack(str: string): string { - return run(str, code([40], 49)); -} - -/** - * Set background color to red. - * @param str text to make its background red - */ -export function bgRed(str: string): string { - return run(str, code([41], 49)); -} - -/** - * Set background color to green. - * @param str text to make its background green - */ -export function bgGreen(str: string): string { - return run(str, code([42], 49)); -} - -/** - * Set background color to yellow. - * @param str text to make its background yellow - */ -export function bgYellow(str: string): string { - return run(str, code([43], 49)); -} - -/** - * Set background color to blue. - * @param str text to make its background blue - */ -export function bgBlue(str: string): string { - return run(str, code([44], 49)); -} - -/** - * Set background color to magenta. - * @param str text to make its background magenta - */ -export function bgMagenta(str: string): string { - return run(str, code([45], 49)); -} - -/** - * Set background color to cyan. - * @param str text to make its background cyan - */ -export function bgCyan(str: string): string { - return run(str, code([46], 49)); -} - -/** - * Set background color to white. - * @param str text to make its background white - */ -export function bgWhite(str: string): string { - return run(str, code([47], 49)); -} - -/** - * Set background color to bright black. - * @param str text to make its background bright-black - */ -export function bgBrightBlack(str: string): string { - return run(str, code([100], 49)); -} - -/** - * Set background color to bright red. - * @param str text to make its background bright-red - */ -export function bgBrightRed(str: string): string { - return run(str, code([101], 49)); -} - -/** - * Set background color to bright green. - * @param str text to make its background bright-green - */ -export function bgBrightGreen(str: string): string { - return run(str, code([102], 49)); -} - -/** - * Set background color to bright yellow. - * @param str text to make its background bright-yellow - */ -export function bgBrightYellow(str: string): string { - return run(str, code([103], 49)); -} - -/** - * Set background color to bright blue. - * @param str text to make its background bright-blue - */ -export function bgBrightBlue(str: string): string { - return run(str, code([104], 49)); -} - -/** - * Set background color to bright magenta. - * @param str text to make its background bright-magenta - */ -export function bgBrightMagenta(str: string): string { - return run(str, code([105], 49)); -} - -/** - * Set background color to bright cyan. - * @param str text to make its background bright-cyan - */ -export function bgBrightCyan(str: string): string { - return run(str, code([106], 49)); -} - -/** - * Set background color to bright white. - * @param str text to make its background bright-white - */ -export function bgBrightWhite(str: string): string { - return run(str, code([107], 49)); -} - -/* Special Color Sequences */ - -/** - * Clam and truncate color codes - * @param n - * @param max number to truncate to - * @param min number to truncate from - */ -function clampAndTruncate(n: number, max = 255, min = 0): number { - return Math.trunc(Math.max(Math.min(n, max), min)); -} - -/** - * Set text color using paletted 8bit colors. - * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit - * @param str text color to apply paletted 8bit colors to - * @param color code - */ -export function rgb8(str: string, color: number): string { - return run(str, code([38, 5, clampAndTruncate(color)], 39)); -} - -/** - * Set background color using paletted 8bit colors. - * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit - * @param str text color to apply paletted 8bit background colors to - * @param color code - */ -export function bgRgb8(str: string, color: number): string { - return run(str, code([48, 5, clampAndTruncate(color)], 49)); -} - -/** - * Set text color using 24bit rgb. - * `color` can be a number in range `0x000000` to `0xffffff` or - * an `Rgb`. - * - * To produce the color magenta: - * - * rgb24("foo", 0xff00ff); - * rgb24("foo", {r: 255, g: 0, b: 255}); - * @param str text color to apply 24bit rgb to - * @param color code - */ -export function rgb24(str: string, color: number | Rgb): string { - if (typeof color === "number") { - return run( - str, - code( - [38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], - 39, - ), - ); - } - return run( - str, - code( - [ - 38, - 2, - clampAndTruncate(color.r), - clampAndTruncate(color.g), - clampAndTruncate(color.b), - ], - 39, - ), - ); -} - -/** - * Set background color using 24bit rgb. - * `color` can be a number in range `0x000000` to `0xffffff` or - * an `Rgb`. - * - * To produce the color magenta: - * - * bgRgb24("foo", 0xff00ff); - * bgRgb24("foo", {r: 255, g: 0, b: 255}); - * @param str text color to apply 24bit rgb to - * @param color code - */ -export function bgRgb24(str: string, color: number | Rgb): string { - if (typeof color === "number") { - return run( - str, - code( - [48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], - 49, - ), - ); - } - return run( - str, - code( - [ - 48, - 2, - clampAndTruncate(color.r), - clampAndTruncate(color.g), - clampAndTruncate(color.b), - ], - 49, - ), - ); -} - -// https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js -const ANSI_PATTERN = new RegExp( - [ - "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", - "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", - ].join("|"), - "g", -); - -/** - * Remove ANSI escape codes from the string. - * @param string to remove ANSI escape codes from - */ -export function stripColor(string: string): string { - return string.replace(ANSI_PATTERN, ""); -} diff --git "a/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.metadata.json" "b/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.metadata.json" deleted file mode 100644 index 788a240..0000000 --- "a/.\\.cache/deps/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.metadata.json" +++ /dev/null @@ -1,26 +0,0 @@ -{ - "headers": { - "via": "1.1 16074517396ff3ce754e4ac422c346c8.cloudfront.net (CloudFront)", - "x-amz-replication-status": "FAILED", - "accept-ranges": "bytes", - "content-length": "11534", - "server": "deno/asia-southeast1-a", - "x-cache": "Miss from cloudfront", - "last-modified": "Tue, 09 Mar 2021 20:51:36 GMT", - "access-control-allow-origin": "*", - "x-amz-cf-pop": "SIN52-P1", - "cache-control": "public, max-age=31536000, immutable", - "content-type": "application/typescript; charset=utf-8", - "x-amz-cf-id": "sUT0Vbt2wx6_55PuRCWVAU_lMzpJKsER22pedMtdQvWv3inTn3sZBg==", - "etag": "\"2f4b78d714903ed31adbf934e39dba7d\"", - "date": "Sat, 22 Oct 2022 10:22:52 GMT", - "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", - "x-amz-version-id": "C8dK133OTLoAhq8XAmqc66CkiXwmD2Wa", - "vary": "Accept-Encoding, Origin" - }, - "url": "https://deno.land/std@0.90.0/fmt/colors.ts", - "now": { - "secs_since_epoch": 1666434171, - "nanos_since_epoch": 517815000 - } -} \ No newline at end of file diff --git "a/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.js" "b/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.js" deleted file mode 100644 index abb6e4e..0000000 --- "a/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.js" +++ /dev/null @@ -1,25 +0,0 @@ -import { Clarinet } from "https://deno.land/x/clarinet@v1.0.2/index.ts"; -import { assertEquals } from "https://deno.land/std@0.90.0/testing/asserts.ts"; -// Clarinet Default Test -Clarinet.test({ - name: "Ensure that <...>", - async fn (chain, accounts) { - let block = chain.mineBlock([]); - assertEquals(block.receipts.length, 0); - assertEquals(block.height, 2); - block = chain.mineBlock([]); - assertEquals(block.receipts.length, 0); - assertEquals(block.height, 3); - } -}); -//* Stats to Run the test -const contractname = "deed"; -const defaultStxVaultAmount = 5000; -const defaultMembers = [ - "deployer", - "wallet_1", - "wallet_2", - "wallet_3", - "wallet_4", -]; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vVXNlcnMveWFzaHVyYS9EZXZlbG9wZXIvVlNDb2RlUHJvamVjdHMvSGFja2F0aG9uL0RlZWRzL3Rlc3RzL2RlZWRfdGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDbGFyaW5ldCxcbiAgVHgsXG4gIENoYWluLFxuICBBY2NvdW50LFxuICB0eXBlcyxcbn0gZnJvbSBcImh0dHBzOi8vZGVuby5sYW5kL3gvY2xhcmluZXRAdjEuMC4yL2luZGV4LnRzXCI7XG5pbXBvcnQgeyBhc3NlcnRFcXVhbHMgfSBmcm9tIFwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuOTAuMC90ZXN0aW5nL2Fzc2VydHMudHNcIjtcblxuLy8gQ2xhcmluZXQgRGVmYXVsdCBUZXN0XG5DbGFyaW5ldC50ZXN0KHtcbiAgbmFtZTogXCJFbnN1cmUgdGhhdCA8Li4uPlwiLFxuICBhc3luYyBmbihjaGFpbjogQ2hhaW4sIGFjY291bnRzOiBNYXA8c3RyaW5nLCBBY2NvdW50Pikge1xuICAgIGxldCBibG9jayA9IGNoYWluLm1pbmVCbG9jayhbXG4gICAgICAvKlxuICAgICAgICogQWRkIHRyYW5zYWN0aW9ucyB3aXRoOlxuICAgICAgICogVHguY29udHJhY3RDYWxsKC4uLilcbiAgICAgICAqL1xuICAgIF0pO1xuICAgIGFzc2VydEVxdWFscyhibG9jay5yZWNlaXB0cy5sZW5ndGgsIDApO1xuICAgIGFzc2VydEVxdWFscyhibG9jay5oZWlnaHQsIDIpO1xuXG4gICAgYmxvY2sgPSBjaGFpbi5taW5lQmxvY2soW1xuICAgICAgLypcbiAgICAgICAqIEFkZCB0cmFuc2FjdGlvbnMgd2l0aDpcbiAgICAgICAqIFR4LmNvbnRyYWN0Q2FsbCguLi4pXG4gICAgICAgKi9cbiAgICBdKTtcbiAgICBhc3NlcnRFcXVhbHMoYmxvY2sucmVjZWlwdHMubGVuZ3RoLCAwKTtcbiAgICBhc3NlcnRFcXVhbHMoYmxvY2suaGVpZ2h0LCAzKTtcbiAgfSxcbn0pO1xuXG4vLyogU3RhdHMgdG8gUnVuIHRoZSB0ZXN0XG5jb25zdCBjb250cmFjdG5hbWUgPSBcImRlZWRcIjtcblxuY29uc3QgZGVmYXVsdFN0eFZhdWx0QW1vdW50ID0gNTAwMDtcbmNvbnN0IGRlZmF1bHRNZW1iZXJzID0gW1xuICBcImRlcGxveWVyXCIsXG4gIFwid2FsbGV0XzFcIixcbiAgXCJ3YWxsZXRfMlwiLFxuICBcIndhbGxldF8zXCIsXG4gIFwid2FsbGV0XzRcIixcbl07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsU0FDRSxRQUFRLFFBS0gsOENBQThDLENBQUM7QUFDdEQsU0FBUyxZQUFZLFFBQVEsaURBQWlELENBQUM7QUFFL0Usd0JBQXdCO0FBQ3hCLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDWixJQUFJLEVBQUUsbUJBQW1CO0lBQ3pCLE1BQU0sRUFBRSxFQUFDLEtBQVksRUFBRSxRQUE4QixFQUFFO1FBQ3JELElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFLM0IsQ0FBQyxBQUFDO1FBQ0gsWUFBWSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTlCLEtBQUssR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBS3ZCLENBQUMsQ0FBQztRQUNILFlBQVksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2QyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztLQUMvQjtDQUNGLENBQUMsQ0FBQztBQUVILHlCQUF5QjtBQUN6QixNQUFNLFlBQVksR0FBRyxNQUFNLEFBQUM7QUFFNUIsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEFBQUM7QUFDbkMsTUFBTSxjQUFjLEdBQUc7SUFDckIsVUFBVTtJQUNWLFVBQVU7SUFDVixVQUFVO0lBQ1YsVUFBVTtJQUNWLFVBQVU7Q0FDWCxBQUFDIn0= \ No newline at end of file diff --git "a/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.meta" "b/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.meta" deleted file mode 100644 index 0fa16a9..0000000 --- "a/.\\.cache/gen/file/Users/yashura/Developer/VSCodeProjects/Hackathon/Deeds/tests/deed_test.ts.meta" +++ /dev/null @@ -1 +0,0 @@ -{"source_hash":"8357632346833155902","emit_hash":"7647498746124307573"} \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.js" "b/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.js" deleted file mode 100644 index b1b431e..0000000 --- "a/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.js" +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. Do not rely on good formatting of values -// for AssertionError messages in browsers. -import { bold, gray, green, red, stripColor, white } from "../fmt/colors.ts"; -import { diff, DiffType } from "./_diff.ts"; -const CAN_NOT_DISPLAY = "[Cannot display]"; -export class AssertionError extends Error { - constructor(message){ - super(message); - this.name = "AssertionError"; - } -} -/** - * Converts the input into a string. Objects, Sets and Maps are sorted so as to - * make tests less flaky - * @param v Value to be formatted - */ export function _format(v) { - return globalThis.Deno ? Deno.inspect(v, { - depth: Infinity, - sorted: true, - trailingComma: true, - compact: false, - iterableLimit: Infinity - }) : `"${String(v).replace(/(?=["\\])/g, "\\")}"`; -} -/** - * Colors the output of assertion diffs - * @param diffType Difference type, either added or removed - */ function createColor(diffType) { - switch(diffType){ - case DiffType.added: - return (s)=>green(bold(s)); - case DiffType.removed: - return (s)=>red(bold(s)); - default: - return white; - } -} -/** - * Prefixes `+` or `-` in diff output - * @param diffType Difference type, either added or removed - */ function createSign(diffType) { - switch(diffType){ - case DiffType.added: - return "+ "; - case DiffType.removed: - return "- "; - default: - return " "; - } -} -function buildMessage(diffResult) { - const messages = []; - messages.push(""); - messages.push(""); - messages.push(` ${gray(bold("[Diff]"))} ${red(bold("Actual"))} / ${green(bold("Expected"))}`); - messages.push(""); - messages.push(""); - diffResult.forEach((result)=>{ - const c = createColor(result.type); - messages.push(c(`${createSign(result.type)}${result.value}`)); - }); - messages.push(""); - return messages; -} -function isKeyedCollection(x) { - return [ - Symbol.iterator, - "size" - ].every((k)=>k in x); -} -/** - * Deep equality comparison used in assertions - * @param c actual value - * @param d expected value - */ export function equal(c, d) { - const seen = new Map(); - return function compare(a, b) { - // Have to render RegExp & Date for string comparison - // unless it's mistreated as object - if (a && b && (a instanceof RegExp && b instanceof RegExp || a instanceof URL && b instanceof URL)) { - return String(a) === String(b); - } - if (a instanceof Date && b instanceof Date) { - const aTime = a.getTime(); - const bTime = b.getTime(); - // Check for NaN equality manually since NaN is not - // equal to itself. - if (Number.isNaN(aTime) && Number.isNaN(bTime)) { - return true; - } - return a.getTime() === b.getTime(); - } - if (Object.is(a, b)) { - return true; - } - if (a && typeof a === "object" && b && typeof b === "object") { - if (seen.get(a) === b) { - return true; - } - if (Object.keys(a || {}).length !== Object.keys(b || {}).length) { - return false; - } - if (isKeyedCollection(a) && isKeyedCollection(b)) { - if (a.size !== b.size) { - return false; - } - let unmatchedEntries = a.size; - for (const [aKey, aValue] of a.entries()){ - for (const [bKey, bValue] of b.entries()){ - /* Given that Map keys can be references, we need - * to ensure that they are also deeply equal */ if (aKey === aValue && bKey === bValue && compare(aKey, bKey) || compare(aKey, bKey) && compare(aValue, bValue)) { - unmatchedEntries--; - } - } - } - return unmatchedEntries === 0; - } - const merged = { - ...a, - ...b - }; - for (const key of [ - ...Object.getOwnPropertyNames(merged), - ...Object.getOwnPropertySymbols(merged), - ]){ - if (!compare(a && a[key], b && b[key])) { - return false; - } - } - seen.set(a, b); - return true; - } - return false; - }(c, d); -} -/** Make an assertion, error will be thrown if `expr` does not have truthy value. */ export function assert(expr, msg = "") { - if (!expr) { - throw new AssertionError(msg); - } -} -export function assertEquals(actual, expected, msg) { - if (equal(actual, expected)) { - return; - } - let message = ""; - const actualString = _format(actual); - const expectedString = _format(expected); - try { - const diffResult = diff(actualString.split("\n"), expectedString.split("\n")); - const diffMsg = buildMessage(diffResult).join("\n"); - message = `Values are not equal:\n${diffMsg}`; - } catch { - message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`; - } - if (msg) { - message = msg; - } - throw new AssertionError(message); -} -export function assertNotEquals(actual, expected, msg) { - if (!equal(actual, expected)) { - return; - } - let actualString; - let expectedString; - try { - actualString = String(actual); - } catch { - actualString = "[Cannot display]"; - } - try { - expectedString = String(expected); - } catch { - expectedString = "[Cannot display]"; - } - if (!msg) { - msg = `actual: ${actualString} expected: ${expectedString}`; - } - throw new AssertionError(msg); -} -export function assertStrictEquals(actual, expected, msg) { - if (actual === expected) { - return; - } - let message; - if (msg) { - message = msg; - } else { - const actualString = _format(actual); - const expectedString = _format(expected); - if (actualString === expectedString) { - const withOffset = actualString.split("\n").map((l)=>` ${l}`).join("\n"); - message = `Values have the same structure but are not reference-equal:\n\n${red(withOffset)}\n`; - } else { - try { - const diffResult = diff(actualString.split("\n"), expectedString.split("\n")); - const diffMsg = buildMessage(diffResult).join("\n"); - message = `Values are not strictly equal:\n${diffMsg}`; - } catch { - message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`; - } - } - } - throw new AssertionError(message); -} -export function assertNotStrictEquals(actual, expected, msg) { - if (actual !== expected) { - return; - } - throw new AssertionError(msg ?? `Expected "actual" to be strictly unequal to: ${_format(actual)}\n`); -} -/** - * Make an assertion that actual is not null or undefined. If not - * then thrown. - */ export function assertExists(actual, msg) { - if (actual === undefined || actual === null) { - if (!msg) { - msg = `actual: "${actual}" expected to match anything but null or undefined`; - } - throw new AssertionError(msg); - } -} -/** - * Make an assertion that actual includes expected. If not - * then thrown. - */ export function assertStringIncludes(actual, expected, msg) { - if (!actual.includes(expected)) { - if (!msg) { - msg = `actual: "${actual}" expected to contain: "${expected}"`; - } - throw new AssertionError(msg); - } -} -export function assertArrayIncludes(actual, expected, msg) { - const missing = []; - for(let i = 0; i < expected.length; i++){ - let found = false; - for(let j = 0; j < actual.length; j++){ - if (equal(expected[i], actual[j])) { - found = true; - break; - } - } - if (!found) { - missing.push(expected[i]); - } - } - if (missing.length === 0) { - return; - } - if (!msg) { - msg = `actual: "${_format(actual)}" expected to include: "${_format(expected)}"\nmissing: ${_format(missing)}`; - } - throw new AssertionError(msg); -} -/** - * Make an assertion that `actual` match RegExp `expected`. If not - * then thrown - */ export function assertMatch(actual, expected, msg) { - if (!expected.test(actual)) { - if (!msg) { - msg = `actual: "${actual}" expected to match: "${expected}"`; - } - throw new AssertionError(msg); - } -} -/** - * Make an assertion that `actual` not match RegExp `expected`. If match - * then thrown - */ export function assertNotMatch(actual, expected, msg) { - if (expected.test(actual)) { - if (!msg) { - msg = `actual: "${actual}" expected to not match: "${expected}"`; - } - throw new AssertionError(msg); - } -} -/** - * Make an assertion that `actual` object is a subset of `expected` object, deeply. - * If not, then throw. - */ export function assertObjectMatch(actual, expected) { - const seen = new WeakMap(); - return assertEquals(function filter(a, b) { - // Prevent infinite loop with circular references with same filter - if (seen.has(a) && seen.get(a) === b) { - return a; - } - seen.set(a, b); - // Filter keys and symbols which are present in both actual and expected - const filtered = {}; - const entries = [ - ...Object.getOwnPropertyNames(a), - ...Object.getOwnPropertySymbols(a), - ].filter((key)=>key in b).map((key)=>[ - key, - a[key] - ]); - // Build filtered object and filter recursively on nested objects references - for (const [key, value] of entries){ - if (typeof value === "object") { - const subset = b[key]; - if (typeof subset === "object" && subset) { - filtered[key] = filter(value, subset); - continue; - } - } - filtered[key] = value; - } - return filtered; - }(actual, expected), expected); -} -/** - * Forcefully throws a failed assertion - */ export function fail(msg) { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`); -} -/** - * Executes a function, expecting it to throw. If it does not, then it - * throws. An error class and a string that should be included in the - * error message can also be asserted. - */ export function assertThrows(fn, ErrorClass, msgIncludes = "", msg) { - let doesThrow = false; - let error = null; - try { - fn(); - } catch (e) { - if (e instanceof Error === false) { - throw new AssertionError("A non-Error object was thrown."); - } - if (ErrorClass && !(e instanceof ErrorClass)) { - msg = `Expected error to be instance of "${ErrorClass.name}", but was "${e.constructor.name}"${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - if (msgIncludes && !stripColor(e.message).includes(stripColor(msgIncludes))) { - msg = `Expected error message to include "${msgIncludes}", but got "${e.message}"${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - doesThrow = true; - error = e; - } - if (!doesThrow) { - msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - return error; -} -/** - * Executes a function which returns a promise, expecting it to throw or reject. - * If it does not, then it throws. An error class and a string that should be - * included in the error message can also be asserted. - */ export async function assertThrowsAsync(fn, ErrorClass, msgIncludes = "", msg) { - let doesThrow = false; - let error = null; - try { - await fn(); - } catch (e) { - if (e instanceof Error === false) { - throw new AssertionError("A non-Error object was thrown or rejected."); - } - if (ErrorClass && !(e instanceof ErrorClass)) { - msg = `Expected error to be instance of "${ErrorClass.name}", but got "${e.name}"${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - if (msgIncludes && !stripColor(e.message).includes(stripColor(msgIncludes))) { - msg = `Expected error message to include "${msgIncludes}", but got "${e.message}"${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - doesThrow = true; - error = e; - } - if (!doesThrow) { - msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; - throw new AssertionError(msg); - } - return error; -} -/** Use this to stub out methods that will throw when invoked. */ export function unimplemented(msg) { - throw new AssertionError(msg || "unimplemented"); -} -/** Use this to assert unreachable code. */ export function unreachable() { - throw new AssertionError("unreachable"); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjkwLjAvdGVzdGluZy9hc3NlcnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjEgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuIERvIG5vdCByZWx5IG9uIGdvb2QgZm9ybWF0dGluZyBvZiB2YWx1ZXNcbi8vIGZvciBBc3NlcnRpb25FcnJvciBtZXNzYWdlcyBpbiBicm93c2Vycy5cblxuaW1wb3J0IHsgYm9sZCwgZ3JheSwgZ3JlZW4sIHJlZCwgc3RyaXBDb2xvciwgd2hpdGUgfSBmcm9tIFwiLi4vZm10L2NvbG9ycy50c1wiO1xuaW1wb3J0IHsgZGlmZiwgRGlmZlJlc3VsdCwgRGlmZlR5cGUgfSBmcm9tIFwiLi9fZGlmZi50c1wiO1xuXG5jb25zdCBDQU5fTk9UX0RJU1BMQVkgPSBcIltDYW5ub3QgZGlzcGxheV1cIjtcblxuaW50ZXJmYWNlIENvbnN0cnVjdG9yIHtcbiAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgbmV3ICguLi5hcmdzOiBhbnlbXSk6IGFueTtcbn1cblxuZXhwb3J0IGNsYXNzIEFzc2VydGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIkFzc2VydGlvbkVycm9yXCI7XG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgaW5wdXQgaW50byBhIHN0cmluZy4gT2JqZWN0cywgU2V0cyBhbmQgTWFwcyBhcmUgc29ydGVkIHNvIGFzIHRvXG4gKiBtYWtlIHRlc3RzIGxlc3MgZmxha3lcbiAqIEBwYXJhbSB2IFZhbHVlIHRvIGJlIGZvcm1hdHRlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2Zvcm1hdCh2OiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdsb2JhbFRoaXMuRGVub1xuICAgID8gRGVuby5pbnNwZWN0KHYsIHtcbiAgICAgIGRlcHRoOiBJbmZpbml0eSxcbiAgICAgIHNvcnRlZDogdHJ1ZSxcbiAgICAgIHRyYWlsaW5nQ29tbWE6IHRydWUsXG4gICAgICBjb21wYWN0OiBmYWxzZSxcbiAgICAgIGl0ZXJhYmxlTGltaXQ6IEluZmluaXR5LFxuICAgIH0pXG4gICAgOiBgXCIke1N0cmluZyh2KS5yZXBsYWNlKC8oPz1bXCJcXFxcXSkvZywgXCJcXFxcXCIpfVwiYDtcbn1cblxuLyoqXG4gKiBDb2xvcnMgdGhlIG91dHB1dCBvZiBhc3NlcnRpb24gZGlmZnNcbiAqIEBwYXJhbSBkaWZmVHlwZSBEaWZmZXJlbmNlIHR5cGUsIGVpdGhlciBhZGRlZCBvciByZW1vdmVkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNvbG9yKGRpZmZUeXBlOiBEaWZmVHlwZSk6IChzOiBzdHJpbmcpID0+IHN0cmluZyB7XG4gIHN3aXRjaCAoZGlmZlR5cGUpIHtcbiAgICBjYXNlIERpZmZUeXBlLmFkZGVkOlxuICAgICAgcmV0dXJuIChzOiBzdHJpbmcpOiBzdHJpbmcgPT4gZ3JlZW4oYm9sZChzKSk7XG4gICAgY2FzZSBEaWZmVHlwZS5yZW1vdmVkOlxuICAgICAgcmV0dXJuIChzOiBzdHJpbmcpOiBzdHJpbmcgPT4gcmVkKGJvbGQocykpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gd2hpdGU7XG4gIH1cbn1cblxuLyoqXG4gKiBQcmVmaXhlcyBgK2Agb3IgYC1gIGluIGRpZmYgb3V0cHV0XG4gKiBAcGFyYW0gZGlmZlR5cGUgRGlmZmVyZW5jZSB0eXBlLCBlaXRoZXIgYWRkZWQgb3IgcmVtb3ZlZFxuICovXG5mdW5jdGlvbiBjcmVhdGVTaWduKGRpZmZUeXBlOiBEaWZmVHlwZSk6IHN0cmluZyB7XG4gIHN3aXRjaCAoZGlmZlR5cGUpIHtcbiAgICBjYXNlIERpZmZUeXBlLmFkZGVkOlxuICAgICAgcmV0dXJuIFwiKyAgIFwiO1xuICAgIGNhc2UgRGlmZlR5cGUucmVtb3ZlZDpcbiAgICAgIHJldHVybiBcIi0gICBcIjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFwiICAgIFwiO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTWVzc2FnZShkaWZmUmVzdWx0OiBSZWFkb25seUFycmF5PERpZmZSZXN1bHQ8c3RyaW5nPj4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG1lc3NhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICBtZXNzYWdlcy5wdXNoKFwiXCIpO1xuICBtZXNzYWdlcy5wdXNoKFwiXCIpO1xuICBtZXNzYWdlcy5wdXNoKFxuICAgIGAgICAgJHtncmF5KGJvbGQoXCJbRGlmZl1cIikpfSAke3JlZChib2xkKFwiQWN0dWFsXCIpKX0gLyAke1xuICAgICAgZ3JlZW4oYm9sZChcIkV4cGVjdGVkXCIpKVxuICAgIH1gLFxuICApO1xuICBtZXNzYWdlcy5wdXNoKFwiXCIpO1xuICBtZXNzYWdlcy5wdXNoKFwiXCIpO1xuICBkaWZmUmVzdWx0LmZvckVhY2goKHJlc3VsdDogRGlmZlJlc3VsdDxzdHJpbmc+KTogdm9pZCA9PiB7XG4gICAgY29uc3QgYyA9IGNyZWF0ZUNvbG9yKHJlc3VsdC50eXBlKTtcbiAgICBtZXNzYWdlcy5wdXNoKGMoYCR7Y3JlYXRlU2lnbihyZXN1bHQudHlwZSl9JHtyZXN1bHQudmFsdWV9YCkpO1xuICB9KTtcbiAgbWVzc2FnZXMucHVzaChcIlwiKTtcblxuICByZXR1cm4gbWVzc2FnZXM7XG59XG5cbmZ1bmN0aW9uIGlzS2V5ZWRDb2xsZWN0aW9uKHg6IHVua25vd24pOiB4IGlzIFNldDx1bmtub3duPiB7XG4gIHJldHVybiBbU3ltYm9sLml0ZXJhdG9yLCBcInNpemVcIl0uZXZlcnkoKGspID0+IGsgaW4gKHggYXMgU2V0PHVua25vd24+KSk7XG59XG5cbi8qKlxuICogRGVlcCBlcXVhbGl0eSBjb21wYXJpc29uIHVzZWQgaW4gYXNzZXJ0aW9uc1xuICogQHBhcmFtIGMgYWN0dWFsIHZhbHVlXG4gKiBAcGFyYW0gZCBleHBlY3RlZCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWwoYzogdW5rbm93biwgZDogdW5rbm93bik6IGJvb2xlYW4ge1xuICBjb25zdCBzZWVuID0gbmV3IE1hcCgpO1xuICByZXR1cm4gKGZ1bmN0aW9uIGNvbXBhcmUoYTogdW5rbm93biwgYjogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIC8vIEhhdmUgdG8gcmVuZGVyIFJlZ0V4cCAmIERhdGUgZm9yIHN0cmluZyBjb21wYXJpc29uXG4gICAgLy8gdW5sZXNzIGl0J3MgbWlzdHJlYXRlZCBhcyBvYmplY3RcbiAgICBpZiAoXG4gICAgICBhICYmXG4gICAgICBiICYmXG4gICAgICAoKGEgaW5zdGFuY2VvZiBSZWdFeHAgJiYgYiBpbnN0YW5jZW9mIFJlZ0V4cCkgfHxcbiAgICAgICAgKGEgaW5zdGFuY2VvZiBVUkwgJiYgYiBpbnN0YW5jZW9mIFVSTCkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGEpID09PSBTdHJpbmcoYik7XG4gICAgfVxuICAgIGlmIChhIGluc3RhbmNlb2YgRGF0ZSAmJiBiIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgY29uc3QgYVRpbWUgPSBhLmdldFRpbWUoKTtcbiAgICAgIGNvbnN0IGJUaW1lID0gYi5nZXRUaW1lKCk7XG4gICAgICAvLyBDaGVjayBmb3IgTmFOIGVxdWFsaXR5IG1hbnVhbGx5IHNpbmNlIE5hTiBpcyBub3RcbiAgICAgIC8vIGVxdWFsIHRvIGl0c2VsZi5cbiAgICAgIGlmIChOdW1iZXIuaXNOYU4oYVRpbWUpICYmIE51bWJlci5pc05hTihiVGltZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYS5nZXRUaW1lKCkgPT09IGIuZ2V0VGltZSgpO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LmlzKGEsIGIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGEgJiYgdHlwZW9mIGEgPT09IFwib2JqZWN0XCIgJiYgYiAmJiB0eXBlb2YgYiA9PT0gXCJvYmplY3RcIikge1xuICAgICAgaWYgKHNlZW4uZ2V0KGEpID09PSBiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKE9iamVjdC5rZXlzKGEgfHwge30pLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYiB8fCB7fSkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0tleWVkQ29sbGVjdGlvbihhKSAmJiBpc0tleWVkQ29sbGVjdGlvbihiKSkge1xuICAgICAgICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdW5tYXRjaGVkRW50cmllcyA9IGEuc2l6ZTtcblxuICAgICAgICBmb3IgKGNvbnN0IFthS2V5LCBhVmFsdWVdIG9mIGEuZW50cmllcygpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBbYktleSwgYlZhbHVlXSBvZiBiLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgLyogR2l2ZW4gdGhhdCBNYXAga2V5cyBjYW4gYmUgcmVmZXJlbmNlcywgd2UgbmVlZFxuICAgICAgICAgICAgICogdG8gZW5zdXJlIHRoYXQgdGhleSBhcmUgYWxzbyBkZWVwbHkgZXF1YWwgKi9cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgKGFLZXkgPT09IGFWYWx1ZSAmJiBiS2V5ID09PSBiVmFsdWUgJiYgY29tcGFyZShhS2V5LCBiS2V5KSkgfHxcbiAgICAgICAgICAgICAgKGNvbXBhcmUoYUtleSwgYktleSkgJiYgY29tcGFyZShhVmFsdWUsIGJWYWx1ZSkpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdW5tYXRjaGVkRW50cmllcy0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bm1hdGNoZWRFbnRyaWVzID09PSAwO1xuICAgICAgfVxuICAgICAgY29uc3QgbWVyZ2VkID0geyAuLi5hLCAuLi5iIH07XG4gICAgICBmb3IgKFxuICAgICAgICBjb25zdCBrZXkgb2YgW1xuICAgICAgICAgIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG1lcmdlZCksXG4gICAgICAgICAgLi4uT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtZXJnZWQpLFxuICAgICAgICBdXG4gICAgICApIHtcbiAgICAgICAgdHlwZSBLZXkgPSBrZXlvZiB0eXBlb2YgbWVyZ2VkO1xuICAgICAgICBpZiAoIWNvbXBhcmUoYSAmJiBhW2tleSBhcyBLZXldLCBiICYmIGJba2V5IGFzIEtleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzZWVuLnNldChhLCBiKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pKGMsIGQpO1xufVxuXG4vKiogTWFrZSBhbiBhc3NlcnRpb24sIGVycm9yIHdpbGwgYmUgdGhyb3duIGlmIGBleHByYCBkb2VzIG5vdCBoYXZlIHRydXRoeSB2YWx1ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogdW5rbm93biwgbXNnID0gXCJcIik6IGFzc2VydHMgZXhwciB7XG4gIGlmICghZXhwcikge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuICB9XG59XG5cbi8qKlxuICogTWFrZSBhbiBhc3NlcnRpb24gdGhhdCBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYCBhcmUgZXF1YWwsIGRlZXBseS4gSWYgbm90XG4gKiBkZWVwbHkgZXF1YWwsIHRoZW4gdGhyb3cuXG4gKlxuICogVHlwZSBwYXJhbWV0ZXIgY2FuIGJlIHNwZWNpZmllZCB0byBlbnN1cmUgdmFsdWVzIHVuZGVyIGNvbXBhcmlzb24gaGF2ZSB0aGUgc2FtZSB0eXBlLlxuICogRm9yIGV4YW1wbGU6XG4gKmBgYHRzXG4gKmFzc2VydEVxdWFsczxudW1iZXI+KDEsIDIpXG4gKmBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0RXF1YWxzKFxuICBhY3R1YWw6IHVua25vd24sXG4gIGV4cGVjdGVkOiB1bmtub3duLFxuICBtc2c/OiBzdHJpbmcsXG4pOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydEVxdWFsczxUPihhY3R1YWw6IFQsIGV4cGVjdGVkOiBULCBtc2c/OiBzdHJpbmcpOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydEVxdWFscyhcbiAgYWN0dWFsOiB1bmtub3duLFxuICBleHBlY3RlZDogdW5rbm93bixcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZCB7XG4gIGlmIChlcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgbWVzc2FnZSA9IFwiXCI7XG4gIGNvbnN0IGFjdHVhbFN0cmluZyA9IF9mb3JtYXQoYWN0dWFsKTtcbiAgY29uc3QgZXhwZWN0ZWRTdHJpbmcgPSBfZm9ybWF0KGV4cGVjdGVkKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBkaWZmUmVzdWx0ID0gZGlmZihcbiAgICAgIGFjdHVhbFN0cmluZy5zcGxpdChcIlxcblwiKSxcbiAgICAgIGV4cGVjdGVkU3RyaW5nLnNwbGl0KFwiXFxuXCIpLFxuICAgICk7XG4gICAgY29uc3QgZGlmZk1zZyA9IGJ1aWxkTWVzc2FnZShkaWZmUmVzdWx0KS5qb2luKFwiXFxuXCIpO1xuICAgIG1lc3NhZ2UgPSBgVmFsdWVzIGFyZSBub3QgZXF1YWw6XFxuJHtkaWZmTXNnfWA7XG4gIH0gY2F0Y2gge1xuICAgIG1lc3NhZ2UgPSBgXFxuJHtyZWQoQ0FOX05PVF9ESVNQTEFZKX0gKyBcXG5cXG5gO1xuICB9XG4gIGlmIChtc2cpIHtcbiAgICBtZXNzYWdlID0gbXNnO1xuICB9XG4gIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBNYWtlIGFuIGFzc2VydGlvbiB0aGF0IGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgIGFyZSBub3QgZXF1YWwsIGRlZXBseS5cbiAqIElmIG5vdCB0aGVuIHRocm93LlxuICpcbiAqIFR5cGUgcGFyYW1ldGVyIGNhbiBiZSBzcGVjaWZpZWQgdG8gZW5zdXJlIHZhbHVlcyB1bmRlciBjb21wYXJpc29uIGhhdmUgdGhlIHNhbWUgdHlwZS5cbiAqIEZvciBleGFtcGxlOlxuICpgYGB0c1xuICphc3NlcnROb3RFcXVhbHM8bnVtYmVyPigxLCAyKVxuICpgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vdEVxdWFscyhcbiAgYWN0dWFsOiB1bmtub3duLFxuICBleHBlY3RlZDogdW5rbm93bixcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROb3RFcXVhbHM8VD4oYWN0dWFsOiBULCBleHBlY3RlZDogVCwgbXNnPzogc3RyaW5nKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROb3RFcXVhbHMoXG4gIGFjdHVhbDogdW5rbm93bixcbiAgZXhwZWN0ZWQ6IHVua25vd24sXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQge1xuICBpZiAoIWVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBhY3R1YWxTdHJpbmc6IHN0cmluZztcbiAgbGV0IGV4cGVjdGVkU3RyaW5nOiBzdHJpbmc7XG4gIHRyeSB7XG4gICAgYWN0dWFsU3RyaW5nID0gU3RyaW5nKGFjdHVhbCk7XG4gIH0gY2F0Y2gge1xuICAgIGFjdHVhbFN0cmluZyA9IFwiW0Nhbm5vdCBkaXNwbGF5XVwiO1xuICB9XG4gIHRyeSB7XG4gICAgZXhwZWN0ZWRTdHJpbmcgPSBTdHJpbmcoZXhwZWN0ZWQpO1xuICB9IGNhdGNoIHtcbiAgICBleHBlY3RlZFN0cmluZyA9IFwiW0Nhbm5vdCBkaXNwbGF5XVwiO1xuICB9XG4gIGlmICghbXNnKSB7XG4gICAgbXNnID0gYGFjdHVhbDogJHthY3R1YWxTdHJpbmd9IGV4cGVjdGVkOiAke2V4cGVjdGVkU3RyaW5nfWA7XG4gIH1cbiAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1zZyk7XG59XG5cbi8qKlxuICogTWFrZSBhbiBhc3NlcnRpb24gdGhhdCBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYCBhcmUgc3RyaWN0bHkgZXF1YWwuICBJZlxuICogbm90IHRoZW4gdGhyb3cuXG4gKiBgYGB0c1xuICogYXNzZXJ0U3RyaWN0RXF1YWxzKDEsIDIpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFN0cmljdEVxdWFscyhcbiAgYWN0dWFsOiB1bmtub3duLFxuICBleHBlY3RlZDogdW5rbm93bixcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRTdHJpY3RFcXVhbHM8VD4oXG4gIGFjdHVhbDogVCxcbiAgZXhwZWN0ZWQ6IFQsXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0U3RyaWN0RXF1YWxzKFxuICBhY3R1YWw6IHVua25vd24sXG4gIGV4cGVjdGVkOiB1bmtub3duLFxuICBtc2c/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgbWVzc2FnZTogc3RyaW5nO1xuXG4gIGlmIChtc2cpIHtcbiAgICBtZXNzYWdlID0gbXNnO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFjdHVhbFN0cmluZyA9IF9mb3JtYXQoYWN0dWFsKTtcbiAgICBjb25zdCBleHBlY3RlZFN0cmluZyA9IF9mb3JtYXQoZXhwZWN0ZWQpO1xuXG4gICAgaWYgKGFjdHVhbFN0cmluZyA9PT0gZXhwZWN0ZWRTdHJpbmcpIHtcbiAgICAgIGNvbnN0IHdpdGhPZmZzZXQgPSBhY3R1YWxTdHJpbmdcbiAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgIC5tYXAoKGwpID0+IGAgICAgJHtsfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpO1xuICAgICAgbWVzc2FnZSA9XG4gICAgICAgIGBWYWx1ZXMgaGF2ZSB0aGUgc2FtZSBzdHJ1Y3R1cmUgYnV0IGFyZSBub3QgcmVmZXJlbmNlLWVxdWFsOlxcblxcbiR7XG4gICAgICAgICAgcmVkKHdpdGhPZmZzZXQpXG4gICAgICAgIH1cXG5gO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkaWZmUmVzdWx0ID0gZGlmZihcbiAgICAgICAgICBhY3R1YWxTdHJpbmcuc3BsaXQoXCJcXG5cIiksXG4gICAgICAgICAgZXhwZWN0ZWRTdHJpbmcuc3BsaXQoXCJcXG5cIiksXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGRpZmZNc2cgPSBidWlsZE1lc3NhZ2UoZGlmZlJlc3VsdCkuam9pbihcIlxcblwiKTtcbiAgICAgICAgbWVzc2FnZSA9IGBWYWx1ZXMgYXJlIG5vdCBzdHJpY3RseSBlcXVhbDpcXG4ke2RpZmZNc2d9YDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBtZXNzYWdlID0gYFxcbiR7cmVkKENBTl9OT1RfRElTUExBWSl9ICsgXFxuXFxuYDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSk7XG59XG5cbi8qKlxuICogTWFrZSBhbiBhc3NlcnRpb24gdGhhdCBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYCBhcmUgbm90IHN0cmljdGx5IGVxdWFsLlxuICogSWYgdGhlIHZhbHVlcyBhcmUgc3RyaWN0bHkgZXF1YWwgdGhlbiB0aHJvdy5cbiAqIGBgYHRzXG4gKiBhc3NlcnROb3RTdHJpY3RFcXVhbHMoMSwgMSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0Tm90U3RyaWN0RXF1YWxzKFxuICBhY3R1YWw6IHVua25vd24sXG4gIGV4cGVjdGVkOiB1bmtub3duLFxuICBtc2c/OiBzdHJpbmcsXG4pOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vdFN0cmljdEVxdWFsczxUPihcbiAgYWN0dWFsOiBULFxuICBleHBlY3RlZDogVCxcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROb3RTdHJpY3RFcXVhbHMoXG4gIGFjdHVhbDogdW5rbm93bixcbiAgZXhwZWN0ZWQ6IHVua25vd24sXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICBtc2cgPz8gYEV4cGVjdGVkIFwiYWN0dWFsXCIgdG8gYmUgc3RyaWN0bHkgdW5lcXVhbCB0bzogJHtfZm9ybWF0KGFjdHVhbCl9XFxuYCxcbiAgKTtcbn1cblxuLyoqXG4gKiBNYWtlIGFuIGFzc2VydGlvbiB0aGF0IGFjdHVhbCBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQuIElmIG5vdFxuICogdGhlbiB0aHJvd24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRFeGlzdHMoXG4gIGFjdHVhbDogdW5rbm93bixcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZCB7XG4gIGlmIChhY3R1YWwgPT09IHVuZGVmaW5lZCB8fCBhY3R1YWwgPT09IG51bGwpIHtcbiAgICBpZiAoIW1zZykge1xuICAgICAgbXNnID1cbiAgICAgICAgYGFjdHVhbDogXCIke2FjdHVhbH1cIiBleHBlY3RlZCB0byBtYXRjaCBhbnl0aGluZyBidXQgbnVsbCBvciB1bmRlZmluZWRgO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobXNnKTtcbiAgfVxufVxuXG4vKipcbiAqIE1ha2UgYW4gYXNzZXJ0aW9uIHRoYXQgYWN0dWFsIGluY2x1ZGVzIGV4cGVjdGVkLiBJZiBub3RcbiAqIHRoZW4gdGhyb3duLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0U3RyaW5nSW5jbHVkZXMoXG4gIGFjdHVhbDogc3RyaW5nLFxuICBleHBlY3RlZDogc3RyaW5nLFxuICBtc2c/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgaWYgKCFhY3R1YWwuaW5jbHVkZXMoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFtc2cpIHtcbiAgICAgIG1zZyA9IGBhY3R1YWw6IFwiJHthY3R1YWx9XCIgZXhwZWN0ZWQgdG8gY29udGFpbjogXCIke2V4cGVjdGVkfVwiYDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1zZyk7XG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlIGFuIGFzc2VydGlvbiB0aGF0IGBhY3R1YWxgIGluY2x1ZGVzIHRoZSBgZXhwZWN0ZWRgIHZhbHVlcy5cbiAqIElmIG5vdCB0aGVuIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICpcbiAqIFR5cGUgcGFyYW1ldGVyIGNhbiBiZSBzcGVjaWZpZWQgdG8gZW5zdXJlIHZhbHVlcyB1bmRlciBjb21wYXJpc29uIGhhdmUgdGhlIHNhbWUgdHlwZS5cbiAqIEZvciBleGFtcGxlOlxuICpgYGB0c1xuICphc3NlcnRBcnJheUluY2x1ZGVzPG51bWJlcj4oWzEsIDJdLCBbMl0pXG4gKmBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QXJyYXlJbmNsdWRlcyhcbiAgYWN0dWFsOiBBcnJheUxpa2U8dW5rbm93bj4sXG4gIGV4cGVjdGVkOiBBcnJheUxpa2U8dW5rbm93bj4sXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QXJyYXlJbmNsdWRlczxUPihcbiAgYWN0dWFsOiBBcnJheUxpa2U8VD4sXG4gIGV4cGVjdGVkOiBBcnJheUxpa2U8VD4sXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QXJyYXlJbmNsdWRlcyhcbiAgYWN0dWFsOiBBcnJheUxpa2U8dW5rbm93bj4sXG4gIGV4cGVjdGVkOiBBcnJheUxpa2U8dW5rbm93bj4sXG4gIG1zZz86IHN0cmluZyxcbik6IHZvaWQge1xuICBjb25zdCBtaXNzaW5nOiB1bmtub3duW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkrKykge1xuICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgYWN0dWFsLmxlbmd0aDsgaisrKSB7XG4gICAgICBpZiAoZXF1YWwoZXhwZWN0ZWRbaV0sIGFjdHVhbFtqXSkpIHtcbiAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFmb3VuZCkge1xuICAgICAgbWlzc2luZy5wdXNoKGV4cGVjdGVkW2ldKTtcbiAgICB9XG4gIH1cbiAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICghbXNnKSB7XG4gICAgbXNnID0gYGFjdHVhbDogXCIke19mb3JtYXQoYWN0dWFsKX1cIiBleHBlY3RlZCB0byBpbmNsdWRlOiBcIiR7XG4gICAgICBfZm9ybWF0KGV4cGVjdGVkKVxuICAgIH1cIlxcbm1pc3Npbmc6ICR7X2Zvcm1hdChtaXNzaW5nKX1gO1xuICB9XG4gIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xufVxuXG4vKipcbiAqIE1ha2UgYW4gYXNzZXJ0aW9uIHRoYXQgYGFjdHVhbGAgbWF0Y2ggUmVnRXhwIGBleHBlY3RlZGAuIElmIG5vdFxuICogdGhlbiB0aHJvd25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE1hdGNoKFxuICBhY3R1YWw6IHN0cmluZyxcbiAgZXhwZWN0ZWQ6IFJlZ0V4cCxcbiAgbXNnPzogc3RyaW5nLFxuKTogdm9pZCB7XG4gIGlmICghZXhwZWN0ZWQudGVzdChhY3R1YWwpKSB7XG4gICAgaWYgKCFtc2cpIHtcbiAgICAgIG1zZyA9IGBhY3R1YWw6IFwiJHthY3R1YWx9XCIgZXhwZWN0ZWQgdG8gbWF0Y2g6IFwiJHtleHBlY3RlZH1cImA7XG4gICAgfVxuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuICB9XG59XG5cbi8qKlxuICogTWFrZSBhbiBhc3NlcnRpb24gdGhhdCBgYWN0dWFsYCBub3QgbWF0Y2ggUmVnRXhwIGBleHBlY3RlZGAuIElmIG1hdGNoXG4gKiB0aGVuIHRocm93blxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0Tm90TWF0Y2goXG4gIGFjdHVhbDogc3RyaW5nLFxuICBleHBlY3RlZDogUmVnRXhwLFxuICBtc2c/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgaWYgKGV4cGVjdGVkLnRlc3QoYWN0dWFsKSkge1xuICAgIGlmICghbXNnKSB7XG4gICAgICBtc2cgPSBgYWN0dWFsOiBcIiR7YWN0dWFsfVwiIGV4cGVjdGVkIHRvIG5vdCBtYXRjaDogXCIke2V4cGVjdGVkfVwiYDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1zZyk7XG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlIGFuIGFzc2VydGlvbiB0aGF0IGBhY3R1YWxgIG9iamVjdCBpcyBhIHN1YnNldCBvZiBgZXhwZWN0ZWRgIG9iamVjdCwgZGVlcGx5LlxuICogSWYgbm90LCB0aGVuIHRocm93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0T2JqZWN0TWF0Y2goXG4gIGFjdHVhbDogUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPixcbiAgZXhwZWN0ZWQ6IFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4sXG4pOiB2b2lkIHtcbiAgdHlwZSBsb29zZSA9IFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj47XG4gIGNvbnN0IHNlZW4gPSBuZXcgV2Vha01hcCgpO1xuICByZXR1cm4gYXNzZXJ0RXF1YWxzKFxuICAgIChmdW5jdGlvbiBmaWx0ZXIoYTogbG9vc2UsIGI6IGxvb3NlKTogbG9vc2Uge1xuICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIHdpdGggY2lyY3VsYXIgcmVmZXJlbmNlcyB3aXRoIHNhbWUgZmlsdGVyXG4gICAgICBpZiAoKHNlZW4uaGFzKGEpKSAmJiAoc2Vlbi5nZXQoYSkgPT09IGIpKSB7XG4gICAgICAgIHJldHVybiBhO1xuICAgICAgfVxuICAgICAgc2Vlbi5zZXQoYSwgYik7XG4gICAgICAvLyBGaWx0ZXIga2V5cyBhbmQgc3ltYm9scyB3aGljaCBhcmUgcHJlc2VudCBpbiBib3RoIGFjdHVhbCBhbmQgZXhwZWN0ZWRcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0ge30gYXMgbG9vc2U7XG4gICAgICBjb25zdCBlbnRyaWVzID0gW1xuICAgICAgICAuLi5PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhKSxcbiAgICAgICAgLi4uT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhhKSxcbiAgICAgIF1cbiAgICAgICAgLmZpbHRlcigoa2V5KSA9PiBrZXkgaW4gYilcbiAgICAgICAgLm1hcCgoa2V5KSA9PiBba2V5LCBhW2tleSBhcyBzdHJpbmddXSkgYXMgQXJyYXk8W3N0cmluZywgdW5rbm93bl0+O1xuICAgICAgLy8gQnVpbGQgZmlsdGVyZWQgb2JqZWN0IGFuZCBmaWx0ZXIgcmVjdXJzaXZlbHkgb24gbmVzdGVkIG9iamVjdHMgcmVmZXJlbmNlc1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgZW50cmllcykge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgY29uc3Qgc3Vic2V0ID0gKGIgYXMgbG9vc2UpW2tleV07XG4gICAgICAgICAgaWYgKCh0eXBlb2Ygc3Vic2V0ID09PSBcIm9iamVjdFwiKSAmJiAoc3Vic2V0KSkge1xuICAgICAgICAgICAgZmlsdGVyZWRba2V5XSA9IGZpbHRlcih2YWx1ZSBhcyBsb29zZSwgc3Vic2V0IGFzIGxvb3NlKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmaWx0ZXJlZFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmlsdGVyZWQ7XG4gICAgfSkoYWN0dWFsLCBleHBlY3RlZCksXG4gICAgZXhwZWN0ZWQsXG4gICk7XG59XG5cbi8qKlxuICogRm9yY2VmdWxseSB0aHJvd3MgYSBmYWlsZWQgYXNzZXJ0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmYWlsKG1zZz86IHN0cmluZyk6IHZvaWQge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIGFzc2VydChmYWxzZSwgYEZhaWxlZCBhc3NlcnRpb24ke21zZyA/IGA6ICR7bXNnfWAgOiBcIi5cIn1gKTtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhIGZ1bmN0aW9uLCBleHBlY3RpbmcgaXQgdG8gdGhyb3cuICBJZiBpdCBkb2VzIG5vdCwgdGhlbiBpdFxuICogdGhyb3dzLiAgQW4gZXJyb3IgY2xhc3MgYW5kIGEgc3RyaW5nIHRoYXQgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZVxuICogZXJyb3IgbWVzc2FnZSBjYW4gYWxzbyBiZSBhc3NlcnRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFRocm93czxUID0gdm9pZD4oXG4gIGZuOiAoKSA9PiBULFxuICBFcnJvckNsYXNzPzogQ29uc3RydWN0b3IsXG4gIG1zZ0luY2x1ZGVzID0gXCJcIixcbiAgbXNnPzogc3RyaW5nLFxuKTogRXJyb3Ige1xuICBsZXQgZG9lc1Rocm93ID0gZmFsc2U7XG4gIGxldCBlcnJvciA9IG51bGw7XG4gIHRyeSB7XG4gICAgZm4oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXCJBIG5vbi1FcnJvciBvYmplY3Qgd2FzIHRocm93bi5cIik7XG4gICAgfVxuICAgIGlmIChFcnJvckNsYXNzICYmICEoZSBpbnN0YW5jZW9mIEVycm9yQ2xhc3MpKSB7XG4gICAgICBtc2cgPVxuICAgICAgICBgRXhwZWN0ZWQgZXJyb3IgdG8gYmUgaW5zdGFuY2Ugb2YgXCIke0Vycm9yQ2xhc3MubmFtZX1cIiwgYnV0IHdhcyBcIiR7ZS5jb25zdHJ1Y3Rvci5uYW1lfVwiJHtcbiAgICAgICAgICBtc2cgPyBgOiAke21zZ31gIDogXCIuXCJcbiAgICAgICAgfWA7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobXNnKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgbXNnSW5jbHVkZXMgJiZcbiAgICAgICFzdHJpcENvbG9yKGUubWVzc2FnZSkuaW5jbHVkZXMoc3RyaXBDb2xvcihtc2dJbmNsdWRlcykpXG4gICAgKSB7XG4gICAgICBtc2cgPVxuICAgICAgICBgRXhwZWN0ZWQgZXJyb3IgbWVzc2FnZSB0byBpbmNsdWRlIFwiJHttc2dJbmNsdWRlc31cIiwgYnV0IGdvdCBcIiR7ZS5tZXNzYWdlfVwiJHtcbiAgICAgICAgICBtc2cgPyBgOiAke21zZ31gIDogXCIuXCJcbiAgICAgICAgfWA7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobXNnKTtcbiAgICB9XG4gICAgZG9lc1Rocm93ID0gdHJ1ZTtcbiAgICBlcnJvciA9IGU7XG4gIH1cbiAgaWYgKCFkb2VzVGhyb3cpIHtcbiAgICBtc2cgPSBgRXhwZWN0ZWQgZnVuY3Rpb24gdG8gdGhyb3cke21zZyA/IGA6ICR7bXNnfWAgOiBcIi5cIn1gO1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSBwcm9taXNlLCBleHBlY3RpbmcgaXQgdG8gdGhyb3cgb3IgcmVqZWN0LlxuICogSWYgaXQgZG9lcyBub3QsIHRoZW4gaXQgdGhyb3dzLiAgQW4gZXJyb3IgY2xhc3MgYW5kIGEgc3RyaW5nIHRoYXQgc2hvdWxkIGJlXG4gKiBpbmNsdWRlZCBpbiB0aGUgZXJyb3IgbWVzc2FnZSBjYW4gYWxzbyBiZSBhc3NlcnRlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFzc2VydFRocm93c0FzeW5jPFQgPSB2b2lkPihcbiAgZm46ICgpID0+IFByb21pc2U8VD4sXG4gIEVycm9yQ2xhc3M/OiBDb25zdHJ1Y3RvcixcbiAgbXNnSW5jbHVkZXMgPSBcIlwiLFxuICBtc2c/OiBzdHJpbmcsXG4pOiBQcm9taXNlPEVycm9yPiB7XG4gIGxldCBkb2VzVGhyb3cgPSBmYWxzZTtcbiAgbGV0IGVycm9yID0gbnVsbDtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmbigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciA9PT0gZmFsc2UpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcIkEgbm9uLUVycm9yIG9iamVjdCB3YXMgdGhyb3duIG9yIHJlamVjdGVkLlwiKTtcbiAgICB9XG4gICAgaWYgKEVycm9yQ2xhc3MgJiYgIShlIGluc3RhbmNlb2YgRXJyb3JDbGFzcykpIHtcbiAgICAgIG1zZyA9XG4gICAgICAgIGBFeHBlY3RlZCBlcnJvciB0byBiZSBpbnN0YW5jZSBvZiBcIiR7RXJyb3JDbGFzcy5uYW1lfVwiLCBidXQgZ290IFwiJHtlLm5hbWV9XCIke1xuICAgICAgICAgIG1zZyA/IGA6ICR7bXNnfWAgOiBcIi5cIlxuICAgICAgICB9YDtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBtc2dJbmNsdWRlcyAmJlxuICAgICAgIXN0cmlwQ29sb3IoZS5tZXNzYWdlKS5pbmNsdWRlcyhzdHJpcENvbG9yKG1zZ0luY2x1ZGVzKSlcbiAgICApIHtcbiAgICAgIG1zZyA9XG4gICAgICAgIGBFeHBlY3RlZCBlcnJvciBtZXNzYWdlIHRvIGluY2x1ZGUgXCIke21zZ0luY2x1ZGVzfVwiLCBidXQgZ290IFwiJHtlLm1lc3NhZ2V9XCIke1xuICAgICAgICAgIG1zZyA/IGA6ICR7bXNnfWAgOiBcIi5cIlxuICAgICAgICB9YDtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuICAgIH1cbiAgICBkb2VzVGhyb3cgPSB0cnVlO1xuICAgIGVycm9yID0gZTtcbiAgfVxuICBpZiAoIWRvZXNUaHJvdykge1xuICAgIG1zZyA9IGBFeHBlY3RlZCBmdW5jdGlvbiB0byB0aHJvdyR7bXNnID8gYDogJHttc2d9YCA6IFwiLlwifWA7XG4gICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1zZyk7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG4vKiogVXNlIHRoaXMgdG8gc3R1YiBvdXQgbWV0aG9kcyB0aGF0IHdpbGwgdGhyb3cgd2hlbiBpbnZva2VkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaW1wbGVtZW50ZWQobXNnPzogc3RyaW5nKTogbmV2ZXIge1xuICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobXNnIHx8IFwidW5pbXBsZW1lbnRlZFwiKTtcbn1cblxuLyoqIFVzZSB0aGlzIHRvIGFzc2VydCB1bnJlYWNoYWJsZSBjb2RlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVucmVhY2hhYmxlKCk6IG5ldmVyIHtcbiAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFwidW5yZWFjaGFibGVcIik7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSwyQ0FBMkM7QUFFM0MsU0FBUyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEtBQUssUUFBUSxrQkFBa0IsQ0FBQztBQUM3RSxTQUFTLElBQUksRUFBYyxRQUFRLFFBQVEsWUFBWSxDQUFDO0FBRXhELE1BQU0sZUFBZSxHQUFHLGtCQUFrQixBQUFDO0FBTzNDLE9BQU8sTUFBTSxjQUFjLFNBQVMsS0FBSztJQUN2QyxZQUFZLE9BQWUsQ0FBRTtRQUMzQixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJ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 \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.meta" "b/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.meta" deleted file mode 100644 index 2a9b655..0000000 --- "a/.\\.cache/gen/https/deno.land/688e058fb547030f059b02f08b6bc2f36f15d56e6edb3bce6b48fdf563fb7ae9.meta" +++ /dev/null @@ -1 +0,0 @@ -{"source_hash":"9406172266376655746","emit_hash":"7495598743142824601"} \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.js" "b/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.js" deleted file mode 100644 index c9c0a0d..0000000 --- "a/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.js" +++ /dev/null @@ -1,622 +0,0 @@ -export class Tx { - type; - sender; - contractCall; - transferStx; - deployContract; - constructor(type, sender){ - this.type = type; - this.sender = sender; - } - static transferSTX(amount, recipient, sender) { - let tx = new Tx(1, sender); - tx.transferStx = { - recipient, - amount - }; - return tx; - } - static contractCall(contract, method, args, sender) { - let tx = new Tx(2, sender); - tx.contractCall = { - contract, - method, - args - }; - return tx; - } - static deployContract(name, code, sender) { - let tx = new Tx(3, sender); - tx.deployContract = { - name, - code - }; - return tx; - } -} -export class Chain { - sessionId; - blockHeight = 1; - constructor(sessionId){ - this.sessionId = sessionId; - } - mineBlock(transactions) { - // @ts-ignore - let result = JSON.parse(Deno.core.opSync("api/v1/mine_block", { - sessionId: this.sessionId, - transactions: transactions - })); - this.blockHeight = result.block_height; - let block = { - height: result.block_height, - receipts: result.receipts - }; - return block; - } - mineEmptyBlock(count) { - let result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/mine_empty_blocks", { - sessionId: this.sessionId, - count: count - })); - this.blockHeight = result.block_height; - let emptyBlock = { - session_id: result.session_id, - block_height: result.block_height - }; - return emptyBlock; - } - mineEmptyBlockUntil(targetBlockHeight) { - let count = targetBlockHeight - this.blockHeight; - if (count < 0) { - throw new Error(`Chain tip cannot be moved from ${this.blockHeight} to ${targetBlockHeight}`); - } - return this.mineEmptyBlock(count); - } - callReadOnlyFn(contract, method, args, sender) { - let result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/call_read_only_fn", { - sessionId: this.sessionId, - contract: contract, - method: method, - args: args, - sender: sender - })); - let readOnlyFn = { - session_id: result.session_id, - result: result.result, - events: result.events - }; - return readOnlyFn; - } - getAssetsMaps() { - let result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/get_assets_maps", { - sessionId: this.sessionId - })); - let assetsMaps = { - session_id: result.session_id, - assets: result.assets - }; - return assetsMaps; - } -} -export class Clarinet { - static test(options) { - // @ts-ignore - Deno.test({ - name: options.name, - only: options.only, - ignore: options.ignore, - async fn () { - let hasPreDeploymentSteps = options.preDeployment !== undefined; - let result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/new_session", { - name: options.name, - loadDeployment: !hasPreDeploymentSteps, - deploymentPath: options.deploymentPath - })); - if (options.preDeployment) { - let chain = new Chain(result["session_id"]); - let accounts = new Map(); - for (let account of result["accounts"]){ - accounts.set(account.name, account); - } - await options.preDeployment(chain, accounts); - result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/load_deployment", { - sessionId: chain.sessionId, - deploymentPath: options.deploymentPath - })); - } - let chain1 = new Chain(result["session_id"]); - let accounts1 = new Map(); - for (let account1 of result["accounts"]){ - accounts1.set(account1.name, account1); - } - let contracts = new Map(); - for (let contract of result["contracts"]){ - contracts.set(contract.contract_id, contract); - } - await options.fn(chain1, accounts1, contracts); - // @ts-ignore - JSON.parse(Deno.core.opSync("api/v1/terminate_session", { - sessionId: chain1.sessionId - })); - } - }); - } - static run(options) { - // @ts-ignore - Deno.test({ - name: "running script", - async fn () { - let result = JSON.parse(// @ts-ignore - Deno.core.opSync("api/v1/new_session", { - name: "running script", - loadDeployment: true, - deploymentPath: undefined - })); - let accounts = new Map(); - for (let account of result["accounts"]){ - accounts.set(account.name, account); - } - let contracts = new Map(); - for (let contract of result["contracts"]){ - contracts.set(contract.contract_id, contract); - } - let stacks_node = { - url: result["stacks_node_url"] - }; - await options.fn(accounts, contracts, stacks_node); - } - }); - } -} -export var types; -(function(types) { - const byteToHex = []; - for(let n = 0; n <= 0xff; ++n){ - const hexOctet = n.toString(16).padStart(2, "0"); - byteToHex.push(hexOctet); - } - function serializeTuple(input) { - let items = []; - for (var [key, value] of Object.entries(input)){ - if (typeof value === "object") { - items.push(`${key}: { ${serializeTuple(value)} }`); - } else if (Array.isArray(value)) { - // todo(ludo): not supported, should panic - } else { - items.push(`${key}: ${value}`); - } - } - return items.join(", "); - } - function isObject(obj) { - return typeof obj === "object" && !Array.isArray(obj); - } - function ok(val) { - return `(ok ${val})`; - } - types.ok = ok; - function err(val) { - return `(err ${val})`; - } - types.err = err; - function some(val) { - return `(some ${val})`; - } - types.some = some; - function none() { - return `none`; - } - types.none = none; - function bool(val) { - return `${val}`; - } - types.bool = bool; - function int(val) { - return `${val}`; - } - types.int = int; - function uint(val) { - return `u${val}`; - } - types.uint = uint; - function ascii(val) { - return JSON.stringify(val); - } - types.ascii = ascii; - function utf8(val) { - return `u${JSON.stringify(val)}`; - } - types.utf8 = utf8; - function buff(val) { - const buff = typeof val == "string" ? new TextEncoder().encode(val) : new Uint8Array(val); - const hexOctets = new Array(buff.length); - for(let i = 0; i < buff.length; ++i){ - hexOctets[i] = byteToHex[buff[i]]; - } - return `0x${hexOctets.join("")}`; - } - types.buff = buff; - function list(val) { - return `(list ${val.join(" ")})`; - } - types.list = list; - function principal(val) { - return `'${val}`; - } - types.principal = principal; - function tuple(val) { - return `{ ${serializeTuple(val)} }`; - } - types.tuple = tuple; -})(types || (types = {})); -function consume(src, expectation, wrapped) { - let dst = (" " + src).slice(1); - let size = expectation.length; - if (!wrapped && src !== expectation) { - throw new Error(`Expected ${green(expectation.toString())}, got ${red(src.toString())}`); - } - if (wrapped) { - size += 2; - } - if (dst.length < size) { - throw new Error(`Expected ${green(expectation.toString())}, got ${red(src.toString())}`); - } - if (wrapped) { - dst = dst.substring(1, dst.length - 1); - } - let res = dst.slice(0, expectation.length); - if (res !== expectation) { - throw new Error(`Expected ${green(expectation.toString())}, got ${red(src.toString())}`); - } - let leftPad = 0; - if (dst.charAt(expectation.length) === " ") { - leftPad = 1; - } - let remainder = dst.substring(expectation.length + leftPad); - return remainder; -} -String.prototype.expectOk = function() { - return consume(this, "ok", true); -}; -String.prototype.expectErr = function() { - return consume(this, "err", true); -}; -String.prototype.expectSome = function() { - return consume(this, "some", true); -}; -String.prototype.expectNone = function() { - return consume(this, "none", false); -}; -String.prototype.expectBool = function(value) { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return value; -}; -String.prototype.expectUint = function(value) { - try { - consume(this, `u${value}`, false); - } catch (error) { - throw error; - } - return BigInt(value); -}; -String.prototype.expectInt = function(value) { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return BigInt(value); -}; -String.prototype.expectBuff = function(value) { - let buffer = types.buff(value); - if (this !== buffer) { - throw new Error(`Expected ${green(buffer)}, got ${red(this.toString())}`); - } - return value; -}; -String.prototype.expectAscii = function(value) { - try { - consume(this, `"${value}"`, false); - } catch (error) { - throw error; - } - return value; -}; -String.prototype.expectUtf8 = function(value) { - try { - consume(this, `u"${value}"`, false); - } catch (error) { - throw error; - } - return value; -}; -String.prototype.expectPrincipal = function(value) { - try { - consume(this, `${value}`, false); - } catch (error) { - throw error; - } - return value; -}; -String.prototype.expectList = function() { - if (this.charAt(0) !== "[" || this.charAt(this.length - 1) !== "]") { - throw new Error(`Expected ${green("(list ...)")}, got ${red(this.toString())}`); - } - let stack = []; - let elements = []; - let start = 1; - for(var i = 0; i < this.length; i++){ - if (this.charAt(i) === "," && stack.length == 1) { - elements.push(this.substring(start, i)); - start = i + 2; - } - if ([ - "(", - "[", - "{" - ].includes(this.charAt(i))) { - stack.push(this.charAt(i)); - } - if (this.charAt(i) === ")" && stack[stack.length - 1] === "(") { - stack.pop(); - } - if (this.charAt(i) === "}" && stack[stack.length - 1] === "{") { - stack.pop(); - } - if (this.charAt(i) === "]" && stack[stack.length - 1] === "[") { - stack.pop(); - } - } - let remainder = this.substring(start, this.length - 1); - if (remainder.length > 0) { - elements.push(remainder); - } - return elements; -}; -String.prototype.expectTuple = function() { - if (this.charAt(0) !== "{" || this.charAt(this.length - 1) !== "}") { - throw new Error(`Expected ${green("(tuple ...)")}, got ${red(this.toString())}`); - } - let start = 1; - let stack = []; - let elements = []; - for(var i = 0; i < this.length; i++){ - if (this.charAt(i) === "," && stack.length == 1) { - elements.push(this.substring(start, i)); - start = i + 2; - } - if ([ - "(", - "[", - "{" - ].includes(this.charAt(i))) { - stack.push(this.charAt(i)); - } - if (this.charAt(i) === ")" && stack[stack.length - 1] === "(") { - stack.pop(); - } - if (this.charAt(i) === "}" && stack[stack.length - 1] === "{") { - stack.pop(); - } - if (this.charAt(i) === "]" && stack[stack.length - 1] === "[") { - stack.pop(); - } - } - let remainder = this.substring(start, this.length - 1); - if (remainder.length > 0) { - elements.push(remainder); - } - let tuple = {}; - for (let element of elements){ - for(var i = 0; i < element.length; i++){ - if (element.charAt(i) === ":") { - let key = element.substring(0, i); - let value = element.substring(i + 2, element.length); - tuple[key] = value; - break; - } - } - } - return tuple; -}; -Array.prototype.expectSTXTransferEvent = function(amount, sender, recipient) { - for (let event of this){ - try { - let e = {}; - e["amount"] = event.stx_transfer_event.amount.expectInt(amount); - e["sender"] = event.stx_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.stx_transfer_event.recipient.expectPrincipal(recipient); - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected STXTransferEvent`); -}; -Array.prototype.expectFungibleTokenTransferEvent = function(amount, sender, recipient, assetId) { - for (let event of this){ - try { - let e = {}; - e["amount"] = event.ft_transfer_event.amount.expectInt(amount); - e["sender"] = event.ft_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.ft_transfer_event.recipient.expectPrincipal(recipient); - if (event.ft_transfer_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_transfer_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected FungibleTokenTransferEvent(${amount}, ${sender}, ${recipient}, ${assetId})\n${JSON.stringify(this)}`); -}; -Array.prototype.expectFungibleTokenMintEvent = function(amount, recipient, assetId) { - for (let event of this){ - try { - let e = {}; - e["amount"] = event.ft_mint_event.amount.expectInt(amount); - e["recipient"] = event.ft_mint_event.recipient.expectPrincipal(recipient); - if (event.ft_mint_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_mint_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected FungibleTokenMintEvent`); -}; -Array.prototype.expectFungibleTokenBurnEvent = function(amount, sender, assetId) { - for (let event of this){ - try { - let e = {}; - e["amount"] = event.ft_burn_event.amount.expectInt(amount); - e["sender"] = event.ft_burn_event.sender.expectPrincipal(sender); - if (event.ft_burn_event.asset_identifier.endsWith(assetId)) { - e["assetId"] = event.ft_burn_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected FungibleTokenBurnEvent`); -}; -Array.prototype.expectPrintEvent = function(contract_identifier, value) { - for (let event of this){ - try { - let e = {}; - e["contract_identifier"] = event.contract_event.contract_identifier.expectPrincipal(contract_identifier); - if (event.contract_event.topic.endsWith("print")) { - e["topic"] = event.contract_event.topic; - } else { - continue; - } - if (event.contract_event.value.endsWith(value)) { - e["value"] = event.contract_event.value; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected PrintEvent`); -}; -// Array.prototype.expectEvent = function(sel: (e: Object) => Object) { -// for (let event of this) { -// try { -// sel(event); -// return event as Object; -// } catch (error) { -// continue; -// } -// } -// throw new Error(`Unable to retrieve expected PrintEvent`); -// } -Array.prototype.expectNonFungibleTokenTransferEvent = function(tokenId, sender, recipient, assetAddress, assetId) { - for (let event of this){ - try { - let e = {}; - if (event.nft_transfer_event.value === tokenId) { - e["tokenId"] = event.nft_transfer_event.value; - } else { - continue; - } - e["sender"] = event.nft_transfer_event.sender.expectPrincipal(sender); - e["recipient"] = event.nft_transfer_event.recipient.expectPrincipal(recipient); - if (event.nft_transfer_event.asset_identifier === `${assetAddress}::${assetId}`) { - e["assetId"] = event.nft_transfer_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenTransferEvent`); -}; -Array.prototype.expectNonFungibleTokenMintEvent = function(tokenId, recipient, assetAddress, assetId) { - for (let event of this){ - try { - let e = {}; - if (event.nft_mint_event.value === tokenId) { - e["tokenId"] = event.nft_mint_event.value; - } else { - continue; - } - e["recipient"] = event.nft_mint_event.recipient.expectPrincipal(recipient); - if (event.nft_mint_event.asset_identifier === `${assetAddress}::${assetId}`) { - e["assetId"] = event.nft_mint_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenMintEvent`); -}; -Array.prototype.expectNonFungibleTokenBurnEvent = function(tokenId, sender, assetAddress, assetId) { - for (let event of this){ - try { - let e = {}; - if (event.nft_burn_event.value === tokenId) { - e["tokenId"] = event.nft_burn_event.value; - } else { - continue; - } - e["sender"] = event.nft_burn_event.sender.expectPrincipal(sender); - if (event.nft_burn_event.asset_identifier === `${assetAddress}::${assetId}`) { - e["assetId"] = event.nft_burn_event.asset_identifier; - } else { - continue; - } - return e; - } catch (error) { - continue; - } - } - throw new Error(`Unable to retrieve expected NonFungibleTokenBurnEvent`); -}; -const noColor = globalThis.Deno?.noColor ?? true; -let enabled = !noColor; -function code(open, close) { - return { - open: `\x1b[${open.join(";")}m`, - close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g") - }; -} -function run(str, code) { - return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; -} -export function red(str) { - return run(str, code([ - 31 - ], 39)); -} -export function green(str) { - return run(str, code([ - 32 - ], 39)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3gvY2xhcmluZXRAdjEuMC4yL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBUeCB7XG4gIHR5cGU6IG51bWJlcjtcbiAgc2VuZGVyOiBzdHJpbmc7XG4gIGNvbnRyYWN0Q2FsbD86IFR4Q29udHJhY3RDYWxsO1xuICB0cmFuc2ZlclN0eD86IFR4VHJhbnNmZXI7XG4gIGRlcGxveUNvbnRyYWN0PzogVHhEZXBsb3lDb250cmFjdDtcblxuICBjb25zdHJ1Y3Rvcih0eXBlOiBudW1iZXIsIHNlbmRlcjogc3RyaW5nKSB7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLnNlbmRlciA9IHNlbmRlcjtcbiAgfVxuXG4gIHN0YXRpYyB0cmFuc2ZlclNUWChhbW91bnQ6IG51bWJlciwgcmVjaXBpZW50OiBzdHJpbmcsIHNlbmRlcjogc3RyaW5nKSB7XG4gICAgbGV0IHR4ID0gbmV3IFR4KDEsIHNlbmRlcik7XG4gICAgdHgudHJhbnNmZXJTdHggPSB7XG4gICAgICByZWNpcGllbnQsXG4gICAgICBhbW91bnQsXG4gICAgfTtcbiAgICByZXR1cm4gdHg7XG4gIH1cblxuICBzdGF0aWMgY29udHJhY3RDYWxsKFxuICAgIGNvbnRyYWN0OiBzdHJpbmcsXG4gICAgbWV0aG9kOiBzdHJpbmcsXG4gICAgYXJnczogQXJyYXk8c3RyaW5nPixcbiAgICBzZW5kZXI6IHN0cmluZyxcbiAgKSB7XG4gICAgbGV0IHR4ID0gbmV3IFR4KDIsIHNlbmRlcik7XG4gICAgdHguY29udHJhY3RDYWxsID0ge1xuICAgICAgY29udHJhY3QsXG4gICAgICBtZXRob2QsXG4gICAgICBhcmdzLFxuICAgIH07XG4gICAgcmV0dXJuIHR4O1xuICB9XG5cbiAgc3RhdGljIGRlcGxveUNvbnRyYWN0KG5hbWU6IHN0cmluZywgY29kZTogc3RyaW5nLCBzZW5kZXI6IHN0cmluZykge1xuICAgIGxldCB0eCA9IG5ldyBUeCgzLCBzZW5kZXIpO1xuICAgIHR4LmRlcGxveUNvbnRyYWN0ID0ge1xuICAgICAgbmFtZSxcbiAgICAgIGNvZGUsXG4gICAgfTtcbiAgICByZXR1cm4gdHg7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeENvbnRyYWN0Q2FsbCB7XG4gIGNvbnRyYWN0OiBzdHJpbmc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICBhcmdzOiBBcnJheTxzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFR4RGVwbG95Q29udHJhY3Qge1xuICBjb2RlOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeFRyYW5zZmVyIHtcbiAgYW1vdW50OiBudW1iZXI7XG4gIHJlY2lwaWVudDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFR4UmVjZWlwdCB7XG4gIHJlc3VsdDogc3RyaW5nO1xuICBldmVudHM6IEFycmF5PGFueT47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmxvY2sge1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgcmVjZWlwdHM6IEFycmF5PFR4UmVjZWlwdD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWNjb3VudCB7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgYmFsYW5jZTogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhaW4ge1xuICBzZXNzaW9uSWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkT25seUZuIHtcbiAgc2Vzc2lvbl9pZDogbnVtYmVyO1xuICByZXN1bHQ6IHN0cmluZztcbiAgZXZlbnRzOiBBcnJheTxhbnk+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVtcHR5QmxvY2sge1xuICBzZXNzaW9uX2lkOiBudW1iZXI7XG4gIGJsb2NrX2hlaWdodDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2V0c01hcHMge1xuICBzZXNzaW9uX2lkOiBudW1iZXI7XG4gIGFzc2V0czoge1xuICAgIFtuYW1lOiBzdHJpbmddOiB7XG4gICAgICBbb3duZXI6IHN0cmluZ106IG51bWJlcjtcbiAgICB9O1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgQ2hhaW4ge1xuICBzZXNzaW9uSWQ6IG51bWJlcjtcbiAgYmxvY2tIZWlnaHQ6IG51bWJlciA9IDE7XG5cbiAgY29uc3RydWN0b3Ioc2Vzc2lvbklkOiBudW1iZXIpIHtcbiAgICB0aGlzLnNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgfVxuXG4gIG1pbmVCbG9jayh0cmFuc2FjdGlvbnM6IEFycmF5PFR4Pik6IEJsb2NrIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgbGV0IHJlc3VsdCA9IEpTT04ucGFyc2UoRGVuby5jb3JlLm9wU3luYyhcImFwaS92MS9taW5lX2Jsb2NrXCIsIHtcbiAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uSWQsXG4gICAgICB0cmFuc2FjdGlvbnM6IHRyYW5zYWN0aW9ucyxcbiAgICB9KSk7XG4gICAgdGhpcy5ibG9ja0hlaWdodCA9IHJlc3VsdC5ibG9ja19oZWlnaHQ7XG4gICAgbGV0IGJsb2NrOiBCbG9jayA9IHtcbiAgICAgIGhlaWdodDogcmVzdWx0LmJsb2NrX2hlaWdodCxcbiAgICAgIHJlY2VpcHRzOiByZXN1bHQucmVjZWlwdHMsXG4gICAgfTtcbiAgICByZXR1cm4gYmxvY2s7XG4gIH1cblxuICBtaW5lRW1wdHlCbG9jayhjb3VudDogbnVtYmVyKTogRW1wdHlCbG9jayB7XG4gICAgbGV0IHJlc3VsdCA9IEpTT04ucGFyc2UoXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBEZW5vLmNvcmUub3BTeW5jKFwiYXBpL3YxL21pbmVfZW1wdHlfYmxvY2tzXCIsIHtcbiAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgICAgY291bnQ6IGNvdW50LFxuICAgICAgfSksXG4gICAgKTtcbiAgICB0aGlzLmJsb2NrSGVpZ2h0ID0gcmVzdWx0LmJsb2NrX2hlaWdodDtcbiAgICBsZXQgZW1wdHlCbG9jazogRW1wdHlCbG9jayA9IHtcbiAgICAgIHNlc3Npb25faWQ6IHJlc3VsdC5zZXNzaW9uX2lkLFxuICAgICAgYmxvY2tfaGVpZ2h0OiByZXN1bHQuYmxvY2tfaGVpZ2h0LFxuICAgIH07XG4gICAgcmV0dXJuIGVtcHR5QmxvY2s7XG4gIH1cblxuICBtaW5lRW1wdHlCbG9ja1VudGlsKHRhcmdldEJsb2NrSGVpZ2h0OiBudW1iZXIpOiBFbXB0eUJsb2NrIHtcbiAgICBsZXQgY291bnQgPSB0YXJnZXRCbG9ja0hlaWdodCAtIHRoaXMuYmxvY2tIZWlnaHQ7XG4gICAgaWYgKGNvdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ2hhaW4gdGlwIGNhbm5vdCBiZSBtb3ZlZCBmcm9tICR7dGhpcy5ibG9ja0hlaWdodH0gdG8gJHt0YXJnZXRCbG9ja0hlaWdodH1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWluZUVtcHR5QmxvY2soY291bnQpO1xuICB9XG5cbiAgY2FsbFJlYWRPbmx5Rm4oXG4gICAgY29udHJhY3Q6IHN0cmluZyxcbiAgICBtZXRob2Q6IHN0cmluZyxcbiAgICBhcmdzOiBBcnJheTxhbnk+LFxuICAgIHNlbmRlcjogc3RyaW5nLFxuICApOiBSZWFkT25seUZuIHtcbiAgICBsZXQgcmVzdWx0ID0gSlNPTi5wYXJzZShcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIERlbm8uY29yZS5vcFN5bmMoXCJhcGkvdjEvY2FsbF9yZWFkX29ubHlfZm5cIiwge1xuICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICBjb250cmFjdDogY29udHJhY3QsXG4gICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICBhcmdzOiBhcmdzLFxuICAgICAgICBzZW5kZXI6IHNlbmRlcixcbiAgICAgIH0pLFxuICAgICk7XG4gICAgbGV0IHJlYWRPbmx5Rm46IFJlYWRPbmx5Rm4gPSB7XG4gICAgICBzZXNzaW9uX2lkOiByZXN1bHQuc2Vzc2lvbl9pZCxcbiAgICAgIHJlc3VsdDogcmVzdWx0LnJlc3VsdCxcbiAgICAgIGV2ZW50czogcmVzdWx0LmV2ZW50cyxcbiAgICB9O1xuICAgIHJldHVybiByZWFkT25seUZuO1xuICB9XG5cbiAgZ2V0QXNzZXRzTWFwcygpOiBBc3NldHNNYXBzIHtcbiAgICBsZXQgcmVzdWx0ID0gSlNPTi5wYXJzZShcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIERlbm8uY29yZS5vcFN5bmMoXCJhcGkvdjEvZ2V0X2Fzc2V0c19tYXBzXCIsIHtcbiAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgbGV0IGFzc2V0c01hcHM6IEFzc2V0c01hcHMgPSB7XG4gICAgICBzZXNzaW9uX2lkOiByZXN1bHQuc2Vzc2lvbl9pZCxcbiAgICAgIGFzc2V0czogcmVzdWx0LmFzc2V0cyxcbiAgICB9O1xuICAgIHJldHVybiBhc3NldHNNYXBzO1xuICB9XG59XG5cbnR5cGUgUHJlRGVwbG95bWVudEZ1bmN0aW9uID0gKFxuICBjaGFpbjogQ2hhaW4sXG4gIGFjY291bnRzOiBNYXA8c3RyaW5nLCBBY2NvdW50PixcbikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG5cbnR5cGUgVGVzdEZ1bmN0aW9uID0gKFxuICBjaGFpbjogQ2hhaW4sXG4gIGFjY291bnRzOiBNYXA8c3RyaW5nLCBBY2NvdW50PixcbiAgY29udHJhY3RzOiBNYXA8c3RyaW5nLCBDb250cmFjdD4sXG4pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xudHlwZSBQcmVTZXR1cEZ1bmN0aW9uID0gKCkgPT4gQXJyYXk8VHg+O1xuXG5pbnRlcmZhY2UgVW5pdFRlc3RPcHRpb25zIHtcbiAgbmFtZTogc3RyaW5nO1xuICBvbmx5PzogdHJ1ZTtcbiAgaWdub3JlPzogdHJ1ZTtcbiAgZGVwbG95bWVudFBhdGg/OiBzdHJpbmc7XG4gIHByZURlcGxveW1lbnQ/OiBQcmVEZXBsb3ltZW50RnVuY3Rpb247XG4gIGZuOiBUZXN0RnVuY3Rpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udHJhY3Qge1xuICBjb250cmFjdF9pZDogc3RyaW5nO1xuICBzb3VyY2U6IHN0cmluZztcbiAgY29udHJhY3RfaW50ZXJmYWNlOiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tzTm9kZSB7XG4gIHVybDogc3RyaW5nO1xufVxuXG50eXBlIFNjcmlwdEZ1bmN0aW9uID0gKFxuICBhY2NvdW50czogTWFwPHN0cmluZywgQWNjb3VudD4sXG4gIGNvbnRyYWN0czogTWFwPHN0cmluZywgQ29udHJhY3Q+LFxuICBub2RlOiBTdGFja3NOb2RlLFxuKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcblxuaW50ZXJmYWNlIFNjcmlwdE9wdGlvbnMge1xuICBmbjogU2NyaXB0RnVuY3Rpb247XG59XG5cbmV4cG9ydCBjbGFzcyBDbGFyaW5ldCB7XG4gIHN0YXRpYyB0ZXN0KG9wdGlvbnM6IFVuaXRUZXN0T3B0aW9ucykge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBEZW5vLnRlc3Qoe1xuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgb25seTogb3B0aW9ucy5vbmx5LFxuICAgICAgaWdub3JlOiBvcHRpb25zLmlnbm9yZSxcbiAgICAgIGFzeW5jIGZuKCkge1xuICAgICAgICBsZXQgaGFzUHJlRGVwbG95bWVudFN0ZXBzID0gb3B0aW9ucy5wcmVEZXBsb3ltZW50ICE9PSB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IHJlc3VsdCA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIERlbm8uY29yZS5vcFN5bmMoXCJhcGkvdjEvbmV3X3Nlc3Npb25cIiwge1xuICAgICAgICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgbG9hZERlcGxveW1lbnQ6ICFoYXNQcmVEZXBsb3ltZW50U3RlcHMsXG4gICAgICAgICAgICBkZXBsb3ltZW50UGF0aDogb3B0aW9ucy5kZXBsb3ltZW50UGF0aCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5wcmVEZXBsb3ltZW50KSB7XG4gICAgICAgICAgbGV0IGNoYWluID0gbmV3IENoYWluKHJlc3VsdFtcInNlc3Npb25faWRcIl0pO1xuICAgICAgICAgIGxldCBhY2NvdW50czogTWFwPHN0cmluZywgQWNjb3VudD4gPSBuZXcgTWFwKCk7XG4gICAgICAgICAgZm9yIChsZXQgYWNjb3VudCBvZiByZXN1bHRbXCJhY2NvdW50c1wiXSkge1xuICAgICAgICAgICAgYWNjb3VudHMuc2V0KGFjY291bnQubmFtZSwgYWNjb3VudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IG9wdGlvbnMucHJlRGVwbG95bWVudChjaGFpbiwgYWNjb3VudHMpO1xuXG4gICAgICAgICAgcmVzdWx0ID0gSlNPTi5wYXJzZShcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIERlbm8uY29yZS5vcFN5bmMoXCJhcGkvdjEvbG9hZF9kZXBsb3ltZW50XCIsIHtcbiAgICAgICAgICAgICAgc2Vzc2lvbklkOiBjaGFpbi5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgIGRlcGxveW1lbnRQYXRoOiBvcHRpb25zLmRlcGxveW1lbnRQYXRoLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjaGFpbiA9IG5ldyBDaGFpbihyZXN1bHRbXCJzZXNzaW9uX2lkXCJdKTtcbiAgICAgICAgbGV0IGFjY291bnRzOiBNYXA8c3RyaW5nLCBBY2NvdW50PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChsZXQgYWNjb3VudCBvZiByZXN1bHRbXCJhY2NvdW50c1wiXSkge1xuICAgICAgICAgIGFjY291bnRzLnNldChhY2NvdW50Lm5hbWUsIGFjY291bnQpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjb250cmFjdHM6IE1hcDxzdHJpbmcsIENvbnRyYWN0PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChsZXQgY29udHJhY3Qgb2YgcmVzdWx0W1wiY29udHJhY3RzXCJdKSB7XG4gICAgICAgICAgY29udHJhY3RzLnNldChjb250cmFjdC5jb250cmFjdF9pZCwgY29udHJhY3QpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IG9wdGlvbnMuZm4oY2hhaW4sIGFjY291bnRzLCBjb250cmFjdHMpO1xuXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgSlNPTi5wYXJzZShEZW5vLmNvcmUub3BTeW5jKFwiYXBpL3YxL3Rlcm1pbmF0ZV9zZXNzaW9uXCIsIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6IGNoYWluLnNlc3Npb25JZCxcbiAgICAgICAgfSkpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBydW4ob3B0aW9uczogU2NyaXB0T3B0aW9ucykge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBEZW5vLnRlc3Qoe1xuICAgICAgbmFtZTogXCJydW5uaW5nIHNjcmlwdFwiLFxuICAgICAgYXN5bmMgZm4oKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBKU09OLnBhcnNlKFxuICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICBEZW5vLmNvcmUub3BTeW5jKFwiYXBpL3YxL25ld19zZXNzaW9uXCIsIHtcbiAgICAgICAgICAgIG5hbWU6IFwicnVubmluZyBzY3JpcHRcIixcbiAgICAgICAgICAgIGxvYWREZXBsb3ltZW50OiB0cnVlLFxuICAgICAgICAgICAgZGVwbG95bWVudFBhdGg6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgbGV0IGFjY291bnRzOiBNYXA8c3RyaW5nLCBBY2NvdW50PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChsZXQgYWNjb3VudCBvZiByZXN1bHRbXCJhY2NvdW50c1wiXSkge1xuICAgICAgICAgIGFjY291bnRzLnNldChhY2NvdW50Lm5hbWUsIGFjY291bnQpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjb250cmFjdHM6IE1hcDxzdHJpbmcsIENvbnRyYWN0PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChsZXQgY29udHJhY3Qgb2YgcmVzdWx0W1wiY29udHJhY3RzXCJdKSB7XG4gICAgICAgICAgY29udHJhY3RzLnNldChjb250cmFjdC5jb250cmFjdF9pZCwgY29udHJhY3QpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdGFja3Nfbm9kZTogU3RhY2tzTm9kZSA9IHtcbiAgICAgICAgICB1cmw6IHJlc3VsdFtcInN0YWNrc19ub2RlX3VybFwiXSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgb3B0aW9ucy5mbihhY2NvdW50cywgY29udHJhY3RzLCBzdGFja3Nfbm9kZSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgdHlwZXMge1xuICBjb25zdCBieXRlVG9IZXg6IGFueSA9IFtdO1xuICBmb3IgKGxldCBuID0gMDsgbiA8PSAweGZmOyArK24pIHtcbiAgICBjb25zdCBoZXhPY3RldCA9IG4udG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgICBieXRlVG9IZXgucHVzaChoZXhPY3RldCk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXJpYWxpemVUdXBsZShpbnB1dDogT2JqZWN0KSB7XG4gICAgbGV0IGl0ZW1zOiBBcnJheTxzdHJpbmc+ID0gW107XG4gICAgZm9yICh2YXIgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGlucHV0KSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBpdGVtcy5wdXNoKGAke2tleX06IHsgJHtzZXJpYWxpemVUdXBsZSh2YWx1ZSl9IH1gKTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgLy8gdG9kbyhsdWRvKTogbm90IHN1cHBvcnRlZCwgc2hvdWxkIHBhbmljXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtcy5wdXNoKGAke2tleX06ICR7dmFsdWV9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpdGVtcy5qb2luKFwiLCBcIik7XG4gIH1cblxuICBmdW5jdGlvbiBpc09iamVjdChvYmo6IGFueSkge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KG9iaik7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gb2sodmFsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYChvayAke3ZhbH0pYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBlcnIodmFsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYChlcnIgJHt2YWx9KWA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gc29tZSh2YWw6IHN0cmluZykge1xuICAgIHJldHVybiBgKHNvbWUgJHt2YWx9KWA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gbm9uZSgpIHtcbiAgICByZXR1cm4gYG5vbmVgO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGJvb2wodmFsOiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGAke3ZhbH1gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGludCh2YWw6IG51bWJlciB8IGJpZ2ludCkge1xuICAgIHJldHVybiBgJHt2YWx9YDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiB1aW50KHZhbDogbnVtYmVyIHwgYmlnaW50KSB7XG4gICAgcmV0dXJuIGB1JHt2YWx9YDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBhc2NpaSh2YWw6IHN0cmluZykge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWwpO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHV0ZjgodmFsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYHUke0pTT04uc3RyaW5naWZ5KHZhbCl9YDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBidWZmKHZhbDogQXJyYXlCdWZmZXIgfCBzdHJpbmcpIHtcbiAgICBjb25zdCBidWZmID0gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiXG4gICAgICA/IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh2YWwpXG4gICAgICA6IG5ldyBVaW50OEFycmF5KHZhbCk7XG5cbiAgICBjb25zdCBoZXhPY3RldHMgPSBuZXcgQXJyYXkoYnVmZi5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmLmxlbmd0aDsgKytpKSB7XG4gICAgICBoZXhPY3RldHNbaV0gPSBieXRlVG9IZXhbYnVmZltpXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGAweCR7aGV4T2N0ZXRzLmpvaW4oXCJcIil9YDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBsaXN0KHZhbDogQXJyYXk8YW55Pikge1xuICAgIHJldHVybiBgKGxpc3QgJHt2YWwuam9pbihcIiBcIil9KWA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gcHJpbmNpcGFsKHZhbDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAnJHt2YWx9YDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiB0dXBsZSh2YWw6IE9iamVjdCkge1xuICAgIHJldHVybiBgeyAke3NlcmlhbGl6ZVR1cGxlKHZhbCl9IH1gO1xuICB9XG59XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFN0cmluZyB7XG4gICAgZXhwZWN0T2soKTogU3RyaW5nO1xuICAgIGV4cGVjdEVycigpOiBTdHJpbmc7XG4gICAgZXhwZWN0U29tZSgpOiBTdHJpbmc7XG4gICAgZXhwZWN0Tm9uZSgpOiB2b2lkO1xuICAgIGV4cGVjdEJvb2wodmFsdWU6IGJvb2xlYW4pOiBib29sZWFuO1xuICAgIGV4cGVjdFVpbnQodmFsdWU6IG51bWJlciB8IGJpZ2ludCk6IGJpZ2ludDtcbiAgICBleHBlY3RJbnQodmFsdWU6IG51bWJlciB8IGJpZ2ludCk6IGJpZ2ludDtcbiAgICBleHBlY3RCdWZmKHZhbHVlOiBBcnJheUJ1ZmZlcik6IEFycmF5QnVmZmVyO1xuICAgIGV4cGVjdEFzY2lpKHZhbHVlOiBTdHJpbmcpOiBTdHJpbmc7XG4gICAgZXhwZWN0VXRmOCh2YWx1ZTogU3RyaW5nKTogU3RyaW5nO1xuICAgIGV4cGVjdFByaW5jaXBhbCh2YWx1ZTogU3RyaW5nKTogU3RyaW5nO1xuICAgIGV4cGVjdExpc3QoKTogQXJyYXk8U3RyaW5nPjtcbiAgICBleHBlY3RUdXBsZSgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9XG5cbiAgaW50ZXJmYWNlIEFycmF5PFQ+IHtcbiAgICBleHBlY3RTVFhUcmFuc2ZlckV2ZW50KFxuICAgICAgYW1vdW50OiBOdW1iZXIgfCBiaWdpbnQsXG4gICAgICBzZW5kZXI6IFN0cmluZyxcbiAgICAgIHJlY2lwaWVudDogU3RyaW5nLFxuICAgICk6IE9iamVjdDtcbiAgICBleHBlY3RGdW5naWJsZVRva2VuVHJhbnNmZXJFdmVudChcbiAgICAgIGFtb3VudDogTnVtYmVyIHwgYmlnaW50LFxuICAgICAgc2VuZGVyOiBTdHJpbmcsXG4gICAgICByZWNpcGllbnQ6IFN0cmluZyxcbiAgICAgIGFzc2V0SWQ6IFN0cmluZyxcbiAgICApOiBPYmplY3Q7XG4gICAgZXhwZWN0RnVuZ2libGVUb2tlbk1pbnRFdmVudChcbiAgICAgIGFtb3VudDogTnVtYmVyIHwgYmlnaW50LFxuICAgICAgcmVjaXBpZW50OiBTdHJpbmcsXG4gICAgICBhc3NldElkOiBTdHJpbmcsXG4gICAgKTogT2JqZWN0O1xuICAgIGV4cGVjdEZ1bmdpYmxlVG9rZW5CdXJuRXZlbnQoXG4gICAgICBhbW91bnQ6IE51bWJlciB8IGJpZ2ludCxcbiAgICAgIHNlbmRlcjogU3RyaW5nLFxuICAgICAgYXNzZXRJZDogU3RyaW5nLFxuICAgICk6IE9iamVjdDtcbiAgICBleHBlY3RQcmludEV2ZW50KFxuICAgICAgY29udHJhY3RfaWRlbnRpZmllcjogc3RyaW5nLFxuICAgICAgdmFsdWU6IHN0cmluZyxcbiAgICApOiBPYmplY3Q7XG4gICAgZXhwZWN0Tm9uRnVuZ2libGVUb2tlblRyYW5zZmVyRXZlbnQoXG4gICAgICB0b2tlbklkOiBTdHJpbmcsXG4gICAgICBzZW5kZXI6IFN0cmluZyxcbiAgICAgIHJlY2lwaWVudDogU3RyaW5nLFxuICAgICAgYXNzZXRBZGRyZXNzOiBTdHJpbmcsXG4gICAgICBhc3NldElkOiBTdHJpbmcsXG4gICAgKTogT2JqZWN0O1xuICAgIGV4cGVjdE5vbkZ1bmdpYmxlVG9rZW5NaW50RXZlbnQoXG4gICAgICB0b2tlbklkOiBTdHJpbmcsXG4gICAgICByZWNpcGllbnQ6IFN0cmluZyxcbiAgICAgIGFzc2V0QWRkcmVzczogU3RyaW5nLFxuICAgICAgYXNzZXRJZDogU3RyaW5nLFxuICAgICk6IE9iamVjdDtcbiAgICBleHBlY3ROb25GdW5naWJsZVRva2VuQnVybkV2ZW50KFxuICAgICAgdG9rZW5JZDogU3RyaW5nLFxuICAgICAgc2VuZGVyOiBTdHJpbmcsXG4gICAgICBhc3NldEFkZHJlc3M6IFN0cmluZyxcbiAgICAgIGFzc2V0SWQ6IFN0cmluZyxcbiAgICApOiBPYmplY3Q7XG4gICAgLy8gZXhwZWN0RXZlbnQoc2VsOiAoZTogT2JqZWN0KSA9PiBPYmplY3QpOiBPYmplY3Q7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3VtZShzcmM6IFN0cmluZywgZXhwZWN0YXRpb246IFN0cmluZywgd3JhcHBlZDogYm9vbGVhbikge1xuICBsZXQgZHN0ID0gKFwiIFwiICsgc3JjKS5zbGljZSgxKTtcbiAgbGV0IHNpemUgPSBleHBlY3RhdGlvbi5sZW5ndGg7XG4gIGlmICghd3JhcHBlZCAmJiBzcmMgIT09IGV4cGVjdGF0aW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEV4cGVjdGVkICR7Z3JlZW4oZXhwZWN0YXRpb24udG9TdHJpbmcoKSl9LCBnb3QgJHtyZWQoc3JjLnRvU3RyaW5nKCkpfWAsXG4gICAgKTtcbiAgfVxuICBpZiAod3JhcHBlZCkge1xuICAgIHNpemUgKz0gMjtcbiAgfVxuICBpZiAoZHN0Lmxlbmd0aCA8IHNpemUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXhwZWN0ZWQgJHtncmVlbihleHBlY3RhdGlvbi50b1N0cmluZygpKX0sIGdvdCAke3JlZChzcmMudG9TdHJpbmcoKSl9YCxcbiAgICApO1xuICB9XG4gIGlmICh3cmFwcGVkKSB7XG4gICAgZHN0ID0gZHN0LnN1YnN0cmluZygxLCBkc3QubGVuZ3RoIC0gMSk7XG4gIH1cbiAgbGV0IHJlcyA9IGRzdC5zbGljZSgwLCBleHBlY3RhdGlvbi5sZW5ndGgpO1xuICBpZiAocmVzICE9PSBleHBlY3RhdGlvbikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBFeHBlY3RlZCAke2dyZWVuKGV4cGVjdGF0aW9uLnRvU3RyaW5nKCkpfSwgZ290ICR7cmVkKHNyYy50b1N0cmluZygpKX1gLFxuICAgICk7XG4gIH1cbiAgbGV0IGxlZnRQYWQgPSAwO1xuICBpZiAoZHN0LmNoYXJBdChleHBlY3RhdGlvbi5sZW5ndGgpID09PSBcIiBcIikge1xuICAgIGxlZnRQYWQgPSAxO1xuICB9XG4gIGxldCByZW1haW5kZXIgPSBkc3Quc3Vic3RyaW5nKGV4cGVjdGF0aW9uLmxlbmd0aCArIGxlZnRQYWQpO1xuICByZXR1cm4gcmVtYWluZGVyO1xufVxuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdE9rID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gY29uc3VtZSh0aGlzLCBcIm9rXCIsIHRydWUpO1xufTtcblxuU3RyaW5nLnByb3RvdHlwZS5leHBlY3RFcnIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBjb25zdW1lKHRoaXMsIFwiZXJyXCIsIHRydWUpO1xufTtcblxuU3RyaW5nLnByb3RvdHlwZS5leHBlY3RTb21lID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gY29uc3VtZSh0aGlzLCBcInNvbWVcIiwgdHJ1ZSk7XG59O1xuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdE5vbmUgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBjb25zdW1lKHRoaXMsIFwibm9uZVwiLCBmYWxzZSk7XG59O1xuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdEJvb2wgPSBmdW5jdGlvbiAodmFsdWU6IGJvb2xlYW4pIHtcbiAgdHJ5IHtcbiAgICBjb25zdW1lKHRoaXMsIGAke3ZhbHVlfWAsIGZhbHNlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdFVpbnQgPSBmdW5jdGlvbiAodmFsdWU6IG51bWJlciB8IGJpZ2ludCk6IGJpZ2ludCB7XG4gIHRyeSB7XG4gICAgY29uc3VtZSh0aGlzLCBgdSR7dmFsdWV9YCwgZmFsc2UpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IGVycm9yO1xuICB9XG4gIHJldHVybiBCaWdJbnQodmFsdWUpO1xufTtcblxuU3RyaW5nLnByb3RvdHlwZS5leHBlY3RJbnQgPSBmdW5jdGlvbiAodmFsdWU6IG51bWJlciB8IGJpZ2ludCk6IGJpZ2ludCB7XG4gIHRyeSB7XG4gICAgY29uc3VtZSh0aGlzLCBgJHt2YWx1ZX1gLCBmYWxzZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIEJpZ0ludCh2YWx1ZSk7XG59O1xuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdEJ1ZmYgPSBmdW5jdGlvbiAodmFsdWU6IEFycmF5QnVmZmVyKSB7XG4gIGxldCBidWZmZXIgPSB0eXBlcy5idWZmKHZhbHVlKTtcbiAgaWYgKHRoaXMgIT09IGJ1ZmZlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtncmVlbihidWZmZXIpfSwgZ290ICR7cmVkKHRoaXMudG9TdHJpbmcoKSl9YCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuU3RyaW5nLnByb3RvdHlwZS5leHBlY3RBc2NpaSA9IGZ1bmN0aW9uICh2YWx1ZTogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3VtZSh0aGlzLCBgXCIke3ZhbHVlfVwiYCwgZmFsc2UpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IGVycm9yO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cblN0cmluZy5wcm90b3R5cGUuZXhwZWN0VXRmOCA9IGZ1bmN0aW9uICh2YWx1ZTogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3VtZSh0aGlzLCBgdVwiJHt2YWx1ZX1cImAsIGZhbHNlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5TdHJpbmcucHJvdG90eXBlLmV4cGVjdFByaW5jaXBhbCA9IGZ1bmN0aW9uICh2YWx1ZTogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3VtZSh0aGlzLCBgJHt2YWx1ZX1gLCBmYWxzZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuU3RyaW5nLnByb3RvdHlwZS5leHBlY3RMaXN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jaGFyQXQoMCkgIT09IFwiW1wiIHx8IHRoaXMuY2hhckF0KHRoaXMubGVuZ3RoIC0gMSkgIT09IFwiXVwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEV4cGVjdGVkICR7Z3JlZW4oXCIobGlzdCAuLi4pXCIpfSwgZ290ICR7cmVkKHRoaXMudG9TdHJpbmcoKSl9YCxcbiAgICApO1xuICB9XG5cbiAgbGV0IHN0YWNrID0gW107XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBsZXQgc3RhcnQgPSAxO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGhpcy5jaGFyQXQoaSkgPT09IFwiLFwiICYmIHN0YWNrLmxlbmd0aCA9PSAxKSB7XG4gICAgICBlbGVtZW50cy5wdXNoKHRoaXMuc3Vic3RyaW5nKHN0YXJ0LCBpKSk7XG4gICAgICBzdGFydCA9IGkgKyAyO1xuICAgIH1cbiAgICBpZiAoW1wiKFwiLCBcIltcIiwgXCJ7XCJdLmluY2x1ZGVzKHRoaXMuY2hhckF0KGkpKSkge1xuICAgICAgc3RhY2sucHVzaCh0aGlzLmNoYXJBdChpKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNoYXJBdChpKSA9PT0gXCIpXCIgJiYgc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0gPT09IFwiKFwiKSB7XG4gICAgICBzdGFjay5wb3AoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2hhckF0KGkpID09PSBcIn1cIiAmJiBzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gXCJ7XCIpIHtcbiAgICAgIHN0YWNrLnBvcCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jaGFyQXQoaSkgPT09IFwiXVwiICYmIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdID09PSBcIltcIikge1xuICAgICAgc3RhY2sucG9wKCk7XG4gICAgfVxuICB9XG4gIGxldCByZW1haW5kZXIgPSB0aGlzLnN1YnN0cmluZyhzdGFydCwgdGhpcy5sZW5ndGggLSAxKTtcbiAgaWYgKHJlbWFpbmRlci5sZW5ndGggPiAwKSB7XG4gICAgZWxlbWVudHMucHVzaChyZW1haW5kZXIpO1xuICB9XG4gIHJldHVybiBlbGVtZW50cztcbn07XG5cblN0cmluZy5wcm90b3R5cGUuZXhwZWN0VHVwbGUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNoYXJBdCgwKSAhPT0gXCJ7XCIgfHwgdGhpcy5jaGFyQXQodGhpcy5sZW5ndGggLSAxKSAhPT0gXCJ9XCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXhwZWN0ZWQgJHtncmVlbihcIih0dXBsZSAuLi4pXCIpfSwgZ290ICR7cmVkKHRoaXMudG9TdHJpbmcoKSl9YCxcbiAgICApO1xuICB9XG5cbiAgbGV0IHN0YXJ0ID0gMTtcbiAgbGV0IHN0YWNrID0gW107XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGhpcy5jaGFyQXQoaSkgPT09IFwiLFwiICYmIHN0YWNrLmxlbmd0aCA9PSAxKSB7XG4gICAgICBlbGVtZW50cy5wdXNoKHRoaXMuc3Vic3RyaW5nKHN0YXJ0LCBpKSk7XG4gICAgICBzdGFydCA9IGkgKyAyO1xuICAgIH1cbiAgICBpZiAoW1wiKFwiLCBcIltcIiwgXCJ7XCJdLmluY2x1ZGVzKHRoaXMuY2hhckF0KGkpKSkge1xuICAgICAgc3RhY2sucHVzaCh0aGlzLmNoYXJBdChpKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNoYXJBdChpKSA9PT0gXCIpXCIgJiYgc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0gPT09IFwiKFwiKSB7XG4gICAgICBzdGFjay5wb3AoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2hhckF0KGkpID09PSBcIn1cIiAmJiBzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gXCJ7XCIpIHtcbiAgICAgIHN0YWNrLnBvcCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jaGFyQXQoaSkgPT09IFwiXVwiICYmIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdID09PSBcIltcIikge1xuICAgICAgc3RhY2sucG9wKCk7XG4gICAgfVxuICB9XG4gIGxldCByZW1haW5kZXIgPSB0aGlzLnN1YnN0cmluZyhzdGFydCwgdGhpcy5sZW5ndGggLSAxKTtcbiAgaWYgKHJlbWFpbmRlci5sZW5ndGggPiAwKSB7XG4gICAgZWxlbWVudHMucHVzaChyZW1haW5kZXIpO1xuICB9XG5cbiAgbGV0IHR1cGxlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAobGV0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlbGVtZW50LmNoYXJBdChpKSA9PT0gXCI6XCIpIHtcbiAgICAgICAgbGV0IGtleTogc3RyaW5nID0gZWxlbWVudC5zdWJzdHJpbmcoMCwgaSk7XG4gICAgICAgIGxldCB2YWx1ZTogc3RyaW5nID0gZWxlbWVudC5zdWJzdHJpbmcoaSArIDIsIGVsZW1lbnQubGVuZ3RoKTtcbiAgICAgICAgdHVwbGVba2V5XSA9IHZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHVwbGU7XG59O1xuXG5BcnJheS5wcm90b3R5cGUuZXhwZWN0U1RYVHJhbnNmZXJFdmVudCA9IGZ1bmN0aW9uIChcbiAgYW1vdW50OiBOdW1iZXIgfCBiaWdpbnQsXG4gIHNlbmRlcjogU3RyaW5nLFxuICByZWNpcGllbnQ6IFN0cmluZyxcbikge1xuICBmb3IgKGxldCBldmVudCBvZiB0aGlzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBlOiBhbnkgPSB7fTtcbiAgICAgIGVbXCJhbW91bnRcIl0gPSBldmVudC5zdHhfdHJhbnNmZXJfZXZlbnQuYW1vdW50LmV4cGVjdEludChhbW91bnQpO1xuICAgICAgZVtcInNlbmRlclwiXSA9IGV2ZW50LnN0eF90cmFuc2Zlcl9ldmVudC5zZW5kZXIuZXhwZWN0UHJpbmNpcGFsKHNlbmRlcik7XG4gICAgICBlW1wicmVjaXBpZW50XCJdID0gZXZlbnQuc3R4X3RyYW5zZmVyX2V2ZW50LnJlY2lwaWVudC5leHBlY3RQcmluY2lwYWwoXG4gICAgICAgIHJlY2lwaWVudCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJldHJpZXZlIGV4cGVjdGVkIFNUWFRyYW5zZmVyRXZlbnRgKTtcbn07XG5cbkFycmF5LnByb3RvdHlwZS5leHBlY3RGdW5naWJsZVRva2VuVHJhbnNmZXJFdmVudCA9IGZ1bmN0aW9uIChcbiAgYW1vdW50OiBOdW1iZXIsXG4gIHNlbmRlcjogU3RyaW5nLFxuICByZWNpcGllbnQ6IFN0cmluZyxcbiAgYXNzZXRJZDogU3RyaW5nLFxuKSB7XG4gIGZvciAobGV0IGV2ZW50IG9mIHRoaXMpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGU6IGFueSA9IHt9O1xuICAgICAgZVtcImFtb3VudFwiXSA9IGV2ZW50LmZ0X3RyYW5zZmVyX2V2ZW50LmFtb3VudC5leHBlY3RJbnQoYW1vdW50KTtcbiAgICAgIGVbXCJzZW5kZXJcIl0gPSBldmVudC5mdF90cmFuc2Zlcl9ldmVudC5zZW5kZXIuZXhwZWN0UHJpbmNpcGFsKHNlbmRlcik7XG4gICAgICBlW1wicmVjaXBpZW50XCJdID0gZXZlbnQuZnRfdHJhbnNmZXJfZXZlbnQucmVjaXBpZW50LmV4cGVjdFByaW5jaXBhbChcbiAgICAgICAgcmVjaXBpZW50LFxuICAgICAgKTtcbiAgICAgIGlmIChldmVudC5mdF90cmFuc2Zlcl9ldmVudC5hc3NldF9pZGVudGlmaWVyLmVuZHNXaXRoKGFzc2V0SWQpKSB7XG4gICAgICAgIGVbXCJhc3NldElkXCJdID0gZXZlbnQuZnRfdHJhbnNmZXJfZXZlbnQuYXNzZXRfaWRlbnRpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYFVuYWJsZSB0byByZXRyaWV2ZSBleHBlY3RlZCBGdW5naWJsZVRva2VuVHJhbnNmZXJFdmVudCgke2Ftb3VudH0sICR7c2VuZGVyfSwgJHtyZWNpcGllbnR9LCAke2Fzc2V0SWR9KVxcbiR7XG4gICAgICBKU09OLnN0cmluZ2lmeSh0aGlzKVxuICAgIH1gLFxuICApO1xufTtcblxuQXJyYXkucHJvdG90eXBlLmV4cGVjdEZ1bmdpYmxlVG9rZW5NaW50RXZlbnQgPSBmdW5jdGlvbiAoXG4gIGFtb3VudDogTnVtYmVyIHwgYmlnaW50LFxuICByZWNpcGllbnQ6IFN0cmluZyxcbiAgYXNzZXRJZDogU3RyaW5nLFxuKSB7XG4gIGZvciAobGV0IGV2ZW50IG9mIHRoaXMpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGU6IGFueSA9IHt9O1xuICAgICAgZVtcImFtb3VudFwiXSA9IGV2ZW50LmZ0X21pbnRfZXZlbnQuYW1vdW50LmV4cGVjdEludChhbW91bnQpO1xuICAgICAgZVtcInJlY2lwaWVudFwiXSA9IGV2ZW50LmZ0X21pbnRfZXZlbnQucmVjaXBpZW50LmV4cGVjdFByaW5jaXBhbChyZWNpcGllbnQpO1xuICAgICAgaWYgKGV2ZW50LmZ0X21pbnRfZXZlbnQuYXNzZXRfaWRlbnRpZmllci5lbmRzV2l0aChhc3NldElkKSkge1xuICAgICAgICBlW1wiYXNzZXRJZFwiXSA9IGV2ZW50LmZ0X21pbnRfZXZlbnQuYXNzZXRfaWRlbnRpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZXRyaWV2ZSBleHBlY3RlZCBGdW5naWJsZVRva2VuTWludEV2ZW50YCk7XG59O1xuXG5BcnJheS5wcm90b3R5cGUuZXhwZWN0RnVuZ2libGVUb2tlbkJ1cm5FdmVudCA9IGZ1bmN0aW9uIChcbiAgYW1vdW50OiBOdW1iZXIgfCBiaWdpbnQsXG4gIHNlbmRlcjogU3RyaW5nLFxuICBhc3NldElkOiBTdHJpbmcsXG4pIHtcbiAgZm9yIChsZXQgZXZlbnQgb2YgdGhpcykge1xuICAgIHRyeSB7XG4gICAgICBsZXQgZTogYW55ID0ge307XG4gICAgICBlW1wiYW1vdW50XCJdID0gZXZlbnQuZnRfYnVybl9ldmVudC5hbW91bnQuZXhwZWN0SW50KGFtb3VudCk7XG4gICAgICBlW1wic2VuZGVyXCJdID0gZXZlbnQuZnRfYnVybl9ldmVudC5zZW5kZXIuZXhwZWN0UHJpbmNpcGFsKHNlbmRlcik7XG4gICAgICBpZiAoZXZlbnQuZnRfYnVybl9ldmVudC5hc3NldF9pZGVudGlmaWVyLmVuZHNXaXRoKGFzc2V0SWQpKSB7XG4gICAgICAgIGVbXCJhc3NldElkXCJdID0gZXZlbnQuZnRfYnVybl9ldmVudC5hc3NldF9pZGVudGlmaWVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJldHJpZXZlIGV4cGVjdGVkIEZ1bmdpYmxlVG9rZW5CdXJuRXZlbnRgKTtcbn07XG5cbkFycmF5LnByb3RvdHlwZS5leHBlY3RQcmludEV2ZW50ID0gZnVuY3Rpb24gKFxuICBjb250cmFjdF9pZGVudGlmaWVyOiBzdHJpbmcsXG4gIHZhbHVlOiBzdHJpbmcsXG4pIHtcbiAgZm9yIChsZXQgZXZlbnQgb2YgdGhpcykge1xuICAgIHRyeSB7XG4gICAgICBsZXQgZTogYW55ID0ge307XG4gICAgICBlW1wiY29udHJhY3RfaWRlbnRpZmllclwiXSA9IGV2ZW50LmNvbnRyYWN0X2V2ZW50LmNvbnRyYWN0X2lkZW50aWZpZXJcbiAgICAgICAgLmV4cGVjdFByaW5jaXBhbChcbiAgICAgICAgICBjb250cmFjdF9pZGVudGlmaWVyLFxuICAgICAgICApO1xuXG4gICAgICBpZiAoZXZlbnQuY29udHJhY3RfZXZlbnQudG9waWMuZW5kc1dpdGgoXCJwcmludFwiKSkge1xuICAgICAgICBlW1widG9waWNcIl0gPSBldmVudC5jb250cmFjdF9ldmVudC50b3BpYztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQuY29udHJhY3RfZXZlbnQudmFsdWUuZW5kc1dpdGgodmFsdWUpKSB7XG4gICAgICAgIGVbXCJ2YWx1ZVwiXSA9IGV2ZW50LmNvbnRyYWN0X2V2ZW50LnZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJldHJpZXZlIGV4cGVjdGVkIFByaW50RXZlbnRgKTtcbn07XG4vLyBBcnJheS5wcm90b3R5cGUuZXhwZWN0RXZlbnQgPSBmdW5jdGlvbihzZWw6IChlOiBPYmplY3QpID0+IE9iamVjdCkge1xuLy8gICAgIGZvciAobGV0IGV2ZW50IG9mIHRoaXMpIHtcbi8vICAgICAgICAgdHJ5IHtcbi8vICAgICAgICAgICAgIHNlbChldmVudCk7XG4vLyAgICAgICAgICAgICByZXR1cm4gZXZlbnQgYXMgT2JqZWN0O1xuLy8gICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuLy8gICAgICAgICAgICAgY29udGludWU7XG4vLyAgICAgICAgIH1cbi8vICAgICB9XG4vLyAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmV0cmlldmUgZXhwZWN0ZWQgUHJpbnRFdmVudGApO1xuLy8gfVxuQXJyYXkucHJvdG90eXBlLmV4cGVjdE5vbkZ1bmdpYmxlVG9rZW5UcmFuc2ZlckV2ZW50ID0gZnVuY3Rpb24gKFxuICB0b2tlbklkOiBTdHJpbmcsXG4gIHNlbmRlcjogU3RyaW5nLFxuICByZWNpcGllbnQ6IFN0cmluZyxcbiAgYXNzZXRBZGRyZXNzOiBTdHJpbmcsXG4gIGFzc2V0SWQ6IFN0cmluZyxcbikge1xuICBmb3IgKGxldCBldmVudCBvZiB0aGlzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBlOiBhbnkgPSB7fTtcbiAgICAgIGlmIChldmVudC5uZnRfdHJhbnNmZXJfZXZlbnQudmFsdWUgPT09IHRva2VuSWQpIHtcbiAgICAgICAgZVtcInRva2VuSWRcIl0gPSBldmVudC5uZnRfdHJhbnNmZXJfZXZlbnQudmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGVbXCJzZW5kZXJcIl0gPSBldmVudC5uZnRfdHJhbnNmZXJfZXZlbnQuc2VuZGVyLmV4cGVjdFByaW5jaXBhbChzZW5kZXIpO1xuICAgICAgZVtcInJlY2lwaWVudFwiXSA9IGV2ZW50Lm5mdF90cmFuc2Zlcl9ldmVudC5yZWNpcGllbnQuZXhwZWN0UHJpbmNpcGFsKFxuICAgICAgICByZWNpcGllbnQsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBldmVudC5uZnRfdHJhbnNmZXJfZXZlbnQuYXNzZXRfaWRlbnRpZmllciA9PT1cbiAgICAgICAgICBgJHthc3NldEFkZHJlc3N9Ojoke2Fzc2V0SWR9YFxuICAgICAgKSB7XG4gICAgICAgIGVbXCJhc3NldElkXCJdID0gZXZlbnQubmZ0X3RyYW5zZmVyX2V2ZW50LmFzc2V0X2lkZW50aWZpZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmV0cmlldmUgZXhwZWN0ZWQgTm9uRnVuZ2libGVUb2tlblRyYW5zZmVyRXZlbnRgKTtcbn07XG5cbkFycmF5LnByb3RvdHlwZS5leHBlY3ROb25GdW5naWJsZVRva2VuTWludEV2ZW50ID0gZnVuY3Rpb24gKFxuICB0b2tlbklkOiBTdHJpbmcsXG4gIHJlY2lwaWVudDogU3RyaW5nLFxuICBhc3NldEFkZHJlc3M6IFN0cmluZyxcbiAgYXNzZXRJZDogU3RyaW5nLFxuKSB7XG4gIGZvciAobGV0IGV2ZW50IG9mIHRoaXMpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGU6IGFueSA9IHt9O1xuICAgICAgaWYgKGV2ZW50Lm5mdF9taW50X2V2ZW50LnZhbHVlID09PSB0b2tlbklkKSB7XG4gICAgICAgIGVbXCJ0b2tlbklkXCJdID0gZXZlbnQubmZ0X21pbnRfZXZlbnQudmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGVbXCJyZWNpcGllbnRcIl0gPSBldmVudC5uZnRfbWludF9ldmVudC5yZWNpcGllbnQuZXhwZWN0UHJpbmNpcGFsKFxuICAgICAgICByZWNpcGllbnQsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBldmVudC5uZnRfbWludF9ldmVudC5hc3NldF9pZGVudGlmaWVyID09PSBgJHthc3NldEFkZHJlc3N9Ojoke2Fzc2V0SWR9YFxuICAgICAgKSB7XG4gICAgICAgIGVbXCJhc3NldElkXCJdID0gZXZlbnQubmZ0X21pbnRfZXZlbnQuYXNzZXRfaWRlbnRpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZXRyaWV2ZSBleHBlY3RlZCBOb25GdW5naWJsZVRva2VuTWludEV2ZW50YCk7XG59O1xuXG5BcnJheS5wcm90b3R5cGUuZXhwZWN0Tm9uRnVuZ2libGVUb2tlbkJ1cm5FdmVudCA9IGZ1bmN0aW9uIChcbiAgdG9rZW5JZDogU3RyaW5nLFxuICBzZW5kZXI6IFN0cmluZyxcbiAgYXNzZXRBZGRyZXNzOiBTdHJpbmcsXG4gIGFzc2V0SWQ6IFN0cmluZyxcbikge1xuICBmb3IgKGxldCBldmVudCBvZiB0aGlzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBlOiBhbnkgPSB7fTtcbiAgICAgIGlmIChldmVudC5uZnRfYnVybl9ldmVudC52YWx1ZSA9PT0gdG9rZW5JZCkge1xuICAgICAgICBlW1widG9rZW5JZFwiXSA9IGV2ZW50Lm5mdF9idXJuX2V2ZW50LnZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBlW1wic2VuZGVyXCJdID0gZXZlbnQubmZ0X2J1cm5fZXZlbnQuc2VuZGVyLmV4cGVjdFByaW5jaXBhbChzZW5kZXIpO1xuICAgICAgaWYgKFxuICAgICAgICBldmVudC5uZnRfYnVybl9ldmVudC5hc3NldF9pZGVudGlmaWVyID09PSBgJHthc3NldEFkZHJlc3N9Ojoke2Fzc2V0SWR9YFxuICAgICAgKSB7XG4gICAgICAgIGVbXCJhc3NldElkXCJdID0gZXZlbnQubmZ0X2J1cm5fZXZlbnQuYXNzZXRfaWRlbnRpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZXRyaWV2ZSBleHBlY3RlZCBOb25GdW5naWJsZVRva2VuQnVybkV2ZW50YCk7XG59O1xuXG5jb25zdCBub0NvbG9yID0gZ2xvYmFsVGhpcy5EZW5vPy5ub0NvbG9yID8/IHRydWU7XG5cbmludGVyZmFjZSBDb2RlIHtcbiAgb3Blbjogc3RyaW5nO1xuICBjbG9zZTogc3RyaW5nO1xuICByZWdleHA6IFJlZ0V4cDtcbn1cblxubGV0IGVuYWJsZWQgPSAhbm9Db2xvcjtcblxuZnVuY3Rpb24gY29kZShvcGVuOiBudW1iZXJbXSwgY2xvc2U6IG51bWJlcik6IENvZGUge1xuICByZXR1cm4ge1xuICAgIG9wZW46IGBcXHgxYlske29wZW4uam9pbihcIjtcIil9bWAsXG4gICAgY2xvc2U6IGBcXHgxYlske2Nsb3NlfW1gLFxuICAgIHJlZ2V4cDogbmV3IFJlZ0V4cChgXFxcXHgxYlxcXFxbJHtjbG9zZX1tYCwgXCJnXCIpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBydW4oc3RyOiBzdHJpbmcsIGNvZGU6IENvZGUpOiBzdHJpbmcge1xuICByZXR1cm4gZW5hYmxlZFxuICAgID8gYCR7Y29kZS5vcGVufSR7c3RyLnJlcGxhY2UoY29kZS5yZWdleHAsIGNvZGUub3Blbil9JHtjb2RlLmNsb3NlfWBcbiAgICA6IHN0cjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFszMV0sIDM5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBncmVlbihzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFszMl0sIDM5KSk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLEVBQUU7SUFDYixJQUFJLENBQVM7SUFDYixNQUFNLENBQVM7SUFDZixZQUFZLENBQWtCO0lBQzlCLFdBQVcsQ0FBYztJQUN6QixjQUFjLENBQW9CO0lBRWxDLFlBQVksSUFBWSxFQUFFLE1BQWMsQ0FBRTtRQUN4QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztLQUN0QjtJQUVELE9BQU8sV0FBVyxDQUFDLE1BQWMsRUFBRSxTQUFpQixFQUFFLE1BQWMsRUFBRTtRQUNwRSxJQUFJLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLEFBQUM7UUFDM0IsRUFBRSxDQUFDLFdBQVcsR0FBRztZQUNmLFNBQVM7WUFDVCxNQUFNO1NBQ1AsQ0FBQztRQUNGLE9BQU8sRUFBRSxDQUFDO0tBQ1g7SUFFRCxPQUFPLFlBQVksQ0FDakIsUUFBZ0IsRUFDaEIsTUFBYyxFQUNkLElBQW1CLEVBQ25CLE1BQWMsRUFDZDtRQUNBLElBQUksRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQUFBQztRQUMzQixFQUFFLENBQUMsWUFBWSxHQUFHO1lB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QyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFFO1FBQ3BDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7WUFDL0MsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLEtBQUssR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2Y7UUFDRCxJQUFJO1lBQUMsR0FBRztZQUFFLEdBQUc7WUFBRSxHQUFHO1NBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQzVDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzVCO1FBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7WUFDN0QsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ2I7UUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtZQUM3RCxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDYjtRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO1lBQzdELEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNiO0tBQ0Y7SUFDRCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMs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 \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.meta" "b/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.meta" deleted file mode 100644 index 7975923..0000000 --- "a/.\\.cache/gen/https/deno.land/7c02e05b5297e003cb3d3ca5a0297c761a2f3a683dbb03ff3a1380681fcb8d54.meta" +++ /dev/null @@ -1 +0,0 @@ -{"source_hash":"1067396034229057420","emit_hash":"13598205218251017875"} \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.js" "b/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.js" deleted file mode 100644 index 602d9c8..0000000 --- "a/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.js" +++ /dev/null @@ -1,178 +0,0 @@ -export var DiffType; -(function(DiffType) { - DiffType["removed"] = "removed"; - DiffType["common"] = "common"; - DiffType["added"] = "added"; -})(DiffType || (DiffType = {})); -const REMOVED = 1; -const COMMON = 2; -const ADDED = 3; -function createCommon(A, B, reverse) { - const common = []; - if (A.length === 0 || B.length === 0) return []; - for(let i = 0; i < Math.min(A.length, B.length); i += 1){ - if (A[reverse ? A.length - i - 1 : i] === B[reverse ? B.length - i - 1 : i]) { - common.push(A[reverse ? A.length - i - 1 : i]); - } else { - return common; - } - } - return common; -} -/** - * Renders the differences between the actual and expected values - * @param A Actual value - * @param B Expected value - */ export function diff(A, B) { - const prefixCommon = createCommon(A, B); - const suffixCommon = createCommon(A.slice(prefixCommon.length), B.slice(prefixCommon.length), true).reverse(); - A = suffixCommon.length ? A.slice(prefixCommon.length, -suffixCommon.length) : A.slice(prefixCommon.length); - B = suffixCommon.length ? B.slice(prefixCommon.length, -suffixCommon.length) : B.slice(prefixCommon.length); - const swapped = B.length > A.length; - [A, B] = swapped ? [ - B, - A - ] : [ - A, - B - ]; - const M = A.length; - const N = B.length; - if (!M && !N && !suffixCommon.length && !prefixCommon.length) return []; - if (!N) { - return [ - ...prefixCommon.map((c)=>({ - type: DiffType.common, - value: c - })), - ...A.map((a)=>({ - type: swapped ? DiffType.added : DiffType.removed, - value: a - })), - ...suffixCommon.map((c)=>({ - type: DiffType.common, - value: c - })), - ]; - } - const offset = N; - const delta = M - N; - const size = M + N + 1; - const fp = new Array(size).fill({ - y: -1 - }); - /** - * INFO: - * This buffer is used to save memory and improve performance. - * The first half is used to save route and last half is used to save diff - * type. - * This is because, when I kept new uint8array area to save type,performance - * worsened. - */ const routes = new Uint32Array((M * N + size + 1) * 2); - const diffTypesPtrOffset = routes.length / 2; - let ptr = 0; - let p = -1; - function backTrace(A, B, current, swapped) { - const M = A.length; - const N = B.length; - const result = []; - let a = M - 1; - let b = N - 1; - let j = routes[current.id]; - let type = routes[current.id + diffTypesPtrOffset]; - while(true){ - if (!j && !type) break; - const prev = j; - if (type === REMOVED) { - result.unshift({ - type: swapped ? DiffType.removed : DiffType.added, - value: B[b] - }); - b -= 1; - } else if (type === ADDED) { - result.unshift({ - type: swapped ? DiffType.added : DiffType.removed, - value: A[a] - }); - a -= 1; - } else { - result.unshift({ - type: DiffType.common, - value: A[a] - }); - a -= 1; - b -= 1; - } - j = routes[prev]; - type = routes[prev + diffTypesPtrOffset]; - } - return result; - } - function createFP(slide, down, k, M) { - if (slide && slide.y === -1 && down && down.y === -1) { - return { - y: 0, - id: 0 - }; - } - if (down && down.y === -1 || k === M || (slide && slide.y) > (down && down.y) + 1) { - const prev = slide.id; - ptr++; - routes[ptr] = prev; - routes[ptr + diffTypesPtrOffset] = ADDED; - return { - y: slide.y, - id: ptr - }; - } else { - const prev1 = down.id; - ptr++; - routes[ptr] = prev1; - routes[ptr + diffTypesPtrOffset] = REMOVED; - return { - y: down.y + 1, - id: ptr - }; - } - } - function snake(k, slide, down, _offset, A, B) { - const M = A.length; - const N = B.length; - if (k < -N || M < k) return { - y: -1, - id: -1 - }; - const fp = createFP(slide, down, k, M); - while(fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]){ - const prev = fp.id; - ptr++; - fp.id = ptr; - fp.y += 1; - routes[ptr] = prev; - routes[ptr + diffTypesPtrOffset] = COMMON; - } - return fp; - } - while(fp[delta + offset].y < N){ - p = p + 1; - for(let k = -p; k < delta; ++k){ - fp[k + offset] = snake(k, fp[k - 1 + offset], fp[k + 1 + offset], offset, A, B); - } - for(let k1 = delta + p; k1 > delta; --k1){ - fp[k1 + offset] = snake(k1, fp[k1 - 1 + offset], fp[k1 + 1 + offset], offset, A, B); - } - fp[delta + offset] = snake(delta, fp[delta - 1 + offset], fp[delta + 1 + offset], offset, A, B); - } - return [ - ...prefixCommon.map((c)=>({ - type: DiffType.common, - value: c - })), - ...backTrace(A, B, fp[delta + offset], swapped), - ...suffixCommon.map((c)=>({ - type: DiffType.common, - value: c - })), - ]; -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjkwLjAvdGVzdGluZy9fZGlmZi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIxIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5pbnRlcmZhY2UgRmFydGhlc3RQb2ludCB7XG4gIHk6IG51bWJlcjtcbiAgaWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGVudW0gRGlmZlR5cGUge1xuICByZW1vdmVkID0gXCJyZW1vdmVkXCIsXG4gIGNvbW1vbiA9IFwiY29tbW9uXCIsXG4gIGFkZGVkID0gXCJhZGRlZFwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERpZmZSZXN1bHQ8VD4ge1xuICB0eXBlOiBEaWZmVHlwZTtcbiAgdmFsdWU6IFQ7XG59XG5cbmNvbnN0IFJFTU9WRUQgPSAxO1xuY29uc3QgQ09NTU9OID0gMjtcbmNvbnN0IEFEREVEID0gMztcblxuZnVuY3Rpb24gY3JlYXRlQ29tbW9uPFQ+KEE6IFRbXSwgQjogVFtdLCByZXZlcnNlPzogYm9vbGVhbik6IFRbXSB7XG4gIGNvbnN0IGNvbW1vbiA9IFtdO1xuICBpZiAoQS5sZW5ndGggPT09IDAgfHwgQi5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1pbihBLmxlbmd0aCwgQi5sZW5ndGgpOyBpICs9IDEpIHtcbiAgICBpZiAoXG4gICAgICBBW3JldmVyc2UgPyBBLmxlbmd0aCAtIGkgLSAxIDogaV0gPT09IEJbcmV2ZXJzZSA/IEIubGVuZ3RoIC0gaSAtIDEgOiBpXVxuICAgICkge1xuICAgICAgY29tbW9uLnB1c2goQVtyZXZlcnNlID8gQS5sZW5ndGggLSBpIC0gMSA6IGldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbW1vbjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbW1vbjtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlc1xuICogQHBhcmFtIEEgQWN0dWFsIHZhbHVlXG4gKiBAcGFyYW0gQiBFeHBlY3RlZCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlmZjxUPihBOiBUW10sIEI6IFRbXSk6IEFycmF5PERpZmZSZXN1bHQ8VD4+IHtcbiAgY29uc3QgcHJlZml4Q29tbW9uID0gY3JlYXRlQ29tbW9uKEEsIEIpO1xuICBjb25zdCBzdWZmaXhDb21tb24gPSBjcmVhdGVDb21tb24oXG4gICAgQS5zbGljZShwcmVmaXhDb21tb24ubGVuZ3RoKSxcbiAgICBCLnNsaWNlKHByZWZpeENvbW1vbi5sZW5ndGgpLFxuICAgIHRydWUsXG4gICkucmV2ZXJzZSgpO1xuICBBID0gc3VmZml4Q29tbW9uLmxlbmd0aFxuICAgID8gQS5zbGljZShwcmVmaXhDb21tb24ubGVuZ3RoLCAtc3VmZml4Q29tbW9uLmxlbmd0aClcbiAgICA6IEEuc2xpY2UocHJlZml4Q29tbW9uLmxlbmd0aCk7XG4gIEIgPSBzdWZmaXhDb21tb24ubGVuZ3RoXG4gICAgPyBCLnNsaWNlKHByZWZpeENvbW1vbi5sZW5ndGgsIC1zdWZmaXhDb21tb24ubGVuZ3RoKVxuICAgIDogQi5zbGljZShwcmVmaXhDb21tb24ubGVuZ3RoKTtcbiAgY29uc3Qgc3dhcHBlZCA9IEIubGVuZ3RoID4gQS5sZW5ndGg7XG4gIFtBLCBCXSA9IHN3YXBwZWQgPyBbQiwgQV0gOiBbQSwgQl07XG4gIGNvbnN0IE0gPSBBLmxlbmd0aDtcbiAgY29uc3QgTiA9IEIubGVuZ3RoO1xuICBpZiAoIU0gJiYgIU4gJiYgIXN1ZmZpeENvbW1vbi5sZW5ndGggJiYgIXByZWZpeENvbW1vbi5sZW5ndGgpIHJldHVybiBbXTtcbiAgaWYgKCFOKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLnByZWZpeENvbW1vbi5tYXAoXG4gICAgICAgIChjKTogRGlmZlJlc3VsdDx0eXBlb2YgYz4gPT4gKHsgdHlwZTogRGlmZlR5cGUuY29tbW9uLCB2YWx1ZTogYyB9KSxcbiAgICAgICksXG4gICAgICAuLi5BLm1hcChcbiAgICAgICAgKGEpOiBEaWZmUmVzdWx0PHR5cGVvZiBhPiA9PiAoe1xuICAgICAgICAgIHR5cGU6IHN3YXBwZWQgPyBEaWZmVHlwZS5hZGRlZCA6IERpZmZUeXBlLnJlbW92ZWQsXG4gICAgICAgICAgdmFsdWU6IGEsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICAgIC4uLnN1ZmZpeENvbW1vbi5tYXAoXG4gICAgICAgIChjKTogRGlmZlJlc3VsdDx0eXBlb2YgYz4gPT4gKHsgdHlwZTogRGlmZlR5cGUuY29tbW9uLCB2YWx1ZTogYyB9KSxcbiAgICAgICksXG4gICAgXTtcbiAgfVxuICBjb25zdCBvZmZzZXQgPSBOO1xuICBjb25zdCBkZWx0YSA9IE0gLSBOO1xuICBjb25zdCBzaXplID0gTSArIE4gKyAxO1xuICBjb25zdCBmcCA9IG5ldyBBcnJheShzaXplKS5maWxsKHsgeTogLTEgfSk7XG4gIC8qKlxuICAgKiBJTkZPOlxuICAgKiBUaGlzIGJ1ZmZlciBpcyB1c2VkIHRvIHNhdmUgbWVtb3J5IGFuZCBpbXByb3ZlIHBlcmZvcm1hbmNlLlxuICAgKiBUaGUgZmlyc3QgaGFsZiBpcyB1c2VkIHRvIHNhdmUgcm91dGUgYW5kIGxhc3QgaGFsZiBpcyB1c2VkIHRvIHNhdmUgZGlmZlxuICAgKiB0eXBlLlxuICAgKiBUaGlzIGlzIGJlY2F1c2UsIHdoZW4gSSBrZXB0IG5ldyB1aW50OGFycmF5IGFyZWEgdG8gc2F2ZSB0eXBlLHBlcmZvcm1hbmNlXG4gICAqIHdvcnNlbmVkLlxuICAgKi9cbiAgY29uc3Qgcm91dGVzID0gbmV3IFVpbnQzMkFycmF5KChNICogTiArIHNpemUgKyAxKSAqIDIpO1xuICBjb25zdCBkaWZmVHlwZXNQdHJPZmZzZXQgPSByb3V0ZXMubGVuZ3RoIC8gMjtcbiAgbGV0IHB0ciA9IDA7XG4gIGxldCBwID0gLTE7XG5cbiAgZnVuY3Rpb24gYmFja1RyYWNlPFQ+KFxuICAgIEE6IFRbXSxcbiAgICBCOiBUW10sXG4gICAgY3VycmVudDogRmFydGhlc3RQb2ludCxcbiAgICBzd2FwcGVkOiBib29sZWFuLFxuICApOiBBcnJheTx7XG4gICAgdHlwZTogRGlmZlR5cGU7XG4gICAgdmFsdWU6IFQ7XG4gIH0+IHtcbiAgICBjb25zdCBNID0gQS5sZW5ndGg7XG4gICAgY29uc3QgTiA9IEIubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGxldCBhID0gTSAtIDE7XG4gICAgbGV0IGIgPSBOIC0gMTtcbiAgICBsZXQgaiA9IHJvdXRlc1tjdXJyZW50LmlkXTtcbiAgICBsZXQgdHlwZSA9IHJvdXRlc1tjdXJyZW50LmlkICsgZGlmZlR5cGVzUHRyT2Zmc2V0XTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKCFqICYmICF0eXBlKSBicmVhaztcbiAgICAgIGNvbnN0IHByZXYgPSBqO1xuICAgICAgaWYgKHR5cGUgPT09IFJFTU9WRUQpIHtcbiAgICAgICAgcmVzdWx0LnVuc2hpZnQoe1xuICAgICAgICAgIHR5cGU6IHN3YXBwZWQgPyBEaWZmVHlwZS5yZW1vdmVkIDogRGlmZlR5cGUuYWRkZWQsXG4gICAgICAgICAgdmFsdWU6IEJbYl0sXG4gICAgICAgIH0pO1xuICAgICAgICBiIC09IDE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IEFEREVEKSB7XG4gICAgICAgIHJlc3VsdC51bnNoaWZ0KHtcbiAgICAgICAgICB0eXBlOiBzd2FwcGVkID8gRGlmZlR5cGUuYWRkZWQgOiBEaWZmVHlwZS5yZW1vdmVkLFxuICAgICAgICAgIHZhbHVlOiBBW2FdLFxuICAgICAgICB9KTtcbiAgICAgICAgYSAtPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LnVuc2hpZnQoeyB0eXBlOiBEaWZmVHlwZS5jb21tb24sIHZhbHVlOiBBW2FdIH0pO1xuICAgICAgICBhIC09IDE7XG4gICAgICAgIGIgLT0gMTtcbiAgICAgIH1cbiAgICAgIGogPSByb3V0ZXNbcHJldl07XG4gICAgICB0eXBlID0gcm91dGVzW3ByZXYgKyBkaWZmVHlwZXNQdHJPZmZzZXRdO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlRlAoXG4gICAgc2xpZGU6IEZhcnRoZXN0UG9pbnQsXG4gICAgZG93bjogRmFydGhlc3RQb2ludCxcbiAgICBrOiBudW1iZXIsXG4gICAgTTogbnVtYmVyLFxuICApOiBGYXJ0aGVzdFBvaW50IHtcbiAgICBpZiAoc2xpZGUgJiYgc2xpZGUueSA9PT0gLTEgJiYgZG93biAmJiBkb3duLnkgPT09IC0xKSB7XG4gICAgICByZXR1cm4geyB5OiAwLCBpZDogMCB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAoZG93biAmJiBkb3duLnkgPT09IC0xKSB8fFxuICAgICAgayA9PT0gTSB8fFxuICAgICAgKHNsaWRlICYmIHNsaWRlLnkpID4gKGRvd24gJiYgZG93bi55KSArIDFcbiAgICApIHtcbiAgICAgIGNvbnN0IHByZXYgPSBzbGlkZS5pZDtcbiAgICAgIHB0cisrO1xuICAgICAgcm91dGVzW3B0cl0gPSBwcmV2O1xuICAgICAgcm91dGVzW3B0ciArIGRpZmZUeXBlc1B0ck9mZnNldF0gPSBBRERFRDtcbiAgICAgIHJldHVybiB7IHk6IHNsaWRlLnksIGlkOiBwdHIgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcHJldiA9IGRvd24uaWQ7XG4gICAgICBwdHIrKztcbiAgICAgIHJvdXRlc1twdHJdID0gcHJldjtcbiAgICAgIHJvdXRlc1twdHIgKyBkaWZmVHlwZXNQdHJPZmZzZXRdID0gUkVNT1ZFRDtcbiAgICAgIHJldHVybiB7IHk6IGRvd24ueSArIDEsIGlkOiBwdHIgfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzbmFrZTxUPihcbiAgICBrOiBudW1iZXIsXG4gICAgc2xpZGU6IEZhcnRoZXN0UG9pbnQsXG4gICAgZG93bjogRmFydGhlc3RQb2ludCxcbiAgICBfb2Zmc2V0OiBudW1iZXIsXG4gICAgQTogVFtdLFxuICAgIEI6IFRbXSxcbiAgKTogRmFydGhlc3RQb2ludCB7XG4gICAgY29uc3QgTSA9IEEubGVuZ3RoO1xuICAgIGNvbnN0IE4gPSBCLmxlbmd0aDtcbiAgICBpZiAoayA8IC1OIHx8IE0gPCBrKSByZXR1cm4geyB5OiAtMSwgaWQ6IC0xIH07XG4gICAgY29uc3QgZnAgPSBjcmVhdGVGUChzbGlkZSwgZG93biwgaywgTSk7XG4gICAgd2hpbGUgKGZwLnkgKyBrIDwgTSAmJiBmcC55IDwgTiAmJiBBW2ZwLnkgKyBrXSA9PT0gQltmcC55XSkge1xuICAgICAgY29uc3QgcHJldiA9IGZwLmlkO1xuICAgICAgcHRyKys7XG4gICAgICBmcC5pZCA9IHB0cjtcbiAgICAgIGZwLnkgKz0gMTtcbiAgICAgIHJvdXRlc1twdHJdID0gcHJldjtcbiAgICAgIHJvdXRlc1twdHIgKyBkaWZmVHlwZXNQdHJPZmZzZXRdID0gQ09NTU9OO1xuICAgIH1cbiAgICByZXR1cm4gZnA7XG4gIH1cblxuICB3aGlsZSAoZnBbZGVsdGEgKyBvZmZzZXRdLnkgPCBOKSB7XG4gICAgcCA9IHAgKyAxO1xuICAgIGZvciAobGV0IGsgPSAtcDsgayA8IGRlbHRhOyArK2spIHtcbiAgICAgIGZwW2sgKyBvZmZzZXRdID0gc25ha2UoXG4gICAgICAgIGssXG4gICAgICAgIGZwW2sgLSAxICsgb2Zmc2V0XSxcbiAgICAgICAgZnBbayArIDEgKyBvZmZzZXRdLFxuICAgICAgICBvZmZzZXQsXG4gICAgICAgIEEsXG4gICAgICAgIEIsXG4gICAgICApO1xuICAgIH1cbiAgICBmb3IgKGxldCBrID0gZGVsdGEgKyBwOyBrID4gZGVsdGE7IC0taykge1xuICAgICAgZnBbayArIG9mZnNldF0gPSBzbmFrZShcbiAgICAgICAgayxcbiAgICAgICAgZnBbayAtIDEgKyBvZmZzZXRdLFxuICAgICAgICBmcFtrICsgMSArIG9mZnNldF0sXG4gICAgICAgIG9mZnNldCxcbiAgICAgICAgQSxcbiAgICAgICAgQixcbiAgICAgICk7XG4gICAgfVxuICAgIGZwW2RlbHRhICsgb2Zmc2V0XSA9IHNuYWtlKFxuICAgICAgZGVsdGEsXG4gICAgICBmcFtkZWx0YSAtIDEgKyBvZmZzZXRdLFxuICAgICAgZnBbZGVsdGEgKyAxICsgb2Zmc2V0XSxcbiAgICAgIG9mZnNldCxcbiAgICAgIEEsXG4gICAgICBCLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIFtcbiAgICAuLi5wcmVmaXhDb21tb24ubWFwKFxuICAgICAgKGMpOiBEaWZmUmVzdWx0PHR5cGVvZiBjPiA9PiAoeyB0eXBlOiBEaWZmVHlwZS5jb21tb24sIHZhbHVlOiBjIH0pLFxuICAgICksXG4gICAgLi4uYmFja1RyYWNlKEEsIEIsIGZwW2RlbHRhICsgb2Zmc2V0XSwgc3dhcHBlZCksXG4gICAgLi4uc3VmZml4Q29tbW9uLm1hcChcbiAgICAgIChjKTogRGlmZlJlc3VsdDx0eXBlb2YgYz4gPT4gKHsgdHlwZTogRGlmZlR5cGUuY29tbW9uLCB2YWx1ZTogYyB9KSxcbiAgICApLFxuICBdO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLFdBS08sUUFJTjtVQUpXLFFBQVE7SUFBUixRQUFRLENBQ2xCLFNBQU8sSUFBUCxTQUFPO0lBREcsUUFBUSxDQUVsQixRQUFNLElBQU4sUUFBTTtJQUZJLFFBQVEsQ0FHbEIsT0FBSyxJQUFMLE9BQUs7R0FISyxRQUFRLEtBQVIsUUFBUTtBQVdwQixNQUFNLE9BQU8sR0FBRyxDQUFDLEFBQUM7QUFDbEIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxBQUFDO0FBQ2pCLE1BQU0sS0FBSyxHQUFHLENBQUMsQUFBQztBQUVoQixTQUFTLFlBQVksQ0FBSSxDQUFNLEVBQUUsQ0FBTSxFQUFFLE9BQWlCLEVBQU87SUFDL0QsTUFBTSxNQUFNLEdBQUcsRUFBRSxBQUFDO0lBQ2xCLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxD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 \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.meta" "b/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.meta" deleted file mode 100644 index 4b36acd..0000000 --- "a/.\\.cache/gen/https/deno.land/b74532b63b4b2b08e618f6ccbb6ec181293852d7b2c4aea34cb1599ab82741d4.meta" +++ /dev/null @@ -1 +0,0 @@ -{"source_hash":"14728771330113844916","emit_hash":"17537645386804052"} \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.js" "b/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.js" deleted file mode 100644 index 32bcc6f..0000000 --- "a/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.js" +++ /dev/null @@ -1,473 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// A module to print ANSI terminal colors. Inspired by chalk, kleur, and colors -// on npm. -// -// ``` -// import { bgBlue, red, bold } from "https://deno.land/std/fmt/colors.ts"; -// console.log(bgBlue(red(bold("Hello world!")))); -// ``` -// -// This module supports `NO_COLOR` environmental variable disabling any coloring -// if `NO_COLOR` is set. -// -// This module is browser compatible. -const noColor = globalThis.Deno?.noColor ?? true; -let enabled = !noColor; -/** - * Set changing text color to enabled or disabled - * @param value - */ export function setColorEnabled(value) { - if (noColor) { - return; - } - enabled = value; -} -/** Get whether text color change is enabled or disabled. */ export function getColorEnabled() { - return enabled; -} -/** - * Builds color code - * @param open - * @param close - */ function code(open, close) { - return { - open: `\x1b[${open.join(";")}m`, - close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g") - }; -} -/** - * Applies color and background based on color code and its associated text - * @param str text to apply color settings to - * @param code color code to apply - */ function run(str, code) { - return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; -} -/** - * Reset the text modified - * @param str text to reset - */ export function reset(str) { - return run(str, code([ - 0 - ], 0)); -} -/** - * Make the text bold. - * @param str text to make bold - */ export function bold(str) { - return run(str, code([ - 1 - ], 22)); -} -/** - * The text emits only a small amount of light. - * @param str text to dim - */ export function dim(str) { - return run(str, code([ - 2 - ], 22)); -} -/** - * Make the text italic. - * @param str text to make italic - */ export function italic(str) { - return run(str, code([ - 3 - ], 23)); -} -/** - * Make the text underline. - * @param str text to underline - */ export function underline(str) { - return run(str, code([ - 4 - ], 24)); -} -/** - * Invert background color and text color. - * @param str text to invert its color - */ export function inverse(str) { - return run(str, code([ - 7 - ], 27)); -} -/** - * Make the text hidden. - * @param str text to hide - */ export function hidden(str) { - return run(str, code([ - 8 - ], 28)); -} -/** - * Put horizontal line through the center of the text. - * @param str text to strike through - */ export function strikethrough(str) { - return run(str, code([ - 9 - ], 29)); -} -/** - * Set text color to black. - * @param str text to make black - */ export function black(str) { - return run(str, code([ - 30 - ], 39)); -} -/** - * Set text color to red. - * @param str text to make red - */ export function red(str) { - return run(str, code([ - 31 - ], 39)); -} -/** - * Set text color to green. - * @param str text to make green - */ export function green(str) { - return run(str, code([ - 32 - ], 39)); -} -/** - * Set text color to yellow. - * @param str text to make yellow - */ export function yellow(str) { - return run(str, code([ - 33 - ], 39)); -} -/** - * Set text color to blue. - * @param str text to make blue - */ export function blue(str) { - return run(str, code([ - 34 - ], 39)); -} -/** - * Set text color to magenta. - * @param str text to make magenta - */ export function magenta(str) { - return run(str, code([ - 35 - ], 39)); -} -/** - * Set text color to cyan. - * @param str text to make cyan - */ export function cyan(str) { - return run(str, code([ - 36 - ], 39)); -} -/** - * Set text color to white. - * @param str text to make white - */ export function white(str) { - return run(str, code([ - 37 - ], 39)); -} -/** - * Set text color to gray. - * @param str text to make gray - */ export function gray(str) { - return brightBlack(str); -} -/** - * Set text color to bright black. - * @param str text to make bright-black - */ export function brightBlack(str) { - return run(str, code([ - 90 - ], 39)); -} -/** - * Set text color to bright red. - * @param str text to make bright-red - */ export function brightRed(str) { - return run(str, code([ - 91 - ], 39)); -} -/** - * Set text color to bright green. - * @param str text to make bright-green - */ export function brightGreen(str) { - return run(str, code([ - 92 - ], 39)); -} -/** - * Set text color to bright yellow. - * @param str text to make bright-yellow - */ export function brightYellow(str) { - return run(str, code([ - 93 - ], 39)); -} -/** - * Set text color to bright blue. - * @param str text to make bright-blue - */ export function brightBlue(str) { - return run(str, code([ - 94 - ], 39)); -} -/** - * Set text color to bright magenta. - * @param str text to make bright-magenta - */ export function brightMagenta(str) { - return run(str, code([ - 95 - ], 39)); -} -/** - * Set text color to bright cyan. - * @param str text to make bright-cyan - */ export function brightCyan(str) { - return run(str, code([ - 96 - ], 39)); -} -/** - * Set text color to bright white. - * @param str text to make bright-white - */ export function brightWhite(str) { - return run(str, code([ - 97 - ], 39)); -} -/** - * Set background color to black. - * @param str text to make its background black - */ export function bgBlack(str) { - return run(str, code([ - 40 - ], 49)); -} -/** - * Set background color to red. - * @param str text to make its background red - */ export function bgRed(str) { - return run(str, code([ - 41 - ], 49)); -} -/** - * Set background color to green. - * @param str text to make its background green - */ export function bgGreen(str) { - return run(str, code([ - 42 - ], 49)); -} -/** - * Set background color to yellow. - * @param str text to make its background yellow - */ export function bgYellow(str) { - return run(str, code([ - 43 - ], 49)); -} -/** - * Set background color to blue. - * @param str text to make its background blue - */ export function bgBlue(str) { - return run(str, code([ - 44 - ], 49)); -} -/** - * Set background color to magenta. - * @param str text to make its background magenta - */ export function bgMagenta(str) { - return run(str, code([ - 45 - ], 49)); -} -/** - * Set background color to cyan. - * @param str text to make its background cyan - */ export function bgCyan(str) { - return run(str, code([ - 46 - ], 49)); -} -/** - * Set background color to white. - * @param str text to make its background white - */ export function bgWhite(str) { - return run(str, code([ - 47 - ], 49)); -} -/** - * Set background color to bright black. - * @param str text to make its background bright-black - */ export function bgBrightBlack(str) { - return run(str, code([ - 100 - ], 49)); -} -/** - * Set background color to bright red. - * @param str text to make its background bright-red - */ export function bgBrightRed(str) { - return run(str, code([ - 101 - ], 49)); -} -/** - * Set background color to bright green. - * @param str text to make its background bright-green - */ export function bgBrightGreen(str) { - return run(str, code([ - 102 - ], 49)); -} -/** - * Set background color to bright yellow. - * @param str text to make its background bright-yellow - */ export function bgBrightYellow(str) { - return run(str, code([ - 103 - ], 49)); -} -/** - * Set background color to bright blue. - * @param str text to make its background bright-blue - */ export function bgBrightBlue(str) { - return run(str, code([ - 104 - ], 49)); -} -/** - * Set background color to bright magenta. - * @param str text to make its background bright-magenta - */ export function bgBrightMagenta(str) { - return run(str, code([ - 105 - ], 49)); -} -/** - * Set background color to bright cyan. - * @param str text to make its background bright-cyan - */ export function bgBrightCyan(str) { - return run(str, code([ - 106 - ], 49)); -} -/** - * Set background color to bright white. - * @param str text to make its background bright-white - */ export function bgBrightWhite(str) { - return run(str, code([ - 107 - ], 49)); -} -/* Special Color Sequences */ /** - * Clam and truncate color codes - * @param n - * @param max number to truncate to - * @param min number to truncate from - */ function clampAndTruncate(n, max = 255, min = 0) { - return Math.trunc(Math.max(Math.min(n, max), min)); -} -/** - * Set text color using paletted 8bit colors. - * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit - * @param str text color to apply paletted 8bit colors to - * @param color code - */ export function rgb8(str, color) { - return run(str, code([ - 38, - 5, - clampAndTruncate(color) - ], 39)); -} -/** - * Set background color using paletted 8bit colors. - * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit - * @param str text color to apply paletted 8bit background colors to - * @param color code - */ export function bgRgb8(str, color) { - return run(str, code([ - 48, - 5, - clampAndTruncate(color) - ], 49)); -} -/** - * Set text color using 24bit rgb. - * `color` can be a number in range `0x000000` to `0xffffff` or - * an `Rgb`. - * - * To produce the color magenta: - * - * rgb24("foo", 0xff00ff); - * rgb24("foo", {r: 255, g: 0, b: 255}); - * @param str text color to apply 24bit rgb to - * @param color code - */ export function rgb24(str, color) { - if (typeof color === "number") { - return run(str, code([ - 38, - 2, - color >> 16 & 0xff, - color >> 8 & 0xff, - color & 0xff - ], 39)); - } - return run(str, code([ - 38, - 2, - clampAndTruncate(color.r), - clampAndTruncate(color.g), - clampAndTruncate(color.b), - ], 39)); -} -/** - * Set background color using 24bit rgb. - * `color` can be a number in range `0x000000` to `0xffffff` or - * an `Rgb`. - * - * To produce the color magenta: - * - * bgRgb24("foo", 0xff00ff); - * bgRgb24("foo", {r: 255, g: 0, b: 255}); - * @param str text color to apply 24bit rgb to - * @param color code - */ export function bgRgb24(str, color) { - if (typeof color === "number") { - return run(str, code([ - 48, - 2, - color >> 16 & 0xff, - color >> 8 & 0xff, - color & 0xff - ], 49)); - } - return run(str, code([ - 48, - 2, - clampAndTruncate(color.r), - clampAndTruncate(color.g), - clampAndTruncate(color.b), - ], 49)); -} -// https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js -const ANSI_PATTERN = new RegExp([ - "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", - "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", -].join("|"), "g"); -/** - * Remove ANSI escape codes from the string. - * @param string to remove ANSI escape codes from - */ export function stripColor(string) { - return string.replace(ANSI_PATTERN, ""); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjkwLjAvZm10L2NvbG9ycy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIxIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gQSBtb2R1bGUgdG8gcHJpbnQgQU5TSSB0ZXJtaW5hbCBjb2xvcnMuIEluc3BpcmVkIGJ5IGNoYWxrLCBrbGV1ciwgYW5kIGNvbG9yc1xuLy8gb24gbnBtLlxuLy9cbi8vIGBgYFxuLy8gaW1wb3J0IHsgYmdCbHVlLCByZWQsIGJvbGQgfSBmcm9tIFwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkL2ZtdC9jb2xvcnMudHNcIjtcbi8vIGNvbnNvbGUubG9nKGJnQmx1ZShyZWQoYm9sZChcIkhlbGxvIHdvcmxkIVwiKSkpKTtcbi8vIGBgYFxuLy9cbi8vIFRoaXMgbW9kdWxlIHN1cHBvcnRzIGBOT19DT0xPUmAgZW52aXJvbm1lbnRhbCB2YXJpYWJsZSBkaXNhYmxpbmcgYW55IGNvbG9yaW5nXG4vLyBpZiBgTk9fQ09MT1JgIGlzIHNldC5cbi8vXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmNvbnN0IG5vQ29sb3IgPSBnbG9iYWxUaGlzLkRlbm8/Lm5vQ29sb3IgPz8gdHJ1ZTtcblxuaW50ZXJmYWNlIENvZGUge1xuICBvcGVuOiBzdHJpbmc7XG4gIGNsb3NlOiBzdHJpbmc7XG4gIHJlZ2V4cDogUmVnRXhwO1xufVxuXG4vKiogUkdCIDgtYml0cyBwZXIgY2hhbm5lbC4gRWFjaCBpbiByYW5nZSBgMC0+MjU1YCBvciBgMHgwMC0+MHhmZmAgKi9cbmludGVyZmFjZSBSZ2Ige1xuICByOiBudW1iZXI7XG4gIGc6IG51bWJlcjtcbiAgYjogbnVtYmVyO1xufVxuXG5sZXQgZW5hYmxlZCA9ICFub0NvbG9yO1xuXG4vKipcbiAqIFNldCBjaGFuZ2luZyB0ZXh0IGNvbG9yIHRvIGVuYWJsZWQgb3IgZGlzYWJsZWRcbiAqIEBwYXJhbSB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0Q29sb3JFbmFibGVkKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gIGlmIChub0NvbG9yKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZW5hYmxlZCA9IHZhbHVlO1xufVxuXG4vKiogR2V0IHdoZXRoZXIgdGV4dCBjb2xvciBjaGFuZ2UgaXMgZW5hYmxlZCBvciBkaXNhYmxlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2xvckVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIHJldHVybiBlbmFibGVkO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBjb2xvciBjb2RlXG4gKiBAcGFyYW0gb3BlblxuICogQHBhcmFtIGNsb3NlXG4gKi9cbmZ1bmN0aW9uIGNvZGUob3BlbjogbnVtYmVyW10sIGNsb3NlOiBudW1iZXIpOiBDb2RlIHtcbiAgcmV0dXJuIHtcbiAgICBvcGVuOiBgXFx4MWJbJHtvcGVuLmpvaW4oXCI7XCIpfW1gLFxuICAgIGNsb3NlOiBgXFx4MWJbJHtjbG9zZX1tYCxcbiAgICByZWdleHA6IG5ldyBSZWdFeHAoYFxcXFx4MWJcXFxcWyR7Y2xvc2V9bWAsIFwiZ1wiKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBBcHBsaWVzIGNvbG9yIGFuZCBiYWNrZ3JvdW5kIGJhc2VkIG9uIGNvbG9yIGNvZGUgYW5kIGl0cyBhc3NvY2lhdGVkIHRleHRcbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBhcHBseSBjb2xvciBzZXR0aW5ncyB0b1xuICogQHBhcmFtIGNvZGUgY29sb3IgY29kZSB0byBhcHBseVxuICovXG5mdW5jdGlvbiBydW4oc3RyOiBzdHJpbmcsIGNvZGU6IENvZGUpOiBzdHJpbmcge1xuICByZXR1cm4gZW5hYmxlZFxuICAgID8gYCR7Y29kZS5vcGVufSR7c3RyLnJlcGxhY2UoY29kZS5yZWdleHAsIGNvZGUub3Blbil9JHtjb2RlLmNsb3NlfWBcbiAgICA6IHN0cjtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgdGV4dCBtb2RpZmllZFxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIHJlc2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFswXSwgMCkpO1xufVxuXG4vKipcbiAqIE1ha2UgdGhlIHRleHQgYm9sZC5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGJvbGRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJvbGQoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcnVuKHN0ciwgY29kZShbMV0sIDIyKSk7XG59XG5cbi8qKlxuICogVGhlIHRleHQgZW1pdHMgb25seSBhIHNtYWxsIGFtb3VudCBvZiBsaWdodC5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBkaW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpbShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFsyXSwgMjIpKTtcbn1cblxuLyoqXG4gKiBNYWtlIHRoZSB0ZXh0IGl0YWxpYy5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0YWxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXRhbGljKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzNdLCAyMykpO1xufVxuXG4vKipcbiAqIE1ha2UgdGhlIHRleHQgdW5kZXJsaW5lLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIHVuZGVybGluZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5kZXJsaW5lKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzRdLCAyNCkpO1xufVxuXG4vKipcbiAqIEludmVydCBiYWNrZ3JvdW5kIGNvbG9yIGFuZCB0ZXh0IGNvbG9yLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIGludmVydCBpdHMgY29sb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludmVyc2Uoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcnVuKHN0ciwgY29kZShbN10sIDI3KSk7XG59XG5cbi8qKlxuICogTWFrZSB0aGUgdGV4dCBoaWRkZW4uXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gaGlkZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlkZGVuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzhdLCAyOCkpO1xufVxuXG4vKipcbiAqIFB1dCBob3Jpem9udGFsIGxpbmUgdGhyb3VnaCB0aGUgY2VudGVyIG9mIHRoZSB0ZXh0LlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIHN0cmlrZSB0aHJvdWdoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpa2V0aHJvdWdoKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzldLCAyOSkpO1xufVxuXG4vKipcbiAqIFNldCB0ZXh0IGNvbG9yIHRvIGJsYWNrLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgYmxhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJsYWNrKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzMwXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byByZWQuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSByZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFszMV0sIDM5KSk7XG59XG5cbi8qKlxuICogU2V0IHRleHQgY29sb3IgdG8gZ3JlZW4uXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBncmVlblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlZW4oc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcnVuKHN0ciwgY29kZShbMzJdLCAzOSkpO1xufVxuXG4vKipcbiAqIFNldCB0ZXh0IGNvbG9yIHRvIHllbGxvdy5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIHllbGxvd1xuICovXG5leHBvcnQgZnVuY3Rpb24geWVsbG93KHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzMzXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBibHVlLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgYmx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmx1ZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFszNF0sIDM5KSk7XG59XG5cbi8qKlxuICogU2V0IHRleHQgY29sb3IgdG8gbWFnZW50YS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIG1hZ2VudGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hZ2VudGEoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcnVuKHN0ciwgY29kZShbMzVdLCAzOSkpO1xufVxuXG4vKipcbiAqIFNldCB0ZXh0IGNvbG9yIHRvIGN5YW4uXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBjeWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjeWFuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzM2XSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byB3aGl0ZS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIHdoaXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aGl0ZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFszN10sIDM5KSk7XG59XG5cbi8qKlxuICogU2V0IHRleHQgY29sb3IgdG8gZ3JheS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGdyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyYXkoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYnJpZ2h0QmxhY2soc3RyKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgYmxhY2suXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBicmlnaHQtYmxhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJyaWdodEJsYWNrKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzkwXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgcmVkLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgYnJpZ2h0LXJlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gYnJpZ2h0UmVkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzkxXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgZ3JlZW4uXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBicmlnaHQtZ3JlZW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJyaWdodEdyZWVuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzkyXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgeWVsbG93LlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgYnJpZ2h0LXllbGxvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gYnJpZ2h0WWVsbG93KHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzkzXSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgYmx1ZS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGJyaWdodC1ibHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBicmlnaHRCbHVlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzk0XSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgbWFnZW50YS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGJyaWdodC1tYWdlbnRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBicmlnaHRNYWdlbnRhKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzk1XSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgY3lhbi5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGJyaWdodC1jeWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBicmlnaHRDeWFuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzk2XSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgdGV4dCBjb2xvciB0byBicmlnaHQgd2hpdGUuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBicmlnaHQtd2hpdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJyaWdodFdoaXRlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzk3XSwgMzkpKTtcbn1cblxuLyoqXG4gKiBTZXQgYmFja2dyb3VuZCBjb2xvciB0byBibGFjay5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIGJsYWNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZ0JsYWNrKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzQwXSwgNDkpKTtcbn1cblxuLyoqXG4gKiBTZXQgYmFja2dyb3VuZCBjb2xvciB0byByZWQuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCByZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnUmVkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzQxXSwgNDkpKTtcbn1cblxuLyoqXG4gKiBTZXQgYmFja2dyb3VuZCBjb2xvciB0byBncmVlbi5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIGdyZWVuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZ0dyZWVuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzQyXSwgNDkpKTtcbn1cblxuLyoqXG4gKiBTZXQgYmFja2dyb3VuZCBjb2xvciB0byB5ZWxsb3cuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCB5ZWxsb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnWWVsbG93KHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzQzXSwgNDkpKTtcbn1cblxuLyoqXG4gKiBTZXQgYmFja2dyb3VuZCBjb2xvciB0byBibHVlLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgaXRzIGJhY2tncm91bmQgYmx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdCbHVlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzQ0XSwgNDkpKTtcbn1cblxuLyoqXG4gKiAgU2V0IGJhY2tncm91bmQgY29sb3IgdG8gbWFnZW50YS5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIG1hZ2VudGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnTWFnZW50YShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFs0NV0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gY3lhbi5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIGN5YW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnQ3lhbihzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFs0Nl0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gd2hpdGUuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCB3aGl0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdXaGl0ZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFs0N10sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IGJsYWNrLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgaXRzIGJhY2tncm91bmQgYnJpZ2h0LWJsYWNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZ0JyaWdodEJsYWNrKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwMF0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IHJlZC5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIGJyaWdodC1yZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnQnJpZ2h0UmVkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwMV0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IGdyZWVuLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgaXRzIGJhY2tncm91bmQgYnJpZ2h0LWdyZWVuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZ0JyaWdodEdyZWVuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwMl0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IHllbGxvdy5cbiAqIEBwYXJhbSBzdHIgdGV4dCB0byBtYWtlIGl0cyBiYWNrZ3JvdW5kIGJyaWdodC15ZWxsb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnQnJpZ2h0WWVsbG93KHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwM10sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IGJsdWUuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCBicmlnaHQtYmx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdCcmlnaHRCbHVlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwNF0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IG1hZ2VudGEuXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCBicmlnaHQtbWFnZW50YVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdCcmlnaHRNYWdlbnRhKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwNV0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IGN5YW4uXG4gKiBAcGFyYW0gc3RyIHRleHQgdG8gbWFrZSBpdHMgYmFja2dyb3VuZCBicmlnaHQtY3lhblxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdCcmlnaHRDeWFuKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwNl0sIDQ5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdG8gYnJpZ2h0IHdoaXRlLlxuICogQHBhcmFtIHN0ciB0ZXh0IHRvIG1ha2UgaXRzIGJhY2tncm91bmQgYnJpZ2h0LXdoaXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZ0JyaWdodFdoaXRlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzEwN10sIDQ5KSk7XG59XG5cbi8qIFNwZWNpYWwgQ29sb3IgU2VxdWVuY2VzICovXG5cbi8qKlxuICogQ2xhbSBhbmQgdHJ1bmNhdGUgY29sb3IgY29kZXNcbiAqIEBwYXJhbSBuXG4gKiBAcGFyYW0gbWF4IG51bWJlciB0byB0cnVuY2F0ZSB0b1xuICogQHBhcmFtIG1pbiBudW1iZXIgdG8gdHJ1bmNhdGUgZnJvbVxuICovXG5mdW5jdGlvbiBjbGFtcEFuZFRydW5jYXRlKG46IG51bWJlciwgbWF4ID0gMjU1LCBtaW4gPSAwKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgudHJ1bmMoTWF0aC5tYXgoTWF0aC5taW4obiwgbWF4KSwgbWluKSk7XG59XG5cbi8qKlxuICogU2V0IHRleHQgY29sb3IgdXNpbmcgcGFsZXR0ZWQgOGJpdCBjb2xvcnMuXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlIzgtYml0XG4gKiBAcGFyYW0gc3RyIHRleHQgY29sb3IgdG8gYXBwbHkgcGFsZXR0ZWQgOGJpdCBjb2xvcnMgdG9cbiAqIEBwYXJhbSBjb2xvciBjb2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZ2I4KHN0cjogc3RyaW5nLCBjb2xvcjogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJ1bihzdHIsIGNvZGUoWzM4LCA1LCBjbGFtcEFuZFRydW5jYXRlKGNvbG9yKV0sIDM5KSk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdXNpbmcgcGFsZXR0ZWQgOGJpdCBjb2xvcnMuXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlIzgtYml0XG4gKiBAcGFyYW0gc3RyIHRleHQgY29sb3IgdG8gYXBwbHkgcGFsZXR0ZWQgOGJpdCBiYWNrZ3JvdW5kIGNvbG9ycyB0b1xuICogQHBhcmFtIGNvbG9yIGNvZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJnUmdiOChzdHI6IHN0cmluZywgY29sb3I6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBydW4oc3RyLCBjb2RlKFs0OCwgNSwgY2xhbXBBbmRUcnVuY2F0ZShjb2xvcildLCA0OSkpO1xufVxuXG4vKipcbiAqIFNldCB0ZXh0IGNvbG9yIHVzaW5nIDI0Yml0IHJnYi5cbiAqIGBjb2xvcmAgY2FuIGJlIGEgbnVtYmVyIGluIHJhbmdlIGAweDAwMDAwMGAgdG8gYDB4ZmZmZmZmYCBvclxuICogYW4gYFJnYmAuXG4gKlxuICogVG8gcHJvZHVjZSB0aGUgY29sb3IgbWFnZW50YTpcbiAqXG4gKiAgICAgIHJnYjI0KFwiZm9vXCIsIDB4ZmYwMGZmKTtcbiAqICAgICAgcmdiMjQoXCJmb29cIiwge3I6IDI1NSwgZzogMCwgYjogMjU1fSk7XG4gKiBAcGFyYW0gc3RyIHRleHQgY29sb3IgdG8gYXBwbHkgMjRiaXQgcmdiIHRvXG4gKiBAcGFyYW0gY29sb3IgY29kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmdiMjQoc3RyOiBzdHJpbmcsIGNvbG9yOiBudW1iZXIgfCBSZ2IpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIGNvbG9yID09PSBcIm51bWJlclwiKSB7XG4gICAgcmV0dXJuIHJ1bihcbiAgICAgIHN0cixcbiAgICAgIGNvZGUoXG4gICAgICAgIFszOCwgMiwgKGNvbG9yID4+IDE2KSAmIDB4ZmYsIChjb2xvciA+PiA4KSAmIDB4ZmYsIGNvbG9yICYgMHhmZl0sXG4gICAgICAgIDM5LFxuICAgICAgKSxcbiAgICApO1xuICB9XG4gIHJldHVybiBydW4oXG4gICAgc3RyLFxuICAgIGNvZGUoXG4gICAgICBbXG4gICAgICAgIDM4LFxuICAgICAgICAyLFxuICAgICAgICBjbGFtcEFuZFRydW5jYXRlKGNvbG9yLnIpLFxuICAgICAgICBjbGFtcEFuZFRydW5jYXRlKGNvbG9yLmcpLFxuICAgICAgICBjbGFtcEFuZFRydW5jYXRlKGNvbG9yLmIpLFxuICAgICAgXSxcbiAgICAgIDM5LFxuICAgICksXG4gICk7XG59XG5cbi8qKlxuICogU2V0IGJhY2tncm91bmQgY29sb3IgdXNpbmcgMjRiaXQgcmdiLlxuICogYGNvbG9yYCBjYW4gYmUgYSBudW1iZXIgaW4gcmFuZ2UgYDB4MDAwMDAwYCB0byBgMHhmZmZmZmZgIG9yXG4gKiBhbiBgUmdiYC5cbiAqXG4gKiBUbyBwcm9kdWNlIHRoZSBjb2xvciBtYWdlbnRhOlxuICpcbiAqICAgICAgYmdSZ2IyNChcImZvb1wiLCAweGZmMDBmZik7XG4gKiAgICAgIGJnUmdiMjQoXCJmb29cIiwge3I6IDI1NSwgZzogMCwgYjogMjU1fSk7XG4gKiBAcGFyYW0gc3RyIHRleHQgY29sb3IgdG8gYXBwbHkgMjRiaXQgcmdiIHRvXG4gKiBAcGFyYW0gY29sb3IgY29kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmdSZ2IyNChzdHI6IHN0cmluZywgY29sb3I6IG51bWJlciB8IFJnYik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgY29sb3IgPT09IFwibnVtYmVyXCIpIHtcbiAgICByZXR1cm4gcnVuKFxuICAgICAgc3RyLFxuICAgICAgY29kZShcbiAgICAgICAgWzQ4LCAyLCAoY29sb3IgPj4gMTYpICYgMHhmZiwgKGNvbG9yID4+IDgpICYgMHhmZiwgY29sb3IgJiAweGZmXSxcbiAgICAgICAgNDksXG4gICAgICApLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHJ1bihcbiAgICBzdHIsXG4gICAgY29kZShcbiAgICAgIFtcbiAgICAgICAgNDgsXG4gICAgICAgIDIsXG4gICAgICAgIGNsYW1wQW5kVHJ1bmNhdGUoY29sb3IuciksXG4gICAgICAgIGNsYW1wQW5kVHJ1bmNhdGUoY29sb3IuZyksXG4gICAgICAgIGNsYW1wQW5kVHJ1bmNhdGUoY29sb3IuYiksXG4gICAgICBdLFxuICAgICAgNDksXG4gICAgKSxcbiAgKTtcbn1cblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYWxrL2Fuc2ktcmVnZXgvYmxvYi8yYjU2ZmIwYzdhMDcxMDhlNWI1NDI0MWU4ZmFlYzE2MGQzOTNhZWRiL2luZGV4LmpzXG5jb25zdCBBTlNJX1BBVFRFUk4gPSBuZXcgUmVnRXhwKFxuICBbXG4gICAgXCJbXFxcXHUwMDFCXFxcXHUwMDlCXVtbXFxcXF0oKSM7P10qKD86KD86KD86W2EtekEtWlxcXFxkXSooPzo7Wy1hLXpBLVpcXFxcZFxcXFwvIyYuOj0/JUB+X10qKSopP1xcXFx1MDAwNylcIixcbiAgICBcIig/Oig/OlxcXFxkezEsNH0oPzo7XFxcXGR7MCw0fSkqKT9bXFxcXGRBLVBSLVRaY2YtbnRxcnk9Pjx+XSkpXCIsXG4gIF0uam9pbihcInxcIiksXG4gIFwiZ1wiLFxuKTtcblxuLyoqXG4gKiBSZW1vdmUgQU5TSSBlc2NhcGUgY29kZXMgZnJvbSB0aGUgc3RyaW5nLlxuICogQHBhcmFtIHN0cmluZyB0byByZW1vdmUgQU5TSSBlc2NhcGUgY29kZXMgZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaXBDb2xvcihzdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzdHJpbmcucmVwbGFjZShBTlNJX1BBVFRFUk4sIFwiXCIpO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSwrRUFBK0U7QUFDL0UsVUFBVTtBQUNWLEVBQUU7QUFDRixNQUFNO0FBQ04sMkVBQTJFO0FBQzNFLGtEQUFrRDtBQUNsRCxNQUFNO0FBQ04sRUFBRTtBQUNGLGdGQUFnRjtBQUNoRix3QkFBd0I7QUFDeEIsRUFBRTtBQUNGLHFDQUFxQztBQUVyQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsSUFBSSxFQUFFLE9BQU8sSUFBSSxJQUFJLEFBQUM7QUFlakQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEFBQUM7QUFFdkI7OztHQUdHLENBQ0gsT0FBTyxTQUFTLGVBQWUsQ0FBQyxLQUFjLEVBQVE7SUFDcEQsSUFBSSxPQUFPLEVBQUU7UUFDWCxPQUFPO0tBQ1I7SUFFRCxPQUFPLEdBQUcsS0FBSyxDQUFDO0NBQ2pCO0FBRUQsNERBQTRE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 \ No newline at end of file diff --git "a/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.meta" "b/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.meta" deleted file mode 100644 index 5f7523a..0000000 --- "a/.\\.cache/gen/https/deno.land/c3031fe6d1ec46c7ee6519cd64b11875eca3b83ce3ceb1323a43a0810846f180.meta" +++ /dev/null @@ -1 +0,0 @@ -{"source_hash":"6994463079202639405","emit_hash":"5311910704850736559"} \ No newline at end of file diff --git a/README.md b/README.md index b8d330e..00eab21 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ By default, this makes the blockchain the best place to keep deeds. - Basic Checks before listing and unlisting data. - Error Handling and checking to make sure information is posted and rooms cannot be zero -![Code_Screenshot](https://i.imgur.com/vQjHhOB.png) +![Code_Screenshot](https://i.imgur.com/xcWAHWr.png) ## 👨‍🔧 Project Plan diff --git a/contracts/deed.clar b/contracts/deed.clar index 11780c9..d058a2b 100644 --- a/contracts/deed.clar +++ b/contracts/deed.clar @@ -110,12 +110,13 @@ (define-public (buy-deed (deed-id uint)) (let ( - (listed (unwrap! (get listed (map-get? deeds deed-id)) err-deed-does-not-exist)) + (owner (unwrap! (get owner (map-get? deeds deed-id)) err-deed-does-not-exist)) + (listed (unwrap-panic (get listed (map-get? deeds deed-id)))) (price (unwrap-panic (get price (map-get? deeds deed-id)))) ) (asserts! listed err-deed-not-listed) (asserts! (is-eq (> price u0)) err-price-expected-more) - (try! (stx-transfer? price tx-sender (as-contract tx-sender))) ;; Do the transaction + (try! (stx-transfer? price tx-sender owner)) ;; Transaction from the buyer to the owner (map-set deeds deed-id (merge (unwrap-panic (map-get? deeds deed-id)) {owner: tx-sender, listed: false})) (ok true) ) @@ -228,3 +229,10 @@ ) ) ) + +;;* Gets the owner of a deed +;; @param deed-id The Deed ID +;; @returns principal The Owner address of the Deed +(define-read-only (get-owner (deed-id uint)) + (ok (unwrap! (get owner (map-get? deeds deed-id)) err-deed-does-not-exist)) +) diff --git a/tests/deed_test.ts b/tests/deed_test.ts index 5c4b9da..daef270 100644 --- a/tests/deed_test.ts +++ b/tests/deed_test.ts @@ -7,9 +7,9 @@ import { } from "https://deno.land/x/clarinet@v1.0.2/index.ts"; import { assertEquals } from "https://deno.land/std@0.90.0/testing/asserts.ts"; -// Clarinet Default Test +//* Clarinet Default Test Clarinet.test({ - name: "Ensure that <...>", + name: "Ensure that contract works", async fn(chain: Chain, accounts: Map) { let block = chain.mineBlock([ /* @@ -32,7 +32,7 @@ Clarinet.test({ }); //* Stats to Run the test -const contractname = "deed"; +const contractName = "deed"; const defaultStxVaultAmount = 5000; const defaultMembers = [ @@ -42,3 +42,462 @@ const defaultMembers = [ "wallet_3", "wallet_4", ]; + +/* +- Error List - + +err u100 - Deed is not listed for sale +err u101 - Deed is listed for sale +err u102 - Deed does not exist +err u103 - Deed already exists +err u104 - Invalid Value in a Tuple +err u105 - Not the Deed Owner +err u106 - Price is zero or not enough +*/ + +//* Accessing all the functions using the Deed ID #1 +Clarinet.test({ + name: "Cannot access any function without creating a deed", + async fn(chain: Chain, accounts: Map) { + let deployer = accounts.get("deployer")!; + let wallet1 = accounts.get("wallet_1")!; + + let block = chain.mineBlock([ + // Transfer Deed + Tx.contractCall( + contractName, + "transfer-deed", + [types.principal(wallet1.address), types.uint(1)], + deployer.address + ), + // Listing for sale + Tx.contractCall( + contractName, + "list-for-sale", + [types.uint(1), types.uint(100)], + deployer.address + ), + // Unlisting from sale + Tx.contractCall( + contractName, + "unlist-for-sale", + [types.uint(1)], + deployer.address + ), + // Buy Deed + Tx.contractCall( + contractName, + "buy-deed", + [types.uint(1)], + deployer.address + ), + // Change Price + Tx.contractCall( + contractName, + "change-price", + [types.uint(1), types.uint(500)], + deployer.address + ), + // Change Images + Tx.contractCall( + contractName, + "change-images", + [types.uint(1), types.ascii("Test")], + deployer.address + ), + // Change Name + Tx.contractCall( + contractName, + "change-name", + [types.uint(1), types.ascii("Test")], + deployer.address + ), + // Change Bedroom + Tx.contractCall( + contractName, + "change-bedroom", + [types.uint(1), types.uint(4)], + deployer.address + ), + // Change Bathroom + Tx.contractCall( + contractName, + "change-bathroom", + [types.uint(1), types.uint(4)], + deployer.address + ), + // Change Size + Tx.contractCall( + contractName, + "change-size", + [types.uint(1), types.uint(200), types.uint(200)], + deployer.address + ), + // Get Deed + Tx.contractCall( + contractName, + "get-deed", + [types.uint(1)], + deployer.address + ), + ]); + + // Transfer Should Fail + block.receipts[0].result.expectErr().expectUint(102); + // Listing should fail + block.receipts[1].result.expectErr().expectUint(102); + // Unlist should fail + block.receipts[2].result.expectErr().expectUint(102); + // Buy Deed should fail + block.receipts[3].result.expectErr().expectUint(102); + // Changing Price should fail + block.receipts[4].result.expectErr().expectUint(102); + // Changing Images should fail + block.receipts[5].result.expectErr().expectUint(102); + // Changing Name should fail + block.receipts[6].result.expectErr().expectUint(102); + // Changing Bedroom should fail + block.receipts[7].result.expectErr().expectUint(102); + // Changing Bathroom should fail + block.receipts[8].result.expectErr().expectUint(102); + // Changing Size + block.receipts[9].result.expectErr().expectUint(102); + // Getting Deed + block.receipts[10].result.expectErr().expectUint(102); + }, +}); + +//* Creating a Deed starting from incorrect values +Clarinet.test({ + name: "Creating a Deed starting from incorrect values", + async fn(chain: Chain, accounts: Map) { + let deployer = accounts.get("deployer")!; + + let block = chain.mineBlock([ + // Create a Deeds Incorrectly + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii(""), // Name + types.ascii(""), // Image URL + types.uint(0), // Bedroom + types.uint(0), // Bathroom + types.uint(0), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii(""), // Image URL + types.uint(0), // Bedroom + types.uint(0), // Bathroom + types.uint(0), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(0), // Bedroom + types.uint(0), // Bathroom + types.uint(0), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(1), // Bedroom + types.uint(0), // Bathroom + types.uint(0), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(0), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(500), // Size X + types.uint(0), // Size Y + ], + deployer.address + ), + // Valid Transaction + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(500), // Size X + types.uint(500), // Size Y + ], + deployer.address + ), + ]); + + // Incorrect Ones + block.receipts[0].result.expectErr().expectUint(104); + block.receipts[1].result.expectErr().expectUint(104); + block.receipts[2].result.expectErr().expectUint(104); + block.receipts[3].result.expectErr().expectUint(104); + block.receipts[4].result.expectErr().expectUint(104); + block.receipts[5].result.expectErr().expectUint(104); + + // Correct one + block.receipts[6].result.expectOk(); + }, +}); + +//* Creating a Deed and changing information +Clarinet.test({ + name: "Creating a Deed and changing information", + async fn(chain: Chain, accounts: Map) { + let deployer = accounts.get("deployer")!; + + let block = chain.mineBlock([ + // Valid Transaction + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("Name"), // Name + types.ascii("URL"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(500), // Size X + types.uint(500), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "get-deed", + [types.uint(1)], + deployer.address + ), + // Changing Price + Tx.contractCall( + contractName, + "change-price", + [types.uint(1), types.uint(500)], + deployer.address + ), + // Changing Images URL + Tx.contractCall( + contractName, + "change-images", + [types.uint(1), types.ascii("https://google.com")], + deployer.address + ), + // Changing Images URL + Tx.contractCall( + contractName, + "change-name", + [types.uint(1), types.ascii("Jake")], + deployer.address + ), + // Changing Bedroom Count + Tx.contractCall( + contractName, + "change-bedroom", + [types.uint(1), types.uint(4)], + deployer.address + ), + Tx.contractCall( + contractName, + "change-bathroom", + [types.uint(1), types.uint(2)], + deployer.address + ), + Tx.contractCall( + contractName, + "change-size", + [types.uint(1), types.uint(200), types.uint(200)], + deployer.address + ), + ]); + + // Created Deed + block.receipts[0].result.expectOk(); + // Getting Deed by ID + block.receipts[1].result.expectOk().expectTuple(); + // Changing Price + block.receipts[2].result.expectOk(); + // Changing Image URL + block.receipts[3].result.expectOk(); + // Changing Name + block.receipts[4].result.expectOk(); + // Changing Bedroom count + block.receipts[5].result.expectOk(); + // Changing Bathroom count + block.receipts[6].result.expectOk(); + // Changing Size + block.receipts[7].result.expectOk(); + }, +}); + +//* Listing a Deed and Selling it +Clarinet.test({ + name: "Listing a Deed and selling it", + async fn(chain: Chain, accounts: Map) { + let deployer = accounts.get("deployer")!; + let buyer = accounts.get("wallet_1")!; + + let block = chain.mineBlock([ + // Valid Transaction + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("House"), // Name + types.ascii("https://google.com"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(500), // Size X + types.uint(500), // Size Y + ], + deployer.address + ), + // Listing House for Sale + Tx.contractCall( + contractName, + "list-for-sale", + [ + types.uint(1), // ID + types.uint(1200), // Price + ], + deployer.address + ), + Tx.contractCall( + contractName, + "get-owner", + [ + types.uint(1), // ID + ], + deployer.address + ), + // Buying Deed + Tx.contractCall(contractName, "buy-deed", [types.uint(1)], buyer.address), + Tx.contractCall( + contractName, + "get-owner", + [ + types.uint(1), // ID + ], + deployer.address + ), + ]); + + // Created Deed + block.receipts[0].result.expectOk(); + // Listing Deed + block.receipts[1].result.expectOk(); + // Checking Address before transfer + block.receipts[2].result.expectOk().expectPrincipal(deployer.address); + // Buying Deed + block.receipts[3].events.expectSTXTransferEvent( + 1200, + buyer.address, + deployer.address + ); + // Confirming Address after transfer + block.receipts[4].result.expectOk().expectPrincipal(buyer.address); + }, +}); + +//* Trying to change information on an unowned deed + +//* Transferring Deed +Clarinet.test({ + name: "Transfer Deed", + async fn(chain: Chain, accounts: Map) { + let deployer = accounts.get("deployer")!; + let buyer = accounts.get("wallet_1")!; + + let block = chain.mineBlock([ + // Valid Transaction + Tx.contractCall( + contractName, + "create-deed", + [ + types.ascii("House"), // Name + types.ascii("https://google.com"), // Image URL + types.uint(1), // Bedroom + types.uint(2), // Bathroom + types.uint(500), // Size X + types.uint(500), // Size Y + ], + deployer.address + ), + Tx.contractCall( + contractName, + "get-owner", + [ + types.uint(1), // ID + ], + deployer.address + ), + // Transfer Deed + Tx.contractCall( + contractName, + "transfer-deed", + [ + types.principal(buyer.address), // Transfer Account + types.uint(1), // ID + ], + deployer.address + ), + Tx.contractCall( + contractName, + "get-owner", + [ + types.uint(1), // ID + ], + deployer.address + ), + ]); + + // Created Deed + block.receipts[0].result.expectOk(); + // Checking the Owner before transfer + block.receipts[1].result.expectOk().expectPrincipal(deployer.address); + // Transferred Ownership + block.receipts[2].result.expectOk(); + // Checking the Owner after transfer + block.receipts[3].result.expectOk().expectPrincipal(buyer.address); + }, +});