UNPKG

@zkpersona/noir-jwt

Version:

JWT Verification and claims attestation library for Noir

197 lines (192 loc) 23.5 kB
import { Field, FixedSizeArray, toJSON, U8, BoundedVec } from '@zkpersona/noir-helpers'; import { bnToLimbStrArray, bnToRedcLimbStrArray } from '@mach-34/noir-bignum-paramgen'; import forge from 'node-forge'; // src/jwt.ts // src/helpers.ts var bytesToBigInt = (bytes) => { const arr = bytes instanceof Uint8Array ? Array.from(bytes) : bytes; return arr.reduce((acc, byte) => acc << 8n | BigInt(byte), 0n); }; // src/rsa.ts var RSAPubKey = class _RSAPubKey { /** * Private constructor to enforce immutability and proper initialization. * Use factory methods `fromPem` or `fromAsn1` to create instances. * * @param modulus - The RSA modulus (n) as a bigint * @param exponent - The RSA public exponent (e) as a bigint */ constructor(modulus, exponent) { this.modulus = modulus; this.exponent = exponent; } /** * Creates an RSAPubKey instance from a PEM-encoded public key. * * @param pem - The RSA public key in PEM format * @returns A new RSAPubKey instance */ static fromPem(pem) { const key = forge.pki.publicKeyFromPem(pem); return new _RSAPubKey( BigInt(key.n.toString(10)), BigInt(key.e.toString(10)) ); } /** * Creates an RSAPubKey instance from an ASN.1 encoded public key. * * @param key - The RSA public key in ASN.1 format * @returns A new RSAPubKey instance */ static fromAsn1(key) { const publicKey = forge.pki.publicKeyFromAsn1(key); return new _RSAPubKey( BigInt(publicKey.n.toString(10)), BigInt(publicKey.e.toString(10)) ); } /** * Converts the RSA public key into field element arrays for Noir circuit input. * * @param numBits - Optional number of bits to use for the limb representation. * If not provided, a default value will be used. * @returns An object containing: * - modulus: Array of field elements representing the RSA modulus * - redc: Array of field elements representing the Montgomery reduction parameters */ toFieldArray(numBits) { const modulus = bnToLimbStrArray(this.modulus, numBits).map( (e) => new Field(e) ); const redc = bnToRedcLimbStrArray(this.modulus, numBits).map( (e) => new Field(e) ); return { modulus: new FixedSizeArray(modulus.length, modulus), redc: new FixedSizeArray(redc.length, redc) }; } /** * Converts the RSA public key into an object for Noir circuit input. */ toCircuitInputs() { return toJSON({ pub_key: this.toFieldArray(2048) }); } }; var RSASignature = class _RSASignature { /** * Private constructor to enforce immutability and proper initialization. * Use factory method `fromString` to create instances. * * @param bytes - The raw bytes of the RSA signature */ constructor(bytes) { this.bytes = bytes; } /** * Creates an RSASignature instance from a string-encoded signature. * * @param signature - The RSA signature as a string * @param encoding - The encoding of the signature string (e.g., 'base64', 'hex') * @returns A new RSASignature instance */ static fromString(signature, encoding) { const bytes = Buffer.from(signature, encoding); return new _RSASignature(Array.from(bytes)); } /** * Converts the RSA signature into an array of field elements for Noir circuit input. * * @returns An array of field elements representing the signature */ toFieldArray() { const arr = bnToLimbStrArray(bytesToBigInt(this.bytes), 2048).map( (e) => new Field(e) ); return new FixedSizeArray(arr.length, arr); } /** * Converts the RSA signature into an object for Noir circuit input. */ toCircuitInputs() { return toJSON({ signature: this.toFieldArray() }); } }; // src/jwt.ts var JWT = class { /** Base64-encoded JWT header */ header; /** Base64-encoded JWT payload */ payload; /** Base64-encoded JWT signature */ signature; /** The algorithm used for signature verification */ alg; /** * Creates a new JWT instance from a JWT string. * * @param jwt - The JWT string in the format 'header.payload.signature' * @param alg - The algorithm to use for signature verification (defaults to H256) * @throws Error if the JWT string is malformed or missing components */ constructor(jwt, alg = "H256") { const [header, payload, signature] = jwt.trim().split("."); if (!header) throw new Error("Invalid JWT: header is missing"); if (!payload) throw new Error("Invalid JWT: payload is missing"); if (!signature) throw new Error("Invalid JWT: signature is missing"); this.header = header; this.payload = payload; this.signature = signature; this.alg = alg; } /** * Converts the JWT components into Noir circuit compatible inputs. * * @param maxHeaderLength - Maximum length for the header vector * @param maxPayloadLength - Maximum length for the payload vector * @param maxSignatureLength - Maximum length for the signature vector * @returns InputMap containing the JWT components as Noir circuit inputs. * @throws Error if an unsupported algorithm is specified */ toCircuitInputs({ maxHeaderLength, maxPayloadLength, maxSignatureLength }) { let sig; if (this.alg === "H256") { const arr = Array.from(Buffer.from(this.signature)).map((e) => new U8(e)); sig = new BoundedVec(maxSignatureLength, () => new U8(0)); sig.extendFromArray(arr); } else if (this.alg === "RS256") { const sigArr = RSASignature.fromString( this.signature, "base64" ).toFieldArray(); sig = new BoundedVec(sigArr.len(), () => new Field(0)); sig.extendFromArray(sigArr.toArray()); } else { throw new Error(`Unsupported algorithm: ${this.alg}`); } const headerArr = Array.from(Buffer.from(this.header)).map( (e) => new U8(e) ); const header = new BoundedVec(maxHeaderLength, () => new U8(0)); header.extendFromArray(headerArr); const payloadArr = Array.from(Buffer.from(this.payload)).map( (e) => new U8(e) ); const payload = new BoundedVec(maxPayloadLength, () => new U8(0)); payload.extendFromArray(payloadArr); const data = { header, payload, signature: sig }; return toJSON({ jwt: data }); } }; export { JWT, RSAPubKey, RSASignature, bytesToBigInt }; //# sourceMappingURL=index.mjs.map //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9oZWxwZXJzLnRzIiwiLi4vc3JjL3JzYS50cyIsIi4uL3NyYy9qd3QudHMiXSwibmFtZXMiOlsiRmllbGQiLCJ0b0pTT04iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFNYSxJQUFBLGFBQUEsR0FBZ0IsQ0FBQyxLQUF5QyxLQUFBO0FBQ3JFLEVBQUEsTUFBTSxNQUFNLEtBQWlCLFlBQUEsVUFBQSxHQUFhLEtBQU0sQ0FBQSxJQUFBLENBQUssS0FBSyxDQUFJLEdBQUEsS0FBQTtBQUM5RCxFQUFPLE9BQUEsR0FBQSxDQUFJLE1BQU8sQ0FBQSxDQUFDLEdBQUssRUFBQSxJQUFBLEtBQVUsT0FBTyxFQUFNLEdBQUEsTUFBQSxDQUFPLElBQUksQ0FBQSxFQUFHLEVBQUUsQ0FBQTtBQUNqRTs7O0FDR2EsSUFBQSxTQUFBLEdBQU4sTUFBTSxVQUFVLENBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUWIsV0FBQSxDQUVHLFNBRUEsUUFDVCxFQUFBO0FBSFMsSUFBQSxJQUFBLENBQUEsT0FBQSxHQUFBLE9BQUE7QUFFQSxJQUFBLElBQUEsQ0FBQSxRQUFBLEdBQUEsUUFBQTtBQUFBO0FBQ1I7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRSCxPQUFPLFFBQVEsR0FBYSxFQUFBO0FBQzFCLElBQUEsTUFBTSxHQUFNLEdBQUEsS0FBQSxDQUFNLEdBQUksQ0FBQSxnQkFBQSxDQUFpQixHQUFHLENBQUE7QUFDMUMsSUFBQSxPQUFPLElBQUksVUFBQTtBQUFBLE1BQ1QsTUFBTyxDQUFBLEdBQUEsQ0FBSSxDQUFFLENBQUEsUUFBQSxDQUFTLEVBQUUsQ0FBQyxDQUFBO0FBQUEsTUFDekIsTUFBTyxDQUFBLEdBQUEsQ0FBSSxDQUFFLENBQUEsUUFBQSxDQUFTLEVBQUUsQ0FBQztBQUFBLEtBQzNCO0FBQUE7QUFDRjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE9BQU8sU0FBUyxHQUFzQixFQUFBO0FB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S0FDYjtBQUVBLElBQUEsT0FBT0MsTUFBTyxDQUFBLEVBQUUsR0FBSyxFQUFBLElBQUEsRUFBTSxDQUFBO0FBQUE7QUFFL0IiLCJmaWxlIjoiaW5kZXgubWpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb252ZXJ0cyBhIGJ5dGUgYXJyYXkgdG8gYSBiaWdpbnQuXG4gKlxuICogQHBhcmFtIGJ5dGVzIC0gVGhlIGJ5dGUgYXJyYXkgdG8gY29udmVydFxuICogQHJldHVybnMgVGhlIHJlc3VsdGluZyBiaWdpbnRcbiAqL1xuZXhwb3J0IGNvbnN0IGJ5dGVzVG9CaWdJbnQgPSAoYnl0ZXM6IG51bWJlcltdIHwgVWludDhBcnJheSk6IGJpZ2ludCA9PiB7XG4gIGNvbnN0IGFyciA9IGJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSA/IEFycmF5LmZyb20oYnl0ZXMpIDogYnl0ZXM7XG4gIHJldHVybiBhcnIucmVkdWNlKChhY2MsIGJ5dGUpID0+IChhY2MgPDwgOG4pIHwgQmlnSW50KGJ5dGUpLCAwbik7XG59O1xuIiwiaW1wb3J0IHtcbiAgYm5Ub0xpbWJTdHJBcnJheSxcbiAgYm5Ub1JlZGNMaW1iU3RyQXJyYXksXG59IGZyb20gJ0BtYWNoLTM0L25vaXItYmlnbnVtLXBhcmFtZ2VuJztcbmltcG9ydCB7IEZpZWxkLCBGaXhlZFNpemVBcnJheSwgdG9KU09OIH0gZnJvbSAnQHprcGVyc29uYS9ub2lyLWhlbHBlcnMnO1xuaW1wb3J0IGZvcmdlIGZyb20gJ25vZGUtZm9yZ2UnO1xuaW1wb3J0IHsgYnl0ZXNUb0JpZ0ludCB9IGZyb20gJy4vaGVscGVycyc7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBSU0EgcHVibGljIGtleSB3aXRoIGltbXV0YWJsZSBwcm9wZXJ0aWVzLlxuICogUHJvdmlkZXMgbWV0aG9kcyB0byBjcmVhdGUgaW5zdGFuY2VzIGZyb20gZGlmZmVyZW50IGZvcm1hdHMgYW5kIGNvbnZlcnQgdG8gTm9pciBjaXJjdWl0IGlucHV0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJTQVB1YktleSB7XG4gIC8qKlxuICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIGVuZm9yY2UgaW1tdXRhYmlsaXR5IGFuZCBwcm9wZXIgaW5pdGlhbGl6YXRpb24uXG4gICAqIFVzZSBmYWN0b3J5IG1ldGhvZHMgYGZyb21QZW1gIG9yIGBmcm9tQXNuMWAgdG8gY3JlYXRlIGluc3RhbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIG1vZHVsdXMgLSBUaGUgUlNBIG1vZHVsdXMgKG4pIGFzIGEgYmlnaW50XG4gICAqIEBwYXJhbSBleHBvbmVudCAtIFRoZSBSU0EgcHVibGljIGV4cG9uZW50IChlKSBhcyBhIGJpZ2ludFxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS9ub1BhcmFtZXRlclByb3BlcnRpZXM6IHByaXZhdGUgY29uc3RydWN0b3JcbiAgICByZWFkb25seSBtb2R1bHVzOiBiaWdpbnQsXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvbm9QYXJhbWV0ZXJQcm9wZXJ0aWVzOiBwcml2YXRlIGNvbnN0cnVjdG9yXG4gICAgcmVhZG9ubHkgZXhwb25lbnQ6IGJpZ2ludFxuICApIHt9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gUlNBUHViS2V5IGluc3RhbmNlIGZyb20gYSBQRU0tZW5jb2RlZCBwdWJsaWMga2V5LlxuICAgKlxuICAgKiBAcGFyYW0gcGVtIC0gVGhlIFJTQSBwdWJsaWMga2V5IGluIFBFTSBmb3JtYXRcbiAgICogQHJldHVybnMgQSBuZXcgUlNBUHViS2V5IGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgZnJvbVBlbShwZW06IHN0cmluZykge1xuICAgIGNvbnN0IGtleSA9IGZvcmdlLnBraS5wdWJsaWNLZXlGcm9tUGVtKHBlbSk7XG4gICAgcmV0dXJuIG5ldyBSU0FQdWJLZXkoXG4gICAgICBCaWdJbnQoa2V5Lm4udG9TdHJpbmcoMTApKSxcbiAgICAgIEJpZ0ludChrZXkuZS50b1N0cmluZygxMCkpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIFJTQVB1YktleSBpbnN0YW5jZSBmcm9tIGFuIEFTTi4xIGVuY29kZWQgcHVibGljIGtleS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFRoZSBSU0EgcHVibGljIGtleSBpbiBBU04uMSBmb3JtYXRcbiAgICogQHJldHVybnMgQSBuZXcgUlNBUHViS2V5IGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgZnJvbUFzbjEoa2V5OiBmb3JnZS5hc24xLkFzbjEpIHtcbiAgICBjb25zdCBwdWJsaWNLZXkgPSBmb3JnZS5wa2kucHVibGljS2V5RnJvbUFzbjEoa2V5KTtcbiAgICByZXR1cm4gbmV3IFJTQVB1YktleShcbiAgICAgIEJpZ0ludChwdWJsaWNLZXkubi50b1N0cmluZygxMCkpLFxuICAgICAgQmlnSW50KHB1YmxpY0tleS5lLnRvU3RyaW5nKDEwKSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBSU0EgcHVibGljIGtleSBpbnRvIGZpZWxkIGVsZW1lbnQgYXJyYXlzIGZvciBOb2lyIGNpcmN1aXQgaW5wdXQuXG4gICAqXG4gICAqIEBwYXJhbSBudW1CaXRzIC0gT3B0aW9uYWwgbnVtYmVyIG9mIGJpdHMgdG8gdXNlIGZvciB0aGUgbGltYiByZXByZXNlbnRhdGlvbi5cbiAgICogICAgICAgICAgICAgICAgIElmIG5vdCBwcm92aWRlZCwgYSBkZWZhdWx0IHZhbHVlIHdpbGwgYmUgdXNlZC5cbiAgICogQHJldHVybnMgQW4gb2JqZWN0IGNvbnRhaW5pbmc6XG4gICAqICAgICAgICAgIC0gbW9kdWx1czogQXJyYXkgb2YgZmllbGQgZWxlbWVudHMgcmVwcmVzZW50aW5nIHRoZSBSU0EgbW9kdWx1c1xuICAgKiAgICAgICAgICAtIHJlZGM6IEFycmF5IG9mIGZpZWxkIGVsZW1lbnRzIHJlcHJlc2VudGluZyB0aGUgTW9udGdvbWVyeSByZWR1Y3Rpb24gcGFyYW1ldGVyc1xuICAgKi9cbiAgdG9GaWVsZEFycmF5KG51bUJpdHM/OiBudW1iZXIpIHtcbiAgICBjb25zdCBtb2R1bHVzID0gYm5Ub0xpbWJTdHJBcnJheSh0aGlzLm1vZHVsdXMsIG51bUJpdHMpLm1hcChcbiAgICAgIChlKSA9PiBuZXcgRmllbGQoZSlcbiAgICApO1xuICAgIGNvbnN0IHJlZGMgPSBiblRvUmVkY0xpbWJTdHJBcnJheSh0aGlzLm1vZHVsdXMsIG51bUJpdHMpLm1hcChcbiAgICAgIChlKSA9PiBuZXcgRmllbGQoZSlcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsdXM6IG5ldyBGaXhlZFNpemVBcnJheShtb2R1bHVzLmxlbmd0aCwgbW9kdWx1cyksXG4gICAgICByZWRjOiBuZXcgRml4ZWRTaXplQXJyYXkocmVkYy5sZW5ndGgsIHJlZGMpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIFJTQSBwdWJsaWMga2V5IGludG8gYW4gb2JqZWN0IGZvciBOb2lyIGNpcmN1aXQgaW5wdXQuXG4gICAqL1xuICB0b0NpcmN1aXRJbnB1dHMoKSB7XG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvdXNlTmFtaW5nQ29udmVudGlvbjogc2FmZVxuICAgIHJldHVybiB0b0pTT04oeyBwdWJfa2V5OiB0aGlzLnRvRmllbGRBcnJheSgyMDQ4KSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gUlNBIHNpZ25hdHVyZSB3aXRoIGltbXV0YWJsZSBwcm9wZXJ0aWVzLlxuICogUHJvdmlkZXMgbWV0aG9kcyB0byBjcmVhdGUgaW5zdGFuY2VzIGZyb20gZGlmZmVyZW50IGZvcm1hdHMgYW5kIGNvbnZlcnQgdG8gTm9pciBjaXJjdWl0IGlucHV0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJTQVNpZ25hdHVyZSB7XG4gIC8qKlxuICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIGVuZm9yY2UgaW1tdXRhYmlsaXR5IGFuZCBwcm9wZXIgaW5pdGlhbGl6YXRpb24uXG4gICAqIFVzZSBmYWN0b3J5IG1ldGhvZCBgZnJvbVN0cmluZ2AgdG8gY3JlYXRlIGluc3RhbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIGJ5dGVzIC0gVGhlIHJhdyBieXRlcyBvZiB0aGUgUlNBIHNpZ25hdHVyZVxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS9ub1BhcmFtZXRlclByb3BlcnRpZXM6IHByaXZhdGUgY29uc3RydWN0b3JcbiAgICByZWFkb25seSBieXRlczogbnVtYmVyW11cbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIFJTQVNpZ25hdHVyZSBpbnN0YW5jZSBmcm9tIGEgc3RyaW5nLWVuY29kZWQgc2lnbmF0dXJlLlxuICAgKlxuICAgKiBAcGFyYW0gc2lnbmF0dXJlIC0gVGhlIFJTQSBzaWduYXR1cmUgYXMgYSBzdHJpbmdcbiAgICogQHBhcmFtIGVuY29kaW5nIC0gVGhlIGVuY29kaW5nIG9mIHRoZSBzaWduYXR1cmUgc3RyaW5nIChlLmcuLCAnYmFzZTY0JywgJ2hleCcpXG4gICAqIEByZXR1cm5zIEEgbmV3IFJTQVNpZ25hdHVyZSBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGZyb21TdHJpbmcoc2lnbmF0dXJlOiBzdHJpbmcsIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZykge1xuICAgIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmZyb20oc2lnbmF0dXJlLCBlbmNvZGluZyk7XG4gICAgcmV0dXJuIG5ldyBSU0FTaWduYXR1cmUoQXJyYXkuZnJvbShieXRlcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBSU0Egc2lnbmF0dXJlIGludG8gYW4gYXJyYXkgb2YgZmllbGQgZWxlbWVudHMgZm9yIE5vaXIgY2lyY3VpdCBpbnB1dC5cbiAgICpcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZmllbGQgZWxlbWVudHMgcmVwcmVzZW50aW5nIHRoZSBzaWduYXR1cmVcbiAgICovXG4gIHRvRmllbGRBcnJheSgpIHtcbiAgICBjb25zdCBhcnIgPSBiblRvTGltYlN0ckFycmF5KGJ5dGVzVG9CaWdJbnQodGhpcy5ieXRlcyksIDIwNDgpLm1hcChcbiAgICAgIChlKSA9PiBuZXcgRmllbGQoZSlcbiAgICApO1xuXG4gICAgcmV0dXJuIG5ldyBGaXhlZFNpemVBcnJheShhcnIubGVuZ3RoLCBhcnIpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBSU0Egc2lnbmF0dXJlIGludG8gYW4gb2JqZWN0IGZvciBOb2lyIGNpcmN1aXQgaW5wdXQuXG4gICAqL1xuICB0b0NpcmN1aXRJbnB1dHMoKSB7XG4gICAgcmV0dXJuIHRvSlNPTih7IHNpZ25hdHVyZTogdGhpcy50b0ZpZWxkQXJyYXkoKSB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQm91bmRlZFZlYywgRmllbGQsIFU4LCB0b0pTT04gfSBmcm9tICdAemtwZXJzb25hL25vaXItaGVscGVycyc7XG5pbXBvcnQgeyBSU0FTaWduYXR1cmUgfSBmcm9tICcuL3JzYSc7XG5cbi8qKlxuICogU3VwcG9ydGVkIEpXVCBzaWduYXR1cmUgYWxnb3JpdGhtcy5cbiAqXG4gKi9cbmV4cG9ydCB0eXBlIEpXVEFsZ29yaXRobSA9ICdIMjU2JyB8ICdSUzI1Nic7XG5cbi8qKlxuICogQ2xhc3MgZm9yIHBhcnNpbmcgYW5kIGNvbnZlcnRpbmcgSldUIHN0cmluZ3MgaW50byBOb2lyIGNpcmN1aXQgaW5wdXRzLlxuICogSGFuZGxlcyBib3RoIEhNQUMtU0hBMjU2IGFuZCBSU0EtU0hBMjU2IHNpZ25hdHVyZXMsIGNvbnZlcnRpbmcgdGhlbSBpbnRvXG4gKiBhcHByb3ByaWF0ZSBmaWVsZCBlbGVtZW50IHJlcHJlc2VudGF0aW9ucyBmb3IgTm9pciBjaXJjdWl0IHZlcmlmaWNhdGlvbi5cbiAqL1xuLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvdXNlTmFtaW5nQ29udmVudGlvbjogY29udmVudGlvblxuZXhwb3J0IGNsYXNzIEpXVCB7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCBKV1QgaGVhZGVyICovXG4gIHByb3RlY3RlZCBoZWFkZXI6IHN0cmluZztcbiAgLyoqIEJhc2U2NC1lbmNvZGVkIEpXVCBwYXlsb2FkICovXG4gIHByb3RlY3RlZCBwYXlsb2FkOiBzdHJpbmc7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCBKV1Qgc2lnbmF0dXJlICovXG4gIHByb3RlY3RlZCBzaWduYXR1cmU6IHN0cmluZztcbiAgLyoqIFRoZSBhbGdvcml0aG0gdXNlZCBmb3Igc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiAqL1xuICBwcm90ZWN0ZWQgYWxnOiBKV1RBbGdvcml0aG07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgSldUIGluc3RhbmNlIGZyb20gYSBKV1Qgc3RyaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gand0IC0gVGhlIEpXVCBzdHJpbmcgaW4gdGhlIGZvcm1hdCAnaGVhZGVyLnBheWxvYWQuc2lnbmF0dXJlJ1xuICAgKiBAcGFyYW0gYWxnIC0gVGhlIGFsZ29yaXRobSB0byB1c2UgZm9yIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gKGRlZmF1bHRzIHRvIEgyNTYpXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIEpXVCBzdHJpbmcgaXMgbWFsZm9ybWVkIG9yIG1pc3NpbmcgY29tcG9uZW50c1xuICAgKi9cbiAgY29uc3RydWN0b3Ioand0OiBzdHJpbmcsIGFsZzogSldUQWxnb3JpdGhtID0gJ0gyNTYnKSB7XG4gICAgY29uc3QgW2hlYWRlciwgcGF5bG9hZCwgc2lnbmF0dXJlXSA9IGp3dC50cmltKCkuc3BsaXQoJy4nKTtcbiAgICBpZiAoIWhlYWRlcikgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEpXVDogaGVhZGVyIGlzIG1pc3NpbmcnKTtcbiAgICBpZiAoIXBheWxvYWQpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBKV1Q6IHBheWxvYWQgaXMgbWlzc2luZycpO1xuICAgIGlmICghc2lnbmF0dXJlKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSldUOiBzaWduYXR1cmUgaXMgbWlzc2luZycpO1xuXG4gICAgdGhpcy5oZWFkZXIgPSBoZWFkZXI7XG4gICAgdGhpcy5wYXlsb2FkID0gcGF5bG9hZDtcbiAgICB0aGlzLnNpZ25hdHVyZSA9IHNpZ25hdHVyZTtcbiAgICB0aGlzLmFsZyA9IGFsZztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgSldUIGNvbXBvbmVudHMgaW50byBOb2lyIGNpcmN1aXQgY29tcGF0aWJsZSBpbnB1dHMuXG4gICAqXG4gICAqIEBwYXJhbSBtYXhIZWFkZXJMZW5ndGggLSBNYXhpbXVtIGxlbmd0aCBmb3IgdGhlIGhlYWRlciB2ZWN0b3JcbiAgICogQHBhcmFtIG1heFBheWxvYWRMZW5ndGggLSBNYXhpbXVtIGxlbmd0aCBmb3IgdGhlIHBheWxvYWQgdmVjdG9yXG4gICAqIEBwYXJhbSBtYXhTaWduYXR1cmVMZW5ndGggLSBNYXhpbXVtIGxlbmd0aCBmb3IgdGhlIHNpZ25hdHVyZSB2ZWN0b3JcbiAgICogQHJldHVybnMgSW5wdXRNYXAgY29udGFpbmluZyB0aGUgSldUIGNvbXBvbmVudHMgYXMgTm9pciBjaXJjdWl0IGlucHV0cy5cbiAgICogQHRocm93cyBFcnJvciBpZiBhbiB1bnN1cHBvcnRlZCBhbGdvcml0aG0gaXMgc3BlY2lmaWVkXG4gICAqL1xuICB0b0NpcmN1aXRJbnB1dHMoe1xuICAgIG1heEhlYWRlckxlbmd0aCxcbiAgICBtYXhQYXlsb2FkTGVuZ3RoLFxuICAgIG1heFNpZ25hdHVyZUxlbmd0aCxcbiAgfToge1xuICAgIG1heEhlYWRlckxlbmd0aDogbnVtYmVyO1xuICAgIG1heFBheWxvYWRMZW5ndGg6IG51bWJlcjtcbiAgICBtYXhTaWduYXR1cmVMZW5ndGg6IG51bWJlcjtcbiAgfSkge1xuICAgIGxldCBzaWc6IEJvdW5kZWRWZWM8RmllbGQ+IHwgQm91bmRlZFZlYzxVOD47XG4gICAgaWYgKHRoaXMuYWxnID09PSAnSDI1NicpIHtcbiAgICAgIGNvbnN0IGFyciA9IEFycmF5LmZyb20oQnVmZmVyLmZyb20odGhpcy5zaWduYXR1cmUpKS5tYXAoKGUpID0+IG5ldyBVOChlKSk7XG4gICAgICBzaWcgPSBuZXcgQm91bmRlZFZlYyhtYXhTaWduYXR1cmVMZW5ndGgsICgpID0+IG5ldyBVOCgwKSk7XG4gICAgICBzaWcuZXh0ZW5kRnJvbUFycmF5KGFycik7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFsZyA9PT0gJ1JTMjU2Jykge1xuICAgICAgY29uc3Qgc2lnQXJyID0gUlNBU2lnbmF0dXJlLmZyb21TdHJpbmcoXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlLFxuICAgICAgICAnYmFzZTY0J1xuICAgICAgKS50b0ZpZWxkQXJyYXkoKTtcblxuICAgICAgc2lnID0gbmV3IEJvdW5kZWRWZWMoc2lnQXJyLmxlbigpLCAoKSA9PiBuZXcgRmllbGQoMCkpO1xuICAgICAgc2lnLmV4dGVuZEZyb21BcnJheShzaWdBcnIudG9BcnJheSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBhbGdvcml0aG06ICR7dGhpcy5hbGd9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVyQXJyID0gQXJyYXkuZnJvbShCdWZmZXIuZnJvbSh0aGlzLmhlYWRlcikpLm1hcChcbiAgICAgIChlKSA9PiBuZXcgVTgoZSlcbiAgICApO1xuICAgIGNvbnN0IGhlYWRlciA9IG5ldyBCb3VuZGVkVmVjKG1heEhlYWRlckxlbmd0aCwgKCkgPT4gbmV3IFU4KDApKTtcbiAgICBoZWFkZXIuZXh0ZW5kRnJvbUFycmF5KGhlYWRlckFycik7XG5cbiAgICBjb25zdCBwYXlsb2FkQXJyID0gQXJyYXkuZnJvbShCdWZmZXIuZnJvbSh0aGlzLnBheWxvYWQpKS5tYXAoXG4gICAgICAoZSkgPT4gbmV3IFU4KGUpXG4gICAgKTtcbiAgICBjb25zdCBwYXlsb2FkID0gbmV3IEJvdW5kZWRWZWMobWF4UGF5bG9hZExlbmd0aCwgKCkgPT4gbmV3IFU4KDApKTtcbiAgICBwYXlsb2FkLmV4dGVuZEZyb21BcnJheShwYXlsb2FkQXJyKTtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBoZWFkZXIsXG4gICAgICBwYXlsb2FkLFxuICAgICAgc2lnbmF0dXJlOiBzaWcsXG4gICAgfTtcblxuICAgIHJldHVybiB0b0pTT04oeyBqd3Q6IGRhdGEgfSk7XG4gIH1cbn1cbiJdfQ==