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.

197 lines 17.5 kB
"use strict"; /** * Intent Detection Module * * Detects the primary intent/purpose of LLM output. * * @module engines/classification/intent * @author Haiec * @license MIT */ Object.defineProperty(exports, "__esModule", { value: true }); exports.detectIntent = detectIntent; exports.getPrimaryIntent = getPrimaryIntent; const utils_1 = require("./utils"); /** * Intent detection patterns. */ const INTENT_PATTERNS = [ { tag: 'summary', patterns: [ /\b(in summary|to summarize|overall|in conclusion|key points?|main points?)\b/i, /\b(tldr|tl;dr|brief overview)\b/i ], weight: 1.0 }, { tag: 'explanation', patterns: [ /\b(because|therefore|this means|in other words|for example|such as)\b/i, /\b(the reason|explains?|due to|as a result)\b/i, /\b(works by|functions by|operates by)\b/i ], weight: 0.8 }, { tag: 'code', patterns: [ /```[\s\S]*```/, /\b(function|const|let|var|class|import|export|return|if|else|for|while)\b/, /[{}\[\]();]=>/, /\b(def|async|await|try|catch)\b/ ], weight: 1.0 }, { tag: 'list', patterns: [ /^[-*•]\s+/m, /^\d+[.)]\s+/m, /\b(here are|the following|steps?:|items?:)\b/i ], weight: 0.9 }, { tag: 'question', patterns: [ /\?$/m, /\b(what|why|how|when|where|who|which|would you|could you|can you)\b/i ], weight: 0.7 }, { tag: 'instruction', patterns: [ /\b(step \d|first,?|then,?|next,?|finally,?|make sure|ensure|remember to)\b/i, /\b(you should|you need to|you must|please|do not|don't)\b/i ], weight: 0.8 }, { tag: 'creative', patterns: [ /\b(once upon|imagine|picture this|in a world)\b/i, /\b(poem|story|tale|narrative|fiction)\b/i ], weight: 0.9 }, { tag: 'analysis', patterns: [ /\b(analysis|analyzing|examine|examining|evaluate|evaluating)\b/i, /\b(pros and cons|advantages|disadvantages|strengths|weaknesses)\b/i, /\b(factors|considerations|implications)\b/i ], weight: 0.8 }, { tag: 'comparison', patterns: [ /\b(compared to|versus|vs\.?|differ|difference|similar|unlike|whereas)\b/i, /\b(on the other hand|in contrast|alternatively)\b/i ], weight: 0.9 }, { tag: 'definition', patterns: [ /\b(is defined as|refers to|means|is a|are a)\b/i, /\b(definition|meaning|concept of)\b/i ], weight: 0.7 }, { tag: 'translation', patterns: [ /\b(translates? to|in [a-z]+ language|translation)\b/i ], weight: 1.0 }, { tag: 'conversation', patterns: [ /\b(hi|hello|hey|thanks|thank you|you're welcome|sure|okay|ok)\b/i, /\b(I think|I believe|in my opinion|personally)\b/i ], weight: 0.5 }, { tag: 'data', patterns: [ /\b(data|dataset|statistics|numbers|figures|metrics)\b/i, /\d+%|\d+\.\d+/, /\b(table|chart|graph)\b/i ], weight: 0.7 } ]; /** * Detects intent candidates from text. * * @param text - The text to analyze * @returns Array of intent candidates sorted by confidence */ function detectIntent(text) { const candidates = []; const words = (0, utils_1.tokenize)(text); const bullets = (0, utils_1.countBullets)(text); for (const { tag, patterns, weight } of INTENT_PATTERNS) { let matchCount = 0; const signals = []; for (const pattern of patterns) { if (pattern.test(text)) { matchCount++; signals.push(pattern.source.substring(0, 30)); } } if (matchCount > 0) { // Calculate confidence based on matches and text characteristics let confidence = (matchCount / patterns.length) * weight; // Boost for structural matches if (tag === 'list' && bullets >= 3) { confidence = Math.min(1, confidence + 0.3); } if (tag === 'code' && text.includes('```')) { confidence = Math.min(1, confidence + 0.4); } // Normalize by text length (longer text = more reliable) if (words.length < 20) { confidence *= 0.7; } else if (words.length > 100) { confidence = Math.min(1, confidence * 1.1); } candidates.push({ tag, confidence: Math.round(confidence * 100) / 100, signals }); } } // Sort by confidence descending candidates.sort((a, b) => b.confidence - a.confidence); // If no candidates, return unknown if (candidates.length === 0) { candidates.push({ tag: 'unknown', confidence: 0.5, signals: ['no_patterns_matched'] }); } return candidates; } /** * Gets the primary intent from candidates. */ function getPrimaryIntent(candidates) { if (candidates.length === 0) return null; const top = candidates[0]; // Only return if confidence is reasonable if (top.confidence >= 0.3) { return top.tag; } return null; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VuZ2luZXMvY2xhc3NpZmljYXRpb24vaW50ZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7R0FRRzs7QUFrSUgsb0NBd0RDO0FBS0QsNENBVUM7QUF0TUQsbUNBQWlEO0FBRWpEOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBSWhCO0lBQ0g7UUFDRSxHQUFHLEVBQUUsU0FBUztRQUNkLFFBQVEsRUFBRTtZQUNSLCtFQUErRTtZQUMvRSxrQ0FBa0M7U0FDbkM7UUFDRCxNQUFNLEVBQUUsR0FBRztLQUNaO0lBQ0Q7UUFDRSxHQUFHLEVBQUUsYUFBYTtRQUNsQixRQUFRLEVBQUU7WUFDUix3RUFBd0U7WUFDeEUsZ0RBQWdEO1lBQ2hELDBDQUEwQztTQUMzQztRQUNELE1BQU0sRUFBRSxHQUFHO0tBQ1o7SUFDRDtRQUNFLEdBQUcsRUFBRSxNQUFNO1FBQ1gsUUFBUSxFQUFFO1lBQ1IsZUFBZTtZQUNmLDJFQUEyRTtZQUMzRSxlQUFlO1lBQ2YsaUNBQWlDO1NBQ2xDO1FBQ0QsTUFBTSxFQUFFLEdBQUc7S0FDWjtJQUNEO1FBQ0UsR0FBRyxFQUFFLE1BQU07UUFDWCxRQUFRLEVBQUU7WUFDUixZQUFZO1lBQ1osY0FBYztZQUNkLCtDQUErQztTQUNoRDtRQUNELE1BQU0sRUFBRSxHQUFHO0tBQ1o7SUFDRDtRQUNFLEdBQUcsRUFBRSxVQUFVO1FBQ2YsUUFBUSxFQUFFO1lBQ1IsTUFBTTtZQUNOLHNFQUFzRTtTQUN2RTtRQUNELE1BQU0sRUFBRSxHQUFHO0tBQ1o7SUFDRDtRQUNFLEdBQUcsRUFBRSxhQUFhO1FBQ2xCLFFBQVEsRUFBRTtZQUNSLDZFQUE2RTtZQUM3RSw0REFBNEQ7U0FDN0Q7UUFDRCxNQUFNLEVBQUUsR0FBRztLQUNaO0lBQ0Q7UUFDRSxHQUFHLEVBQUUsVUFBVTtRQUNmLFFBQVEsRUFBRTtZQUNSLGtEQUFrRDtZQUNsRCwwQ0FBMEM7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QUM3QyxDQUFDO1lBRUQsVUFBVSxDQUFDLElBQUksQ0FBQztnQkFDZCxHQUFHO2dCQUNILFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHO2dCQUM5QyxPQUFPO2FBQ1IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRCxnQ0FBZ0M7SUFDaEMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXZELG1DQUFtQztJQUNuQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDNUIsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNkLEdBQUcsRUFBRSxTQUFTO1lBQ2QsVUFBVSxFQUFFLEdBQUc7WUFDZixPQUFPLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztTQUNqQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQUMsVUFBNkI7SUFDNUQsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUV6QyxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsMENBQTBDO0lBQzFDLElBQUksR0FBRyxDQUFDLFVBQVUsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMxQixPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW50ZW50IERldGVjdGlvbiBNb2R1bGVcbiAqIFxuICogRGV0ZWN0cyB0aGUgcHJpbWFyeSBpbnRlbnQvcHVycG9zZSBvZiBMTE0gb3V0cHV0LlxuICogXG4gKiBAbW9kdWxlIGVuZ2luZXMvY2xhc3NpZmljYXRpb24vaW50ZW50XG4gKiBAYXV0aG9yIEhhaWVjXG4gKiBAbGljZW5zZSBNSVRcbiAqL1xuXG5pbXBvcnQgeyBJbnRlbnRUYWcsIEludGVudENhbmRpZGF0ZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgY291bnRCdWxsZXRzLCB0b2tlbml6ZSB9IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIEludGVudCBkZXRlY3Rpb24gcGF0dGVybnMuXG4gKi9cbmNvbnN0IElOVEVOVF9QQVRURVJOUzogQXJyYXk8e1xuICB0YWc6IEludGVudFRhZztcbiAgcGF0dGVybnM6IFJlZ0V4cFtdO1xuICB3ZWlnaHQ6IG51bWJlcjtcbn0+ID0gW1xuICB7XG4gICAgdGFnOiAnc3VtbWFyeScsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9cXGIoaW4gc3VtbWFyeXx0byBzdW1tYXJpemV8b3ZlcmFsbHxpbiBjb25jbHVzaW9ufGtleSBwb2ludHM/fG1haW4gcG9pbnRzPylcXGIvaSxcbiAgICAgIC9cXGIodGxkcnx0bDtkcnxicmllZiBvdmVydmlldylcXGIvaVxuICAgIF0sXG4gICAgd2VpZ2h0OiAxLjBcbiAgfSxcbiAge1xuICAgIHRhZzogJ2V4cGxhbmF0aW9uJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL1xcYihiZWNhdXNlfHRoZXJlZm9yZXx0aGlzIG1lYW5zfGluIG90aGVyIHdvcmRzfGZvciBleGFtcGxlfHN1Y2ggYXMpXFxiL2ksXG4gICAgICAvXFxiKHRoZSByZWFzb258ZXhwbGFpbnM/fGR1ZSB0b3xhcyBhIHJlc3VsdClcXGIvaSxcbiAgICAgIC9cXGIod29ya3MgYnl8ZnVuY3Rpb25zIGJ5fG9wZXJhdGVzIGJ5KVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuOFxuICB9LFxuICB7XG4gICAgdGFnOiAnY29kZScsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9gYGBbXFxzXFxTXSpgYGAvLFxuICAgICAgL1xcYihmdW5jdGlvbnxjb25zdHxsZXR8dmFyfGNsYXNzfGltcG9ydHxleHBvcnR8cmV0dXJufGlmfGVsc2V8Zm9yfHdoaWxlKVxcYi8sXG4gICAgICAvW3t9XFxbXFxdKCk7XT0+LyxcbiAgICAgIC9cXGIoZGVmfGFzeW5jfGF3YWl0fHRyeXxjYXRjaClcXGIvXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDEuMFxuICB9LFxuICB7XG4gICAgdGFnOiAnbGlzdCcsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9eWy0q4oCiXVxccysvbSxcbiAgICAgIC9eXFxkK1suKV1cXHMrL20sXG4gICAgICAvXFxiKGhlcmUgYXJlfHRoZSBmb2xsb3dpbmd8c3RlcHM/OnxpdGVtcz86KVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuOVxuICB9LFxuICB7XG4gICAgdGFnOiAncXVlc3Rpb24nLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFw/JC9tLFxuICAgICAgL1xcYih3aGF0fHdoeXxob3d8d2hlbnx3aGVyZXx3aG98d2hpY2h8d291bGQgeW91fGNvdWxkIHlvdXxjYW4geW91KVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuN1xuICB9LFxuICB7XG4gICAgdGFnOiAnaW5zdHJ1Y3Rpb24nLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFxiKHN0ZXAgXFxkfGZpcnN0LD98dGhlbiw/fG5leHQsP3xmaW5hbGx5LD98bWFrZSBzdXJlfGVuc3VyZXxyZW1lbWJlciB0bylcXGIvaSxcbiAgICAgIC9cXGIoeW91IHNob3VsZHx5b3UgbmVlZCB0b3x5b3UgbXVzdHxwbGVhc2V8ZG8gbm90fGRvbid0KVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuOFxuICB9LFxuICB7XG4gICAgdGFnOiAnY3JlYXRpdmUnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFxiKG9uY2UgdXBvbnxpbWFnaW5lfHBpY3R1cmUgdGhpc3xpbiBhIHdvcmxkKVxcYi9pLFxuICAgICAgL1xcYihwb2VtfHN0b3J5fHRhbGV8bmFycmF0aXZlfGZpY3Rpb24pXFxiL2lcbiAgICBdLFxuICAgIHdlaWdodDogMC45XG4gIH0sXG4gIHtcbiAgICB0YWc6ICdhbmFseXNpcycsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9cXGIoYW5hbHlzaXN8YW5hbHl6aW5nfGV4YW1pbmV8ZXhhbWluaW5nfGV2YWx1YXRlfGV2YWx1YXRpbmcpXFxiL2ksXG4gICAgICAvXFxiKHByb3MgYW5kIGNvbnN8YWR2YW50YWdlc3xkaXNhZHZhbnRhZ2VzfHN0cmVuZ3Roc3x3ZWFrbmVzc2VzKVxcYi9pLFxuICAgICAgL1xcYihmYWN0b3JzfGNvbnNpZGVyYXRpb25zfGltcGxpY2F0aW9ucylcXGIvaVxuICAgIF0sXG4gICAgd2VpZ2h0OiAwLjhcbiAgfSxcbiAge1xuICAgIHRhZzogJ2NvbXBhcmlzb24nLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFxiKGNvbXBhcmVkIHRvfHZlcnN1c3x2c1xcLj98ZGlmZmVyfGRpZmZlcmVuY2V8c2ltaWxhcnx1bmxpa2V8d2hlcmVhcylcXGIvaSxcbiAgICAgIC9cXGIob24gdGhlIG90aGVyIGhhbmR8aW4gY29udHJhc3R8YWx0ZXJuYXRpdmVseSlcXGIvaVxuICAgIF0sXG4gICAgd2VpZ2h0OiAwLjlcbiAgfSxcbiAge1xuICAgIHRhZzogJ2RlZmluaXRpb24nLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFxiKGlzIGRlZmluZWQgYXN8cmVmZXJzIHRvfG1lYW5zfGlzIGF8YXJlIGEpXFxiL2ksXG4gICAgICAvXFxiKGRlZmluaXRpb258bWVhbmluZ3xjb25jZXB0IG9mKVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuN1xuICB9LFxuICB7XG4gICAgdGFnOiAndHJhbnNsYXRpb24nLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvXFxiKHRyYW5zbGF0ZXM/IHRvfGluIFthLXpdKyBsYW5ndWFnZXx0cmFuc2xhdGlvbilcXGIvaVxuICAgIF0sXG4gICAgd2VpZ2h0OiAxLjBcbiAgfSxcbiAge1xuICAgIHRhZzogJ2NvbnZlcnNhdGlvbicsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9cXGIoaGl8aGVsbG98aGV5fHRoYW5rc3x0aGFuayB5b3V8eW91J3JlIHdlbGNvbWV8c3VyZXxva2F5fG9rKVxcYi9pLFxuICAgICAgL1xcYihJIHRoaW5rfEkgYmVsaWV2ZXxpbiBteSBvcGluaW9ufHBlcnNvbmFsbHkpXFxiL2lcbiAgICBdLFxuICAgIHdlaWdodDogMC41XG4gIH0sXG4gIHtcbiAgICB0YWc6ICdkYXRhJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL1xcYihkYXRhfGRhdGFzZXR8c3RhdGlzdGljc3xudW1iZXJzfGZpZ3VyZXN8bWV0cmljcylcXGIvaSxcbiAgICAgIC9cXGQrJXxcXGQrXFwuXFxkKy8sXG4gICAgICAvXFxiKHRhYmxlfGNoYXJ0fGdyYXBoKVxcYi9pXG4gICAgXSxcbiAgICB3ZWlnaHQ6IDAuN1xuICB9XG5dO1xuXG4vKipcbiAqIERldGVjdHMgaW50ZW50IGNhbmRpZGF0ZXMgZnJvbSB0ZXh0LlxuICogXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSB0ZXh0IHRvIGFuYWx5emVcbiAqIEByZXR1cm5zIEFycmF5IG9mIGludGVudCBjYW5kaWRhdGVzIHNvcnRlZCBieSBjb25maWRlbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RJbnRlbnQodGV4dDogc3RyaW5nKTogSW50ZW50Q2FuZGlkYXRlW10ge1xuICBjb25zdCBjYW5kaWRhdGVzOiBJbnRlbnRDYW5kaWRhdGVbXSA9IFtdO1xuICBjb25zdCB3b3JkcyA9IHRva2VuaXplKHRleHQpO1xuICBjb25zdCBidWxsZXRzID0gY291bnRCdWxsZXRzKHRleHQpO1xuICBcbiAgZm9yIChjb25zdCB7IHRhZywgcGF0dGVybnMsIHdlaWdodCB9IG9mIElOVEVOVF9QQVRURVJOUykge1xuICAgIGxldCBtYXRjaENvdW50ID0gMDtcbiAgICBjb25zdCBzaWduYWxzOiBzdHJpbmdbXSA9IFtdO1xuICAgIFxuICAgIGZvciAoY29uc3QgcGF0dGVybiBvZiBwYXR0ZXJucykge1xuICAgICAgaWYgKHBhdHRlcm4udGVzdCh0ZXh0KSkge1xuICAgICAgICBtYXRjaENvdW50Kys7XG4gICAgICAgIHNpZ25hbHMucHVzaChwYXR0ZXJuLnNvdXJjZS5zdWJzdHJpbmcoMCwgMzApKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKG1hdGNoQ291bnQgPiAwKSB7XG4gICAgICAvLyBDYWxjdWxhdGUgY29uZmlkZW5jZSBiYXNlZCBvbiBtYXRjaGVzIGFuZCB0ZXh0IGNoYXJhY3RlcmlzdGljc1xuICAgICAgbGV0IGNvbmZpZGVuY2UgPSAobWF0Y2hDb3VudCAvIHBhdHRlcm5zLmxlbmd0aCkgKiB3ZWlnaHQ7XG4gICAgICBcbiAgICAgIC8vIEJvb3N0IGZvciBzdHJ1Y3R1cmFsIG1hdGNoZXNcbiAgICAgIGlmICh0YWcgPT09ICdsaXN0JyAmJiBidWxsZXRzID49IDMpIHtcbiAgICAgICAgY29uZmlkZW5jZSA9IE1hdGgubWluKDEsIGNvbmZpZGVuY2UgKyAwLjMpO1xuICAgICAgfVxuICAgICAgaWYgKHRhZyA9PT0gJ2NvZGUnICYmIHRleHQuaW5jbHVkZXMoJ2BgYCcpKSB7XG4gICAgICAgIGNvbmZpZGVuY2UgPSBNYXRoLm1pbigxLCBjb25maWRlbmNlICsgMC40KTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gTm9ybWFsaXplIGJ5IHRleHQgbGVuZ3RoIChsb25nZXIgdGV4dCA9IG1vcmUgcmVsaWFibGUpXG4gICAgICBpZiAod29yZHMubGVuZ3RoIDwgMjApIHtcbiAgICAgICAgY29uZmlkZW5jZSAqPSAwLjc7XG4gICAgICB9IGVsc2UgaWYgKHdvcmRzLmxlbmd0aCA+IDEwMCkge1xuICAgICAgICBjb25maWRlbmNlID0gTWF0aC5taW4oMSwgY29uZmlkZW5jZSAqIDEuMSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNhbmRpZGF0ZXMucHVzaCh7XG4gICAgICAgIHRhZyxcbiAgICAgICAgY29uZmlkZW5jZTogTWF0aC5yb3VuZChjb25maWRlbmNlICogMTAwKSAvIDEwMCxcbiAgICAgICAgc2lnbmFsc1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIFxuICAvLyBTb3J0IGJ5IGNvbmZpZGVuY2UgZGVzY2VuZGluZ1xuICBjYW5kaWRhdGVzLnNvcnQoKGEsIGIpID0+IGIuY29uZmlkZW5jZSAtIGEuY29uZmlkZW5jZSk7XG4gIFxuICAvLyBJZiBubyBjYW5kaWRhdGVzLCByZXR1cm4gdW5rbm93blxuICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICBjYW5kaWRhdGVzLnB1c2goe1xuICAgICAgdGFnOiAndW5rbm93bicsXG4gICAgICBjb25maWRlbmNlOiAwLjUsXG4gICAgICBzaWduYWxzOiBbJ25vX3BhdHRlcm5zX21hdGNoZWQnXVxuICAgIH0pO1xuICB9XG4gIFxuICByZXR1cm4gY2FuZGlkYXRlcztcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBwcmltYXJ5IGludGVudCBmcm9tIGNhbmRpZGF0ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmltYXJ5SW50ZW50KGNhbmRpZGF0ZXM6IEludGVudENhbmRpZGF0ZVtdKTogSW50ZW50VGFnIHwgbnVsbCB7XG4gIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gIFxuICBjb25zdCB0b3AgPSBjYW5kaWRhdGVzWzBdO1xuICAvLyBPbmx5IHJldHVybiBpZiBjb25maWRlbmNlIGlzIHJlYXNvbmFibGVcbiAgaWYgKHRvcC5jb25maWRlbmNlID49IDAuMykge1xuICAgIHJldHVybiB0b3AudGFnO1xuICB9XG4gIFxuICByZXR1cm4gbnVsbDtcbn1cbiJdfQ==