UNPKG

llmverify

Version:

AI Output Verification Toolkit — Local-first LLM safety, hallucination detection, PII redaction, prompt injection defense, and runtime monitoring. Zero telemetry. OWASP LLM Top 10 aligned.

372 lines 39.1 kB
"use strict"; /** * llmverify Core Module * * Pre-configured verification pipelines for different use cases. * Run all engines with a single command using preset configurations. * * @module core * @author KingCaliber Labs * @license MIT */ Object.defineProperty(exports, "__esModule", { value: true }); exports.presets = exports.PRESETS = void 0; exports.run = run; exports.devVerify = devVerify; exports.prodVerify = prodVerify; exports.strictVerify = strictVerify; exports.fastVerify = fastVerify; exports.ciVerify = ciVerify; exports.createPipeline = createPipeline; const verify_1 = require("../verify"); const classification_1 = require("../engines/classification"); const security_1 = require("../csm6/security"); /** * Preset configurations for quick setup */ /** * Full checks configuration helper */ const fullChecks = { security: true, privacy: true, safety: true, fairness: false, reliability: false, transparency: true }; const minimalChecks = { security: true, privacy: false, safety: false, fairness: false, reliability: false, transparency: false }; exports.PRESETS = { /** * Development mode - balanced, informative output * Good for local development and testing */ dev: { tier: 'free', engines: { hallucination: { enabled: true }, consistency: { enabled: true }, jsonValidator: { enabled: true }, csm6: { enabled: true, profile: 'baseline', checks: fullChecks } }, output: { verbose: true, includeEvidence: true, includeMethodology: true, includeLimitations: true } }, /** * Production mode - optimized for speed, essential checks only * Good for production APIs with latency requirements */ prod: { tier: 'free', engines: { hallucination: { enabled: false }, consistency: { enabled: false }, jsonValidator: { enabled: true }, csm6: { enabled: true, profile: 'baseline', checks: fullChecks } }, output: { verbose: false, includeEvidence: false, includeMethodology: false, includeLimitations: false } }, /** * Strict mode - all engines, maximum scrutiny * Good for high-stakes content, compliance requirements */ strict: { tier: 'free', engines: { hallucination: { enabled: true }, consistency: { enabled: true }, jsonValidator: { enabled: true }, csm6: { enabled: true, profile: 'high_risk', checks: { ...fullChecks, fairness: true, reliability: true } } }, output: { verbose: true, includeEvidence: true, includeMethodology: true, includeLimitations: true } }, /** * Fast mode - minimal checks, maximum speed * Good for high-throughput scenarios */ fast: { tier: 'free', engines: { hallucination: { enabled: false }, consistency: { enabled: false }, jsonValidator: { enabled: false }, csm6: { enabled: true, profile: 'baseline', checks: minimalChecks } }, output: { verbose: false, includeEvidence: false, includeMethodology: false, includeLimitations: false } }, /** * CI mode - optimized for CI/CD pipelines * Returns structured output, fails on high risk */ ci: { tier: 'free', engines: { hallucination: { enabled: true }, consistency: { enabled: true }, jsonValidator: { enabled: true }, csm6: { enabled: true, profile: 'baseline', checks: fullChecks } }, output: { verbose: false, includeEvidence: true, includeMethodology: false, includeLimitations: false } } }; exports.presets = exports.PRESETS; /** * Run all verification engines with a single command * * This is the master function that developers can use to run * comprehensive verification with preset configurations. * * @example * ```typescript * import { run } from 'llmverify/core'; * * // Quick dev mode * const result = await run({ content: aiOutput, preset: 'dev' }); * * // Production mode with input check * const result = await run({ * content: aiOutput, * userInput: userMessage, * preset: 'prod' * }); * * // Strict mode with classification * const result = await run({ * content: aiOutput, * prompt: originalPrompt, * preset: 'strict' * }); * ``` */ async function run(options) { const startTime = Date.now(); const preset = options.preset || 'dev'; const config = { ...exports.PRESETS[preset], ...options.config }; const enginesRun = []; // Prepare parallel tasks const tasks = []; // 1. Main verification (always runs) enginesRun.push('verify'); const verifyTask = (0, verify_1.verify)({ content: options.content, config }); tasks.push(verifyTask); // 2. Classification (if prompt provided) let classificationTask = null; if (options.prompt) { enginesRun.push('classification'); classificationTask = Promise.resolve((0, classification_1.classify)(options.prompt, options.content)); tasks.push(classificationTask); } // 3. Input safety check (if userInput provided) let inputSafetyTask = null; if (options.userInput) { enginesRun.push('input-safety'); inputSafetyTask = Promise.resolve({ safe: (0, security_1.isInputSafe)(options.userInput), injectionFindings: (0, security_1.checkPromptInjection)(options.userInput), riskScore: 0 // Will be calculated }); tasks.push(inputSafetyTask); } // 4. PII check if (config.engines?.csm6?.checks?.privacy !== false) { enginesRun.push('pii-detection'); const piiFindings = (0, security_1.checkPII)(options.content); const { redacted, piiCount } = (0, security_1.redactPII)(options.content); const piiTask = Promise.resolve({ hasPII: piiFindings.length > 0, findings: piiFindings, redacted, piiCount }); tasks.push(piiTask); } // 5. Harmful content check if (config.engines?.csm6?.checks?.safety !== false) { enginesRun.push('harmful-content'); const harmfulFindings = (0, security_1.checkHarmfulContent)(options.content); const harmfulTask = Promise.resolve({ hasHarmful: harmfulFindings.length > 0, findings: harmfulFindings }); tasks.push(harmfulTask); } // Execute all tasks (parallel or sequential based on option) let results; if (options.parallel !== false) { results = await Promise.all(tasks); } else { results = []; for (const task of tasks) { results.push(await task); } } // Extract results const verification = results[0]; let resultIndex = 1; const classification = options.prompt ? results[resultIndex++] : null; const inputSafety = options.userInput ? results[resultIndex++] : null; let piiCheck = null; if (config.engines?.csm6?.checks?.privacy !== false) { piiCheck = results[resultIndex++]; } let harmfulCheck = null; if (config.engines?.csm6?.checks?.safety !== false) { harmfulCheck = results[resultIndex++]; } const totalLatencyMs = Date.now() - startTime; return { verification, classification, inputSafety, piiCheck, harmfulCheck, meta: { preset, enginesRun, totalLatencyMs, timestamp: new Date().toISOString() } }; } // ============================================================================ // QUICK FUNCTIONS // ============================================================================ /** * Quick verification with dev preset */ async function devVerify(content, prompt) { return run({ content, prompt, preset: 'dev' }); } /** * Quick verification with prod preset */ async function prodVerify(content) { return run({ content, preset: 'prod' }); } /** * Quick verification with strict preset */ async function strictVerify(content, prompt) { return run({ content, prompt, preset: 'strict' }); } /** * Quick verification with fast preset */ async function fastVerify(content) { return run({ content, preset: 'fast' }); } /** * Quick verification for CI/CD */ async function ciVerify(content) { return run({ content, preset: 'ci' }); } /** * Build a custom verification pipeline * * @example * ```typescript * const pipeline = createPipeline() * .addStep('pii', async (content) => checkPII(content)) * .addStep('injection', async (content) => checkPromptInjection(content)) * .build(); * * const results = await pipeline.run(content); * ``` */ function createPipeline() { const steps = []; return { addStep(name, run) { steps.push({ name, enabled: true, run }); return this; }, disableStep(name) { const step = steps.find(s => s.name === name); if (step) step.enabled = false; return this; }, enableStep(name) { const step = steps.find(s => s.name === name); if (step) step.enabled = true; return this; }, build() { return { async run(content, context = {}) { const results = {}; const enabledSteps = steps.filter(s => s.enabled); // Run all enabled steps in parallel const promises = enabledSteps.map(async (step) => { const result = await step.run(content, context); return { name: step.name, result }; }); const stepResults = await Promise.all(promises); stepResults.forEach(({ name, result }) => { results[name] = result; }); return results; }, getSteps() { return steps.map(s => ({ name: s.name, enabled: s.enabled })); } }; } }; } exports.default = { run, devVerify, prodVerify, strictVerify, fastVerify, ciVerify, createPipeline, PRESETS: exports.PRESETS }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29yZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOzs7QUF3UEgsa0JBc0dDO0FBU0QsOEJBRUM7QUFLRCxnQ0FFQztBQUtELG9DQUVDO0FBS0QsZ0NBRUM7QUFLRCw0QkFFQztBQTRCRCx3Q0ErQ0M7QUE5Y0Qsc0NBQWtEO0FBQ2xELDhEQUEyRTtBQUMzRSwrQ0FBK0c7QUFhL0c7O0dBRUc7QUFDSDs7R0FFRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLFFBQVEsRUFBRSxJQUFJO0lBQ2QsT0FBTyxFQUFFLElBQUk7SUFDYixNQUFNLEVBQUUsSUFBSTtJQUNaLFFBQVEsRUFBRSxLQUFLO0lBQ2YsV0FBVyxFQUFFLEtBQUs7SUFDbEIsWUFBWSxFQUFFLElBQUk7Q0FDbkIsQ0FBQztBQUVGLE1BQU0sYUFBYSxHQUFHO0lBQ3BCLFFBQVEsRUFBRSxJQUFJO0lBQ2QsT0FBTyxFQUFFLEtBQUs7SUFDZCxNQUFNLEVBQUUsS0FBSztJQUNiLFFBQVEsRUFBRSxLQUFLO0lBQ2YsV0FBVyxFQUFFLEtBQUs7SUFDbEIsWUFBWSxFQUFFLEtBQUs7Q0FDcEIsQ0FBQztBQUVXLFFBQUEsT0FBTyxHQUF3QztJQUMxRDs7O09BR0c7SUFDSCxHQUFHLEVBQUU7UUFDSCxJQUFJLEVBQUUsTUFBTTtRQUNaLE9BQU8sRUFBRTtZQUNQLGFBQWEsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7WUFDaEMsV0FBVyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRTtZQUM5QixhQUFhLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFO1lBQ2hDLElBQUksRUFBRTtnQkFDSixPQUFPLEVBQUUsSUFBSTtnQkFDYixPQUFPLEVBQUUsVUFBVTtnQkFDbkIsTUFBTSxFQUFFLFVBQVU7YUFDbkI7U0FDRjtRQUNELE1BQU0sRUFBRTtZQUNOLE9BQU8s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QUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUVsRCxvQ0FBb0M7b0JBQ3BDLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO3dCQUM3QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3dCQUNoRCxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7b0JBQ3JDLENBQUMsQ0FBQyxDQUFDO29CQUVILE1BQU0sV0FBVyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDaEQsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUU7d0JBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUM7b0JBQ3pCLENBQUMsQ0FBQyxDQUFDO29CQUVILE9BQU8sT0FBTyxDQUFDO2dCQUNqQixDQUFDO2dCQUVELFFBQVE7b0JBQ04sT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNoRSxDQUFDO2FBQ0YsQ0FBQztRQUNKLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQU9ELGtCQUFlLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBUCxlQUFPLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogbGxtdmVyaWZ5IENvcmUgTW9kdWxlXG4gKiBcbiAqIFByZS1jb25maWd1cmVkIHZlcmlmaWNhdGlvbiBwaXBlbGluZXMgZm9yIGRpZmZlcmVudCB1c2UgY2FzZXMuXG4gKiBSdW4gYWxsIGVuZ2luZXMgd2l0aCBhIHNpbmdsZSBjb21tYW5kIHVzaW5nIHByZXNldCBjb25maWd1cmF0aW9ucy5cbiAqIFxuICogQG1vZHVsZSBjb3JlXG4gKiBAYXV0aG9yIEtpbmdDYWxpYmVyIExhYnNcbiAqIEBsaWNlbnNlIE1JVFxuICovXG5cbmltcG9ydCB7IHZlcmlmeSwgVmVyaWZ5T3B0aW9ucyB9IGZyb20gJy4uL3ZlcmlmeSc7XG5pbXBvcnQgeyBjbGFzc2lmeSwgQ2xhc3NpZmljYXRpb25SZXN1bHQgfSBmcm9tICcuLi9lbmdpbmVzL2NsYXNzaWZpY2F0aW9uJztcbmltcG9ydCB7IGNoZWNrUHJvbXB0SW5qZWN0aW9uLCBjaGVja1BJSSwgY2hlY2tIYXJtZnVsQ29udGVudCwgaXNJbnB1dFNhZmUsIHJlZGFjdFBJSSB9IGZyb20gJy4uL2NzbTYvc2VjdXJpdHknO1xuaW1wb3J0IHsgVmVyaWZ5UmVzdWx0LCBGaW5kaW5nIH0gZnJvbSAnLi4vdHlwZXMvcmVzdWx0cyc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi90eXBlcy9jb25maWcnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBQUkVTRVQgQ09ORklHVVJBVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBQcmVzZXQgY29uZmlndXJhdGlvbiBtb2RlcyBmb3IgZGlmZmVyZW50IGVudmlyb25tZW50c1xuICovXG5leHBvcnQgdHlwZSBQcmVzZXRNb2RlID0gJ2RldicgfCAncHJvZCcgfCAnc3RyaWN0JyB8ICdmYXN0JyB8ICdjaSc7XG5cbi8qKlxuICogUHJlc2V0IGNvbmZpZ3VyYXRpb25zIGZvciBxdWljayBzZXR1cFxuICovXG4vKipcbiAqIEZ1bGwgY2hlY2tzIGNvbmZpZ3VyYXRpb24gaGVscGVyXG4gKi9cbmNvbnN0IGZ1bGxDaGVja3MgPSB7XG4gIHNlY3VyaXR5OiB0cnVlLFxuICBwcml2YWN5OiB0cnVlLFxuICBzYWZldHk6IHRydWUsXG4gIGZhaXJuZXNzOiBmYWxzZSxcbiAgcmVsaWFiaWxpdHk6IGZhbHNlLFxuICB0cmFuc3BhcmVuY3k6IHRydWVcbn07XG5cbmNvbnN0IG1pbmltYWxDaGVja3MgPSB7XG4gIHNlY3VyaXR5OiB0cnVlLFxuICBwcml2YWN5OiBmYWxzZSxcbiAgc2FmZXR5OiBmYWxzZSxcbiAgZmFpcm5lc3M6IGZhbHNlLFxuICByZWxpYWJpbGl0eTogZmFsc2UsXG4gIHRyYW5zcGFyZW5jeTogZmFsc2Vcbn07XG5cbmV4cG9ydCBjb25zdCBQUkVTRVRTOiBSZWNvcmQ8UHJlc2V0TW9kZSwgUGFydGlhbDxDb25maWc+PiA9IHtcbiAgLyoqXG4gICAqIERldmVsb3BtZW50IG1vZGUgLSBiYWxhbmNlZCwgaW5mb3JtYXRpdmUgb3V0cHV0XG4gICAqIEdvb2QgZm9yIGxvY2FsIGRldmVsb3BtZW50IGFuZCB0ZXN0aW5nXG4gICAqL1xuICBkZXY6IHtcbiAgICB0aWVyOiAnZnJlZScsXG4gICAgZW5naW5lczoge1xuICAgICAgaGFsbHVjaW5hdGlvbjogeyBlbmFibGVkOiB0cnVlIH0sXG4gICAgICBjb25zaXN0ZW5jeTogeyBlbmFibGVkOiB0cnVlIH0sXG4gICAgICBqc29uVmFsaWRhdG9yOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgICAgIGNzbTY6IHsgXG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHByb2ZpbGU6ICdiYXNlbGluZScsXG4gICAgICAgIGNoZWNrczogZnVsbENoZWNrc1xuICAgICAgfVxuICAgIH0sXG4gICAgb3V0cHV0OiB7XG4gICAgICB2ZXJib3NlOiB0cnVlLFxuICAgICAgaW5jbHVkZUV2aWRlbmNlOiB0cnVlLFxuICAgICAgaW5jbHVkZU1ldGhvZG9sb2d5OiB0cnVlLFxuICAgICAgaW5jbHVkZUxpbWl0YXRpb25zOiB0cnVlXG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBQcm9kdWN0aW9uIG1vZGUgLSBvcHRpbWl6ZWQgZm9yIHNwZWVkLCBlc3NlbnRpYWwgY2hlY2tzIG9ubHlcbiAgICogR29vZCBmb3IgcHJvZHVjdGlvbiBBUElzIHdpdGggbGF0ZW5jeSByZXF1aXJlbWVudHNcbiAgICovXG4gIHByb2Q6IHtcbiAgICB0aWVyOiAnZnJlZScsXG4gICAgZW5naW5lczoge1xuICAgICAgaGFsbHVjaW5hdGlvbjogeyBlbmFibGVkOiBmYWxzZSB9LFxuICAgICAgY29uc2lzdGVuY3k6IHsgZW5hYmxlZDogZmFsc2UgfSxcbiAgICAgIGpzb25WYWxpZGF0b3I6IHsgZW5hYmxlZDogdHJ1ZSB9LFxuICAgICAgY3NtNjogeyBcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcHJvZmlsZTogJ2Jhc2VsaW5lJyxcbiAgICAgICAgY2hlY2tzOiBmdWxsQ2hlY2tzXG4gICAgICB9XG4gICAgfSxcbiAgICBvdXRwdXQ6IHtcbiAgICAgIHZlcmJvc2U6IGZhbHNlLFxuICAgICAgaW5jbHVkZUV2aWRlbmNlOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVNZXRob2RvbG9neTogZmFsc2UsXG4gICAgICBpbmNsdWRlTGltaXRhdGlvbnM6IGZhbHNlXG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTdHJpY3QgbW9kZSAtIGFsbCBlbmdpbmVzLCBtYXhpbXVtIHNjcnV0aW55XG4gICAqIEdvb2QgZm9yIGhpZ2gtc3Rha2VzIGNvbnRlbnQsIGNvbXBsaWFuY2UgcmVxdWlyZW1lbnRzXG4gICAqL1xuICBzdHJpY3Q6IHtcbiAgICB0aWVyOiAnZnJlZScsXG4gICAgZW5naW5lczoge1xuICAgICAgaGFsbHVjaW5hdGlvbjogeyBlbmFibGVkOiB0cnVlIH0sXG4gICAgICBjb25zaXN0ZW5jeTogeyBlbmFibGVkOiB0cnVlIH0sXG4gICAgICBqc29uVmFsaWRhdG9yOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgICAgIGNzbTY6IHsgXG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHByb2ZpbGU6ICdoaWdoX3Jpc2snLFxuICAgICAgICBjaGVja3M6IHsgLi4uZnVsbENoZWNrcywgZmFpcm5lc3M6IHRydWUsIHJlbGlhYmlsaXR5OiB0cnVlIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIG91dHB1dDoge1xuICAgICAgdmVyYm9zZTogdHJ1ZSxcbiAgICAgIGluY2x1ZGVFdmlkZW5jZTogdHJ1ZSxcbiAgICAgIGluY2x1ZGVNZXRob2RvbG9neTogdHJ1ZSxcbiAgICAgIGluY2x1ZGVMaW1pdGF0aW9uczogdHJ1ZVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogRmFzdCBtb2RlIC0gbWluaW1hbCBjaGVja3MsIG1heGltdW0gc3BlZWRcbiAgICogR29vZCBmb3IgaGlnaC10aHJvdWdocHV0IHNjZW5hcmlvc1xuICAgKi9cbiAgZmFzdDoge1xuICAgIHRpZXI6ICdmcmVlJyxcbiAgICBlbmdpbmVzOiB7XG4gICAgICBoYWxsdWNpbmF0aW9uOiB7IGVuYWJsZWQ6IGZhbHNlIH0sXG4gICAgICBjb25zaXN0ZW5jeTogeyBlbmFibGVkOiBmYWxzZSB9LFxuICAgICAganNvblZhbGlkYXRvcjogeyBlbmFibGVkOiBmYWxzZSB9LFxuICAgICAgY3NtNjogeyBcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcHJvZmlsZTogJ2Jhc2VsaW5lJyxcbiAgICAgICAgY2hlY2tzOiBtaW5pbWFsQ2hlY2tzXG4gICAgICB9XG4gICAgfSxcbiAgICBvdXRwdXQ6IHtcbiAgICAgIHZlcmJvc2U6IGZhbHNlLFxuICAgICAgaW5jbHVkZUV2aWRlbmNlOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVNZXRob2RvbG9neTogZmFsc2UsXG4gICAgICBpbmNsdWRlTGltaXRhdGlvbnM6IGZhbHNlXG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBDSSBtb2RlIC0gb3B0aW1pemVkIGZvciBDSS9DRCBwaXBlbGluZXNcbiAgICogUmV0dXJucyBzdHJ1Y3R1cmVkIG91dHB1dCwgZmFpbHMgb24gaGlnaCByaXNrXG4gICAqL1xuICBjaToge1xuICAgIHRpZXI6ICdmcmVlJyxcbiAgICBlbmdpbmVzOiB7XG4gICAgICBoYWxsdWNpbmF0aW9uOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgICAgIGNvbnNpc3RlbmN5OiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgICAgIGpzb25WYWxpZGF0b3I6IHsgZW5hYmxlZDogdHJ1ZSB9LFxuICAgICAgY3NtNjogeyBcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcHJvZmlsZTogJ2Jhc2VsaW5lJyxcbiAgICAgICAgY2hlY2tzOiBmdWxsQ2hlY2tzXG4gICAgICB9XG4gICAgfSxcbiAgICBvdXRwdXQ6IHtcbiAgICAgIHZlcmJvc2U6IGZhbHNlLFxuICAgICAgaW5jbHVkZUV2aWRlbmNlOiB0cnVlLFxuICAgICAgaW5jbHVkZU1ldGhvZG9sb2d5OiBmYWxzZSxcbiAgICAgIGluY2x1ZGVMaW1pdGF0aW9uczogZmFsc2VcbiAgICB9XG4gIH1cbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENPUkUgUlVOIEZVTkNUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogUmVzdWx0IGZyb20gcnVubmluZyBhbGwgZW5naW5lc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIENvcmVSdW5SZXN1bHQge1xuICAvKiogT3ZlcmFsbCB2ZXJpZmljYXRpb24gcmVzdWx0ICovXG4gIHZlcmlmaWNhdGlvbjogVmVyaWZ5UmVzdWx0O1xuICAvKiogQ2xhc3NpZmljYXRpb24gcmVzdWx0IChpbnRlbnQsIGhhbGx1Y2luYXRpb24sIGV0Yy4pICovXG4gIGNsYXNzaWZpY2F0aW9uOiBDbGFzc2lmaWNhdGlvblJlc3VsdCB8IG51bGw7XG4gIC8qKiBJbnB1dCBzYWZldHkgY2hlY2sgcmVzdWx0ICovXG4gIGlucHV0U2FmZXR5OiB7XG4gICAgc2FmZTogYm9vbGVhbjtcbiAgICBpbmplY3Rpb25GaW5kaW5nczogRmluZGluZ1tdO1xuICAgIHJpc2tTY29yZTogbnVtYmVyO1xuICB9IHwgbnVsbDtcbiAgLyoqIFBJSSBkZXRlY3Rpb24gcmVzdWx0ICovXG4gIHBpaUNoZWNrOiB7XG4gICAgaGFzUElJOiBib29sZWFuO1xuICAgIGZpbmRpbmdzOiBGaW5kaW5nW107XG4gICAgcmVkYWN0ZWQ6IHN0cmluZztcbiAgICBwaWlDb3VudDogbnVtYmVyO1xuICB9IHwgbnVsbDtcbiAgLyoqIEhhcm1mdWwgY29udGVudCBjaGVjayByZXN1bHQgKi9cbiAgaGFybWZ1bENoZWNrOiB7XG4gICAgaGFzSGFybWZ1bDogYm9vbGVhbjtcbiAgICBmaW5kaW5nczogRmluZGluZ1tdO1xuICB9IHwgbnVsbDtcbiAgLyoqIEV4ZWN1dGlvbiBtZXRhZGF0YSAqL1xuICBtZXRhOiB7XG4gICAgcHJlc2V0OiBQcmVzZXRNb2RlO1xuICAgIGVuZ2luZXNSdW46IHN0cmluZ1tdO1xuICAgIHRvdGFsTGF0ZW5jeU1zOiBudW1iZXI7XG4gICAgdGltZXN0YW1wOiBzdHJpbmc7XG4gIH07XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY29yZSBydW5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3JlUnVuT3B0aW9ucyB7XG4gIC8qKiBDb250ZW50IHRvIHZlcmlmeSAoQUkgb3V0cHV0KSAqL1xuICBjb250ZW50OiBzdHJpbmc7XG4gIC8qKiBPcmlnaW5hbCBwcm9tcHQgKG9wdGlvbmFsLCBmb3IgY2xhc3NpZmljYXRpb24pICovXG4gIHByb21wdD86IHN0cmluZztcbiAgLyoqIFVzZXIgaW5wdXQgdG8gY2hlY2sgKG9wdGlvbmFsLCBmb3IgaW5wdXQgc2FmZXR5KSAqL1xuICB1c2VySW5wdXQ/OiBzdHJpbmc7XG4gIC8qKiBQcmVzZXQgbW9kZSAqL1xuICBwcmVzZXQ/OiBQcmVzZXRNb2RlO1xuICAvKiogQ3VzdG9tIGNvbmZpZyAob3ZlcnJpZGVzIHByZXNldCkgKi9cbiAgY29uZmlnPzogUGFydGlhbDxDb25maWc+O1xuICAvKiogUnVuIGVuZ2luZXMgaW4gcGFyYWxsZWwgKi9cbiAgcGFyYWxsZWw/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJ1biBhbGwgdmVyaWZpY2F0aW9uIGVuZ2luZXMgd2l0aCBhIHNpbmdsZSBjb21tYW5kXG4gKiBcbiAqIFRoaXMgaXMgdGhlIG1hc3RlciBmdW5jdGlvbiB0aGF0IGRldmVsb3BlcnMgY2FuIHVzZSB0byBydW5cbiAqIGNvbXByZWhlbnNpdmUgdmVyaWZpY2F0aW9uIHdpdGggcHJlc2V0IGNvbmZpZ3VyYXRpb25zLlxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgcnVuIH0gZnJvbSAnbGxtdmVyaWZ5L2NvcmUnO1xuICogXG4gKiAvLyBRdWljayBkZXYgbW9kZVxuICogY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuKHsgY29udGVudDogYWlPdXRwdXQsIHByZXNldDogJ2RldicgfSk7XG4gKiBcbiAqIC8vIFByb2R1Y3Rpb24gbW9kZSB3aXRoIGlucHV0IGNoZWNrXG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCBydW4oeyBcbiAqICAgY29udGVudDogYWlPdXRwdXQsIFxuICogICB1c2VySW5wdXQ6IHVzZXJNZXNzYWdlLFxuICogICBwcmVzZXQ6ICdwcm9kJyBcbiAqIH0pO1xuICogXG4gKiAvLyBTdHJpY3QgbW9kZSB3aXRoIGNsYXNzaWZpY2F0aW9uXG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCBydW4oeyBcbiAqICAgY29udGVudDogYWlPdXRwdXQsIFxuICogICBwcm9tcHQ6IG9yaWdpbmFsUHJvbXB0LFxuICogICBwcmVzZXQ6ICdzdHJpY3QnIFxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bihvcHRpb25zOiBDb3JlUnVuT3B0aW9ucyk6IFByb21pc2U8Q29yZVJ1blJlc3VsdD4ge1xuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICBjb25zdCBwcmVzZXQgPSBvcHRpb25zLnByZXNldCB8fCAnZGV2JztcbiAgY29uc3QgY29uZmlnID0geyAuLi5QUkVTRVRTW3ByZXNldF0sIC4uLm9wdGlvbnMuY29uZmlnIH07XG4gIGNvbnN0IGVuZ2luZXNSdW46IHN0cmluZ1tdID0gW107XG5cbiAgLy8gUHJlcGFyZSBwYXJhbGxlbCB0YXNrc1xuICBjb25zdCB0YXNrczogUHJvbWlzZTxhbnk+W10gPSBbXTtcblxuICAvLyAxLiBNYWluIHZlcmlmaWNhdGlvbiAoYWx3YXlzIHJ1bnMpXG4gIGVuZ2luZXNSdW4ucHVzaCgndmVyaWZ5Jyk7XG4gIGNvbnN0IHZlcmlmeVRhc2sgPSB2ZXJpZnkoeyBjb250ZW50OiBvcHRpb25zLmNvbnRlbnQsIGNvbmZpZyB9KTtcbiAgdGFza3MucHVzaCh2ZXJpZnlUYXNrKTtcblxuICAvLyAyLiBDbGFzc2lmaWNhdGlvbiAoaWYgcHJvbXB0IHByb3ZpZGVkKVxuICBsZXQgY2xhc3NpZmljYXRpb25UYXNrOiBQcm9taXNlPENsYXNzaWZpY2F0aW9uUmVzdWx0PiB8IG51bGwgPSBudWxsO1xuICBpZiAob3B0aW9ucy5wcm9tcHQpIHtcbiAgICBlbmdpbmVzUnVuLnB1c2goJ2NsYXNzaWZpY2F0aW9uJyk7XG4gICAgY2xhc3NpZmljYXRpb25UYXNrID0gUHJvbWlzZS5yZXNvbHZlKGNsYXNzaWZ5KG9wdGlvbnMucHJvbXB0LCBvcHRpb25zLmNvbnRlbnQpKTtcbiAgICB0YXNrcy5wdXNoKGNsYXNzaWZpY2F0aW9uVGFzayk7XG4gIH1cblxuICAvLyAzLiBJbnB1dCBzYWZldHkgY2hlY2sgKGlmIHVzZXJJbnB1dCBwcm92aWRlZClcbiAgbGV0IGlucHV0U2FmZXR5VGFzazogUHJvbWlzZTxhbnk+IHwgbnVsbCA9IG51bGw7XG4gIGlmIChvcHRpb25zLnVzZXJJbnB1dCkge1xuICAgIGVuZ2luZXNSdW4ucHVzaCgnaW5wdXQtc2FmZXR5Jyk7XG4gICAgaW5wdXRTYWZldHlUYXNrID0gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHNhZmU6IGlzSW5wdXRTYWZlKG9wdGlvbnMudXNlcklucHV0KSxcbiAgICAgIGluamVjdGlvbkZpbmRpbmdzOiBjaGVja1Byb21wdEluamVjdGlvbihvcHRpb25zLnVzZXJJbnB1dCksXG4gICAgICByaXNrU2NvcmU6IDAgLy8gV2lsbCBiZSBjYWxjdWxhdGVkXG4gICAgfSk7XG4gICAgdGFza3MucHVzaChpbnB1dFNhZmV0eVRhc2spO1xuICB9XG5cbiAgLy8gNC4gUElJIGNoZWNrXG4gIGlmIChjb25maWcuZW5naW5lcz8uY3NtNj8uY2hlY2tzPy5wcml2YWN5ICE9PSBmYWxzZSkge1xuICAgIGVuZ2luZXNSdW4ucHVzaCgncGlpLWRldGVjdGlvbicpO1xuICAgIGNvbnN0IHBpaUZpbmRpbmdzID0gY2hlY2tQSUkob3B0aW9ucy5jb250ZW50KTtcbiAgICBjb25zdCB7IHJlZGFjdGVkLCBwaWlDb3VudCB9ID0gcmVkYWN0UElJKG9wdGlvbnMuY29udGVudCk7XG4gICAgY29uc3QgcGlpVGFzayA9IFByb21pc2UucmVzb2x2ZSh7XG4gICAgICBoYXNQSUk6IHBpaUZpbmRpbmdzLmxlbmd0aCA+IDAsXG4gICAgICBmaW5kaW5nczogcGlpRmluZGluZ3MsXG4gICAgICByZWRhY3RlZCxcbiAgICAgIHBpaUNvdW50XG4gICAgfSk7XG4gICAgdGFza3MucHVzaChwaWlUYXNrKTtcbiAgfVxuXG4gIC8vIDUuIEhhcm1mdWwgY29udGVudCBjaGVja1xuICBpZiAoY29uZmlnLmVuZ2luZXM/LmNzbTY/LmNoZWNrcz8uc2FmZXR5ICE9PSBmYWxzZSkge1xuICAgIGVuZ2luZXNSdW4ucHVzaCgnaGFybWZ1bC1jb250ZW50Jyk7XG4gICAgY29uc3QgaGFybWZ1bEZpbmRpbmdzID0gY2hlY2tIYXJtZnVsQ29udGVudChvcHRpb25zLmNvbnRlbnQpO1xuICAgIGNvbnN0IGhhcm1mdWxUYXNrID0gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIGhhc0hhcm1mdWw6IGhhcm1mdWxGaW5kaW5ncy5sZW5ndGggPiAwLFxuICAgICAgZmluZGluZ3M6IGhhcm1mdWxGaW5kaW5nc1xuICAgIH0pO1xuICAgIHRhc2tzLnB1c2goaGFybWZ1bFRhc2spO1xuICB9XG5cbiAgLy8gRXhlY3V0ZSBhbGwgdGFza3MgKHBhcmFsbGVsIG9yIHNlcXVlbnRpYWwgYmFzZWQgb24gb3B0aW9uKVxuICBsZXQgcmVzdWx0czogYW55W107XG4gIGlmIChvcHRpb25zLnBhcmFsbGVsICE9PSBmYWxzZSkge1xuICAgIHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbCh0YXNrcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFzayBvZiB0YXNrcykge1xuICAgICAgcmVzdWx0cy5wdXNoKGF3YWl0IHRhc2spO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV4dHJhY3QgcmVzdWx0c1xuICBjb25zdCB2ZXJpZmljYXRpb24gPSByZXN1bHRzWzBdIGFzIFZlcmlmeVJlc3VsdDtcbiAgbGV0IHJlc3VsdEluZGV4ID0gMTtcblxuICBjb25zdCBjbGFzc2lmaWNhdGlvbiA9IG9wdGlvbnMucHJvbXB0ID8gcmVzdWx0c1tyZXN1bHRJbmRleCsrXSBhcyBDbGFzc2lmaWNhdGlvblJlc3VsdCA6IG51bGw7XG4gIGNvbnN0IGlucHV0U2FmZXR5ID0gb3B0aW9ucy51c2VySW5wdXQgPyByZXN1bHRzW3Jlc3VsdEluZGV4KytdIDogbnVsbDtcbiAgXG4gIGxldCBwaWlDaGVjayA9IG51bGw7XG4gIGlmIChjb25maWcuZW5naW5lcz8uY3NtNj8uY2hlY2tzPy5wcml2YWN5ICE9PSBmYWxzZSkge1xuICAgIHBpaUNoZWNrID0gcmVzdWx0c1tyZXN1bHRJbmRleCsrXTtcbiAgfVxuXG4gIGxldCBoYXJtZnVsQ2hlY2sgPSBudWxsO1xuICBpZiAoY29uZmlnLmVuZ2luZXM/LmNzbTY/LmNoZWNrcz8uc2FmZXR5ICE9PSBmYWxzZSkge1xuICAgIGhhcm1mdWxDaGVjayA9IHJlc3VsdHNbcmVzdWx0SW5kZXgrK107XG4gIH1cblxuICBjb25zdCB0b3RhbExhdGVuY3lNcyA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XG5cbiAgcmV0dXJuIHtcbiAgICB2ZXJpZmljYXRpb24sXG4gICAgY2xhc3NpZmljYXRpb24sXG4gICAgaW5wdXRTYWZldHksXG4gICAgcGlpQ2hlY2ssXG4gICAgaGFybWZ1bENoZWNrLFxuICAgIG1ldGE6IHtcbiAgICAgIHByZXNldCxcbiAgICAgIGVuZ2luZXNSdW4sXG4gICAgICB0b3RhbExhdGVuY3lNcyxcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgfVxuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBRVUlDSyBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBRdWljayB2ZXJpZmljYXRpb24gd2l0aCBkZXYgcHJlc2V0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZXZWZXJpZnkoY29udGVudDogc3RyaW5nLCBwcm9tcHQ/OiBzdHJpbmcpOiBQcm9taXNlPENvcmVSdW5SZXN1bHQ+IHtcbiAgcmV0dXJuIHJ1bih7IGNvbnRlbnQsIHByb21wdCwgcHJlc2V0OiAnZGV2JyB9KTtcbn1cblxuLyoqXG4gKiBRdWljayB2ZXJpZmljYXRpb24gd2l0aCBwcm9kIHByZXNldFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvZFZlcmlmeShjb250ZW50OiBzdHJpbmcpOiBQcm9taXNlPENvcmVSdW5SZXN1bHQ+IHtcbiAgcmV0dXJuIHJ1bih7IGNvbnRlbnQsIHByZXNldDogJ3Byb2QnIH0pO1xufVxuXG4vKipcbiAqIFF1aWNrIHZlcmlmaWNhdGlvbiB3aXRoIHN0cmljdCBwcmVzZXRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0cmljdFZlcmlmeShjb250ZW50OiBzdHJpbmcsIHByb21wdD86IHN0cmluZyk6IFByb21pc2U8Q29yZVJ1blJlc3VsdD4ge1xuICByZXR1cm4gcnVuKHsgY29udGVudCwgcHJvbXB0LCBwcmVzZXQ6ICdzdHJpY3QnIH0pO1xufVxuXG4vKipcbiAqIFF1aWNrIHZlcmlmaWNhdGlvbiB3aXRoIGZhc3QgcHJlc2V0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmYXN0VmVyaWZ5KGNvbnRlbnQ6IHN0cmluZyk6IFByb21pc2U8Q29yZVJ1blJlc3VsdD4ge1xuICByZXR1cm4gcnVuKHsgY29udGVudCwgcHJlc2V0OiAnZmFzdCcgfSk7XG59XG5cbi8qKlxuICogUXVpY2sgdmVyaWZpY2F0aW9uIGZvciBDSS9DRFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2lWZXJpZnkoY29udGVudDogc3RyaW5nKTogUHJvbWlzZTxDb3JlUnVuUmVzdWx0PiB7XG4gIHJldHVybiBydW4oeyBjb250ZW50LCBwcmVzZXQ6ICdjaScgfSk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFBJUEVMSU5FIEJVSUxERVJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBQaXBlbGluZSBzdGVwIGRlZmluaXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaXBlbGluZVN0ZXAge1xuICBuYW1lOiBzdHJpbmc7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIHJ1bjogKGNvbnRlbnQ6IHN0cmluZywgY29udGV4dDogYW55KSA9PiBQcm9taXNlPGFueT47XG59XG5cbi8qKlxuICogQnVpbGQgYSBjdXN0b20gdmVyaWZpY2F0aW9uIHBpcGVsaW5lXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBwaXBlbGluZSA9IGNyZWF0ZVBpcGVsaW5lKClcbiAqICAgLmFkZFN0ZXAoJ3BpaScsIGFzeW5jIChjb250ZW50KSA9PiBjaGVja1BJSShjb250ZW50KSlcbiAqICAgLmFkZFN0ZXAoJ2luamVjdGlvbicsIGFzeW5jIChjb250ZW50KSA9PiBjaGVja1Byb21wdEluamVjdGlvbihjb250ZW50KSlcbiAqICAgLmJ1aWxkKCk7XG4gKiBcbiAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBwaXBlbGluZS5ydW4oY29udGVudCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBpcGVsaW5lKCkge1xuICBjb25zdCBzdGVwczogUGlwZWxpbmVTdGVwW10gPSBbXTtcblxuICByZXR1cm4ge1xuICAgIGFkZFN0ZXAobmFtZTogc3RyaW5nLCBydW46IChjb250ZW50OiBzdHJpbmcsIGNvbnRleHQ6IGFueSkgPT4gUHJvbWlzZTxhbnk+KSB7XG4gICAgICBzdGVwcy5wdXNoKHsgbmFtZSwgZW5hYmxlZDogdHJ1ZSwgcnVuIH0pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGRpc2FibGVTdGVwKG5hbWU6IHN0cmluZykge1xuICAgICAgY29uc3Qgc3RlcCA9IHN0ZXBzLmZpbmQocyA9PiBzLm5hbWUgPT09IG5hbWUpO1xuICAgICAgaWYgKHN0ZXApIHN0ZXAuZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGVuYWJsZVN0ZXAobmFtZTogc3RyaW5nKSB7XG4gICAgICBjb25zdCBzdGVwID0gc3RlcHMuZmluZChzID0+IHMubmFtZSA9PT0gbmFtZSk7XG4gICAgICBpZiAoc3RlcCkgc3RlcC5lbmFibGVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBidWlsZCgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFzeW5jIHJ1bihjb250ZW50OiBzdHJpbmcsIGNvbnRleHQ6IGFueSA9IHt9KSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgICAgIGNvbnN0IGVuYWJsZWRTdGVwcyA9IHN0ZXBzLmZpbHRlcihzID0+IHMuZW5hYmxlZCk7XG5cbiAgICAgICAgICAvLyBSdW4gYWxsIGVuYWJsZWQgc3RlcHMgaW4gcGFyYWxsZWxcbiAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IGVuYWJsZWRTdGVwcy5tYXAoYXN5bmMgc3RlcCA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdGVwLnJ1bihjb250ZW50LCBjb250ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IHN0ZXAubmFtZSwgcmVzdWx0IH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBzdGVwUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICBzdGVwUmVzdWx0cy5mb3JFYWNoKCh7IG5hbWUsIHJlc3VsdCB9KSA9PiB7XG4gICAgICAgICAgICByZXN1bHRzW25hbWVdID0gcmVzdWx0O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZ2V0U3RlcHMoKSB7XG4gICAgICAgICAgcmV0dXJuIHN0ZXBzLm1hcChzID0+ICh7IG5hbWU6IHMubmFtZSwgZW5hYmxlZDogcy5lbmFibGVkIH0pKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVYUE9SVFNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IHsgUFJFU0VUUyBhcyBwcmVzZXRzIH07XG5leHBvcnQgZGVmYXVsdCB7IHJ1biwgZGV2VmVyaWZ5LCBwcm9kVmVyaWZ5LCBzdHJpY3RWZXJpZnksIGZhc3RWZXJpZnksIGNpVmVyaWZ5LCBjcmVhdGVQaXBlbGluZSwgUFJFU0VUUyB9O1xuIl19