@zkpersona/noir-jwt
Version:
JWT Verification and claims attestation library for Noir
197 lines (192 loc) • 23.5 kB
JavaScript
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==