@thinkhive/sdk 2.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,262 @@
1
+ /**
2
+ * ThinkHive SDK v3.0 - Claims API
3
+ *
4
+ * Facts vs Inferences API for accessing analysis claims
5
+ */
6
+ import type { Claim, ClaimType, ClaimCategory, AnalysisResult, EvidenceReference } from '../core/types';
7
+ /**
8
+ * List claims query options
9
+ */
10
+ export interface ListClaimsOptions {
11
+ runId?: string;
12
+ analysisId?: string;
13
+ claimType?: ClaimType;
14
+ claimCategory?: ClaimCategory;
15
+ minConfidence?: number;
16
+ humanVerified?: boolean;
17
+ limit?: number;
18
+ offset?: number;
19
+ }
20
+ /**
21
+ * Create analysis options
22
+ */
23
+ export interface CreateAnalysisOptions {
24
+ runId: string;
25
+ modelUsed?: string;
26
+ outcomeVerdict: 'success' | 'partial_success' | 'failure';
27
+ outcomeConfidence?: number;
28
+ rootCauseCategory?: string;
29
+ rootCauseConfidence?: number;
30
+ claims?: CreateClaimInput[];
31
+ }
32
+ export interface CreateClaimInput {
33
+ claimType: ClaimType;
34
+ claimCategory: ClaimCategory;
35
+ claimText: string;
36
+ confidence: number;
37
+ confidenceCalibration?: 'calibrated' | 'uncalibrated' | 'needs_more_data';
38
+ evidence?: EvidenceReference[];
39
+ isExplainable?: boolean;
40
+ probabilityValue?: number;
41
+ }
42
+ /**
43
+ * Facts vs inferences summary
44
+ */
45
+ export interface FactsVsInferencesSummary {
46
+ analysisIds: string[];
47
+ totalClaims: number;
48
+ observed: {
49
+ count: number;
50
+ avgConfidence: number;
51
+ categories: Record<string, number>;
52
+ };
53
+ inferred: {
54
+ count: number;
55
+ avgConfidence: number;
56
+ categories: Record<string, number>;
57
+ };
58
+ computed: {
59
+ count: number;
60
+ avgConfidence: number;
61
+ categories: Record<string, number>;
62
+ };
63
+ humanVerifiedCount: number;
64
+ humanRejectedCount: number;
65
+ }
66
+ /**
67
+ * Claims API client for facts vs inferences management
68
+ */
69
+ export declare const claims: {
70
+ /**
71
+ * Create a new analysis for a run
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const analysis = await claims.createAnalysis({
76
+ * runId: 'run_abc123',
77
+ * outcomeVerdict: 'failure',
78
+ * outcomeConfidence: 0.85,
79
+ * rootCauseCategory: 'retrieval_failure',
80
+ * claims: [
81
+ * {
82
+ * claimType: 'observed',
83
+ * claimCategory: 'root_cause',
84
+ * claimText: 'Vector search returned 0 results',
85
+ * confidence: 1.0,
86
+ * evidence: [{ type: 'span', referenceId: 'span_123', relevance: 'direct', confidence: 1.0 }],
87
+ * },
88
+ * {
89
+ * claimType: 'inferred',
90
+ * claimCategory: 'churn_risk',
91
+ * claimText: 'High churn risk due to repeated failures',
92
+ * confidence: 0.7,
93
+ * },
94
+ * ],
95
+ * });
96
+ * ```
97
+ */
98
+ createAnalysis(options: CreateAnalysisOptions): Promise<AnalysisResult>;
99
+ /**
100
+ * Get an analysis by ID
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const analysis = await claims.getAnalysis('analysis_abc123');
105
+ * ```
106
+ */
107
+ getAnalysis(analysisId: string): Promise<AnalysisResult>;
108
+ /**
109
+ * Get current analysis for a run
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const analysis = await claims.getRunAnalysis('run_abc123');
114
+ * ```
115
+ */
116
+ getRunAnalysis(runId: string): Promise<AnalysisResult>;
117
+ /**
118
+ * Get analysis history for a run
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const history = await claims.getAnalysisHistory('run_abc123');
123
+ * ```
124
+ */
125
+ getAnalysisHistory(runId: string): Promise<{
126
+ runId: string;
127
+ analyses: Array<{
128
+ id: string;
129
+ analysisVersion: string;
130
+ modelUsed: string;
131
+ outcomeVerdict: string;
132
+ isCurrent: boolean;
133
+ supersededBy?: string;
134
+ supersessionReason?: string;
135
+ analyzedAt: string;
136
+ }>;
137
+ }>;
138
+ /**
139
+ * Supersede an analysis with a new one
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const newAnalysis = await claims.supersedeAnalysis('analysis_old', {
144
+ * reason: 'Improved model accuracy',
145
+ * newAnalysis: {
146
+ * outcomeVerdict: 'success',
147
+ * outcomeConfidence: 0.95,
148
+ * claims: [...],
149
+ * },
150
+ * });
151
+ * ```
152
+ */
153
+ supersedeAnalysis(analysisId: string, options: {
154
+ reason: string;
155
+ newAnalysis: Omit<CreateAnalysisOptions, "runId">;
156
+ }): Promise<{
157
+ supersededAnalysisId: string;
158
+ newAnalysis: AnalysisResult;
159
+ }>;
160
+ /**
161
+ * List claims with filters
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * // Get all inferred claims with high confidence
166
+ * const { claims } = await claims.list({
167
+ * claimType: 'inferred',
168
+ * minConfidence: 0.8,
169
+ * });
170
+ *
171
+ * // Get all churn risk claims for a run
172
+ * const { claims } = await claims.list({
173
+ * runId: 'run_abc123',
174
+ * claimCategory: 'churn_risk',
175
+ * });
176
+ * ```
177
+ */
178
+ list(options?: ListClaimsOptions): Promise<{
179
+ claims: Claim[];
180
+ limit: number;
181
+ offset: number;
182
+ hasMore: boolean;
183
+ }>;
184
+ /**
185
+ * Get a claim by ID
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const claim = await claims.get('claim_abc123');
190
+ * ```
191
+ */
192
+ get(claimId: string): Promise<Claim>;
193
+ /**
194
+ * Verify or reject a claim (human feedback)
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * // Confirm a claim
199
+ * await claims.verify('claim_abc123', {
200
+ * verdict: 'confirmed',
201
+ * notes: 'Verified against ticket history',
202
+ * });
203
+ *
204
+ * // Reject a claim
205
+ * await claims.verify('claim_abc123', {
206
+ * verdict: 'rejected',
207
+ * notes: 'Customer context was missing',
208
+ * });
209
+ * ```
210
+ */
211
+ verify(claimId: string, options: {
212
+ verdict: "confirmed" | "rejected" | "modified";
213
+ notes?: string;
214
+ modifiedText?: string;
215
+ }): Promise<{
216
+ claimId: string;
217
+ verdict: string;
218
+ message: string;
219
+ }>;
220
+ /**
221
+ * Get facts vs inferences summary
222
+ *
223
+ * @example
224
+ * ```typescript
225
+ * // Summary for a specific run
226
+ * const summary = await claims.summary({ runId: 'run_abc123' });
227
+ *
228
+ * // Summary for multiple analyses
229
+ * const summary = await claims.summary({
230
+ * analysisIds: ['analysis_1', 'analysis_2'],
231
+ * });
232
+ * ```
233
+ */
234
+ summary(options?: {
235
+ runId?: string;
236
+ analysisIds?: string[];
237
+ }): Promise<FactsVsInferencesSummary>;
238
+ };
239
+ /**
240
+ * Check if a claim is a fact (observed)
241
+ */
242
+ export declare function isFact(claim: Claim): boolean;
243
+ /**
244
+ * Check if a claim is an inference
245
+ */
246
+ export declare function isInference(claim: Claim): boolean;
247
+ /**
248
+ * Check if a claim is computed
249
+ */
250
+ export declare function isComputed(claim: Claim): boolean;
251
+ /**
252
+ * Get high confidence claims (>= threshold)
253
+ */
254
+ export declare function getHighConfidenceClaims(claimsList: Claim[], threshold?: number): Claim[];
255
+ /**
256
+ * Group claims by type
257
+ */
258
+ export declare function groupClaimsByType(claimsList: Claim[]): Record<ClaimType, Claim[]>;
259
+ /**
260
+ * Group claims by category
261
+ */
262
+ export declare function groupClaimsByCategory(claimsList: Claim[]): Record<ClaimCategory, Claim[]>;
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ /**
3
+ * ThinkHive SDK v3.0 - Claims API
4
+ *
5
+ * Facts vs Inferences API for accessing analysis claims
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.claims = void 0;
9
+ exports.isFact = isFact;
10
+ exports.isInference = isInference;
11
+ exports.isComputed = isComputed;
12
+ exports.getHighConfidenceClaims = getHighConfidenceClaims;
13
+ exports.groupClaimsByType = groupClaimsByType;
14
+ exports.groupClaimsByCategory = groupClaimsByCategory;
15
+ const client_1 = require("../core/client");
16
+ /**
17
+ * Claims API client for facts vs inferences management
18
+ */
19
+ exports.claims = {
20
+ /**
21
+ * Create a new analysis for a run
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const analysis = await claims.createAnalysis({
26
+ * runId: 'run_abc123',
27
+ * outcomeVerdict: 'failure',
28
+ * outcomeConfidence: 0.85,
29
+ * rootCauseCategory: 'retrieval_failure',
30
+ * claims: [
31
+ * {
32
+ * claimType: 'observed',
33
+ * claimCategory: 'root_cause',
34
+ * claimText: 'Vector search returned 0 results',
35
+ * confidence: 1.0,
36
+ * evidence: [{ type: 'span', referenceId: 'span_123', relevance: 'direct', confidence: 1.0 }],
37
+ * },
38
+ * {
39
+ * claimType: 'inferred',
40
+ * claimCategory: 'churn_risk',
41
+ * claimText: 'High churn risk due to repeated failures',
42
+ * confidence: 0.7,
43
+ * },
44
+ * ],
45
+ * });
46
+ * ```
47
+ */
48
+ async createAnalysis(options) {
49
+ return (0, client_1.apiRequestWithData)('/analyses', {
50
+ method: 'POST',
51
+ body: options,
52
+ });
53
+ },
54
+ /**
55
+ * Get an analysis by ID
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const analysis = await claims.getAnalysis('analysis_abc123');
60
+ * ```
61
+ */
62
+ async getAnalysis(analysisId) {
63
+ return (0, client_1.apiRequestWithData)(`/analyses/${analysisId}`);
64
+ },
65
+ /**
66
+ * Get current analysis for a run
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const analysis = await claims.getRunAnalysis('run_abc123');
71
+ * ```
72
+ */
73
+ async getRunAnalysis(runId) {
74
+ return (0, client_1.apiRequestWithData)(`/runs/${runId}/analysis`);
75
+ },
76
+ /**
77
+ * Get analysis history for a run
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const history = await claims.getAnalysisHistory('run_abc123');
82
+ * ```
83
+ */
84
+ async getAnalysisHistory(runId) {
85
+ return (0, client_1.apiRequestWithData)(`/runs/${runId}/analyses`);
86
+ },
87
+ /**
88
+ * Supersede an analysis with a new one
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const newAnalysis = await claims.supersedeAnalysis('analysis_old', {
93
+ * reason: 'Improved model accuracy',
94
+ * newAnalysis: {
95
+ * outcomeVerdict: 'success',
96
+ * outcomeConfidence: 0.95,
97
+ * claims: [...],
98
+ * },
99
+ * });
100
+ * ```
101
+ */
102
+ async supersedeAnalysis(analysisId, options) {
103
+ return (0, client_1.apiRequestWithData)(`/analyses/${analysisId}/supersede`, {
104
+ method: 'POST',
105
+ body: options,
106
+ });
107
+ },
108
+ /**
109
+ * List claims with filters
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * // Get all inferred claims with high confidence
114
+ * const { claims } = await claims.list({
115
+ * claimType: 'inferred',
116
+ * minConfidence: 0.8,
117
+ * });
118
+ *
119
+ * // Get all churn risk claims for a run
120
+ * const { claims } = await claims.list({
121
+ * runId: 'run_abc123',
122
+ * claimCategory: 'churn_risk',
123
+ * });
124
+ * ```
125
+ */
126
+ async list(options = {}) {
127
+ const params = new URLSearchParams();
128
+ if (options.runId)
129
+ params.set('runId', options.runId);
130
+ if (options.analysisId)
131
+ params.set('analysisId', options.analysisId);
132
+ if (options.claimType)
133
+ params.set('claimType', options.claimType);
134
+ if (options.claimCategory)
135
+ params.set('claimCategory', options.claimCategory);
136
+ if (options.minConfidence !== undefined) {
137
+ params.set('minConfidence', String(options.minConfidence));
138
+ }
139
+ if (options.humanVerified !== undefined) {
140
+ params.set('humanVerified', String(options.humanVerified));
141
+ }
142
+ if (options.limit)
143
+ params.set('limit', String(options.limit));
144
+ if (options.offset)
145
+ params.set('offset', String(options.offset));
146
+ const response = await (0, client_1.apiRequest)(`/claims?${params.toString()}`);
147
+ return response.data;
148
+ },
149
+ /**
150
+ * Get a claim by ID
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const claim = await claims.get('claim_abc123');
155
+ * ```
156
+ */
157
+ async get(claimId) {
158
+ return (0, client_1.apiRequestWithData)(`/claims/${claimId}`);
159
+ },
160
+ /**
161
+ * Verify or reject a claim (human feedback)
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * // Confirm a claim
166
+ * await claims.verify('claim_abc123', {
167
+ * verdict: 'confirmed',
168
+ * notes: 'Verified against ticket history',
169
+ * });
170
+ *
171
+ * // Reject a claim
172
+ * await claims.verify('claim_abc123', {
173
+ * verdict: 'rejected',
174
+ * notes: 'Customer context was missing',
175
+ * });
176
+ * ```
177
+ */
178
+ async verify(claimId, options) {
179
+ return (0, client_1.apiRequestWithData)(`/claims/${claimId}/verify`, {
180
+ method: 'POST',
181
+ body: options,
182
+ });
183
+ },
184
+ /**
185
+ * Get facts vs inferences summary
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * // Summary for a specific run
190
+ * const summary = await claims.summary({ runId: 'run_abc123' });
191
+ *
192
+ * // Summary for multiple analyses
193
+ * const summary = await claims.summary({
194
+ * analysisIds: ['analysis_1', 'analysis_2'],
195
+ * });
196
+ * ```
197
+ */
198
+ async summary(options = {}) {
199
+ const params = new URLSearchParams();
200
+ if (options.runId)
201
+ params.set('runId', options.runId);
202
+ if (options.analysisIds)
203
+ params.set('analysisIds', options.analysisIds.join(','));
204
+ return (0, client_1.apiRequestWithData)(`/claims/summary?${params.toString()}`);
205
+ },
206
+ };
207
+ // ============================================================================
208
+ // HELPER FUNCTIONS
209
+ // ============================================================================
210
+ /**
211
+ * Check if a claim is a fact (observed)
212
+ */
213
+ function isFact(claim) {
214
+ return claim.claimType === 'observed';
215
+ }
216
+ /**
217
+ * Check if a claim is an inference
218
+ */
219
+ function isInference(claim) {
220
+ return claim.claimType === 'inferred';
221
+ }
222
+ /**
223
+ * Check if a claim is computed
224
+ */
225
+ function isComputed(claim) {
226
+ return claim.claimType === 'computed';
227
+ }
228
+ /**
229
+ * Get high confidence claims (>= threshold)
230
+ */
231
+ function getHighConfidenceClaims(claimsList, threshold = 0.8) {
232
+ return claimsList.filter((c) => c.confidence >= threshold);
233
+ }
234
+ /**
235
+ * Group claims by type
236
+ */
237
+ function groupClaimsByType(claimsList) {
238
+ return {
239
+ observed: claimsList.filter((c) => c.claimType === 'observed'),
240
+ inferred: claimsList.filter((c) => c.claimType === 'inferred'),
241
+ computed: claimsList.filter((c) => c.claimType === 'computed'),
242
+ };
243
+ }
244
+ /**
245
+ * Group claims by category
246
+ */
247
+ function groupClaimsByCategory(claimsList) {
248
+ const groups = {
249
+ outcome: [],
250
+ root_cause: [],
251
+ customer_impact: [],
252
+ churn_risk: [],
253
+ revenue_impact: [],
254
+ quality: [],
255
+ other: [],
256
+ };
257
+ for (const claim of claimsList) {
258
+ groups[claim.claimCategory].push(claim);
259
+ }
260
+ return groups;
261
+ }
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhaW1zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9jbGFpbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQTBUSCx3QkFFQztBQUtELGtDQUVDO0FBS0QsZ0NBRUM7QUFLRCwwREFLQztBQUtELDhDQVFDO0FBS0Qsc0RBa0JDO0FBdFhELDJDQUFnRTtBQThFaEU7O0dBRUc7QUFDVSxRQUFBLE1BQU0sR0FBRztJQUNwQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMkJHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUE4QjtRQUNqRCxPQUFPLElBQUEsMkJBQWtCLEVBQWlCLFdBQVcsRUFBRTtZQUNyRCxNQUFNLEVBQUUsTUFBTTtZQUNkLElBQUksRUFBRSxPQUFPO1NBQ2QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLFVBQWtCO1FBQ2xDLE9BQU8sSUFBQSwyQkFBa0IsRUFBaUIsYUFBYSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFhO1FBQ2hDLE9BQU8sSUFBQSwyQkFBa0IsRUFBaUIsU0FBUyxLQUFLLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQWE7UUFhcEMsT0FBTyxJQUFBLDJCQUFrQixFQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQ3JCLFVBQWtCLEVBQ2xCLE9BR0M7UUFFRCxPQUFPLElBQUEsMkJBQWtCLEVBQUMsYUFBYSxVQUFVLFlBQVksRUFBRTtZQUM3RCxNQUFNLEVBQUUsTUFBTTtZQUNkLElBQUksRUFBRSxP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RTtRQUNkLGNBQWMsRUFBRSxFQUFFO1FBQ2xCLE9BQU8sRUFBRSxFQUFFO1FBQ1gsS0FBSyxFQUFFLEVBQUU7S0FDVixDQUFDO0lBRUYsS0FBSyxNQUFNLEtBQUssSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpbmtIaXZlIFNESyB2My4wIC0gQ2xhaW1zIEFQSVxuICpcbiAqIEZhY3RzIHZzIEluZmVyZW5jZXMgQVBJIGZvciBhY2Nlc3NpbmcgYW5hbHlzaXMgY2xhaW1zXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdCwgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuaW1wb3J0IHR5cGUge1xuICBDbGFpbSxcbiAgQ2xhaW1UeXBlLFxuICBDbGFpbUNhdGVnb3J5LFxuICBBbmFseXNpc1Jlc3VsdCxcbiAgQXBpUmVzcG9uc2UsXG4gIFBhZ2luYXRlZFJlc3BvbnNlLFxuICBFdmlkZW5jZVJlZmVyZW5jZSxcbn0gZnJvbSAnLi4vY29yZS90eXBlcyc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENMQUlNUyBBUEkgQ0xJRU5UXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogTGlzdCBjbGFpbXMgcXVlcnkgb3B0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RDbGFpbXNPcHRpb25zIHtcbiAgcnVuSWQ/OiBzdHJpbmc7XG4gIGFuYWx5c2lzSWQ/OiBzdHJpbmc7XG4gIGNsYWltVHlwZT86IENsYWltVHlwZTtcbiAgY2xhaW1DYXRlZ29yeT86IENsYWltQ2F0ZWdvcnk7XG4gIG1pbkNvbmZpZGVuY2U/OiBudW1iZXI7XG4gIGh1bWFuVmVyaWZpZWQ/OiBib29sZWFuO1xuICBsaW1pdD86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbmFseXNpcyBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlQW5hbHlzaXNPcHRpb25zIHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgbW9kZWxVc2VkPzogc3RyaW5nO1xuICBvdXRjb21lVmVyZGljdDogJ3N1Y2Nlc3MnIHwgJ3BhcnRpYWxfc3VjY2VzcycgfCAnZmFpbHVyZSc7XG4gIG91dGNvbWVDb25maWRlbmNlPzogbnVtYmVyO1xuICByb290Q2F1c2VDYXRlZ29yeT86IHN0cmluZztcbiAgcm9vdENhdXNlQ29uZmlkZW5jZT86IG51bWJlcjtcbiAgY2xhaW1zPzogQ3JlYXRlQ2xhaW1JbnB1dFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUNsYWltSW5wdXQge1xuICBjbGFpbVR5cGU6IENsYWltVHlwZTtcbiAgY2xhaW1DYXRlZ29yeTogQ2xhaW1DYXRlZ29yeTtcbiAgY2xhaW1UZXh0OiBzdHJpbmc7XG4gIGNvbmZpZGVuY2U6IG51bWJlcjtcbiAgY29uZmlkZW5jZUNhbGlicmF0aW9uPzogJ2NhbGlicmF0ZWQnIHwgJ3VuY2FsaWJyYXRlZCcgfCAnbmVlZHNfbW9yZV9kYXRhJztcbiAgZXZpZGVuY2U/OiBFdmlkZW5jZVJlZmVyZW5jZVtdO1xuICBpc0V4cGxhaW5hYmxlPzogYm9vbGVhbjtcbiAgcHJvYmFiaWxpdHlWYWx1ZT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBGYWN0cyB2cyBpbmZlcmVuY2VzIHN1bW1hcnlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGYWN0c1ZzSW5mZXJlbmNlc1N1bW1hcnkge1xuICBhbmFseXNpc0lkczogc3RyaW5nW107XG4gIHRvdGFsQ2xhaW1zOiBudW1iZXI7XG4gIG9ic2VydmVkOiB7XG4gICAgY291bnQ6IG51bWJlcjtcbiAgICBhdmdDb25maWRlbmNlOiBudW1iZXI7XG4gICAgY2F0ZWdvcmllczogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgfTtcbiAgaW5mZXJyZWQ6IHtcbiAgICBjb3VudDogbnVtYmVyO1xuICAgIGF2Z0NvbmZpZGVuY2U6IG51bWJlcjtcbiAgICBjYXRlZ29yaWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICB9O1xuICBjb21wdXRlZDoge1xuICAgIGNvdW50OiBudW1iZXI7XG4gICAgYXZnQ29uZmlkZW5jZTogbnVtYmVyO1xuICAgIGNhdGVnb3JpZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG4gIH07XG4gIGh1bWFuVmVyaWZpZWRDb3VudDogbnVtYmVyO1xuICBodW1hblJlamVjdGVkQ291bnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBDbGFpbXMgQVBJIGNsaWVudCBmb3IgZmFjdHMgdnMgaW5mZXJlbmNlcyBtYW5hZ2VtZW50XG4gKi9cbmV4cG9ydCBjb25zdCBjbGFpbXMgPSB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgYW5hbHlzaXMgZm9yIGEgcnVuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgYW5hbHlzaXMgPSBhd2FpdCBjbGFpbXMuY3JlYXRlQW5hbHlzaXMoe1xuICAgKiAgIHJ1bklkOiAncnVuX2FiYzEyMycsXG4gICAqICAgb3V0Y29tZVZlcmRpY3Q6ICdmYWlsdXJlJyxcbiAgICogICBvdXRjb21lQ29uZmlkZW5jZTogMC44NSxcbiAgICogICByb290Q2F1c2VDYXRlZ29yeTogJ3JldHJpZXZhbF9mYWlsdXJlJyxcbiAgICogICBjbGFpbXM6IFtcbiAgICogICAgIHtcbiAgICogICAgICAgY2xhaW1UeXBlOiAnb2JzZXJ2ZWQnLFxuICAgKiAgICAgICBjbGFpbUNhdGVnb3J5OiAncm9vdF9jYXVzZScsXG4gICAqICAgICAgIGNsYWltVGV4dDogJ1ZlY3RvciBzZWFyY2ggcmV0dXJuZWQgMCByZXN1bHRzJyxcbiAgICogICAgICAgY29uZmlkZW5jZTogMS4wLFxuICAgKiAgICAgICBldmlkZW5jZTogW3sgdHlwZTogJ3NwYW4nLCByZWZlcmVuY2VJZDogJ3NwYW5fMTIzJywgcmVsZXZhbmNlOiAnZGlyZWN0JywgY29uZmlkZW5jZTogMS4wIH1dLFxuICAgKiAgICAgfSxcbiAgICogICAgIHtcbiAgICogICAgICAgY2xhaW1UeXBlOiAnaW5mZXJyZWQnLFxuICAgKiAgICAgICBjbGFpbUNhdGVnb3J5OiAnY2h1cm5fcmlzaycsXG4gICAqICAgICAgIGNsYWltVGV4dDogJ0hpZ2ggY2h1cm4gcmlzayBkdWUgdG8gcmVwZWF0ZWQgZmFpbHVyZXMnLFxuICAgKiAgICAgICBjb25maWRlbmNlOiAwLjcsXG4gICAqICAgICB9LFxuICAgKiAgIF0sXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGNyZWF0ZUFuYWx5c2lzKG9wdGlvbnM6IENyZWF0ZUFuYWx5c2lzT3B0aW9ucyk6IFByb21pc2U8QW5hbHlzaXNSZXN1bHQ+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEFuYWx5c2lzUmVzdWx0PignL2FuYWx5c2VzJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgYW4gYW5hbHlzaXMgYnkgSURcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBhbmFseXNpcyA9IGF3YWl0IGNsYWltcy5nZXRBbmFseXNpcygnYW5hbHlzaXNfYWJjMTIzJyk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0QW5hbHlzaXMoYW5hbHlzaXNJZDogc3RyaW5nKTogUHJvbWlzZTxBbmFseXNpc1Jlc3VsdD4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8QW5hbHlzaXNSZXN1bHQ+KGAvYW5hbHlzZXMvJHthbmFseXNpc0lkfWApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBhbmFseXNpcyBmb3IgYSBydW5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBhbmFseXNpcyA9IGF3YWl0IGNsYWltcy5nZXRSdW5BbmFseXNpcygncnVuX2FiYzEyMycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldFJ1bkFuYWx5c2lzKHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPEFuYWx5c2lzUmVzdWx0PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxBbmFseXNpc1Jlc3VsdD4oYC9ydW5zLyR7cnVuSWR9L2FuYWx5c2lzYCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhbmFseXNpcyBoaXN0b3J5IGZvciBhIHJ1blxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IGhpc3RvcnkgPSBhd2FpdCBjbGFpbXMuZ2V0QW5hbHlzaXNIaXN0b3J5KCdydW5fYWJjMTIzJyk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0QW5hbHlzaXNIaXN0b3J5KHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgICBydW5JZDogc3RyaW5nO1xuICAgIGFuYWx5c2VzOiBBcnJheTx7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgYW5hbHlzaXNWZXJzaW9uOiBzdHJpbmc7XG4gICAgICBtb2RlbFVzZWQ6IHN0cmluZztcbiAgICAgIG91dGNvbWVWZXJkaWN0OiBzdHJpbmc7XG4gICAgICBpc0N1cnJlbnQ6IGJvb2xlYW47XG4gICAgICBzdXBlcnNlZGVkQnk/OiBzdHJpbmc7XG4gICAgICBzdXBlcnNlc3Npb25SZWFzb24/OiBzdHJpbmc7XG4gICAgICBhbmFseXplZEF0OiBzdHJpbmc7XG4gICAgfT47XG4gIH0+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhKGAvcnVucy8ke3J1bklkfS9hbmFseXNlc2ApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBTdXBlcnNlZGUgYW4gYW5hbHlzaXMgd2l0aCBhIG5ldyBvbmVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBuZXdBbmFseXNpcyA9IGF3YWl0IGNsYWltcy5zdXBlcnNlZGVBbmFseXNpcygnYW5hbHlzaXNfb2xkJywge1xuICAgKiAgIHJlYXNvbjogJ0ltcHJvdmVkIG1vZGVsIGFjY3VyYWN5JyxcbiAgICogICBuZXdBbmFseXNpczoge1xuICAgKiAgICAgb3V0Y29tZVZlcmRpY3Q6ICdzdWNjZXNzJyxcbiAgICogICAgIG91dGNvbWVDb25maWRlbmNlOiAwLjk1LFxuICAgKiAgICAgY2xhaW1zOiBbLi4uXSxcbiAgICogICB9LFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBzdXBlcnNlZGVBbmFseXNpcyhcbiAgICBhbmFseXNpc0lkOiBzdHJpbmcsXG4gICAgb3B0aW9uczoge1xuICAgICAgcmVhc29uOiBzdHJpbmc7XG4gICAgICBuZXdBbmFseXNpczogT21pdDxDcmVhdGVBbmFseXNpc09wdGlvbnMsICdydW5JZCc+O1xuICAgIH1cbiAgKTogUHJvbWlzZTx7IHN1cGVyc2VkZWRBbmFseXNpc0lkOiBzdHJpbmc7IG5ld0FuYWx5c2lzOiBBbmFseXNpc1Jlc3VsdCB9PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YShgL2FuYWx5c2VzLyR7YW5hbHlzaXNJZH0vc3VwZXJzZWRlYCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBMaXN0IGNsYWltcyB3aXRoIGZpbHRlcnNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiAvLyBHZXQgYWxsIGluZmVycmVkIGNsYWltcyB3aXRoIGhpZ2ggY29uZmlkZW5jZVxuICAgKiBjb25zdCB7IGNsYWltcyB9ID0gYXdhaXQgY2xhaW1zLmxpc3Qoe1xuICAgKiAgIGNsYWltVHlwZTogJ2luZmVycmVkJyxcbiAgICogICBtaW5Db25maWRlbmNlOiAwLjgsXG4gICAqIH0pO1xuICAgKlxuICAgKiAvLyBHZXQgYWxsIGNodXJuIHJpc2sgY2xhaW1zIGZvciBhIHJ1blxuICAgKiBjb25zdCB7IGNsYWltcyB9ID0gYXdhaXQgY2xhaW1zLmxpc3Qoe1xuICAgKiAgIHJ1bklkOiAncnVuX2FiYzEyMycsXG4gICAqICAgY2xhaW1DYXRlZ29yeTogJ2NodXJuX3Jpc2snLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBsaXN0KFxuICAgIG9wdGlvbnM6IExpc3RDbGFpbXNPcHRpb25zID0ge31cbiAgKTogUHJvbWlzZTx7IGNsYWltczogQ2xhaW1bXTsgbGltaXQ6IG51bWJlcjsgb2Zmc2V0OiBudW1iZXI7IGhhc01vcmU6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICBpZiAob3B0aW9ucy5ydW5JZCkgcGFyYW1zLnNldCgncnVuSWQnLCBvcHRpb25zLnJ1bklkKTtcbiAgICBpZiAob3B0aW9ucy5hbmFseXNpc0lkKSBwYXJhbXMuc2V0KCdhbmFseXNpc0lkJywgb3B0aW9ucy5hbmFseXNpc0lkKTtcbiAgICBpZiAob3B0aW9ucy5jbGFpbVR5cGUpIHBhcmFtcy5zZXQoJ2NsYWltVHlwZScsIG9wdGlvbnMuY2xhaW1UeXBlKTtcbiAgICBpZiAob3B0aW9ucy5jbGFpbUNhdGVnb3J5KSBwYXJhbXMuc2V0KCdjbGFpbUNhdGVnb3J5Jywgb3B0aW9ucy5jbGFpbUNhdGVnb3J5KTtcbiAgICBpZiAob3B0aW9ucy5taW5Db25maWRlbmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtcy5zZXQoJ21pbkNvbmZpZGVuY2UnLCBTdHJpbmcob3B0aW9ucy5taW5Db25maWRlbmNlKSk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmh1bWFuVmVyaWZpZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFyYW1zLnNldCgnaHVtYW5WZXJpZmllZCcsIFN0cmluZyhvcHRpb25zLmh1bWFuVmVyaWZpZWQpKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMubGltaXQpIHBhcmFtcy5zZXQoJ2xpbWl0JywgU3RyaW5nKG9wdGlvbnMubGltaXQpKTtcbiAgICBpZiAob3B0aW9ucy5vZmZzZXQpIHBhcmFtcy5zZXQoJ29mZnNldCcsIFN0cmluZyhvcHRpb25zLm9mZnNldCkpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhcGlSZXF1ZXN0PEFwaVJlc3BvbnNlPHsgY2xhaW1zOiBDbGFpbVtdOyBsaW1pdDogbnVtYmVyOyBvZmZzZXQ6IG51bWJlcjsgaGFzTW9yZTogYm9vbGVhbiB9Pj4oXG4gICAgICBgL2NsYWltcz8ke3BhcmFtcy50b1N0cmluZygpfWBcbiAgICApO1xuICAgIHJldHVybiByZXNwb25zZS5kYXRhITtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGEgY2xhaW0gYnkgSURcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBjbGFpbSA9IGF3YWl0IGNsYWltcy5nZXQoJ2NsYWltX2FiYzEyMycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldChjbGFpbUlkOiBzdHJpbmcpOiBQcm9taXNlPENsYWltPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxDbGFpbT4oYC9jbGFpbXMvJHtjbGFpbUlkfWApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBWZXJpZnkgb3IgcmVqZWN0IGEgY2xhaW0gKGh1bWFuIGZlZWRiYWNrKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIC8vIENvbmZpcm0gYSBjbGFpbVxuICAgKiBhd2FpdCBjbGFpbXMudmVyaWZ5KCdjbGFpbV9hYmMxMjMnLCB7XG4gICAqICAgdmVyZGljdDogJ2NvbmZpcm1lZCcsXG4gICAqICAgbm90ZXM6ICdWZXJpZmllZCBhZ2FpbnN0IHRpY2tldCBoaXN0b3J5JyxcbiAgICogfSk7XG4gICAqXG4gICAqIC8vIFJlamVjdCBhIGNsYWltXG4gICAqIGF3YWl0IGNsYWltcy52ZXJpZnkoJ2NsYWltX2FiYzEyMycsIHtcbiAgICogICB2ZXJkaWN0OiAncmVqZWN0ZWQnLFxuICAgKiAgIG5vdGVzOiAnQ3VzdG9tZXIgY29udGV4dCB3YXMgbWlzc2luZycsXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIHZlcmlmeShcbiAgICBjbGFpbUlkOiBzdHJpbmcsXG4gICAgb3B0aW9uczoge1xuICAgICAgdmVyZGljdDogJ2NvbmZpcm1lZCcgfCAncmVqZWN0ZWQnIHwgJ21vZGlmaWVkJztcbiAgICAgIG5vdGVzPzogc3RyaW5nO1xuICAgICAgbW9kaWZpZWRUZXh0Pzogc3RyaW5nO1xuICAgIH1cbiAgKTogUHJvbWlzZTx7IGNsYWltSWQ6IHN0cmluZzsgdmVyZGljdDogc3RyaW5nOyBtZXNzYWdlOiBzdHJpbmcgfT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGEoYC9jbGFpbXMvJHtjbGFpbUlkfS92ZXJpZnlgLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBmYWN0cyB2cyBpbmZlcmVuY2VzIHN1bW1hcnlcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiAvLyBTdW1tYXJ5IGZvciBhIHNwZWNpZmljIHJ1blxuICAgKiBjb25zdCBzdW1tYXJ5ID0gYXdhaXQgY2xhaW1zLnN1bW1hcnkoeyBydW5JZDogJ3J1bl9hYmMxMjMnIH0pO1xuICAgKlxuICAgKiAvLyBTdW1tYXJ5IGZvciBtdWx0aXBsZSBhbmFseXNlc1xuICAgKiBjb25zdCBzdW1tYXJ5ID0gYXdhaXQgY2xhaW1zLnN1bW1hcnkoe1xuICAgKiAgIGFuYWx5c2lzSWRzOiBbJ2FuYWx5c2lzXzEnLCAnYW5hbHlzaXNfMiddLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBzdW1tYXJ5KFxuICAgIG9wdGlvbnM6IHsgcnVuSWQ/OiBzdHJpbmc7IGFuYWx5c2lzSWRzPzogc3RyaW5nW10gfSA9IHt9XG4gICk6IFByb21pc2U8RmFjdHNWc0luZmVyZW5jZXNTdW1tYXJ5PiB7XG4gICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgIGlmIChvcHRpb25zLnJ1bklkKSBwYXJhbXMuc2V0KCdydW5JZCcsIG9wdGlvbnMucnVuSWQpO1xuICAgIGlmIChvcHRpb25zLmFuYWx5c2lzSWRzKSBwYXJhbXMuc2V0KCdhbmFseXNpc0lkcycsIG9wdGlvbnMuYW5hbHlzaXNJZHMuam9pbignLCcpKTtcblxuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8RmFjdHNWc0luZmVyZW5jZXNTdW1tYXJ5PihcbiAgICAgIGAvY2xhaW1zL3N1bW1hcnk/JHtwYXJhbXMudG9TdHJpbmcoKX1gXG4gICAgKTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDaGVjayBpZiBhIGNsYWltIGlzIGEgZmFjdCAob2JzZXJ2ZWQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0ZhY3QoY2xhaW06IENsYWltKTogYm9vbGVhbiB7XG4gIHJldHVybiBjbGFpbS5jbGFpbVR5cGUgPT09ICdvYnNlcnZlZCc7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBjbGFpbSBpcyBhbiBpbmZlcmVuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSW5mZXJlbmNlKGNsYWltOiBDbGFpbSk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2xhaW0uY2xhaW1UeXBlID09PSAnaW5mZXJyZWQnO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgY2xhaW0gaXMgY29tcHV0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29tcHV0ZWQoY2xhaW06IENsYWltKTogYm9vbGVhbiB7XG4gIHJldHVybiBjbGFpbS5jbGFpbVR5cGUgPT09ICdjb21wdXRlZCc7XG59XG5cbi8qKlxuICogR2V0IGhpZ2ggY29uZmlkZW5jZSBjbGFpbXMgKD49IHRocmVzaG9sZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEhpZ2hDb25maWRlbmNlQ2xhaW1zKFxuICBjbGFpbXNMaXN0OiBDbGFpbVtdLFxuICB0aHJlc2hvbGQ6IG51bWJlciA9IDAuOFxuKTogQ2xhaW1bXSB7XG4gIHJldHVybiBjbGFpbXNMaXN0LmZpbHRlcigoYykgPT4gYy5jb25maWRlbmNlID49IHRocmVzaG9sZCk7XG59XG5cbi8qKlxuICogR3JvdXAgY2xhaW1zIGJ5IHR5cGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwQ2xhaW1zQnlUeXBlKFxuICBjbGFpbXNMaXN0OiBDbGFpbVtdXG4pOiBSZWNvcmQ8Q2xhaW1UeXBlLCBDbGFpbVtdPiB7XG4gIHJldHVybiB7XG4gICAgb2JzZXJ2ZWQ6IGNsYWltc0xpc3QuZmlsdGVyKChjKSA9PiBjLmNsYWltVHlwZSA9PT0gJ29ic2VydmVkJyksXG4gICAgaW5mZXJyZWQ6IGNsYWltc0xpc3QuZmlsdGVyKChjKSA9PiBjLmNsYWltVHlwZSA9PT0gJ2luZmVycmVkJyksXG4gICAgY29tcHV0ZWQ6IGNsYWltc0xpc3QuZmlsdGVyKChjKSA9PiBjLmNsYWltVHlwZSA9PT0gJ2NvbXB1dGVkJyksXG4gIH07XG59XG5cbi8qKlxuICogR3JvdXAgY2xhaW1zIGJ5IGNhdGVnb3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncm91cENsYWltc0J5Q2F0ZWdvcnkoXG4gIGNsYWltc0xpc3Q6IENsYWltW11cbik6IFJlY29yZDxDbGFpbUNhdGVnb3J5LCBDbGFpbVtdPiB7XG4gIGNvbnN0IGdyb3VwczogUmVjb3JkPENsYWltQ2F0ZWdvcnksIENsYWltW10+ID0ge1xuICAgIG91dGNvbWU6IFtdLFxuICAgIHJvb3RfY2F1c2U6IFtdLFxuICAgIGN1c3RvbWVyX2ltcGFjdDogW10sXG4gICAgY2h1cm5fcmlzazogW10sXG4gICAgcmV2ZW51ZV9pbXBhY3Q6IFtdLFxuICAgIHF1YWxpdHk6IFtdLFxuICAgIG90aGVyOiBbXSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGNsYWltIG9mIGNsYWltc0xpc3QpIHtcbiAgICBncm91cHNbY2xhaW0uY2xhaW1DYXRlZ29yeV0ucHVzaChjbGFpbSk7XG4gIH1cblxuICByZXR1cm4gZ3JvdXBzO1xufVxuIl19