diff --git a/AGENTS.md b/AGENTS.md index 334982c..519f9f4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,6 +32,8 @@ npm run lint:src # ESLint on src/ npm run lint:lib # ESLint on lib/ ``` +Documentation-only changes (`.md` files) do not require running tests or linters. + ## Module architecture - CJS consumers get `lib/index.js` via `main` / `exports.require`. @@ -54,6 +56,66 @@ npm run lint:lib # ESLint on lib/ - Class properties that should be type-checked must be declared with `declare prop: Type;` and assigned inside the constructor. Initialized class fields (`prop: Type = value`) bypass the Proxy. - `src/esm.ts` must not introduce new runtime logic; it only re-exports. +## Prototype wiring internals + +Understanding how the proxy is attached prevents accidental prototype pollution or coverage regressions. + +### `BaseClass` + +The constructor checks whether the instance already reaches a TypeØmatica proxy through its prototype chain. If it does, it returns immediately. + +Otherwise it walks up the prototype chain until it finds the class that directly extends `BaseClass` and installs the proxy there. This keeps intermediate classes intact. For `class C extends B extends A extends BaseClass` the resulting chain is: + +``` +instance → C.prototype → B.prototype → A.prototype → proxy → target +``` + +Every class prototype in that chain (`C.prototype`, `B.prototype`, and `A.prototype`) is frozen by default, so none of them can be reassigned or grow new properties at runtime. Pass `{ frozenPrototypes: false }` in `TypeomaticaOptions` to keep them mutable. + +For a direct subclass `class X extends BaseClass` the walk stops immediately: + +``` +instance → X.prototype → proxy → target +``` + +For a direct `new BaseClass(...)` call the instance itself is wired and `BaseClass.prototype` is frozen, but not mutated into a proxy. + +### `BaseConstructorPrototype` + +In constructor mode the function walks the instance's prototype chain until it reaches `BaseConstructorPrototype.prototype` (or a prototype whose `constructor` is `BaseConstructorPrototype`). The object just before that stopping point is treated as the class prototype: + +``` +instance → DerivedClass.prototype → BaseConstructorPrototype.prototype +``` + +It sets `DerivedClass.prototype.__proto__` to the proxy and freezes `DerivedClass.prototype` by default (configurable via `frozenPrototypes: false`): + +``` +instance → DerivedClass.prototype → proxy → target +``` + +For a direct `new BaseConstructorPrototype(...)` call there is no derived class, so the instance itself becomes the wired object and `BaseConstructorPrototype.prototype` is frozen as the class prototype. + +### `@Strict()` decorator + +At decoration time it reparents the class prototype to a plain object that itself inherits from the proxy, then freezes the class prototype by default (configurable via `frozenPrototypes: false`): + +``` +Class.prototype → plainReplacer → proxy → target +``` + +The extra plain replacer exists because the class already owns its methods and accessors on `Class.prototype`; the proxy only needs to handle missing properties. + +### Direct extension + +`class MyClass extends BaseConstructorPrototype {}` is valid, but after the first instance the chain becomes: + +``` +MyClass.prototype → proxy → target → null +``` + +Therefore `instanceof BaseConstructorPrototype` will be `false` after wiring. The factory form `class MyClass extends BasePrototype({...})` is the preferred API. + ## What to discuss before changing - Proxy handler logic in `createHandlers()`. diff --git a/FOR_HUMANS.md b/FOR_HUMANS.md index 051641b..50fb85c 100644 --- a/FOR_HUMANS.md +++ b/FOR_HUMANS.md @@ -71,6 +71,18 @@ class User extends BaseClass { Or use `FieldConstructor` if you need custom getters/setters. +## Three ways to attach it + +TypeØmatica gives you three APIs that all put a Proxy on your class prototype chain and then freeze that prototype. Pick whichever fits your existing code shape. + +| API | Looks like | When it wires | Initial state | Best for | +|---|---|---|---|---| +| `BaseClass` | `class X extends BaseClass { ... }` | First instance constructed | Per instance via `super({...})` | Modern class-based code | +| `BasePrototype` | `class X extends BasePrototype({...}) { ... }` or `const X = BasePrototype({...})` | First instance constructed | Bound at class/factory creation | Function constructors or factory-returned constructors | +| `@Strict()` | `@Strict({...}) class X { ... }` | When the class is decorated | Bound at decoration | Existing classes you do not want to `extend` | + +The behavior is the same: after a property is assigned, its type is locked, and attempts to mutate the prototype or add new properties to it are rejected. + ## Five-minute example ```typescript diff --git a/README.md b/README.md index 3736c0c..8c0ea9e 100644 --- a/README.md +++ b/README.md @@ -153,11 +153,93 @@ TypeØmatica wraps objects with JavaScript Proxies that intercept: --- +## The Three Entry Points + +TypeØmatica exposes three APIs that all do the same underlying thing — attach a Proxy to a prototype chain so property writes are type-checked and the class prototype is frozen. They differ in how you create and attach that prototype. + +| | `BaseClass` | `BasePrototype` / `BaseConstructorPrototype` | `@Strict()` | +|---|---|---|---| +| **How you use it** | `class X extends BaseClass { ... }` | `class X extends BasePrototype({...}) { ... }` or `const X = BasePrototype({...})` | `@Strict({...}) class X { ... }` | +| **Wiring moment** | First time an instance is constructed | First time an instance is constructed | When the class is decorated (module load) | +| **Initial state** | Can pass a *new* target per instance via `super({...})` | Target is bound at class/factory creation; `super(...)` args are ignored because the constructor is bound | Target/options are bound at decoration | +| **Prototype chain shape** | `X.prototype → … → classDirectlyExtendingBase.prototype → proxy → target` | `X.prototype → proxy → target` (class usage) | `X.prototype → plain replacer → proxy → target` | +| **Function-constructor support** | No | Yes — `BasePrototype` can return a constructor function | No | +| **Default export?** | No, it is a named export/property | Yes, `require('typeomatica')` is `BaseConstructorPrototype` | No, exported as `Strict` | + +### 1. `BaseConstructorPrototype` (default export) — manual prototype manipulation + +`BaseConstructorPrototype` is the lowest-level API. It returns an instance that is designed to be assigned as the prototype of an existing constructor function using `Object.setPrototypeOf`. + +```typescript +import BasePrototype from 'typeomatica'; + +const MyConstructor = function (this: { value: number }) { + this.value = 0; +}; + +const baseProto = new BasePrototype({ value: 0 }); +Object.setPrototypeOf(MyConstructor.prototype, baseProto); + +const instance = new MyConstructor(); +instance.value = 42; // ✓ Works +// @ts-ignore +instance.value = '42'; // ✗ TypeError: Type Mismatch +``` + +Use this when you already have a constructor function and need to inject type checking into its prototype chain manually, or when you want a factory that returns a constructor function. + +### 2. `BaseClass` — `extends` + +`BaseClass` is the same mechanism wrapped in a class. When you `extends BaseClass`, TypeØmatica internally sets the proxy prototype for you. + +```typescript +import { BaseClass } from 'typeomatica'; + +class MyClass extends BaseClass { + declare value: number; + constructor() { + super({ value: 0 }); + this.value = this.value; + } +} +``` + +`super()` accepts an optional initial-state object and `TypeomaticaOptions`. Because the proxy target is set up during `super()`, you usually re-assign the inherited values inside the constructor (as shown above) so they pass through the proxy and become type-locked. Unlike `BasePrototype`, `BaseClass` lets you pass a *new* initial-state object per instance. + +### 3. `@Strict()` — decorator + +`@Strict()` does the same prototype injection but as a class decorator. It accepts the same optional arguments as `BaseConstructorPrototype`: + +- First argument: initial-state object (`{ starterProp: value }`). +- Second argument: `TypeomaticaOptions` (e.g., `{ strictAccessCheck: true }`). + +```typescript +import { Strict } from 'typeomatica'; + +@Strict({ value: 0 }, { strictAccessCheck: true }) +class MyClass { + declare value: number; + constructor() { + this.value = 0; + } +} +``` + +Use `@Strict()` when you want a clean class decorator and need to pass initial state or options without changing the class `extends` clause. + +### Which one should I use? + +- Use **`BaseClass`** for modern `extends`-based classes, especially when you want per-instance initial state through `super({...})`. +- Use **`BasePrototype(...)`** when you need a factory that returns a constructor, or when working with function constructors. +- Use **`@Strict()`** when you want to Typeømatica-wrap an existing class without changing its `extends` clause. + +--- + ## API Reference ### BaseClass -The primary class for strict-type objects. +The primary class for strict-type objects. `super()` accepts an optional initial-state object and `TypeomaticaOptions`. ```typescript import { BaseClass } from 'typeomatica'; @@ -165,15 +247,17 @@ import { BaseClass } from 'typeomatica'; class MyClass extends BaseClass { declare field: string; constructor() { - super(); - this.field = 'value'; + super({ field: 'value' }); + this.field = this.field; } } ``` ### BaseConstructorPrototype (default export) -Functional equivalent of `BaseClass`. The default export of the package is `BaseConstructorPrototype`, which can be called without `new` to produce a base constructor. +Functional equivalent of `BaseClass`. The default export of the package is `BaseConstructorPrototype`. + +**Form 1 — call without `new` to get a base constructor:** ```typescript import BasePrototype from 'typeomatica'; @@ -183,6 +267,21 @@ const Base = BasePrototype({ initialProp: 123 }); class MyClass extends Base { } ``` +**Form 2 — call with `new` to get a prototype object for `Object.setPrototypeOf`:** + +```typescript +import BasePrototype from 'typeomatica'; + +const MyConstructor = function (this: { initialProp: number }) { + this.initialProp = 0; +}; + +const baseProto = new BasePrototype({ initialProp: 123 }); +Object.setPrototypeOf(MyConstructor.prototype, baseProto); + +const instance = new MyConstructor(); +``` + ### @Strict() Decorator Apply strict typing without extending BaseClass. @@ -415,11 +514,13 @@ const doubled = registers.count.valueOf() * 2; ```typescript interface TypeomaticaOptions { strictAccessCheck?: boolean; // default: false + frozenPrototypes?: boolean; // default: true } ``` **Options:** - `strictAccessCheck: true` - Enables strict receiver checking (throws `ACCESS_DENIED` error when property is accessed from wrong context) +- `frozenPrototypes: false` - Keeps class prototypes mutable so methods/properties can be added at runtime (foot-gun allowed) ### Usage with Options @@ -451,6 +552,16 @@ class Product { this.price = 0; } } + +// With BaseClass - allow runtime prototype mutation (not recommended) +class ExtensibleBase extends BaseClass { + declare value: number; + constructor() { + super(undefined, { frozenPrototypes: false }); + this.value = 0; + } +} +ExtensibleBase.prototype.helper = () => 'ok'; ``` ### Symbol Exports diff --git a/lib/esm/fields.d.ts b/lib/esm/fields.d.ts index 1fceeb5..049a9b8 100644 --- a/lib/esm/fields.d.ts +++ b/lib/esm/fields.d.ts @@ -3,10 +3,10 @@ interface FieldDefinition { [SymbolInitialValue]: unknown; } export declare class FieldConstructor implements FieldDefinition { - [SymbolInitialValue]: unknown; - get get(): () => unknown; - get set(): () => never; - constructor(value: unknown); - static get SymbolInitialValue(): symbol; + [SymbolInitialValue]: unknown; + get get(): () => unknown; + get set(): () => never; + constructor(value: unknown); + static get SymbolInitialValue(): symbol; } export {}; diff --git a/lib/esm/index.d.ts b/lib/esm/index.d.ts index dcf8bc1..4a25d32 100644 --- a/lib/esm/index.d.ts +++ b/lib/esm/index.d.ts @@ -1,6 +1,7 @@ import { FieldConstructor } from './fields.js'; export interface TypeomaticaOptions { strictAccessCheck?: boolean; + frozenPrototypes?: boolean; } export declare const baseTarget: (_proto?: object) => any; export declare const SymbolTypeomaticaProxyReference: unique symbol; @@ -9,7 +10,7 @@ export declare const BaseConstructorPrototype: { (_target?: S extends infer InferredS ? InferredS : {}, options?: TypeomaticaOptions): S; }; export declare class BaseClass { - constructor(_target?: object, options?: TypeomaticaOptions); + constructor(_target?: object, options?: TypeomaticaOptions); } export declare const SymbolInitialValue: symbol; declare const FieldConstructorExport: typeof FieldConstructor; diff --git a/lib/esm/index.js b/lib/esm/index.js index 003ca6f..8edcd60 100644 --- a/lib/esm/index.js +++ b/lib/esm/index.js @@ -93,6 +93,9 @@ const createHandlers = (options) => ({ }, {})); }; } + if (prop === 'constructor') { + return undefined; + } const { name } = receiver.constructor; if (props2skip.has(prop)) { const message = `${name} lacks definition of [ ${String(prop).valueOf()} ]`; @@ -155,7 +158,9 @@ export const BaseConstructorPrototype = function (_target, options) { return this; } const target = baseTarget(_target); + const { frozenPrototypes: freezeProtos = true } = options || {}; const InstancePrototype = getTypeomaticaProxyReference(target, options); + const classPrototype = Object.getPrototypeOf(this); let proto; let protoPointer = this; let protoConstrcutor; @@ -185,41 +190,64 @@ export const BaseConstructorPrototype = function (_target, options) { throw new Error('Unable to setup TypeØmatica handler!'); } Object.setPrototypeOf(proto, InstancePrototype); + if (freezeProtos) { + Object.freeze(classPrototype); + } // @ts-ignore return this; }; +const freezeClassPrototypes = (instance, shouldFreeze) => { + if (!shouldFreeze) { + return; + } + const first = Object.getPrototypeOf(instance); + const firstIsProxy = first !== null && !!Reflect.getOwnPropertyDescriptor(first, SymbolTypeomaticaProxyReference); + if (firstIsProxy) { + Object.freeze(BaseClass.prototype); + return; + } + let p = first; + while (p !== null && p !== BaseClass.prototype && p !== Object.prototype) { + const next = Object.getPrototypeOf(p); + const nextIsProxy = next !== null && !!Reflect.getOwnPropertyDescriptor(next, SymbolTypeomaticaProxyReference); + Object.freeze(p); + if (nextIsProxy) { + break; + } + p = next; + } + Object.freeze(BaseClass.prototype); +}; export class BaseClass { constructor(_target, options) { + const { frozenPrototypes: freezeProtos = true } = options || {}; // @ts-ignore if (this[SymbolTypeomaticaProxyReference]) { + freezeClassPrototypes(this, freezeProtos); return this; } const target = baseTarget(_target); const proxy = getTypeomaticaProxyReference(target, options); - let proto = this; - let protoPointer; - let found = false; - do { - protoPointer = Object.getPrototypeOf(proto); - // if (protoPointer[SymbolTypeomaticaProxyReference]) { - // throw new Error('Double TypeØmatica extension is not allowed!'); - // } - if (protoPointer === Object.prototype) { - found = true; - break; - } - /* - // it can be, that protoPointer === null - // though too hard to implement this test - */ - proto = protoPointer; - } while (!found); - Object.setPrototypeOf(proto, proxy); + const instanceProto = Object.getPrototypeOf(this); + if (instanceProto === BaseClass.prototype) { + Object.setPrototypeOf(this, proxy); + freezeClassPrototypes(this, freezeProtos); + return this; + } + let classProto = instanceProto; + let parentProto = Object.getPrototypeOf(classProto); + while (parentProto !== BaseClass.prototype && parentProto !== null) { + classProto = parentProto; + parentProto = Object.getPrototypeOf(classProto); + } + Object.setPrototypeOf(classProto, proxy); + freezeClassPrototypes(this, freezeProtos); } } const strict = function (_target, options) { + const { frozenPrototypes: freezeProtos = true } = options || {}; const decorator = function (cstr) { // @ts-ignore if (cstr.prototype[SymbolTypeomaticaProxyReference]) { @@ -230,6 +258,10 @@ const strict = function (_target, options) { const _replacer = Object.create(proxy); // @ts-ignore Object.setPrototypeOf(cstr.prototype, _replacer); + if (freezeProtos) { + // @ts-ignore + Object.freeze(cstr.prototype); + } return cstr; // const MyClassProxy = new Proxy(cstr, { // construct(_, argumentsList, newTarget) { @@ -312,4 +344,4 @@ function setupCommonJS() { setupCommonJS(); Object.freeze(BaseConstructorPrototype); Object.freeze(BaseConstructorPrototype.prototype); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBRTFDLFlBQVksQ0FBQztBQUViLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUxQyxPQUFPLEVBQ04sU0FBUyxFQUNULE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLE9BQU8sRUFDUCxXQUFXLEVBQ1gsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFNL0MsTUFBTSxjQUFjLEdBQUcsQ0FBQyxVQUE4QixFQUFFLEVBQUUsRUFBRTtJQUMzRCxNQUFNLEVBQUUsaUJBQWlCLEdBQUcsS0FBSyxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRTlDLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNyQixVQUFVO1FBQ1YsT0FBTztRQUNQLE9BQU87UUFDUCxPQUFPO1FBQ1AsU0FBUztLQUNULENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRTtRQUMxQyxhQUFhO1FBQ2IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsWUFBb0IsRUFBRSxRQUFnQjtZQUMxRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDdkMsT0FBTztnQkFDTixHQUFHO29CQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQztvQkFDNUIsSUFBSSxpQkFBaUIsSUFBSSxjQUFjLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQ3RELE1BQU0sSUFBSSxjQUFjLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUNyRCxDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFH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LENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRTtRQUN4RSxHQUFHO1lBQ0YsT0FBTywrQkFBK0IsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsVUFBVSxFQUFFLElBQUk7S0FDaEIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRTtRQUNuRCxHQUFHO1lBQ0YsT0FBTyxVQUFVLENBQUM7UUFDbkIsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUU7UUFDL0MsR0FBRztZQUNGLE9BQU8sTUFBTSxDQUFDO1FBQ2YsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxhQUFhLEVBQUUsQ0FBQztBQUVoQixNQUFNLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIG94bGludC1kaXNhYmxlIHR5cGVzY3JpcHQvbm8tdGhpcy1hbGlhc1xuIFxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBFcnJvcnNOYW1lcyB9IGZyb20gJy4vZXJyb3JzLmpzJztcblxuaW1wb3J0IHtcblx0ZnVuY3Rpb25zLFxuXHRudWxsaXNoLFxuXHRvYmplY3RzLFxuXHRwcmltaXRpdmVzLFxuXHRzcGVjaWFsLFxuXHRpc1ByaW1pdGl2ZVxufSBmcm9tICcuL3R5cGVzL2luZGV4LmpzJztcblxuaW1wb3J0IHsgRmllbGRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmllbGRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUeXBlb21hdGljYU9wdGlvbnMge1xuXHRzdHJpY3RBY2Nlc3NDaGVjaz86IGJvb2xlYW47XG59XG5cbmNvbnN0IGNyZWF0ZVJlc29sdmVyID0gKG9wdGlvbnM6IFR5cGVvbWF0aWNhT3B0aW9ucyA9IHt9KSA9PiB7XG5cdGNvbnN0IHsgc3RyaWN0QWNjZXNzQ2hlY2sgPSBmYWxzZSB9ID0gb3B0aW9ucztcblx0XG5cdHJldHVybiBPYmplY3QuZW50cmllcyh7XG5cdFx0cHJpbWl0aXZlcyxcblx0XHRzcGVjaWFsLFxuXHRcdG51bGxpc2gsXG5cdFx0b2JqZWN0cyxcblx0XHRmdW5jdGlvbnNcblx0fSkucmVkdWNlKChvYmo6IG9iamVjdCwgW2tleSwgX2hhbmRsZXJdKSA9PiB7XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdG9ialtrZXldID0gZnVuY3Rpb24gKGluaXRpYWxWYWx1ZTogb2JqZWN0LCByZWNlaXZlcjogb2JqZWN0KSB7XG5cdFx0XHRjb25zdCBoYW5kbGVyID0gX2hhbmRsZXIoaW5pdGlhbFZhbHVlKTtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGdldCgpIHtcblx0XHRcdFx0XHRjb25zdCBpbnZvY2F0aW9uVGhpcyA9IHRoaXM7XG5cdFx0XHRcdFx0aWYgKHN0cmljdEFjY2Vzc0NoZWNrICYmIGludm9jYXRpb25UaGlzICE9PSByZWNlaXZlcikge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKEVycm9yc05hbWVzLkFDQ0VTU19ERU5JRUQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCByZXN1bHQgPSBoYW5kbGVyLmdldCgpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNldChyZXBsYWNlbWVudFZhbHVlOiB1bmtub3duKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW52b2NhdGlvblRoaXMgPSB0aGlzO1xuXHRcdFx0XHRcdGlmIChzdHJpY3RBY2Nlc3NDaGVjayAmJiBpbnZvY2F0aW9uVGhpcyAhPT0gcmVjZWl2ZXIpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihFcnJvcnNOYW1lcy5BQ0NFU1NfREVOSUVEKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gaGFuZGxlci5zZXQocmVwbGFjZW1lbnRWYWx1ZSk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9O1xuXG5cdFx0cmV0dXJuIG9iajtcblx0fSwge30pO1xufTtcblxuY29uc3QgY3JlYXRlUHJvcGVydHkgPSAocHJvcE5hbWU6IHN0cmluZywgaW5pdGlhbFZhbHVlOiB1bmtub3duLCByZWNlaXZlcjogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSA9PiB7XG5cblx0Y29uc3QgdmFsdWUgPSBpbml0aWFsVmFsdWU7XG5cdGNvbnN0IHZhbHVlSXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZShpbml0aWFsVmFsdWUpO1xuXHRjb25zdCBpc09iamVjdCA9IHR5cGVvZiBpbml0aWFsVmFsdWUgPT09ICdvYmplY3QnO1xuXHRjb25zdCBpc0Z1bmN0aW9uID0gaW5pdGlhbFZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb247XG5cdGNvbnN0IGlzTnVsbCA9IGluaXRpYWxWYWx1ZSA9PT0gbnVsbDtcblxuXHQvKipcblx0ICogc3BlY2lhbDogdW5kZWZpbmVkIG9yIEJpZ0ludCBvciBTeW1ib2xcblx0ICogXHRvciBvdGhlciBub24gY29uc3RydWN0aWJsZSB0eXBlXG5cdCAqL1xuXG5cdGNvbnN0IHR5cGVzID0gdmFsdWVJc1ByaW1pdGl2ZSA/ICdwcmltaXRpdmVzJyA6IChcblx0XHRpc09iamVjdCA/IChcblx0XHRcdGlzTnVsbCA/ICdudWxsaXNoJyA6ICdvYmplY3RzJ1xuXHRcdCkgOiAoXG5cdFx0XHRpc0Z1bmN0aW9uID8gJ2Z1bmN0aW9ucycgOiAnc3BlY2lhbCdcblx0XHQpXG5cdCk7XG5cblx0Y29uc3QgcmVzb2x2ZXIgPSBjcmVhdGVSZXNvbHZlcihvcHRpb25zKTtcblxuXHRjb25zdCBkZXNjcmlwdG9yID0gKGlzT2JqZWN0ICYmICh2YWx1ZSBpbnN0YW5jZW9mIEZpZWxkQ29uc3RydWN0b3IpKSA/XG5cdFx0dmFsdWUgOiB7XG5cdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdFx0Li4ucmVzb2x2ZXJbdHlwZXNdKHZhbHVlLCByZWNlaXZlciksXG5cdFx0fTtcblxuXHQvLyBpZiAodmFsdWUgaW5zdGFuY2VvZiBGaWVsZENvbnN0cnVjdG9yKSB7XG5cdC8vIFx0ZGVzY3JpcHRvcjtcblx0Ly8gXHRkZWJ1Z2dlcjtcblx0Ly8gfVxuXG5cdGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZGVmaW5lUHJvcGVydHkocmVjZWl2ZXIsIHByb3BOYW1lLCBkZXNjcmlwdG9yKTtcblx0cmV0dXJuIHJlc3VsdDtcblxufTtcblxuLy8gbGluZSBiZWxvdyAnaHJlZicgaXMgZm9yIHV0aWwuaW5zcGVjdCB3b3JrcywgdXNlZnVsIGZvciB2MjRcbmNvbnN0IHByb3BzMnNraXAgPSBuZXcgU2V0KFtcblx0U3ltYm9sLnRvU3RyaW5nVGFnLFxuXHRTeW1ib2wuaXRlcmF0b3IsXG5cdC8vIFN5bWJvbC50b1ByaW1pdGl2ZSxcblx0J3RvU3RyaW5nJyxcblx0J3ZhbHVlT2YnLFxuXHQnaHJlZidcbl0pO1xuLy8gY29uc3QgcHJvcHMyc2tpcCA9IG5ldyBTZXQoW1N5bWJvbC50b1N0cmluZ1RhZywgU3ltYm9sLml0ZXJhdG9yXSk7XG5jb25zdCBoYXNOb2RlSW5zcGVjdCA9IChpbnNwZWN0ICYmIGluc3BlY3QuY3VzdG9tKTtcbi8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbihoYXNOb2RlSW5zcGVjdCAmJiAocHJvcHMyc2tpcC5hZGQoaW5zcGVjdC5jdXN0b20pKSk7XG5cbmNvbnN0IGNyZWF0ZUhhbmRsZXJzID0gKG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpID0+ICh7XG5cdGdldCh0YXJnZXQ6IG9iamVjdCwgcHJvcDogc3RyaW5nIHwgc3ltYm9sLCByZWNlaXZlcjogb2JqZWN0KSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG5cdFx0aWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblx0XHRpZiAocHJvcCA9PT0gJ3RvSlNPTicpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uICh0aGlzOiB0eXBlb2YgdGFyZ2V0KSB7XG5cdFx0XHRcdGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyh0aGlzKTtcblx0XHRcdFx0cmV0dXJuIEpTT04uc3RyaW5naWZ5KGVudHJpZXMucmVkdWNlKChvYmosIFtrZXksIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdFx0XHRvYmpba2V5XSA9IHZhbHVlLnZhbHVlT2YoKTtcblx0XHRcdFx0XHRyZXR1cm4gb2JqO1xuXHRcdFx0XHR9LCB7fSkpO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0Y29uc3QgeyBuYW1lIH0gPSByZWNlaXZlci5jb25zdHJ1Y3Rvcjtcblx0XHRpZiAocHJvcHMyc2tpcC5oYXMocHJvcCkpIHtcblx0XHRcdGNvbnN0IG1lc3NhZ2UgPSBgJHtuYW1lfSBsYWNrcyBkZWZpbml0aW9uIG9mIFsgJHtTdHJpbmcocHJvcCkudmFsdWVPZigpfSBdYDtcblx0XHRcdHJldHVybiBtZXNzYWdlO1xuXHRcdH1cblx0XHQvLyBjb25zdCBlcnJvck1lc3NhZ2UgPSBgJHtFcnJvcnNOYW1lcy5NSVNTSU5HX1BST1B9OiBbICR7U3RyaW5nKHByb3ApLnZhbHVlT2YoKX0gXSBmb3IgJHtuYW1lfWA7XG5cdFx0Ly8gdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG5cdH0sXG5cdHNldChfOiBvYmplY3QsIHByb3A6IHN0cmluZywgdmFsdWU6IHVua25vd24sIHJlY2VpdmVyOiBvYmplY3QpIHtcblx0XHRjb25zdCByZXN1bHQgPSBjcmVhdGVQcm9wZXJ0eShwcm9wLCB2YWx1ZSwgcmVjZWl2ZXIsIG9wdGlvbnMpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH0sXG5cdHNldFByb3RvdHlwZU9mKCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignU2V0dGluZyBwcm90b3R5cGUgaXMgbm90IGFsbG93ZWQhJyk7XG5cdH0sXG5cdC8vIGRlZmluZVByb3BlcnR5KHRhcmdldDogb2JqZWN0LCBrZXk6IHN0cmluZywgZGVzY3JpcHRvcjogb2JqZWN0KSB7XG5cdGRlZmluZVByb3BlcnR5KCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignRGVmaW5pbmcgbmV3IFByb3BlcnRpZXMgaXMgbm90IGFsbG93ZWQhJyk7XG5cdFx0Ly8gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcik7XG5cdH0sXG5cdGRlbGV0ZVByb3BlcnR5KCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignUHJvcGVydGllcyBEZWxldGlvbiBpcyBub3QgYWxsb3dlZCEnKTtcblx0fSxcblx0Ly8gZ2V0UHJvdG90eXBlT2YoKSB7XG5cdC8vIFx0ZGVidWdnZXI7XG5cdC8vIFx0dGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIHByb3RvdHlwZSBpcyBub3QgYWxsb3dlZCcpO1xuXHQvLyB9LFxufSk7XG5cbi8vIHVzZXIgaGF2ZSB0byBwcmVjaXNlbHkgZGVmaW5lIGFsbCBwcm9wc1xuZXhwb3J0IGNvbnN0IGJhc2VUYXJnZXQgPSAoX3Byb3RvPzogb2JqZWN0KSA9PiB7XG5cdGNvbnN0IHByb3RvID0gdHlwZW9mIF9wcm90byA9PT0gJ29iamVjdCcgPyBfcHJvdG8gOiBudWxsO1xuXHRjb25zdCBhbnN3ZXIgPSBPYmplY3QuY3JlYXRlKHByb3RvKTtcblx0cmV0dXJuIGFuc3dlcjtcbn07XG5cbmV4cG9ydCBjb25zdCBTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlID0gU3ltYm9sKCdUeXBlw5htYXRpY2FQcm94eVJlZmVyZW5jZScpO1xuY29uc3QgZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSA9IChfdGFyZ2V0OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpID0+IHtcblx0Y29uc3QgdGFyZ2V0ID0gT2JqZWN0LmNyZWF0ZShfdGFyZ2V0KTtcblx0Y29uc3QgaWQgPSBgVHlwZcOYbWF0aWNhUHJveHlSZWZlcmVuY2UtJHtNYXRoLnJhbmRvbSgpfWA7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIFN5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gaWQ7XG5cdFx0fVxuXHR9KTtcblx0Y29uc3QgaGFuZGxlcnMgPSBjcmVhdGVIYW5kbGVycyhvcHRpb25zKTtcblx0Y29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVycyk7XG5cdHJldHVybiBwcm94eTtcbn07XG5cblxuZXhwb3J0IGNvbnN0IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSA9IGZ1bmN0aW9uIDxUIGV4dGVuZHMgb2JqZWN0LCBTIGV4dGVuZHMgVD4odGhpczogUyBleHRlbmRzIFQgPyBTIDoge30sIF90YXJnZXQ/OiBULCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zICk6IFQge1xuXHRpZiAoIW5ldy50YXJnZXQpIHtcblxuXHRcdGNvbnN0IHNlbGY6IHtcblx0XHRcdHByb3RvdHlwZToge1xuXHRcdFx0XHRjb25zdHJ1Y3RvcjogdHlwZW9mIEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZVxuXHRcdFx0fVxuXHRcdFx0Ly9AdHMtaWdub3JlXG5cdFx0fSA9IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5iaW5kKHRoaXMsIF90YXJnZXQsIG9wdGlvbnMpO1xuXG5cdFx0c2VsZi5wcm90b3R5cGUgPSB7XG5cdFx0XHRjb25zdHJ1Y3RvcjogQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlXG5cdFx0fTtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRyZXR1cm4gc2VsZjtcblxuXHR9XG5cblx0Ly8gQHRzLWlnbm9yZVxuXHRpZiAodGhpc1tTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSkge1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCkgYXMgb2JqZWN0O1xuXG5cdGNvbnN0IEluc3RhbmNlUHJvdG90eXBlID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXG5cdGxldCBwcm90bztcblx0bGV0IHByb3RvUG9pbnRlciA9IHRoaXMgYXMgb2JqZWN0O1xuXHRsZXQgcHJvdG9Db25zdHJjdXRvcjtcblxuXHRsZXQgY29uc3RydWN0b3JzID0gZmFsc2U7XG5cblx0Ly8gQHRzLWlnbm9yZVxuXHQvLyBjb25zdCBoYXNQcm94eVJlZmVyZW5jZSA9IHByb3RvUG9pbnRlcltTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSBhcyB1bmtub3duIGFzIGJvb2xlYW47XG5cdC8vIGlmIChoYXNQcm94eVJlZmVyZW5jZSkge1xuXHQvLyBcdHRocm93IG5ldyBFcnJvcignTXVsdGlwbGUgVHlwZcOYbWF0aWNhIGluc3RhbnRpYXRpb25zIGFyZSBub3QgYWxsb3dlZCBmb3IgdGhlIHNhbWUgUHJvdG90eXBlIENoYWluIScpO1xuXHQvLyB9XG5cblx0ZG8ge1xuXHRcdHByb3RvID0gcHJvdG9Qb2ludGVyO1xuXHRcdHByb3RvUG9pbnRlciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cdFx0aWYgKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5wcm90b3R5cGUgPT09IHByb3RvUG9pbnRlcikge1xuXHRcdFx0Y29uc3RydWN0b3JzID0gdHJ1ZTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRpZiAoIXByb3RvUG9pbnRlcikgYnJlYWs7XG5cdFx0Y29uc3QgZGVzY3JpcHRvciA9IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvUG9pbnRlciwgJ2NvbnN0cnVjdG9yJyk7XG5cdFx0aWYgKCFkZXNjcmlwdG9yKSBjb250aW51ZTtcblx0XHRjb25zdCB2YWx1ZSA9IGRlc2NyaXB0b3IudmFsdWUgfHwgZGVzY3JpcHRvci5nZXQ7XG5cdFx0Ly8gaWYgKCF2YWx1ZSkgY29udGludWU7XG5cdFx0cHJvdG9Db25zdHJjdXRvciA9IHZhbHVlO1xuXHR9IHdoaWxlIChwcm90b0NvbnN0cmN1dG9yICE9PSBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUpO1xuXG5cdGlmICghY29uc3RydWN0b3JzICYmIHByb3RvQ29uc3RyY3V0b3IgIT09IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSkge1xuXHRcdHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIHNldHVwIFR5cGXDmG1hdGljYSBoYW5kbGVyIScpO1xuXHR9XG5cblx0T2JqZWN0LnNldFByb3RvdHlwZU9mKHByb3RvLCBJbnN0YW5jZVByb3RvdHlwZSk7XG5cdC8vIEB0cy1pZ25vcmVcblx0cmV0dXJuIHRoaXM7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG59IGFzIHtcblx0bmV3PFQgZXh0ZW5kcyBvYmplY3QgfCB7fT4oX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpOiBUXG5cdDxUIGV4dGVuZHMgb2JqZWN0IHwge30sIFMgZXh0ZW5kcyBUPihfdGFyZ2V0PzogUyBleHRlbmRzIGluZmVyIEluZmVycmVkUyA/IEluZmVycmVkUyA6IHt9LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKTogU1xufTtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuZXhwb3J0IGNsYXNzIEJhc2VDbGFzcyB7XG5cdGNvbnN0cnVjdG9yKF90YXJnZXQ/OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpIHtcblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKHRoaXNbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCkgYXMgb2JqZWN0O1xuXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXHRcdGxldCBwcm90bzogb2JqZWN0IHwgbnVsbCA9IHRoaXM7XG5cdFx0bGV0IHByb3RvUG9pbnRlcjogb2JqZWN0IHwgbnVsbDtcblx0XHRsZXQgZm91bmQ6IGJvb2xlYW4gPSBmYWxzZTtcblx0XHRkbyB7XG5cdFx0XHRwcm90b1BvaW50ZXIgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXHRcdFx0Ly8gaWYgKHByb3RvUG9pbnRlcltTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSkge1xuXHRcdFx0Ly8gXHR0aHJvdyBuZXcgRXJyb3IoJ0RvdWJsZSBUeXBlw5htYXRpY2EgZXh0ZW5zaW9uIGlzIG5vdCBhbGxvd2VkIScpO1xuXHRcdFx0Ly8gfVxuXHRcdFx0aWYgKHByb3RvUG9pbnRlciA9PT0gT2JqZWN0LnByb3RvdHlwZSkge1xuXHRcdFx0XHRmb3VuZCA9IHRydWU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Lypcblx0XHRcdC8vIGl0IGNhbiBiZSwgdGhhdCBwcm90b1BvaW50ZXIgPT09IG51bGxcblx0XHRcdC8vIHRob3VnaCB0b28gaGFyZCB0byBpbXBsZW1lbnQgdGhpcyB0ZXN0XG5cdFx0XHQqL1xuXHRcdFx0cHJvdG8gPSBwcm90b1BvaW50ZXI7XG5cdFx0fSB3aGlsZSAoIWZvdW5kKTtcblx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIHByb3h5KTtcblx0fVxufVxuXG5cbmNvbnN0IHN0cmljdCA9IGZ1bmN0aW9uIChfdGFyZ2V0Pzogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSB7XG5cdGNvbnN0IGRlY29yYXRvciA9IGZ1bmN0aW9uPFQ+KGNzdHI6IFQpOiBUIHtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRpZiAoY3N0ci5wcm90b3R5cGVbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdHJldHVybiBjc3RyO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCk7XG5cdFx0Y29uc3QgcHJveHkgPSBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlKHRhcmdldCwgb3B0aW9ucyk7XG5cdFx0Y29uc3QgX3JlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShwcm94eSk7XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBfcmVwbGFjZXIpO1xuXG5cdFx0cmV0dXJuIGNzdHI7XG5cblxuXHRcdC8vIGNvbnN0IE15Q2xhc3NQcm94eSA9IG5ldyBQcm94eShjc3RyLCB7XG5cdFx0Ly8gXHRjb25zdHJ1Y3QoXywgYXJndW1lbnRzTGlzdCwgbmV3VGFyZ2V0KSB7XG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXHRcdC8vIFx0XHRjb25zdCB0YXJnZXQgPSBiYXNlVGFyZ2V0KF90YXJnZXQpO1xuXHRcdC8vIFx0XHRjb25zdCBwcm94eSA9IGdldFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UodGFyZ2V0KTtcblx0XHQvLyBcdFx0Y29uc3QgX3JlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShwcm94eSk7XG5cblx0XHQvLyBcdFx0Y29uc3QgX3Byb3RvID0gY3N0ci5wcm90b3R5cGU7XG5cblx0XHQvLyBcdFx0Y29uc3QgcHJvdG8gPSBPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZihfcHJvdG8pKTtcblx0XHQvLyBcdFx0cHJvdG8uaUFtUHJvdG8gPSB0cnVlO1xuXG5cdFx0Ly8gXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgcHJvdG8pO1xuXG5cdFx0Ly8gXHRcdGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoX3Byb3RvKTtcblx0XHQvLyBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMocHJvdG8sIGRlc2NyaXB0b3JzKTtcblxuXHRcdC8vIFx0XHRjb25zdCByZXBsYWNlciA9IE9iamVjdC5jcmVhdGUoX3JlcGxhY2VyKTtcblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKHByb3RvLCByZXBsYWNlcik7XG5cblxuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YoY3N0ci5wcm90b3R5cGUsIHByb3RvKTtcblx0XHQvLyBcdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoY3N0ciwgYXJndW1lbnRzTGlzdCwgbmV3VGFyZ2V0KTtcblxuXHRcdC8vIFx0XHRkZWJ1Z2dlcjtcblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBfcHJvdG8pO1xuXHRcdC8vIFx0XHRkZWJ1Z2dlcjtcblxuXHRcdC8vIFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdC8vIFx0fSxcblx0XHQvLyB9KTtcblx0XHQvLyByZXR1cm4gTXlDbGFzc1Byb3h5O1xuXHR9O1xuXG5cdHJldHVybiBkZWNvcmF0b3I7XG5cbn07XG5leHBvcnQgY29uc3QgeyBTeW1ib2xJbml0aWFsVmFsdWUgfSA9IEZpZWxkQ29uc3RydWN0b3I7XG5jb25zdCBGaWVsZENvbnN0cnVjdG9yRXhwb3J0ID0gRmllbGRDb25zdHJ1Y3RvcjtcbmV4cG9ydCB7IEZpZWxkQ29uc3RydWN0b3JFeHBvcnQgYXMgRmllbGRDb25zdHJ1Y3RvciB9O1xuZXhwb3J0IGNvbnN0IFN0cmljdCA9IHN0cmljdDtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIHNldHVwQ29tbW9uSlMoKSB7XG5cdGlmICh0eXBlb2YgbW9kdWxlID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUsICdleHBvcnRzJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGU7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ0Jhc2VDbGFzcycsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gQmFzZUNsYXNzO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnRmllbGRDb25zdHJ1Y3RvcicsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gRmllbGRDb25zdHJ1Y3Rvcjtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ1N5bWJvbEluaXRpYWxWYWx1ZScsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gU3ltYm9sSW5pdGlhbFZhbHVlO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZScsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZTtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ2Jhc2VUYXJnZXQnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIGJhc2VUYXJnZXQ7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdTdHJpY3QnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIHN0cmljdDtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG59XG5cbnNldHVwQ29tbW9uSlMoKTtcblxuT2JqZWN0LmZyZWV6ZShCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUpO1xuT2JqZWN0LmZyZWV6ZShCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUucHJvdG90eXBlKTtcbiJdfQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBRTFDLFlBQVksQ0FBQztBQUViLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUxQyxPQUFPLEVBQ04sU0FBUyxFQUNULE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLE9BQU8sRUFDUCxXQUFXLEVBQ1gsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFPL0MsTUFBTSxjQUFjLEdBQUcsQ0FBQyxVQUE4QixFQUFFLEVBQUUsRUFBRTtJQUMzRCxNQUFNLEVBQUUsaUJBQWlCLEdBQUcsS0FBSyxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRTlDLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNyQixVQUFVO1FBQ1YsT0FBTztRQUNQLE9BQU87UUFDUCxPQUFPO1FBQ1AsU0FBUztLQUNULENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRTtRQUMxQyxhQUFhO1FBQ2IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsWUFBb0IsRUFBRSxRQUFnQjtZQUMxRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDdkMsT0FBTztnQkFDTixHQUFHO29CQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQztvQkFDNUIsSUFBSSxpQkFBaUIsSUFBSSxjQUFjLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQ3RELE1BQU0sSUFBSSxjQUFjLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUNyRCxDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDN0IsT0FBTyxNQUFNLENBQUM7Z0JBQ2YsQ0FBQztnQkFDRCxHQUFHLENBQUMsZ0JBQXlCO29CQUM1QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUM7b0JBQzVCLElBQUksaUJBQWlCLElBQUksY0FBYyxLQUFLLFFBQVEsRUFBRSxDQUFDO3dCQUN0RCxNQUFNLElBQUksY0FBYyxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDckQsQ0FBQztvQkFDRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7b0JBQzdDLE9BQU8sTUFBTSxDQUFDO2dCQUNmLENBQUM7YUFDRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsT0FBTyxHQUFHLENBQUM7SUFDWixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDUixDQUFDLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQWdCLEVBQUUsWUFBcUIsRUFBRSxRQUFnQixFQUFFLE9BQTRCLEVBQUUsRUFBRTtJQUVsSCxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUM7SUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbkQsTUFBTSxRQUFRLEdBQUcsT0FBTyxZQUFZLEtBQUssUUFBUSxDQUFDO0lBQ2xELE1BQU0sVUFBVSxHQUFHLFlBQVksWUFBWSxRQUFRLENBQUM7SUFDcEQsTUFBTSxNQUFNLEdBQUcsWUFBWSxLQUFLLElBQUksQ0FBQztJQUVyQzs7O09BR0c7SUFFSCxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUMvQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FDOUIsQ0FBQyxDQUFDLENBQUMsQ0FDSCxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUNwQyxDQUNELENBQUM7SUFFRixNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFekMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLFlBQVksZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNQLFVBQVUsRUFBRSxJQUFJO1FBQ2hCLGFBQWE7UUFDYixHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDO0tBQ25DLENBQUM7SUFFSCwyQ0FBMkM7SUFDM0MsZUFBZTtJQUNmLGFBQWE7SUFDYixJQUFJO0lBRUosTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RFLE9BQU8sTUFBTSxDQUFDO0FBRWYsQ0FBQyxDQUFDO0FBRUYsOERBQThEO0FBQzlELE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzFCLE1BQU0sQ0FBQyxXQUFXO0lBQ2xCLE1BQU0sQ0FBQyxRQUFRO0lBQ2Ysc0JBQXNCO0lBQ3RCLFVBQVU7SUFDVixTQUFTO0lBQ1QsTUFBTTtDQUNOLENBQUMsQ0FBQztBQUNILHFFQUFxRTtBQUNyRSxNQUFNLGNBQWMsR0FBRyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkQsaURBQWlEO0FBQ2pELENBQUMsY0FBYyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXJELE1BQU0sY0FBYyxHQUFHLENBQUMsT0FBNEIsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6RCxHQUFHLENBQUMsTUFBYyxFQUFFLElBQXFCLEVBQUUsUUFBZ0I7UUFDMUQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ25ELElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLE9BQU8sTUFBTSxDQUFDO1FBQ2YsQ0FBQztRQUNELElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3ZCLDBDQUEwQztZQUMxQyxPQUFPO2dCQUNOLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3JDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7b0JBQzFELGFBQWE7b0JBQ2IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDM0IsT0FBTyxHQUFHLENBQUM7Z0JBQ1osQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDVCxDQUFDLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxJQUFJLEtBQUssYUFBYSxFQUFFLENBQUM7WUFDNUIsT0FBTyxTQUFTLENBQUM7UUFDbEIsQ0FBQztRQUNELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBQ3RDLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sT0FBTyxHQUFHLEdBQUcsSUFBSSwwQkFBMEIsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUM7WUFDNUUsT0FBTyxPQUFPLENBQUM7UUFDaEIsQ0FBQztRQUNELGlHQUFpRztRQUNqRyxpQ0FBaUM7SUFDbEMsQ0FBQztJQUNELEdBQUcsQ0FBQyxDQUFTLEVBQUUsSUFBWSxFQUFFLEtBQWMsRUFBRSxRQUFnQjtRQUM1RCxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDOUQsT0FBTyxNQUFNLENBQUM7SUFDZixDQUFDO0lBQ0QsY0FBYztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBQ0Qsb0VBQW9FO0lBQ3BFLGNBQWM7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDM0QsbURBQW1EO0lBQ3BELENBQUM7SUFDRCxjQUFjO1FBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFDRCxxQkFBcUI7SUFDckIsYUFBYTtJQUNiLHdEQUF3RDtJQUN4RCxLQUFLO0NBQ0wsQ0FBQyxDQUFDO0FBRUgsMENBQTBDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQWUsRUFBRSxFQUFFO0lBQzdDLE1BQU0sS0FBSyxHQUFHLE9BQU8sTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDekQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwQyxPQUFPLE1BQU0sQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQ25GLE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxPQUFlLEVBQUUsT0FBNEIsRUFBRSxFQUFFO0lBQ3RGLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsTUFBTSxFQUFFLEdBQUcsNkJBQTZCLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLCtCQUErQixFQUFFO1FBQzlELEdBQUc7WUFDRixPQUFPLEVBQUUsQ0FBQztRQUNYLENBQUM7S0FDRCxDQUFDLENBQUM7SUFDSCxNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLE9BQU8sS0FBSyxDQUFDO0FBQ2QsQ0FBQyxDQUFDO0FBR0YsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsVUFBcUUsT0FBVyxFQUFFLE9BQTRCO0lBQ3JKLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFakIsTUFBTSxJQUFJLEdBS04sd0JBQXdCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNoQixXQUFXLEVBQUUsd0JBQXdCO1NBQ3JDLENBQUM7UUFFRixhQUFhO1FBQ2IsT0FBTyxJQUFJLENBQUM7SUFFYixDQUFDO0lBRUQsYUFBYTtJQUNiLElBQUksSUFBSSxDQUFDLCtCQUErQixDQUFDLEVBQUUsQ0FBQztRQUMzQyxhQUFhO1FBQ2IsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBVyxDQUFDO0lBQzdDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUVoRSxNQUFNLGlCQUFpQixHQUFHLDRCQUE0QixDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUV4RSxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBVyxDQUFDO0lBRTdELElBQUksS0FBSyxDQUFDO0lBQ1YsSUFBSSxZQUFZLEdBQUcsSUFBYyxDQUFDO0lBQ2xDLElBQUksZ0JBQWdCLENBQUM7SUFFckIsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRXpCLGFBQWE7SUFDYixpR0FBaUc7SUFDakcsMkJBQTJCO0lBQzNCLHlHQUF5RztJQUN6RyxJQUFJO0lBRUosR0FBRyxDQUFDO1FBQ0gsS0FBSyxHQUFHLFlBQVksQ0FBQztRQUNyQixZQUFZLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxJQUFJLHdCQUF3QixDQUFDLFNBQVMsS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUN6RCxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLE1BQU07UUFDUCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVk7WUFBRSxNQUFNO1FBQ3pCLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDakYsSUFBSSxDQUFDLFVBQVU7WUFBRSxTQUFTO1FBQzFCLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUNqRCx3QkFBd0I7UUFDeEIsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUMsUUFBUSxnQkFBZ0IsS0FBSyx3QkFBd0IsRUFBRTtJQUV4RCxJQUFJLENBQUMsWUFBWSxJQUFJLGdCQUFnQixLQUFLLHdCQUF3QixFQUFFLENBQUM7UUFDcEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2hELElBQUksWUFBWSxFQUFFLENBQUM7UUFDbEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBQ0QsYUFBYTtJQUNiLE9BQU8sSUFBSSxDQUFDO0lBRWIsbUNBQW1DO0FBQ25DLENBR0MsQ0FBQztBQUNGLGtDQUFrQztBQUVsQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsUUFBZ0IsRUFBRSxZQUFxQixFQUFFLEVBQUU7SUFDekUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ25CLE9BQU87SUFDUixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QyxNQUFNLFlBQVksR0FBRyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsS0FBSyxFQUFFLCtCQUErQixDQUFDLENBQUM7SUFDbEgsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNsQixNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxPQUFPO0lBQ1IsQ0FBQztJQUVELElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUNkLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDLFNBQVMsSUFBSSxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzFFLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO1FBQy9HLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakIsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNO1FBQ1AsQ0FBQztRQUNELENBQUMsR0FBRyxJQUFJLENBQUM7SUFDVixDQUFDO0lBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRUYsTUFBTSxPQUFPLFNBQVM7SUFDckIsWUFBWSxPQUFnQixFQUFFLE9BQTRCO1FBQ3pELE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVoRSxhQUFhO1FBQ2IsSUFBSSxJQUFJLENBQUMsK0JBQStCLENBQUMsRUFBRSxDQUFDO1lBQzNDLHFCQUFxQixDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMxQyxPQUFPLElBQUksQ0FBQztRQUNiLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFXLENBQUM7UUFDN0MsTUFBTSxLQUFLLEdBQUcsNEJBQTRCLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEQsSUFBSSxhQUFhLEtBQUssU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ25DLHFCQUFxQixDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMxQyxPQUFPLElBQUksQ0FBQztRQUNiLENBQUM7UUFFRCxJQUFJLFVBQVUsR0FBRyxhQUFhLENBQUM7UUFDL0IsSUFBSSxXQUFXLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwRCxPQUFPLFdBQVcsS0FBSyxTQUFTLENBQUMsU0FBUyxJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNwRSxVQUFVLEdBQUcsV0FBVyxDQUFDO1lBQ3pCLFdBQVcsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6QyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNEO0FBR0QsTUFBTSxNQUFNLEdBQUcsVUFBVSxPQUFnQixFQUFFLE9BQTRCO0lBQ3RFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUVoRSxNQUFNLFNBQVMsR0FBRyxVQUFZLElBQU87UUFFcEMsYUFBYTtRQUNiLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQywrQkFBK0IsQ0FBQyxFQUFFLENBQUM7WUFDckQsT0FBTyxJQUFJLENBQUM7UUFDYixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLDRCQUE0QixDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXZDLGFBQWE7UUFDYixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNsQixhQUFhO1lBQ2IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO1FBR1oseUNBQXlDO1FBQ3pDLDRDQUE0QztRQUM1QyxjQUFjO1FBQ2Qsd0NBQXdDO1FBQ3hDLHdEQUF3RDtRQUN4RCw0Q0FBNEM7UUFFNUMsbUNBQW1DO1FBRW5DLGdFQUFnRTtRQUNoRSwyQkFBMkI7UUFFM0Isa0RBQWtEO1FBRWxELGtFQUFrRTtRQUNsRSxpREFBaUQ7UUFFakQsK0NBQStDO1FBQy9DLDRDQUE0QztRQUc1QyxrREFBa0Q7UUFDbEQsc0VBQXNFO1FBRXRFLGNBQWM7UUFDZCxtREFBbUQ7UUFDbkQsY0FBYztRQUVkLG1CQUFtQjtRQUNuQixNQUFNO1FBQ04sTUFBTTtRQUNOLHVCQUF1QjtJQUN4QixDQUFDLENBQUM7SUFFRixPQUFPLFNBQVMsQ0FBQztBQUVsQixDQUFDLENBQUM7QUFDRixNQUFNLENBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFFLEdBQUcsZ0JBQWdCLENBQUM7QUFDdkQsTUFBTSxzQkFBc0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsc0JBQXNCLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztBQUN0RCxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRTdCLDBCQUEwQjtBQUMxQixTQUFTLGFBQWE7SUFDckIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksT0FBTyxNQUFNLENBQUMsT0FBTyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQzVFLE9BQU87SUFDUixDQUFDO0lBQ0QsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFO1FBQ3hDLEdBQUc7WUFDRixPQUFPLHdCQUF3QixDQUFDO1FBQ2pDLENBQUM7UUFDRCxVQUFVLEVBQUUsSUFBSTtLQUNoQixDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFO1FBQ2xELEdBQUc7WUFDRixPQUFPLFNBQVMsQ0FBQztRQUNsQixDQUFDO1FBQ0QsVUFBVSxFQUFFLElBQUk7S0FDaEIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFFO1FBQ3pELEdBQUc7WUFDRixPQUFPLGdCQUFnQixDQUFDO1FBQ3pCLENBQUM7UUFDRCxVQUFVLEVBQUUsSUFBSTtLQUNoQixDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUU7UUFDM0QsR0FBRztZQUNGLE9BQU8sa0JBQWtCLENBQUM7UUFDM0IsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRTtRQUN4RSxHQUFHO1lBQ0YsT0FBTywrQkFBK0IsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsVUFBVSxFQUFFLElBQUk7S0FDaEIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRTtRQUNuRCxHQUFHO1lBQ0YsT0FBTyxVQUFVLENBQUM7UUFDbkIsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUU7UUFDL0MsR0FBRztZQUNGLE9BQU8sTUFBTSxDQUFDO1FBQ2YsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxhQUFhLEVBQUUsQ0FBQztBQUVoQixNQUFNLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIG94bGludC1kaXNhYmxlIHR5cGVzY3JpcHQvbm8tdGhpcy1hbGlhc1xuIFxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBFcnJvcnNOYW1lcyB9IGZyb20gJy4vZXJyb3JzLmpzJztcblxuaW1wb3J0IHtcblx0ZnVuY3Rpb25zLFxuXHRudWxsaXNoLFxuXHRvYmplY3RzLFxuXHRwcmltaXRpdmVzLFxuXHRzcGVjaWFsLFxuXHRpc1ByaW1pdGl2ZVxufSBmcm9tICcuL3R5cGVzL2luZGV4LmpzJztcblxuaW1wb3J0IHsgRmllbGRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmllbGRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUeXBlb21hdGljYU9wdGlvbnMge1xuXHRzdHJpY3RBY2Nlc3NDaGVjaz86IGJvb2xlYW47XG5cdGZyb3plblByb3RvdHlwZXM/OiBib29sZWFuO1xufVxuXG5jb25zdCBjcmVhdGVSZXNvbHZlciA9IChvcHRpb25zOiBUeXBlb21hdGljYU9wdGlvbnMgPSB7fSkgPT4ge1xuXHRjb25zdCB7IHN0cmljdEFjY2Vzc0NoZWNrID0gZmFsc2UgfSA9IG9wdGlvbnM7XG5cdFxuXHRyZXR1cm4gT2JqZWN0LmVudHJpZXMoe1xuXHRcdHByaW1pdGl2ZXMsXG5cdFx0c3BlY2lhbCxcblx0XHRudWxsaXNoLFxuXHRcdG9iamVjdHMsXG5cdFx0ZnVuY3Rpb25zXG5cdH0pLnJlZHVjZSgob2JqOiBvYmplY3QsIFtrZXksIF9oYW5kbGVyXSkgPT4ge1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRvYmpba2V5XSA9IGZ1bmN0aW9uIChpbml0aWFsVmFsdWU6IG9iamVjdCwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdFx0Y29uc3QgaGFuZGxlciA9IF9oYW5kbGVyKGluaXRpYWxWYWx1ZSk7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRnZXQoKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW52b2NhdGlvblRoaXMgPSB0aGlzO1xuXHRcdFx0XHRcdGlmIChzdHJpY3RBY2Nlc3NDaGVjayAmJiBpbnZvY2F0aW9uVGhpcyAhPT0gcmVjZWl2ZXIpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihFcnJvcnNOYW1lcy5BQ0NFU1NfREVOSUVEKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gaGFuZGxlci5nZXQoKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZXQocmVwbGFjZW1lbnRWYWx1ZTogdW5rbm93bikge1xuXHRcdFx0XHRcdGNvbnN0IGludm9jYXRpb25UaGlzID0gdGhpcztcblx0XHRcdFx0XHRpZiAoc3RyaWN0QWNjZXNzQ2hlY2sgJiYgaW52b2NhdGlvblRoaXMgIT09IHJlY2VpdmVyKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoRXJyb3JzTmFtZXMuQUNDRVNTX0RFTklFRCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGhhbmRsZXIuc2V0KHJlcGxhY2VtZW50VmFsdWUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fTtcblxuXHRcdHJldHVybiBvYmo7XG5cdH0sIHt9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVByb3BlcnR5ID0gKHByb3BOYW1lOiBzdHJpbmcsIGluaXRpYWxWYWx1ZTogdW5rbm93biwgcmVjZWl2ZXI6IG9iamVjdCwgb3B0aW9ucz86IFR5cGVvbWF0aWNhT3B0aW9ucykgPT4ge1xuXG5cdGNvbnN0IHZhbHVlID0gaW5pdGlhbFZhbHVlO1xuXHRjb25zdCB2YWx1ZUlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmUoaW5pdGlhbFZhbHVlKTtcblx0Y29uc3QgaXNPYmplY3QgPSB0eXBlb2YgaW5pdGlhbFZhbHVlID09PSAnb2JqZWN0Jztcblx0Y29uc3QgaXNGdW5jdGlvbiA9IGluaXRpYWxWYWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uO1xuXHRjb25zdCBpc051bGwgPSBpbml0aWFsVmFsdWUgPT09IG51bGw7XG5cblx0LyoqXG5cdCAqIHNwZWNpYWw6IHVuZGVmaW5lZCBvciBCaWdJbnQgb3IgU3ltYm9sXG5cdCAqIFx0b3Igb3RoZXIgbm9uIGNvbnN0cnVjdGlibGUgdHlwZVxuXHQgKi9cblxuXHRjb25zdCB0eXBlcyA9IHZhbHVlSXNQcmltaXRpdmUgPyAncHJpbWl0aXZlcycgOiAoXG5cdFx0aXNPYmplY3QgPyAoXG5cdFx0XHRpc051bGwgPyAnbnVsbGlzaCcgOiAnb2JqZWN0cydcblx0XHQpIDogKFxuXHRcdFx0aXNGdW5jdGlvbiA/ICdmdW5jdGlvbnMnIDogJ3NwZWNpYWwnXG5cdFx0KVxuXHQpO1xuXG5cdGNvbnN0IHJlc29sdmVyID0gY3JlYXRlUmVzb2x2ZXIob3B0aW9ucyk7XG5cblx0Y29uc3QgZGVzY3JpcHRvciA9IChpc09iamVjdCAmJiAodmFsdWUgaW5zdGFuY2VvZiBGaWVsZENvbnN0cnVjdG9yKSkgP1xuXHRcdHZhbHVlIDoge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdC4uLnJlc29sdmVyW3R5cGVzXSh2YWx1ZSwgcmVjZWl2ZXIpLFxuXHRcdH07XG5cblx0Ly8gaWYgKHZhbHVlIGluc3RhbmNlb2YgRmllbGRDb25zdHJ1Y3Rvcikge1xuXHQvLyBcdGRlc2NyaXB0b3I7XG5cdC8vIFx0ZGVidWdnZXI7XG5cdC8vIH1cblxuXHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHJlY2VpdmVyLCBwcm9wTmFtZSwgZGVzY3JpcHRvcik7XG5cdHJldHVybiByZXN1bHQ7XG5cbn07XG5cbi8vIGxpbmUgYmVsb3cgJ2hyZWYnIGlzIGZvciB1dGlsLmluc3BlY3Qgd29ya3MsIHVzZWZ1bCBmb3IgdjI0XG5jb25zdCBwcm9wczJza2lwID0gbmV3IFNldChbXG5cdFN5bWJvbC50b1N0cmluZ1RhZyxcblx0U3ltYm9sLml0ZXJhdG9yLFxuXHQvLyBTeW1ib2wudG9QcmltaXRpdmUsXG5cdCd0b1N0cmluZycsXG5cdCd2YWx1ZU9mJyxcblx0J2hyZWYnXG5dKTtcbi8vIGNvbnN0IHByb3BzMnNraXAgPSBuZXcgU2V0KFtTeW1ib2wudG9TdHJpbmdUYWcsIFN5bWJvbC5pdGVyYXRvcl0pO1xuY29uc3QgaGFzTm9kZUluc3BlY3QgPSAoaW5zcGVjdCAmJiBpbnNwZWN0LmN1c3RvbSk7XG4vLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4oaGFzTm9kZUluc3BlY3QgJiYgKHByb3BzMnNraXAuYWRkKGluc3BlY3QuY3VzdG9tKSkpO1xuXG5jb25zdCBjcmVhdGVIYW5kbGVycyA9IChvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSA9PiAoe1xuXHRnZXQodGFyZ2V0OiBvYmplY3QsIHByb3A6IHN0cmluZyB8IHN5bWJvbCwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuXHRcdGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0aWYgKHByb3AgPT09ICd0b0pTT04nKSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcblx0XHRcdHJldHVybiBmdW5jdGlvbiAodGhpczogdHlwZW9mIHRhcmdldCkge1xuXHRcdFx0XHRjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGhpcyk7XG5cdFx0XHRcdHJldHVybiBKU09OLnN0cmluZ2lmeShlbnRyaWVzLnJlZHVjZSgob2JqLCBba2V5LCB2YWx1ZV0pID0+IHtcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRcdFx0b2JqW2tleV0gPSB2YWx1ZS52YWx1ZU9mKCk7XG5cdFx0XHRcdFx0cmV0dXJuIG9iajtcblx0XHRcdFx0fSwge30pKTtcblx0XHRcdH07XG5cdFx0fVxuXHRcdGlmIChwcm9wID09PSAnY29uc3RydWN0b3InKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRjb25zdCB7IG5hbWUgfSA9IHJlY2VpdmVyLmNvbnN0cnVjdG9yO1xuXHRcdGlmIChwcm9wczJza2lwLmhhcyhwcm9wKSkge1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IGAke25hbWV9IGxhY2tzIGRlZmluaXRpb24gb2YgWyAke1N0cmluZyhwcm9wKS52YWx1ZU9mKCl9IF1gO1xuXHRcdFx0cmV0dXJuIG1lc3NhZ2U7XG5cdFx0fVxuXHRcdC8vIGNvbnN0IGVycm9yTWVzc2FnZSA9IGAke0Vycm9yc05hbWVzLk1JU1NJTkdfUFJPUH06IFsgJHtTdHJpbmcocHJvcCkudmFsdWVPZigpfSBdIGZvciAke25hbWV9YDtcblx0XHQvLyB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcblx0fSxcblx0c2V0KF86IG9iamVjdCwgcHJvcDogc3RyaW5nLCB2YWx1ZTogdW5rbm93biwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IGNyZWF0ZVByb3BlcnR5KHByb3AsIHZhbHVlLCByZWNlaXZlciwgb3B0aW9ucyk7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblx0c2V0UHJvdG90eXBlT2YoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdTZXR0aW5nIHByb3RvdHlwZSBpcyBub3QgYWxsb3dlZCEnKTtcblx0fSxcblx0Ly8gZGVmaW5lUHJvcGVydHkodGFyZ2V0OiBvYmplY3QsIGtleTogc3RyaW5nLCBkZXNjcmlwdG9yOiBvYmplY3QpIHtcblx0ZGVmaW5lUHJvcGVydHkoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdEZWZpbmluZyBuZXcgUHJvcGVydGllcyBpcyBub3QgYWxsb3dlZCEnKTtcblx0XHQvLyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKTtcblx0fSxcblx0ZGVsZXRlUHJvcGVydHkoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdQcm9wZXJ0aWVzIERlbGV0aW9uIGlzIG5vdCBhbGxvd2VkIScpO1xuXHR9LFxuXHQvLyBnZXRQcm90b3R5cGVPZigpIHtcblx0Ly8gXHRkZWJ1Z2dlcjtcblx0Ly8gXHR0aHJvdyBuZXcgRXJyb3IoJ0dldHRpbmcgcHJvdG90eXBlIGlzIG5vdCBhbGxvd2VkJyk7XG5cdC8vIH0sXG59KTtcblxuLy8gdXNlciBoYXZlIHRvIHByZWNpc2VseSBkZWZpbmUgYWxsIHByb3BzXG5leHBvcnQgY29uc3QgYmFzZVRhcmdldCA9IChfcHJvdG8/OiBvYmplY3QpID0+IHtcblx0Y29uc3QgcHJvdG8gPSB0eXBlb2YgX3Byb3RvID09PSAnb2JqZWN0JyA/IF9wcm90byA6IG51bGw7XG5cdGNvbnN0IGFuc3dlciA9IE9iamVjdC5jcmVhdGUocHJvdG8pO1xuXHRyZXR1cm4gYW5zd2VyO1xufTtcblxuZXhwb3J0IGNvbnN0IFN5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UgPSBTeW1ib2woJ1R5cGXDmG1hdGljYVByb3h5UmVmZXJlbmNlJyk7XG5jb25zdCBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlID0gKF90YXJnZXQ6IG9iamVjdCwgb3B0aW9ucz86IFR5cGVvbWF0aWNhT3B0aW9ucykgPT4ge1xuXHRjb25zdCB0YXJnZXQgPSBPYmplY3QuY3JlYXRlKF90YXJnZXQpO1xuXHRjb25zdCBpZCA9IGBUeXBlw5htYXRpY2FQcm94eVJlZmVyZW5jZS0ke01hdGgucmFuZG9tKCl9YDtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSwge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBpZDtcblx0XHR9XG5cdH0pO1xuXHRjb25zdCBoYW5kbGVycyA9IGNyZWF0ZUhhbmRsZXJzKG9wdGlvbnMpO1xuXHRjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0YXJnZXQsIGhhbmRsZXJzKTtcblx0cmV0dXJuIHByb3h5O1xufTtcblxuXG5leHBvcnQgY29uc3QgQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBvYmplY3QsIFMgZXh0ZW5kcyBUPih0aGlzOiBTIGV4dGVuZHMgVCA/IFMgOiB7fSwgX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMgKTogVCB7XG5cdGlmICghbmV3LnRhcmdldCkge1xuXG5cdFx0Y29uc3Qgc2VsZjoge1xuXHRcdFx0cHJvdG90eXBlOiB7XG5cdFx0XHRcdGNvbnN0cnVjdG9yOiB0eXBlb2YgQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlXG5cdFx0XHR9XG5cdFx0XHQvL0B0cy1pZ25vcmVcblx0XHR9ID0gQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlLmJpbmQodGhpcywgX3RhcmdldCwgb3B0aW9ucyk7XG5cblx0XHRzZWxmLnByb3RvdHlwZSA9IHtcblx0XHRcdGNvbnN0cnVjdG9yOiBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGVcblx0XHR9O1xuXG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdHJldHVybiBzZWxmO1xuXG5cdH1cblxuXHQvLyBAdHMtaWdub3JlXG5cdGlmICh0aGlzW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdKSB7XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0Y29uc3QgdGFyZ2V0ID0gYmFzZVRhcmdldChfdGFyZ2V0KSBhcyBvYmplY3Q7XG5cdGNvbnN0IHsgZnJvemVuUHJvdG90eXBlczogZnJlZXplUHJvdG9zID0gdHJ1ZSB9ID0gb3B0aW9ucyB8fCB7fTtcblxuXHRjb25zdCBJbnN0YW5jZVByb3RvdHlwZSA9IGdldFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UodGFyZ2V0LCBvcHRpb25zKTtcblxuXHRjb25zdCBjbGFzc1Byb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSBhcyBvYmplY3Q7XG5cblx0bGV0IHByb3RvO1xuXHRsZXQgcHJvdG9Qb2ludGVyID0gdGhpcyBhcyBvYmplY3Q7XG5cdGxldCBwcm90b0NvbnN0cmN1dG9yO1xuXG5cdGxldCBjb25zdHJ1Y3RvcnMgPSBmYWxzZTtcblxuXHQvLyBAdHMtaWdub3JlXG5cdC8vIGNvbnN0IGhhc1Byb3h5UmVmZXJlbmNlID0gcHJvdG9Qb2ludGVyW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdIGFzIHVua25vd24gYXMgYm9vbGVhbjtcblx0Ly8gaWYgKGhhc1Byb3h5UmVmZXJlbmNlKSB7XG5cdC8vIFx0dGhyb3cgbmV3IEVycm9yKCdNdWx0aXBsZSBUeXBlw5htYXRpY2EgaW5zdGFudGlhdGlvbnMgYXJlIG5vdCBhbGxvd2VkIGZvciB0aGUgc2FtZSBQcm90b3R5cGUgQ2hhaW4hJyk7XG5cdC8vIH1cblxuXHRkbyB7XG5cdFx0cHJvdG8gPSBwcm90b1BvaW50ZXI7XG5cdFx0cHJvdG9Qb2ludGVyID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcblx0XHRpZiAoQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlLnByb3RvdHlwZSA9PT0gcHJvdG9Qb2ludGVyKSB7XG5cdFx0XHRjb25zdHJ1Y3RvcnMgPSB0cnVlO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdGlmICghcHJvdG9Qb2ludGVyKSBicmVhaztcblx0XHRjb25zdCBkZXNjcmlwdG9yID0gUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocHJvdG9Qb2ludGVyLCAnY29uc3RydWN0b3InKTtcblx0XHRpZiAoIWRlc2NyaXB0b3IpIGNvbnRpbnVlO1xuXHRcdGNvbnN0IHZhbHVlID0gZGVzY3JpcHRvci52YWx1ZSB8fCBkZXNjcmlwdG9yLmdldDtcblx0XHQvLyBpZiAoIXZhbHVlKSBjb250aW51ZTtcblx0XHRwcm90b0NvbnN0cmN1dG9yID0gdmFsdWU7XG5cdH0gd2hpbGUgKHByb3RvQ29uc3RyY3V0b3IgIT09IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSk7XG5cblx0aWYgKCFjb25zdHJ1Y3RvcnMgJiYgcHJvdG9Db25zdHJjdXRvciAhPT0gQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gc2V0dXAgVHlwZcOYbWF0aWNhIGhhbmRsZXIhJyk7XG5cdH1cblxuXHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIEluc3RhbmNlUHJvdG90eXBlKTtcblx0aWYgKGZyZWV6ZVByb3Rvcykge1xuXHRcdE9iamVjdC5mcmVlemUoY2xhc3NQcm90b3R5cGUpO1xuXHR9XG5cdC8vIEB0cy1pZ25vcmVcblx0cmV0dXJuIHRoaXM7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG59IGFzIHtcblx0bmV3PFQgZXh0ZW5kcyBvYmplY3QgfCB7fT4oX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpOiBUXG5cdDxUIGV4dGVuZHMgb2JqZWN0IHwge30sIFMgZXh0ZW5kcyBUPihfdGFyZ2V0PzogUyBleHRlbmRzIGluZmVyIEluZmVycmVkUyA/IEluZmVycmVkUyA6IHt9LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKTogU1xufTtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuY29uc3QgZnJlZXplQ2xhc3NQcm90b3R5cGVzID0gKGluc3RhbmNlOiBvYmplY3QsIHNob3VsZEZyZWV6ZTogYm9vbGVhbikgPT4ge1xuXHRpZiAoIXNob3VsZEZyZWV6ZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGNvbnN0IGZpcnN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGluc3RhbmNlKTtcblx0Y29uc3QgZmlyc3RJc1Byb3h5ID0gZmlyc3QgIT09IG51bGwgJiYgISFSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihmaXJzdCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSk7XG5cdGlmIChmaXJzdElzUHJveHkpIHtcblx0XHRPYmplY3QuZnJlZXplKEJhc2VDbGFzcy5wcm90b3R5cGUpO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGxldCBwID0gZmlyc3Q7XG5cdHdoaWxlIChwICE9PSBudWxsICYmIHAgIT09IEJhc2VDbGFzcy5wcm90b3R5cGUgJiYgcCAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuXHRcdGNvbnN0IG5leHQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocCk7XG5cdFx0Y29uc3QgbmV4dElzUHJveHkgPSBuZXh0ICE9PSBudWxsICYmICEhUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobmV4dCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSk7XG5cdFx0T2JqZWN0LmZyZWV6ZShwKTtcblx0XHRpZiAobmV4dElzUHJveHkpIHtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRwID0gbmV4dDtcblx0fVxuXHRPYmplY3QuZnJlZXplKEJhc2VDbGFzcy5wcm90b3R5cGUpO1xufTtcblxuZXhwb3J0IGNsYXNzIEJhc2VDbGFzcyB7XG5cdGNvbnN0cnVjdG9yKF90YXJnZXQ/OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpIHtcblx0XHRjb25zdCB7IGZyb3plblByb3RvdHlwZXM6IGZyZWV6ZVByb3RvcyA9IHRydWUgfSA9IG9wdGlvbnMgfHwge307XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKHRoaXNbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdGZyZWV6ZUNsYXNzUHJvdG90eXBlcyh0aGlzLCBmcmVlemVQcm90b3MpO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgdGFyZ2V0ID0gYmFzZVRhcmdldChfdGFyZ2V0KSBhcyBvYmplY3Q7XG5cdFx0Y29uc3QgcHJveHkgPSBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlKHRhcmdldCwgb3B0aW9ucyk7XG5cdFx0Y29uc3QgaW5zdGFuY2VQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKTtcblxuXHRcdGlmIChpbnN0YW5jZVByb3RvID09PSBCYXNlQ2xhc3MucHJvdG90eXBlKSB7XG5cdFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgcHJveHkpO1xuXHRcdFx0ZnJlZXplQ2xhc3NQcm90b3R5cGVzKHRoaXMsIGZyZWV6ZVByb3Rvcyk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRsZXQgY2xhc3NQcm90byA9IGluc3RhbmNlUHJvdG87XG5cdFx0bGV0IHBhcmVudFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGNsYXNzUHJvdG8pO1xuXHRcdHdoaWxlIChwYXJlbnRQcm90byAhPT0gQmFzZUNsYXNzLnByb3RvdHlwZSAmJiBwYXJlbnRQcm90byAhPT0gbnVsbCkge1xuXHRcdFx0Y2xhc3NQcm90byA9IHBhcmVudFByb3RvO1xuXHRcdFx0cGFyZW50UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY2xhc3NQcm90byk7XG5cdFx0fVxuXG5cdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNsYXNzUHJvdG8sIHByb3h5KTtcblx0XHRmcmVlemVDbGFzc1Byb3RvdHlwZXModGhpcywgZnJlZXplUHJvdG9zKTtcblx0fVxufVxuXG5cbmNvbnN0IHN0cmljdCA9IGZ1bmN0aW9uIChfdGFyZ2V0Pzogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSB7XG5cdGNvbnN0IHsgZnJvemVuUHJvdG90eXBlczogZnJlZXplUHJvdG9zID0gdHJ1ZSB9ID0gb3B0aW9ucyB8fCB7fTtcblxuXHRjb25zdCBkZWNvcmF0b3IgPSBmdW5jdGlvbjxUPihjc3RyOiBUKTogVCB7XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKGNzdHIucHJvdG90eXBlW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdKSB7XG5cdFx0XHRyZXR1cm4gY3N0cjtcblx0XHR9XG5cblx0XHRjb25zdCB0YXJnZXQgPSBiYXNlVGFyZ2V0KF90YXJnZXQpO1xuXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXHRcdGNvbnN0IF9yZXBsYWNlciA9IE9iamVjdC5jcmVhdGUocHJveHkpO1xuXG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgX3JlcGxhY2VyKTtcblx0XHRpZiAoZnJlZXplUHJvdG9zKSB7XG5cdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRPYmplY3QuZnJlZXplKGNzdHIucHJvdG90eXBlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gY3N0cjtcblxuXG5cdFx0Ly8gY29uc3QgTXlDbGFzc1Byb3h5ID0gbmV3IFByb3h5KGNzdHIsIHtcblx0XHQvLyBcdGNvbnN0cnVjdChfLCBhcmd1bWVudHNMaXN0LCBuZXdUYXJnZXQpIHtcblx0XHQvLyBcdFx0ZGVidWdnZXI7XG5cdFx0Ly8gXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCk7XG5cdFx0Ly8gXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQpO1xuXHRcdC8vIFx0XHRjb25zdCBfcmVwbGFjZXIgPSBPYmplY3QuY3JlYXRlKHByb3h5KTtcblxuXHRcdC8vIFx0XHRjb25zdCBfcHJvdG8gPSBjc3RyLnByb3RvdHlwZTtcblxuXHRcdC8vIFx0XHRjb25zdCBwcm90byA9IE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKF9wcm90bykpO1xuXHRcdC8vIFx0XHRwcm90by5pQW1Qcm90byA9IHRydWU7XG5cblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBwcm90byk7XG5cblx0XHQvLyBcdFx0Y29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhfcHJvdG8pO1xuXHRcdC8vIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydGllcyhwcm90bywgZGVzY3JpcHRvcnMpO1xuXG5cdFx0Ly8gXHRcdGNvbnN0IHJlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShfcmVwbGFjZXIpO1xuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIHJlcGxhY2VyKTtcblxuXG5cdFx0Ly8gXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgcHJvdG8pO1xuXHRcdC8vIFx0XHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChjc3RyLCBhcmd1bWVudHNMaXN0LCBuZXdUYXJnZXQpO1xuXG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YoY3N0ci5wcm90b3R5cGUsIF9wcm90byk7XG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXG5cdFx0Ly8gXHRcdHJldHVybiByZXN1bHQ7XG5cdFx0Ly8gXHR9LFxuXHRcdC8vIH0pO1xuXHRcdC8vIHJldHVybiBNeUNsYXNzUHJveHk7XG5cdH07XG5cblx0cmV0dXJuIGRlY29yYXRvcjtcblxufTtcbmV4cG9ydCBjb25zdCB7IFN5bWJvbEluaXRpYWxWYWx1ZSB9ID0gRmllbGRDb25zdHJ1Y3RvcjtcbmNvbnN0IEZpZWxkQ29uc3RydWN0b3JFeHBvcnQgPSBGaWVsZENvbnN0cnVjdG9yO1xuZXhwb3J0IHsgRmllbGRDb25zdHJ1Y3RvckV4cG9ydCBhcyBGaWVsZENvbnN0cnVjdG9yIH07XG5leHBvcnQgY29uc3QgU3RyaWN0ID0gc3RyaWN0O1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gc2V0dXBDb21tb25KUygpIHtcblx0aWYgKHR5cGVvZiBtb2R1bGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgJ2V4cG9ydHMnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZTtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnQmFzZUNsYXNzJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBCYXNlQ2xhc3M7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdGaWVsZENvbnN0cnVjdG9yJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBGaWVsZENvbnN0cnVjdG9yO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnU3ltYm9sSW5pdGlhbFZhbHVlJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBTeW1ib2xJbml0aWFsVmFsdWU7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYmFzZVRhcmdldCcsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gYmFzZVRhcmdldDtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ1N0cmljdCcsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gc3RyaWN0O1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcbn1cblxuc2V0dXBDb21tb25KUygpO1xuXG5PYmplY3QuZnJlZXplKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSk7XG5PYmplY3QuZnJlZXplKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5wcm90b3R5cGUpO1xuIl19 \ No newline at end of file diff --git a/lib/fields.d.ts b/lib/fields.d.ts index 1fceeb5..049a9b8 100644 --- a/lib/fields.d.ts +++ b/lib/fields.d.ts @@ -3,10 +3,10 @@ interface FieldDefinition { [SymbolInitialValue]: unknown; } export declare class FieldConstructor implements FieldDefinition { - [SymbolInitialValue]: unknown; - get get(): () => unknown; - get set(): () => never; - constructor(value: unknown); - static get SymbolInitialValue(): symbol; + [SymbolInitialValue]: unknown; + get get(): () => unknown; + get set(): () => never; + constructor(value: unknown); + static get SymbolInitialValue(): symbol; } export {}; diff --git a/lib/index.d.ts b/lib/index.d.ts index dcf8bc1..4a25d32 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -1,6 +1,7 @@ import { FieldConstructor } from './fields.js'; export interface TypeomaticaOptions { strictAccessCheck?: boolean; + frozenPrototypes?: boolean; } export declare const baseTarget: (_proto?: object) => any; export declare const SymbolTypeomaticaProxyReference: unique symbol; @@ -9,7 +10,7 @@ export declare const BaseConstructorPrototype: { (_target?: S extends infer InferredS ? InferredS : {}, options?: TypeomaticaOptions): S; }; export declare class BaseClass { - constructor(_target?: object, options?: TypeomaticaOptions); + constructor(_target?: object, options?: TypeomaticaOptions); } export declare const SymbolInitialValue: symbol; declare const FieldConstructorExport: typeof FieldConstructor; diff --git a/lib/index.js b/lib/index.js index ea4eec6..fa278ef 100644 --- a/lib/index.js +++ b/lib/index.js @@ -95,6 +95,9 @@ const createHandlers = (options) => ({ }, {})); }; } + if (prop === 'constructor') { + return undefined; + } const { name } = receiver.constructor; if (props2skip.has(prop)) { const message = `${name} lacks definition of [ ${String(prop).valueOf()} ]`; @@ -158,7 +161,9 @@ exports.BaseConstructorPrototype = function (_target, options) { return this; } const target = (0, exports.baseTarget)(_target); + const { frozenPrototypes: freezeProtos = true } = options || {}; const InstancePrototype = getTypeomaticaProxyReference(target, options); + const classPrototype = Object.getPrototypeOf(this); let proto; let protoPointer = this; let protoConstrcutor; @@ -188,42 +193,65 @@ exports.BaseConstructorPrototype = function (_target, options) { throw new Error('Unable to setup TypeØmatica handler!'); } Object.setPrototypeOf(proto, InstancePrototype); + if (freezeProtos) { + Object.freeze(classPrototype); + } // @ts-ignore return this; }; +const freezeClassPrototypes = (instance, shouldFreeze) => { + if (!shouldFreeze) { + return; + } + const first = Object.getPrototypeOf(instance); + const firstIsProxy = first !== null && !!Reflect.getOwnPropertyDescriptor(first, exports.SymbolTypeomaticaProxyReference); + if (firstIsProxy) { + Object.freeze(BaseClass.prototype); + return; + } + let p = first; + while (p !== null && p !== BaseClass.prototype && p !== Object.prototype) { + const next = Object.getPrototypeOf(p); + const nextIsProxy = next !== null && !!Reflect.getOwnPropertyDescriptor(next, exports.SymbolTypeomaticaProxyReference); + Object.freeze(p); + if (nextIsProxy) { + break; + } + p = next; + } + Object.freeze(BaseClass.prototype); +}; class BaseClass { constructor(_target, options) { + const { frozenPrototypes: freezeProtos = true } = options || {}; // @ts-ignore if (this[exports.SymbolTypeomaticaProxyReference]) { + freezeClassPrototypes(this, freezeProtos); return this; } const target = (0, exports.baseTarget)(_target); const proxy = getTypeomaticaProxyReference(target, options); - let proto = this; - let protoPointer; - let found = false; - do { - protoPointer = Object.getPrototypeOf(proto); - // if (protoPointer[SymbolTypeomaticaProxyReference]) { - // throw new Error('Double TypeØmatica extension is not allowed!'); - // } - if (protoPointer === Object.prototype) { - found = true; - break; - } - /* - // it can be, that protoPointer === null - // though too hard to implement this test - */ - proto = protoPointer; - } while (!found); - Object.setPrototypeOf(proto, proxy); + const instanceProto = Object.getPrototypeOf(this); + if (instanceProto === BaseClass.prototype) { + Object.setPrototypeOf(this, proxy); + freezeClassPrototypes(this, freezeProtos); + return this; + } + let classProto = instanceProto; + let parentProto = Object.getPrototypeOf(classProto); + while (parentProto !== BaseClass.prototype && parentProto !== null) { + classProto = parentProto; + parentProto = Object.getPrototypeOf(classProto); + } + Object.setPrototypeOf(classProto, proxy); + freezeClassPrototypes(this, freezeProtos); } } exports.BaseClass = BaseClass; const strict = function (_target, options) { + const { frozenPrototypes: freezeProtos = true } = options || {}; const decorator = function (cstr) { // @ts-ignore if (cstr.prototype[exports.SymbolTypeomaticaProxyReference]) { @@ -234,6 +262,10 @@ const strict = function (_target, options) { const _replacer = Object.create(proxy); // @ts-ignore Object.setPrototypeOf(cstr.prototype, _replacer); + if (freezeProtos) { + // @ts-ignore + Object.freeze(cstr.prototype); + } return cstr; // const MyClassProxy = new Proxy(cstr, { // construct(_, argumentsList, newTarget) { @@ -316,4 +348,4 @@ function setupCommonJS() { setupCommonJS(); Object.freeze(exports.BaseConstructorPrototype); Object.freeze(exports.BaseConstructorPrototype.prototype); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBRTFDLFlBQVksQ0FBQzs7O0FBRWIsK0JBQStCO0FBQy9CLDJDQUEwQztBQUUxQywrQ0FPMEI7QUFFMUIsMkNBQStDO0FBTS9DLE1BQU0sY0FBYyxHQUFHLENBQUMsVUFBOEIsRUFBRSxFQUFFLEVBQUU7SUFDM0QsTUFBTSxFQUFFLGlCQUFpQixHQUFHLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUU5QyxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDckIsVUFBVSxFQUFWLHFCQUFVO1FBQ1YsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsU0FBUyxFQUFULG9CQUFTO0tBQ1QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVcsRUFBRSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsRUFBRSxFQUFFO1FBQzFDLGFBQWE7UUFDYixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsVUFBVSxZQUFvQixFQUFFLFFBQWdCO1lBQzFELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2QyxPQUFPO2dCQUNOLEdBQUc7b0JBQ0YsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO29CQUM1QixJQUFJLGlCQUFpQixJQUFJLGNBQWMsS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDdEQsTUFBTSxJQUFJLGNBQWMsQ0FBQyx1QkFBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUNyRCxDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDN0IsT0FBTyxNQUFNLENBQUM7Z0JBQ2YsQ0FBQztnQkFDRCxHQUFHLENBQUMsZ0JBQXlCO29CQUM1QixNQUFNLGNBQWMsR0FBRyxJQUFJLENB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QUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFO1FBQ25ELEdBQUc7WUFDRixPQUFPLGtCQUFVLENBQUM7UUFDbkIsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUU7UUFDL0MsR0FBRztZQUNGLE9BQU8sTUFBTSxDQUFDO1FBQ2YsQ0FBQztRQUNELFVBQVUsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxhQUFhLEVBQUUsQ0FBQztBQUVoQixNQUFNLENBQUMsTUFBTSxDQUFDLGdDQUF3QixDQUFDLENBQUM7QUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxnQ0FBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIG94bGludC1kaXNhYmxlIHR5cGVzY3JpcHQvbm8tdGhpcy1hbGlhc1xuIFxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBFcnJvcnNOYW1lcyB9IGZyb20gJy4vZXJyb3JzLmpzJztcblxuaW1wb3J0IHtcblx0ZnVuY3Rpb25zLFxuXHRudWxsaXNoLFxuXHRvYmplY3RzLFxuXHRwcmltaXRpdmVzLFxuXHRzcGVjaWFsLFxuXHRpc1ByaW1pdGl2ZVxufSBmcm9tICcuL3R5cGVzL2luZGV4LmpzJztcblxuaW1wb3J0IHsgRmllbGRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmllbGRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUeXBlb21hdGljYU9wdGlvbnMge1xuXHRzdHJpY3RBY2Nlc3NDaGVjaz86IGJvb2xlYW47XG59XG5cbmNvbnN0IGNyZWF0ZVJlc29sdmVyID0gKG9wdGlvbnM6IFR5cGVvbWF0aWNhT3B0aW9ucyA9IHt9KSA9PiB7XG5cdGNvbnN0IHsgc3RyaWN0QWNjZXNzQ2hlY2sgPSBmYWxzZSB9ID0gb3B0aW9ucztcblx0XG5cdHJldHVybiBPYmplY3QuZW50cmllcyh7XG5cdFx0cHJpbWl0aXZlcyxcblx0XHRzcGVjaWFsLFxuXHRcdG51bGxpc2gsXG5cdFx0b2JqZWN0cyxcblx0XHRmdW5jdGlvbnNcblx0fSkucmVkdWNlKChvYmo6IG9iamVjdCwgW2tleSwgX2hhbmRsZXJdKSA9PiB7XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdG9ialtrZXldID0gZnVuY3Rpb24gKGluaXRpYWxWYWx1ZTogb2JqZWN0LCByZWNlaXZlcjogb2JqZWN0KSB7XG5cdFx0XHRjb25zdCBoYW5kbGVyID0gX2hhbmRsZXIoaW5pdGlhbFZhbHVlKTtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGdldCgpIHtcblx0XHRcdFx0XHRjb25zdCBpbnZvY2F0aW9uVGhpcyA9IHRoaXM7XG5cdFx0XHRcdFx0aWYgKHN0cmljdEFjY2Vzc0NoZWNrICYmIGludm9jYXRpb25UaGlzICE9PSByZWNlaXZlcikge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKEVycm9yc05hbWVzLkFDQ0VTU19ERU5JRUQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCByZXN1bHQgPSBoYW5kbGVyLmdldCgpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNldChyZXBsYWNlbWVudFZhbHVlOiB1bmtub3duKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW52b2NhdGlvblRoaXMgPSB0aGlzO1xuXHRcdFx0XHRcdGlmIChzdHJpY3RBY2Nlc3NDaGVjayAmJiBpbnZvY2F0aW9uVGhpcyAhPT0gcmVjZWl2ZXIpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihFcnJvcnNOYW1lcy5BQ0NFU1NfREVOSUVEKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gaGFuZGxlci5zZXQocmVwbGFjZW1lbnRWYWx1ZSk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9O1xuXG5cdFx0cmV0dXJuIG9iajtcblx0fSwge30pO1xufTtcblxuY29uc3QgY3JlYXRlUHJvcGVydHkgPSAocHJvcE5hbWU6IHN0cmluZywgaW5pdGlhbFZhbHVlOiB1bmtub3duLCByZWNlaXZlcjogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSA9PiB7XG5cblx0Y29uc3QgdmFsdWUgPSBpbml0aWFsVmFsdWU7XG5cdGNvbnN0IHZhbHVlSXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZShpbml0aWFsVmFsdWUpO1xuXHRjb25zdCBpc09iamVjdCA9IHR5cGVvZiBpbml0aWFsVmFsdWUgPT09ICdvYmplY3QnO1xuXHRjb25zdCBpc0Z1bmN0aW9uID0gaW5pdGlhbFZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb247XG5cdGNvbnN0IGlzTnVsbCA9IGluaXRpYWxWYWx1ZSA9PT0gbnVsbDtcblxuXHQvKipcblx0ICogc3BlY2lhbDogdW5kZWZpbmVkIG9yIEJpZ0ludCBvciBTeW1ib2xcblx0ICogXHRvciBvdGhlciBub24gY29uc3RydWN0aWJsZSB0eXBlXG5cdCAqL1xuXG5cdGNvbnN0IHR5cGVzID0gdmFsdWVJc1ByaW1pdGl2ZSA/ICdwcmltaXRpdmVzJyA6IChcblx0XHRpc09iamVjdCA/IChcblx0XHRcdGlzTnVsbCA/ICdudWxsaXNoJyA6ICdvYmplY3RzJ1xuXHRcdCkgOiAoXG5cdFx0XHRpc0Z1bmN0aW9uID8gJ2Z1bmN0aW9ucycgOiAnc3BlY2lhbCdcblx0XHQpXG5cdCk7XG5cblx0Y29uc3QgcmVzb2x2ZXIgPSBjcmVhdGVSZXNvbHZlcihvcHRpb25zKTtcblxuXHRjb25zdCBkZXNjcmlwdG9yID0gKGlzT2JqZWN0ICYmICh2YWx1ZSBpbnN0YW5jZW9mIEZpZWxkQ29uc3RydWN0b3IpKSA/XG5cdFx0dmFsdWUgOiB7XG5cdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdFx0Li4ucmVzb2x2ZXJbdHlwZXNdKHZhbHVlLCByZWNlaXZlciksXG5cdFx0fTtcblxuXHQvLyBpZiAodmFsdWUgaW5zdGFuY2VvZiBGaWVsZENvbnN0cnVjdG9yKSB7XG5cdC8vIFx0ZGVzY3JpcHRvcjtcblx0Ly8gXHRkZWJ1Z2dlcjtcblx0Ly8gfVxuXG5cdGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZGVmaW5lUHJvcGVydHkocmVjZWl2ZXIsIHByb3BOYW1lLCBkZXNjcmlwdG9yKTtcblx0cmV0dXJuIHJlc3VsdDtcblxufTtcblxuLy8gbGluZSBiZWxvdyAnaHJlZicgaXMgZm9yIHV0aWwuaW5zcGVjdCB3b3JrcywgdXNlZnVsIGZvciB2MjRcbmNvbnN0IHByb3BzMnNraXAgPSBuZXcgU2V0KFtcblx0U3ltYm9sLnRvU3RyaW5nVGFnLFxuXHRTeW1ib2wuaXRlcmF0b3IsXG5cdC8vIFN5bWJvbC50b1ByaW1pdGl2ZSxcblx0J3RvU3RyaW5nJyxcblx0J3ZhbHVlT2YnLFxuXHQnaHJlZidcbl0pO1xuLy8gY29uc3QgcHJvcHMyc2tpcCA9IG5ldyBTZXQoW1N5bWJvbC50b1N0cmluZ1RhZywgU3ltYm9sLml0ZXJhdG9yXSk7XG5jb25zdCBoYXNOb2RlSW5zcGVjdCA9IChpbnNwZWN0ICYmIGluc3BlY3QuY3VzdG9tKTtcbi8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbihoYXNOb2RlSW5zcGVjdCAmJiAocHJvcHMyc2tpcC5hZGQoaW5zcGVjdC5jdXN0b20pKSk7XG5cbmNvbnN0IGNyZWF0ZUhhbmRsZXJzID0gKG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpID0+ICh7XG5cdGdldCh0YXJnZXQ6IG9iamVjdCwgcHJvcDogc3RyaW5nIHwgc3ltYm9sLCByZWNlaXZlcjogb2JqZWN0KSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG5cdFx0aWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblx0XHRpZiAocHJvcCA9PT0gJ3RvSlNPTicpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uICh0aGlzOiB0eXBlb2YgdGFyZ2V0KSB7XG5cdFx0XHRcdGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyh0aGlzKTtcblx0XHRcdFx0cmV0dXJuIEpTT04uc3RyaW5naWZ5KGVudHJpZXMucmVkdWNlKChvYmosIFtrZXksIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdFx0XHRvYmpba2V5XSA9IHZhbHVlLnZhbHVlT2YoKTtcblx0XHRcdFx0XHRyZXR1cm4gb2JqO1xuXHRcdFx0XHR9LCB7fSkpO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0Y29uc3QgeyBuYW1lIH0gPSByZWNlaXZlci5jb25zdHJ1Y3Rvcjtcblx0XHRpZiAocHJvcHMyc2tpcC5oYXMocHJvcCkpIHtcblx0XHRcdGNvbnN0IG1lc3NhZ2UgPSBgJHtuYW1lfSBsYWNrcyBkZWZpbml0aW9uIG9mIFsgJHtTdHJpbmcocHJvcCkudmFsdWVPZigpfSBdYDtcblx0XHRcdHJldHVybiBtZXNzYWdlO1xuXHRcdH1cblx0XHQvLyBjb25zdCBlcnJvck1lc3NhZ2UgPSBgJHtFcnJvcnNOYW1lcy5NSVNTSU5HX1BST1B9OiBbICR7U3RyaW5nKHByb3ApLnZhbHVlT2YoKX0gXSBmb3IgJHtuYW1lfWA7XG5cdFx0Ly8gdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG5cdH0sXG5cdHNldChfOiBvYmplY3QsIHByb3A6IHN0cmluZywgdmFsdWU6IHVua25vd24sIHJlY2VpdmVyOiBvYmplY3QpIHtcblx0XHRjb25zdCByZXN1bHQgPSBjcmVhdGVQcm9wZXJ0eShwcm9wLCB2YWx1ZSwgcmVjZWl2ZXIsIG9wdGlvbnMpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH0sXG5cdHNldFByb3RvdHlwZU9mKCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignU2V0dGluZyBwcm90b3R5cGUgaXMgbm90IGFsbG93ZWQhJyk7XG5cdH0sXG5cdC8vIGRlZmluZVByb3BlcnR5KHRhcmdldDogb2JqZWN0LCBrZXk6IHN0cmluZywgZGVzY3JpcHRvcjogb2JqZWN0KSB7XG5cdGRlZmluZVByb3BlcnR5KCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignRGVmaW5pbmcgbmV3IFByb3BlcnRpZXMgaXMgbm90IGFsbG93ZWQhJyk7XG5cdFx0Ly8gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcik7XG5cdH0sXG5cdGRlbGV0ZVByb3BlcnR5KCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignUHJvcGVydGllcyBEZWxldGlvbiBpcyBub3QgYWxsb3dlZCEnKTtcblx0fSxcblx0Ly8gZ2V0UHJvdG90eXBlT2YoKSB7XG5cdC8vIFx0ZGVidWdnZXI7XG5cdC8vIFx0dGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIHByb3RvdHlwZSBpcyBub3QgYWxsb3dlZCcpO1xuXHQvLyB9LFxufSk7XG5cbi8vIHVzZXIgaGF2ZSB0byBwcmVjaXNlbHkgZGVmaW5lIGFsbCBwcm9wc1xuZXhwb3J0IGNvbnN0IGJhc2VUYXJnZXQgPSAoX3Byb3RvPzogb2JqZWN0KSA9PiB7XG5cdGNvbnN0IHByb3RvID0gdHlwZW9mIF9wcm90byA9PT0gJ29iamVjdCcgPyBfcHJvdG8gOiBudWxsO1xuXHRjb25zdCBhbnN3ZXIgPSBPYmplY3QuY3JlYXRlKHByb3RvKTtcblx0cmV0dXJuIGFuc3dlcjtcbn07XG5cbmV4cG9ydCBjb25zdCBTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlID0gU3ltYm9sKCdUeXBlw5htYXRpY2FQcm94eVJlZmVyZW5jZScpO1xuY29uc3QgZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSA9IChfdGFyZ2V0OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpID0+IHtcblx0Y29uc3QgdGFyZ2V0ID0gT2JqZWN0LmNyZWF0ZShfdGFyZ2V0KTtcblx0Y29uc3QgaWQgPSBgVHlwZcOYbWF0aWNhUHJveHlSZWZlcmVuY2UtJHtNYXRoLnJhbmRvbSgpfWA7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIFN5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gaWQ7XG5cdFx0fVxuXHR9KTtcblx0Y29uc3QgaGFuZGxlcnMgPSBjcmVhdGVIYW5kbGVycyhvcHRpb25zKTtcblx0Y29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVycyk7XG5cdHJldHVybiBwcm94eTtcbn07XG5cblxuZXhwb3J0IGNvbnN0IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSA9IGZ1bmN0aW9uIDxUIGV4dGVuZHMgb2JqZWN0LCBTIGV4dGVuZHMgVD4odGhpczogUyBleHRlbmRzIFQgPyBTIDoge30sIF90YXJnZXQ/OiBULCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zICk6IFQge1xuXHRpZiAoIW5ldy50YXJnZXQpIHtcblxuXHRcdGNvbnN0IHNlbGY6IHtcblx0XHRcdHByb3RvdHlwZToge1xuXHRcdFx0XHRjb25zdHJ1Y3RvcjogdHlwZW9mIEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZVxuXHRcdFx0fVxuXHRcdFx0Ly9AdHMtaWdub3JlXG5cdFx0fSA9IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5iaW5kKHRoaXMsIF90YXJnZXQsIG9wdGlvbnMpO1xuXG5cdFx0c2VsZi5wcm90b3R5cGUgPSB7XG5cdFx0XHRjb25zdHJ1Y3RvcjogQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlXG5cdFx0fTtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRyZXR1cm4gc2VsZjtcblxuXHR9XG5cblx0Ly8gQHRzLWlnbm9yZVxuXHRpZiAodGhpc1tTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSkge1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCkgYXMgb2JqZWN0O1xuXG5cdGNvbnN0IEluc3RhbmNlUHJvdG90eXBlID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXG5cdGxldCBwcm90bztcblx0bGV0IHByb3RvUG9pbnRlciA9IHRoaXMgYXMgb2JqZWN0O1xuXHRsZXQgcHJvdG9Db25zdHJjdXRvcjtcblxuXHRsZXQgY29uc3RydWN0b3JzID0gZmFsc2U7XG5cblx0Ly8gQHRzLWlnbm9yZVxuXHQvLyBjb25zdCBoYXNQcm94eVJlZmVyZW5jZSA9IHByb3RvUG9pbnRlcltTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSBhcyB1bmtub3duIGFzIGJvb2xlYW47XG5cdC8vIGlmIChoYXNQcm94eVJlZmVyZW5jZSkge1xuXHQvLyBcdHRocm93IG5ldyBFcnJvcignTXVsdGlwbGUgVHlwZcOYbWF0aWNhIGluc3RhbnRpYXRpb25zIGFyZSBub3QgYWxsb3dlZCBmb3IgdGhlIHNhbWUgUHJvdG90eXBlIENoYWluIScpO1xuXHQvLyB9XG5cblx0ZG8ge1xuXHRcdHByb3RvID0gcHJvdG9Qb2ludGVyO1xuXHRcdHByb3RvUG9pbnRlciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cdFx0aWYgKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5wcm90b3R5cGUgPT09IHByb3RvUG9pbnRlcikge1xuXHRcdFx0Y29uc3RydWN0b3JzID0gdHJ1ZTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRpZiAoIXByb3RvUG9pbnRlcikgYnJlYWs7XG5cdFx0Y29uc3QgZGVzY3JpcHRvciA9IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvUG9pbnRlciwgJ2NvbnN0cnVjdG9yJyk7XG5cdFx0aWYgKCFkZXNjcmlwdG9yKSBjb250aW51ZTtcblx0XHRjb25zdCB2YWx1ZSA9IGRlc2NyaXB0b3IudmFsdWUgfHwgZGVzY3JpcHRvci5nZXQ7XG5cdFx0Ly8gaWYgKCF2YWx1ZSkgY29udGludWU7XG5cdFx0cHJvdG9Db25zdHJjdXRvciA9IHZhbHVlO1xuXHR9IHdoaWxlIChwcm90b0NvbnN0cmN1dG9yICE9PSBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUpO1xuXG5cdGlmICghY29uc3RydWN0b3JzICYmIHByb3RvQ29uc3RyY3V0b3IgIT09IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSkge1xuXHRcdHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIHNldHVwIFR5cGXDmG1hdGljYSBoYW5kbGVyIScpO1xuXHR9XG5cblx0T2JqZWN0LnNldFByb3RvdHlwZU9mKHByb3RvLCBJbnN0YW5jZVByb3RvdHlwZSk7XG5cdC8vIEB0cy1pZ25vcmVcblx0cmV0dXJuIHRoaXM7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG59IGFzIHtcblx0bmV3PFQgZXh0ZW5kcyBvYmplY3QgfCB7fT4oX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpOiBUXG5cdDxUIGV4dGVuZHMgb2JqZWN0IHwge30sIFMgZXh0ZW5kcyBUPihfdGFyZ2V0PzogUyBleHRlbmRzIGluZmVyIEluZmVycmVkUyA/IEluZmVycmVkUyA6IHt9LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKTogU1xufTtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuZXhwb3J0IGNsYXNzIEJhc2VDbGFzcyB7XG5cdGNvbnN0cnVjdG9yKF90YXJnZXQ/OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpIHtcblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKHRoaXNbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCkgYXMgb2JqZWN0O1xuXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXHRcdGxldCBwcm90bzogb2JqZWN0IHwgbnVsbCA9IHRoaXM7XG5cdFx0bGV0IHByb3RvUG9pbnRlcjogb2JqZWN0IHwgbnVsbDtcblx0XHRsZXQgZm91bmQ6IGJvb2xlYW4gPSBmYWxzZTtcblx0XHRkbyB7XG5cdFx0XHRwcm90b1BvaW50ZXIgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXHRcdFx0Ly8gaWYgKHByb3RvUG9pbnRlcltTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlXSkge1xuXHRcdFx0Ly8gXHR0aHJvdyBuZXcgRXJyb3IoJ0RvdWJsZSBUeXBlw5htYXRpY2EgZXh0ZW5zaW9uIGlzIG5vdCBhbGxvd2VkIScpO1xuXHRcdFx0Ly8gfVxuXHRcdFx0aWYgKHByb3RvUG9pbnRlciA9PT0gT2JqZWN0LnByb3RvdHlwZSkge1xuXHRcdFx0XHRmb3VuZCA9IHRydWU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Lypcblx0XHRcdC8vIGl0IGNhbiBiZSwgdGhhdCBwcm90b1BvaW50ZXIgPT09IG51bGxcblx0XHRcdC8vIHRob3VnaCB0b28gaGFyZCB0byBpbXBsZW1lbnQgdGhpcyB0ZXN0XG5cdFx0XHQqL1xuXHRcdFx0cHJvdG8gPSBwcm90b1BvaW50ZXI7XG5cdFx0fSB3aGlsZSAoIWZvdW5kKTtcblx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIHByb3h5KTtcblx0fVxufVxuXG5cbmNvbnN0IHN0cmljdCA9IGZ1bmN0aW9uIChfdGFyZ2V0Pzogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSB7XG5cdGNvbnN0IGRlY29yYXRvciA9IGZ1bmN0aW9uPFQ+KGNzdHI6IFQpOiBUIHtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRpZiAoY3N0ci5wcm90b3R5cGVbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdHJldHVybiBjc3RyO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCk7XG5cdFx0Y29uc3QgcHJveHkgPSBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlKHRhcmdldCwgb3B0aW9ucyk7XG5cdFx0Y29uc3QgX3JlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShwcm94eSk7XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBfcmVwbGFjZXIpO1xuXG5cdFx0cmV0dXJuIGNzdHI7XG5cblxuXHRcdC8vIGNvbnN0IE15Q2xhc3NQcm94eSA9IG5ldyBQcm94eShjc3RyLCB7XG5cdFx0Ly8gXHRjb25zdHJ1Y3QoXywgYXJndW1lbnRzTGlzdCwgbmV3VGFyZ2V0KSB7XG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXHRcdC8vIFx0XHRjb25zdCB0YXJnZXQgPSBiYXNlVGFyZ2V0KF90YXJnZXQpO1xuXHRcdC8vIFx0XHRjb25zdCBwcm94eSA9IGdldFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UodGFyZ2V0KTtcblx0XHQvLyBcdFx0Y29uc3QgX3JlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShwcm94eSk7XG5cblx0XHQvLyBcdFx0Y29uc3QgX3Byb3RvID0gY3N0ci5wcm90b3R5cGU7XG5cblx0XHQvLyBcdFx0Y29uc3QgcHJvdG8gPSBPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZihfcHJvdG8pKTtcblx0XHQvLyBcdFx0cHJvdG8uaUFtUHJvdG8gPSB0cnVlO1xuXG5cdFx0Ly8gXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgcHJvdG8pO1xuXG5cdFx0Ly8gXHRcdGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoX3Byb3RvKTtcblx0XHQvLyBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMocHJvdG8sIGRlc2NyaXB0b3JzKTtcblxuXHRcdC8vIFx0XHRjb25zdCByZXBsYWNlciA9IE9iamVjdC5jcmVhdGUoX3JlcGxhY2VyKTtcblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKHByb3RvLCByZXBsYWNlcik7XG5cblxuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YoY3N0ci5wcm90b3R5cGUsIHByb3RvKTtcblx0XHQvLyBcdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoY3N0ciwgYXJndW1lbnRzTGlzdCwgbmV3VGFyZ2V0KTtcblxuXHRcdC8vIFx0XHRkZWJ1Z2dlcjtcblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBfcHJvdG8pO1xuXHRcdC8vIFx0XHRkZWJ1Z2dlcjtcblxuXHRcdC8vIFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdC8vIFx0fSxcblx0XHQvLyB9KTtcblx0XHQvLyByZXR1cm4gTXlDbGFzc1Byb3h5O1xuXHR9O1xuXG5cdHJldHVybiBkZWNvcmF0b3I7XG5cbn07XG5leHBvcnQgY29uc3QgeyBTeW1ib2xJbml0aWFsVmFsdWUgfSA9IEZpZWxkQ29uc3RydWN0b3I7XG5jb25zdCBGaWVsZENvbnN0cnVjdG9yRXhwb3J0ID0gRmllbGRDb25zdHJ1Y3RvcjtcbmV4cG9ydCB7IEZpZWxkQ29uc3RydWN0b3JFeHBvcnQgYXMgRmllbGRDb25zdHJ1Y3RvciB9O1xuZXhwb3J0IGNvbnN0IFN0cmljdCA9IHN0cmljdDtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIHNldHVwQ29tbW9uSlMoKSB7XG5cdGlmICh0eXBlb2YgbW9kdWxlID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUsICdleHBvcnRzJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGU7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ0Jhc2VDbGFzcycsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gQmFzZUNsYXNzO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnRmllbGRDb25zdHJ1Y3RvcicsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gRmllbGRDb25zdHJ1Y3Rvcjtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ1N5bWJvbEluaXRpYWxWYWx1ZScsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gU3ltYm9sSW5pdGlhbFZhbHVlO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZScsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZTtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ2Jhc2VUYXJnZXQnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIGJhc2VUYXJnZXQ7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdTdHJpY3QnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIHN0cmljdDtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG59XG5cbnNldHVwQ29tbW9uSlMoKTtcblxuT2JqZWN0LmZyZWV6ZShCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUpO1xuT2JqZWN0LmZyZWV6ZShCYXNlQ29uc3RydWN0b3JQcm90b3R5cGUucHJvdG90eXBlKTtcbiJdfQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBRTFDLFlBQVksQ0FBQzs7O0FBRWIsK0JBQStCO0FBQy9CLDJDQUEwQztBQUUxQywrQ0FPMEI7QUFFMUIsMkNBQStDO0FBTy9DLE1BQU0sY0FBYyxHQUFHLENBQUMsVUFBOEIsRUFBRSxFQUFFLEVBQUU7SUFDM0QsTUFBTSxFQUFFLGlCQUFpQixHQUFHLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUU5QyxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDckIsVUFBVSxFQUFWLHFCQUFVO1FBQ1YsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsT0FBTyxFQUFQLGtCQUFPO1FBQ1AsU0FBUyxFQUFULG9CQUFTO0tBQ1QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVcsRUFBRSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsRUFBRSxFQUFFO1FBQzFDLGFBQWE7UUFDYixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsVUFBVSxZQUFvQixFQUFFLFFBQWdCO1lBQzFELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2QyxPQUFPO2dCQUNOLEdBQUc7b0JBQ0YsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO29CQUM1QixJQUFJLGlCQUFpQixJQUFJLGNBQWMsS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDdEQsTUFBTSxJQUFJLGNBQWMsQ0FBQyx1QkFBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUNyRCxDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDN0IsT0FBTyxNQUFNLENBQUM7Z0JBQ2YsQ0FBQztnQkFDRCxHQUFHLENBQUMsZ0JBQXlCO29CQUM1QixNQUFNLGNBQWMsR0FBRyxJQUFJLENB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QUMsQ0FBQztBQUNKLENBQUM7QUFFRCxhQUFhLEVBQUUsQ0FBQztBQUVoQixNQUFNLENBQUMsTUFBTSxDQUFDLGdDQUF3QixDQUFDLENBQUM7QUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxnQ0FBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIG94bGludC1kaXNhYmxlIHR5cGVzY3JpcHQvbm8tdGhpcy1hbGlhc1xuIFxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBFcnJvcnNOYW1lcyB9IGZyb20gJy4vZXJyb3JzLmpzJztcblxuaW1wb3J0IHtcblx0ZnVuY3Rpb25zLFxuXHRudWxsaXNoLFxuXHRvYmplY3RzLFxuXHRwcmltaXRpdmVzLFxuXHRzcGVjaWFsLFxuXHRpc1ByaW1pdGl2ZVxufSBmcm9tICcuL3R5cGVzL2luZGV4LmpzJztcblxuaW1wb3J0IHsgRmllbGRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmllbGRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUeXBlb21hdGljYU9wdGlvbnMge1xuXHRzdHJpY3RBY2Nlc3NDaGVjaz86IGJvb2xlYW47XG5cdGZyb3plblByb3RvdHlwZXM/OiBib29sZWFuO1xufVxuXG5jb25zdCBjcmVhdGVSZXNvbHZlciA9IChvcHRpb25zOiBUeXBlb21hdGljYU9wdGlvbnMgPSB7fSkgPT4ge1xuXHRjb25zdCB7IHN0cmljdEFjY2Vzc0NoZWNrID0gZmFsc2UgfSA9IG9wdGlvbnM7XG5cdFxuXHRyZXR1cm4gT2JqZWN0LmVudHJpZXMoe1xuXHRcdHByaW1pdGl2ZXMsXG5cdFx0c3BlY2lhbCxcblx0XHRudWxsaXNoLFxuXHRcdG9iamVjdHMsXG5cdFx0ZnVuY3Rpb25zXG5cdH0pLnJlZHVjZSgob2JqOiBvYmplY3QsIFtrZXksIF9oYW5kbGVyXSkgPT4ge1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRvYmpba2V5XSA9IGZ1bmN0aW9uIChpbml0aWFsVmFsdWU6IG9iamVjdCwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdFx0Y29uc3QgaGFuZGxlciA9IF9oYW5kbGVyKGluaXRpYWxWYWx1ZSk7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRnZXQoKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW52b2NhdGlvblRoaXMgPSB0aGlzO1xuXHRcdFx0XHRcdGlmIChzdHJpY3RBY2Nlc3NDaGVjayAmJiBpbnZvY2F0aW9uVGhpcyAhPT0gcmVjZWl2ZXIpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihFcnJvcnNOYW1lcy5BQ0NFU1NfREVOSUVEKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gaGFuZGxlci5nZXQoKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZXQocmVwbGFjZW1lbnRWYWx1ZTogdW5rbm93bikge1xuXHRcdFx0XHRcdGNvbnN0IGludm9jYXRpb25UaGlzID0gdGhpcztcblx0XHRcdFx0XHRpZiAoc3RyaWN0QWNjZXNzQ2hlY2sgJiYgaW52b2NhdGlvblRoaXMgIT09IHJlY2VpdmVyKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoRXJyb3JzTmFtZXMuQUNDRVNTX0RFTklFRCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGhhbmRsZXIuc2V0KHJlcGxhY2VtZW50VmFsdWUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fTtcblxuXHRcdHJldHVybiBvYmo7XG5cdH0sIHt9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVByb3BlcnR5ID0gKHByb3BOYW1lOiBzdHJpbmcsIGluaXRpYWxWYWx1ZTogdW5rbm93biwgcmVjZWl2ZXI6IG9iamVjdCwgb3B0aW9ucz86IFR5cGVvbWF0aWNhT3B0aW9ucykgPT4ge1xuXG5cdGNvbnN0IHZhbHVlID0gaW5pdGlhbFZhbHVlO1xuXHRjb25zdCB2YWx1ZUlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmUoaW5pdGlhbFZhbHVlKTtcblx0Y29uc3QgaXNPYmplY3QgPSB0eXBlb2YgaW5pdGlhbFZhbHVlID09PSAnb2JqZWN0Jztcblx0Y29uc3QgaXNGdW5jdGlvbiA9IGluaXRpYWxWYWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uO1xuXHRjb25zdCBpc051bGwgPSBpbml0aWFsVmFsdWUgPT09IG51bGw7XG5cblx0LyoqXG5cdCAqIHNwZWNpYWw6IHVuZGVmaW5lZCBvciBCaWdJbnQgb3IgU3ltYm9sXG5cdCAqIFx0b3Igb3RoZXIgbm9uIGNvbnN0cnVjdGlibGUgdHlwZVxuXHQgKi9cblxuXHRjb25zdCB0eXBlcyA9IHZhbHVlSXNQcmltaXRpdmUgPyAncHJpbWl0aXZlcycgOiAoXG5cdFx0aXNPYmplY3QgPyAoXG5cdFx0XHRpc051bGwgPyAnbnVsbGlzaCcgOiAnb2JqZWN0cydcblx0XHQpIDogKFxuXHRcdFx0aXNGdW5jdGlvbiA/ICdmdW5jdGlvbnMnIDogJ3NwZWNpYWwnXG5cdFx0KVxuXHQpO1xuXG5cdGNvbnN0IHJlc29sdmVyID0gY3JlYXRlUmVzb2x2ZXIob3B0aW9ucyk7XG5cblx0Y29uc3QgZGVzY3JpcHRvciA9IChpc09iamVjdCAmJiAodmFsdWUgaW5zdGFuY2VvZiBGaWVsZENvbnN0cnVjdG9yKSkgP1xuXHRcdHZhbHVlIDoge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdC4uLnJlc29sdmVyW3R5cGVzXSh2YWx1ZSwgcmVjZWl2ZXIpLFxuXHRcdH07XG5cblx0Ly8gaWYgKHZhbHVlIGluc3RhbmNlb2YgRmllbGRDb25zdHJ1Y3Rvcikge1xuXHQvLyBcdGRlc2NyaXB0b3I7XG5cdC8vIFx0ZGVidWdnZXI7XG5cdC8vIH1cblxuXHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHJlY2VpdmVyLCBwcm9wTmFtZSwgZGVzY3JpcHRvcik7XG5cdHJldHVybiByZXN1bHQ7XG5cbn07XG5cbi8vIGxpbmUgYmVsb3cgJ2hyZWYnIGlzIGZvciB1dGlsLmluc3BlY3Qgd29ya3MsIHVzZWZ1bCBmb3IgdjI0XG5jb25zdCBwcm9wczJza2lwID0gbmV3IFNldChbXG5cdFN5bWJvbC50b1N0cmluZ1RhZyxcblx0U3ltYm9sLml0ZXJhdG9yLFxuXHQvLyBTeW1ib2wudG9QcmltaXRpdmUsXG5cdCd0b1N0cmluZycsXG5cdCd2YWx1ZU9mJyxcblx0J2hyZWYnXG5dKTtcbi8vIGNvbnN0IHByb3BzMnNraXAgPSBuZXcgU2V0KFtTeW1ib2wudG9TdHJpbmdUYWcsIFN5bWJvbC5pdGVyYXRvcl0pO1xuY29uc3QgaGFzTm9kZUluc3BlY3QgPSAoaW5zcGVjdCAmJiBpbnNwZWN0LmN1c3RvbSk7XG4vLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4oaGFzTm9kZUluc3BlY3QgJiYgKHByb3BzMnNraXAuYWRkKGluc3BlY3QuY3VzdG9tKSkpO1xuXG5jb25zdCBjcmVhdGVIYW5kbGVycyA9IChvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSA9PiAoe1xuXHRnZXQodGFyZ2V0OiBvYmplY3QsIHByb3A6IHN0cmluZyB8IHN5bWJvbCwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuXHRcdGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0aWYgKHByb3AgPT09ICd0b0pTT04nKSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcblx0XHRcdHJldHVybiBmdW5jdGlvbiAodGhpczogdHlwZW9mIHRhcmdldCkge1xuXHRcdFx0XHRjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGhpcyk7XG5cdFx0XHRcdHJldHVybiBKU09OLnN0cmluZ2lmeShlbnRyaWVzLnJlZHVjZSgob2JqLCBba2V5LCB2YWx1ZV0pID0+IHtcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRcdFx0b2JqW2tleV0gPSB2YWx1ZS52YWx1ZU9mKCk7XG5cdFx0XHRcdFx0cmV0dXJuIG9iajtcblx0XHRcdFx0fSwge30pKTtcblx0XHRcdH07XG5cdFx0fVxuXHRcdGlmIChwcm9wID09PSAnY29uc3RydWN0b3InKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRjb25zdCB7IG5hbWUgfSA9IHJlY2VpdmVyLmNvbnN0cnVjdG9yO1xuXHRcdGlmIChwcm9wczJza2lwLmhhcyhwcm9wKSkge1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IGAke25hbWV9IGxhY2tzIGRlZmluaXRpb24gb2YgWyAke1N0cmluZyhwcm9wKS52YWx1ZU9mKCl9IF1gO1xuXHRcdFx0cmV0dXJuIG1lc3NhZ2U7XG5cdFx0fVxuXHRcdC8vIGNvbnN0IGVycm9yTWVzc2FnZSA9IGAke0Vycm9yc05hbWVzLk1JU1NJTkdfUFJPUH06IFsgJHtTdHJpbmcocHJvcCkudmFsdWVPZigpfSBdIGZvciAke25hbWV9YDtcblx0XHQvLyB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcblx0fSxcblx0c2V0KF86IG9iamVjdCwgcHJvcDogc3RyaW5nLCB2YWx1ZTogdW5rbm93biwgcmVjZWl2ZXI6IG9iamVjdCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IGNyZWF0ZVByb3BlcnR5KHByb3AsIHZhbHVlLCByZWNlaXZlciwgb3B0aW9ucyk7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblx0c2V0UHJvdG90eXBlT2YoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdTZXR0aW5nIHByb3RvdHlwZSBpcyBub3QgYWxsb3dlZCEnKTtcblx0fSxcblx0Ly8gZGVmaW5lUHJvcGVydHkodGFyZ2V0OiBvYmplY3QsIGtleTogc3RyaW5nLCBkZXNjcmlwdG9yOiBvYmplY3QpIHtcblx0ZGVmaW5lUHJvcGVydHkoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdEZWZpbmluZyBuZXcgUHJvcGVydGllcyBpcyBub3QgYWxsb3dlZCEnKTtcblx0XHQvLyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKTtcblx0fSxcblx0ZGVsZXRlUHJvcGVydHkoKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdQcm9wZXJ0aWVzIERlbGV0aW9uIGlzIG5vdCBhbGxvd2VkIScpO1xuXHR9LFxuXHQvLyBnZXRQcm90b3R5cGVPZigpIHtcblx0Ly8gXHRkZWJ1Z2dlcjtcblx0Ly8gXHR0aHJvdyBuZXcgRXJyb3IoJ0dldHRpbmcgcHJvdG90eXBlIGlzIG5vdCBhbGxvd2VkJyk7XG5cdC8vIH0sXG59KTtcblxuLy8gdXNlciBoYXZlIHRvIHByZWNpc2VseSBkZWZpbmUgYWxsIHByb3BzXG5leHBvcnQgY29uc3QgYmFzZVRhcmdldCA9IChfcHJvdG8/OiBvYmplY3QpID0+IHtcblx0Y29uc3QgcHJvdG8gPSB0eXBlb2YgX3Byb3RvID09PSAnb2JqZWN0JyA/IF9wcm90byA6IG51bGw7XG5cdGNvbnN0IGFuc3dlciA9IE9iamVjdC5jcmVhdGUocHJvdG8pO1xuXHRyZXR1cm4gYW5zd2VyO1xufTtcblxuZXhwb3J0IGNvbnN0IFN5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UgPSBTeW1ib2woJ1R5cGXDmG1hdGljYVByb3h5UmVmZXJlbmNlJyk7XG5jb25zdCBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlID0gKF90YXJnZXQ6IG9iamVjdCwgb3B0aW9ucz86IFR5cGVvbWF0aWNhT3B0aW9ucykgPT4ge1xuXHRjb25zdCB0YXJnZXQgPSBPYmplY3QuY3JlYXRlKF90YXJnZXQpO1xuXHRjb25zdCBpZCA9IGBUeXBlw5htYXRpY2FQcm94eVJlZmVyZW5jZS0ke01hdGgucmFuZG9tKCl9YDtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSwge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBpZDtcblx0XHR9XG5cdH0pO1xuXHRjb25zdCBoYW5kbGVycyA9IGNyZWF0ZUhhbmRsZXJzKG9wdGlvbnMpO1xuXHRjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0YXJnZXQsIGhhbmRsZXJzKTtcblx0cmV0dXJuIHByb3h5O1xufTtcblxuXG5leHBvcnQgY29uc3QgQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBvYmplY3QsIFMgZXh0ZW5kcyBUPih0aGlzOiBTIGV4dGVuZHMgVCA/IFMgOiB7fSwgX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMgKTogVCB7XG5cdGlmICghbmV3LnRhcmdldCkge1xuXG5cdFx0Y29uc3Qgc2VsZjoge1xuXHRcdFx0cHJvdG90eXBlOiB7XG5cdFx0XHRcdGNvbnN0cnVjdG9yOiB0eXBlb2YgQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlXG5cdFx0XHR9XG5cdFx0XHQvL0B0cy1pZ25vcmVcblx0XHR9ID0gQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlLmJpbmQodGhpcywgX3RhcmdldCwgb3B0aW9ucyk7XG5cblx0XHRzZWxmLnByb3RvdHlwZSA9IHtcblx0XHRcdGNvbnN0cnVjdG9yOiBCYXNlQ29uc3RydWN0b3JQcm90b3R5cGVcblx0XHR9O1xuXG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdHJldHVybiBzZWxmO1xuXG5cdH1cblxuXHQvLyBAdHMtaWdub3JlXG5cdGlmICh0aGlzW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdKSB7XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0Y29uc3QgdGFyZ2V0ID0gYmFzZVRhcmdldChfdGFyZ2V0KSBhcyBvYmplY3Q7XG5cdGNvbnN0IHsgZnJvemVuUHJvdG90eXBlczogZnJlZXplUHJvdG9zID0gdHJ1ZSB9ID0gb3B0aW9ucyB8fCB7fTtcblxuXHRjb25zdCBJbnN0YW5jZVByb3RvdHlwZSA9IGdldFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2UodGFyZ2V0LCBvcHRpb25zKTtcblxuXHRjb25zdCBjbGFzc1Byb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSBhcyBvYmplY3Q7XG5cblx0bGV0IHByb3RvO1xuXHRsZXQgcHJvdG9Qb2ludGVyID0gdGhpcyBhcyBvYmplY3Q7XG5cdGxldCBwcm90b0NvbnN0cmN1dG9yO1xuXG5cdGxldCBjb25zdHJ1Y3RvcnMgPSBmYWxzZTtcblxuXHQvLyBAdHMtaWdub3JlXG5cdC8vIGNvbnN0IGhhc1Byb3h5UmVmZXJlbmNlID0gcHJvdG9Qb2ludGVyW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdIGFzIHVua25vd24gYXMgYm9vbGVhbjtcblx0Ly8gaWYgKGhhc1Byb3h5UmVmZXJlbmNlKSB7XG5cdC8vIFx0dGhyb3cgbmV3IEVycm9yKCdNdWx0aXBsZSBUeXBlw5htYXRpY2EgaW5zdGFudGlhdGlvbnMgYXJlIG5vdCBhbGxvd2VkIGZvciB0aGUgc2FtZSBQcm90b3R5cGUgQ2hhaW4hJyk7XG5cdC8vIH1cblxuXHRkbyB7XG5cdFx0cHJvdG8gPSBwcm90b1BvaW50ZXI7XG5cdFx0cHJvdG9Qb2ludGVyID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcblx0XHRpZiAoQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlLnByb3RvdHlwZSA9PT0gcHJvdG9Qb2ludGVyKSB7XG5cdFx0XHRjb25zdHJ1Y3RvcnMgPSB0cnVlO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdGlmICghcHJvdG9Qb2ludGVyKSBicmVhaztcblx0XHRjb25zdCBkZXNjcmlwdG9yID0gUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocHJvdG9Qb2ludGVyLCAnY29uc3RydWN0b3InKTtcblx0XHRpZiAoIWRlc2NyaXB0b3IpIGNvbnRpbnVlO1xuXHRcdGNvbnN0IHZhbHVlID0gZGVzY3JpcHRvci52YWx1ZSB8fCBkZXNjcmlwdG9yLmdldDtcblx0XHQvLyBpZiAoIXZhbHVlKSBjb250aW51ZTtcblx0XHRwcm90b0NvbnN0cmN1dG9yID0gdmFsdWU7XG5cdH0gd2hpbGUgKHByb3RvQ29uc3RyY3V0b3IgIT09IEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSk7XG5cblx0aWYgKCFjb25zdHJ1Y3RvcnMgJiYgcHJvdG9Db25zdHJjdXRvciAhPT0gQmFzZUNvbnN0cnVjdG9yUHJvdG90eXBlKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gc2V0dXAgVHlwZcOYbWF0aWNhIGhhbmRsZXIhJyk7XG5cdH1cblxuXHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIEluc3RhbmNlUHJvdG90eXBlKTtcblx0aWYgKGZyZWV6ZVByb3Rvcykge1xuXHRcdE9iamVjdC5mcmVlemUoY2xhc3NQcm90b3R5cGUpO1xuXHR9XG5cdC8vIEB0cy1pZ25vcmVcblx0cmV0dXJuIHRoaXM7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG59IGFzIHtcblx0bmV3PFQgZXh0ZW5kcyBvYmplY3QgfCB7fT4oX3RhcmdldD86IFQsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpOiBUXG5cdDxUIGV4dGVuZHMgb2JqZWN0IHwge30sIFMgZXh0ZW5kcyBUPihfdGFyZ2V0PzogUyBleHRlbmRzIGluZmVyIEluZmVycmVkUyA/IEluZmVycmVkUyA6IHt9LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKTogU1xufTtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuY29uc3QgZnJlZXplQ2xhc3NQcm90b3R5cGVzID0gKGluc3RhbmNlOiBvYmplY3QsIHNob3VsZEZyZWV6ZTogYm9vbGVhbikgPT4ge1xuXHRpZiAoIXNob3VsZEZyZWV6ZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGNvbnN0IGZpcnN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGluc3RhbmNlKTtcblx0Y29uc3QgZmlyc3RJc1Byb3h5ID0gZmlyc3QgIT09IG51bGwgJiYgISFSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihmaXJzdCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSk7XG5cdGlmIChmaXJzdElzUHJveHkpIHtcblx0XHRPYmplY3QuZnJlZXplKEJhc2VDbGFzcy5wcm90b3R5cGUpO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGxldCBwID0gZmlyc3Q7XG5cdHdoaWxlIChwICE9PSBudWxsICYmIHAgIT09IEJhc2VDbGFzcy5wcm90b3R5cGUgJiYgcCAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuXHRcdGNvbnN0IG5leHQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocCk7XG5cdFx0Y29uc3QgbmV4dElzUHJveHkgPSBuZXh0ICE9PSBudWxsICYmICEhUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobmV4dCwgU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSk7XG5cdFx0T2JqZWN0LmZyZWV6ZShwKTtcblx0XHRpZiAobmV4dElzUHJveHkpIHtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRwID0gbmV4dDtcblx0fVxuXHRPYmplY3QuZnJlZXplKEJhc2VDbGFzcy5wcm90b3R5cGUpO1xufTtcblxuZXhwb3J0IGNsYXNzIEJhc2VDbGFzcyB7XG5cdGNvbnN0cnVjdG9yKF90YXJnZXQ/OiBvYmplY3QsIG9wdGlvbnM/OiBUeXBlb21hdGljYU9wdGlvbnMpIHtcblx0XHRjb25zdCB7IGZyb3plblByb3RvdHlwZXM6IGZyZWV6ZVByb3RvcyA9IHRydWUgfSA9IG9wdGlvbnMgfHwge307XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKHRoaXNbU3ltYm9sVHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZV0pIHtcblx0XHRcdGZyZWV6ZUNsYXNzUHJvdG90eXBlcyh0aGlzLCBmcmVlemVQcm90b3MpO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgdGFyZ2V0ID0gYmFzZVRhcmdldChfdGFyZ2V0KSBhcyBvYmplY3Q7XG5cdFx0Y29uc3QgcHJveHkgPSBnZXRUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlKHRhcmdldCwgb3B0aW9ucyk7XG5cdFx0Y29uc3QgaW5zdGFuY2VQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKTtcblxuXHRcdGlmIChpbnN0YW5jZVByb3RvID09PSBCYXNlQ2xhc3MucHJvdG90eXBlKSB7XG5cdFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgcHJveHkpO1xuXHRcdFx0ZnJlZXplQ2xhc3NQcm90b3R5cGVzKHRoaXMsIGZyZWV6ZVByb3Rvcyk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRsZXQgY2xhc3NQcm90byA9IGluc3RhbmNlUHJvdG87XG5cdFx0bGV0IHBhcmVudFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGNsYXNzUHJvdG8pO1xuXHRcdHdoaWxlIChwYXJlbnRQcm90byAhPT0gQmFzZUNsYXNzLnByb3RvdHlwZSAmJiBwYXJlbnRQcm90byAhPT0gbnVsbCkge1xuXHRcdFx0Y2xhc3NQcm90byA9IHBhcmVudFByb3RvO1xuXHRcdFx0cGFyZW50UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY2xhc3NQcm90byk7XG5cdFx0fVxuXG5cdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNsYXNzUHJvdG8sIHByb3h5KTtcblx0XHRmcmVlemVDbGFzc1Byb3RvdHlwZXModGhpcywgZnJlZXplUHJvdG9zKTtcblx0fVxufVxuXG5cbmNvbnN0IHN0cmljdCA9IGZ1bmN0aW9uIChfdGFyZ2V0Pzogb2JqZWN0LCBvcHRpb25zPzogVHlwZW9tYXRpY2FPcHRpb25zKSB7XG5cdGNvbnN0IHsgZnJvemVuUHJvdG90eXBlczogZnJlZXplUHJvdG9zID0gdHJ1ZSB9ID0gb3B0aW9ucyB8fCB7fTtcblxuXHRjb25zdCBkZWNvcmF0b3IgPSBmdW5jdGlvbjxUPihjc3RyOiBUKTogVCB7XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0aWYgKGNzdHIucHJvdG90eXBlW1N5bWJvbFR5cGVvbWF0aWNhUHJveHlSZWZlcmVuY2VdKSB7XG5cdFx0XHRyZXR1cm4gY3N0cjtcblx0XHR9XG5cblx0XHRjb25zdCB0YXJnZXQgPSBiYXNlVGFyZ2V0KF90YXJnZXQpO1xuXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQsIG9wdGlvbnMpO1xuXHRcdGNvbnN0IF9yZXBsYWNlciA9IE9iamVjdC5jcmVhdGUocHJveHkpO1xuXG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgX3JlcGxhY2VyKTtcblx0XHRpZiAoZnJlZXplUHJvdG9zKSB7XG5cdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRPYmplY3QuZnJlZXplKGNzdHIucHJvdG90eXBlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gY3N0cjtcblxuXG5cdFx0Ly8gY29uc3QgTXlDbGFzc1Byb3h5ID0gbmV3IFByb3h5KGNzdHIsIHtcblx0XHQvLyBcdGNvbnN0cnVjdChfLCBhcmd1bWVudHNMaXN0LCBuZXdUYXJnZXQpIHtcblx0XHQvLyBcdFx0ZGVidWdnZXI7XG5cdFx0Ly8gXHRcdGNvbnN0IHRhcmdldCA9IGJhc2VUYXJnZXQoX3RhcmdldCk7XG5cdFx0Ly8gXHRcdGNvbnN0IHByb3h5ID0gZ2V0VHlwZW9tYXRpY2FQcm94eVJlZmVyZW5jZSh0YXJnZXQpO1xuXHRcdC8vIFx0XHRjb25zdCBfcmVwbGFjZXIgPSBPYmplY3QuY3JlYXRlKHByb3h5KTtcblxuXHRcdC8vIFx0XHRjb25zdCBfcHJvdG8gPSBjc3RyLnByb3RvdHlwZTtcblxuXHRcdC8vIFx0XHRjb25zdCBwcm90byA9IE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKF9wcm90bykpO1xuXHRcdC8vIFx0XHRwcm90by5pQW1Qcm90byA9IHRydWU7XG5cblx0XHQvLyBcdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKGNzdHIucHJvdG90eXBlLCBwcm90byk7XG5cblx0XHQvLyBcdFx0Y29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhfcHJvdG8pO1xuXHRcdC8vIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydGllcyhwcm90bywgZGVzY3JpcHRvcnMpO1xuXG5cdFx0Ly8gXHRcdGNvbnN0IHJlcGxhY2VyID0gT2JqZWN0LmNyZWF0ZShfcmVwbGFjZXIpO1xuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YocHJvdG8sIHJlcGxhY2VyKTtcblxuXG5cdFx0Ly8gXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZihjc3RyLnByb3RvdHlwZSwgcHJvdG8pO1xuXHRcdC8vIFx0XHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChjc3RyLCBhcmd1bWVudHNMaXN0LCBuZXdUYXJnZXQpO1xuXG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXHRcdC8vIFx0XHRPYmplY3Quc2V0UHJvdG90eXBlT2YoY3N0ci5wcm90b3R5cGUsIF9wcm90byk7XG5cdFx0Ly8gXHRcdGRlYnVnZ2VyO1xuXG5cdFx0Ly8gXHRcdHJldHVybiByZXN1bHQ7XG5cdFx0Ly8gXHR9LFxuXHRcdC8vIH0pO1xuXHRcdC8vIHJldHVybiBNeUNsYXNzUHJveHk7XG5cdH07XG5cblx0cmV0dXJuIGRlY29yYXRvcjtcblxufTtcbmV4cG9ydCBjb25zdCB7IFN5bWJvbEluaXRpYWxWYWx1ZSB9ID0gRmllbGRDb25zdHJ1Y3RvcjtcbmNvbnN0IEZpZWxkQ29uc3RydWN0b3JFeHBvcnQgPSBGaWVsZENvbnN0cnVjdG9yO1xuZXhwb3J0IHsgRmllbGRDb25zdHJ1Y3RvckV4cG9ydCBhcyBGaWVsZENvbnN0cnVjdG9yIH07XG5leHBvcnQgY29uc3QgU3RyaWN0ID0gc3RyaWN0O1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gc2V0dXBDb21tb25KUygpIHtcblx0aWYgKHR5cGVvZiBtb2R1bGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgJ2V4cG9ydHMnLCB7XG5cdFx0Z2V0KCkge1xuXHRcdFx0cmV0dXJuIEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZTtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnQmFzZUNsYXNzJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBCYXNlQ2xhc3M7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdGaWVsZENvbnN0cnVjdG9yJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBGaWVsZENvbnN0cnVjdG9yO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnU3ltYm9sSW5pdGlhbFZhbHVlJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBTeW1ib2xJbml0aWFsVmFsdWU7XG5cdFx0fSxcblx0XHRlbnVtZXJhYmxlOiB0cnVlXG5cdH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlJywge1xuXHRcdGdldCgpIHtcblx0XHRcdHJldHVybiBTeW1ib2xUeXBlb21hdGljYVByb3h5UmVmZXJlbmNlO1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYmFzZVRhcmdldCcsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gYmFzZVRhcmdldDtcblx0XHR9LFxuXHRcdGVudW1lcmFibGU6IHRydWVcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUuZXhwb3J0cywgJ1N0cmljdCcsIHtcblx0XHRnZXQoKSB7XG5cdFx0XHRyZXR1cm4gc3RyaWN0O1xuXHRcdH0sXG5cdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHR9KTtcbn1cblxuc2V0dXBDb21tb25KUygpO1xuXG5PYmplY3QuZnJlZXplKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZSk7XG5PYmplY3QuZnJlZXplKEJhc2VDb25zdHJ1Y3RvclByb3RvdHlwZS5wcm90b3R5cGUpO1xuIl19 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 82256cb..3136adb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typeomatica", - "version": "0.3.58", + "version": "0.3.59", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typeomatica", - "version": "0.3.58", + "version": "0.3.59", "license": "MIT", "devDependencies": { "@eslint/eslintrc": "^3.3.5", @@ -2812,9 +2812,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.38", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz", - "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==", + "version": "2.10.40", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz", + "integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3300,9 +3300,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.378", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz", - "integrity": "sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==", + "version": "1.5.379", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.379.tgz", + "integrity": "sha512-v/qV5aV5EUA2pGilzUCq5/eyOloZAqDZBu9UMBIzgPpLlprjSR6zswsWBTv0KpqxLGUAZEwhO95ZCt7srymNVA==", "dev": true, "license": "ISC" }, @@ -3650,9 +3650,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { diff --git a/package.json b/package.json index 4b0457a..f872add 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typeomatica", - "version": "0.3.58", + "version": "0.3.59", "description": "type logic against javascript metaprogramming", "engines": { "node": ">=16" diff --git a/src/index.ts b/src/index.ts index da34892..4411b55 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,7 @@ import { FieldConstructor } from './fields.js'; export interface TypeomaticaOptions { strictAccessCheck?: boolean; + frozenPrototypes?: boolean; } const createResolver = (options: TypeomaticaOptions = {}) => { @@ -128,6 +129,9 @@ const createHandlers = (options?: TypeomaticaOptions) => ({ }, {})); }; } + if (prop === 'constructor') { + return undefined; + } const { name } = receiver.constructor; if (props2skip.has(prop)) { const message = `${name} lacks definition of [ ${String(prop).valueOf()} ]`; @@ -205,9 +209,12 @@ export const BaseConstructorPrototype = function } const target = baseTarget(_target) as object; + const { frozenPrototypes: freezeProtos = true } = options || {}; const InstancePrototype = getTypeomaticaProxyReference(target, options); + const classPrototype = Object.getPrototypeOf(this) as object; + let proto; let protoPointer = this as object; let protoConstrcutor; @@ -240,6 +247,9 @@ export const BaseConstructorPrototype = function } Object.setPrototypeOf(proto, InstancePrototype); + if (freezeProtos) { + Object.freeze(classPrototype); + } // @ts-ignore return this; @@ -250,39 +260,67 @@ export const BaseConstructorPrototype = function }; /* eslint-enable no-unused-vars */ +const freezeClassPrototypes = (instance: object, shouldFreeze: boolean) => { + if (!shouldFreeze) { + return; + } + + const first = Object.getPrototypeOf(instance); + const firstIsProxy = first !== null && !!Reflect.getOwnPropertyDescriptor(first, SymbolTypeomaticaProxyReference); + if (firstIsProxy) { + Object.freeze(BaseClass.prototype); + return; + } + + let p = first; + while (p !== null && p !== BaseClass.prototype && p !== Object.prototype) { + const next = Object.getPrototypeOf(p); + const nextIsProxy = next !== null && !!Reflect.getOwnPropertyDescriptor(next, SymbolTypeomaticaProxyReference); + Object.freeze(p); + if (nextIsProxy) { + break; + } + p = next; + } + Object.freeze(BaseClass.prototype); +}; + export class BaseClass { constructor(_target?: object, options?: TypeomaticaOptions) { + const { frozenPrototypes: freezeProtos = true } = options || {}; + // @ts-ignore if (this[SymbolTypeomaticaProxyReference]) { + freezeClassPrototypes(this, freezeProtos); return this; } const target = baseTarget(_target) as object; const proxy = getTypeomaticaProxyReference(target, options); - let proto: object | null = this; - let protoPointer: object | null; - let found: boolean = false; - do { - protoPointer = Object.getPrototypeOf(proto); - // if (protoPointer[SymbolTypeomaticaProxyReference]) { - // throw new Error('Double TypeØmatica extension is not allowed!'); - // } - if (protoPointer === Object.prototype) { - found = true; - break; - } - /* - // it can be, that protoPointer === null - // though too hard to implement this test - */ - proto = protoPointer; - } while (!found); - Object.setPrototypeOf(proto, proxy); + const instanceProto = Object.getPrototypeOf(this); + + if (instanceProto === BaseClass.prototype) { + Object.setPrototypeOf(this, proxy); + freezeClassPrototypes(this, freezeProtos); + return this; + } + + let classProto = instanceProto; + let parentProto = Object.getPrototypeOf(classProto); + while (parentProto !== BaseClass.prototype && parentProto !== null) { + classProto = parentProto; + parentProto = Object.getPrototypeOf(classProto); + } + + Object.setPrototypeOf(classProto, proxy); + freezeClassPrototypes(this, freezeProtos); } } const strict = function (_target?: object, options?: TypeomaticaOptions) { + const { frozenPrototypes: freezeProtos = true } = options || {}; + const decorator = function(cstr: T): T { // @ts-ignore @@ -296,6 +334,10 @@ const strict = function (_target?: object, options?: TypeomaticaOptions) { // @ts-ignore Object.setPrototypeOf(cstr.prototype, _replacer); + if (freezeProtos) { + // @ts-ignore + Object.freeze(cstr.prototype); + } return cstr; diff --git a/test/index.ts b/test/index.ts index a5610e1..da3977c 100644 --- a/test/index.ts +++ b/test/index.ts @@ -121,6 +121,35 @@ class SimpleBase extends BaseClass { } const simpleInstance = addTag(new SimpleBase); +class InitialStateBase extends BaseClass { + constructor() { + super({ initialNumber: 42, initialString: 'hello' }); + // @ts-ignore + this.initialNumber = this.initialNumber; + // @ts-ignore + this.initialString = this.initialString; + } +} + +class DeepBaseA extends BaseClass { + aMethod() { + return 'A'; + } +} +class DeepBaseB extends DeepBaseA { + bMethod() { + return 'B'; + } +} +class DeepBaseC extends DeepBaseB { + cMethod() { + return 'C'; + } +} +const deepBaseInstance = addTag(new DeepBaseC()); + +const directBaseInstance = addTag(new BaseClass({ directProp: 123 })); + interface IFCstr { (): void new(): { @@ -281,6 +310,46 @@ describe('props tests', () => { expect(proto.someProp).toEqual(123); }); + test('BaseClass accepts initial state through super()', () => { + const instance = addTag(new InitialStateBase()); + expect(instance.initialNumber.valueOf()).toEqual(42); + expect(instance.initialString.valueOf()).toEqual('hello'); + + instance.initialNumber = 100; + expect(instance.initialNumber.valueOf()).toEqual(100); + + expect(() => { + // @ts-ignore + instance.initialNumber = 'wrong'; + }).toThrow('Type Mismatch'); + }); + + test('direct BaseClass instantiation works without polluting BaseClass.prototype', () => { + expect(directBaseInstance.directProp.valueOf()).toEqual(123); + // @ts-ignore + directBaseInstance.directProp = 456; + expect(directBaseInstance.directProp.valueOf()).toEqual(456); + expect(() => { + // @ts-ignore + directBaseInstance.directProp = 'wrong'; + }).toThrow('Type Mismatch'); + }); + + test('frozenPrototypes: false allows runtime prototype mutation', () => { + class UnfrozenBase extends BaseClass { + declare value: number; + constructor() { + super(undefined, { frozenPrototypes: false }); + this.value = 1; + } + } + const instance = addTag(new UnfrozenBase()); + expect(Object.isFrozen(UnfrozenBase.prototype)).toBe(false); + // @ts-ignore + UnfrozenBase.prototype.extra = 123; + expect(instance.extra.valueOf()).toEqual(123); + }); + test('base instance has props', () => { let gf: string; let sv: string; @@ -636,6 +705,29 @@ describe('prototype mutations tests', () => { }).toThrow(new ReferenceError('Value Access Denied')); }); + test('class prototype cannot be reassigned', () => { + expect(() => { + Object.setPrototypeOf(Base.prototype, {}); + }).toThrow(TypeError); + }); + + test('class prototype cannot grow new properties', () => { + expect(() => { + // @ts-ignore + Base.prototype.newProp = 1; + }).toThrow(TypeError); + }); + + test('proxy constructor access does not recurse', () => { + const proxy = Object.getPrototypeOf(DeepBaseA.prototype); + expect(() => { + // @ts-ignore + proxy.constructor; + }).not.toThrow(); + // @ts-ignore + expect(proxy.constructor).toBeUndefined(); + }); + }); describe('methods tests', () => { @@ -722,6 +814,25 @@ describe('deep extend works', () => { }); + test('BaseClass deep hierarchy preserves intermediate prototype methods', () => { + expect(deepBaseInstance.aMethod()).toEqual('A'); + expect(deepBaseInstance.bMethod()).toEqual('B'); + expect(deepBaseInstance.cMethod()).toEqual('C'); + expect(deepBaseInstance).toBeInstanceOf(DeepBaseA); + expect(deepBaseInstance).toBeInstanceOf(DeepBaseB); + expect(deepBaseInstance).toBeInstanceOf(DeepBaseC); + }); + + test('BaseClass freezes every prototype in the hierarchy', () => { + expect(Object.isFrozen(DeepBaseA.prototype)).toBe(true); + expect(Object.isFrozen(DeepBaseB.prototype)).toBe(true); + expect(Object.isFrozen(DeepBaseC.prototype)).toBe(true); + expect(() => { + // @ts-ignore + DeepBaseB.prototype.newProp = 1; + }).toThrow(TypeError); + }); + test('network extention works', () => { expect(networkedInstance).toBeInstanceOf(NetworkedExtention); @@ -871,7 +982,6 @@ describe('coverage: ', () => { // @ts-ignore expect(cov5.hidden).toBeTruthy(); - console.log(ogp(cov5)); debugger; const proxyPointer = ogp(ogp(ogp(cov5))); @@ -900,6 +1010,27 @@ describe('coverage: ', () => { expect(error).toBeInstanceOf(Error); expect(error.message).toBe('Properties Deletion is not allowed!'); + class CovCLS6 extends BasePrototype({ value: 1 }, { frozenPrototypes: false }) { + declare value: number; + } + const cov6 = addTag(new CovCLS6); + expect(Object.isFrozen(CovCLS6.prototype)).toBe(false); + // @ts-ignore + CovCLS6.prototype.extra = 2; + // @ts-ignore + expect(cov6.extra.valueOf()).toEqual(2); + + @Strict({ value: 1 }, { frozenPrototypes: false }) + class CovCLS7 { + declare value: number; + } + const cov7 = addTag(new CovCLS7); + expect(Object.isFrozen(CovCLS7.prototype)).toBe(false); + // @ts-ignore + CovCLS7.prototype.extra = 3; + // @ts-ignore + expect(cov7.extra.valueOf()).toEqual(3); + // this tests we passed null // as a target for proto // though it anyway be converted to Object.create(null)