@pipeline-builder/api-server 4.1.46 → 4.2.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.
- package/lib/api/app-factory.js +9 -3
- package/lib/api/index.d.ts +1 -0
- package/lib/api/index.js +2 -1
- package/lib/api/tenant-context.d.ts +1 -8
- package/lib/api/tenant-context.js +47 -4
- package/lib/api/write-pin.d.ts +50 -0
- package/lib/api/write-pin.js +193 -0
- package/lib/testing/exports.json +8 -1
- package/package.json +4 -4
package/lib/api/app-factory.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { sendSuccess, sendError, generateOpenApiSpec, ErrorCode, createLogger, verifyServicePrincipal, createHealthRouter, setCounterEmitter, requireAuth, safeEqual, createEnvSseTicketStore, SSE_TICKET_TTL_MS } from '@pipeline-builder/api-core';
|
|
3
|
+
import { sendSuccess, sendError, generateOpenApiSpec, ErrorCode, createLogger, verifyServicePrincipal, createHealthRouter, setCounterEmitter, setGaugeEmitter, requireAuth, safeEqual, createEnvSseTicketStore, SSE_TICKET_TTL_MS } from '@pipeline-builder/api-core';
|
|
4
4
|
import { Config, CoreConstants } from '@pipeline-builder/pipeline-core';
|
|
5
5
|
import { getConnection } from '@pipeline-builder/pipeline-data';
|
|
6
6
|
import compression from 'compression';
|
|
@@ -12,7 +12,7 @@ import swaggerUi from 'swagger-ui-express';
|
|
|
12
12
|
import { v7 as uuid } from 'uuid';
|
|
13
13
|
import { etagMiddleware } from './etag-middleware.js';
|
|
14
14
|
import { createEnvRedisIdempotencyStore, setIdempotencyStore } from './idempotency-middleware.js';
|
|
15
|
-
import { metricsMiddleware, metricsHandler, incCounter } from './metrics.js';
|
|
15
|
+
import { metricsMiddleware, metricsHandler, incCounter, setGauge } from './metrics.js';
|
|
16
16
|
import { createSharedRateLimitStore } from './rate-limit-store.js';
|
|
17
17
|
import { readinessGuard } from './readiness.js';
|
|
18
18
|
import { SSEManager, SSE_REQUEST_ID_RE } from '../http/sse-connection-manager.js';
|
|
@@ -22,6 +22,12 @@ import { createEnvRedisSSERelay } from '../http/sse-relay.js';
|
|
|
22
22
|
// in metrics.ts), and lets api-core helpers like the quota client record
|
|
23
23
|
// `quota_fail_open_total` without taking a hard dep on api-server.
|
|
24
24
|
setCounterEmitter(incCounter);
|
|
25
|
+
// Same seam for GAUGES. pipeline-data's read-replica lag sampler needs it:
|
|
26
|
+
// replay lag and the state of the read fallback circuit are sampled
|
|
27
|
+
// point-in-time values, so emitting them as counters would make every query
|
|
28
|
+
// over them wrong. pipeline-data depends on api-core and must not depend on
|
|
29
|
+
// api-server, hence the shim rather than a direct import.
|
|
30
|
+
setGaugeEmitter(setGauge);
|
|
25
31
|
/** Helmet (strict CSP), CORS, compression and ETags. */
|
|
26
32
|
function applySecurityHeaders(app, options, enableOpenApi) {
|
|
27
33
|
const { enableCors = true, enableHelmet = true, enableCompression = true } = options;
|
|
@@ -379,4 +385,4 @@ export function createApp(options = {}) {
|
|
|
379
385
|
wireSse(app, sseManager);
|
|
380
386
|
return { app, sseManager };
|
|
381
387
|
}
|
|
382
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2FwcC1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFclAsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxXQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLE9BQU8sRUFBRSxFQUFnRSxNQUFNLFNBQVMsQ0FBQztBQUNoRyxPQUFPLFNBQVMsRUFBRSxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9ELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLG1CQUFtQixFQUF5QixNQUFNLDZCQUE2QixDQUFDO0FBQ3pILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFOUQseUVBQXlFO0FBQ3pFLDJFQUEyRTtBQUMzRSx5RUFBeUU7QUFDekUsbUVBQW1FO0FBQ25FLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBK0U5Qix3REFBd0Q7QUFDeEQsU0FBUyxvQkFBb0IsQ0FBQyxHQUFZLEVBQUUsT0FBeUIsRUFBRSxhQUFzQjtJQUMzRixNQUFNLEVBQUUsVUFBVSxHQUFHLElBQUksRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLGlCQUFpQixHQUFHLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUNyRix5RUFBeUU7SUFDekUsNkVBQTZFO0lBQzdFLHlFQUF5RTtJQUN6RSwwRUFBMEU7SUFDMUUsc0RBQXNEO0lBQ3RELE1BQU0sZUFBZSxHQUFHLGFBQWEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUM7SUFDL0UsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqQixHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUNiLHFCQUFxQixFQUFFO2dCQUNyQixVQUFVLEVBQUU7b0JBQ1YsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDO29CQUN0QixTQUFTLEVBQUUsZUFBZTt3QkFDeEIsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsQ0FBQzt3QkFDaEQsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUNkLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQztvQkFDdkMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUM7b0JBQ3BDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDdEIsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO29CQUNuQixTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ3JCLGNBQWMsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDMUIsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO29CQUNuQixVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUM7aUJBQ3ZCO2FBQ0Y7U0FDRixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2YsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCx5REFBeUQ7SUFDekQsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1FBQ3RCLEdBQUcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxDQUFDLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtnQkFDdEMsdUVBQXVFO2dCQUN2RSxxRUFBcUU7Z0JBQ3JFLGdEQUFnRDtnQkFDaEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQztvQkFBRSxPQUFPLEtBQUssQ0FBQztnQkFDM0UsT0FBTyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsU0FBUyxFQUFFLGFBQWEsQ0FBQywyQkFBMkI7U0FDckQsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQsdUNBQXVDO0FBQ3ZDLFNBQVMsZ0JBQWdCLENBQUMsR0FBWSxFQUFFLE9BQXlCO0lBQy9ELE1BQU0sRUFBRSxjQUFjLEdBQUcsSUFBSSxFQUFFLFNBQVMsR0FBRyxLQUFLLEVBQUUsZ0JBQWdCLEdBQUcsSUFBSSxFQUFFLGVBQWUsR0FBRyxLQUFLLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDL0csSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUNuQixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDdEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUM7UUFDOUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLCtFQUErRTtZQUMvRSxvREFBb0Q7WUFDcEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkgsQ0FBQzthQUFNLENBQUM7WUFDTixHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsR0FBWSxFQUFFLE9BQXlCLEVBQUUsV0FBbUIsRUFBRSxhQUFzQjtJQUMvRyxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLFdBQVcsR0FBRyxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFFeEUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztRQUN6QixXQUFXO1FBQ1gsaUJBQWlCO0tBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUosd0VBQXdFO0lBQ3hFLDJFQUEyRTtJQUMzRSx3RUFBd0U7SUFDeEUsNkVBQTZFO0lBQzdFLG9FQUFvRTtJQUNwRSw2RUFBNkU7SUFDN0UsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRTFCLDBFQUEwRTtJQUMxRSx3RUFBd0U7SUFDeEUsMEVBQTBFO0lBQzFFLEVBQUU7SUFDRiw2RUFBNkU7SUFDN0UsNkVBQTZFO0lBQzdFLDZFQUE2RTtJQUM3RSw2RUFBNkU7SUFDN0UsK0VBQStFO0lBQy9FLGtDQUFrQztJQUNsQyxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsR0FBWSxFQUFFLEdBQWEsRUFBRSxFQUFFO1FBQ3ZELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2pDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ2pDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO2dCQUNoQixhQUFhLEVBQUUsQ0FBQyxjQUFjLEVBQUU7Z0JBQ2hDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDckMsQ0FBQyxDQUFDO1lBQ0gsV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgscUVBQXFFO0lBQ3JFLEVBQUU7SUFDRiw4RUFBOEU7SUFDOUUsK0VBQStFO0lBQy9FLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUsNEVBQTRFO0lBQzVFLCtDQUErQztJQUMvQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDO0lBQ3RELEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFFLEVBQUU7UUFDdEUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2xCLElBQUksRUFBRSxDQUFDO1lBQ1AsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUN6QyxNQUFNLFNBQVMsR0FBRyxNQUFNLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDOUUseUVBQXlFO1FBQ3pFLG1DQUFtQztRQUNuQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3RELFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ2pDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztJQUVyQixJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxHQUFHLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELEdBQUcsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxJQUFhLEVBQUUsR0FBYSxFQUFFLEVBQUU7WUFDN0QsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUNILEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDdEQsZUFBZSxFQUFFLGNBQWMsRUFBRSxLQUFLLElBQUksMkJBQTJCO1NBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztBQUNILENBQUM7QUFFRCxzRkFBc0Y7QUFDdEYsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZLEVBQUUsV0FBbUI7SUFDekQsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUVoRCxNQUFNLGdCQUFnQixHQUFvQztRQUN4RCxHQUFHLEVBQUUsZUFBZSxDQUFDLEdBQUc7UUFDeEIsUUFBUSxFQUFFLGVBQWUsQ0FBQyxRQUFRO1FBQ2xDLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLGFBQWEsRUFBRSxLQUFLO1FBQ3BCLDBFQUEwRTtRQUMxRSxzRUFBc0U7UUFDdEUsNERBQTREO1FBQzVELGtFQUFrRTtRQUNsRSw2REFBNkQ7UUFDN0QsSUFBSSxFQUFFLENBQUMsR0FBWSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUM7UUFDbkQsMkVBQTJFO1FBQzNFLHlFQUF5RTtRQUN6RSxzRUFBc0U7UUFDdEUsdUVBQXVFO1FBQ3ZFLGdFQUFnRTtRQUNoRSxZQUFZLEVBQUUsQ0FBQyxHQUFZLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFDcEUsd0VBQXdFO1FBQ3hFLDhEQUE4RDtRQUM5RCxnQkFBZ0IsRUFBRSxJQUFJO1FBQ3RCLE9BQU8sRUFBRSxDQUFDLElBQWEsRUFBRSxHQUFhLEVBQUUsRUFBRTtZQUN4QyxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw0Q0FBNEMsRUFBRSxTQUFTLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNuRyxDQUFDO1FBQ0QsOEVBQThFO1FBQzlFLDhFQUE4RTtRQUM5RSw0RUFBNEU7UUFDNUUsd0VBQXdFO1FBQ3hFLDJCQUEyQjtRQUMzQixLQUFLLEVBQUUsMEJBQTBCLENBQUMsR0FBRyxXQUFXLFNBQVMsQ0FBQztLQUMzRCxDQUFDO0lBRUYsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFFRCwwREFBMEQ7QUFDMUQsU0FBUyxxQkFBcUIsQ0FBQyxHQUFZO0lBQ3pDLDRGQUE0RjtJQUM1RixNQUFNLFNBQVMsR0FBRyxhQUFhLENBQUMsa0JBQWtCLENBQUM7SUFDbkQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQWEsRUFBRSxHQUFhLEVBQUUsSUFBa0IsRUFBRSxFQUFFO1FBQzNELEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtZQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3pDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksRUFBRSxDQUFDO0lBQ1QsQ0FBQyxDQUFDLENBQUM7SUFFSCwyQkFBMkI7SUFDM0IsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDeEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQVksRUFBRSxHQUFhLEVBQUUsSUFBa0IsRUFBRSxFQUFFO1FBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN6QixHQUFHLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUU7WUFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQztZQUNwQyw4RUFBOEU7WUFDOUUsa0ZBQWtGO1lBQ2xGLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLFVBQVUsSUFBSSxRQUFRLElBQUksRUFBRTtnQkFDL0UsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNO2dCQUNsQixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7Z0JBQ2QsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVO2dCQUMxQixVQUFVLEVBQUUsUUFBUTtnQkFDcEIsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTO2FBQ3pCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztJQUVILHFFQUFxRTtJQUNyRSxHQUFHLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLHVCQUF1QixDQUFDLFdBQW1CLEVBQUUsU0FBa0I7SUFDdEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUM7UUFDaEMsU0FBUztRQUNULFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUM7UUFDdkQsR0FBRyxDQUFDLFNBQVMsSUFBSTtZQUNmLFdBQVcsRUFBRSx1QkFBdUIsQ0FBQztnQkFDbkMsS0FBSyxFQUFFLGlCQUFpQjtnQkFDeEIsU0FBUyxFQUFFLFFBQVEsV0FBVyxFQUFFO2FBQ2pDLENBQUM7U0FDSCxDQUFDO0tBQ0gsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxTQUFTO1FBQUUsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3hDLE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQVMsT0FBTyxDQUFDLEdBQVksRUFBRSxVQUFzQjtJQUNuRCxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtRQUMxRSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUN0RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw0QkFBNEIsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM5RSxPQUFPO1FBQ1QsQ0FBQztRQUNELDZFQUE2RTtRQUM3RSx5RUFBeUU7UUFDekUsMkVBQTJFO1FBQzNFLDRFQUE0RTtRQUM1RSxNQUFNLFNBQVMsR0FBSSxHQUFHLENBQUMsSUFBNEMsRUFBRSxTQUFTLENBQUM7UUFDL0UsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN4RSxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw4QkFBOEIsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNoRixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sVUFBVSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDbEMsMEVBQTBFO2dCQUMxRSxtRUFBbUU7Z0JBQ25FLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLG9DQUFvQyxFQUFFLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ2hHLENBQUM7aUJBQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO2dCQUN6QyxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxvQ0FBb0MsRUFBRSxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDdEYsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLHFDQUFxQyxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUN2RixDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFDRCxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNuRCxDQUFDLENBQUMsQ0FBQztJQUVILDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztBQUN2RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUFPLEdBQXFCLEVBQUU7SUFDdEQsTUFBTSxFQUNKLGVBQWUsR0FBRyxJQUFJLEVBQ3RCLFNBQVMsR0FBRyxLQUFLLEVBQ2pCLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLEdBQ3RELEdBQUcsT0FBTyxDQUFDO0lBRVosTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDO0lBRXRELDBFQUEwRTtJQUMxRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLHVCQUF1QixDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUV6Rix3RUFBd0U7SUFDeEUsNkVBQTZFO0lBQzdFLDZFQUE2RTtJQUM3RSw0RUFBNEU7SUFDNUUsOEVBQThFO0lBQzlFLE1BQU0sd0JBQXdCLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixJQUFJLDhCQUE4QixFQUFFLENBQUM7SUFDOUYsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO1FBQzdCLG1CQUFtQixDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSx5RUFBeUU7SUFDekUsMEVBQTBFO0lBQzFFLDJFQUEyRTtJQUMzRSxrRUFBa0U7SUFDbEUsNEVBQTRFO0lBRTVFLE1BQU0sR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO0lBRXRCLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDbEQsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRS9CLDZFQUE2RTtJQUM3RSxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXhELHlFQUF5RTtJQUN6RSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFFLEVBQUU7UUFDMUQsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN4QyxNQUFNLFNBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDaEUsR0FBRyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDMUIsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDekMsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztJQUVILG1CQUFtQixDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQzlELElBQUksZUFBZTtRQUFFLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN4RCxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUzQiw2RUFBNkU7SUFDN0UsK0VBQStFO0lBQy9FLDRFQUE0RTtJQUM1RSwrRUFBK0U7SUFDL0UsaUVBQWlFO0lBQ2pFLDhEQUE4RDtJQUU5RCxJQUFJLFNBQVM7UUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRXhDLE9BQU8sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBzZW5kU3VjY2Vzcywgc2VuZEVycm9yLCBnZW5lcmF0ZU9wZW5BcGlTcGVjLCBFcnJvckNvZGUsIGNyZWF0ZUxvZ2dlciwgdmVyaWZ5U2VydmljZVByaW5jaXBhbCwgY3JlYXRlSGVhbHRoUm91dGVyLCBzZXRDb3VudGVyRW1pdHRlciwgcmVxdWlyZUF1dGgsIHNhZmVFcXVhbCwgY3JlYXRlRW52U3NlVGlja2V0U3RvcmUsIFNTRV9USUNLRVRfVFRMX01TIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBPcGVuQXBpU3BlY09wdGlvbnMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBDb25maWcsIENvcmVDb25zdGFudHMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlJztcbmltcG9ydCB7IGdldENvbm5lY3Rpb24gfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1kYXRhJztcbmltcG9ydCBjb21wcmVzc2lvbiBmcm9tICdjb21wcmVzc2lvbic7XG5pbXBvcnQgY29ycyBmcm9tICdjb3JzJztcbmltcG9ydCBleHByZXNzLCB7IHR5cGUgRXhwcmVzcywgdHlwZSBOZXh0RnVuY3Rpb24sIHR5cGUgUmVxdWVzdCwgdHlwZSBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHJhdGVMaW1pdCwgeyBpcEtleUdlbmVyYXRvciB9IGZyb20gJ2V4cHJlc3MtcmF0ZS1saW1pdCc7XG5pbXBvcnQgaGVsbWV0IGZyb20gJ2hlbG1ldCc7XG5pbXBvcnQgc3dhZ2dlclVpIGZyb20gJ3N3YWdnZXItdWktZXhwcmVzcyc7XG5pbXBvcnQgeyB2NyBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBldGFnTWlkZGxld2FyZSB9IGZyb20gJy4vZXRhZy1taWRkbGV3YXJlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVudlJlZGlzSWRlbXBvdGVuY3lTdG9yZSwgc2V0SWRlbXBvdGVuY3lTdG9yZSwgdHlwZSBJZGVtcG90ZW5jeVN0b3JlIH0gZnJvbSAnLi9pZGVtcG90ZW5jeS1taWRkbGV3YXJlLmpzJztcbmltcG9ydCB7IG1ldHJpY3NNaWRkbGV3YXJlLCBtZXRyaWNzSGFuZGxlciwgaW5jQ291bnRlciB9IGZyb20gJy4vbWV0cmljcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVTaGFyZWRSYXRlTGltaXRTdG9yZSB9IGZyb20gJy4vcmF0ZS1saW1pdC1zdG9yZS5qcyc7XG5pbXBvcnQgeyByZWFkaW5lc3NHdWFyZCB9IGZyb20gJy4vcmVhZGluZXNzLmpzJztcbmltcG9ydCB7IFNTRU1hbmFnZXIsIFNTRV9SRVFVRVNUX0lEX1JFIH0gZnJvbSAnLi4vaHR0cC9zc2UtY29ubmVjdGlvbi1tYW5hZ2VyLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVudlJlZGlzU1NFUmVsYXkgfSBmcm9tICcuLi9odHRwL3NzZS1yZWxheS5qcyc7XG5cbi8vIFdpcmUgYXBpLWNvcmUncyBjb3VudGVyIHNoaW0gdG8gdGhlIHJlYWwgcHJvbS1jbGllbnQgcmVnaXN0cnkuIFRoaXMgaXNcbi8vIGEgbm8tb3AgdW50aWwgaW5jQ291bnRlciBpcyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lIChsYXp5IHJlZ2lzdHJhdGlvblxuLy8gaW4gbWV0cmljcy50cyksIGFuZCBsZXRzIGFwaS1jb3JlIGhlbHBlcnMgbGlrZSB0aGUgcXVvdGEgY2xpZW50IHJlY29yZFxuLy8gYHF1b3RhX2ZhaWxfb3Blbl90b3RhbGAgd2l0aG91dCB0YWtpbmcgYSBoYXJkIGRlcCBvbiBhcGktc2VydmVyLlxuc2V0Q291bnRlckVtaXR0ZXIoaW5jQ291bnRlcik7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFwcE9wdGlvbnMge1xuICAvKiogRW5hYmxlIENPUlMgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUNvcnM/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIEhlbG1ldCBzZWN1cml0eSBoZWFkZXJzIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVIZWxtZXQ/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIHJhdGUgbGltaXRpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZVJhdGVMaW1pdD86IGJvb2xlYW47XG4gIC8qKiBFbmFibGUgSlNPTiBib2R5IHBhcnNpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUpzb25Cb2R5PzogYm9vbGVhbjtcbiAgLyoqIEpTT04gYm9keSBzaXplIGxpbWl0IChkZWZhdWx0OiAnMW1iJykgKi9cbiAganNvbkxpbWl0Pzogc3RyaW5nO1xuICAvKipcbiAgICogUGF0aCBwcmVmaXhlcyB0aGUgZ2xvYmFsIEpTT04gYm9keSBwYXJzZXIgbXVzdCBOT1QgdG91Y2gg4oCUIGZvciByb3V0ZXMgdGhhdCBuZWVkXG4gICAqIHRoZSByYXcgYm9keSAoZS5nLiBhIFN0cmlwZSB3ZWJob29rIHdob3NlIEhNQUMgaXMgY29tcHV0ZWQgb3ZlciB0aGUgZXhhY3QgYnl0ZXMpLlxuICAgKiBXaXRob3V0IHRoaXMgdGhlIGdsb2JhbCBwYXJzZXIgY29uc3VtZXMgdGhlIGJvZHkgZmlyc3QgYW5kIGEgbGF0ZXIgYGV4cHJlc3MucmF3KClgXG4gICAqIG9uIHRoZSBzYW1lIHBhdGggaXMgYSBuby1vcCwgYnJlYWtpbmcgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbi5cbiAgICovXG4gIGpzb25Cb2R5RXhjbHVkZT86IHN0cmluZ1tdO1xuICAvKiogRW5hYmxlIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2luZyAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlVXJsRW5jb2RlZD86IGJvb2xlYW47XG4gIC8qKiBVUkwtZW5jb2RlZCBib2R5IHNpemUgbGltaXQgKGRlZmF1bHQ6ICcxbWInKSAqL1xuICB1cmxFbmNvZGVkTGltaXQ/OiBzdHJpbmc7XG4gIC8qKiBDdXN0b20gU1NFIG1hbmFnZXIgaW5zdGFuY2UgKi9cbiAgc3NlTWFuYWdlcj86IFNTRU1hbmFnZXI7XG4gIC8qKlxuICAgKiBTZXJ2ZSB0aGUgcGVyLXJlcXVlc3QgYnVpbGQtbG9nIHN0cmVhbTogYFBPU1QgL2xvZ3MvdGlja2V0YCArXG4gICAqIGBHRVQgL2xvZ3MvOnJlcXVlc3RJZGAsIGEgbG9nIHRpY2tldCBzdG9yZSwgdGhlIGNyb3NzLXBvZCByZWxheSwgYW5kXG4gICAqIGBjdHgubG9nYCBmcmFtZXMgcHVzaGVkIHRvIFNTRS4gRGVmYXVsdCBmYWxzZSDigJQgYSBzZXJ2aWNlIHdpdGhvdXQgaXQgaGFzIG5vXG4gICAqIGAvbG9nc2Agcm91dGVzIGFuZCBgY3R4LmxvZ2Agb25seSB3cml0ZXMgdG8gdGhlIGxvZ2dlci5cbiAgICovXG4gIGxvZ1N0cmVhbT86IGJvb2xlYW47XG4gIC8qKiBIZWFsdGggY2hlY2sgZGVwZW5kZW5jeSBjaGVja2VyIOKAlCBpZiBwcm92aWRlZCwgL2hlYWx0aCByZXBvcnRzIGRlcGVuZGVuY3kgc3RhdHVzICovXG4gIGNoZWNrRGVwZW5kZW5jaWVzPzogKCkgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCAnY29ubmVjdGVkJyB8ICdkaXNjb25uZWN0ZWQnIHwgJ3Vua25vd24nPj47XG4gIC8qKlxuICAgKiBTZXJ2ZSB0aGUgT3BlbkFQSSBzcGVjIGF0IGAvZG9jcy9vcGVuYXBpLmpzb25gIGFuZCBTd2FnZ2VyIFVJIGF0IGAvZG9jc2AuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIE9GRiB1bmRlciBgTk9ERV9FTlY9cHJvZHVjdGlvbmA6IHRoZSByb3V0ZXMgYXJlIHJlZ2lzdGVyZWQgYWJvdmVcbiAgICogdGhlIHJhdGUgbGltaXRlciBhbmQgYXJlIG5vdCBhdXRoLWdhdGVkLCBzbyBpbiBwcm9kdWN0aW9uIHRoZXkgd291bGQgcHVibGlzaFxuICAgKiB0aGUgZnVsbCByb3V0ZSArIHNjaGVtYSBpbnZlbnRvcnkgb2YgZXZlcnkgc2VydmljZSB0byBhbnlvbmUgd2hvIGNvdWxkIHJlYWNoXG4gICAqIHRoZSBwb3J0LiBQYXNzIGB0cnVlYCBleHBsaWNpdGx5IHRvIHNlcnZlIHRoZW0gaW4gcHJvZHVjdGlvbiBhbnl3YXkuXG4gICAqL1xuICBlbmFibGVPcGVuQXBpPzogYm9vbGVhbjtcbiAgLyoqIE9wZW5BUEkgc3BlYyBjdXN0b21pemF0aW9uIG9wdGlvbnMgKi9cbiAgb3BlbkFwaU9wdGlvbnM/OiBPcGVuQXBpU3BlY09wdGlvbnM7XG4gIC8qKiBFbmFibGUgZ3ppcC9kZWZsYXRlIHJlc3BvbnNlIGNvbXByZXNzaW9uIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVDb21wcmVzc2lvbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZGVtcG90ZW5jeSByZXBsYXktY2FjaGUgYmFja2VuZCBmb3Iga2V5ZWQgbXV0YXRpb24gcmV0cmllcy4gV2hlbiBvbWl0dGVkLFxuICAgKiBjcmVhdGVBcHAgYXV0by13aXJlcyB0aGUgc2hhcmVkIGVudiBSZWRpcyBzdG9yZSAobXVsdGktcmVwbGljYSBkZWR1cCkgaWZcbiAgICogUmVkaXMgaXMgY29uZmlndXJlZCwgZWxzZSBrZWVwcyB0aGUgaW4tbWVtb3J5IGRlZmF1bHQgKHNpbmdsZS1yZXBsaWNhKS5cbiAgICogUGFzcyBhbiBleHBsaWNpdCBzdG9yZSB0byBpbmplY3QgYSBiZXNwb2tlIGJhY2tlbmQgKGUuZy4gYSBzZXJ2aWNlJ3Mgb3duXG4gICAqIGlvcmVkaXMgY29ubmVjdGlvbikuXG4gICAqL1xuICBpZGVtcG90ZW5jeVN0b3JlPzogSWRlbXBvdGVuY3lTdG9yZTtcbiAgLyoqXG4gICAqIEV4dHJhIHdhcm11cCBjYWxsYmFja3MgaW52b2tlZCBieSBgR0VUIC93YXJtdXBgIGluIGFkZGl0aW9uIHRvIHRoZVxuICAgKiBkZWZhdWx0IFBvc3RncmVzIHBpbmcuIFVzZSBmb3Igc2VydmljZXMgdGhhdCBkZXBlbmQgb24gTW9uZ28sIFJlZGlzLFxuICAgKiBTUVMsIGV0Yy4g4oCUIHByZS13YXJtaW5nIG9wZW5zIGNvbm5lY3Rpb24gcG9vbHMgYmVmb3JlIHJlYWwgdHJhZmZpY1xuICAgKiBhcnJpdmVzLiBFYWNoIGNhbGxiYWNrIHNob3VsZCByZXNvbHZlIHdoZW4gaXRzIGRlcGVuZGVuY3kgaXMgcmVhZHk7XG4gICAqIGFueSByZWplY3Rpb24gY2F1c2VzIC93YXJtdXAgdG8gcmV0dXJuIDUwMy5cbiAgICovXG4gIHdhcm11cEhvb2tzPzogQXJyYXk8KCkgPT4gUHJvbWlzZTx2b2lkPj47XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGNyZWF0aW5nIGFuIEV4cHJlc3MgYXBwbGljYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVBcHBSZXN1bHQge1xuICAvKiogQ29uZmlndXJlZCBFeHByZXNzIGFwcGxpY2F0aW9uICovXG4gIGFwcDogRXhwcmVzcztcbiAgLyoqIFNTRSBtYW5hZ2VyIGluc3RhbmNlICovXG4gIHNzZU1hbmFnZXI6IFNTRU1hbmFnZXI7XG59XG5cbi8qKiBIZWxtZXQgKHN0cmljdCBDU1ApLCBDT1JTLCBjb21wcmVzc2lvbiBhbmQgRVRhZ3MuICovXG5mdW5jdGlvbiBhcHBseVNlY3VyaXR5SGVhZGVycyhhcHA6IEV4cHJlc3MsIG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMsIGVuYWJsZU9wZW5BcGk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgeyBlbmFibGVDb3JzID0gdHJ1ZSwgZW5hYmxlSGVsbWV0ID0gdHJ1ZSwgZW5hYmxlQ29tcHJlc3Npb24gPSB0cnVlIH0gPSBvcHRpb25zO1xuICAvLyBTd2FnZ2VyIFVJIG5lZWRzIHVuc2FmZS1pbmxpbmUgKyB1bnNhZmUtZXZhbCBmb3IgaXRzIGJ1bmRsZWQgc2NyaXB0cyDigJRcbiAgLy8gYnV0IENTUCBpcyBvbmx5IHJlbGF4ZWQgdGhhdCBmYXIgd2hlbiAoYSkgT3BlbkFQSSBpcyBlbmFibGVkIEFORCAoYikgd2UncmVcbiAgLy8gbm90IGluIHByb2R1Y3Rpb24uIEluIHByb2QsIFN3YWdnZXIgc2hvdWxkIGJlIHNlcnZlZCBiZWhpbmQgYSBzZXBhcmF0ZVxuICAvLyBob3N0IG9yIGF1dGgtZ2F0ZWQgcm91dGU7IHRoZSBtYWluIGFwcCBrZWVwcyB0aGUgc3RyaWN0IENTUCBzbyBhIFN0b3JlZFxuICAvLyBYU1MgaW4gYW55IGhhbmRsZXIgY2FuJ3QgYGV2YWwoKWAgYXJiaXRyYXJ5IHNjcmlwdC5cbiAgY29uc3QgYWxsb3dTd2FnZ2VyQ3NwID0gZW5hYmxlT3BlbkFwaSAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuICBpZiAoZW5hYmxlSGVsbWV0KSB7XG4gICAgYXBwLnVzZShoZWxtZXQoe1xuICAgICAgY29udGVudFNlY3VyaXR5UG9saWN5OiB7XG4gICAgICAgIGRpcmVjdGl2ZXM6IHtcbiAgICAgICAgICBkZWZhdWx0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc2NyaXB0U3JjOiBhbGxvd1N3YWdnZXJDc3BcbiAgICAgICAgICAgID8gW1wiJ3NlbGYnXCIsIFwiJ3Vuc2FmZS1pbmxpbmUnXCIsIFwiJ3Vuc2FmZS1ldmFsJ1wiXVxuICAgICAgICAgICAgOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc3R5bGVTcmM6IFtcIidzZWxmJ1wiLCBcIid1bnNhZmUtaW5saW5lJ1wiXSxcbiAgICAgICAgICBpbWdTcmM6IFtcIidzZWxmJ1wiLCAnZGF0YTonLCAnYmxvYjonXSxcbiAgICAgICAgICBjb25uZWN0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgZm9udFNyYzogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIG9iamVjdFNyYzogW1wiJ25vbmUnXCJdLFxuICAgICAgICAgIGZyYW1lQW5jZXN0b3JzOiBbXCInbm9uZSdcIl0sXG4gICAgICAgICAgYmFzZVVyaTogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIGZvcm1BY3Rpb246IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSkpO1xuICB9XG5cbiAgaWYgKGVuYWJsZUNvcnMpIHtcbiAgICBhcHAudXNlKGNvcnMoQ29uZmlnLmdldCgnc2VydmVyJykuY29ycykpO1xuICB9XG5cbiAgLy8gUmVzcG9uc2UgY29tcHJlc3Npb24gKGd6aXAvZGVmbGF0ZSkg4oCUIHNraXAgU1NFIHN0cmVhbXNcbiAgaWYgKGVuYWJsZUNvbXByZXNzaW9uKSB7XG4gICAgYXBwLnVzZShjb21wcmVzc2lvbih7XG4gICAgICBmaWx0ZXI6IChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gRG9uJ3QgY29tcHJlc3MgU1NFIHN0cmVhbXMuIE1hdGNoIGJ5IGluY2x1c2lvbjogdGhlIEFjY2VwdCBoZWFkZXIgaXNcbiAgICAgICAgLy8gb2Z0ZW4gYSBsaXN0IChlLmcuIFwidGV4dC9ldmVudC1zdHJlYW0sICovKlwiKSwgd2hpY2ggZXhhY3QgZXF1YWxpdHlcbiAgICAgICAgLy8gd291bGQgbWlzcywgY29tcHJlc3NpbmcvYnVmZmVyaW5nIHRoZSBzdHJlYW0uXG4gICAgICAgIGlmICgocmVxLmhlYWRlcnMuYWNjZXB0IHx8ICcnKS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gY29tcHJlc3Npb24uZmlsdGVyKHJlcSwgcmVzKTtcbiAgICAgIH0sXG4gICAgICB0aHJlc2hvbGQ6IENvcmVDb25zdGFudHMuQ09NUFJFU1NJT05fVEhSRVNIT0xEX0JZVEVTLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEVUYWcgc3VwcG9ydCBmb3IgY29uZGl0aW9uYWwgR0VUIHJlcXVlc3RzICgzMDQgTm90IE1vZGlmaWVkKVxuICBhcHAudXNlKGV0YWdNaWRkbGV3YXJlKCkpO1xufVxuXG4vKiogSlNPTiArIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2Vycy4gKi9cbmZ1bmN0aW9uIGFwcGx5Qm9keVBhcnNpbmcoYXBwOiBFeHByZXNzLCBvcHRpb25zOiBDcmVhdGVBcHBPcHRpb25zKTogdm9pZCB7XG4gIGNvbnN0IHsgZW5hYmxlSnNvbkJvZHkgPSB0cnVlLCBqc29uTGltaXQgPSAnMW1iJywgZW5hYmxlVXJsRW5jb2RlZCA9IHRydWUsIHVybEVuY29kZWRMaW1pdCA9ICcxbWInIH0gPSBvcHRpb25zO1xuICBpZiAoZW5hYmxlSnNvbkJvZHkpIHtcbiAgICBjb25zdCBqc29uUGFyc2VyID0gZXhwcmVzcy5qc29uKHsgbGltaXQ6IGpzb25MaW1pdCB9KTtcbiAgICBjb25zdCBleGNsdWRlID0gb3B0aW9ucy5qc29uQm9keUV4Y2x1ZGUgPz8gW107XG4gICAgaWYgKGV4Y2x1ZGUubGVuZ3RoID4gMCkge1xuICAgICAgLy8gU2tpcCB0aGUgZ2xvYmFsIEpTT04gcGFyc2VyIGZvciByYXctYm9keSBwYXRocyBzbyBhIHBlci1wYXRoIGBleHByZXNzLnJhdygpYFxuICAgICAgLy8gY2FuIHJlYWQgdGhlIGV4YWN0IGJ5dGVzIChzZWUgYGpzb25Cb2R5RXhjbHVkZWApLlxuICAgICAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IChleGNsdWRlLnNvbWUoKHApID0+IHJlcS5wYXRoLnN0YXJ0c1dpdGgocCkpID8gbmV4dCgpIDoganNvblBhcnNlcihyZXEsIHJlcywgbmV4dCkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXBwLnVzZShqc29uUGFyc2VyKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZW5hYmxlVXJsRW5jb2RlZCkge1xuICAgIGFwcC51c2UoZXhwcmVzcy51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiB1cmxFbmNvZGVkTGltaXQgfSkpO1xuICB9XG59XG5cbi8qKlxuICogSGVhbHRoLCByZWFkaW5lc3MgZ3VhcmQsIGAvd2FybXVwYCwgYC9tZXRyaWNzYCBhbmQgdGhlIE9wZW5BUEkgZG9jcyDigJQgYWxsXG4gKiByZWdpc3RlcmVkIGJlZm9yZSB0aGUgcmF0ZSBsaW1pdGVyIHNvIHRoZXkgYXJlIG5ldmVyIHRocm90dGxlZC5cbiAqL1xuZnVuY3Rpb24gbW91bnRJbmZyYUVuZHBvaW50cyhhcHA6IEV4cHJlc3MsIG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMsIHNlcnZpY2VOYW1lOiBzdHJpbmcsIGVuYWJsZU9wZW5BcGk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgeyBjaGVja0RlcGVuZGVuY2llcywgb3BlbkFwaU9wdGlvbnMsIHdhcm11cEhvb2tzID0gW10gfSA9IG9wdGlvbnM7XG5cbiAgYXBwLnVzZShjcmVhdGVIZWFsdGhSb3V0ZXIoe1xuICAgIHNlcnZpY2VOYW1lLFxuICAgIGNoZWNrRGVwZW5kZW5jaWVzLFxuICB9KSk7XG5cbiAgLy8gUmVhZGluZXNzIGd1YXJkIOKAlCA1MDNzIGJ1c2luZXNzIHRyYWZmaWMgd2hpbGUgdGhlIHNlcnZpY2UgaXMgTm90UmVhZHlcbiAgLy8gKGRhdGFzdG9yZSBzdGlsbCBjb25uZWN0aW5nIGF0IHN0YXJ0dXAsIG9yIGRyb3BwZWQpLiBNb3VudGVkIHJpZ2h0IGFmdGVyXG4gIC8vIHRoZSBoZWFsdGggcm91dGVyIGFuZCBiZWZvcmUgZXZlcnl0aGluZyBlbHNlIHNvIGEgTm90UmVhZHkgcmVxdWVzdCBpc1xuICAvLyByZWplY3RlZCBjaGVhcGx5LCBiZWZvcmUgcmF0ZS1saW1pdCAvIGlkZW1wb3RlbmN5IC8gYnVzaW5lc3MgaGFuZGxlcnMgZXZlclxuICAvLyB0b3VjaCBhIGRpc2Nvbm5lY3RlZCBkYXRhc3RvcmUuIEl0IGFsbG93bGlzdHMgdGhlIGluZnJhIGVuZHBvaW50c1xuICAvLyAoL21ldHJpY3MsIC93YXJtdXAsIC9kb2NzLCAvbG9ncykgcmVnaXN0ZXJlZCBiZWxvdywgcGx1cyAvaGVhbHRoICsgL3JlYWR5LlxuICBhcHAudXNlKHJlYWRpbmVzc0d1YXJkKCkpO1xuXG4gIC8vIFdhcm0tdXAgZW5kcG9pbnQg4oCUIHByZS1vcGVucyBjb25uZWN0aW9uIHBvb2xzIHNvIHRoZSBmaXJzdCByZWFsIHJlcXVlc3RcbiAgLy8gZG9lc24ndCBwYXkgY29sZC1zdGFydCBsYXRlbmN5LiBBbHdheXMgcGluZ3MgUG9zdGdyZXM7IHNlcnZpY2VzIHVzaW5nXG4gIC8vIE1vbmdvIC8gUmVkaXMgLyBTUVMgcGFzcyBgd2FybXVwSG9va3NgIHNvIHRob3NlIGFyZSB3YXJtZWQgaW4gcGFyYWxsZWwuXG4gIC8vXG4gIC8vIEdBVEVEIHRvIHZlcmlmaWVkIHNlcnZpY2UgcHJpbmNpcGFscy4gRXZlcnkgaGl0IHJ1bnMgYSBQb3N0Z3JlcyByb3VuZC10cmlwXG4gIC8vIHBsdXMgYWxsIGB3YXJtdXBIb29rc2AgKE1vbmdvL1JlZGlzL1NRUyksIHNvIGFuIG9wZW4gZW5kcG9pbnQgd291bGQgbGV0IGFuXG4gIC8vIGFub255bW91cyBsb29wIGFtcGxpZnkgaW50byBkYXRhc3RvcmUgbG9hZCBvbiBldmVyeSBzZXJ2aWNlIGluIHRoZSBmbGVldCDigJRcbiAgLy8gYW5kIGl0IGlzIHJlZ2lzdGVyZWQgYWJvdmUgdGhlIHJhdGUgbGltaXRlciwgc28gbm90aGluZyB3b3VsZCB0aHJvdHRsZSBpdC5cbiAgLy8gYHZlcmlmeVNlcnZpY2VQcmluY2lwYWxgIGNoZWNrcyB0aGUgYmVhcmVyIHRva2VuIGNyeXB0b2dyYXBoaWNhbGx5LCBzbyBpdCBpc1xuICAvLyBzYWZlIGhlcmUsIGFib3ZlIGByZXF1aXJlQXV0aGAuXG4gIGFwcC5nZXQoJy93YXJtdXAnLCBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgaWYgKCF2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwNCwgJ05vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBnZXRDb25uZWN0aW9uKCkudGVzdENvbm5lY3Rpb24oKSxcbiAgICAgICAgLi4ud2FybXVwSG9va3MubWFwKChob29rKSA9PiBob29rKCkpLFxuICAgICAgXSk7XG4gICAgICBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyB3YXJtZWQ6IHRydWUsIGhvb2tzOiB3YXJtdXBIb29rcy5sZW5ndGggfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA1MDMsICdXYXJtdXAgZmFpbGVkJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBQcm9tZXRoZXVzIG1ldHJpY3MgZW5kcG9pbnQg4oCUIGFsd2F5cyByZWdpc3RlcmVkIChuZXZlciB0aHJvdHRsZWQpLlxuICAvL1xuICAvLyBPcHRpb25hbGx5IGdhdGVkOiB3aGVuIGBNRVRSSUNTX1NDUkFQRV9UT0tFTmAgaXMgc2V0LCB0aGUgc2NyYXBlciBtdXN0IHNlbmRcbiAgLy8gaXQgYXMgYSBiZWFyZXIgdG9rZW4gKFByb21ldGhldXMgYGJlYXJlcl90b2tlbmAgLyBgYmVhcmVyX3Rva2VuX2ZpbGVgIGluIHRoZVxuICAvLyBzY3JhcGUgY29uZmlnKS4gTGVmdCB1bmdhdGVkIHdoZW4gdW5zZXQgc28gZW5hYmxpbmcgaXQgaXMgYSBkZWxpYmVyYXRlLFxuICAvLyBjb29yZGluYXRlZCBjaGFuZ2UgcmF0aGVyIHRoYW4gYSBzaWxlbnQgbW9uaXRvcmluZyBvdXRhZ2Ug4oCUIHRlbmFudCBpZHMgc3RheVxuICAvLyBvdXQgb2YgdGhlIG91dHB1dCByZWdhcmRsZXNzLCBiZWNhdXNlIHRoZSBwZXItb3JnIGxhYmVsIGRlZmF1bHRzIE9GRiAoc2VlXG4gIC8vIEhUVFBfTUVUUklDU19PUkdfU0FNUExFX1JBVEUgaW4gbWV0cmljcy50cykuXG4gIGNvbnN0IG1ldHJpY3NUb2tlbiA9IHByb2Nlc3MuZW52Lk1FVFJJQ1NfU0NSQVBFX1RPS0VOO1xuICBhcHAuZ2V0KCcvbWV0cmljcycsIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIGlmICghbWV0cmljc1Rva2VuKSB7XG4gICAgICBuZXh0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gICAgY29uc3QgcHJlc2VudGVkID0gaGVhZGVyPy5zdGFydHNXaXRoKCdCZWFyZXIgJykgPyBoZWFkZXIuc2xpY2UoNykgOiB1bmRlZmluZWQ7XG4gICAgLy8gQ29uc3RhbnQtdGltZSBjb21wYXJlIOKAlCBhIGxlbmd0aC1pbmRlcGVuZGVudCBlcXVhbGl0eSBjaGVjayBoZXJlIHdvdWxkXG4gICAgLy8gbGVhayB0aGUgdG9rZW4gYSBieXRlIGF0IGEgdGltZS5cbiAgICBpZiAoIXByZXNlbnRlZCB8fCAhc2FmZUVxdWFsKHByZXNlbnRlZCwgbWV0cmljc1Rva2VuKSkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDA0LCAnTm90IGZvdW5kJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5leHQoKTtcbiAgfSwgbWV0cmljc0hhbmRsZXIoKSk7XG5cbiAgaWYgKGVuYWJsZU9wZW5BcGkpIHtcbiAgICBjb25zdCBzcGVjID0gZ2VuZXJhdGVPcGVuQXBpU3BlYyhvcGVuQXBpT3B0aW9ucyk7XG4gICAgYXBwLmdldCgnL2RvY3Mvb3BlbmFwaS5qc29uJywgKF9yZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIHJlcy5qc29uKHNwZWMpO1xuICAgIH0pO1xuICAgIGFwcC51c2UoJy9kb2NzJywgc3dhZ2dlclVpLnNlcnZlLCBzd2FnZ2VyVWkuc2V0dXAoc3BlYywge1xuICAgICAgY3VzdG9tU2l0ZVRpdGxlOiBvcGVuQXBpT3B0aW9ucz8udGl0bGUgPz8gJ1BpcGVsaW5lIEJ1aWxkZXIgQVBJIERvY3MnLFxuICAgIH0pKTtcbiAgfVxufVxuXG4vKiogR2xvYmFsIHJhdGUgbGltaXRlciDigJQgc2hhcmVkIGFjcm9zcyByZXBsaWNhcyB2aWEgdGhlIGVudiBSZWRpcyB3aGVuIGNvbmZpZ3VyZWQuICovXG5mdW5jdGlvbiBtb3VudFJhdGVMaW1pdGVyKGFwcDogRXhwcmVzcywgc2VydmljZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCByYXRlTGltaXRDb25maWcgPSBDb25maWcuZ2V0KCdyYXRlTGltaXQnKTtcblxuICBjb25zdCByYXRlTGltaXRPcHRpb25zOiBQYXJhbWV0ZXJzPHR5cGVvZiByYXRlTGltaXQ+WzBdID0ge1xuICAgIG1heDogcmF0ZUxpbWl0Q29uZmlnLm1heCxcbiAgICB3aW5kb3dNczogcmF0ZUxpbWl0Q29uZmlnLndpbmRvd01zLFxuICAgIHN0YW5kYXJkSGVhZGVyczogdHJ1ZSxcbiAgICBsZWdhY3lIZWFkZXJzOiBmYWxzZSxcbiAgICAvLyBTa2lwIHJhdGUgbGltaXRpbmcgb25seSBmb3IgQ1JZUFRPR1JBUEhJQ0FMTFktVkVSSUZJRUQgaW50ZXJuYWwgc2VydmljZVxuICAgIC8vIGNhbGxlcnMuIFRoZSBsaW1pdGVyIHJ1bnMgYmVmb3JlIHJlcXVpcmVBdXRoLCBzbyBhIHBsYWludGV4dCBoZWFkZXJcbiAgICAvLyB3b3VsZCBiZSBzcG9vZmFibGUgYnkgYW55IGV4dGVybmFsIGNsaWVudCDihpIgdG90YWwgYnlwYXNzLlxuICAgIC8vIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwgdmVyaWZpZXMgdGhlIHNpZ25lZCBzZXJ2aWNlIEpXVCBpbnN0ZWFkO1xuICAgIC8vIGludGVyLXNlcnZpY2UgY2FsbGVycyBhbGwgc2VuZCBvbmUgKGdldFNlcnZpY2VBdXRoSGVhZGVyKS5cbiAgICBza2lwOiAocmVxOiBSZXF1ZXN0KSA9PiB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcSksXG4gICAgLy8gS2V5IG9uIGNsaWVudCBJUCBvbmx5LiBUaGUgbGltaXRlciBydW5zIHByZS1hdXRoLCBzbyBgcmVxLnVzZXJgIGlzIHVuc2V0XG4gICAgLy8gYW5kIGFueSBvcmcgaWQgd291bGQgY29tZSBmcm9tIHRoZSBjYWxsZXItc3VwcGxpZWQgYHgtb3JnLWlkYCBoZWFkZXIg4oCUXG4gICAgLy8gc3Bvb2ZhYmxlLCBsZXR0aW5nIGFuIGF0dGFja2VyIHJvdGF0ZSB2YWx1ZXMgdG8gZXZhZGUgdGhlIGJ1Y2tldCBvclxuICAgIC8vIGZsb29kIGEgdmljdGltIG9yZydzIGJ1Y2tldC4gaXBLZXlHZW5lcmF0b3Igbm9ybWFsaXplcyBJUHY2IHRvIGEgLzY0XG4gICAgLy8gcHJlZml4IChhbHNvIHJlcXVpcmVkIGJ5IGV4cHJlc3MtcmF0ZS1saW1pdCA4LngncyB2YWxpZGF0b3IpLlxuICAgIGtleUdlbmVyYXRvcjogKHJlcTogUmVxdWVzdCkgPT4gaXBLZXlHZW5lcmF0b3IocmVxLmlwIHx8ICdhbm9uJywgNjQpLFxuICAgIC8vIEEgc3RvcmUgZmFpbHVyZSAoUmVkaXMgZG93biAvIGZhaWxpbmcgb3ZlcikgbXVzdCBkZWdyYWRlIHRvIFwibm90IHJhdGVcbiAgICAvLyBsaW1pdGVkXCIsIG5ldmVyIHRvIGEgNTAwIG9uIGV2ZXJ5IHJlcXVlc3Qgb2YgZXZlcnkgc2VydmljZS5cbiAgICBwYXNzT25TdG9yZUVycm9yOiB0cnVlLFxuICAgIGhhbmRsZXI6IChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MjksICdUb28gbWFueSByZXF1ZXN0cywgcGxlYXNlIHRyeSBhZ2FpbiBsYXRlci4nLCBFcnJvckNvZGUuUkFURV9MSU1JVF9FWENFRURFRCk7XG4gICAgfSxcbiAgICAvLyBTaGFyZWQgc3RhdGUgYWNyb3NzIHJlcGxpY2FzICh0aGUgcHJvY2Vzcy13aWRlIHJhdGUtbGltaXQgUmVkaXMgY29ubmVjdGlvbjtcbiAgICAvLyB1bmRlZmluZWQgd2l0aG91dCBSZWRpcyDihpIgcGVyLXByb2Nlc3MgbWVtb3J5IHN0b3JlLCByaWdodCBmb3Igb25lIHJlcGxpY2EpLlxuICAgIC8vIE5hbWVzcGFjZWQgcGVyIFNFUlZJQ0U6IGV2ZXJ5IHNlcnZpY2Ugc2hhcmVzIG9uZSBSZWRpcywgYW5kIGFuIHVucHJlZml4ZWRcbiAgICAvLyBgcmw6PGlwPmAga2V5IHdvdWxkIGxldCBvbmUgY2xpZW50J3MgdHJhZmZpYyB0byBBTlkgc2VydmljZSBkcmFpbiBpdHNcbiAgICAvLyBidWRnZXQgb24gRVZFUlkgc2VydmljZS5cbiAgICBzdG9yZTogY3JlYXRlU2hhcmVkUmF0ZUxpbWl0U3RvcmUoYCR7c2VydmljZU5hbWV9Omdsb2JhbGApLFxuICB9O1xuXG4gIGFwcC51c2UocmF0ZUxpbWl0KHJhdGVMaW1pdE9wdGlvbnMpKTtcbn1cblxuLyoqIFJlcXVlc3QgdGltZW91dCwgZHVyYXRpb24gbG9nZ2luZyBhbmQgSFRUUCBtZXRyaWNzLiAqL1xuZnVuY3Rpb24gYXBwbHlSZXF1ZXN0VGVsZW1ldHJ5KGFwcDogRXhwcmVzcyk6IHZvaWQge1xuICAvLyBFeHByZXNzIHJlcXVlc3QgdGltZW91dCDigJQgdXNlcyBDb3JlQ29uc3RhbnRzIHRvIHNoYXJlIHRoZSBzYW1lIGRlZmF1bHQgYXMgTGFtYmRhIGhhbmRsZXJzXG4gIGNvbnN0IHRpbWVvdXRNcyA9IENvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TO1xuICBhcHAudXNlKChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICByZXMuc2V0VGltZW91dCh0aW1lb3V0TXMsICgpID0+IHtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ1JlcXVlc3QgdGltZW91dCcpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUmVxdWVzdCBkdXJhdGlvbiBsb2dnaW5nXG4gIGNvbnN0IGR1cmF0aW9uTG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXF1ZXN0LWR1cmF0aW9uJyk7XG4gIGFwcC51c2UoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKSA9PiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHJlcy5vbignZmluaXNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnQ7XG4gICAgICAvLyBMb2cgYHJlcS5wYXRoYCAobm8gcXVlcnkgc3RyaW5nKSDigJQgYSBzdHJheSBgP3Rva2VuPWAvYD90aWNrZXQ9YCBtdXN0IG5vdCBiZVxuICAgICAgLy8gcGVyc2lzdGVkIHZlcmJhdGltIG9uIGV2ZXJ5IHJlcXVlc3QgKG1pcnJvcnMgdGhlIGF1dGh6LWRlbmlhbCBhdWRpdG9yJ3Mgc3RyaXApLlxuICAgICAgZHVyYXRpb25Mb2dnZXIuaW5mbyhgJHtyZXEubWV0aG9kfSAke3JlcS5wYXRofSAke3Jlcy5zdGF0dXNDb2RlfSAke2R1cmF0aW9ufW1zYCwge1xuICAgICAgICBtZXRob2Q6IHJlcS5tZXRob2QsXG4gICAgICAgIHBhdGg6IHJlcS5wYXRoLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXMuc3RhdHVzQ29kZSxcbiAgICAgICAgZHVyYXRpb25NczogZHVyYXRpb24sXG4gICAgICAgIHJlcXVlc3RJZDogcmVxLnJlcXVlc3RJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUHJvbWV0aGV1cyBtZXRyaWNzIG1pZGRsZXdhcmUg4oCUIHJlY29yZHMgcmVxdWVzdCBkdXJhdGlvbiBhbmQgY291bnRcbiAgYXBwLnVzZShtZXRyaWNzTWlkZGxld2FyZSgpKTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBTU0UgbWFuYWdlci4gVGhlIHJlbGF5ICh0aGlzIHNlcnZpY2UncyBvd24gUmVkaXMgY2hhbm5lbCkgaXNcbiAqIGJ1aWx0IG9ubHkgd2hlbiBzb21ldGhpbmcgc3RyZWFtczogdGhlIGxvZyBzdHJlYW0gdHVybnMgaXQgb24gaGVyZSwgYW5kIGFuXG4gKiBvcmcta2V5ZWQgY2hhbm5lbCB0dXJucyBpdCBvbiB3aGVuIHJlZ2lzdGVyZWQgKHJlZ2lzdGVyU3NlVGlja2V0Q2hhbm5lbCkuXG4gKiBUaGUgbG9nIHRpY2tldCBzdG9yZSBleGlzdHMgb25seSB3aXRoIHRoZSBsb2cgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBjcmVhdGVEZWZhdWx0U3NlTWFuYWdlcihzZXJ2aWNlTmFtZTogc3RyaW5nLCBsb2dTdHJlYW06IGJvb2xlYW4pOiBTU0VNYW5hZ2VyIHtcbiAgY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHtcbiAgICBsb2dTdHJlYW0sXG4gICAgcmVsYXlGYWN0b3J5OiAoKSA9PiBjcmVhdGVFbnZSZWRpc1NTRVJlbGF5KHNlcnZpY2VOYW1lKSxcbiAgICAuLi4obG9nU3RyZWFtICYmIHtcbiAgICAgIHRpY2tldFN0b3JlOiBjcmVhdGVFbnZTc2VUaWNrZXRTdG9yZSh7XG4gICAgICAgIHR0bE1zOiBTU0VfVElDS0VUX1RUTF9NUyxcbiAgICAgICAga2V5UHJlZml4OiBgbG9nczoke3NlcnZpY2VOYW1lfWAsXG4gICAgICB9KSxcbiAgICB9KSxcbiAgfSk7XG4gIGlmIChsb2dTdHJlYW0pIHNzZU1hbmFnZXIuZW5hYmxlUmVsYXkoKTtcbiAgcmV0dXJuIHNzZU1hbmFnZXI7XG59XG5cbi8qKlxuICogVGhlIHBlci1yZXF1ZXN0IGJ1aWxkLWxvZyBzdHJlYW06IGBQT1NUIC9sb2dzL3RpY2tldGAgKyBgR0VUIC9sb2dzLzpyZXF1ZXN0SWRgLlxuICpcbiAqIFRpY2tldC1nYXRlZCDigJQgdGhlIHN0cmVhbSBjYXJyaWVzIHBlci1vcmcgYnVpbGQgbG9ncywgc28gaXQgbXVzdCBub3QgYmVcbiAqIHdvcmxkLXJlYWRhYmxlLiBDbGllbnRzIGZpcnN0IFBPU1QgL2xvZ3MvdGlja2V0IChKV1QtYXV0aGVudGljYXRlZCkgdG8gbWludCBhXG4gKiBzaG9ydC1saXZlZCwgc2luZ2xlLXVzZSB0aWNrZXQgYm91bmQgdG8gdGhlaXIgb3JnIEFORCB0byB0aGUgc3BlY2lmaWNcbiAqIGByZXF1ZXN0SWRgIHN0cmVhbSB0aGV5IGludGVuZCB0byBvcGVuLCB0aGVuIG9wZW4gdGhlIEV2ZW50U291cmNlIHdpdGhcbiAqID90aWNrZXQ9PHQ+LiBUaGlzIGtlZXBzIHRoZSBKV1Qgb3V0IG9mIHF1ZXJ5IHN0cmluZ3MgLyBhY2Nlc3MgbG9ncyB3aGlsZVxuICogZW5mb3JjaW5nIG9yZyBvd25lcnNoaXAsIHBlci1zdWJqZWN0IGF1dGhvcml6YXRpb24sIGFuZCB0aGUgcGVyLW9yZ1xuICogY29ubmVjdGlvbiBjYXAgb24gdGhlIHN0cmVhbS4gTWlycm9ycyB0aGUgbWVzc2FnZS1zZXJ2aWNlIG5vdGlmaWNhdGlvbnMgU1NFXG4gKiB0aWNrZXQgZXhjaGFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHdpcmVTc2UoYXBwOiBFeHByZXNzLCBzc2VNYW5hZ2VyOiBTU0VNYW5hZ2VyKTogdm9pZCB7XG4gIGFwcC5wb3N0KCcvbG9ncy90aWNrZXQnLCByZXF1aXJlQXV0aCwgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGNvbnN0IG9yZ0lkID0gcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkPy50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwMCwgJ1Rva2VuIG1pc3Npbmcgb3JnYW5pemF0aW9uJywgRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUaGUgY2FsbGVyIG11c3QgbmFtZSB0aGUgc3RyZWFtIHN1YmplY3QgdXAgZnJvbnQgc28gdGhlIHRpY2tldCBpcyBib3VuZCB0b1xuICAgIC8vIGl0LiBXaXRob3V0IHRoaXMsIGEgdGlja2V0IGNvdWxkIGJlIHJlcGxheWVkIGFnYWluc3QgQU5ZIHJlcXVlc3RJZCB0aGVcbiAgICAvLyBvcmcgY291bGQgZ3Vlc3MsIGxldHRpbmcgaXQgYXR0YWNoIHRvIGFub3RoZXIgb3JnJ3MgbG9nIHN0cmVhbS4gU3RyaWN0bHlcbiAgICAvLyBmb3JtYXQtdmFsaWRhdGVkIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiBwYXlsb2FkIGludG8gdGhlIHN1YmplY3QuXG4gICAgY29uc3QgcmVxdWVzdElkID0gKHJlcS5ib2R5IGFzIHsgcmVxdWVzdElkPzogdW5rbm93biB9IHwgdW5kZWZpbmVkKT8ucmVxdWVzdElkO1xuICAgIGlmICh0eXBlb2YgcmVxdWVzdElkICE9PSAnc3RyaW5nJyB8fCAhU1NFX1JFUVVFU1RfSURfUkUudGVzdChyZXF1ZXN0SWQpKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDAsICdNaXNzaW5nIG9yIGludmFsaWQgcmVxdWVzdElkJywgRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzc2VNYW5hZ2VyLmNyZWF0ZVRpY2tldChvcmdJZCwgcmVxdWVzdElkKTtcbiAgICBpZiAoIXJlc3VsdC5vaykge1xuICAgICAgaWYgKHJlc3VsdC5yZWFzb24gPT09ICdmb3JiaWRkZW4nKSB7XG4gICAgICAgIC8vIFRoZSBzdWJqZWN0IGlzIG93bmVkIGJ5IGFub3RoZXIgb3JnIOKAlCBkbyBub3QgY29uZmlybSBpdCBleGlzdHM7IGEgcGxhaW5cbiAgICAgICAgLy8gNDAzIGlzIGVub3VnaCBhbmQgbGVha3Mgbm90aGluZyBhYm91dCB3aGljaCByZXF1ZXN0SWRzIGFyZSBsaXZlLlxuICAgICAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdOb3QgYXV0aG9yaXplZCBmb3IgdGhpcyBsb2cgc3RyZWFtJywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5yZWFzb24gPT09ICdvcmctbGltaXQnKSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDQyOSwgJ1RvbyBtYW55IGxvZyBzdHJlYW0gdGlja2V0cyBpc3N1ZWQnLCBFcnJvckNvZGUuUVVPVEFfRVhDRUVERUQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VuZEVycm9yKHJlcywgNTAzLCAnTG9nIHN0cmVhbWluZyBzdWJzeXN0ZW0gYXQgY2FwYWNpdHknLCBFcnJvckNvZGUuUVVPVEFfRVhDRUVERUQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyB0aWNrZXQ6IHJlc3VsdC50aWNrZXQgfSk7XG4gIH0pO1xuXG4gIC8vIFRoZSBzdHJlYW0gaXRzZWxmIHJlc29sdmVzICsgY29uc3VtZXMgdGhlIHRpY2tldCBpbnNpZGUgbWlkZGxld2FyZSgpIGFuZFxuICAvLyByZWplY3RzIGFueSBhbm9ueW1vdXMgLyBpbnZhbGlkIC8gZXhwaXJlZCAvIGFscmVhZHktdXNlZCB0aWNrZXQgd2l0aCA0MDEuXG4gIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGFuZCBjb25maWd1cmUgYW4gRXhwcmVzcyBhcHBsaWNhdGlvbiB3aXRoIGNvbW1vbiBtaWRkbGV3YXJlXG4gKlxuICogU2V0cyB1cDpcbiAqIC0gQ09SUyB3aXRoIGNvbmZpZ3VyZWQgb3JpZ2luc1xuICogLSBIZWxtZXQgc2VjdXJpdHkgaGVhZGVyc1xuICogLSBSYXRlIGxpbWl0aW5nXG4gKiAtIEpTT04gYW5kIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2luZ1xuICogLSBUcnVzdCBwcm94eSBzZXR0aW5nc1xuICogLSBIZWFsdGggY2hlY2sgZW5kcG9pbnQgKC9oZWFsdGgpXG4gKiAtIE1ldHJpY3MgZW5kcG9pbnQgKC9tZXRyaWNzKVxuICogLSBTU0UgbG9ncyBlbmRwb2ludCAoL2xvZ3MvOnJlcXVlc3RJZCkg4oCUIG9ubHkgd2l0aCBgbG9nU3RyZWFtOiB0cnVlYFxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gKiBAcmV0dXJucyBDb25maWd1cmVkIEV4cHJlc3MgYXBwIGFuZCBTU0UgbWFuYWdlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB7IGFwcCwgc3NlTWFuYWdlciB9ID0gY3JlYXRlQXBwKCk7XG4gKlxuICogYXBwLnBvc3QoJy9hcGkvcmVzb3VyY2UnLCByZXF1aXJlQXV0aCwgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gKiAgIC8vIFlvdXIgcm91dGUgaGFuZGxlclxuICogfSk7XG4gKlxuICogc3RhcnRTZXJ2ZXIoYXBwLCB7IG5hbWU6ICdNeSBTZXJ2aWNlJyB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBwKG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMgPSB7fSk6IENyZWF0ZUFwcFJlc3VsdCB7XG4gIGNvbnN0IHtcbiAgICBlbmFibGVSYXRlTGltaXQgPSB0cnVlLFxuICAgIGxvZ1N0cmVhbSA9IGZhbHNlLFxuICAgIGVuYWJsZU9wZW5BcGkgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nLFxuICB9ID0gb3B0aW9ucztcblxuICBjb25zdCBzZXJ2aWNlTmFtZSA9IHByb2Nlc3MuZW52LlNFUlZJQ0VfTkFNRSB8fCAnYXBpJztcblxuICAvLyBBIGNhbGxlci1zdXBwbGllZCBgc3NlTWFuYWdlcmAgc2tpcHMgdGhlIGRlZmF1bHQgY29uc3RydWN0aW9uIGVudGlyZWx5LlxuICBjb25zdCBzc2VNYW5hZ2VyID0gb3B0aW9ucy5zc2VNYW5hZ2VyID8/IGNyZWF0ZURlZmF1bHRTc2VNYW5hZ2VyKHNlcnZpY2VOYW1lLCBsb2dTdHJlYW0pO1xuXG4gIC8vIFdpcmUgdGhlIGlkZW1wb3RlbmN5IHJlcGxheS1jYWNoZSBiYWNrZW5kIHVzZWQgYnkgdGhlIHBvc3QtYXV0aCByb3V0ZVxuICAvLyBmYWN0b3JpZXMgKGNyZWF0ZVByb3RlY3RlZFJvdXRlIC8gY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZSkuIFByZWZlclxuICAvLyBhbiBleHBsaWNpdGx5IGluamVjdGVkIHN0b3JlOyBvdGhlcndpc2UgYXV0by1jb25zdHJ1Y3QgZnJvbSB0aGUgc2hhcmVkIGVudlxuICAvLyBSZWRpcyBzbyBrZXllZCBtdXRhdGlvbiByZXRyaWVzIGRlZHVwZSBhY3Jvc3MgcmVwbGljYXMuIEZhbGxzIGJhY2sgdG8gdGhlXG4gIC8vIGluLW1lbW9yeSBkZWZhdWx0IHdoZW4gbm8gUmVkaXMgaXMgY29uZmlndXJlZCAoc2luZ2xlLXJlcGxpY2EgY29ycmVjdG5lc3MpLlxuICBjb25zdCByZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUgPSBvcHRpb25zLmlkZW1wb3RlbmN5U3RvcmUgPz8gY3JlYXRlRW52UmVkaXNJZGVtcG90ZW5jeVN0b3JlKCk7XG4gIGlmIChyZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUpIHtcbiAgICBzZXRJZGVtcG90ZW5jeVN0b3JlKHJlc29sdmVkSWRlbXBvdGVuY3lTdG9yZSk7XG4gIH1cblxuICAvLyBPcGVuVGVsZW1ldHJ5IGlzIE5PVCBpbml0aWFsaXplZCBoZXJlOiBieSB0aGUgdGltZSBjcmVhdGVBcHAgcnVucywgZXhwcmVzc1xuICAvLyBhbmQgaHR0cCBoYXZlIGFscmVhZHkgYmVlbiByZXF1aXJlZCwgc28gdGhlIGF1dG8taW5zdHJ1bWVudGF0aW9uIGhvb2tzXG4gIC8vIHdvdWxkIGhhdmUgbm90aGluZyB0byBwYXRjaCAobm8gaW5ib3VuZCBzcGFuIOKGkiBubyB0cmFjZSBpZCkuIFRyYWNpbmcgaXNcbiAgLy8gc3RhcnRlZCBieSB0aGUgYG90ZWwtYm9vdHN0cmFwLmpzYCBwcmVsb2FkIGluc3RlYWQgKG5vZGUgLXIg4oCmIOKAlCBzZWUgZWFjaFxuICAvLyBzZXJ2aWNlJ3MgRG9ja2VyZmlsZSBDTUQgLyBzdGFydCBzY3JpcHQpLCB3aGljaCBydW5zIGJlZm9yZSBhbnlcbiAgLy8gaW5zdHJ1bWVudGVkIG1vZHVsZSBsb2Fkcy4gYGN1cnJlbnRUcmFjZUlkKClgIHRoZW4gcmVhZHMgdGhlIGFjdGl2ZSBzcGFuLlxuXG4gIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuICBhcHBseVNlY3VyaXR5SGVhZGVycyhhcHAsIG9wdGlvbnMsIGVuYWJsZU9wZW5BcGkpO1xuICBhcHBseUJvZHlQYXJzaW5nKGFwcCwgb3B0aW9ucyk7XG5cbiAgLy8gVHJ1c3QgcHJveHkgKG11c3QgYmUgc2V0IGJlZm9yZSByYXRlIGxpbWl0ZXIgc28gcmVxLmlwIHJlc29sdmVzIGNvcnJlY3RseSlcbiAgYXBwLnNldCgndHJ1c3QgcHJveHknLCBDb25maWcuZ2V0KCdzZXJ2ZXInKS50cnVzdFByb3h5KTtcblxuICAvLyBSZXF1ZXN0IElEIOKAlCBwcmVmZXIgZXhpc3RpbmcgaGVhZGVyIGZyb20gbmdpbngsIG90aGVyd2lzZSBnZW5lcmF0ZSBvbmVcbiAgYXBwLnVzZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICBjb25zdCBoZHIgPSByZXEuaGVhZGVyc1sneC1yZXF1ZXN0LWlkJ107XG4gICAgY29uc3QgcmVxdWVzdElkID0gKEFycmF5LmlzQXJyYXkoaGRyKSA/IGhkclswXSA6IGhkcikgfHwgdXVpZCgpO1xuICAgIHJlcS5yZXF1ZXN0SWQgPSByZXF1ZXN0SWQ7XG4gICAgcmVzLnNldEhlYWRlcignWC1SZXF1ZXN0LUlkJywgcmVxdWVzdElkKTtcbiAgICBuZXh0KCk7XG4gIH0pO1xuXG4gIG1vdW50SW5mcmFFbmRwb2ludHMoYXBwLCBvcHRpb25zLCBzZXJ2aWNlTmFtZSwgZW5hYmxlT3BlbkFwaSk7XG4gIGlmIChlbmFibGVSYXRlTGltaXQpIG1vdW50UmF0ZUxpbWl0ZXIoYXBwLCBzZXJ2aWNlTmFtZSk7XG4gIGFwcGx5UmVxdWVzdFRlbGVtZXRyeShhcHApO1xuXG4gIC8vIE5PVEU6IGlkZW1wb3RlbmN5IGlzIGludGVudGlvbmFsbHkgTk9UIG1vdW50ZWQgaGVyZS4gSXQgbmVlZHMgdGhlIFZFUklGSUVEXG4gIC8vIG9yZyBpZCB0byBuYW1lc3BhY2UgaXRzIHJlcGxheSBjYWNoZSwgYnV0IHRoaXMgcHJlLWF1dGggcG9zaXRpb24gcnVucyBiZWZvcmVcbiAgLy8gYHJlcXVpcmVBdXRoYC9gYXR0YWNoUmVxdWVzdENvbnRleHRgIHBvcHVsYXRlIGlkZW50aXR5LCBzbyBhIGdsb2JhbCBtb3VudFxuICAvLyBoZXJlIGlzIGEgcGVybWFuZW50IG5vLW9wIChvcmcgYWx3YXlzIHVuZGVmaW5lZCDihpIgc2tpcCkuIEl0IGlzIGluc3RlYWQgd2lyZWRcbiAgLy8gaW50byB0aGUgcG9zdC1hdXRoIHJvdXRlIGNoYWlucyDigJQgc2VlIGBjcmVhdGVQcm90ZWN0ZWRSb3V0ZWAgL1xuICAvLyBgY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZWAgaW4gbWlkZGxld2FyZS1mYWN0b3J5LnRzLlxuXG4gIGlmIChsb2dTdHJlYW0pIHdpcmVTc2UoYXBwLCBzc2VNYW5hZ2VyKTtcblxuICByZXR1cm4geyBhcHAsIHNzZU1hbmFnZXIgfTtcbn1cbiJdfQ==
|
|
388
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2FwcC1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXRRLE9BQU8sRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2hFLE9BQU8sV0FBVyxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxPQUFPLEVBQUUsRUFBZ0UsTUFBTSxTQUFTLENBQUM7QUFDaEcsT0FBTyxTQUFTLEVBQUUsRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvRCxPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDM0MsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxtQkFBbUIsRUFBeUIsTUFBTSw2QkFBNkIsQ0FBQztBQUN6SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sdUJBQXVC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NEVBQTRFO0lBQzVFLCtFQUErRTtJQUMvRSxpRUFBaUU7SUFDakUsOERBQThEO0lBRTlELElBQUksU0FBUztRQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFFeEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHNlbmRTdWNjZXNzLCBzZW5kRXJyb3IsIGdlbmVyYXRlT3BlbkFwaVNwZWMsIEVycm9yQ29kZSwgY3JlYXRlTG9nZ2VyLCB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsLCBjcmVhdGVIZWFsdGhSb3V0ZXIsIHNldENvdW50ZXJFbWl0dGVyLCBzZXRHYXVnZUVtaXR0ZXIsIHJlcXVpcmVBdXRoLCBzYWZlRXF1YWwsIGNyZWF0ZUVudlNzZVRpY2tldFN0b3JlLCBTU0VfVElDS0VUX1RUTF9NUyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgT3BlbkFwaVNwZWNPcHRpb25zIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29uZmlnLCBDb3JlQ29uc3RhbnRzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtY29yZSc7XG5pbXBvcnQgeyBnZXRDb25uZWN0aW9uIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtZGF0YSc7XG5pbXBvcnQgY29tcHJlc3Npb24gZnJvbSAnY29tcHJlc3Npb24nO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgZXhwcmVzcywgeyB0eXBlIEV4cHJlc3MsIHR5cGUgTmV4dEZ1bmN0aW9uLCB0eXBlIFJlcXVlc3QsIHR5cGUgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCByYXRlTGltaXQsIHsgaXBLZXlHZW5lcmF0b3IgfSBmcm9tICdleHByZXNzLXJhdGUtbGltaXQnO1xuaW1wb3J0IGhlbG1ldCBmcm9tICdoZWxtZXQnO1xuaW1wb3J0IHN3YWdnZXJVaSBmcm9tICdzd2FnZ2VyLXVpLWV4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgZXRhZ01pZGRsZXdhcmUgfSBmcm9tICcuL2V0YWctbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0lkZW1wb3RlbmN5U3RvcmUsIHNldElkZW1wb3RlbmN5U3RvcmUsIHR5cGUgSWRlbXBvdGVuY3lTdG9yZSB9IGZyb20gJy4vaWRlbXBvdGVuY3ktbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBtZXRyaWNzTWlkZGxld2FyZSwgbWV0cmljc0hhbmRsZXIsIGluY0NvdW50ZXIsIHNldEdhdWdlIH0gZnJvbSAnLi9tZXRyaWNzLmpzJztcbmltcG9ydCB7IGNyZWF0ZVNoYXJlZFJhdGVMaW1pdFN0b3JlIH0gZnJvbSAnLi9yYXRlLWxpbWl0LXN0b3JlLmpzJztcbmltcG9ydCB7IHJlYWRpbmVzc0d1YXJkIH0gZnJvbSAnLi9yZWFkaW5lc3MuanMnO1xuaW1wb3J0IHsgU1NFTWFuYWdlciwgU1NFX1JFUVVFU1RfSURfUkUgfSBmcm9tICcuLi9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIuanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNTU0VSZWxheSB9IGZyb20gJy4uL2h0dHAvc3NlLXJlbGF5LmpzJztcblxuLy8gV2lyZSBhcGktY29yZSdzIGNvdW50ZXIgc2hpbSB0byB0aGUgcmVhbCBwcm9tLWNsaWVudCByZWdpc3RyeS4gVGhpcyBpc1xuLy8gYSBuby1vcCB1bnRpbCBpbmNDb3VudGVyIGlzIGNhbGxlZCBmb3IgdGhlIGZpcnN0IHRpbWUgKGxhenkgcmVnaXN0cmF0aW9uXG4vLyBpbiBtZXRyaWNzLnRzKSwgYW5kIGxldHMgYXBpLWNvcmUgaGVscGVycyBsaWtlIHRoZSBxdW90YSBjbGllbnQgcmVjb3JkXG4vLyBgcXVvdGFfZmFpbF9vcGVuX3RvdGFsYCB3aXRob3V0IHRha2luZyBhIGhhcmQgZGVwIG9uIGFwaS1zZXJ2ZXIuXG5zZXRDb3VudGVyRW1pdHRlcihpbmNDb3VudGVyKTtcbi8vIFNhbWUgc2VhbSBmb3IgR0FVR0VTLiBwaXBlbGluZS1kYXRhJ3MgcmVhZC1yZXBsaWNhIGxhZyBzYW1wbGVyIG5lZWRzIGl0OlxuLy8gcmVwbGF5IGxhZyBhbmQgdGhlIHN0YXRlIG9mIHRoZSByZWFkIGZhbGxiYWNrIGNpcmN1aXQgYXJlIHNhbXBsZWRcbi8vIHBvaW50LWluLXRpbWUgdmFsdWVzLCBzbyBlbWl0dGluZyB0aGVtIGFzIGNvdW50ZXJzIHdvdWxkIG1ha2UgZXZlcnkgcXVlcnlcbi8vIG92ZXIgdGhlbSB3cm9uZy4gcGlwZWxpbmUtZGF0YSBkZXBlbmRzIG9uIGFwaS1jb3JlIGFuZCBtdXN0IG5vdCBkZXBlbmQgb25cbi8vIGFwaS1zZXJ2ZXIsIGhlbmNlIHRoZSBzaGltIHJhdGhlciB0aGFuIGEgZGlyZWN0IGltcG9ydC5cbnNldEdhdWdlRW1pdHRlcihzZXRHYXVnZSk7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFwcE9wdGlvbnMge1xuICAvKiogRW5hYmxlIENPUlMgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUNvcnM/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIEhlbG1ldCBzZWN1cml0eSBoZWFkZXJzIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVIZWxtZXQ/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIHJhdGUgbGltaXRpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZVJhdGVMaW1pdD86IGJvb2xlYW47XG4gIC8qKiBFbmFibGUgSlNPTiBib2R5IHBhcnNpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUpzb25Cb2R5PzogYm9vbGVhbjtcbiAgLyoqIEpTT04gYm9keSBzaXplIGxpbWl0IChkZWZhdWx0OiAnMW1iJykgKi9cbiAganNvbkxpbWl0Pzogc3RyaW5nO1xuICAvKipcbiAgICogUGF0aCBwcmVmaXhlcyB0aGUgZ2xvYmFsIEpTT04gYm9keSBwYXJzZXIgbXVzdCBOT1QgdG91Y2gg4oCUIGZvciByb3V0ZXMgdGhhdCBuZWVkXG4gICAqIHRoZSByYXcgYm9keSAoZS5nLiBhIFN0cmlwZSB3ZWJob29rIHdob3NlIEhNQUMgaXMgY29tcHV0ZWQgb3ZlciB0aGUgZXhhY3QgYnl0ZXMpLlxuICAgKiBXaXRob3V0IHRoaXMgdGhlIGdsb2JhbCBwYXJzZXIgY29uc3VtZXMgdGhlIGJvZHkgZmlyc3QgYW5kIGEgbGF0ZXIgYGV4cHJlc3MucmF3KClgXG4gICAqIG9uIHRoZSBzYW1lIHBhdGggaXMgYSBuby1vcCwgYnJlYWtpbmcgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbi5cbiAgICovXG4gIGpzb25Cb2R5RXhjbHVkZT86IHN0cmluZ1tdO1xuICAvKiogRW5hYmxlIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2luZyAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlVXJsRW5jb2RlZD86IGJvb2xlYW47XG4gIC8qKiBVUkwtZW5jb2RlZCBib2R5IHNpemUgbGltaXQgKGRlZmF1bHQ6ICcxbWInKSAqL1xuICB1cmxFbmNvZGVkTGltaXQ/OiBzdHJpbmc7XG4gIC8qKiBDdXN0b20gU1NFIG1hbmFnZXIgaW5zdGFuY2UgKi9cbiAgc3NlTWFuYWdlcj86IFNTRU1hbmFnZXI7XG4gIC8qKlxuICAgKiBTZXJ2ZSB0aGUgcGVyLXJlcXVlc3QgYnVpbGQtbG9nIHN0cmVhbTogYFBPU1QgL2xvZ3MvdGlja2V0YCArXG4gICAqIGBHRVQgL2xvZ3MvOnJlcXVlc3RJZGAsIGEgbG9nIHRpY2tldCBzdG9yZSwgdGhlIGNyb3NzLXBvZCByZWxheSwgYW5kXG4gICAqIGBjdHgubG9nYCBmcmFtZXMgcHVzaGVkIHRvIFNTRS4gRGVmYXVsdCBmYWxzZSDigJQgYSBzZXJ2aWNlIHdpdGhvdXQgaXQgaGFzIG5vXG4gICAqIGAvbG9nc2Agcm91dGVzIGFuZCBgY3R4LmxvZ2Agb25seSB3cml0ZXMgdG8gdGhlIGxvZ2dlci5cbiAgICovXG4gIGxvZ1N0cmVhbT86IGJvb2xlYW47XG4gIC8qKiBIZWFsdGggY2hlY2sgZGVwZW5kZW5jeSBjaGVja2VyIOKAlCBpZiBwcm92aWRlZCwgL2hlYWx0aCByZXBvcnRzIGRlcGVuZGVuY3kgc3RhdHVzICovXG4gIGNoZWNrRGVwZW5kZW5jaWVzPzogKCkgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCAnY29ubmVjdGVkJyB8ICdkaXNjb25uZWN0ZWQnIHwgJ3Vua25vd24nPj47XG4gIC8qKlxuICAgKiBTZXJ2ZSB0aGUgT3BlbkFQSSBzcGVjIGF0IGAvZG9jcy9vcGVuYXBpLmpzb25gIGFuZCBTd2FnZ2VyIFVJIGF0IGAvZG9jc2AuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIE9GRiB1bmRlciBgTk9ERV9FTlY9cHJvZHVjdGlvbmA6IHRoZSByb3V0ZXMgYXJlIHJlZ2lzdGVyZWQgYWJvdmVcbiAgICogdGhlIHJhdGUgbGltaXRlciBhbmQgYXJlIG5vdCBhdXRoLWdhdGVkLCBzbyBpbiBwcm9kdWN0aW9uIHRoZXkgd291bGQgcHVibGlzaFxuICAgKiB0aGUgZnVsbCByb3V0ZSArIHNjaGVtYSBpbnZlbnRvcnkgb2YgZXZlcnkgc2VydmljZSB0byBhbnlvbmUgd2hvIGNvdWxkIHJlYWNoXG4gICAqIHRoZSBwb3J0LiBQYXNzIGB0cnVlYCBleHBsaWNpdGx5IHRvIHNlcnZlIHRoZW0gaW4gcHJvZHVjdGlvbiBhbnl3YXkuXG4gICAqL1xuICBlbmFibGVPcGVuQXBpPzogYm9vbGVhbjtcbiAgLyoqIE9wZW5BUEkgc3BlYyBjdXN0b21pemF0aW9uIG9wdGlvbnMgKi9cbiAgb3BlbkFwaU9wdGlvbnM/OiBPcGVuQXBpU3BlY09wdGlvbnM7XG4gIC8qKiBFbmFibGUgZ3ppcC9kZWZsYXRlIHJlc3BvbnNlIGNvbXByZXNzaW9uIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVDb21wcmVzc2lvbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZGVtcG90ZW5jeSByZXBsYXktY2FjaGUgYmFja2VuZCBmb3Iga2V5ZWQgbXV0YXRpb24gcmV0cmllcy4gV2hlbiBvbWl0dGVkLFxuICAgKiBjcmVhdGVBcHAgYXV0by13aXJlcyB0aGUgc2hhcmVkIGVudiBSZWRpcyBzdG9yZSAobXVsdGktcmVwbGljYSBkZWR1cCkgaWZcbiAgICogUmVkaXMgaXMgY29uZmlndXJlZCwgZWxzZSBrZWVwcyB0aGUgaW4tbWVtb3J5IGRlZmF1bHQgKHNpbmdsZS1yZXBsaWNhKS5cbiAgICogUGFzcyBhbiBleHBsaWNpdCBzdG9yZSB0byBpbmplY3QgYSBiZXNwb2tlIGJhY2tlbmQgKGUuZy4gYSBzZXJ2aWNlJ3Mgb3duXG4gICAqIGlvcmVkaXMgY29ubmVjdGlvbikuXG4gICAqL1xuICBpZGVtcG90ZW5jeVN0b3JlPzogSWRlbXBvdGVuY3lTdG9yZTtcbiAgLyoqXG4gICAqIEV4dHJhIHdhcm11cCBjYWxsYmFja3MgaW52b2tlZCBieSBgR0VUIC93YXJtdXBgIGluIGFkZGl0aW9uIHRvIHRoZVxuICAgKiBkZWZhdWx0IFBvc3RncmVzIHBpbmcuIFVzZSBmb3Igc2VydmljZXMgdGhhdCBkZXBlbmQgb24gTW9uZ28sIFJlZGlzLFxuICAgKiBTUVMsIGV0Yy4g4oCUIHByZS13YXJtaW5nIG9wZW5zIGNvbm5lY3Rpb24gcG9vbHMgYmVmb3JlIHJlYWwgdHJhZmZpY1xuICAgKiBhcnJpdmVzLiBFYWNoIGNhbGxiYWNrIHNob3VsZCByZXNvbHZlIHdoZW4gaXRzIGRlcGVuZGVuY3kgaXMgcmVhZHk7XG4gICAqIGFueSByZWplY3Rpb24gY2F1c2VzIC93YXJtdXAgdG8gcmV0dXJuIDUwMy5cbiAgICovXG4gIHdhcm11cEhvb2tzPzogQXJyYXk8KCkgPT4gUHJvbWlzZTx2b2lkPj47XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGNyZWF0aW5nIGFuIEV4cHJlc3MgYXBwbGljYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVBcHBSZXN1bHQge1xuICAvKiogQ29uZmlndXJlZCBFeHByZXNzIGFwcGxpY2F0aW9uICovXG4gIGFwcDogRXhwcmVzcztcbiAgLyoqIFNTRSBtYW5hZ2VyIGluc3RhbmNlICovXG4gIHNzZU1hbmFnZXI6IFNTRU1hbmFnZXI7XG59XG5cbi8qKiBIZWxtZXQgKHN0cmljdCBDU1ApLCBDT1JTLCBjb21wcmVzc2lvbiBhbmQgRVRhZ3MuICovXG5mdW5jdGlvbiBhcHBseVNlY3VyaXR5SGVhZGVycyhhcHA6IEV4cHJlc3MsIG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMsIGVuYWJsZU9wZW5BcGk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgeyBlbmFibGVDb3JzID0gdHJ1ZSwgZW5hYmxlSGVsbWV0ID0gdHJ1ZSwgZW5hYmxlQ29tcHJlc3Npb24gPSB0cnVlIH0gPSBvcHRpb25zO1xuICAvLyBTd2FnZ2VyIFVJIG5lZWRzIHVuc2FmZS1pbmxpbmUgKyB1bnNhZmUtZXZhbCBmb3IgaXRzIGJ1bmRsZWQgc2NyaXB0cyDigJRcbiAgLy8gYnV0IENTUCBpcyBvbmx5IHJlbGF4ZWQgdGhhdCBmYXIgd2hlbiAoYSkgT3BlbkFQSSBpcyBlbmFibGVkIEFORCAoYikgd2UncmVcbiAgLy8gbm90IGluIHByb2R1Y3Rpb24uIEluIHByb2QsIFN3YWdnZXIgc2hvdWxkIGJlIHNlcnZlZCBiZWhpbmQgYSBzZXBhcmF0ZVxuICAvLyBob3N0IG9yIGF1dGgtZ2F0ZWQgcm91dGU7IHRoZSBtYWluIGFwcCBrZWVwcyB0aGUgc3RyaWN0IENTUCBzbyBhIFN0b3JlZFxuICAvLyBYU1MgaW4gYW55IGhhbmRsZXIgY2FuJ3QgYGV2YWwoKWAgYXJiaXRyYXJ5IHNjcmlwdC5cbiAgY29uc3QgYWxsb3dTd2FnZ2VyQ3NwID0gZW5hYmxlT3BlbkFwaSAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuICBpZiAoZW5hYmxlSGVsbWV0KSB7XG4gICAgYXBwLnVzZShoZWxtZXQoe1xuICAgICAgY29udGVudFNlY3VyaXR5UG9saWN5OiB7XG4gICAgICAgIGRpcmVjdGl2ZXM6IHtcbiAgICAgICAgICBkZWZhdWx0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc2NyaXB0U3JjOiBhbGxvd1N3YWdnZXJDc3BcbiAgICAgICAgICAgID8gW1wiJ3NlbGYnXCIsIFwiJ3Vuc2FmZS1pbmxpbmUnXCIsIFwiJ3Vuc2FmZS1ldmFsJ1wiXVxuICAgICAgICAgICAgOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc3R5bGVTcmM6IFtcIidzZWxmJ1wiLCBcIid1bnNhZmUtaW5saW5lJ1wiXSxcbiAgICAgICAgICBpbWdTcmM6IFtcIidzZWxmJ1wiLCAnZGF0YTonLCAnYmxvYjonXSxcbiAgICAgICAgICBjb25uZWN0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgZm9udFNyYzogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIG9iamVjdFNyYzogW1wiJ25vbmUnXCJdLFxuICAgICAgICAgIGZyYW1lQW5jZXN0b3JzOiBbXCInbm9uZSdcIl0sXG4gICAgICAgICAgYmFzZVVyaTogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIGZvcm1BY3Rpb246IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSkpO1xuICB9XG5cbiAgaWYgKGVuYWJsZUNvcnMpIHtcbiAgICBhcHAudXNlKGNvcnMoQ29uZmlnLmdldCgnc2VydmVyJykuY29ycykpO1xuICB9XG5cbiAgLy8gUmVzcG9uc2UgY29tcHJlc3Npb24gKGd6aXAvZGVmbGF0ZSkg4oCUIHNraXAgU1NFIHN0cmVhbXNcbiAgaWYgKGVuYWJsZUNvbXByZXNzaW9uKSB7XG4gICAgYXBwLnVzZShjb21wcmVzc2lvbih7XG4gICAgICBmaWx0ZXI6IChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gRG9uJ3QgY29tcHJlc3MgU1NFIHN0cmVhbXMuIE1hdGNoIGJ5IGluY2x1c2lvbjogdGhlIEFjY2VwdCBoZWFkZXIgaXNcbiAgICAgICAgLy8gb2Z0ZW4gYSBsaXN0IChlLmcuIFwidGV4dC9ldmVudC1zdHJlYW0sICovKlwiKSwgd2hpY2ggZXhhY3QgZXF1YWxpdHlcbiAgICAgICAgLy8gd291bGQgbWlzcywgY29tcHJlc3NpbmcvYnVmZmVyaW5nIHRoZSBzdHJlYW0uXG4gICAgICAgIGlmICgocmVxLmhlYWRlcnMuYWNjZXB0IHx8ICcnKS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gY29tcHJlc3Npb24uZmlsdGVyKHJlcSwgcmVzKTtcbiAgICAgIH0sXG4gICAgICB0aHJlc2hvbGQ6IENvcmVDb25zdGFudHMuQ09NUFJFU1NJT05fVEhSRVNIT0xEX0JZVEVTLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEVUYWcgc3VwcG9ydCBmb3IgY29uZGl0aW9uYWwgR0VUIHJlcXVlc3RzICgzMDQgTm90IE1vZGlmaWVkKVxuICBhcHAudXNlKGV0YWdNaWRkbGV3YXJlKCkpO1xufVxuXG4vKiogSlNPTiArIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2Vycy4gKi9cbmZ1bmN0aW9uIGFwcGx5Qm9keVBhcnNpbmcoYXBwOiBFeHByZXNzLCBvcHRpb25zOiBDcmVhdGVBcHBPcHRpb25zKTogdm9pZCB7XG4gIGNvbnN0IHsgZW5hYmxlSnNvbkJvZHkgPSB0cnVlLCBqc29uTGltaXQgPSAnMW1iJywgZW5hYmxlVXJsRW5jb2RlZCA9IHRydWUsIHVybEVuY29kZWRMaW1pdCA9ICcxbWInIH0gPSBvcHRpb25zO1xuICBpZiAoZW5hYmxlSnNvbkJvZHkpIHtcbiAgICBjb25zdCBqc29uUGFyc2VyID0gZXhwcmVzcy5qc29uKHsgbGltaXQ6IGpzb25MaW1pdCB9KTtcbiAgICBjb25zdCBleGNsdWRlID0gb3B0aW9ucy5qc29uQm9keUV4Y2x1ZGUgPz8gW107XG4gICAgaWYgKGV4Y2x1ZGUubGVuZ3RoID4gMCkge1xuICAgICAgLy8gU2tpcCB0aGUgZ2xvYmFsIEpTT04gcGFyc2VyIGZvciByYXctYm9keSBwYXRocyBzbyBhIHBlci1wYXRoIGBleHByZXNzLnJhdygpYFxuICAgICAgLy8gY2FuIHJlYWQgdGhlIGV4YWN0IGJ5dGVzIChzZWUgYGpzb25Cb2R5RXhjbHVkZWApLlxuICAgICAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IChleGNsdWRlLnNvbWUoKHApID0+IHJlcS5wYXRoLnN0YXJ0c1dpdGgocCkpID8gbmV4dCgpIDoganNvblBhcnNlcihyZXEsIHJlcywgbmV4dCkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXBwLnVzZShqc29uUGFyc2VyKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZW5hYmxlVXJsRW5jb2RlZCkge1xuICAgIGFwcC51c2UoZXhwcmVzcy51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiB1cmxFbmNvZGVkTGltaXQgfSkpO1xuICB9XG59XG5cbi8qKlxuICogSGVhbHRoLCByZWFkaW5lc3MgZ3VhcmQsIGAvd2FybXVwYCwgYC9tZXRyaWNzYCBhbmQgdGhlIE9wZW5BUEkgZG9jcyDigJQgYWxsXG4gKiByZWdpc3RlcmVkIGJlZm9yZSB0aGUgcmF0ZSBsaW1pdGVyIHNvIHRoZXkgYXJlIG5ldmVyIHRocm90dGxlZC5cbiAqL1xuZnVuY3Rpb24gbW91bnRJbmZyYUVuZHBvaW50cyhhcHA6IEV4cHJlc3MsIG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMsIHNlcnZpY2VOYW1lOiBzdHJpbmcsIGVuYWJsZU9wZW5BcGk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgeyBjaGVja0RlcGVuZGVuY2llcywgb3BlbkFwaU9wdGlvbnMsIHdhcm11cEhvb2tzID0gW10gfSA9IG9wdGlvbnM7XG5cbiAgYXBwLnVzZShjcmVhdGVIZWFsdGhSb3V0ZXIoe1xuICAgIHNlcnZpY2VOYW1lLFxuICAgIGNoZWNrRGVwZW5kZW5jaWVzLFxuICB9KSk7XG5cbiAgLy8gUmVhZGluZXNzIGd1YXJkIOKAlCA1MDNzIGJ1c2luZXNzIHRyYWZmaWMgd2hpbGUgdGhlIHNlcnZpY2UgaXMgTm90UmVhZHlcbiAgLy8gKGRhdGFzdG9yZSBzdGlsbCBjb25uZWN0aW5nIGF0IHN0YXJ0dXAsIG9yIGRyb3BwZWQpLiBNb3VudGVkIHJpZ2h0IGFmdGVyXG4gIC8vIHRoZSBoZWFsdGggcm91dGVyIGFuZCBiZWZvcmUgZXZlcnl0aGluZyBlbHNlIHNvIGEgTm90UmVhZHkgcmVxdWVzdCBpc1xuICAvLyByZWplY3RlZCBjaGVhcGx5LCBiZWZvcmUgcmF0ZS1saW1pdCAvIGlkZW1wb3RlbmN5IC8gYnVzaW5lc3MgaGFuZGxlcnMgZXZlclxuICAvLyB0b3VjaCBhIGRpc2Nvbm5lY3RlZCBkYXRhc3RvcmUuIEl0IGFsbG93bGlzdHMgdGhlIGluZnJhIGVuZHBvaW50c1xuICAvLyAoL21ldHJpY3MsIC93YXJtdXAsIC9kb2NzLCAvbG9ncykgcmVnaXN0ZXJlZCBiZWxvdywgcGx1cyAvaGVhbHRoICsgL3JlYWR5LlxuICBhcHAudXNlKHJlYWRpbmVzc0d1YXJkKCkpO1xuXG4gIC8vIFdhcm0tdXAgZW5kcG9pbnQg4oCUIHByZS1vcGVucyBjb25uZWN0aW9uIHBvb2xzIHNvIHRoZSBmaXJzdCByZWFsIHJlcXVlc3RcbiAgLy8gZG9lc24ndCBwYXkgY29sZC1zdGFydCBsYXRlbmN5LiBBbHdheXMgcGluZ3MgUG9zdGdyZXM7IHNlcnZpY2VzIHVzaW5nXG4gIC8vIE1vbmdvIC8gUmVkaXMgLyBTUVMgcGFzcyBgd2FybXVwSG9va3NgIHNvIHRob3NlIGFyZSB3YXJtZWQgaW4gcGFyYWxsZWwuXG4gIC8vXG4gIC8vIEdBVEVEIHRvIHZlcmlmaWVkIHNlcnZpY2UgcHJpbmNpcGFscy4gRXZlcnkgaGl0IHJ1bnMgYSBQb3N0Z3JlcyByb3VuZC10cmlwXG4gIC8vIHBsdXMgYWxsIGB3YXJtdXBIb29rc2AgKE1vbmdvL1JlZGlzL1NRUyksIHNvIGFuIG9wZW4gZW5kcG9pbnQgd291bGQgbGV0IGFuXG4gIC8vIGFub255bW91cyBsb29wIGFtcGxpZnkgaW50byBkYXRhc3RvcmUgbG9hZCBvbiBldmVyeSBzZXJ2aWNlIGluIHRoZSBmbGVldCDigJRcbiAgLy8gYW5kIGl0IGlzIHJlZ2lzdGVyZWQgYWJvdmUgdGhlIHJhdGUgbGltaXRlciwgc28gbm90aGluZyB3b3VsZCB0aHJvdHRsZSBpdC5cbiAgLy8gYHZlcmlmeVNlcnZpY2VQcmluY2lwYWxgIGNoZWNrcyB0aGUgYmVhcmVyIHRva2VuIGNyeXB0b2dyYXBoaWNhbGx5LCBzbyBpdCBpc1xuICAvLyBzYWZlIGhlcmUsIGFib3ZlIGByZXF1aXJlQXV0aGAuXG4gIGFwcC5nZXQoJy93YXJtdXAnLCBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgaWYgKCF2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwNCwgJ05vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBnZXRDb25uZWN0aW9uKCkudGVzdENvbm5lY3Rpb24oKSxcbiAgICAgICAgLi4ud2FybXVwSG9va3MubWFwKChob29rKSA9PiBob29rKCkpLFxuICAgICAgXSk7XG4gICAgICBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyB3YXJtZWQ6IHRydWUsIGhvb2tzOiB3YXJtdXBIb29rcy5sZW5ndGggfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA1MDMsICdXYXJtdXAgZmFpbGVkJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBQcm9tZXRoZXVzIG1ldHJpY3MgZW5kcG9pbnQg4oCUIGFsd2F5cyByZWdpc3RlcmVkIChuZXZlciB0aHJvdHRsZWQpLlxuICAvL1xuICAvLyBPcHRpb25hbGx5IGdhdGVkOiB3aGVuIGBNRVRSSUNTX1NDUkFQRV9UT0tFTmAgaXMgc2V0LCB0aGUgc2NyYXBlciBtdXN0IHNlbmRcbiAgLy8gaXQgYXMgYSBiZWFyZXIgdG9rZW4gKFByb21ldGhldXMgYGJlYXJlcl90b2tlbmAgLyBgYmVhcmVyX3Rva2VuX2ZpbGVgIGluIHRoZVxuICAvLyBzY3JhcGUgY29uZmlnKS4gTGVmdCB1bmdhdGVkIHdoZW4gdW5zZXQgc28gZW5hYmxpbmcgaXQgaXMgYSBkZWxpYmVyYXRlLFxuICAvLyBjb29yZGluYXRlZCBjaGFuZ2UgcmF0aGVyIHRoYW4gYSBzaWxlbnQgbW9uaXRvcmluZyBvdXRhZ2Ug4oCUIHRlbmFudCBpZHMgc3RheVxuICAvLyBvdXQgb2YgdGhlIG91dHB1dCByZWdhcmRsZXNzLCBiZWNhdXNlIHRoZSBwZXItb3JnIGxhYmVsIGRlZmF1bHRzIE9GRiAoc2VlXG4gIC8vIEhUVFBfTUVUUklDU19PUkdfU0FNUExFX1JBVEUgaW4gbWV0cmljcy50cykuXG4gIGNvbnN0IG1ldHJpY3NUb2tlbiA9IHByb2Nlc3MuZW52Lk1FVFJJQ1NfU0NSQVBFX1RPS0VOO1xuICBhcHAuZ2V0KCcvbWV0cmljcycsIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIGlmICghbWV0cmljc1Rva2VuKSB7XG4gICAgICBuZXh0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gICAgY29uc3QgcHJlc2VudGVkID0gaGVhZGVyPy5zdGFydHNXaXRoKCdCZWFyZXIgJykgPyBoZWFkZXIuc2xpY2UoNykgOiB1bmRlZmluZWQ7XG4gICAgLy8gQ29uc3RhbnQtdGltZSBjb21wYXJlIOKAlCBhIGxlbmd0aC1pbmRlcGVuZGVudCBlcXVhbGl0eSBjaGVjayBoZXJlIHdvdWxkXG4gICAgLy8gbGVhayB0aGUgdG9rZW4gYSBieXRlIGF0IGEgdGltZS5cbiAgICBpZiAoIXByZXNlbnRlZCB8fCAhc2FmZUVxdWFsKHByZXNlbnRlZCwgbWV0cmljc1Rva2VuKSkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDA0LCAnTm90IGZvdW5kJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5leHQoKTtcbiAgfSwgbWV0cmljc0hhbmRsZXIoKSk7XG5cbiAgaWYgKGVuYWJsZU9wZW5BcGkpIHtcbiAgICBjb25zdCBzcGVjID0gZ2VuZXJhdGVPcGVuQXBpU3BlYyhvcGVuQXBpT3B0aW9ucyk7XG4gICAgYXBwLmdldCgnL2RvY3Mvb3BlbmFwaS5qc29uJywgKF9yZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIHJlcy5qc29uKHNwZWMpO1xuICAgIH0pO1xuICAgIGFwcC51c2UoJy9kb2NzJywgc3dhZ2dlclVpLnNlcnZlLCBzd2FnZ2VyVWkuc2V0dXAoc3BlYywge1xuICAgICAgY3VzdG9tU2l0ZVRpdGxlOiBvcGVuQXBpT3B0aW9ucz8udGl0bGUgPz8gJ1BpcGVsaW5lIEJ1aWxkZXIgQVBJIERvY3MnLFxuICAgIH0pKTtcbiAgfVxufVxuXG4vKiogR2xvYmFsIHJhdGUgbGltaXRlciDigJQgc2hhcmVkIGFjcm9zcyByZXBsaWNhcyB2aWEgdGhlIGVudiBSZWRpcyB3aGVuIGNvbmZpZ3VyZWQuICovXG5mdW5jdGlvbiBtb3VudFJhdGVMaW1pdGVyKGFwcDogRXhwcmVzcywgc2VydmljZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCByYXRlTGltaXRDb25maWcgPSBDb25maWcuZ2V0KCdyYXRlTGltaXQnKTtcblxuICBjb25zdCByYXRlTGltaXRPcHRpb25zOiBQYXJhbWV0ZXJzPHR5cGVvZiByYXRlTGltaXQ+WzBdID0ge1xuICAgIG1heDogcmF0ZUxpbWl0Q29uZmlnLm1heCxcbiAgICB3aW5kb3dNczogcmF0ZUxpbWl0Q29uZmlnLndpbmRvd01zLFxuICAgIHN0YW5kYXJkSGVhZGVyczogdHJ1ZSxcbiAgICBsZWdhY3lIZWFkZXJzOiBmYWxzZSxcbiAgICAvLyBTa2lwIHJhdGUgbGltaXRpbmcgb25seSBmb3IgQ1JZUFRPR1JBUEhJQ0FMTFktVkVSSUZJRUQgaW50ZXJuYWwgc2VydmljZVxuICAgIC8vIGNhbGxlcnMuIFRoZSBsaW1pdGVyIHJ1bnMgYmVmb3JlIHJlcXVpcmVBdXRoLCBzbyBhIHBsYWludGV4dCBoZWFkZXJcbiAgICAvLyB3b3VsZCBiZSBzcG9vZmFibGUgYnkgYW55IGV4dGVybmFsIGNsaWVudCDihpIgdG90YWwgYnlwYXNzLlxuICAgIC8vIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwgdmVyaWZpZXMgdGhlIHNpZ25lZCBzZXJ2aWNlIEpXVCBpbnN0ZWFkO1xuICAgIC8vIGludGVyLXNlcnZpY2UgY2FsbGVycyBhbGwgc2VuZCBvbmUgKGdldFNlcnZpY2VBdXRoSGVhZGVyKS5cbiAgICBza2lwOiAocmVxOiBSZXF1ZXN0KSA9PiB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcSksXG4gICAgLy8gS2V5IG9uIGNsaWVudCBJUCBvbmx5LiBUaGUgbGltaXRlciBydW5zIHByZS1hdXRoLCBzbyBgcmVxLnVzZXJgIGlzIHVuc2V0XG4gICAgLy8gYW5kIGFueSBvcmcgaWQgd291bGQgY29tZSBmcm9tIHRoZSBjYWxsZXItc3VwcGxpZWQgYHgtb3JnLWlkYCBoZWFkZXIg4oCUXG4gICAgLy8gc3Bvb2ZhYmxlLCBsZXR0aW5nIGFuIGF0dGFja2VyIHJvdGF0ZSB2YWx1ZXMgdG8gZXZhZGUgdGhlIGJ1Y2tldCBvclxuICAgIC8vIGZsb29kIGEgdmljdGltIG9yZydzIGJ1Y2tldC4gaXBLZXlHZW5lcmF0b3Igbm9ybWFsaXplcyBJUHY2IHRvIGEgLzY0XG4gICAgLy8gcHJlZml4IChhbHNvIHJlcXVpcmVkIGJ5IGV4cHJlc3MtcmF0ZS1saW1pdCA4LngncyB2YWxpZGF0b3IpLlxuICAgIGtleUdlbmVyYXRvcjogKHJlcTogUmVxdWVzdCkgPT4gaXBLZXlHZW5lcmF0b3IocmVxLmlwIHx8ICdhbm9uJywgNjQpLFxuICAgIC8vIEEgc3RvcmUgZmFpbHVyZSAoUmVkaXMgZG93biAvIGZhaWxpbmcgb3ZlcikgbXVzdCBkZWdyYWRlIHRvIFwibm90IHJhdGVcbiAgICAvLyBsaW1pdGVkXCIsIG5ldmVyIHRvIGEgNTAwIG9uIGV2ZXJ5IHJlcXVlc3Qgb2YgZXZlcnkgc2VydmljZS5cbiAgICBwYXNzT25TdG9yZUVycm9yOiB0cnVlLFxuICAgIGhhbmRsZXI6IChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MjksICdUb28gbWFueSByZXF1ZXN0cywgcGxlYXNlIHRyeSBhZ2FpbiBsYXRlci4nLCBFcnJvckNvZGUuUkFURV9MSU1JVF9FWENFRURFRCk7XG4gICAgfSxcbiAgICAvLyBTaGFyZWQgc3RhdGUgYWNyb3NzIHJlcGxpY2FzICh0aGUgcHJvY2Vzcy13aWRlIHJhdGUtbGltaXQgUmVkaXMgY29ubmVjdGlvbjtcbiAgICAvLyB1bmRlZmluZWQgd2l0aG91dCBSZWRpcyDihpIgcGVyLXByb2Nlc3MgbWVtb3J5IHN0b3JlLCByaWdodCBmb3Igb25lIHJlcGxpY2EpLlxuICAgIC8vIE5hbWVzcGFjZWQgcGVyIFNFUlZJQ0U6IGV2ZXJ5IHNlcnZpY2Ugc2hhcmVzIG9uZSBSZWRpcywgYW5kIGFuIHVucHJlZml4ZWRcbiAgICAvLyBgcmw6PGlwPmAga2V5IHdvdWxkIGxldCBvbmUgY2xpZW50J3MgdHJhZmZpYyB0byBBTlkgc2VydmljZSBkcmFpbiBpdHNcbiAgICAvLyBidWRnZXQgb24gRVZFUlkgc2VydmljZS5cbiAgICBzdG9yZTogY3JlYXRlU2hhcmVkUmF0ZUxpbWl0U3RvcmUoYCR7c2VydmljZU5hbWV9Omdsb2JhbGApLFxuICB9O1xuXG4gIGFwcC51c2UocmF0ZUxpbWl0KHJhdGVMaW1pdE9wdGlvbnMpKTtcbn1cblxuLyoqIFJlcXVlc3QgdGltZW91dCwgZHVyYXRpb24gbG9nZ2luZyBhbmQgSFRUUCBtZXRyaWNzLiAqL1xuZnVuY3Rpb24gYXBwbHlSZXF1ZXN0VGVsZW1ldHJ5KGFwcDogRXhwcmVzcyk6IHZvaWQge1xuICAvLyBFeHByZXNzIHJlcXVlc3QgdGltZW91dCDigJQgdXNlcyBDb3JlQ29uc3RhbnRzIHRvIHNoYXJlIHRoZSBzYW1lIGRlZmF1bHQgYXMgTGFtYmRhIGhhbmRsZXJzXG4gIGNvbnN0IHRpbWVvdXRNcyA9IENvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TO1xuICBhcHAudXNlKChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICByZXMuc2V0VGltZW91dCh0aW1lb3V0TXMsICgpID0+IHtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ1JlcXVlc3QgdGltZW91dCcpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUmVxdWVzdCBkdXJhdGlvbiBsb2dnaW5nXG4gIGNvbnN0IGR1cmF0aW9uTG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXF1ZXN0LWR1cmF0aW9uJyk7XG4gIGFwcC51c2UoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKSA9PiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHJlcy5vbignZmluaXNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnQ7XG4gICAgICAvLyBMb2cgYHJlcS5wYXRoYCAobm8gcXVlcnkgc3RyaW5nKSDigJQgYSBzdHJheSBgP3Rva2VuPWAvYD90aWNrZXQ9YCBtdXN0IG5vdCBiZVxuICAgICAgLy8gcGVyc2lzdGVkIHZlcmJhdGltIG9uIGV2ZXJ5IHJlcXVlc3QgKG1pcnJvcnMgdGhlIGF1dGh6LWRlbmlhbCBhdWRpdG9yJ3Mgc3RyaXApLlxuICAgICAgZHVyYXRpb25Mb2dnZXIuaW5mbyhgJHtyZXEubWV0aG9kfSAke3JlcS5wYXRofSAke3Jlcy5zdGF0dXNDb2RlfSAke2R1cmF0aW9ufW1zYCwge1xuICAgICAgICBtZXRob2Q6IHJlcS5tZXRob2QsXG4gICAgICAgIHBhdGg6IHJlcS5wYXRoLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXMuc3RhdHVzQ29kZSxcbiAgICAgICAgZHVyYXRpb25NczogZHVyYXRpb24sXG4gICAgICAgIHJlcXVlc3RJZDogcmVxLnJlcXVlc3RJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUHJvbWV0aGV1cyBtZXRyaWNzIG1pZGRsZXdhcmUg4oCUIHJlY29yZHMgcmVxdWVzdCBkdXJhdGlvbiBhbmQgY291bnRcbiAgYXBwLnVzZShtZXRyaWNzTWlkZGxld2FyZSgpKTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBTU0UgbWFuYWdlci4gVGhlIHJlbGF5ICh0aGlzIHNlcnZpY2UncyBvd24gUmVkaXMgY2hhbm5lbCkgaXNcbiAqIGJ1aWx0IG9ubHkgd2hlbiBzb21ldGhpbmcgc3RyZWFtczogdGhlIGxvZyBzdHJlYW0gdHVybnMgaXQgb24gaGVyZSwgYW5kIGFuXG4gKiBvcmcta2V5ZWQgY2hhbm5lbCB0dXJucyBpdCBvbiB3aGVuIHJlZ2lzdGVyZWQgKHJlZ2lzdGVyU3NlVGlja2V0Q2hhbm5lbCkuXG4gKiBUaGUgbG9nIHRpY2tldCBzdG9yZSBleGlzdHMgb25seSB3aXRoIHRoZSBsb2cgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBjcmVhdGVEZWZhdWx0U3NlTWFuYWdlcihzZXJ2aWNlTmFtZTogc3RyaW5nLCBsb2dTdHJlYW06IGJvb2xlYW4pOiBTU0VNYW5hZ2VyIHtcbiAgY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHtcbiAgICBsb2dTdHJlYW0sXG4gICAgcmVsYXlGYWN0b3J5OiAoKSA9PiBjcmVhdGVFbnZSZWRpc1NTRVJlbGF5KHNlcnZpY2VOYW1lKSxcbiAgICAuLi4obG9nU3RyZWFtICYmIHtcbiAgICAgIHRpY2tldFN0b3JlOiBjcmVhdGVFbnZTc2VUaWNrZXRTdG9yZSh7XG4gICAgICAgIHR0bE1zOiBTU0VfVElDS0VUX1RUTF9NUyxcbiAgICAgICAga2V5UHJlZml4OiBgbG9nczoke3NlcnZpY2VOYW1lfWAsXG4gICAgICB9KSxcbiAgICB9KSxcbiAgfSk7XG4gIGlmIChsb2dTdHJlYW0pIHNzZU1hbmFnZXIuZW5hYmxlUmVsYXkoKTtcbiAgcmV0dXJuIHNzZU1hbmFnZXI7XG59XG5cbi8qKlxuICogVGhlIHBlci1yZXF1ZXN0IGJ1aWxkLWxvZyBzdHJlYW06IGBQT1NUIC9sb2dzL3RpY2tldGAgKyBgR0VUIC9sb2dzLzpyZXF1ZXN0SWRgLlxuICpcbiAqIFRpY2tldC1nYXRlZCDigJQgdGhlIHN0cmVhbSBjYXJyaWVzIHBlci1vcmcgYnVpbGQgbG9ncywgc28gaXQgbXVzdCBub3QgYmVcbiAqIHdvcmxkLXJlYWRhYmxlLiBDbGllbnRzIGZpcnN0IFBPU1QgL2xvZ3MvdGlja2V0IChKV1QtYXV0aGVudGljYXRlZCkgdG8gbWludCBhXG4gKiBzaG9ydC1saXZlZCwgc2luZ2xlLXVzZSB0aWNrZXQgYm91bmQgdG8gdGhlaXIgb3JnIEFORCB0byB0aGUgc3BlY2lmaWNcbiAqIGByZXF1ZXN0SWRgIHN0cmVhbSB0aGV5IGludGVuZCB0byBvcGVuLCB0aGVuIG9wZW4gdGhlIEV2ZW50U291cmNlIHdpdGhcbiAqID90aWNrZXQ9PHQ+LiBUaGlzIGtlZXBzIHRoZSBKV1Qgb3V0IG9mIHF1ZXJ5IHN0cmluZ3MgLyBhY2Nlc3MgbG9ncyB3aGlsZVxuICogZW5mb3JjaW5nIG9yZyBvd25lcnNoaXAsIHBlci1zdWJqZWN0IGF1dGhvcml6YXRpb24sIGFuZCB0aGUgcGVyLW9yZ1xuICogY29ubmVjdGlvbiBjYXAgb24gdGhlIHN0cmVhbS4gTWlycm9ycyB0aGUgbWVzc2FnZS1zZXJ2aWNlIG5vdGlmaWNhdGlvbnMgU1NFXG4gKiB0aWNrZXQgZXhjaGFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHdpcmVTc2UoYXBwOiBFeHByZXNzLCBzc2VNYW5hZ2VyOiBTU0VNYW5hZ2VyKTogdm9pZCB7XG4gIGFwcC5wb3N0KCcvbG9ncy90aWNrZXQnLCByZXF1aXJlQXV0aCwgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGNvbnN0IG9yZ0lkID0gcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkPy50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwMCwgJ1Rva2VuIG1pc3Npbmcgb3JnYW5pemF0aW9uJywgRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUaGUgY2FsbGVyIG11c3QgbmFtZSB0aGUgc3RyZWFtIHN1YmplY3QgdXAgZnJvbnQgc28gdGhlIHRpY2tldCBpcyBib3VuZCB0b1xuICAgIC8vIGl0LiBXaXRob3V0IHRoaXMsIGEgdGlja2V0IGNvdWxkIGJlIHJlcGxheWVkIGFnYWluc3QgQU5ZIHJlcXVlc3RJZCB0aGVcbiAgICAvLyBvcmcgY291bGQgZ3Vlc3MsIGxldHRpbmcgaXQgYXR0YWNoIHRvIGFub3RoZXIgb3JnJ3MgbG9nIHN0cmVhbS4gU3RyaWN0bHlcbiAgICAvLyBmb3JtYXQtdmFsaWRhdGVkIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiBwYXlsb2FkIGludG8gdGhlIHN1YmplY3QuXG4gICAgY29uc3QgcmVxdWVzdElkID0gKHJlcS5ib2R5IGFzIHsgcmVxdWVzdElkPzogdW5rbm93biB9IHwgdW5kZWZpbmVkKT8ucmVxdWVzdElkO1xuICAgIGlmICh0eXBlb2YgcmVxdWVzdElkICE9PSAnc3RyaW5nJyB8fCAhU1NFX1JFUVVFU1RfSURfUkUudGVzdChyZXF1ZXN0SWQpKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDAsICdNaXNzaW5nIG9yIGludmFsaWQgcmVxdWVzdElkJywgRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzc2VNYW5hZ2VyLmNyZWF0ZVRpY2tldChvcmdJZCwgcmVxdWVzdElkKTtcbiAgICBpZiAoIXJlc3VsdC5vaykge1xuICAgICAgaWYgKHJlc3VsdC5yZWFzb24gPT09ICdmb3JiaWRkZW4nKSB7XG4gICAgICAgIC8vIFRoZSBzdWJqZWN0IGlzIG93bmVkIGJ5IGFub3RoZXIgb3JnIOKAlCBkbyBub3QgY29uZmlybSBpdCBleGlzdHM7IGEgcGxhaW5cbiAgICAgICAgLy8gNDAzIGlzIGVub3VnaCBhbmQgbGVha3Mgbm90aGluZyBhYm91dCB3aGljaCByZXF1ZXN0SWRzIGFyZSBsaXZlLlxuICAgICAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdOb3QgYXV0aG9yaXplZCBmb3IgdGhpcyBsb2cgc3RyZWFtJywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5yZWFzb24gPT09ICdvcmctbGltaXQnKSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDQyOSwgJ1RvbyBtYW55IGxvZyBzdHJlYW0gdGlja2V0cyBpc3N1ZWQnLCBFcnJvckNvZGUuUVVPVEFfRVhDRUVERUQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VuZEVycm9yKHJlcywgNTAzLCAnTG9nIHN0cmVhbWluZyBzdWJzeXN0ZW0gYXQgY2FwYWNpdHknLCBFcnJvckNvZGUuUVVPVEFfRVhDRUVERUQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyB0aWNrZXQ6IHJlc3VsdC50aWNrZXQgfSk7XG4gIH0pO1xuXG4gIC8vIFRoZSBzdHJlYW0gaXRzZWxmIHJlc29sdmVzICsgY29uc3VtZXMgdGhlIHRpY2tldCBpbnNpZGUgbWlkZGxld2FyZSgpIGFuZFxuICAvLyByZWplY3RzIGFueSBhbm9ueW1vdXMgLyBpbnZhbGlkIC8gZXhwaXJlZCAvIGFscmVhZHktdXNlZCB0aWNrZXQgd2l0aCA0MDEuXG4gIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGFuZCBjb25maWd1cmUgYW4gRXhwcmVzcyBhcHBsaWNhdGlvbiB3aXRoIGNvbW1vbiBtaWRkbGV3YXJlXG4gKlxuICogU2V0cyB1cDpcbiAqIC0gQ09SUyB3aXRoIGNvbmZpZ3VyZWQgb3JpZ2luc1xuICogLSBIZWxtZXQgc2VjdXJpdHkgaGVhZGVyc1xuICogLSBSYXRlIGxpbWl0aW5nXG4gKiAtIEpTT04gYW5kIFVSTC1lbmNvZGVkIGJvZHkgcGFyc2luZ1xuICogLSBUcnVzdCBwcm94eSBzZXR0aW5nc1xuICogLSBIZWFsdGggY2hlY2sgZW5kcG9pbnQgKC9oZWFsdGgpXG4gKiAtIE1ldHJpY3MgZW5kcG9pbnQgKC9tZXRyaWNzKVxuICogLSBTU0UgbG9ncyBlbmRwb2ludCAoL2xvZ3MvOnJlcXVlc3RJZCkg4oCUIG9ubHkgd2l0aCBgbG9nU3RyZWFtOiB0cnVlYFxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gKiBAcmV0dXJucyBDb25maWd1cmVkIEV4cHJlc3MgYXBwIGFuZCBTU0UgbWFuYWdlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB7IGFwcCwgc3NlTWFuYWdlciB9ID0gY3JlYXRlQXBwKCk7XG4gKlxuICogYXBwLnBvc3QoJy9hcGkvcmVzb3VyY2UnLCByZXF1aXJlQXV0aCwgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gKiAgIC8vIFlvdXIgcm91dGUgaGFuZGxlclxuICogfSk7XG4gKlxuICogc3RhcnRTZXJ2ZXIoYXBwLCB7IG5hbWU6ICdNeSBTZXJ2aWNlJyB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBwKG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMgPSB7fSk6IENyZWF0ZUFwcFJlc3VsdCB7XG4gIGNvbnN0IHtcbiAgICBlbmFibGVSYXRlTGltaXQgPSB0cnVlLFxuICAgIGxvZ1N0cmVhbSA9IGZhbHNlLFxuICAgIGVuYWJsZU9wZW5BcGkgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nLFxuICB9ID0gb3B0aW9ucztcblxuICBjb25zdCBzZXJ2aWNlTmFtZSA9IHByb2Nlc3MuZW52LlNFUlZJQ0VfTkFNRSB8fCAnYXBpJztcblxuICAvLyBBIGNhbGxlci1zdXBwbGllZCBgc3NlTWFuYWdlcmAgc2tpcHMgdGhlIGRlZmF1bHQgY29uc3RydWN0aW9uIGVudGlyZWx5LlxuICBjb25zdCBzc2VNYW5hZ2VyID0gb3B0aW9ucy5zc2VNYW5hZ2VyID8/IGNyZWF0ZURlZmF1bHRTc2VNYW5hZ2VyKHNlcnZpY2VOYW1lLCBsb2dTdHJlYW0pO1xuXG4gIC8vIFdpcmUgdGhlIGlkZW1wb3RlbmN5IHJlcGxheS1jYWNoZSBiYWNrZW5kIHVzZWQgYnkgdGhlIHBvc3QtYXV0aCByb3V0ZVxuICAvLyBmYWN0b3JpZXMgKGNyZWF0ZVByb3RlY3RlZFJvdXRlIC8gY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZSkuIFByZWZlclxuICAvLyBhbiBleHBsaWNpdGx5IGluamVjdGVkIHN0b3JlOyBvdGhlcndpc2UgYXV0by1jb25zdHJ1Y3QgZnJvbSB0aGUgc2hhcmVkIGVudlxuICAvLyBSZWRpcyBzbyBrZXllZCBtdXRhdGlvbiByZXRyaWVzIGRlZHVwZSBhY3Jvc3MgcmVwbGljYXMuIEZhbGxzIGJhY2sgdG8gdGhlXG4gIC8vIGluLW1lbW9yeSBkZWZhdWx0IHdoZW4gbm8gUmVkaXMgaXMgY29uZmlndXJlZCAoc2luZ2xlLXJlcGxpY2EgY29ycmVjdG5lc3MpLlxuICBjb25zdCByZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUgPSBvcHRpb25zLmlkZW1wb3RlbmN5U3RvcmUgPz8gY3JlYXRlRW52UmVkaXNJZGVtcG90ZW5jeVN0b3JlKCk7XG4gIGlmIChyZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUpIHtcbiAgICBzZXRJZGVtcG90ZW5jeVN0b3JlKHJlc29sdmVkSWRlbXBvdGVuY3lTdG9yZSk7XG4gIH1cblxuICAvLyBPcGVuVGVsZW1ldHJ5IGlzIE5PVCBpbml0aWFsaXplZCBoZXJlOiBieSB0aGUgdGltZSBjcmVhdGVBcHAgcnVucywgZXhwcmVzc1xuICAvLyBhbmQgaHR0cCBoYXZlIGFscmVhZHkgYmVlbiByZXF1aXJlZCwgc28gdGhlIGF1dG8taW5zdHJ1bWVudGF0aW9uIGhvb2tzXG4gIC8vIHdvdWxkIGhhdmUgbm90aGluZyB0byBwYXRjaCAobm8gaW5ib3VuZCBzcGFuIOKGkiBubyB0cmFjZSBpZCkuIFRyYWNpbmcgaXNcbiAgLy8gc3RhcnRlZCBieSB0aGUgYG90ZWwtYm9vdHN0cmFwLmpzYCBwcmVsb2FkIGluc3RlYWQgKG5vZGUgLXIg4oCmIOKAlCBzZWUgZWFjaFxuICAvLyBzZXJ2aWNlJ3MgRG9ja2VyZmlsZSBDTUQgLyBzdGFydCBzY3JpcHQpLCB3aGljaCBydW5zIGJlZm9yZSBhbnlcbiAgLy8gaW5zdHJ1bWVudGVkIG1vZHVsZSBsb2Fkcy4gYGN1cnJlbnRUcmFjZUlkKClgIHRoZW4gcmVhZHMgdGhlIGFjdGl2ZSBzcGFuLlxuXG4gIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuICBhcHBseVNlY3VyaXR5SGVhZGVycyhhcHAsIG9wdGlvbnMsIGVuYWJsZU9wZW5BcGkpO1xuICBhcHBseUJvZHlQYXJzaW5nKGFwcCwgb3B0aW9ucyk7XG5cbiAgLy8gVHJ1c3QgcHJveHkgKG11c3QgYmUgc2V0IGJlZm9yZSByYXRlIGxpbWl0ZXIgc28gcmVxLmlwIHJlc29sdmVzIGNvcnJlY3RseSlcbiAgYXBwLnNldCgndHJ1c3QgcHJveHknLCBDb25maWcuZ2V0KCdzZXJ2ZXInKS50cnVzdFByb3h5KTtcblxuICAvLyBSZXF1ZXN0IElEIOKAlCBwcmVmZXIgZXhpc3RpbmcgaGVhZGVyIGZyb20gbmdpbngsIG90aGVyd2lzZSBnZW5lcmF0ZSBvbmVcbiAgYXBwLnVzZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICBjb25zdCBoZHIgPSByZXEuaGVhZGVyc1sneC1yZXF1ZXN0LWlkJ107XG4gICAgY29uc3QgcmVxdWVzdElkID0gKEFycmF5LmlzQXJyYXkoaGRyKSA/IGhkclswXSA6IGhkcikgfHwgdXVpZCgpO1xuICAgIHJlcS5yZXF1ZXN0SWQgPSByZXF1ZXN0SWQ7XG4gICAgcmVzLnNldEhlYWRlcignWC1SZXF1ZXN0LUlkJywgcmVxdWVzdElkKTtcbiAgICBuZXh0KCk7XG4gIH0pO1xuXG4gIG1vdW50SW5mcmFFbmRwb2ludHMoYXBwLCBvcHRpb25zLCBzZXJ2aWNlTmFtZSwgZW5hYmxlT3BlbkFwaSk7XG4gIGlmIChlbmFibGVSYXRlTGltaXQpIG1vdW50UmF0ZUxpbWl0ZXIoYXBwLCBzZXJ2aWNlTmFtZSk7XG4gIGFwcGx5UmVxdWVzdFRlbGVtZXRyeShhcHApO1xuXG4gIC8vIE5PVEU6IGlkZW1wb3RlbmN5IGlzIGludGVudGlvbmFsbHkgTk9UIG1vdW50ZWQgaGVyZS4gSXQgbmVlZHMgdGhlIFZFUklGSUVEXG4gIC8vIG9yZyBpZCB0byBuYW1lc3BhY2UgaXRzIHJlcGxheSBjYWNoZSwgYnV0IHRoaXMgcHJlLWF1dGggcG9zaXRpb24gcnVucyBiZWZvcmVcbiAgLy8gYHJlcXVpcmVBdXRoYC9gYXR0YWNoUmVxdWVzdENvbnRleHRgIHBvcHVsYXRlIGlkZW50aXR5LCBzbyBhIGdsb2JhbCBtb3VudFxuICAvLyBoZXJlIGlzIGEgcGVybWFuZW50IG5vLW9wIChvcmcgYWx3YXlzIHVuZGVmaW5lZCDihpIgc2tpcCkuIEl0IGlzIGluc3RlYWQgd2lyZWRcbiAgLy8gaW50byB0aGUgcG9zdC1hdXRoIHJvdXRlIGNoYWlucyDigJQgc2VlIGBjcmVhdGVQcm90ZWN0ZWRSb3V0ZWAgL1xuICAvLyBgY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZWAgaW4gbWlkZGxld2FyZS1mYWN0b3J5LnRzLlxuXG4gIGlmIChsb2dTdHJlYW0pIHdpcmVTc2UoYXBwLCBzc2VNYW5hZ2VyKTtcblxuICByZXR1cm4geyBhcHAsIHNzZU1hbmFnZXIgfTtcbn1cbiJdfQ==
|
package/lib/api/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './rate-limit-by-org.js';
|
|
|
6
6
|
export { createSharedRateLimitStore } from './rate-limit-store.js';
|
|
7
7
|
export * from './require-org-id.js';
|
|
8
8
|
export * from './tenant-context.js';
|
|
9
|
+
export * from './write-pin.js';
|
|
9
10
|
export * from './get-context.js';
|
|
10
11
|
export * from './app-factory.js';
|
|
11
12
|
export * from './health-checks.js';
|
package/lib/api/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from './rate-limit-by-org.js';
|
|
|
9
9
|
export { createSharedRateLimitStore } from './rate-limit-store.js';
|
|
10
10
|
export * from './require-org-id.js';
|
|
11
11
|
export * from './tenant-context.js';
|
|
12
|
+
export * from './write-pin.js';
|
|
12
13
|
export * from './get-context.js';
|
|
13
14
|
// App factory
|
|
14
15
|
export * from './app-factory.js';
|
|
@@ -33,4 +34,4 @@ export * from './server.js';
|
|
|
33
34
|
export { isReady, setReady, readinessGuard } from './readiness.js';
|
|
34
35
|
// Route wrapper
|
|
35
36
|
export * from './route-wrapper.js';
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsYUFBYTtBQUNiLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRSxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGtCQUFrQixDQUFDO0FBRWpDLGNBQWM7QUFDZCxjQUFjLGtCQUFrQixDQUFDO0FBRWpDLHVCQUF1QjtBQUN2QixjQUFjLG9CQUFvQixDQUFDO0FBRW5DLDJEQUEyRDtBQUMzRCxjQUFjLG9CQUFvQixDQUFDO0FBRW5DLGdCQUFnQjtBQUNoQixjQUFjLHdCQUF3QixDQUFDO0FBRXZDLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsbURBQW1EO0FBQ25ELE9BQU8sRUFBRSxtQkFBbUIsRUFBeUIsTUFBTSw2QkFBNkIsQ0FBQztBQUV6RiwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLE9BQU8sRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3hELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsRUFBc0IsTUFBTSxjQUFjLENBQUM7QUFFbkksbUJBQW1CO0FBQ25CLGNBQWMsYUFBYSxDQUFDO0FBRTVCLGdGQUFnRjtBQUNoRiw0RUFBNEU7QUFDNUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkUsZ0JBQWdCO0FBQ2hCLGNBQWMsb0JBQW9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLy8gTWlkZGxld2FyZVxuZXhwb3J0ICogZnJvbSAnLi9taWRkbGV3YXJlLWZhY3RvcnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9jb250ZXh0LW1pZGRsZXdhcmUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9jaGVjay1xdW90YS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL21ldGVyLXF1b3RhLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vcmF0ZS1saW1pdC1ieS1vcmcuanMnO1xuZXhwb3J0IHsgY3JlYXRlU2hhcmVkUmF0ZUxpbWl0U3RvcmUgfSBmcm9tICcuL3JhdGUtbGltaXQtc3RvcmUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXF1aXJlLW9yZy1pZC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbmFudC1jb250ZXh0LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vd3JpdGUtcGluLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG4vLyBBcHAgZmFjdG9yeVxuZXhwb3J0ICogZnJvbSAnLi9hcHAtZmFjdG9yeS5qcyc7XG5cbi8vIEhlYWx0aC1jaGVjayBoZWxwZXJzXG5leHBvcnQgKiBmcm9tICcuL2hlYWx0aC1jaGVja3MuanMnO1xuXG4vLyBNb25nb0RCIGNvbm5lY3Rpb24gaGVscGVyIChkZXBlbmRlbmN5LWluamVjdGVkIG1vbmdvb3NlKVxuZXhwb3J0ICogZnJvbSAnLi9tb25nby1jb25uZWN0LmpzJztcblxuLy8gUXVvdGEgaGVscGVyc1xuZXhwb3J0ICogZnJvbSAnLi9xdW90YS1yZXNlcnZhdGlvbi5qcyc7XG5cbi8vIElkZW1wb3RlbmN5IOKAlCBvbmx5IHRoZSBzdG9yZSBhY2Nlc3NvciBpcyBwdWJsaWM7IHRoZSBtaWRkbGV3YXJlLCB0aGUgc3RvcmVcbi8vIGZhY3RvcmllcyBhbmQgdGhlIHN0b3JlIHNldHRlciBhcmUgd2lyZWQgYnkgYGNyZWF0ZUFwcGAvYG1pZGRsZXdhcmUtZmFjdG9yeWBcbi8vIGluc2lkZSB0aGlzIHBhY2thZ2UgYW5kIGhhdmUgbm8gZXh0ZXJuYWwgY2FsbGVyLlxuZXhwb3J0IHsgZ2V0SWRlbXBvdGVuY3lTdG9yZSwgdHlwZSBJZGVtcG90ZW5jeVN0b3JlIH0gZnJvbSAnLi9pZGVtcG90ZW5jeS1taWRkbGV3YXJlLmpzJztcblxuLy8gT2JzZXJ2YWJpbGl0eS4gYHNodXRkb3duVHJhY2luZ2AgaXMgY2FsbGVkIGJ5IHRoaXMgcGFja2FnZSdzIG93biBgc2VydmVyLmpzYFxuLy8gc2h1dGRvd24gcGF0aCwgYW5kIHRoZSBtZXRyaWNzIG1pZGRsZXdhcmUvaGFuZGxlciBhcmUgbW91bnRlZCBieSBgY3JlYXRlQXBwYC5cbmV4cG9ydCB7IHdpdGhTcGFuLCBjdXJyZW50VHJhY2VJZCB9IGZyb20gJy4vdHJhY2luZy5qcyc7XG5leHBvcnQgeyByZWdpc3RlclNlY3JldFJvdGF0aW9uR2F1Z2UsIGluY0NvdW50ZXIsIG9ic2VydmUsIHNldEdhdWdlLCBjcmVhdGVNZXRyaWNIZWxwZXJzLCB0eXBlIE1ldHJpY0hlbHBlcnMgfSBmcm9tICcuL21ldHJpY3MuanMnO1xuXG4vLyBTZXJ2ZXIgdXRpbGl0aWVzXG5leHBvcnQgKiBmcm9tICcuL3NlcnZlci5qcyc7XG5cbi8vIFJlYWRpbmVzcyBzdGF0ZSArIGd1YXJkIG1pZGRsZXdhcmUuIGBERUZBVUxUX1JFQURJTkVTU19CWVBBU1NgIGlzIHRoZSBndWFyZCdzXG4vLyBvd24gZGVmYXVsdCDigJQgY2FsbGVycyBwYXNzIHRoZWlyIG93biBsaXN0IG9yIHRha2UgdGhlIGRlZmF1bHQgaW1wbGljaXRseS5cbmV4cG9ydCB7IGlzUmVhZHksIHNldFJlYWR5LCByZWFkaW5lc3NHdWFyZCB9IGZyb20gJy4vcmVhZGluZXNzLmpzJztcblxuLy8gUm91dGUgd3JhcHBlclxuZXhwb3J0ICogZnJvbSAnLi9yb3V0ZS13cmFwcGVyLmpzJztcblxuLy8gUmVxdWVzdC9SZXNwb25zZSB0eXBlcy4gYGNyZWF0ZVJlcXVlc3RDb250ZXh0YCBpcyB0aGUgZmFjdG9yeVxuLy8gYGF0dGFjaFJlcXVlc3RDb250ZXh0YCBjYWxsczsgaXQgaXMgbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBzdXJmYWNlLlxuZXhwb3J0IHR5cGUgeyBSZXF1ZXN0TG9nZ2VyLCBSZXF1ZXN0Q29udGV4dCB9IGZyb20gJy4vcmVxdWVzdC10eXBlcy5qcyc7XG4iXX0=
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { type TenantContext } from '@pipeline-builder/pipeline-data';
|
|
2
2
|
import type { Request, Response, NextFunction } from 'express';
|
|
3
|
-
/**
|
|
4
|
-
* Resolves the RLS tenant scope for a request. The default reads the CALLER's
|
|
5
|
-
* authenticated identity org (`ctx.identity.orgId`, validated by requireOrgId) — never a
|
|
6
|
-
* route param, which names the QUERIED scope, the wrong tenant for RLS. Services with a different request boundary supply their own resolver (e.g. platform
|
|
7
|
-
* sets the scope pre-auth from an unverified JWT peek so unauthenticated endpoints still
|
|
8
|
-
* get a sane default).
|
|
9
|
-
*/
|
|
10
3
|
export type TenantScopeResolver = (req: Request) => TenantContext;
|
|
11
4
|
/**
|
|
12
5
|
* Establish the request's row-level-security tenant scope.
|
|
@@ -24,4 +17,4 @@ export type TenantScopeResolver = (req: Request) => TenantContext;
|
|
|
24
17
|
* which under FORCE RLS hide every row and refuse writes — a wiring bug surfacing as a
|
|
25
18
|
* silently empty result instead of an error.
|
|
26
19
|
*/
|
|
27
|
-
export declare function withTenantContext(resolve?: TenantScopeResolver): (req: Request,
|
|
20
|
+
export declare function withTenantContext(resolve?: TenantScopeResolver): (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { isSystemAdmin, setLogContextProvider } from '@pipeline-builder/api-core';
|
|
3
|
+
import { createLogger, isSystemAdmin, setLogContextProvider } from '@pipeline-builder/api-core';
|
|
4
4
|
import { getTenantContext, runWithTenantContext } from '@pipeline-builder/pipeline-data';
|
|
5
5
|
import { getContext } from './get-context.js';
|
|
6
|
+
import { applyWritePin, recordWriteForPin, writePinActive } from './write-pin.js';
|
|
6
7
|
/**
|
|
7
8
|
* Teach the logger where the ambient org/user identity lives — the SINGLE wire
|
|
8
9
|
* point for log tenancy across every service.
|
|
@@ -28,6 +29,14 @@ setLogContextProvider(() => {
|
|
|
28
29
|
// rather than to a tenant named "".
|
|
29
30
|
return { orgId: ctx.orgId || undefined, userId: ctx.userId };
|
|
30
31
|
});
|
|
32
|
+
/**
|
|
33
|
+
* Resolves the RLS tenant scope for a request. The default reads the CALLER's
|
|
34
|
+
* authenticated identity org (`ctx.identity.orgId`, validated by requireOrgId) — never a
|
|
35
|
+
* route param, which names the QUERIED scope, the wrong tenant for RLS. Services with a different request boundary supply their own resolver (e.g. platform
|
|
36
|
+
* sets the scope pre-auth from an unverified JWT peek so unauthenticated endpoints still
|
|
37
|
+
* get a sane default).
|
|
38
|
+
*/
|
|
39
|
+
const logger = createLogger('tenant-context');
|
|
31
40
|
/** Default resolver: the authenticated identity's org + super-admin flag, plus
|
|
32
41
|
* the active-org parent (org → team hierarchy) so downstream side-effects can
|
|
33
42
|
* reach it without a request, and the caller's user id for the app-layer
|
|
@@ -58,7 +67,7 @@ const identityScope = (req) => ({
|
|
|
58
67
|
* silently empty result instead of an error.
|
|
59
68
|
*/
|
|
60
69
|
export function withTenantContext(resolve = identityScope) {
|
|
61
|
-
return (req,
|
|
70
|
+
return (req, res, next) => {
|
|
62
71
|
let scope;
|
|
63
72
|
try {
|
|
64
73
|
scope = resolve(req);
|
|
@@ -67,7 +76,41 @@ export function withTenantContext(resolve = identityScope) {
|
|
|
67
76
|
next(err);
|
|
68
77
|
return;
|
|
69
78
|
}
|
|
70
|
-
runWithTenantContext(scope, () =>
|
|
79
|
+
runWithTenantContext(scope, () => {
|
|
80
|
+
// Read-after-write ACROSS requests (see ./write-pin.ts).
|
|
81
|
+
//
|
|
82
|
+
// GATED SYNCHRONOUSLY AND FIRST. With no read replica configured — how
|
|
83
|
+
// all four targets ship — this returns here: no response listener, no
|
|
84
|
+
// Redis, and `next()` called synchronously exactly as before any of this
|
|
85
|
+
// existed. Everything below is opt-in machinery, and a feature nobody has
|
|
86
|
+
// enabled must not make the request path asynchronous for every route on
|
|
87
|
+
// every target.
|
|
88
|
+
if (!writePinActive()) {
|
|
89
|
+
next();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// The pin is recorded on `finish`, after the response, so a write never
|
|
93
|
+
// waits on Redis. It reads the SAME `mayHaveWritten` flag that
|
|
94
|
+
// `withTenantTx` sets, which is why it catches a GET that writes and
|
|
95
|
+
// ignores a POST that only validates — the HTTP method cannot tell you
|
|
96
|
+
// which happened.
|
|
97
|
+
res.on('finish', () => recordWriteForPin(scope));
|
|
98
|
+
// `next()` runs inside the AsyncLocalStorage scope either way:
|
|
99
|
+
// the store propagates through the promise continuation.
|
|
100
|
+
//
|
|
101
|
+
// A failed lookup must not fail the request — applyWritePin already fails
|
|
102
|
+
// CLOSED internally (unknown means "assume written", i.e. use the
|
|
103
|
+
// primary), so the catch here is for a genuinely unexpected throw and
|
|
104
|
+
// continues with whatever the resolver produced.
|
|
105
|
+
void applyWritePin(scope).then(() => next(), (err) => {
|
|
106
|
+
// Defensive: applyWritePin is written not to reject.
|
|
107
|
+
scope.mayHaveWritten = true;
|
|
108
|
+
logger.warn('Write-pin pre-check threw; assuming a recent write and reading from the primary', {
|
|
109
|
+
error: err instanceof Error ? err.message : String(err),
|
|
110
|
+
});
|
|
111
|
+
next();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
71
114
|
};
|
|
72
115
|
}
|
|
73
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3RlbmFudC1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxpQ0FBaUMsQ0FBQztBQUU3RyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFOUM7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gscUJBQXFCLENBQUMsR0FBRyxFQUFFO0lBQ3pCLE1BQU0sR0FBRyxHQUFHLGdCQUFnQixFQUFFLENBQUM7SUFDL0IsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUMzQiw2RUFBNkU7SUFDN0UseUVBQXlFO0lBQ3pFLG9DQUFvQztJQUNwQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLElBQUksU0FBUyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDL0QsQ0FBQyxDQUFDLENBQUM7QUFXSDs7OzZDQUc2QztBQUM3QyxNQUFNLGFBQWEsR0FBd0IsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkQsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSx1RUFBdUU7SUFDdkUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztJQUNyQyxNQUFNLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksU0FBUztJQUNwRCxZQUFZLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQztJQUNoQyxXQUFXLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxvQkFBb0I7Q0FDNUMsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLE9BQU8sR0FBd0IsYUFBYTtJQUM1RSxPQUFPLENBQUMsR0FBWSxFQUFFLElBQWMsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDaEUsSUFBSSxLQUFvQixDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUNELG9CQUFvQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgaXNTeXN0ZW1BZG1pbiwgc2V0TG9nQ29udGV4dFByb3ZpZGVyIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgZ2V0VGVuYW50Q29udGV4dCwgcnVuV2l0aFRlbmFudENvbnRleHQsIHR5cGUgVGVuYW50Q29udGV4dCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWRhdGEnO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSwgTmV4dEZ1bmN0aW9uIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSAnLi9nZXQtY29udGV4dC5qcyc7XG5cbi8qKlxuICogVGVhY2ggdGhlIGxvZ2dlciB3aGVyZSB0aGUgYW1iaWVudCBvcmcvdXNlciBpZGVudGl0eSBsaXZlcyDigJQgdGhlIFNJTkdMRSB3aXJlXG4gKiBwb2ludCBmb3IgbG9nIHRlbmFuY3kgYWNyb3NzIGV2ZXJ5IHNlcnZpY2UuXG4gKlxuICogYGFwaS1jb3JlYCAod2hpY2ggb3ducyB0aGUgbG9nZ2VyKSBoYXMgbm8gaW50ZXJuYWwgZGVwZW5kZW5jaWVzLCBhbmQgdGhlXG4gKiByZXF1ZXN0IHNjb3BlIGxpdmVzIGluIGBwaXBlbGluZS1kYXRhYCwgd2hpY2ggZGVwZW5kcyBvbiBpdCDigJQgc28gdGhlIGxvZ2dlclxuICogdGFrZXMgYSBwcm92aWRlciByYXRoZXIgdGhhbiBpbXBvcnRpbmcgdGhlIEFzeW5jTG9jYWxTdG9yYWdlIGRpcmVjdGx5LiBUaGlzXG4gKiBtb2R1bGUgaXMgdGhlIG5hdHVyYWwgcGxhY2UgdG8gcmVnaXN0ZXI6IGl0IGFscmVhZHkgYnJpZGdlcyBib3RoIHBhY2thZ2VzLFxuICogYW5kIGV2ZXJ5IHNlcnZpY2UgdGhhdCBvcGVucyBhIHRlbmFudCBzY29wZSBkb2VzIHNvIHRocm91Z2ggdGhlXG4gKiBgd2l0aFRlbmFudENvbnRleHRgIGV4cG9ydGVkIGJlbG93IChwbGF0Zm9ybSBpbmNsdWRlZCwgdmlhIGl0cyBvd24gcHJlLWF1dGhcbiAqIHJlc29sdmVyKS4gUmVnaXN0ZXJpbmcgaGVyZSByYXRoZXIgdGhhbiBpbiBlYWNoIHNlcnZpY2UncyBib290c3RyYXAgbWVhbnMgYVxuICogbmV3IHNlcnZpY2UgY2Fubm90IGZvcmdldCB0byBkbyBpdC5cbiAqXG4gKiBNb2R1bGUtc2NvcGUgb24gcHVycG9zZTogaWRlbXBvdGVudCwgYW5kIGl0IG11c3QgYmUgaW4gcGxhY2UgYmVmb3JlIHRoZSBmaXJzdFxuICogcmVxdWVzdCBpcyBsb2dnZWQuXG4gKi9cbnNldExvZ0NvbnRleHRQcm92aWRlcigoKSA9PiB7XG4gIGNvbnN0IGN0eCA9IGdldFRlbmFudENvbnRleHQoKTtcbiAgaWYgKCFjdHgpIHJldHVybiB1bmRlZmluZWQ7XG4gIC8vIEVtcHR5LXN0cmluZyBvcmdJZCAodGhlIHByZS1hdXRoIGRlZmF1bHQgZm9yIHVuYXV0aGVudGljYXRlZCBlbmRwb2ludHMpIGlzXG4gIC8vIE5PVCBhbiBvcmcg4oCUIGxlYXZlIHRoZSBmaWVsZCBvZmYgc28gdGhlIGxpbmUgaXMgcm91dGVkIGFzIHVuYXR0cmlidXRlZFxuICAvLyByYXRoZXIgdGhhbiB0byBhIHRlbmFudCBuYW1lZCBcIlwiLlxuICByZXR1cm4geyBvcmdJZDogY3R4Lm9yZ0lkIHx8IHVuZGVmaW5lZCwgdXNlcklkOiBjdHgudXNlcklkIH07XG59KTtcblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgUkxTIHRlbmFudCBzY29wZSBmb3IgYSByZXF1ZXN0LiBUaGUgZGVmYXVsdCByZWFkcyB0aGUgQ0FMTEVSJ3NcbiAqIGF1dGhlbnRpY2F0ZWQgaWRlbnRpdHkgb3JnIChgY3R4LmlkZW50aXR5Lm9yZ0lkYCwgdmFsaWRhdGVkIGJ5IHJlcXVpcmVPcmdJZCkg4oCUIG5ldmVyIGFcbiAqIHJvdXRlIHBhcmFtLCB3aGljaCBuYW1lcyB0aGUgUVVFUklFRCBzY29wZSwgdGhlIHdyb25nIHRlbmFudCBmb3IgUkxTLiBTZXJ2aWNlcyB3aXRoIGEgZGlmZmVyZW50IHJlcXVlc3QgYm91bmRhcnkgc3VwcGx5IHRoZWlyIG93biByZXNvbHZlciAoZS5nLiBwbGF0Zm9ybVxuICogc2V0cyB0aGUgc2NvcGUgcHJlLWF1dGggZnJvbSBhbiB1bnZlcmlmaWVkIEpXVCBwZWVrIHNvIHVuYXV0aGVudGljYXRlZCBlbmRwb2ludHMgc3RpbGxcbiAqIGdldCBhIHNhbmUgZGVmYXVsdCkuXG4gKi9cbmV4cG9ydCB0eXBlIFRlbmFudFNjb3BlUmVzb2x2ZXIgPSAocmVxOiBSZXF1ZXN0KSA9PiBUZW5hbnRDb250ZXh0O1xuXG4vKiogRGVmYXVsdCByZXNvbHZlcjogdGhlIGF1dGhlbnRpY2F0ZWQgaWRlbnRpdHkncyBvcmcgKyBzdXBlci1hZG1pbiBmbGFnLCBwbHVzXG4gKiAgdGhlIGFjdGl2ZS1vcmcgcGFyZW50IChvcmcg4oaSIHRlYW0gaGllcmFyY2h5KSBzbyBkb3duc3RyZWFtIHNpZGUtZWZmZWN0cyBjYW5cbiAqICByZWFjaCBpdCB3aXRob3V0IGEgcmVxdWVzdCwgYW5kIHRoZSBjYWxsZXIncyB1c2VyIGlkIGZvciB0aGUgYXBwLWxheWVyXG4gKiAgcHJlZGljYXRlcyB0aGF0IGNhcnJ5IGEgcGVyLXVzZXIgcnVuZy4gKi9cbmNvbnN0IGlkZW50aXR5U2NvcGU6IFRlbmFudFNjb3BlUmVzb2x2ZXIgPSAocmVxKSA9PiAoe1xuICAvLyBgaWRlbnRpdHkub3JnSWRgIGlzIGFscmVhZHkgbm9ybWFsaXplZCAodHJpbW1lZCArIGxvd2VyY2FzZWQpIG9uY2UgYXRcbiAgLy8gcmVzb2x1dGlvbiBpbiBhcGktY29yZSdzIGBnZXRJZGVudGl0eWAsIHNvIHRoZSBHVUMgc2V0IGhlcmUgbWF0Y2hlcyB0aGVcbiAgLy8gYXBwLWxheWVyIFdIRVJFIGNsYXVzZXMgZXhhY3RseSDigJQgbm8gYWQtaG9jIHJlLW5vcm1hbGl6YXRpb24gbmVlZGVkLlxuICBvcmdJZDogZ2V0Q29udGV4dChyZXEpLmlkZW50aXR5Lm9yZ0lkLFxuICB1c2VySWQ6IGdldENvbnRleHQocmVxKS5pZGVudGl0eS51c2VySWQgfHwgdW5kZWZpbmVkLFxuICBpc1N1cGVyQWRtaW46IGlzU3lzdGVtQWRtaW4ocmVxKSxcbiAgcGFyZW50T3JnSWQ6IHJlcS51c2VyPy5wYXJlbnRPcmdhbml6YXRpb25JZCxcbn0pO1xuXG4vKipcbiAqIEVzdGFibGlzaCB0aGUgcmVxdWVzdCdzIHJvdy1sZXZlbC1zZWN1cml0eSB0ZW5hbnQgc2NvcGUuXG4gKlxuICogUnVucyB0aGUgcmVzdCBvZiB0aGUgcmVxdWVzdCBpbnNpZGUgYHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbiB9KWAgKGFuXG4gKiBBc3luY0xvY2FsU3RvcmFnZSBzY29wZSkgc28gZXZlcnkgYHdpdGhUZW5hbnRUeGAgcXVlcnkgZG93bnN0cmVhbSBjYW4gYFNFVCBMT0NBTGAgdGhlXG4gKiBQb3N0Z3JlcyBHVUNzIHRoYXQgUkxTIHBvbGljaWVzIHJlYWQuIFdpdGhvdXQgdGhpcywgcmVhZHMgYWdhaW5zdCBGT1JDRS1STFMgdGFibGVzIChlLmcuXG4gKiBgcGx1Z2luc2AsIGBwaXBlbGluZXNgKSBydW4gd2l0aCBlbXB0eSBHVUNzIGFuZCBzaWxlbnRseSByZXR1cm4gbm8gcm93cyDigJQgdGhlIFwic2V0IG9uY2VcbiAqIGF0IHRoZSByZXF1ZXN0IGJvdW5kYXJ5XCIgYm9va2VuZCB0aGUgUkxTIGVuZm9yY2VtZW50IHBsYW4gY2FsbHMgZm9yLlxuICpcbiAqIERlZmF1bHQgcGxhY2VtZW50IGlzIEFGVEVSIGByZXF1aXJlQXV0aGAgKyBgcmVxdWlyZU9yZ0lkYCAodGhlIHJvdXRlIGZhY3RvcmllcyBkbyB0aGlzKTtcbiAqIHBhc3MgYSBjdXN0b20gYHJlc29sdmVgIGZvciBhIGRpZmZlcmVudCBib3VuZGFyeS4gQSB0aHJvd24gcmVzb2x2ZXIgbWVhbnMgdGVuYW50IGlkZW50aXR5XG4gKiBjb3VsZCBOT1QgYmUgZXN0YWJsaXNoZWQgKGEgd2lyaW5nIGJ1ZyDigJQgdGhpcyBydW5zIGFmdGVyIGF1dGgpIOKAlCB3ZSBoYXJkLUZBSUwgdGhlIHJlcXVlc3RcbiAqICg1MDAgdmlhIG5leHQoZXJyKSkgcmF0aGVyIHRoYW4gcHJvY2VlZC4gUHJvY2VlZGluZyB3b3VsZCBydW4gcXVlcmllcyB3aXRoIGVtcHR5IFJMUyBHVUNzLFxuICogd2hpY2ggdW5kZXIgRk9SQ0UgUkxTIGhpZGUgZXZlcnkgcm93IGFuZCByZWZ1c2Ugd3JpdGVzIOKAlCBhIHdpcmluZyBidWcgc3VyZmFjaW5nIGFzIGFcbiAqIHNpbGVudGx5IGVtcHR5IHJlc3VsdCBpbnN0ZWFkIG9mIGFuIGVycm9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aFRlbmFudENvbnRleHQocmVzb2x2ZTogVGVuYW50U2NvcGVSZXNvbHZlciA9IGlkZW50aXR5U2NvcGUpIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIF9yZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBsZXQgc2NvcGU6IFRlbmFudENvbnRleHQ7XG4gICAgdHJ5IHtcbiAgICAgIHNjb3BlID0gcmVzb2x2ZShyZXEpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbmV4dChlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBydW5XaXRoVGVuYW50Q29udGV4dChzY29wZSwgKCkgPT4gbmV4dCgpKTtcbiAgfTtcbn1cbiJdfQ==
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3RlbmFudC1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQXNCLE1BQU0saUNBQWlDLENBQUM7QUFFN0csT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEY7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gscUJBQXFCLENBQUMsR0FBRyxFQUFFO0lBQ3pCLE1BQU0sR0FBRyxHQUFHLGdCQUFnQixFQUFFLENBQUM7SUFDL0IsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUMzQiw2RUFBNkU7SUFDN0UseUVBQXlFO0lBQ3pFLG9DQUFvQztJQUNwQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLElBQUksU0FBUyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDL0QsQ0FBQyxDQUFDLENBQUM7QUFFSDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUk5Qzs7OzZDQUc2QztBQUM3QyxNQUFNLGFBQWEsR0FBd0IsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkQsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSx1RUFBdUU7SUFDdkUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztJQUNyQyxNQUFNLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksU0FBUztJQUNwRCxZQUFZLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQztJQUNoQyxXQUFXLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxvQkFBb0I7Q0FDNUMsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLE9BQU8sR0FBd0IsYUFBYTtJQUM1RSxPQUFPLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDL0QsSUFBSSxLQUFvQixDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUNELG9CQUFvQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7WUFDL0IseURBQXlEO1lBQ3pELEVBQUU7WUFDRix1RUFBdUU7WUFDdkUsc0VBQXNFO1lBQ3RFLHlFQUF5RTtZQUN6RSwwRUFBMEU7WUFDMUUseUVBQXlFO1lBQ3pFLGdCQUFnQjtZQUNoQixJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSxFQUFFLENBQUM7Z0JBQ1AsT0FBTztZQUNULENBQUM7WUFFRCx3RUFBd0U7WUFDeEUsK0RBQStEO1lBQy9ELHFFQUFxRTtZQUNyRSx1RUFBdUU7WUFDdkUsa0JBQWtCO1lBQ2xCLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFakQsK0RBQStEO1lBQy9ELHlEQUF5RDtZQUN6RCxFQUFFO1lBQ0YsMEVBQTBFO1lBQzFFLGtFQUFrRTtZQUNsRSxzRUFBc0U7WUFDdEUsaURBQWlEO1lBQ2pELEtBQUssYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FDNUIsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQ1osQ0FBQyxHQUFZLEVBQUUsRUFBRTtnQkFDZixxREFBcUQ7Z0JBQ3JELEtBQUssQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLGlGQUFpRixFQUFFO29CQUM3RixLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztpQkFDeEQsQ0FBQyxDQUFDO2dCQUNILElBQUksRUFBRSxDQUFDO1lBQ1QsQ0FBQyxDQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBpc1N5c3RlbUFkbWluLCBzZXRMb2dDb250ZXh0UHJvdmlkZXIgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBnZXRUZW5hbnRDb250ZXh0LCBydW5XaXRoVGVuYW50Q29udGV4dCwgdHlwZSBUZW5hbnRDb250ZXh0IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtZGF0YSc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tICcuL2dldC1jb250ZXh0LmpzJztcbmltcG9ydCB7IGFwcGx5V3JpdGVQaW4sIHJlY29yZFdyaXRlRm9yUGluLCB3cml0ZVBpbkFjdGl2ZSB9IGZyb20gJy4vd3JpdGUtcGluLmpzJztcblxuLyoqXG4gKiBUZWFjaCB0aGUgbG9nZ2VyIHdoZXJlIHRoZSBhbWJpZW50IG9yZy91c2VyIGlkZW50aXR5IGxpdmVzIOKAlCB0aGUgU0lOR0xFIHdpcmVcbiAqIHBvaW50IGZvciBsb2cgdGVuYW5jeSBhY3Jvc3MgZXZlcnkgc2VydmljZS5cbiAqXG4gKiBgYXBpLWNvcmVgICh3aGljaCBvd25zIHRoZSBsb2dnZXIpIGhhcyBubyBpbnRlcm5hbCBkZXBlbmRlbmNpZXMsIGFuZCB0aGVcbiAqIHJlcXVlc3Qgc2NvcGUgbGl2ZXMgaW4gYHBpcGVsaW5lLWRhdGFgLCB3aGljaCBkZXBlbmRzIG9uIGl0IOKAlCBzbyB0aGUgbG9nZ2VyXG4gKiB0YWtlcyBhIHByb3ZpZGVyIHJhdGhlciB0aGFuIGltcG9ydGluZyB0aGUgQXN5bmNMb2NhbFN0b3JhZ2UgZGlyZWN0bHkuIFRoaXNcbiAqIG1vZHVsZSBpcyB0aGUgbmF0dXJhbCBwbGFjZSB0byByZWdpc3RlcjogaXQgYWxyZWFkeSBicmlkZ2VzIGJvdGggcGFja2FnZXMsXG4gKiBhbmQgZXZlcnkgc2VydmljZSB0aGF0IG9wZW5zIGEgdGVuYW50IHNjb3BlIGRvZXMgc28gdGhyb3VnaCB0aGVcbiAqIGB3aXRoVGVuYW50Q29udGV4dGAgZXhwb3J0ZWQgYmVsb3cgKHBsYXRmb3JtIGluY2x1ZGVkLCB2aWEgaXRzIG93biBwcmUtYXV0aFxuICogcmVzb2x2ZXIpLiBSZWdpc3RlcmluZyBoZXJlIHJhdGhlciB0aGFuIGluIGVhY2ggc2VydmljZSdzIGJvb3RzdHJhcCBtZWFucyBhXG4gKiBuZXcgc2VydmljZSBjYW5ub3QgZm9yZ2V0IHRvIGRvIGl0LlxuICpcbiAqIE1vZHVsZS1zY29wZSBvbiBwdXJwb3NlOiBpZGVtcG90ZW50LCBhbmQgaXQgbXVzdCBiZSBpbiBwbGFjZSBiZWZvcmUgdGhlIGZpcnN0XG4gKiByZXF1ZXN0IGlzIGxvZ2dlZC5cbiAqL1xuc2V0TG9nQ29udGV4dFByb3ZpZGVyKCgpID0+IHtcbiAgY29uc3QgY3R4ID0gZ2V0VGVuYW50Q29udGV4dCgpO1xuICBpZiAoIWN0eCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgLy8gRW1wdHktc3RyaW5nIG9yZ0lkICh0aGUgcHJlLWF1dGggZGVmYXVsdCBmb3IgdW5hdXRoZW50aWNhdGVkIGVuZHBvaW50cykgaXNcbiAgLy8gTk9UIGFuIG9yZyDigJQgbGVhdmUgdGhlIGZpZWxkIG9mZiBzbyB0aGUgbGluZSBpcyByb3V0ZWQgYXMgdW5hdHRyaWJ1dGVkXG4gIC8vIHJhdGhlciB0aGFuIHRvIGEgdGVuYW50IG5hbWVkIFwiXCIuXG4gIHJldHVybiB7IG9yZ0lkOiBjdHgub3JnSWQgfHwgdW5kZWZpbmVkLCB1c2VySWQ6IGN0eC51c2VySWQgfTtcbn0pO1xuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBSTFMgdGVuYW50IHNjb3BlIGZvciBhIHJlcXVlc3QuIFRoZSBkZWZhdWx0IHJlYWRzIHRoZSBDQUxMRVInc1xuICogYXV0aGVudGljYXRlZCBpZGVudGl0eSBvcmcgKGBjdHguaWRlbnRpdHkub3JnSWRgLCB2YWxpZGF0ZWQgYnkgcmVxdWlyZU9yZ0lkKSDigJQgbmV2ZXIgYVxuICogcm91dGUgcGFyYW0sIHdoaWNoIG5hbWVzIHRoZSBRVUVSSUVEIHNjb3BlLCB0aGUgd3JvbmcgdGVuYW50IGZvciBSTFMuIFNlcnZpY2VzIHdpdGggYSBkaWZmZXJlbnQgcmVxdWVzdCBib3VuZGFyeSBzdXBwbHkgdGhlaXIgb3duIHJlc29sdmVyIChlLmcuIHBsYXRmb3JtXG4gKiBzZXRzIHRoZSBzY29wZSBwcmUtYXV0aCBmcm9tIGFuIHVudmVyaWZpZWQgSldUIHBlZWsgc28gdW5hdXRoZW50aWNhdGVkIGVuZHBvaW50cyBzdGlsbFxuICogZ2V0IGEgc2FuZSBkZWZhdWx0KS5cbiAqL1xuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0ZW5hbnQtY29udGV4dCcpO1xuXG5leHBvcnQgdHlwZSBUZW5hbnRTY29wZVJlc29sdmVyID0gKHJlcTogUmVxdWVzdCkgPT4gVGVuYW50Q29udGV4dDtcblxuLyoqIERlZmF1bHQgcmVzb2x2ZXI6IHRoZSBhdXRoZW50aWNhdGVkIGlkZW50aXR5J3Mgb3JnICsgc3VwZXItYWRtaW4gZmxhZywgcGx1c1xuICogIHRoZSBhY3RpdmUtb3JnIHBhcmVudCAob3JnIOKGkiB0ZWFtIGhpZXJhcmNoeSkgc28gZG93bnN0cmVhbSBzaWRlLWVmZmVjdHMgY2FuXG4gKiAgcmVhY2ggaXQgd2l0aG91dCBhIHJlcXVlc3QsIGFuZCB0aGUgY2FsbGVyJ3MgdXNlciBpZCBmb3IgdGhlIGFwcC1sYXllclxuICogIHByZWRpY2F0ZXMgdGhhdCBjYXJyeSBhIHBlci11c2VyIHJ1bmcuICovXG5jb25zdCBpZGVudGl0eVNjb3BlOiBUZW5hbnRTY29wZVJlc29sdmVyID0gKHJlcSkgPT4gKHtcbiAgLy8gYGlkZW50aXR5Lm9yZ0lkYCBpcyBhbHJlYWR5IG5vcm1hbGl6ZWQgKHRyaW1tZWQgKyBsb3dlcmNhc2VkKSBvbmNlIGF0XG4gIC8vIHJlc29sdXRpb24gaW4gYXBpLWNvcmUncyBgZ2V0SWRlbnRpdHlgLCBzbyB0aGUgR1VDIHNldCBoZXJlIG1hdGNoZXMgdGhlXG4gIC8vIGFwcC1sYXllciBXSEVSRSBjbGF1c2VzIGV4YWN0bHkg4oCUIG5vIGFkLWhvYyByZS1ub3JtYWxpemF0aW9uIG5lZWRlZC5cbiAgb3JnSWQ6IGdldENvbnRleHQocmVxKS5pZGVudGl0eS5vcmdJZCxcbiAgdXNlcklkOiBnZXRDb250ZXh0KHJlcSkuaWRlbnRpdHkudXNlcklkIHx8IHVuZGVmaW5lZCxcbiAgaXNTdXBlckFkbWluOiBpc1N5c3RlbUFkbWluKHJlcSksXG4gIHBhcmVudE9yZ0lkOiByZXEudXNlcj8ucGFyZW50T3JnYW5pemF0aW9uSWQsXG59KTtcblxuLyoqXG4gKiBFc3RhYmxpc2ggdGhlIHJlcXVlc3QncyByb3ctbGV2ZWwtc2VjdXJpdHkgdGVuYW50IHNjb3BlLlxuICpcbiAqIFJ1bnMgdGhlIHJlc3Qgb2YgdGhlIHJlcXVlc3QgaW5zaWRlIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW4gfSlgIChhblxuICogQXN5bmNMb2NhbFN0b3JhZ2Ugc2NvcGUpIHNvIGV2ZXJ5IGB3aXRoVGVuYW50VHhgIHF1ZXJ5IGRvd25zdHJlYW0gY2FuIGBTRVQgTE9DQUxgIHRoZVxuICogUG9zdGdyZXMgR1VDcyB0aGF0IFJMUyBwb2xpY2llcyByZWFkLiBXaXRob3V0IHRoaXMsIHJlYWRzIGFnYWluc3QgRk9SQ0UtUkxTIHRhYmxlcyAoZS5nLlxuICogYHBsdWdpbnNgLCBgcGlwZWxpbmVzYCkgcnVuIHdpdGggZW1wdHkgR1VDcyBhbmQgc2lsZW50bHkgcmV0dXJuIG5vIHJvd3Mg4oCUIHRoZSBcInNldCBvbmNlXG4gKiBhdCB0aGUgcmVxdWVzdCBib3VuZGFyeVwiIGJvb2tlbmQgdGhlIFJMUyBlbmZvcmNlbWVudCBwbGFuIGNhbGxzIGZvci5cbiAqXG4gKiBEZWZhdWx0IHBsYWNlbWVudCBpcyBBRlRFUiBgcmVxdWlyZUF1dGhgICsgYHJlcXVpcmVPcmdJZGAgKHRoZSByb3V0ZSBmYWN0b3JpZXMgZG8gdGhpcyk7XG4gKiBwYXNzIGEgY3VzdG9tIGByZXNvbHZlYCBmb3IgYSBkaWZmZXJlbnQgYm91bmRhcnkuIEEgdGhyb3duIHJlc29sdmVyIG1lYW5zIHRlbmFudCBpZGVudGl0eVxuICogY291bGQgTk9UIGJlIGVzdGFibGlzaGVkIChhIHdpcmluZyBidWcg4oCUIHRoaXMgcnVucyBhZnRlciBhdXRoKSDigJQgd2UgaGFyZC1GQUlMIHRoZSByZXF1ZXN0XG4gKiAoNTAwIHZpYSBuZXh0KGVycikpIHJhdGhlciB0aGFuIHByb2NlZWQuIFByb2NlZWRpbmcgd291bGQgcnVuIHF1ZXJpZXMgd2l0aCBlbXB0eSBSTFMgR1VDcyxcbiAqIHdoaWNoIHVuZGVyIEZPUkNFIFJMUyBoaWRlIGV2ZXJ5IHJvdyBhbmQgcmVmdXNlIHdyaXRlcyDigJQgYSB3aXJpbmcgYnVnIHN1cmZhY2luZyBhcyBhXG4gKiBzaWxlbnRseSBlbXB0eSByZXN1bHQgaW5zdGVhZCBvZiBhbiBlcnJvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhUZW5hbnRDb250ZXh0KHJlc29sdmU6IFRlbmFudFNjb3BlUmVzb2x2ZXIgPSBpZGVudGl0eVNjb3BlKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBsZXQgc2NvcGU6IFRlbmFudENvbnRleHQ7XG4gICAgdHJ5IHtcbiAgICAgIHNjb3BlID0gcmVzb2x2ZShyZXEpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbmV4dChlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBydW5XaXRoVGVuYW50Q29udGV4dChzY29wZSwgKCkgPT4ge1xuICAgICAgLy8gUmVhZC1hZnRlci13cml0ZSBBQ1JPU1MgcmVxdWVzdHMgKHNlZSAuL3dyaXRlLXBpbi50cykuXG4gICAgICAvL1xuICAgICAgLy8gR0FURUQgU1lOQ0hST05PVVNMWSBBTkQgRklSU1QuIFdpdGggbm8gcmVhZCByZXBsaWNhIGNvbmZpZ3VyZWQg4oCUIGhvd1xuICAgICAgLy8gYWxsIGZvdXIgdGFyZ2V0cyBzaGlwIOKAlCB0aGlzIHJldHVybnMgaGVyZTogbm8gcmVzcG9uc2UgbGlzdGVuZXIsIG5vXG4gICAgICAvLyBSZWRpcywgYW5kIGBuZXh0KClgIGNhbGxlZCBzeW5jaHJvbm91c2x5IGV4YWN0bHkgYXMgYmVmb3JlIGFueSBvZiB0aGlzXG4gICAgICAvLyBleGlzdGVkLiBFdmVyeXRoaW5nIGJlbG93IGlzIG9wdC1pbiBtYWNoaW5lcnksIGFuZCBhIGZlYXR1cmUgbm9ib2R5IGhhc1xuICAgICAgLy8gZW5hYmxlZCBtdXN0IG5vdCBtYWtlIHRoZSByZXF1ZXN0IHBhdGggYXN5bmNocm9ub3VzIGZvciBldmVyeSByb3V0ZSBvblxuICAgICAgLy8gZXZlcnkgdGFyZ2V0LlxuICAgICAgaWYgKCF3cml0ZVBpbkFjdGl2ZSgpKSB7XG4gICAgICAgIG5leHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgcGluIGlzIHJlY29yZGVkIG9uIGBmaW5pc2hgLCBhZnRlciB0aGUgcmVzcG9uc2UsIHNvIGEgd3JpdGUgbmV2ZXJcbiAgICAgIC8vIHdhaXRzIG9uIFJlZGlzLiBJdCByZWFkcyB0aGUgU0FNRSBgbWF5SGF2ZVdyaXR0ZW5gIGZsYWcgdGhhdFxuICAgICAgLy8gYHdpdGhUZW5hbnRUeGAgc2V0cywgd2hpY2ggaXMgd2h5IGl0IGNhdGNoZXMgYSBHRVQgdGhhdCB3cml0ZXMgYW5kXG4gICAgICAvLyBpZ25vcmVzIGEgUE9TVCB0aGF0IG9ubHkgdmFsaWRhdGVzIOKAlCB0aGUgSFRUUCBtZXRob2QgY2Fubm90IHRlbGwgeW91XG4gICAgICAvLyB3aGljaCBoYXBwZW5lZC5cbiAgICAgIHJlcy5vbignZmluaXNoJywgKCkgPT4gcmVjb3JkV3JpdGVGb3JQaW4oc2NvcGUpKTtcblxuICAgICAgLy8gYG5leHQoKWAgcnVucyBpbnNpZGUgdGhlIEFzeW5jTG9jYWxTdG9yYWdlIHNjb3BlIGVpdGhlciB3YXk6XG4gICAgICAvLyB0aGUgc3RvcmUgcHJvcGFnYXRlcyB0aHJvdWdoIHRoZSBwcm9taXNlIGNvbnRpbnVhdGlvbi5cbiAgICAgIC8vXG4gICAgICAvLyBBIGZhaWxlZCBsb29rdXAgbXVzdCBub3QgZmFpbCB0aGUgcmVxdWVzdCDigJQgYXBwbHlXcml0ZVBpbiBhbHJlYWR5IGZhaWxzXG4gICAgICAvLyBDTE9TRUQgaW50ZXJuYWxseSAodW5rbm93biBtZWFucyBcImFzc3VtZSB3cml0dGVuXCIsIGkuZS4gdXNlIHRoZVxuICAgICAgLy8gcHJpbWFyeSksIHNvIHRoZSBjYXRjaCBoZXJlIGlzIGZvciBhIGdlbnVpbmVseSB1bmV4cGVjdGVkIHRocm93IGFuZFxuICAgICAgLy8gY29udGludWVzIHdpdGggd2hhdGV2ZXIgdGhlIHJlc29sdmVyIHByb2R1Y2VkLlxuICAgICAgdm9pZCBhcHBseVdyaXRlUGluKHNjb3BlKS50aGVuKFxuICAgICAgICAoKSA9PiBuZXh0KCksXG4gICAgICAgIChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgICAvLyBEZWZlbnNpdmU6IGFwcGx5V3JpdGVQaW4gaXMgd3JpdHRlbiBub3QgdG8gcmVqZWN0LlxuICAgICAgICAgIHNjb3BlLm1heUhhdmVXcml0dGVuID0gdHJ1ZTtcbiAgICAgICAgICBsb2dnZXIud2FybignV3JpdGUtcGluIHByZS1jaGVjayB0aHJldzsgYXNzdW1pbmcgYSByZWNlbnQgd3JpdGUgYW5kIHJlYWRpbmcgZnJvbSB0aGUgcHJpbWFyeScsIHtcbiAgICAgICAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbmV4dCgpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9KTtcbiAgfTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { TenantContext } from '@pipeline-builder/pipeline-data';
|
|
2
|
+
export interface WritePinStore {
|
|
3
|
+
/**
|
|
4
|
+
* Has this org written recently? Returns TRUE when the answer is unknown
|
|
5
|
+
* (no Redis, unreachable, read failed) — see FAIL CLOSED above.
|
|
6
|
+
*/
|
|
7
|
+
isPinned(orgId: string | undefined): Promise<boolean>;
|
|
8
|
+
/** Record that this org just wrote. Never throws. */
|
|
9
|
+
pin(orgId: string | undefined): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
/** A store that reports nothing pinned — for tests and for single-process use. */
|
|
12
|
+
export declare const NO_WRITE_PIN: WritePinStore;
|
|
13
|
+
/** Replace the store. For tests, and for a service that owns its own client. */
|
|
14
|
+
export declare function setWritePinStore(next: WritePinStore | undefined): void;
|
|
15
|
+
/**
|
|
16
|
+
* The process-wide store, built on first use from `REDIS_URL` /
|
|
17
|
+
* `REDIS_SENTINELS` exactly like the other env-Redis consumers here.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getWritePinStore(): WritePinStore;
|
|
20
|
+
export declare function createEnvRedisWritePinStore(): WritePinStore;
|
|
21
|
+
/**
|
|
22
|
+
* Is the pin in play at all?
|
|
23
|
+
*
|
|
24
|
+
* False whenever no read replica is configured — which is how all four targets
|
|
25
|
+
* ship. The middleware uses this as a hard gate so that with no replica it does
|
|
26
|
+
* not register a response listener, does not touch Redis, and calls `next()`
|
|
27
|
+
* SYNCHRONOUSLY, exactly as it did before any of this existed. Making the
|
|
28
|
+
* request path asynchronous for a feature nobody has enabled would be a
|
|
29
|
+
* behaviour change paid by every route on every target.
|
|
30
|
+
*/
|
|
31
|
+
export declare function writePinActive(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Before the request runs: if this org wrote recently, pre-set the same
|
|
34
|
+
* `mayHaveWritten` flag `withTenantTx` would have set, so the read helper keeps
|
|
35
|
+
* the request on the primary.
|
|
36
|
+
*
|
|
37
|
+
* No-ops entirely when no replica is configured — which keeps Redis off the
|
|
38
|
+
* request path for every deploy that has not enabled read-splitting.
|
|
39
|
+
*/
|
|
40
|
+
export declare function applyWritePin(scope: TenantContext): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* After the response: if anything in this request opened a primary transaction,
|
|
43
|
+
* pin the org so its next request reads from the primary too.
|
|
44
|
+
*
|
|
45
|
+
* Reads `mayHaveWritten` rather than the HTTP method on purpose. A POST that
|
|
46
|
+
* only validates has nothing to pin for, and — more importantly — a GET that
|
|
47
|
+
* writes (a lazy backfill, a last-seen stamp) absolutely does. The flag follows
|
|
48
|
+
* what actually touched the primary, which the method cannot tell you.
|
|
49
|
+
*/
|
|
50
|
+
export declare function recordWriteForPin(scope: TenantContext): void;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* The cross-request write pin — read-after-write for a user's NEXT request.
|
|
5
|
+
*
|
|
6
|
+
* THE PROBLEM THIS SOLVES, which is the common case and not an edge case:
|
|
7
|
+
* `POST /pipelines` returns, the page reloads, `GET /pipelines` runs. That GET
|
|
8
|
+
* is a different request with no memory of the POST, so without something
|
|
9
|
+
* carried between them it routes to a replica that may not have replayed the
|
|
10
|
+
* commit, and the pipeline the user just created is simply missing. No error,
|
|
11
|
+
* no retry, and not reproducible on demand.
|
|
12
|
+
*
|
|
13
|
+
* `tenancy.ts` already solves the WITHIN-a-request half: `withTenantTx` sets
|
|
14
|
+
* `mayHaveWritten` on the request's tenant context, and the read helper keeps
|
|
15
|
+
* that request on the primary afterwards. This module extends the same flag
|
|
16
|
+
* ACROSS requests by remembering, in Redis, that an org wrote recently — and it
|
|
17
|
+
* sets the very same `mayHaveWritten` flag, so there is one mechanism and one
|
|
18
|
+
* code path, not two.
|
|
19
|
+
*
|
|
20
|
+
* WHY REDIS AND NOT AN LSN. The alternative is exact: capture
|
|
21
|
+
* `pg_current_wal_lsn()` at commit, carry it with the client, and have the read
|
|
22
|
+
* path wait for the standby to replay at least that far. It was rejected for
|
|
23
|
+
* reasons that are about this system rather than about elegance:
|
|
24
|
+
*
|
|
25
|
+
* 1. Shared state is mandatory anyway — the app tier is 2 replicas wide on
|
|
26
|
+
* eks, so an in-process map misses every request that lands on the other
|
|
27
|
+
* pod. LSN tracking avoids shared state only by carrying the value on the
|
|
28
|
+
* CLIENT, and this product's own pitch is five ways in (dashboard, CLI,
|
|
29
|
+
* REST, CDK, AI). A CLI or CDK caller will not echo an LSN back, so that
|
|
30
|
+
* approach degrades to "primary for every non-browser client" or needs
|
|
31
|
+
* server-side storage — which is this, with extra steps.
|
|
32
|
+
* 2. A client-supplied LSN is attacker-controlled input, and an unbounded
|
|
33
|
+
* wait on a replica that never catches up turns a bogus value into a hang.
|
|
34
|
+
* That is a denial of service wearing a correctness costume, and bounding
|
|
35
|
+
* it correctly is a second security surface to get right.
|
|
36
|
+
*
|
|
37
|
+
* The pin is COARSE and that is the accepted trade: it is keyed per ORG, not
|
|
38
|
+
* per user, because a user may read through a different session than the one
|
|
39
|
+
* that wrote. So one member's write briefly sends the whole org's reads to the
|
|
40
|
+
* primary. That can only remove a benefit, never introduce a regression —
|
|
41
|
+
* reading from the primary is exactly what happens today.
|
|
42
|
+
*
|
|
43
|
+
* FAIL CLOSED. No Redis configured, an unreachable Redis, or a failed read all
|
|
44
|
+
* resolve to "assume this org wrote", which routes reads to the primary. That
|
|
45
|
+
* is the same fail-closed-without-Redis posture the leader lock takes, and it
|
|
46
|
+
* is the only safe direction: guessing "no recent write" when the answer is
|
|
47
|
+
* unknown is how a user loses sight of their own data.
|
|
48
|
+
*
|
|
49
|
+
* COSTS NOTHING UNTIL READ-SPLITTING IS ON. Every entry point short-circuits
|
|
50
|
+
* when no read replica is configured, so a deploy with `DB_READ_HOST` unset —
|
|
51
|
+
* which is how all four targets ship — never touches Redis on the request path.
|
|
52
|
+
*/
|
|
53
|
+
import { createEnvRedisClient, createLogger, createRedisReadyGate, envInt, isReadReplicaConfigured } from '@pipeline-builder/api-core';
|
|
54
|
+
const logger = createLogger('write-pin');
|
|
55
|
+
/**
|
|
56
|
+
* How long a write keeps its org on the primary.
|
|
57
|
+
*
|
|
58
|
+
* Should sit comfortably above observed p99 replication lag. Ten seconds is
|
|
59
|
+
* deliberately generous for a default: too short silently reintroduces the
|
|
60
|
+
* missing-row bug, while too long only costs offload. The asymmetry says which
|
|
61
|
+
* way to err.
|
|
62
|
+
*/
|
|
63
|
+
const ttlSeconds = () => envInt('DB_READ_WRITE_PIN_TTL_SECONDS', 10);
|
|
64
|
+
const key = (orgId) => `rw-pin:${orgId}`;
|
|
65
|
+
/** A store that reports nothing pinned — for tests and for single-process use. */
|
|
66
|
+
export const NO_WRITE_PIN = {
|
|
67
|
+
isPinned: () => Promise.resolve(false),
|
|
68
|
+
pin: () => Promise.resolve(),
|
|
69
|
+
};
|
|
70
|
+
let store;
|
|
71
|
+
/** Replace the store. For tests, and for a service that owns its own client. */
|
|
72
|
+
export function setWritePinStore(next) {
|
|
73
|
+
store = next;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The process-wide store, built on first use from `REDIS_URL` /
|
|
77
|
+
* `REDIS_SENTINELS` exactly like the other env-Redis consumers here.
|
|
78
|
+
*/
|
|
79
|
+
export function getWritePinStore() {
|
|
80
|
+
if (!store)
|
|
81
|
+
store = createEnvRedisWritePinStore();
|
|
82
|
+
return store;
|
|
83
|
+
}
|
|
84
|
+
export function createEnvRedisWritePinStore() {
|
|
85
|
+
// undefined = not yet attempted; null = attempted and unavailable.
|
|
86
|
+
let cached;
|
|
87
|
+
let ready;
|
|
88
|
+
let warned = false;
|
|
89
|
+
async function client() {
|
|
90
|
+
if (cached === undefined) {
|
|
91
|
+
cached = createEnvRedisClient('write-pin');
|
|
92
|
+
if (cached) {
|
|
93
|
+
logger.info('Redis write-pin store initialized', { ttlSeconds: ttlSeconds() });
|
|
94
|
+
ready = createRedisReadyGate(cached);
|
|
95
|
+
}
|
|
96
|
+
else if (!warned) {
|
|
97
|
+
warned = true;
|
|
98
|
+
// Only worth saying when a replica actually exists: without one every
|
|
99
|
+
// read goes to the primary regardless and the pin is irrelevant.
|
|
100
|
+
logger.warn('No Redis configured for the read-after-write pin; every read will use the primary');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (ready)
|
|
104
|
+
await ready();
|
|
105
|
+
return cached;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
async isPinned(orgId) {
|
|
109
|
+
if (!orgId)
|
|
110
|
+
return true; // no org to key on -> assume written
|
|
111
|
+
try {
|
|
112
|
+
const redis = await client();
|
|
113
|
+
if (!redis)
|
|
114
|
+
return true; // fail closed
|
|
115
|
+
return (await redis.exists(key(orgId))) === 1;
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger.warn('Write-pin lookup failed; routing reads to the primary', {
|
|
119
|
+
error: err instanceof Error ? err.message : String(err),
|
|
120
|
+
});
|
|
121
|
+
return true; // fail closed
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
async pin(orgId) {
|
|
125
|
+
// Nothing to key on, so nothing to pin. The read side fails closed for
|
|
126
|
+
// the same scope anyway.
|
|
127
|
+
if (!orgId)
|
|
128
|
+
return;
|
|
129
|
+
try {
|
|
130
|
+
const redis = await client();
|
|
131
|
+
if (!redis)
|
|
132
|
+
return;
|
|
133
|
+
await redis.set(key(orgId), '1', 'EX', ttlSeconds());
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
// A failed pin is the dangerous direction — the NEXT request may read a
|
|
137
|
+
// stale replica — but there is nothing useful to do about it here, and
|
|
138
|
+
// throwing would fail a request whose write already committed. Log it
|
|
139
|
+
// loudly; `postgres_write_pin_errors_total` is the thing to alert on.
|
|
140
|
+
logger.warn('Failed to set the read-after-write pin; a subsequent read may hit a stale replica', {
|
|
141
|
+
orgId,
|
|
142
|
+
error: err instanceof Error ? err.message : String(err),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Is the pin in play at all?
|
|
150
|
+
*
|
|
151
|
+
* False whenever no read replica is configured — which is how all four targets
|
|
152
|
+
* ship. The middleware uses this as a hard gate so that with no replica it does
|
|
153
|
+
* not register a response listener, does not touch Redis, and calls `next()`
|
|
154
|
+
* SYNCHRONOUSLY, exactly as it did before any of this existed. Making the
|
|
155
|
+
* request path asynchronous for a feature nobody has enabled would be a
|
|
156
|
+
* behaviour change paid by every route on every target.
|
|
157
|
+
*/
|
|
158
|
+
export function writePinActive() {
|
|
159
|
+
return isReadReplicaConfigured();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Before the request runs: if this org wrote recently, pre-set the same
|
|
163
|
+
* `mayHaveWritten` flag `withTenantTx` would have set, so the read helper keeps
|
|
164
|
+
* the request on the primary.
|
|
165
|
+
*
|
|
166
|
+
* No-ops entirely when no replica is configured — which keeps Redis off the
|
|
167
|
+
* request path for every deploy that has not enabled read-splitting.
|
|
168
|
+
*/
|
|
169
|
+
export async function applyWritePin(scope) {
|
|
170
|
+
if (!isReadReplicaConfigured())
|
|
171
|
+
return;
|
|
172
|
+
if (scope.mayHaveWritten)
|
|
173
|
+
return; // already known to have written
|
|
174
|
+
if (await getWritePinStore().isPinned(scope.orgId))
|
|
175
|
+
scope.mayHaveWritten = true;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* After the response: if anything in this request opened a primary transaction,
|
|
179
|
+
* pin the org so its next request reads from the primary too.
|
|
180
|
+
*
|
|
181
|
+
* Reads `mayHaveWritten` rather than the HTTP method on purpose. A POST that
|
|
182
|
+
* only validates has nothing to pin for, and — more importantly — a GET that
|
|
183
|
+
* writes (a lazy backfill, a last-seen stamp) absolutely does. The flag follows
|
|
184
|
+
* what actually touched the primary, which the method cannot tell you.
|
|
185
|
+
*/
|
|
186
|
+
export function recordWriteForPin(scope) {
|
|
187
|
+
if (!isReadReplicaConfigured())
|
|
188
|
+
return;
|
|
189
|
+
if (!scope.mayHaveWritten)
|
|
190
|
+
return;
|
|
191
|
+
void getWritePinStore().pin(scope.orgId);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGUtcGluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS93cml0ZS1waW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlERztBQUVILE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFNdkksTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRXpDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsK0JBQStCLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFFckUsTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLFVBQVUsS0FBSyxFQUFFLENBQUM7QUE4QmpELGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSxZQUFZLEdBQWtCO0lBQ3pDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN0QyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRTtDQUM3QixDQUFDO0FBRUYsSUFBSSxLQUFnQyxDQUFDO0FBRXJDLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUsZ0JBQWdCLENBQUMsSUFBK0I7SUFDOUQsS0FBSyxHQUFHLElBQUksQ0FBQztBQUNmLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCO0lBQzlCLElBQUksQ0FBQyxLQUFLO1FBQUUsS0FBSyxHQUFHLDJCQUEyQixFQUFFLENBQUM7SUFDbEQsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsTUFBTSxVQUFVLDJCQUEy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LEtBQW9CO0lBQ3RELElBQUksQ0FBQyx1QkFBdUIsRUFBRTtRQUFFLE9BQU87SUFDdkMsSUFBSSxLQUFLLENBQUMsY0FBYztRQUFFLE9BQU8sQ0FBQyxnQ0FBZ0M7SUFDbEUsSUFBSSxNQUFNLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFBRSxLQUFLLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztBQUNsRixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBb0I7SUFDcEQsSUFBSSxDQUFDLHVCQUF1QixFQUFFO1FBQUUsT0FBTztJQUN2QyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWM7UUFBRSxPQUFPO0lBQ2xDLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgY3Jvc3MtcmVxdWVzdCB3cml0ZSBwaW4g4oCUIHJlYWQtYWZ0ZXItd3JpdGUgZm9yIGEgdXNlcidzIE5FWFQgcmVxdWVzdC5cbiAqXG4gKiBUSEUgUFJPQkxFTSBUSElTIFNPTFZFUywgd2hpY2ggaXMgdGhlIGNvbW1vbiBjYXNlIGFuZCBub3QgYW4gZWRnZSBjYXNlOlxuICogYFBPU1QgL3BpcGVsaW5lc2AgcmV0dXJucywgdGhlIHBhZ2UgcmVsb2FkcywgYEdFVCAvcGlwZWxpbmVzYCBydW5zLiBUaGF0IEdFVFxuICogaXMgYSBkaWZmZXJlbnQgcmVxdWVzdCB3aXRoIG5vIG1lbW9yeSBvZiB0aGUgUE9TVCwgc28gd2l0aG91dCBzb21ldGhpbmdcbiAqIGNhcnJpZWQgYmV0d2VlbiB0aGVtIGl0IHJvdXRlcyB0byBhIHJlcGxpY2EgdGhhdCBtYXkgbm90IGhhdmUgcmVwbGF5ZWQgdGhlXG4gKiBjb21taXQsIGFuZCB0aGUgcGlwZWxpbmUgdGhlIHVzZXIganVzdCBjcmVhdGVkIGlzIHNpbXBseSBtaXNzaW5nLiBObyBlcnJvcixcbiAqIG5vIHJldHJ5LCBhbmQgbm90IHJlcHJvZHVjaWJsZSBvbiBkZW1hbmQuXG4gKlxuICogYHRlbmFuY3kudHNgIGFscmVhZHkgc29sdmVzIHRoZSBXSVRISU4tYS1yZXF1ZXN0IGhhbGY6IGB3aXRoVGVuYW50VHhgIHNldHNcbiAqIGBtYXlIYXZlV3JpdHRlbmAgb24gdGhlIHJlcXVlc3QncyB0ZW5hbnQgY29udGV4dCwgYW5kIHRoZSByZWFkIGhlbHBlciBrZWVwc1xuICogdGhhdCByZXF1ZXN0IG9uIHRoZSBwcmltYXJ5IGFmdGVyd2FyZHMuIFRoaXMgbW9kdWxlIGV4dGVuZHMgdGhlIHNhbWUgZmxhZ1xuICogQUNST1NTIHJlcXVlc3RzIGJ5IHJlbWVtYmVyaW5nLCBpbiBSZWRpcywgdGhhdCBhbiBvcmcgd3JvdGUgcmVjZW50bHkg4oCUIGFuZCBpdFxuICogc2V0cyB0aGUgdmVyeSBzYW1lIGBtYXlIYXZlV3JpdHRlbmAgZmxhZywgc28gdGhlcmUgaXMgb25lIG1lY2hhbmlzbSBhbmQgb25lXG4gKiBjb2RlIHBhdGgsIG5vdCB0d28uXG4gKlxuICogV0hZIFJFRElTIEFORCBOT1QgQU4gTFNOLiBUaGUgYWx0ZXJuYXRpdmUgaXMgZXhhY3Q6IGNhcHR1cmVcbiAqIGBwZ19jdXJyZW50X3dhbF9sc24oKWAgYXQgY29tbWl0LCBjYXJyeSBpdCB3aXRoIHRoZSBjbGllbnQsIGFuZCBoYXZlIHRoZSByZWFkXG4gKiBwYXRoIHdhaXQgZm9yIHRoZSBzdGFuZGJ5IHRvIHJlcGxheSBhdCBsZWFzdCB0aGF0IGZhci4gSXQgd2FzIHJlamVjdGVkIGZvclxuICogcmVhc29ucyB0aGF0IGFyZSBhYm91dCB0aGlzIHN5c3RlbSByYXRoZXIgdGhhbiBhYm91dCBlbGVnYW5jZTpcbiAqXG4gKiAgIDEuIFNoYXJlZCBzdGF0ZSBpcyBtYW5kYXRvcnkgYW55d2F5IOKAlCB0aGUgYXBwIHRpZXIgaXMgMiByZXBsaWNhcyB3aWRlIG9uXG4gKiAgICAgIGVrcywgc28gYW4gaW4tcHJvY2VzcyBtYXAgbWlzc2VzIGV2ZXJ5IHJlcXVlc3QgdGhhdCBsYW5kcyBvbiB0aGUgb3RoZXJcbiAqICAgICAgcG9kLiBMU04gdHJhY2tpbmcgYXZvaWRzIHNoYXJlZCBzdGF0ZSBvbmx5IGJ5IGNhcnJ5aW5nIHRoZSB2YWx1ZSBvbiB0aGVcbiAqICAgICAgQ0xJRU5ULCBhbmQgdGhpcyBwcm9kdWN0J3Mgb3duIHBpdGNoIGlzIGZpdmUgd2F5cyBpbiAoZGFzaGJvYXJkLCBDTEksXG4gKiAgICAgIFJFU1QsIENESywgQUkpLiBBIENMSSBvciBDREsgY2FsbGVyIHdpbGwgbm90IGVjaG8gYW4gTFNOIGJhY2ssIHNvIHRoYXRcbiAqICAgICAgYXBwcm9hY2ggZGVncmFkZXMgdG8gXCJwcmltYXJ5IGZvciBldmVyeSBub24tYnJvd3NlciBjbGllbnRcIiBvciBuZWVkc1xuICogICAgICBzZXJ2ZXItc2lkZSBzdG9yYWdlIOKAlCB3aGljaCBpcyB0aGlzLCB3aXRoIGV4dHJhIHN0ZXBzLlxuICogICAyLiBBIGNsaWVudC1zdXBwbGllZCBMU04gaXMgYXR0YWNrZXItY29udHJvbGxlZCBpbnB1dCwgYW5kIGFuIHVuYm91bmRlZFxuICogICAgICB3YWl0IG9uIGEgcmVwbGljYSB0aGF0IG5ldmVyIGNhdGNoZXMgdXAgdHVybnMgYSBib2d1cyB2YWx1ZSBpbnRvIGEgaGFuZy5cbiAqICAgICAgVGhhdCBpcyBhIGRlbmlhbCBvZiBzZXJ2aWNlIHdlYXJpbmcgYSBjb3JyZWN0bmVzcyBjb3N0dW1lLCBhbmQgYm91bmRpbmdcbiAqICAgICAgaXQgY29ycmVjdGx5IGlzIGEgc2Vjb25kIHNlY3VyaXR5IHN1cmZhY2UgdG8gZ2V0IHJpZ2h0LlxuICpcbiAqIFRoZSBwaW4gaXMgQ09BUlNFIGFuZCB0aGF0IGlzIHRoZSBhY2NlcHRlZCB0cmFkZTogaXQgaXMga2V5ZWQgcGVyIE9SRywgbm90XG4gKiBwZXIgdXNlciwgYmVjYXVzZSBhIHVzZXIgbWF5IHJlYWQgdGhyb3VnaCBhIGRpZmZlcmVudCBzZXNzaW9uIHRoYW4gdGhlIG9uZVxuICogdGhhdCB3cm90ZS4gU28gb25lIG1lbWJlcidzIHdyaXRlIGJyaWVmbHkgc2VuZHMgdGhlIHdob2xlIG9yZydzIHJlYWRzIHRvIHRoZVxuICogcHJpbWFyeS4gVGhhdCBjYW4gb25seSByZW1vdmUgYSBiZW5lZml0LCBuZXZlciBpbnRyb2R1Y2UgYSByZWdyZXNzaW9uIOKAlFxuICogcmVhZGluZyBmcm9tIHRoZSBwcmltYXJ5IGlzIGV4YWN0bHkgd2hhdCBoYXBwZW5zIHRvZGF5LlxuICpcbiAqIEZBSUwgQ0xPU0VELiBObyBSZWRpcyBjb25maWd1cmVkLCBhbiB1bnJlYWNoYWJsZSBSZWRpcywgb3IgYSBmYWlsZWQgcmVhZCBhbGxcbiAqIHJlc29sdmUgdG8gXCJhc3N1bWUgdGhpcyBvcmcgd3JvdGVcIiwgd2hpY2ggcm91dGVzIHJlYWRzIHRvIHRoZSBwcmltYXJ5LiBUaGF0XG4gKiBpcyB0aGUgc2FtZSBmYWlsLWNsb3NlZC13aXRob3V0LVJlZGlzIHBvc3R1cmUgdGhlIGxlYWRlciBsb2NrIHRha2VzLCBhbmQgaXRcbiAqIGlzIHRoZSBvbmx5IHNhZmUgZGlyZWN0aW9uOiBndWVzc2luZyBcIm5vIHJlY2VudCB3cml0ZVwiIHdoZW4gdGhlIGFuc3dlciBpc1xuICogdW5rbm93biBpcyBob3cgYSB1c2VyIGxvc2VzIHNpZ2h0IG9mIHRoZWlyIG93biBkYXRhLlxuICpcbiAqIENPU1RTIE5PVEhJTkcgVU5USUwgUkVBRC1TUExJVFRJTkcgSVMgT04uIEV2ZXJ5IGVudHJ5IHBvaW50IHNob3J0LWNpcmN1aXRzXG4gKiB3aGVuIG5vIHJlYWQgcmVwbGljYSBpcyBjb25maWd1cmVkLCBzbyBhIGRlcGxveSB3aXRoIGBEQl9SRUFEX0hPU1RgIHVuc2V0IOKAlFxuICogd2hpY2ggaXMgaG93IGFsbCBmb3VyIHRhcmdldHMgc2hpcCDigJQgbmV2ZXIgdG91Y2hlcyBSZWRpcyBvbiB0aGUgcmVxdWVzdCBwYXRoLlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUVudlJlZGlzQ2xpZW50LCBjcmVhdGVMb2dnZXIsIGNyZWF0ZVJlZGlzUmVhZHlHYXRlLCBlbnZJbnQsIGlzUmVhZFJlcGxpY2FDb25maWd1cmVkIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuLy8gVFlQRS1PTkxZLCBhbmQgdGhhdCBpcyBkZWxpYmVyYXRlOiBhIHR5cGUgaW1wb3J0IGlzIGVyYXNlZCBhdCBjb21waWxlIHRpbWUsIHNvXG4vLyBpdCBuZXZlciB0b3VjaGVzIHBpcGVsaW5lLWRhdGEncyBgc3R1Yk1vZHVsZWAgYXQgcnVudGltZS4gQSBWQUxVRSBpbXBvcnQgaGVyZVxuLy8gdHVybmVkIGFsbCA5MSBzdWl0ZXMgdGhhdCBzdHViIHRoYXQgcGFja2FnZSBpbnRvIGEgNTAwLlxuaW1wb3J0IHR5cGUgeyBUZW5hbnRDb250ZXh0IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtZGF0YSc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignd3JpdGUtcGluJyk7XG5cbi8qKlxuICogSG93IGxvbmcgYSB3cml0ZSBrZWVwcyBpdHMgb3JnIG9uIHRoZSBwcmltYXJ5LlxuICpcbiAqIFNob3VsZCBzaXQgY29tZm9ydGFibHkgYWJvdmUgb2JzZXJ2ZWQgcDk5IHJlcGxpY2F0aW9uIGxhZy4gVGVuIHNlY29uZHMgaXNcbiAqIGRlbGliZXJhdGVseSBnZW5lcm91cyBmb3IgYSBkZWZhdWx0OiB0b28gc2hvcnQgc2lsZW50bHkgcmVpbnRyb2R1Y2VzIHRoZVxuICogbWlzc2luZy1yb3cgYnVnLCB3aGlsZSB0b28gbG9uZyBvbmx5IGNvc3RzIG9mZmxvYWQuIFRoZSBhc3ltbWV0cnkgc2F5cyB3aGljaFxuICogd2F5IHRvIGVyci5cbiAqL1xuY29uc3QgdHRsU2Vjb25kcyA9ICgpID0+IGVudkludCgnREJfUkVBRF9XUklURV9QSU5fVFRMX1NFQ09ORFMnLCAxMCk7XG5cbmNvbnN0IGtleSA9IChvcmdJZDogc3RyaW5nKSA9PiBgcnctcGluOiR7b3JnSWR9YDtcblxuLyoqXG4gKiBUaGUgdHdvIGlvcmVkaXMgY2FsbHMgdGhpcyBuZWVkcywgcGx1cyB0aGUgdGhyZWUgbWVtYmVyc1xuICogYGNyZWF0ZVJlZGlzUmVhZHlHYXRlYCByZWFkcy5cbiAqXG4gKiBEZWNsYXJlZCBzdHJ1Y3R1cmFsbHkgcmF0aGVyIHRoYW4gYnkgZXh0ZW5kaW5nIGFwaS1jb3JlJ3MgYFJlYWR5QXdhcmVSZWRpc2AsXG4gKiB3aGljaCBpcyBpbnRlcm5hbCB0byB0aGF0IHBhY2thZ2UgYW5kIG5vdCBwYXJ0IG9mIGl0cyBwdWJsaWMgc3VyZmFjZS4gVGhlXG4gKiByZWFkaW5lc3MgZ2F0ZSBpcyBub3Qgb3B0aW9uYWw6IHRoZSBlbnYgY2xpZW50IGhhcyBubyBvZmZsaW5lIHF1ZXVlLCBzbyBhXG4gKiBjb21tYW5kIGlzc3VlZCBiZWZvcmUgdGhlIGZpcnN0IGNvbm5lY3Rpb24gY29tcGxldGVzIGlzIHJlamVjdGVkIG91dHJpZ2h0IOKAlFxuICogd2hpY2ggd291bGQgbWFrZSB0aGUgRklSU1QgcmVhZCBvZiBldmVyeSBwb2QgZmFpbCBjbG9zZWQgdG8gdGhlIHByaW1hcnkuXG4gKi9cbmludGVyZmFjZSBQaW5SZWRpcyB7XG4gIGV4aXN0cyhrZXk6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcbiAgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBtb2RlOiAnRVgnLCB0dGw6IG51bWJlcik6IFByb21pc2U8dW5rbm93bj47XG4gIHN0YXR1cz86IHN0cmluZztcbiAgb25jZT8oZXZlbnQ6IHN0cmluZywgY2I6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQpOiB1bmtub3duO1xuICBvZmY/KGV2ZW50OiBzdHJpbmcsIGNiOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkKTogdW5rbm93bjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZVBpblN0b3JlIHtcbiAgLyoqXG4gICAqIEhhcyB0aGlzIG9yZyB3cml0dGVuIHJlY2VudGx5PyBSZXR1cm5zIFRSVUUgd2hlbiB0aGUgYW5zd2VyIGlzIHVua25vd25cbiAgICogKG5vIFJlZGlzLCB1bnJlYWNoYWJsZSwgcmVhZCBmYWlsZWQpIOKAlCBzZWUgRkFJTCBDTE9TRUQgYWJvdmUuXG4gICAqL1xuICBpc1Bpbm5lZChvcmdJZDogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxib29sZWFuPjtcbiAgLyoqIFJlY29yZCB0aGF0IHRoaXMgb3JnIGp1c3Qgd3JvdGUuIE5ldmVyIHRocm93cy4gKi9cbiAgcGluKG9yZ0lkOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKiogQSBzdG9yZSB0aGF0IHJlcG9ydHMgbm90aGluZyBwaW5uZWQg4oCUIGZvciB0ZXN0cyBhbmQgZm9yIHNpbmdsZS1wcm9jZXNzIHVzZS4gKi9cbmV4cG9ydCBjb25zdCBOT19XUklURV9QSU46IFdyaXRlUGluU3RvcmUgPSB7XG4gIGlzUGlubmVkOiAoKSA9PiBQcm9taXNlLnJlc29sdmUoZmFsc2UpLFxuICBwaW46ICgpID0+IFByb21pc2UucmVzb2x2ZSgpLFxufTtcblxubGV0IHN0b3JlOiBXcml0ZVBpblN0b3JlIHwgdW5kZWZpbmVkO1xuXG4vKiogUmVwbGFjZSB0aGUgc3RvcmUuIEZvciB0ZXN0cywgYW5kIGZvciBhIHNlcnZpY2UgdGhhdCBvd25zIGl0cyBvd24gY2xpZW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFdyaXRlUGluU3RvcmUobmV4dDogV3JpdGVQaW5TdG9yZSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBzdG9yZSA9IG5leHQ7XG59XG5cbi8qKlxuICogVGhlIHByb2Nlc3Mtd2lkZSBzdG9yZSwgYnVpbHQgb24gZmlyc3QgdXNlIGZyb20gYFJFRElTX1VSTGAgL1xuICogYFJFRElTX1NFTlRJTkVMU2AgZXhhY3RseSBsaWtlIHRoZSBvdGhlciBlbnYtUmVkaXMgY29uc3VtZXJzIGhlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXcml0ZVBpblN0b3JlKCk6IFdyaXRlUGluU3RvcmUge1xuICBpZiAoIXN0b3JlKSBzdG9yZSA9IGNyZWF0ZUVudlJlZGlzV3JpdGVQaW5TdG9yZSgpO1xuICByZXR1cm4gc3RvcmU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbnZSZWRpc1dyaXRlUGluU3RvcmUoKTogV3JpdGVQaW5TdG9yZSB7XG4gIC8vIHVuZGVmaW5lZCA9IG5vdCB5ZXQgYXR0ZW1wdGVkOyBudWxsID0gYXR0ZW1wdGVkIGFuZCB1bmF2YWlsYWJsZS5cbiAgbGV0IGNhY2hlZDogUGluUmVkaXMgfCBudWxsIHwgdW5kZWZpbmVkO1xuICBsZXQgcmVhZHk6ICgoKSA9PiBQcm9taXNlPHZvaWQ+KSB8IHVuZGVmaW5lZDtcbiAgbGV0IHdhcm5lZCA9IGZhbHNlO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGNsaWVudCgpOiBQcm9taXNlPFBpblJlZGlzIHwgbnVsbD4ge1xuICAgIGlmIChjYWNoZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FjaGVkID0gY3JlYXRlRW52UmVkaXNDbGllbnQ8UGluUmVkaXM+KCd3cml0ZS1waW4nKTtcbiAgICAgIGlmIChjYWNoZWQpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlZGlzIHdyaXRlLXBpbiBzdG9yZSBpbml0aWFsaXplZCcsIHsgdHRsU2Vjb25kczogdHRsU2Vjb25kcygpIH0pO1xuICAgICAgICByZWFkeSA9IGNyZWF0ZVJlZGlzUmVhZHlHYXRlKGNhY2hlZCk7XG4gICAgICB9IGVsc2UgaWYgKCF3YXJuZWQpIHtcbiAgICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICAgICAgLy8gT25seSB3b3J0aCBzYXlpbmcgd2hlbiBhIHJlcGxpY2EgYWN0dWFsbHkgZXhpc3RzOiB3aXRob3V0IG9uZSBldmVyeVxuICAgICAgICAvLyByZWFkIGdvZXMgdG8gdGhlIHByaW1hcnkgcmVnYXJkbGVzcyBhbmQgdGhlIHBpbiBpcyBpcnJlbGV2YW50LlxuICAgICAgICBsb2dnZXIud2FybignTm8gUmVkaXMgY29uZmlndXJlZCBmb3IgdGhlIHJlYWQtYWZ0ZXItd3JpdGUgcGluOyBldmVyeSByZWFkIHdpbGwgdXNlIHRoZSBwcmltYXJ5Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZWFkeSkgYXdhaXQgcmVhZHkoKTtcbiAgICByZXR1cm4gY2FjaGVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBpc1Bpbm5lZChvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBpZiAoIW9yZ0lkKSByZXR1cm4gdHJ1ZTsgLy8gbm8gb3JnIHRvIGtleSBvbiAtPiBhc3N1bWUgd3JpdHRlblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVkaXMgPSBhd2FpdCBjbGllbnQoKTtcbiAgICAgICAgaWYgKCFyZWRpcykgcmV0dXJuIHRydWU7IC8vIGZhaWwgY2xvc2VkXG4gICAgICAgIHJldHVybiAoYXdhaXQgcmVkaXMuZXhpc3RzKGtleShvcmdJZCkpKSA9PT0gMTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIud2FybignV3JpdGUtcGluIGxvb2t1cCBmYWlsZWQ7IHJvdXRpbmcgcmVhZHMgdG8gdGhlIHByaW1hcnknLCB7XG4gICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBmYWlsIGNsb3NlZFxuICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyBwaW4ob3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgLy8gTm90aGluZyB0byBrZXkgb24sIHNvIG5vdGhpbmcgdG8gcGluLiBUaGUgcmVhZCBzaWRlIGZhaWxzIGNsb3NlZCBmb3JcbiAgICAgIC8vIHRoZSBzYW1lIHNjb3BlIGFueXdheS5cbiAgICAgIGlmICghb3JnSWQpIHJldHVybjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlZGlzID0gYXdhaXQgY2xpZW50KCk7XG4gICAgICAgIGlmICghcmVkaXMpIHJldHVybjtcbiAgICAgICAgYXdhaXQgcmVkaXMuc2V0KGtleShvcmdJZCksICcxJywgJ0VYJywgdHRsU2Vjb25kcygpKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAvLyBBIGZhaWxlZCBwaW4gaXMgdGhlIGRhbmdlcm91cyBkaXJlY3Rpb24g4oCUIHRoZSBORVhUIHJlcXVlc3QgbWF5IHJlYWQgYVxuICAgICAgICAvLyBzdGFsZSByZXBsaWNhIOKAlCBidXQgdGhlcmUgaXMgbm90aGluZyB1c2VmdWwgdG8gZG8gYWJvdXQgaXQgaGVyZSwgYW5kXG4gICAgICAgIC8vIHRocm93aW5nIHdvdWxkIGZhaWwgYSByZXF1ZXN0IHdob3NlIHdyaXRlIGFscmVhZHkgY29tbWl0dGVkLiBMb2cgaXRcbiAgICAgICAgLy8gbG91ZGx5OyBgcG9zdGdyZXNfd3JpdGVfcGluX2Vycm9yc190b3RhbGAgaXMgdGhlIHRoaW5nIHRvIGFsZXJ0IG9uLlxuICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIHNldCB0aGUgcmVhZC1hZnRlci13cml0ZSBwaW47IGEgc3Vic2VxdWVudCByZWFkIG1heSBoaXQgYSBzdGFsZSByZXBsaWNhJywge1xuICAgICAgICAgIG9yZ0lkLFxuICAgICAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogSXMgdGhlIHBpbiBpbiBwbGF5IGF0IGFsbD9cbiAqXG4gKiBGYWxzZSB3aGVuZXZlciBubyByZWFkIHJlcGxpY2EgaXMgY29uZmlndXJlZCDigJQgd2hpY2ggaXMgaG93IGFsbCBmb3VyIHRhcmdldHNcbiAqIHNoaXAuIFRoZSBtaWRkbGV3YXJlIHVzZXMgdGhpcyBhcyBhIGhhcmQgZ2F0ZSBzbyB0aGF0IHdpdGggbm8gcmVwbGljYSBpdCBkb2VzXG4gKiBub3QgcmVnaXN0ZXIgYSByZXNwb25zZSBsaXN0ZW5lciwgZG9lcyBub3QgdG91Y2ggUmVkaXMsIGFuZCBjYWxscyBgbmV4dCgpYFxuICogU1lOQ0hST05PVVNMWSwgZXhhY3RseSBhcyBpdCBkaWQgYmVmb3JlIGFueSBvZiB0aGlzIGV4aXN0ZWQuIE1ha2luZyB0aGVcbiAqIHJlcXVlc3QgcGF0aCBhc3luY2hyb25vdXMgZm9yIGEgZmVhdHVyZSBub2JvZHkgaGFzIGVuYWJsZWQgd291bGQgYmUgYVxuICogYmVoYXZpb3VyIGNoYW5nZSBwYWlkIGJ5IGV2ZXJ5IHJvdXRlIG9uIGV2ZXJ5IHRhcmdldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlUGluQWN0aXZlKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNSZWFkUmVwbGljYUNvbmZpZ3VyZWQoKTtcbn1cblxuLyoqXG4gKiBCZWZvcmUgdGhlIHJlcXVlc3QgcnVuczogaWYgdGhpcyBvcmcgd3JvdGUgcmVjZW50bHksIHByZS1zZXQgdGhlIHNhbWVcbiAqIGBtYXlIYXZlV3JpdHRlbmAgZmxhZyBgd2l0aFRlbmFudFR4YCB3b3VsZCBoYXZlIHNldCwgc28gdGhlIHJlYWQgaGVscGVyIGtlZXBzXG4gKiB0aGUgcmVxdWVzdCBvbiB0aGUgcHJpbWFyeS5cbiAqXG4gKiBOby1vcHMgZW50aXJlbHkgd2hlbiBubyByZXBsaWNhIGlzIGNvbmZpZ3VyZWQg4oCUIHdoaWNoIGtlZXBzIFJlZGlzIG9mZiB0aGVcbiAqIHJlcXVlc3QgcGF0aCBmb3IgZXZlcnkgZGVwbG95IHRoYXQgaGFzIG5vdCBlbmFibGVkIHJlYWQtc3BsaXR0aW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlXcml0ZVBpbihzY29wZTogVGVuYW50Q29udGV4dCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIWlzUmVhZFJlcGxpY2FDb25maWd1cmVkKCkpIHJldHVybjtcbiAgaWYgKHNjb3BlLm1heUhhdmVXcml0dGVuKSByZXR1cm47IC8vIGFscmVhZHkga25vd24gdG8gaGF2ZSB3cml0dGVuXG4gIGlmIChhd2FpdCBnZXRXcml0ZVBpblN0b3JlKCkuaXNQaW5uZWQoc2NvcGUub3JnSWQpKSBzY29wZS5tYXlIYXZlV3JpdHRlbiA9IHRydWU7XG59XG5cbi8qKlxuICogQWZ0ZXIgdGhlIHJlc3BvbnNlOiBpZiBhbnl0aGluZyBpbiB0aGlzIHJlcXVlc3Qgb3BlbmVkIGEgcHJpbWFyeSB0cmFuc2FjdGlvbixcbiAqIHBpbiB0aGUgb3JnIHNvIGl0cyBuZXh0IHJlcXVlc3QgcmVhZHMgZnJvbSB0aGUgcHJpbWFyeSB0b28uXG4gKlxuICogUmVhZHMgYG1heUhhdmVXcml0dGVuYCByYXRoZXIgdGhhbiB0aGUgSFRUUCBtZXRob2Qgb24gcHVycG9zZS4gQSBQT1NUIHRoYXRcbiAqIG9ubHkgdmFsaWRhdGVzIGhhcyBub3RoaW5nIHRvIHBpbiBmb3IsIGFuZCDigJQgbW9yZSBpbXBvcnRhbnRseSDigJQgYSBHRVQgdGhhdFxuICogd3JpdGVzIChhIGxhenkgYmFja2ZpbGwsIGEgbGFzdC1zZWVuIHN0YW1wKSBhYnNvbHV0ZWx5IGRvZXMuIFRoZSBmbGFnIGZvbGxvd3NcbiAqIHdoYXQgYWN0dWFsbHkgdG91Y2hlZCB0aGUgcHJpbWFyeSwgd2hpY2ggdGhlIG1ldGhvZCBjYW5ub3QgdGVsbCB5b3UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRXcml0ZUZvclBpbihzY29wZTogVGVuYW50Q29udGV4dCk6IHZvaWQge1xuICBpZiAoIWlzUmVhZFJlcGxpY2FDb25maWd1cmVkKCkpIHJldHVybjtcbiAgaWYgKCFzY29wZS5tYXlIYXZlV3JpdHRlbikgcmV0dXJuO1xuICB2b2lkIGdldFdyaXRlUGluU3RvcmUoKS5waW4oc2NvcGUub3JnSWQpO1xufVxuIl19
|
package/lib/testing/exports.json
CHANGED
|
@@ -2,26 +2,31 @@
|
|
|
2
2
|
"package": "@pipeline-builder/api-server",
|
|
3
3
|
"entries": {
|
|
4
4
|
".": {
|
|
5
|
+
"applyWritePin": "function",
|
|
5
6
|
"attachRequestContext": "function",
|
|
6
7
|
"checkQuota": "function",
|
|
7
8
|
"combineHealthChecks": "function",
|
|
8
9
|
"connectMongo": "function",
|
|
9
10
|
"createApp": "function",
|
|
10
11
|
"createAuthenticatedWithOrgRoute": "function",
|
|
12
|
+
"createEnvRedisWritePinStore": "function",
|
|
11
13
|
"createMetricHelpers": "function",
|
|
12
14
|
"createProtectedRoute": "function",
|
|
13
15
|
"createSharedRateLimitStore": "function",
|
|
14
16
|
"currentTraceId": "function",
|
|
15
17
|
"getContext": "function",
|
|
16
18
|
"getIdempotencyStore": "function",
|
|
19
|
+
"getWritePinStore": "function",
|
|
17
20
|
"incCounter": "function",
|
|
18
21
|
"isReady": "function",
|
|
19
22
|
"meterQuotaOnSuccess": "function",
|
|
20
23
|
"mongoHealthCheck": "function",
|
|
24
|
+
"NO_WRITE_PIN": "value",
|
|
21
25
|
"observe": "function",
|
|
22
26
|
"postgresHealthCheck": "function",
|
|
23
27
|
"rateLimitByOrg": "function",
|
|
24
28
|
"readinessGuard": "function",
|
|
29
|
+
"recordWriteForPin": "function",
|
|
25
30
|
"redisHealthCheck": "function",
|
|
26
31
|
"registerSecretRotationGauge": "function",
|
|
27
32
|
"registerSseTicketChannel": "function",
|
|
@@ -29,12 +34,14 @@
|
|
|
29
34
|
"runServer": "function",
|
|
30
35
|
"setGauge": "function",
|
|
31
36
|
"setReady": "function",
|
|
37
|
+
"setWritePinStore": "function",
|
|
32
38
|
"SSEManager": "class",
|
|
33
39
|
"startServer": "function",
|
|
34
40
|
"withQuotaReservation": "function",
|
|
35
41
|
"withRoute": "function",
|
|
36
42
|
"withSpan": "function",
|
|
37
|
-
"withTenantContext": "function"
|
|
43
|
+
"withTenantContext": "function",
|
|
44
|
+
"writePinActive": "function"
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
}
|
package/package.json
CHANGED
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"@opentelemetry/instrumentation": "0.300.0",
|
|
36
36
|
"@opentelemetry/resources": "3.0.0",
|
|
37
37
|
"@opentelemetry/sdk-node": "0.300.0",
|
|
38
|
-
"@pipeline-builder/api-core": "5.0
|
|
39
|
-
"@pipeline-builder/pipeline-core": "4.
|
|
40
|
-
"@pipeline-builder/pipeline-data": "4.
|
|
38
|
+
"@pipeline-builder/api-core": "5.1.0",
|
|
39
|
+
"@pipeline-builder/pipeline-core": "4.2.0",
|
|
40
|
+
"@pipeline-builder/pipeline-data": "4.2.0",
|
|
41
41
|
"compression": "1.8.2",
|
|
42
42
|
"cors": "2.8.6",
|
|
43
43
|
"express": "5.2.1",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"access": "public",
|
|
112
112
|
"registry": "https://registry.npmjs.org/"
|
|
113
113
|
},
|
|
114
|
-
"version": "4.
|
|
114
|
+
"version": "4.2.0",
|
|
115
115
|
"bugs": {
|
|
116
116
|
"url": "https://github.com/mwashburn160/pipeline-builder/issues"
|
|
117
117
|
},
|