@blokjs/trigger-worker 0.4.0 → 0.6.1
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/__tests__/integration/nats-adapter.real-nats.test.ts +116 -0
- package/__tests__/integration/pgboss-adapter.real-pg.test.ts +164 -0
- package/__tests__/integration/rabbitmq-adapter.real-rabbitmq.test.ts +179 -0
- package/__tests__/integration/sqs-adapter.real-sqs.test.ts +228 -0
- package/dist/WorkerTrigger.d.ts +37 -1
- package/dist/WorkerTrigger.js +142 -21
- package/dist/adapters/InMemoryAdapter.js +10 -5
- package/dist/adapters/KafkaAdapter.d.ts +62 -0
- package/dist/adapters/KafkaAdapter.js +236 -0
- package/dist/adapters/NATSAdapter.js +3 -3
- package/dist/adapters/PgBossAdapter.d.ts +56 -0
- package/dist/adapters/PgBossAdapter.js +251 -0
- package/dist/adapters/RabbitMQAdapter.d.ts +51 -0
- package/dist/adapters/RabbitMQAdapter.js +241 -0
- package/dist/adapters/RedisStreamsAdapter.d.ts +64 -0
- package/dist/adapters/RedisStreamsAdapter.js +240 -0
- package/dist/adapters/SQSAdapter.d.ts +61 -0
- package/dist/adapters/SQSAdapter.js +269 -0
- package/dist/adapters/factory.d.ts +34 -0
- package/dist/adapters/factory.js +103 -0
- package/dist/index.d.ts +21 -4
- package/dist/index.js +24 -4
- package/package.json +23 -5
- package/src/WorkerTrigger.ts +153 -22
- package/src/adapters/InMemoryAdapter.ts +9 -5
- package/src/adapters/KafkaAdapter.ts +277 -0
- package/src/adapters/NATSAdapter.ts +4 -2
- package/src/adapters/PgBossAdapter.ts +293 -0
- package/src/adapters/RabbitMQAdapter.ts +285 -0
- package/src/adapters/RedisStreamsAdapter.ts +286 -0
- package/src/adapters/SQSAdapter.ts +306 -0
- package/src/adapters/factory.test.ts +89 -0
- package/src/adapters/factory.ts +111 -0
- package/src/adapters/new-adapters.test.ts +130 -0
- package/src/index.ts +30 -4
- package/template/package.json +6 -6
- package/template/src/workflows/jobs/process-job.ts +37 -35
|
@@ -196,7 +196,7 @@ export class NATSWorkerAdapter {
|
|
|
196
196
|
priority,
|
|
197
197
|
attempts,
|
|
198
198
|
maxRetries,
|
|
199
|
-
createdAt: new Date(info.timestampNanos ? Number(info.timestampNanos /
|
|
199
|
+
createdAt: new Date(info.timestampNanos ? Math.floor(Number(info.timestampNanos) / 1_000_000) : Date.now()),
|
|
200
200
|
delay: delay || undefined,
|
|
201
201
|
timeout: timeout || config.timeout || undefined,
|
|
202
202
|
raw: msg,
|
|
@@ -220,7 +220,7 @@ export class NATSWorkerAdapter {
|
|
|
220
220
|
// holding here. createdMs is the message's first-publish timestamp;
|
|
221
221
|
// hold until createdMs + delay. Single-process semantics — for
|
|
222
222
|
// long deferrals, prefer trigger-level `delay` (DeferredRunScheduler).
|
|
223
|
-
const createdMs = info.timestampNanos ? Number(info.timestampNanos /
|
|
223
|
+
const createdMs = info.timestampNanos ? Math.floor(Number(info.timestampNanos) / 1_000_000) : Date.now();
|
|
224
224
|
const waitMs = computeXDelayHoldMs(delay, createdMs, Date.now());
|
|
225
225
|
if (waitMs > 0) {
|
|
226
226
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
@@ -391,4 +391,4 @@ class Semaphore {
|
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
export default NATSWorkerAdapter;
|
|
394
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTkFUU0FkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvTkFUU0FkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUdsQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxLQUFhLEVBQUUsU0FBaUIsRUFBRSxLQUFhO0lBQ2xGLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuQyxNQUFNLFVBQVUsR0FBRyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3JDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFrQkQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBQ3BCLFFBQVEsR0FBRyxNQUFlLENBQUM7SUFFcEMsNkdBQTZHO0lBQ3JHLEVBQUUsR0FBUSxJQUFJLENBQUM7SUFDdkIsa0ZBQWtGO0lBQzFFLEVBQUUsR0FBUSxJQUFJLENBQUM7SUFDdkIsa0ZBQWtGO0lBQzFFLEdBQUcsR0FBUSxJQUFJLENBQUM7SUFDaEIsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixNQUFNLENBQW1CO0lBQ2pDLHNFQUFzRTtJQUM5RCxTQUFTLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDaEQscUVBQXFFO0lBQzdELGdCQUFnQixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXZELFlBQVksTUFBa0M7UUFDN0MsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNiLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksZ0JBQWdC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RUFBRTtZQUNwQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ04sTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1YsSUFBSSxFQUFFLENBQUM7UUFDUixDQUFDO2FBQU0sQ0FBQztZQUNQLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQixDQUFDO0lBQ0YsQ0FBQztDQUNEO0FBRUQsZUFBZSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTkFUU0FkYXB0ZXIgLSBOQVRTIEpldFN0cmVhbSB3b3JrZXIgYWRhcHRlciBmb3IgV29ya2VyVHJpZ2dlclxuICpcbiAqIFVzZXMgTkFUUyBKZXRTdHJlYW0gZm9yIHBlcnNpc3RlbnQgYmFja2dyb3VuZCBqb2IgcHJvY2Vzc2luZyB3aXRoOlxuICogLSBQdWxsLWJhc2VkIGNvbnN1bWVycyB3aXRoIGNvbmZpZ3VyYWJsZSBjb25jdXJyZW5jeVxuICogLSBTZXJ2ZXItc2lkZSByZXRyeSBjb25maWcgKG1heF9kZWxpdmVyKVxuICogLSBBY2sgd2FpdCBmb3Igam9iIHRpbWVvdXRzXG4gKiAtIFByaW9yaXR5IHZpYSBtZXNzYWdlIGhlYWRlcnNcbiAqIC0gRGVsYXllZCBqb2Igc2NoZWR1bGluZ1xuICogLSBRdWV1ZSBzdGF0aXN0aWNzIHZpYSBjb25zdW1lciBpbmZvXG4gKlxuICogUmVxdWlyZXM6IG5wbSBpbnN0YWxsIG5hdHNcbiAqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gKiAtIE5BVFNfU0VSVkVSUzogQ29tbWEtc2VwYXJhdGVkIE5BVFMgc2VydmVyIFVSTHMgKGRlZmF1bHQ6IGxvY2FsaG9zdDo0MjIyKVxuICogLSBOQVRTX1RPS0VOOiBBdXRoZW50aWNhdGlvbiB0b2tlbiAob3B0aW9uYWwpXG4gKiAtIE5BVFNfVVNFUjogVXNlcm5hbWUgZm9yIGF1dGggKG9wdGlvbmFsKVxuICogLSBOQVRTX1BBU1M6IFBhc3N3b3JkIGZvciBhdXRoIChvcHRpb25hbClcbiAqIC0gTkFUU19TVFJFQU1fTkFNRTogSmV0U3RyZWFtIHN0cmVhbSBuYW1lIChkZWZhdWx0OiBibG9rLXdvcmtlcilcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9ranMvaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuLyoqXG4gKiBUaWVyIDIgcG9saXNoIOKAlCBjb21wdXRlIHRoZSBjb25zdW1lci1zaWRlIGhvbGQgdGltZSBmb3IgYSBOQVRTIG1lc3NhZ2VcbiAqIHdpdGggYW4gYHgtZGVsYXlgIGhlYWRlci4gTkFUUyBKZXRTdHJlYW0gc3RvcmVzIGB4LWRlbGF5YCBhcyBvcGFxdWVcbiAqIG1ldGFkYXRhOyB0aGUgYnJva2VyIGRvZXMgTk9UIGRlZmVyIGRlbGl2ZXJ5IG9uIGl0LiBUaGUgY29uc3VtZXIgaXNcbiAqIHJlc3BvbnNpYmxlIGZvciBob25vdXJpbmcgdGhlIGRlbGF5IGJldHdlZW4gdGhlIG1lc3NhZ2UncyBmaXJzdC1wdWJsaXNoXG4gKiB0aW1lc3RhbXAgYW5kIGBjcmVhdGVkTXMgKyBkZWxheWAuXG4gKlxuICogUmV0dXJucyB0aGUgbWlsbGlzZWNvbmRzIHRvIHdhaXQuIENsYW1wcyB0byA+PSAwOyByZXR1cm5zIDAgd2hlbiB0aGVcbiAqIGRlbGF5IGhhcyBhbHJlYWR5IGVsYXBzZWQgKHRoZSBtZXNzYWdlIHdhcyBxdWV1ZWQgZm9yIGxvbmdlciB0aGFuIHRoZVxuICogZGVsYXkpIG9yIHdoZW4gbm8gZGVsYXkgd2FzIHNldC5cbiAqXG4gKiBFeHBvcnRlZCBmb3IgdW5pdCB0ZXN0YWJpbGl0eSDigJQgdGhlIGNvbnN1bWVyIG1lc3NhZ2UgaGFuZGxlciBpblxuICogYE5BVFNXb3JrZXJBZGFwdGVyLnByb2Nlc3MoKWAgbW9ja3MgdGhlIE5BVFMgY2xpZW50IGV4dGVuc2l2ZWx5LCBzb1xuICogaXNvbGF0aW5nIHRoZSBtYXRoIGhlcmUga2VlcHMgdGhlIHN1cmZhY2UgZWFzeSB0byB2ZXJpZnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlWERlbGF5SG9sZE1zKGRlbGF5OiBudW1iZXIsIGNyZWF0ZWRNczogbnVtYmVyLCBub3dNczogbnVtYmVyKTogbnVtYmVyIHtcblx0aWYgKCFkZWxheSB8fCBkZWxheSA8PSAwKSByZXR1cm4gMDtcblx0Y29uc3QgZGlzcGF0Y2hBdCA9IGNyZWF0ZWRNcyArIGRlbGF5O1xuXHRyZXR1cm4gTWF0aC5tYXgoMCwgZGlzcGF0Y2hBdCAtIG5vd01zKTtcbn1cblxuLyoqXG4gKiBOQVRTIHdvcmtlciBhZGFwdGVyIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOQVRTV29ya2VyQ29uZmlnIHtcblx0LyoqIE5BVFMgc2VydmVyIFVSTHMgKi9cblx0c2VydmVyczogc3RyaW5nW107XG5cdC8qKiBBdXRoZW50aWNhdGlvbiB0b2tlbiAqL1xuXHR0b2tlbj86IHN0cmluZztcblx0LyoqIFVzZXJuYW1lICovXG5cdHVzZXI/OiBzdHJpbmc7XG5cdC8qKiBQYXNzd29yZCAqL1xuXHRwYXNzPzogc3RyaW5nO1xuXHQvKiogSmV0U3RyZWFtIHN0cmVhbSBuYW1lIChkZWZhdWx0OiBcImJsb2std29ya2VyXCIpICovXG5cdHN0cmVhbU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogTkFUU1dvcmtlckFkYXB0ZXIgLSBOQVRTIEpldFN0cmVhbSBpbXBsZW1lbnRhdGlvbiBvZiBXb3JrZXJBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBOQVRTV29ya2VyQWRhcHRlciBpbXBsZW1lbnRzIFdvcmtlckFkYXB0ZXIge1xuXHRyZWFkb25seSBwcm92aWRlciA9IFwibmF0c1wiIGFzIGNvbnN0O1xuXG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTkFUUyB0eXBlcyBhcmUgZHluYW1pY2FsbHkgaW1wb3J0ZWQgKG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSlcblx0cHJpdmF0ZSBuYzogYW55ID0gbnVsbDtcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIHR5cGVzIGFyZSBkeW5hbWljYWxseSBpbXBvcnRlZFxuXHRwcml2YXRlIGpzOiBhbnkgPSBudWxsO1xuXHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5BVFMgdHlwZXMgYXJlIGR5bmFtaWNhbGx5IGltcG9ydGVkXG5cdHByaXZhdGUganNtOiBhbnkgPSBudWxsO1xuXHRwcml2YXRlIGNvbm5lY3RlZCA9IGZhbHNlO1xuXHRwcml2YXRlIGNvbmZpZzogTkFUU1dvcmtlckNvbmZpZztcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIGNvbnN1bWVyIGluc3RhbmNlc1xuXHRwcml2YXRlIGNvbnN1bWVyczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIGNvbnN1bWUgaXRlcmF0b3JzXG5cdHByaXZhdGUgY29uc3VtZUl0ZXJhdG9yczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcblxuXHRjb25zdHJ1Y3Rvcihjb25maWc/OiBQYXJ0aWFsPE5BVFNXb3JrZXJDb25maWc+KSB7XG5cdFx0dGhpcy5jb25maWcgPSB7XG5cdFx0XHRzZXJ2ZXJzOiBjb25maWc/LnNlcnZlcnMgfHwgKHByb2Nlc3MuZW52Lk5BVFNfU0VSVkVSUyB8fCBcImxvY2FsaG9zdDo0MjIyXCIpLnNwbGl0KFwiLFwiKSxcblx0XHRcdHRva2VuOiBjb25maWc/LnRva2VuIHx8IHByb2Nlc3MuZW52Lk5BVFNfVE9LRU4sXG5cdFx0XHR1c2VyOiBjb25maWc/LnVzZXIgfHwgcHJvY2Vzcy5lbnYuTkFUU19VU0VSLFxuXHRcdFx0cGFzczogY29uZmlnPy5wYXNzIHx8IHByb2Nlc3MuZW52Lk5BVFNfUEFTUyxcblx0XHRcdHN0cmVhbU5hbWU6IGNvbmZpZz8uc3RyZWFtTmFtZSB8fCBwcm9jZXNzLmVudi5OQVRTX1NUUkVBTV9OQU1FIHx8IFwiYmxvay13b3JrZXJcIixcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbm5lY3QgdG8gTkFUUyBhbmQgaW5pdGlhbGl6ZSBKZXRTdHJlYW1cblx0ICovXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgbmF0cyA9IGF3YWl0IGltcG9ydChcIm5hdHNcIik7XG5cblx0XHRcdGNvbnN0IGNvbm5lY3RPcHRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcblx0XHRcdFx0c2VydmVyczogdGhpcy5jb25maWcuc2VydmVycyxcblx0XHRcdH07XG5cblx0XHRcdGlmICh0aGlzLmNvbmZpZy50b2tlbikgY29ubmVjdE9wdHMudG9rZW4gPSB0aGlzLmNvbmZpZy50b2tlbjtcblx0XHRcdGlmICh0aGlzLmNvbmZpZy51c2VyKSBjb25uZWN0T3B0cy51c2VyID0gdGhpcy5jb25maWcudXNlcjtcblx0XHRcdGlmICh0aGlzLmNvbmZpZy5wYXNzKSBjb25uZWN0T3B0cy5wYXNzID0gdGhpcy5jb25maWcucGFzcztcblxuXHRcdFx0dGhpcy5uYyA9IGF3YWl0IG5hdHMuY29ubmVjdChjb25uZWN0T3B0cyk7XG5cdFx0XHR0aGlzLmpzID0gdGhpcy5uYy5qZXRzdHJlYW0oKTtcblx0XHRcdHRoaXMuanNtID0gYXdhaXQgdGhpcy5uYy5qZXRzdHJlYW1NYW5hZ2VyKCk7XG5cblx0XHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0XHRcdGNvbnNvbGUubG9nKGBbTkFUU1dvcmtlckFkYXB0ZXJdIENvbm5lY3RlZCB0byBOQVRTOiAke3RoaXMuY29uZmlnLnNlcnZlcnMuam9pbihcIiwgXCIpfWApO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBGYWlsZWQgdG8gY29ubmVjdCB0byBOQVRTOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX0uIE1ha2Ugc3VyZSBuYXRzIGlzIGluc3RhbGxlZDogbnBtIGluc3RhbGwgbmF0c2AsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNjb25uZWN0IGZyb20gTkFUU1xuXHQgKi9cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cblx0XHR0cnkge1xuXHRcdFx0Ly8gU3RvcCBhbGwgY29uc3VtZSBpdGVyYXRvcnNcblx0XHRcdGZvciAoY29uc3QgWywgaXRlcl0gb2YgdGhpcy5jb25zdW1lSXRlcmF0b3JzKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0aXRlci5zdG9wKCk7XG5cdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdC8vIEl0ZXJhdG9yIG1heSBhbHJlYWR5IGJlIHN0b3BwZWRcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5jb25zdW1lSXRlcmF0b3JzLmNsZWFyKCk7XG5cdFx0XHR0aGlzLmNvbnN1bWVycy5jbGVhcigpO1xuXG5cdFx0XHRhd2FpdCB0aGlzLm5jLmRyYWluKCk7XG5cdFx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHRcdFx0Y29uc29sZS5sb2coXCJbTkFUU1dvcmtlckFkYXB0ZXJdIERpc2Nvbm5lY3RlZCBmcm9tIE5BVFNcIik7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoYFtOQVRTV29ya2VyQWRhcHRlcl0gRGlzY29ubmVjdCBlcnJvcjogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0IHByb2Nlc3Npbmcgam9icyBmcm9tIGEgcXVldWVcblx0ICovXG5cdGFzeW5jIHByb2Nlc3MoY29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cywgaGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdH1cblxuXHRcdGNvbnN0IG5hdHMgPSBhd2FpdCBpbXBvcnQoXCJuYXRzXCIpO1xuXHRcdGNvbnN0IHF1ZXVlID0gY29uZmlnLnF1ZXVlO1xuXHRcdGNvbnN0IHN0cmVhbU5hbWUgPSB0aGlzLmNvbmZpZy5zdHJlYW1OYW1lIHx8IFwiYmxvay13b3JrZXJcIjtcblx0XHRjb25zdCBzdWJqZWN0ID0gYHdvcmtlci4ke3F1ZXVlfWA7XG5cdFx0Y29uc3QgZHVyYWJsZU5hbWUgPSBgYmxvay13b3JrZXItJHtxdWV1ZX1gO1xuXG5cdFx0Ly8gRW5zdXJlIHN0cmVhbSBleGlzdHMgd2l0aCB3b3JrZXIgc3ViamVjdHNcblx0XHRhd2FpdCB0aGlzLmVuc3VyZVN0cmVhbShzdHJlYW1OYW1lLCBbc3ViamVjdF0pO1xuXG5cdFx0Ly8gQ3JlYXRlIG9yIHVwZGF0ZSBkdXJhYmxlIHB1bGwgY29uc3VtZXIgd2l0aCB3b3JrZXIgc2VtYW50aWNzXG5cdFx0Y29uc3QgYWNrV2FpdE5zID0gKChjb25maWcudGltZW91dCA/PyAzMDAwMCkgKyA1MDAwKSAqIDFfMDAwXzAwMDsgLy8gdGltZW91dCArIDVzIGJ1ZmZlciwgaW4gbmFub3NlY29uZHNcblx0XHRhd2FpdCB0aGlzLmpzbS5jb25zdW1lcnMuYWRkKHN0cmVhbU5hbWUsIHtcblx0XHRcdGR1cmFibGVfbmFtZTogZHVyYWJsZU5hbWUsXG5cdFx0XHRhY2tfcG9saWN5OiBuYXRzLkFja1BvbGljeS5FeHBsaWNpdCxcblx0XHRcdG1heF9kZWxpdmVyOiAoY29uZmlnLnJldHJpZXMgPz8gMykgKyAxLCAvLyArMSBiZWNhdXNlIGZpcnN0IGF0dGVtcHQgY291bnRzXG5cdFx0XHRhY2tfd2FpdDogYWNrV2FpdE5zLFxuXHRcdFx0ZmlsdGVyX3N1YmplY3RzOiBbc3ViamVjdF0sXG5cdFx0fSk7XG5cblx0XHQvLyBHZXQgY29uc3VtZXIgaGFuZGxlXG5cdFx0Y29uc3QgY29uc3VtZXIgPSBhd2FpdCB0aGlzLmpzLmNvbnN1bWVycy5nZXQoc3RyZWFtTmFtZSwgZHVyYWJsZU5hbWUpO1xuXHRcdHRoaXMuY29uc3VtZXJzLnNldChxdWV1ZSwgY29uc3VtZXIpO1xuXG5cdFx0Ly8gU3RhcnQgY29uc3VtaW5nXG5cdFx0Y29uc3QgaXRlciA9IGF3YWl0IGNvbnN1bWVyLmNvbnN1bWUoKTtcblx0XHR0aGlzLmNvbnN1bWVJdGVyYXRvcnMuc2V0KHF1ZXVlLCBpdGVyKTtcblxuXHRcdC8vIFByb2Nlc3Mgam9icyBpbiBiYWNrZ3JvdW5kXG5cdFx0KGFzeW5jICgpID0+IHtcblx0XHRcdGNvbnN0IHNlbWFwaG9yZSA9IG5ldyBTZW1hcGhvcmUoY29uZmlnLmNvbmN1cnJlbmN5ID8/IDEpO1xuXG5cdFx0XHRmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBpdGVyKSB7XG5cdFx0XHRcdGF3YWl0IHNlbWFwaG9yZS5hY3F1aXJlKCk7XG5cblx0XHRcdFx0Ly8gUHJvY2VzcyBlYWNoIGpvYiBjb25jdXJyZW50bHkgdXAgdG8gY29uY3VycmVuY3kgbGltaXRcblx0XHRcdFx0KGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0Ly8gUGFyc2Ugam9iIGRhdGFcblx0XHRcdFx0XHRcdGxldCBkYXRhOiB1bmtub3duO1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgY29kZWMgPSBuYXRzLkpTT05Db2RlYygpO1xuXHRcdFx0XHRcdFx0XHRkYXRhID0gY29kZWMuZGVjb2RlKG1zZy5kYXRhKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNjID0gbmF0cy5TdHJpbmdDb2RlYygpO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGEgPSBKU09OLnBhcnNlKHNjLmRlY29kZShtc2cuZGF0YSkpO1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0XHRkYXRhID0gbXNnLmRhdGE7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gRXh0cmFjdCBoZWFkZXJzXG5cdFx0XHRcdFx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdFx0XHRcdFx0XHRpZiAobXNnLmhlYWRlcnMpIHtcblx0XHRcdFx0XHRcdFx0Zm9yIChjb25zdCBba2V5LCB2YWx1ZXNdIG9mIG1zZy5oZWFkZXJzKSB7XG5cdFx0XHRcdFx0XHRcdFx0aGVhZGVyc1trZXldID0gQXJyYXkuaXNBcnJheSh2YWx1ZXMpID8gdmFsdWVzWzBdIDogdmFsdWVzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEV4dHJhY3Qgam9iIG1ldGFkYXRhIGZyb20gaGVhZGVyc1xuXHRcdFx0XHRcdFx0Y29uc3Qgam9iSWQgPSBoZWFkZXJzW1wieC1qb2ItaWRcIl0gfHwgbXNnLmhlYWRlcnM/LmdldChcIk5hdHMtTXNnLUlkXCIpIHx8IHV1aWQoKTtcblx0XHRcdFx0XHRcdGNvbnN0IHByaW9yaXR5ID0gTnVtYmVyLnBhcnNlSW50KGhlYWRlcnNbXCJ4LXByaW9yaXR5XCJdIHx8IFwiMFwiLCAxMCk7XG5cdFx0XHRcdFx0XHRjb25zdCBkZWxheSA9IE51bWJlci5wYXJzZUludChoZWFkZXJzW1wieC1kZWxheVwiXSB8fCBcIjBcIiwgMTApO1xuXHRcdFx0XHRcdFx0Y29uc3QgdGltZW91dCA9IE51bWJlci5wYXJzZUludChoZWFkZXJzW1wieC10aW1lb3V0XCJdIHx8IFwiMFwiLCAxMCk7XG5cblx0XHRcdFx0XHRcdC8vIEdldCByZWRlbGl2ZXJ5IGNvdW50IChhdHRlbXB0cylcblx0XHRcdFx0XHRcdGNvbnN0IGluZm8gPSBtc2cuaW5mbztcblx0XHRcdFx0XHRcdGNvbnN0IGF0dGVtcHRzID0gaW5mby5yZWRlbGl2ZXJ5Q291bnQgPz8gMDtcblx0XHRcdFx0XHRcdGNvbnN0IG1heFJldHJpZXMgPSBjb25maWcucmV0cmllcyA/PyAzO1xuXG5cdFx0XHRcdFx0XHQvLyBDcmVhdGUgV29ya2VySm9iXG5cdFx0XHRcdFx0XHRjb25zdCB3b3JrZXJKb2I6IFdvcmtlckpvYiA9IHtcblx0XHRcdFx0XHRcdFx0aWQ6IGpvYklkLFxuXHRcdFx0XHRcdFx0XHRkYXRhLFxuXHRcdFx0XHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRcdFx0XHRxdWV1ZSxcblx0XHRcdFx0XHRcdFx0cHJpb3JpdHksXG5cdFx0XHRcdFx0XHRcdGF0dGVtcHRzLFxuXHRcdFx0XHRcdFx0XHRtYXhSZXRyaWVzLFxuXHRcdFx0XHRcdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKGluZm8udGltZXN0YW1wTmFub3MgPyBOdW1iZXIoaW5mby50aW1lc3RhbXBOYW5vcyAvIEJpZ0ludCgxXzAwMF8wMDApKSA6IERhdGUubm93KCkpLFxuXHRcdFx0XHRcdFx0XHRkZWxheTogZGVsYXkgfHwgdW5kZWZpbmVkLFxuXHRcdFx0XHRcdFx0XHR0aW1lb3V0OiB0aW1lb3V0IHx8IGNvbmZpZy50aW1lb3V0IHx8IHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdFx0cmF3OiBtc2csXG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0bXNnLmFjaygpO1xuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRmYWlsOiBhc3luYyAoZXJyb3I6IEVycm9yLCByZXF1ZXVlPzogYm9vbGVhbikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChyZXF1ZXVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBuYWsoKSB0ZWxscyB0aGUgc2VydmVyIHRvIHJlZGVsaXZlclxuXHRcdFx0XHRcdFx0XHRcdFx0bXNnLm5haygpO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyB0ZXJtKCkgdGVybWluYXRlcyBkZWxpdmVyeSDigJQgbm8gbW9yZSByZXRyaWVzXG5cdFx0XHRcdFx0XHRcdFx0XHRtc2cudGVybSgpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRcdC8vIFRpZXIgMiBwb2xpc2gg4oCUIGVuZm9yY2UgYHgtZGVsYXlgIGhlYWRlciBvbiB0aGUgY29uc3VtZXIgc2lkZS5cblx0XHRcdFx0XHRcdC8vIE5BVFMgSmV0U3RyZWFtIHN0b3JlcyBgeC1kZWxheWAgYXMgb3BhcXVlIG1ldGFkYXRhOyB0aGUgYnJva2VyXG5cdFx0XHRcdFx0XHQvLyBkb2VzIE5PVCBkZWZlciBkZWxpdmVyeSBvbiBpdC4gV2UgaW1wbGVtZW50IGNvbnN1bWVyLXNpZGVcblx0XHRcdFx0XHRcdC8vIGhvbGRpbmcgaGVyZS4gY3JlYXRlZE1zIGlzIHRoZSBtZXNzYWdlJ3MgZmlyc3QtcHVibGlzaCB0aW1lc3RhbXA7XG5cdFx0XHRcdFx0XHQvLyBob2xkIHVudGlsIGNyZWF0ZWRNcyArIGRlbGF5LiBTaW5nbGUtcHJvY2VzcyBzZW1hbnRpY3Mg4oCUIGZvclxuXHRcdFx0XHRcdFx0Ly8gbG9uZyBkZWZlcnJhbHMsIHByZWZlciB0cmlnZ2VyLWxldmVsIGBkZWxheWAgKERlZmVycmVkUnVuU2NoZWR1bGVyKS5cblx0XHRcdFx0XHRcdGNvbnN0IGNyZWF0ZWRNcyA9IGluZm8udGltZXN0YW1wTmFub3MgPyBOdW1iZXIoaW5mby50aW1lc3RhbXBOYW5vcyAvIEJpZ0ludCgxXzAwMF8wMDApKSA6IERhdGUubm93KCk7XG5cdFx0XHRcdFx0XHRjb25zdCB3YWl0TXMgPSBjb21wdXRlWERlbGF5SG9sZE1zKGRlbGF5LCBjcmVhdGVkTXMsIERhdGUubm93KCkpO1xuXHRcdFx0XHRcdFx0aWYgKHdhaXRNcyA+IDApIHtcblx0XHRcdFx0XHRcdFx0YXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgd2FpdE1zKSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGF3YWl0IGhhbmRsZXIod29ya2VySm9iKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRcdFx0Y29uc29sZS5lcnJvcihgW05BVFNXb3JrZXJBZGFwdGVyXSBFcnJvciBwcm9jZXNzaW5nIGpvYiBmcm9tICR7cXVldWV9OiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdG1zZy5uYWsoKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdFx0XHQvLyBBbHJlYWR5IGFja2VkL25hY2tlZFxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRzZW1hcGhvcmUucmVsZWFzZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSkoKTtcblx0XHRcdH1cblx0XHR9KSgpO1xuXG5cdFx0Y29uc29sZS5sb2coXG5cdFx0XHRgW05BVFNXb3JrZXJBZGFwdGVyXSBQcm9jZXNzaW5nIHF1ZXVlOiAke3F1ZXVlfSAoY29uY3VycmVuY3k9JHtjb25maWcuY29uY3VycmVuY3kgPz8gMX0sIHJldHJpZXM9JHtjb25maWcucmV0cmllcyA/PyAzfSlgLFxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIGEgam9iIHRvIGEgd29ya2VyIHF1ZXVlXG5cdCAqL1xuXHRhc3luYyBhZGRKb2IoXG5cdFx0cXVldWU6IHN0cmluZyxcblx0XHRkYXRhOiB1bmtub3duLFxuXHRcdG9wdHM/OiB7XG5cdFx0XHRwcmlvcml0eT86IG51bWJlcjtcblx0XHRcdGRlbGF5PzogbnVtYmVyO1xuXHRcdFx0cmV0cmllcz86IG51bWJlcjtcblx0XHRcdHRpbWVvdXQ/OiBudW1iZXI7XG5cdFx0XHRqb2JJZD86IHN0cmluZztcblx0XHR9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIk5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR9XG5cblx0XHRjb25zdCBuYXRzID0gYXdhaXQgaW1wb3J0KFwibmF0c1wiKTtcblx0XHRjb25zdCBzdWJqZWN0ID0gYHdvcmtlci4ke3F1ZXVlfWA7XG5cdFx0Y29uc3Qgc3RyZWFtTmFtZSA9IHRoaXMuY29uZmlnLnN0cmVhbU5hbWUgfHwgXCJibG9rLXdvcmtlclwiO1xuXG5cdFx0Ly8gRW5zdXJlIHN0cmVhbSBoYXMgdGhpcyBzdWJqZWN0XG5cdFx0YXdhaXQgdGhpcy5lbnN1cmVTdHJlYW0oc3RyZWFtTmFtZSwgW3N1YmplY3RdKTtcblxuXHRcdC8vIEJ1aWxkIGhlYWRlcnMgd2l0aCBqb2IgbWV0YWRhdGFcblx0XHRjb25zdCBoZHJzID0gbmF0cy5oZWFkZXJzKCk7XG5cdFx0Y29uc3Qgam9iSWQgPSBvcHRzPy5qb2JJZCB8fCB1dWlkKCk7XG5cdFx0aGRycy5zZXQoXCJ4LWpvYi1pZFwiLCBqb2JJZCk7XG5cdFx0aGRycy5zZXQoXCJOYXRzLU1zZy1JZFwiLCBqb2JJZCk7IC8vIERlZHVwbGljYXRpb25cblx0XHRpZiAob3B0cz8ucHJpb3JpdHkpIGhkcnMuc2V0KFwieC1wcmlvcml0eVwiLCBTdHJpbmcob3B0cy5wcmlvcml0eSkpO1xuXHRcdGlmIChvcHRzPy5kZWxheSkgaGRycy5zZXQoXCJ4LWRlbGF5XCIsIFN0cmluZyhvcHRzLmRlbGF5KSk7XG5cdFx0aWYgKG9wdHM/LnRpbWVvdXQpIGhkcnMuc2V0KFwieC10aW1lb3V0XCIsIFN0cmluZyhvcHRzLnRpbWVvdXQpKTtcblxuXHRcdC8vIEVuY29kZSBhbmQgcHVibGlzaFxuXHRcdGNvbnN0IGNvZGVjID0gbmF0cy5KU09OQ29kZWMoKTtcblx0XHRhd2FpdCB0aGlzLmpzLnB1Ymxpc2goc3ViamVjdCwgY29kZWMuZW5jb2RlKGRhdGEpLCB7IGhlYWRlcnM6IGhkcnMgfSk7XG5cblx0XHRyZXR1cm4gam9iSWQ7XG5cdH1cblxuXHQvKipcblx0ICogU3RvcCBwcm9jZXNzaW5nIGEgc3BlY2lmaWMgcXVldWVcblx0ICovXG5cdGFzeW5jIHN0b3BQcm9jZXNzaW5nKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBpdGVyID0gdGhpcy5jb25zdW1lSXRlcmF0b3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKGl0ZXIpIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGl0ZXIuc3RvcCgpO1xuXHRcdFx0fSBjYXRjaCB7XG5cdFx0XHRcdC8vIEFscmVhZHkgc3RvcHBlZFxuXHRcdFx0fVxuXHRcdFx0dGhpcy5jb25zdW1lSXRlcmF0b3JzLmRlbGV0ZShxdWV1ZSk7XG5cdFx0fVxuXHRcdHRoaXMuY29uc3VtZXJzLmRlbGV0ZShxdWV1ZSk7XG5cdFx0Y29uc29sZS5sb2coYFtOQVRTV29ya2VyQWRhcHRlcl0gU3RvcHBlZCBwcm9jZXNzaW5nIHF1ZXVlOiAke3F1ZXVlfWApO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrIGlmIGNvbm5lY3RlZFxuXHQgKi9cblx0aXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlYWx0aCBjaGVja1xuXHQgKi9cblx0YXN5bmMgaGVhbHRoQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCB8fCAhdGhpcy5uYykgcmV0dXJuIGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBpbmZvID0gdGhpcy5uYy5pbmZvO1xuXHRcdFx0cmV0dXJuIGluZm8gIT09IHVuZGVmaW5lZDtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0IHF1ZXVlIHN0YXRpc3RpY3MgZnJvbSBKZXRTdHJlYW0gY29uc3VtZXIgaW5mb1xuXHQgKi9cblx0YXN5bmMgZ2V0UXVldWVTdGF0cyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTxXb3JrZXJRdWV1ZVN0YXRzPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkge1xuXHRcdFx0cmV0dXJuIHsgd2FpdGluZzogMCwgYWN0aXZlOiAwLCBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCwgZGVsYXllZDogMCB9O1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBzdHJlYW1OYW1lID0gdGhpcy5jb25maWcuc3RyZWFtTmFtZSB8fCBcImJsb2std29ya2VyXCI7XG5cdFx0XHRjb25zdCBkdXJhYmxlTmFtZSA9IGBibG9rLXdvcmtlci0ke3F1ZXVlfWA7XG5cblx0XHRcdGNvbnN0IGluZm8gPSBhd2FpdCB0aGlzLmpzbS5jb25zdW1lcnMuaW5mbyhzdHJlYW1OYW1lLCBkdXJhYmxlTmFtZSk7XG5cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHdhaXRpbmc6IGluZm8ubnVtX3BlbmRpbmcgPz8gMCxcblx0XHRcdFx0YWN0aXZlOiBpbmZvLm51bV9hY2tfcGVuZGluZyA/PyAwLFxuXHRcdFx0XHRjb21wbGV0ZWQ6IGluZm8uZGVsaXZlcmVkPy5jb25zdW1lcl9zZXEgPz8gMCxcblx0XHRcdFx0ZmFpbGVkOiBpbmZvLm51bV9yZWRlbGl2ZXJlZCA/PyAwLFxuXHRcdFx0XHRkZWxheWVkOiAwLCAvLyBOQVRTIGRvZXNuJ3QgaGF2ZSBhIG5hdGl2ZSBkZWxheWVkIGNvdW50XG5cdFx0XHR9O1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIHsgd2FpdGluZzogMCwgYWN0aXZlOiAwLCBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCwgZGVsYXllZDogMCB9O1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFbnN1cmUgYSBKZXRTdHJlYW0gc3RyZWFtIGV4aXN0cyB3aXRoIHRoZSBnaXZlbiBzdWJqZWN0c1xuXHQgKi9cblx0cHJpdmF0ZSBhc3luYyBlbnN1cmVTdHJlYW0obmFtZTogc3RyaW5nLCBzdWJqZWN0czogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgaW5mbyA9IGF3YWl0IHRoaXMuanNtLnN0cmVhbXMuaW5mbyhuYW1lKTtcblxuXHRcdFx0Ly8gTWVyZ2UgbmV3IHN1YmplY3RzIHdpdGggZXhpc3Rpbmdcblx0XHRcdGNvbnN0IGV4aXN0aW5nU3ViamVjdHMgPSBpbmZvLmNvbmZpZy5zdWJqZWN0cyB8fCBbXTtcblx0XHRcdGNvbnN0IGFsbFN1YmplY3RzID0gWy4uLm5ldyBTZXQoWy4uLmV4aXN0aW5nU3ViamVjdHMsIC4uLnN1YmplY3RzXSldO1xuXG5cdFx0XHRpZiAoYWxsU3ViamVjdHMubGVuZ3RoICE9PSBleGlzdGluZ1N1YmplY3RzLmxlbmd0aCkge1xuXHRcdFx0XHRhd2FpdCB0aGlzLmpzbS5zdHJlYW1zLnVwZGF0ZShuYW1lLCB7XG5cdFx0XHRcdFx0Li4uaW5mby5jb25maWcsXG5cdFx0XHRcdFx0c3ViamVjdHM6IGFsbFN1YmplY3RzLFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9IGNhdGNoIHtcblx0XHRcdC8vIFN0cmVhbSBkb2Vzbid0IGV4aXN0LCBjcmVhdGUgaXRcblx0XHRcdGF3YWl0IHRoaXMuanNtLnN0cmVhbXMuYWRkKHtcblx0XHRcdFx0bmFtZSxcblx0XHRcdFx0c3ViamVjdHMsXG5cdFx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogbmF0cyBKZXRTdHJlYW0gcmV0ZW50aW9uIHBvbGljeSBlbnVtXG5cdFx0XHRcdHJldGVudGlvbjogXCJ3b3JrcXVldWVcIiBhcyBhbnksXG5cdFx0XHRcdG1heF9kZWxpdmVyOiA0LCAvLyBkZWZhdWx0OiAzIHJldHJpZXMgKyAxIGluaXRpYWwgYXR0ZW1wdFxuXHRcdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IG5hdHMgSmV0U3RyZWFtIHN0b3JhZ2UgdHlwZSBlbnVtXG5cdFx0XHRcdHN0b3JhZ2U6IFwiZmlsZVwiIGFzIGFueSxcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIFNpbXBsZSBzZW1hcGhvcmUgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2xcbiAqL1xuY2xhc3MgU2VtYXBob3JlIHtcblx0cHJpdmF0ZSBwZXJtaXRzOiBudW1iZXI7XG5cdHByaXZhdGUgd2FpdGluZzogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXTtcblxuXHRjb25zdHJ1Y3RvcihwZXJtaXRzOiBudW1iZXIpIHtcblx0XHR0aGlzLnBlcm1pdHMgPSBwZXJtaXRzO1xuXHR9XG5cblx0YXN5bmMgYWNxdWlyZSgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy5wZXJtaXRzID4gMCkge1xuXHRcdFx0dGhpcy5wZXJtaXRzLS07XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuXHRcdFx0dGhpcy53YWl0aW5nLnB1c2gocmVzb2x2ZSk7XG5cdFx0fSk7XG5cdH1cblxuXHRyZWxlYXNlKCk6IHZvaWQge1xuXHRcdGNvbnN0IG5leHQgPSB0aGlzLndhaXRpbmcuc2hpZnQoKTtcblx0XHRpZiAobmV4dCkge1xuXHRcdFx0bmV4dCgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBlcm1pdHMrKztcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTkFUU1dvcmtlckFkYXB0ZXI7XG4iXX0=
|
|
394
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTkFUU0FkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvTkFUU0FkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUdsQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxLQUFhLEVBQUUsU0FBaUIsRUFBRSxLQUFhO0lBQ2xGLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuQyxNQUFNLFVBQVUsR0FBRyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3JDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFrQkQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBQ3BCLFFBQVEsR0FBRyxNQUFlLENBQUM7SUFFcEMsNkdBQTZHO0lBQ3JHLEVBQUUsR0FBUSxJQUFJLENBQUM7SUFDdkIsa0ZBQWtGO0lBQzFFLEVBQUUsR0FBUSxJQUFJLENBQUM7SUFDdkIsa0ZBQWtGO0lBQzFFLEdBQUcsR0FBUSxJQUFJLENBQUM7SUFDaEIsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixNQUFNLENBQW1CO0lBQ2pDLHNFQUFzRTtJQUM5RCxTQUFTLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDaEQscUVBQXFFO0lBQzdELGdCQUFnQixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXZELFlBQVksTUFBa0M7UUFDN0MsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNiLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksZ0JBQWdC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LENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNwQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ04sTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1YsSUFBSSxFQUFFLENBQUM7UUFDUixDQUFDO2FBQU0sQ0FBQztZQUNQLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQixDQUFDO0lBQ0YsQ0FBQztDQUNEO0FBRUQsZUFBZSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTkFUU0FkYXB0ZXIgLSBOQVRTIEpldFN0cmVhbSB3b3JrZXIgYWRhcHRlciBmb3IgV29ya2VyVHJpZ2dlclxuICpcbiAqIFVzZXMgTkFUUyBKZXRTdHJlYW0gZm9yIHBlcnNpc3RlbnQgYmFja2dyb3VuZCBqb2IgcHJvY2Vzc2luZyB3aXRoOlxuICogLSBQdWxsLWJhc2VkIGNvbnN1bWVycyB3aXRoIGNvbmZpZ3VyYWJsZSBjb25jdXJyZW5jeVxuICogLSBTZXJ2ZXItc2lkZSByZXRyeSBjb25maWcgKG1heF9kZWxpdmVyKVxuICogLSBBY2sgd2FpdCBmb3Igam9iIHRpbWVvdXRzXG4gKiAtIFByaW9yaXR5IHZpYSBtZXNzYWdlIGhlYWRlcnNcbiAqIC0gRGVsYXllZCBqb2Igc2NoZWR1bGluZ1xuICogLSBRdWV1ZSBzdGF0aXN0aWNzIHZpYSBjb25zdW1lciBpbmZvXG4gKlxuICogUmVxdWlyZXM6IG5wbSBpbnN0YWxsIG5hdHNcbiAqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gKiAtIE5BVFNfU0VSVkVSUzogQ29tbWEtc2VwYXJhdGVkIE5BVFMgc2VydmVyIFVSTHMgKGRlZmF1bHQ6IGxvY2FsaG9zdDo0MjIyKVxuICogLSBOQVRTX1RPS0VOOiBBdXRoZW50aWNhdGlvbiB0b2tlbiAob3B0aW9uYWwpXG4gKiAtIE5BVFNfVVNFUjogVXNlcm5hbWUgZm9yIGF1dGggKG9wdGlvbmFsKVxuICogLSBOQVRTX1BBU1M6IFBhc3N3b3JkIGZvciBhdXRoIChvcHRpb25hbClcbiAqIC0gTkFUU19TVFJFQU1fTkFNRTogSmV0U3RyZWFtIHN0cmVhbSBuYW1lIChkZWZhdWx0OiBibG9rLXdvcmtlcilcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9ranMvaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuLyoqXG4gKiBUaWVyIDIgcG9saXNoIOKAlCBjb21wdXRlIHRoZSBjb25zdW1lci1zaWRlIGhvbGQgdGltZSBmb3IgYSBOQVRTIG1lc3NhZ2VcbiAqIHdpdGggYW4gYHgtZGVsYXlgIGhlYWRlci4gTkFUUyBKZXRTdHJlYW0gc3RvcmVzIGB4LWRlbGF5YCBhcyBvcGFxdWVcbiAqIG1ldGFkYXRhOyB0aGUgYnJva2VyIGRvZXMgTk9UIGRlZmVyIGRlbGl2ZXJ5IG9uIGl0LiBUaGUgY29uc3VtZXIgaXNcbiAqIHJlc3BvbnNpYmxlIGZvciBob25vdXJpbmcgdGhlIGRlbGF5IGJldHdlZW4gdGhlIG1lc3NhZ2UncyBmaXJzdC1wdWJsaXNoXG4gKiB0aW1lc3RhbXAgYW5kIGBjcmVhdGVkTXMgKyBkZWxheWAuXG4gKlxuICogUmV0dXJucyB0aGUgbWlsbGlzZWNvbmRzIHRvIHdhaXQuIENsYW1wcyB0byA+PSAwOyByZXR1cm5zIDAgd2hlbiB0aGVcbiAqIGRlbGF5IGhhcyBhbHJlYWR5IGVsYXBzZWQgKHRoZSBtZXNzYWdlIHdhcyBxdWV1ZWQgZm9yIGxvbmdlciB0aGFuIHRoZVxuICogZGVsYXkpIG9yIHdoZW4gbm8gZGVsYXkgd2FzIHNldC5cbiAqXG4gKiBFeHBvcnRlZCBmb3IgdW5pdCB0ZXN0YWJpbGl0eSDigJQgdGhlIGNvbnN1bWVyIG1lc3NhZ2UgaGFuZGxlciBpblxuICogYE5BVFNXb3JrZXJBZGFwdGVyLnByb2Nlc3MoKWAgbW9ja3MgdGhlIE5BVFMgY2xpZW50IGV4dGVuc2l2ZWx5LCBzb1xuICogaXNvbGF0aW5nIHRoZSBtYXRoIGhlcmUga2VlcHMgdGhlIHN1cmZhY2UgZWFzeSB0byB2ZXJpZnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlWERlbGF5SG9sZE1zKGRlbGF5OiBudW1iZXIsIGNyZWF0ZWRNczogbnVtYmVyLCBub3dNczogbnVtYmVyKTogbnVtYmVyIHtcblx0aWYgKCFkZWxheSB8fCBkZWxheSA8PSAwKSByZXR1cm4gMDtcblx0Y29uc3QgZGlzcGF0Y2hBdCA9IGNyZWF0ZWRNcyArIGRlbGF5O1xuXHRyZXR1cm4gTWF0aC5tYXgoMCwgZGlzcGF0Y2hBdCAtIG5vd01zKTtcbn1cblxuLyoqXG4gKiBOQVRTIHdvcmtlciBhZGFwdGVyIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOQVRTV29ya2VyQ29uZmlnIHtcblx0LyoqIE5BVFMgc2VydmVyIFVSTHMgKi9cblx0c2VydmVyczogc3RyaW5nW107XG5cdC8qKiBBdXRoZW50aWNhdGlvbiB0b2tlbiAqL1xuXHR0b2tlbj86IHN0cmluZztcblx0LyoqIFVzZXJuYW1lICovXG5cdHVzZXI/OiBzdHJpbmc7XG5cdC8qKiBQYXNzd29yZCAqL1xuXHRwYXNzPzogc3RyaW5nO1xuXHQvKiogSmV0U3RyZWFtIHN0cmVhbSBuYW1lIChkZWZhdWx0OiBcImJsb2std29ya2VyXCIpICovXG5cdHN0cmVhbU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogTkFUU1dvcmtlckFkYXB0ZXIgLSBOQVRTIEpldFN0cmVhbSBpbXBsZW1lbnRhdGlvbiBvZiBXb3JrZXJBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBOQVRTV29ya2VyQWRhcHRlciBpbXBsZW1lbnRzIFdvcmtlckFkYXB0ZXIge1xuXHRyZWFkb25seSBwcm92aWRlciA9IFwibmF0c1wiIGFzIGNvbnN0O1xuXG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTkFUUyB0eXBlcyBhcmUgZHluYW1pY2FsbHkgaW1wb3J0ZWQgKG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSlcblx0cHJpdmF0ZSBuYzogYW55ID0gbnVsbDtcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIHR5cGVzIGFyZSBkeW5hbWljYWxseSBpbXBvcnRlZFxuXHRwcml2YXRlIGpzOiBhbnkgPSBudWxsO1xuXHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5BVFMgdHlwZXMgYXJlIGR5bmFtaWNhbGx5IGltcG9ydGVkXG5cdHByaXZhdGUganNtOiBhbnkgPSBudWxsO1xuXHRwcml2YXRlIGNvbm5lY3RlZCA9IGZhbHNlO1xuXHRwcml2YXRlIGNvbmZpZzogTkFUU1dvcmtlckNvbmZpZztcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIGNvbnN1bWVyIGluc3RhbmNlc1xuXHRwcml2YXRlIGNvbnN1bWVyczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOQVRTIGNvbnN1bWUgaXRlcmF0b3JzXG5cdHByaXZhdGUgY29uc3VtZUl0ZXJhdG9yczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcblxuXHRjb25zdHJ1Y3Rvcihjb25maWc/OiBQYXJ0aWFsPE5BVFNXb3JrZXJDb25maWc+KSB7XG5cdFx0dGhpcy5jb25maWcgPSB7XG5cdFx0XHRzZXJ2ZXJzOiBjb25maWc/LnNlcnZlcnMgfHwgKHByb2Nlc3MuZW52Lk5BVFNfU0VSVkVSUyB8fCBcImxvY2FsaG9zdDo0MjIyXCIpLnNwbGl0KFwiLFwiKSxcblx0XHRcdHRva2VuOiBjb25maWc/LnRva2VuIHx8IHByb2Nlc3MuZW52Lk5BVFNfVE9LRU4sXG5cdFx0XHR1c2VyOiBjb25maWc/LnVzZXIgfHwgcHJvY2Vzcy5lbnYuTkFUU19VU0VSLFxuXHRcdFx0cGFzczogY29uZmlnPy5wYXNzIHx8IHByb2Nlc3MuZW52Lk5BVFNfUEFTUyxcblx0XHRcdHN0cmVhbU5hbWU6IGNvbmZpZz8uc3RyZWFtTmFtZSB8fCBwcm9jZXNzLmVudi5OQVRTX1NUUkVBTV9OQU1FIHx8IFwiYmxvay13b3JrZXJcIixcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbm5lY3QgdG8gTkFUUyBhbmQgaW5pdGlhbGl6ZSBKZXRTdHJlYW1cblx0ICovXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgbmF0cyA9IGF3YWl0IGltcG9ydChcIm5hdHNcIik7XG5cblx0XHRcdGNvbnN0IGNvbm5lY3RPcHRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcblx0XHRcdFx0c2VydmVyczogdGhpcy5jb25maWcuc2VydmVycyxcblx0XHRcdH07XG5cblx0XHRcdGlmICh0aGlzLmNvbmZpZy50b2tlbikgY29ubmVjdE9wdHMudG9rZW4gPSB0aGlzLmNvbmZpZy50b2tlbjtcblx0XHRcdGlmICh0aGlzLmNvbmZpZy51c2VyKSBjb25uZWN0T3B0cy51c2VyID0gdGhpcy5jb25maWcudXNlcjtcblx0XHRcdGlmICh0aGlzLmNvbmZpZy5wYXNzKSBjb25uZWN0T3B0cy5wYXNzID0gdGhpcy5jb25maWcucGFzcztcblxuXHRcdFx0dGhpcy5uYyA9IGF3YWl0IG5hdHMuY29ubmVjdChjb25uZWN0T3B0cyk7XG5cdFx0XHR0aGlzLmpzID0gdGhpcy5uYy5qZXRzdHJlYW0oKTtcblx0XHRcdHRoaXMuanNtID0gYXdhaXQgdGhpcy5uYy5qZXRzdHJlYW1NYW5hZ2VyKCk7XG5cblx0XHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0XHRcdGNvbnNvbGUubG9nKGBbTkFUU1dvcmtlckFkYXB0ZXJdIENvbm5lY3RlZCB0byBOQVRTOiAke3RoaXMuY29uZmlnLnNlcnZlcnMuam9pbihcIiwgXCIpfWApO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBGYWlsZWQgdG8gY29ubmVjdCB0byBOQVRTOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX0uIE1ha2Ugc3VyZSBuYXRzIGlzIGluc3RhbGxlZDogbnBtIGluc3RhbGwgbmF0c2AsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNjb25uZWN0IGZyb20gTkFUU1xuXHQgKi9cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cblx0XHR0cnkge1xuXHRcdFx0Ly8gU3RvcCBhbGwgY29uc3VtZSBpdGVyYXRvcnNcblx0XHRcdGZvciAoY29uc3QgWywgaXRlcl0gb2YgdGhpcy5jb25zdW1lSXRlcmF0b3JzKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0aXRlci5zdG9wKCk7XG5cdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdC8vIEl0ZXJhdG9yIG1heSBhbHJlYWR5IGJlIHN0b3BwZWRcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5jb25zdW1lSXRlcmF0b3JzLmNsZWFyKCk7XG5cdFx0XHR0aGlzLmNvbnN1bWVycy5jbGVhcigpO1xuXG5cdFx0XHRhd2FpdCB0aGlzLm5jLmRyYWluKCk7XG5cdFx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHRcdFx0Y29uc29sZS5sb2coXCJbTkFUU1dvcmtlckFkYXB0ZXJdIERpc2Nvbm5lY3RlZCBmcm9tIE5BVFNcIik7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoYFtOQVRTV29ya2VyQWRhcHRlcl0gRGlzY29ubmVjdCBlcnJvcjogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0IHByb2Nlc3Npbmcgam9icyBmcm9tIGEgcXVldWVcblx0ICovXG5cdGFzeW5jIHByb2Nlc3MoY29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cywgaGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdH1cblxuXHRcdGNvbnN0IG5hdHMgPSBhd2FpdCBpbXBvcnQoXCJuYXRzXCIpO1xuXHRcdGNvbnN0IHF1ZXVlID0gY29uZmlnLnF1ZXVlO1xuXHRcdGNvbnN0IHN0cmVhbU5hbWUgPSB0aGlzLmNvbmZpZy5zdHJlYW1OYW1lIHx8IFwiYmxvay13b3JrZXJcIjtcblx0XHRjb25zdCBzdWJqZWN0ID0gYHdvcmtlci4ke3F1ZXVlfWA7XG5cdFx0Y29uc3QgZHVyYWJsZU5hbWUgPSBgYmxvay13b3JrZXItJHtxdWV1ZX1gO1xuXG5cdFx0Ly8gRW5zdXJlIHN0cmVhbSBleGlzdHMgd2l0aCB3b3JrZXIgc3ViamVjdHNcblx0XHRhd2FpdCB0aGlzLmVuc3VyZVN0cmVhbShzdHJlYW1OYW1lLCBbc3ViamVjdF0pO1xuXG5cdFx0Ly8gQ3JlYXRlIG9yIHVwZGF0ZSBkdXJhYmxlIHB1bGwgY29uc3VtZXIgd2l0aCB3b3JrZXIgc2VtYW50aWNzXG5cdFx0Y29uc3QgYWNrV2FpdE5zID0gKChjb25maWcudGltZW91dCA/PyAzMDAwMCkgKyA1MDAwKSAqIDFfMDAwXzAwMDsgLy8gdGltZW91dCArIDVzIGJ1ZmZlciwgaW4gbmFub3NlY29uZHNcblx0XHRhd2FpdCB0aGlzLmpzbS5jb25zdW1lcnMuYWRkKHN0cmVhbU5hbWUsIHtcblx0XHRcdGR1cmFibGVfbmFtZTogZHVyYWJsZU5hbWUsXG5cdFx0XHRhY2tfcG9saWN5OiBuYXRzLkFja1BvbGljeS5FeHBsaWNpdCxcblx0XHRcdG1heF9kZWxpdmVyOiAoY29uZmlnLnJldHJpZXMgPz8gMykgKyAxLCAvLyArMSBiZWNhdXNlIGZpcnN0IGF0dGVtcHQgY291bnRzXG5cdFx0XHRhY2tfd2FpdDogYWNrV2FpdE5zLFxuXHRcdFx0ZmlsdGVyX3N1YmplY3RzOiBbc3ViamVjdF0sXG5cdFx0fSk7XG5cblx0XHQvLyBHZXQgY29uc3VtZXIgaGFuZGxlXG5cdFx0Y29uc3QgY29uc3VtZXIgPSBhd2FpdCB0aGlzLmpzLmNvbnN1bWVycy5nZXQoc3RyZWFtTmFtZSwgZHVyYWJsZU5hbWUpO1xuXHRcdHRoaXMuY29uc3VtZXJzLnNldChxdWV1ZSwgY29uc3VtZXIpO1xuXG5cdFx0Ly8gU3RhcnQgY29uc3VtaW5nXG5cdFx0Y29uc3QgaXRlciA9IGF3YWl0IGNvbnN1bWVyLmNvbnN1bWUoKTtcblx0XHR0aGlzLmNvbnN1bWVJdGVyYXRvcnMuc2V0KHF1ZXVlLCBpdGVyKTtcblxuXHRcdC8vIFByb2Nlc3Mgam9icyBpbiBiYWNrZ3JvdW5kXG5cdFx0KGFzeW5jICgpID0+IHtcblx0XHRcdGNvbnN0IHNlbWFwaG9yZSA9IG5ldyBTZW1hcGhvcmUoY29uZmlnLmNvbmN1cnJlbmN5ID8/IDEpO1xuXG5cdFx0XHRmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBpdGVyKSB7XG5cdFx0XHRcdGF3YWl0IHNlbWFwaG9yZS5hY3F1aXJlKCk7XG5cblx0XHRcdFx0Ly8gUHJvY2VzcyBlYWNoIGpvYiBjb25jdXJyZW50bHkgdXAgdG8gY29uY3VycmVuY3kgbGltaXRcblx0XHRcdFx0KGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0Ly8gUGFyc2Ugam9iIGRhdGFcblx0XHRcdFx0XHRcdGxldCBkYXRhOiB1bmtub3duO1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgY29kZWMgPSBuYXRzLkpTT05Db2RlYygpO1xuXHRcdFx0XHRcdFx0XHRkYXRhID0gY29kZWMuZGVjb2RlKG1zZy5kYXRhKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNjID0gbmF0cy5TdHJpbmdDb2RlYygpO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGEgPSBKU09OLnBhcnNlKHNjLmRlY29kZShtc2cuZGF0YSkpO1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0XHRkYXRhID0gbXNnLmRhdGE7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gRXh0cmFjdCBoZWFkZXJzXG5cdFx0XHRcdFx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdFx0XHRcdFx0XHRpZiAobXNnLmhlYWRlcnMpIHtcblx0XHRcdFx0XHRcdFx0Zm9yIChjb25zdCBba2V5LCB2YWx1ZXNdIG9mIG1zZy5oZWFkZXJzKSB7XG5cdFx0XHRcdFx0XHRcdFx0aGVhZGVyc1trZXldID0gQXJyYXkuaXNBcnJheSh2YWx1ZXMpID8gdmFsdWVzWzBdIDogdmFsdWVzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEV4dHJhY3Qgam9iIG1ldGFkYXRhIGZyb20gaGVhZGVyc1xuXHRcdFx0XHRcdFx0Y29uc3Qgam9iSWQgPSBoZWFkZXJzW1wieC1qb2ItaWRcIl0gfHwgbXNnLmhlYWRlcnM/LmdldChcIk5hdHMtTXNnLUlkXCIpIHx8IHV1aWQoKTtcblx0XHRcdFx0XHRcdGNvbnN0IHByaW9yaXR5ID0gTnVtYmVyLnBhcnNlSW50KGhlYWRlcnNbXCJ4LXByaW9yaXR5XCJdIHx8IFwiMFwiLCAxMCk7XG5cdFx0XHRcdFx0XHRjb25zdCBkZWxheSA9IE51bWJlci5wYXJzZUludChoZWFkZXJzW1wieC1kZWxheVwiXSB8fCBcIjBcIiwgMTApO1xuXHRcdFx0XHRcdFx0Y29uc3QgdGltZW91dCA9IE51bWJlci5wYXJzZUludChoZWFkZXJzW1wieC10aW1lb3V0XCJdIHx8IFwiMFwiLCAxMCk7XG5cblx0XHRcdFx0XHRcdC8vIEdldCByZWRlbGl2ZXJ5IGNvdW50IChhdHRlbXB0cylcblx0XHRcdFx0XHRcdGNvbnN0IGluZm8gPSBtc2cuaW5mbztcblx0XHRcdFx0XHRcdGNvbnN0IGF0dGVtcHRzID0gaW5mby5yZWRlbGl2ZXJ5Q291bnQgPz8gMDtcblx0XHRcdFx0XHRcdGNvbnN0IG1heFJldHJpZXMgPSBjb25maWcucmV0cmllcyA/PyAzO1xuXG5cdFx0XHRcdFx0XHQvLyBDcmVhdGUgV29ya2VySm9iXG5cdFx0XHRcdFx0XHRjb25zdCB3b3JrZXJKb2I6IFdvcmtlckpvYiA9IHtcblx0XHRcdFx0XHRcdFx0aWQ6IGpvYklkLFxuXHRcdFx0XHRcdFx0XHRkYXRhLFxuXHRcdFx0XHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRcdFx0XHRxdWV1ZSxcblx0XHRcdFx0XHRcdFx0cHJpb3JpdHksXG5cdFx0XHRcdFx0XHRcdGF0dGVtcHRzLFxuXHRcdFx0XHRcdFx0XHRtYXhSZXRyaWVzLFxuXHRcdFx0XHRcdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKFxuXHRcdFx0XHRcdFx0XHRcdGluZm8udGltZXN0YW1wTmFub3MgPyBNYXRoLmZsb29yKE51bWJlcihpbmZvLnRpbWVzdGFtcE5hbm9zKSAvIDFfMDAwXzAwMCkgOiBEYXRlLm5vdygpLFxuXHRcdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdFx0XHRkZWxheTogZGVsYXkgfHwgdW5kZWZpbmVkLFxuXHRcdFx0XHRcdFx0XHR0aW1lb3V0OiB0aW1lb3V0IHx8IGNvbmZpZy50aW1lb3V0IHx8IHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdFx0cmF3OiBtc2csXG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0bXNnLmFjaygpO1xuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRmYWlsOiBhc3luYyAoZXJyb3I6IEVycm9yLCByZXF1ZXVlPzogYm9vbGVhbikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChyZXF1ZXVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBuYWsoKSB0ZWxscyB0aGUgc2VydmVyIHRvIHJlZGVsaXZlclxuXHRcdFx0XHRcdFx0XHRcdFx0bXNnLm5haygpO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyB0ZXJtKCkgdGVybWluYXRlcyBkZWxpdmVyeSDigJQgbm8gbW9yZSByZXRyaWVzXG5cdFx0XHRcdFx0XHRcdFx0XHRtc2cudGVybSgpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRcdC8vIFRpZXIgMiBwb2xpc2gg4oCUIGVuZm9yY2UgYHgtZGVsYXlgIGhlYWRlciBvbiB0aGUgY29uc3VtZXIgc2lkZS5cblx0XHRcdFx0XHRcdC8vIE5BVFMgSmV0U3RyZWFtIHN0b3JlcyBgeC1kZWxheWAgYXMgb3BhcXVlIG1ldGFkYXRhOyB0aGUgYnJva2VyXG5cdFx0XHRcdFx0XHQvLyBkb2VzIE5PVCBkZWZlciBkZWxpdmVyeSBvbiBpdC4gV2UgaW1wbGVtZW50IGNvbnN1bWVyLXNpZGVcblx0XHRcdFx0XHRcdC8vIGhvbGRpbmcgaGVyZS4gY3JlYXRlZE1zIGlzIHRoZSBtZXNzYWdlJ3MgZmlyc3QtcHVibGlzaCB0aW1lc3RhbXA7XG5cdFx0XHRcdFx0XHQvLyBob2xkIHVudGlsIGNyZWF0ZWRNcyArIGRlbGF5LiBTaW5nbGUtcHJvY2VzcyBzZW1hbnRpY3Mg4oCUIGZvclxuXHRcdFx0XHRcdFx0Ly8gbG9uZyBkZWZlcnJhbHMsIHByZWZlciB0cmlnZ2VyLWxldmVsIGBkZWxheWAgKERlZmVycmVkUnVuU2NoZWR1bGVyKS5cblx0XHRcdFx0XHRcdGNvbnN0IGNyZWF0ZWRNcyA9IGluZm8udGltZXN0YW1wTmFub3MgPyBNYXRoLmZsb29yKE51bWJlcihpbmZvLnRpbWVzdGFtcE5hbm9zKSAvIDFfMDAwXzAwMCkgOiBEYXRlLm5vdygpO1xuXHRcdFx0XHRcdFx0Y29uc3Qgd2FpdE1zID0gY29tcHV0ZVhEZWxheUhvbGRNcyhkZWxheSwgY3JlYXRlZE1zLCBEYXRlLm5vdygpKTtcblx0XHRcdFx0XHRcdGlmICh3YWl0TXMgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHdhaXRNcykpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRhd2FpdCBoYW5kbGVyKHdvcmtlckpvYik7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoYFtOQVRTV29ya2VyQWRhcHRlcl0gRXJyb3IgcHJvY2Vzc2luZyBqb2IgZnJvbSAke3F1ZXVlfTogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRtc2cubmFrKCk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0Ly8gQWxyZWFkeSBhY2tlZC9uYWNrZWRcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0c2VtYXBob3JlLnJlbGVhc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pKCk7XG5cdFx0XHR9XG5cdFx0fSkoKTtcblxuXHRcdGNvbnNvbGUubG9nKFxuXHRcdFx0YFtOQVRTV29ya2VyQWRhcHRlcl0gUHJvY2Vzc2luZyBxdWV1ZTogJHtxdWV1ZX0gKGNvbmN1cnJlbmN5PSR7Y29uZmlnLmNvbmN1cnJlbmN5ID8/IDF9LCByZXRyaWVzPSR7Y29uZmlnLnJldHJpZXMgPz8gM30pYCxcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCBhIGpvYiB0byBhIHdvcmtlciBxdWV1ZVxuXHQgKi9cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzoge1xuXHRcdFx0cHJpb3JpdHk/OiBudW1iZXI7XG5cdFx0XHRkZWxheT86IG51bWJlcjtcblx0XHRcdHJldHJpZXM/OiBudW1iZXI7XG5cdFx0XHR0aW1lb3V0PzogbnVtYmVyO1xuXHRcdFx0am9iSWQ/OiBzdHJpbmc7XG5cdFx0fSxcblx0KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0Y29uc3QgbmF0cyA9IGF3YWl0IGltcG9ydChcIm5hdHNcIik7XG5cdFx0Y29uc3Qgc3ViamVjdCA9IGB3b3JrZXIuJHtxdWV1ZX1gO1xuXHRcdGNvbnN0IHN0cmVhbU5hbWUgPSB0aGlzLmNvbmZpZy5zdHJlYW1OYW1lIHx8IFwiYmxvay13b3JrZXJcIjtcblxuXHRcdC8vIEVuc3VyZSBzdHJlYW0gaGFzIHRoaXMgc3ViamVjdFxuXHRcdGF3YWl0IHRoaXMuZW5zdXJlU3RyZWFtKHN0cmVhbU5hbWUsIFtzdWJqZWN0XSk7XG5cblx0XHQvLyBCdWlsZCBoZWFkZXJzIHdpdGggam9iIG1ldGFkYXRhXG5cdFx0Y29uc3QgaGRycyA9IG5hdHMuaGVhZGVycygpO1xuXHRcdGNvbnN0IGpvYklkID0gb3B0cz8uam9iSWQgfHwgdXVpZCgpO1xuXHRcdGhkcnMuc2V0KFwieC1qb2ItaWRcIiwgam9iSWQpO1xuXHRcdGhkcnMuc2V0KFwiTmF0cy1Nc2ctSWRcIiwgam9iSWQpOyAvLyBEZWR1cGxpY2F0aW9uXG5cdFx0aWYgKG9wdHM/LnByaW9yaXR5KSBoZHJzLnNldChcIngtcHJpb3JpdHlcIiwgU3RyaW5nKG9wdHMucHJpb3JpdHkpKTtcblx0XHRpZiAob3B0cz8uZGVsYXkpIGhkcnMuc2V0KFwieC1kZWxheVwiLCBTdHJpbmcob3B0cy5kZWxheSkpO1xuXHRcdGlmIChvcHRzPy50aW1lb3V0KSBoZHJzLnNldChcIngtdGltZW91dFwiLCBTdHJpbmcob3B0cy50aW1lb3V0KSk7XG5cblx0XHQvLyBFbmNvZGUgYW5kIHB1Ymxpc2hcblx0XHRjb25zdCBjb2RlYyA9IG5hdHMuSlNPTkNvZGVjKCk7XG5cdFx0YXdhaXQgdGhpcy5qcy5wdWJsaXNoKHN1YmplY3QsIGNvZGVjLmVuY29kZShkYXRhKSwgeyBoZWFkZXJzOiBoZHJzIH0pO1xuXG5cdFx0cmV0dXJuIGpvYklkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN0b3AgcHJvY2Vzc2luZyBhIHNwZWNpZmljIHF1ZXVlXG5cdCAqL1xuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgaXRlciA9IHRoaXMuY29uc3VtZUl0ZXJhdG9ycy5nZXQocXVldWUpO1xuXHRcdGlmIChpdGVyKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpdGVyLnN0b3AoKTtcblx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHQvLyBBbHJlYWR5IHN0b3BwZWRcblx0XHRcdH1cblx0XHRcdHRoaXMuY29uc3VtZUl0ZXJhdG9ycy5kZWxldGUocXVldWUpO1xuXHRcdH1cblx0XHR0aGlzLmNvbnN1bWVycy5kZWxldGUocXVldWUpO1xuXHRcdGNvbnNvbGUubG9nKGBbTkFUU1dvcmtlckFkYXB0ZXJdIFN0b3BwZWQgcHJvY2Vzc2luZyBxdWV1ZTogJHtxdWV1ZX1gKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVjayBpZiBjb25uZWN0ZWRcblx0ICovXG5cdGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLmNvbm5lY3RlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBIZWFsdGggY2hlY2tcblx0ICovXG5cdGFzeW5jIGhlYWx0aENoZWNrKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMubmMpIHJldHVybiBmYWxzZTtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgaW5mbyA9IHRoaXMubmMuaW5mbztcblx0XHRcdHJldHVybiBpbmZvICE9PSB1bmRlZmluZWQ7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBxdWV1ZSBzdGF0aXN0aWNzIGZyb20gSmV0U3RyZWFtIGNvbnN1bWVyIGluZm9cblx0ICovXG5cdGFzeW5jIGdldFF1ZXVlU3RhdHMocXVldWU6IHN0cmluZyk6IFByb21pc2U8V29ya2VyUXVldWVTdGF0cz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHJldHVybiB7IHdhaXRpbmc6IDAsIGFjdGl2ZTogMCwgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGRlbGF5ZWQ6IDAgfTtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3Qgc3RyZWFtTmFtZSA9IHRoaXMuY29uZmlnLnN0cmVhbU5hbWUgfHwgXCJibG9rLXdvcmtlclwiO1xuXHRcdFx0Y29uc3QgZHVyYWJsZU5hbWUgPSBgYmxvay13b3JrZXItJHtxdWV1ZX1gO1xuXG5cdFx0XHRjb25zdCBpbmZvID0gYXdhaXQgdGhpcy5qc20uY29uc3VtZXJzLmluZm8oc3RyZWFtTmFtZSwgZHVyYWJsZU5hbWUpO1xuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHR3YWl0aW5nOiBpbmZvLm51bV9wZW5kaW5nID8/IDAsXG5cdFx0XHRcdGFjdGl2ZTogaW5mby5udW1fYWNrX3BlbmRpbmcgPz8gMCxcblx0XHRcdFx0Y29tcGxldGVkOiBpbmZvLmRlbGl2ZXJlZD8uY29uc3VtZXJfc2VxID8/IDAsXG5cdFx0XHRcdGZhaWxlZDogaW5mby5udW1fcmVkZWxpdmVyZWQgPz8gMCxcblx0XHRcdFx0ZGVsYXllZDogMCwgLy8gTkFUUyBkb2Vzbid0IGhhdmUgYSBuYXRpdmUgZGVsYXllZCBjb3VudFxuXHRcdFx0fTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybiB7IHdhaXRpbmc6IDAsIGFjdGl2ZTogMCwgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGRlbGF5ZWQ6IDAgfTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRW5zdXJlIGEgSmV0U3RyZWFtIHN0cmVhbSBleGlzdHMgd2l0aCB0aGUgZ2l2ZW4gc3ViamVjdHNcblx0ICovXG5cdHByaXZhdGUgYXN5bmMgZW5zdXJlU3RyZWFtKG5hbWU6IHN0cmluZywgc3ViamVjdHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IGluZm8gPSBhd2FpdCB0aGlzLmpzbS5zdHJlYW1zLmluZm8obmFtZSk7XG5cblx0XHRcdC8vIE1lcmdlIG5ldyBzdWJqZWN0cyB3aXRoIGV4aXN0aW5nXG5cdFx0XHRjb25zdCBleGlzdGluZ1N1YmplY3RzID0gaW5mby5jb25maWcuc3ViamVjdHMgfHwgW107XG5cdFx0XHRjb25zdCBhbGxTdWJqZWN0cyA9IFsuLi5uZXcgU2V0KFsuLi5leGlzdGluZ1N1YmplY3RzLCAuLi5zdWJqZWN0c10pXTtcblxuXHRcdFx0aWYgKGFsbFN1YmplY3RzLmxlbmd0aCAhPT0gZXhpc3RpbmdTdWJqZWN0cy5sZW5ndGgpIHtcblx0XHRcdFx0YXdhaXQgdGhpcy5qc20uc3RyZWFtcy51cGRhdGUobmFtZSwge1xuXHRcdFx0XHRcdC4uLmluZm8uY29uZmlnLFxuXHRcdFx0XHRcdHN1YmplY3RzOiBhbGxTdWJqZWN0cyxcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHQvLyBTdHJlYW0gZG9lc24ndCBleGlzdCwgY3JlYXRlIGl0XG5cdFx0XHRhd2FpdCB0aGlzLmpzbS5zdHJlYW1zLmFkZCh7XG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdHN1YmplY3RzLFxuXHRcdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IG5hdHMgSmV0U3RyZWFtIHJldGVudGlvbiBwb2xpY3kgZW51bVxuXHRcdFx0XHRyZXRlbnRpb246IFwid29ya3F1ZXVlXCIgYXMgYW55LFxuXHRcdFx0XHRtYXhfZGVsaXZlcjogNCwgLy8gZGVmYXVsdDogMyByZXRyaWVzICsgMSBpbml0aWFsIGF0dGVtcHRcblx0XHRcdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBuYXRzIEpldFN0cmVhbSBzdG9yYWdlIHR5cGUgZW51bVxuXHRcdFx0XHRzdG9yYWdlOiBcImZpbGVcIiBhcyBhbnksXG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBTaW1wbGUgc2VtYXBob3JlIGZvciBjb25jdXJyZW5jeSBjb250cm9sXG4gKi9cbmNsYXNzIFNlbWFwaG9yZSB7XG5cdHByaXZhdGUgcGVybWl0czogbnVtYmVyO1xuXHRwcml2YXRlIHdhaXRpbmc6IEFycmF5PCgpID0+IHZvaWQ+ID0gW107XG5cblx0Y29uc3RydWN0b3IocGVybWl0czogbnVtYmVyKSB7XG5cdFx0dGhpcy5wZXJtaXRzID0gcGVybWl0cztcblx0fVxuXG5cdGFzeW5jIGFjcXVpcmUoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMucGVybWl0cyA+IDApIHtcblx0XHRcdHRoaXMucGVybWl0cy0tO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRyZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcblx0XHRcdHRoaXMud2FpdGluZy5wdXNoKHJlc29sdmUpO1xuXHRcdH0pO1xuXHR9XG5cblx0cmVsZWFzZSgpOiB2b2lkIHtcblx0XHRjb25zdCBuZXh0ID0gdGhpcy53YWl0aW5nLnNoaWZ0KCk7XG5cdFx0aWYgKG5leHQpIHtcblx0XHRcdG5leHQoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wZXJtaXRzKys7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE5BVFNXb3JrZXJBZGFwdGVyO1xuIl19
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PgBossAdapter — v0.7 PR 5 — Worker adapter backed by `pg-boss`,
|
|
3
|
+
* which stores jobs in PostgreSQL. Operationally attractive when
|
|
4
|
+
* Postgres is already in the stack — no extra broker infra needed.
|
|
5
|
+
*
|
|
6
|
+
* Semantics:
|
|
7
|
+
* - `pg-boss` handles concurrency, retries, dead-letter, priority,
|
|
8
|
+
* delays, and exactly-once scheduling natively — the adapter
|
|
9
|
+
* forwards `config.concurrency`, `config.retries`, etc. to the
|
|
10
|
+
* `boss.work(queue, opts, handler)` and `boss.send(queue, data, opts)`
|
|
11
|
+
* calls directly.
|
|
12
|
+
* - **Single connection per process** — `pg-boss` manages its own
|
|
13
|
+
* pool; we instantiate one `PgBoss` instance per `PgBossAdapter`.
|
|
14
|
+
* - **Schema**: `pg-boss` creates its own schema (`pgboss` by
|
|
15
|
+
* default) on first start. Tables are migrated automatically.
|
|
16
|
+
*
|
|
17
|
+
* Requires `pg-boss` as a peer dependency:
|
|
18
|
+
*
|
|
19
|
+
* bun add pg-boss
|
|
20
|
+
*
|
|
21
|
+
* Environment variables:
|
|
22
|
+
* - `DATABASE_URL` — Postgres connection string (default
|
|
23
|
+
* `postgres://localhost:5432/blok`).
|
|
24
|
+
* - `PG_BOSS_SCHEMA` — schema name (default `"pgboss"`).
|
|
25
|
+
*/
|
|
26
|
+
import type { WorkerTriggerOpts } from "@blokjs/helper";
|
|
27
|
+
import type { WorkerAdapter, WorkerJob, WorkerQueueStats } from "../WorkerTrigger";
|
|
28
|
+
export interface PgBossConfig {
|
|
29
|
+
connectionString: string;
|
|
30
|
+
schema?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class PgBossAdapter implements WorkerAdapter {
|
|
33
|
+
readonly provider: "pg-boss";
|
|
34
|
+
private readonly config;
|
|
35
|
+
private boss;
|
|
36
|
+
private workIds;
|
|
37
|
+
private connected;
|
|
38
|
+
private stats;
|
|
39
|
+
constructor(config?: Partial<PgBossConfig>);
|
|
40
|
+
connect(): Promise<void>;
|
|
41
|
+
disconnect(): Promise<void>;
|
|
42
|
+
process(config: WorkerTriggerOpts, handler: (job: WorkerJob) => Promise<void>): Promise<void>;
|
|
43
|
+
private runOneJob;
|
|
44
|
+
private ensureQueue;
|
|
45
|
+
addJob(queue: string, data: unknown, opts?: {
|
|
46
|
+
priority?: number;
|
|
47
|
+
delay?: number;
|
|
48
|
+
retries?: number;
|
|
49
|
+
timeout?: number;
|
|
50
|
+
jobId?: string;
|
|
51
|
+
}): Promise<string>;
|
|
52
|
+
stopProcessing(queue: string): Promise<void>;
|
|
53
|
+
isConnected(): boolean;
|
|
54
|
+
healthCheck(): Promise<boolean>;
|
|
55
|
+
getQueueStats(queue: string): Promise<WorkerQueueStats>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PgBossAdapter — v0.7 PR 5 — Worker adapter backed by `pg-boss`,
|
|
3
|
+
* which stores jobs in PostgreSQL. Operationally attractive when
|
|
4
|
+
* Postgres is already in the stack — no extra broker infra needed.
|
|
5
|
+
*
|
|
6
|
+
* Semantics:
|
|
7
|
+
* - `pg-boss` handles concurrency, retries, dead-letter, priority,
|
|
8
|
+
* delays, and exactly-once scheduling natively — the adapter
|
|
9
|
+
* forwards `config.concurrency`, `config.retries`, etc. to the
|
|
10
|
+
* `boss.work(queue, opts, handler)` and `boss.send(queue, data, opts)`
|
|
11
|
+
* calls directly.
|
|
12
|
+
* - **Single connection per process** — `pg-boss` manages its own
|
|
13
|
+
* pool; we instantiate one `PgBoss` instance per `PgBossAdapter`.
|
|
14
|
+
* - **Schema**: `pg-boss` creates its own schema (`pgboss` by
|
|
15
|
+
* default) on first start. Tables are migrated automatically.
|
|
16
|
+
*
|
|
17
|
+
* Requires `pg-boss` as a peer dependency:
|
|
18
|
+
*
|
|
19
|
+
* bun add pg-boss
|
|
20
|
+
*
|
|
21
|
+
* Environment variables:
|
|
22
|
+
* - `DATABASE_URL` — Postgres connection string (default
|
|
23
|
+
* `postgres://localhost:5432/blok`).
|
|
24
|
+
* - `PG_BOSS_SCHEMA` — schema name (default `"pgboss"`).
|
|
25
|
+
*/
|
|
26
|
+
import { v4 as uuid } from "uuid";
|
|
27
|
+
export class PgBossAdapter {
|
|
28
|
+
provider = "pg-boss";
|
|
29
|
+
config;
|
|
30
|
+
boss = null;
|
|
31
|
+
workIds = new Map();
|
|
32
|
+
connected = false;
|
|
33
|
+
stats = new Map();
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = {
|
|
36
|
+
connectionString: config?.connectionString ?? process.env.DATABASE_URL ?? "postgres://localhost:5432/blok",
|
|
37
|
+
schema: config?.schema ?? process.env.PG_BOSS_SCHEMA ?? "pgboss",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async connect() {
|
|
41
|
+
if (this.connected)
|
|
42
|
+
return;
|
|
43
|
+
try {
|
|
44
|
+
// Indirect specifier so tsc doesn't try to resolve types for
|
|
45
|
+
// the optional peer dependency at build time.
|
|
46
|
+
const moduleName = "pg-boss";
|
|
47
|
+
// biome-ignore lint/suspicious/noExplicitAny: pg-boss is a runtime peer dep.
|
|
48
|
+
const mod = await import(moduleName);
|
|
49
|
+
// biome-ignore lint/suspicious/noExplicitAny: pg-boss is a runtime peer dep.
|
|
50
|
+
const PgBoss = mod.default ?? mod;
|
|
51
|
+
this.boss = new PgBoss({
|
|
52
|
+
connectionString: this.config.connectionString,
|
|
53
|
+
schema: this.config.schema,
|
|
54
|
+
});
|
|
55
|
+
await this.boss.start();
|
|
56
|
+
this.connected = true;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
throw new Error(`[blok][pg-boss] connect failed: ${err.message}. Install pg-boss as a peer dependency: bun add pg-boss`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async disconnect() {
|
|
63
|
+
if (!this.connected)
|
|
64
|
+
return;
|
|
65
|
+
try {
|
|
66
|
+
await this.boss?.stop({ graceful: true });
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* ignore */
|
|
70
|
+
}
|
|
71
|
+
this.workIds.clear();
|
|
72
|
+
this.boss = null;
|
|
73
|
+
this.connected = false;
|
|
74
|
+
}
|
|
75
|
+
async process(config, handler) {
|
|
76
|
+
if (!this.connected || !this.boss)
|
|
77
|
+
throw new Error("[blok][pg-boss] not connected. Call connect() first.");
|
|
78
|
+
this.stats.set(config.queue, { completed: 0, failed: 0, active: 0 });
|
|
79
|
+
const stats = this.stats.get(config.queue);
|
|
80
|
+
// pg-boss v10 requires explicit queue creation before send/work.
|
|
81
|
+
// The call is idempotent — succeeds whether the queue exists or
|
|
82
|
+
// not — so this is safe to repeat across re-entries.
|
|
83
|
+
await this.ensureQueue(config.queue);
|
|
84
|
+
// pg-boss v10's handler receives an ARRAY of jobs (batch); the
|
|
85
|
+
// `batchSize` option controls the max. We keep `batchSize: 1` so
|
|
86
|
+
// the iteration is a single-job loop (matches pre-v10 semantics
|
|
87
|
+
// the adapter was written against). `pollingIntervalSeconds`
|
|
88
|
+
// defaults to 2s which adds ~2s latency on the happy path —
|
|
89
|
+
// tighten it for low-latency workloads via the worker config.
|
|
90
|
+
const id = await this.boss.work(config.queue, {
|
|
91
|
+
batchSize: 1,
|
|
92
|
+
includeMetadata: true,
|
|
93
|
+
}, async (jobOrBatch) => {
|
|
94
|
+
const jobs = Array.isArray(jobOrBatch) ? jobOrBatch : [jobOrBatch];
|
|
95
|
+
for (const job of jobs) {
|
|
96
|
+
await this.runOneJob(config, handler, stats, job);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
this.workIds.set(config.queue, id);
|
|
100
|
+
}
|
|
101
|
+
async runOneJob(config, handler, stats, job) {
|
|
102
|
+
stats.active += 1;
|
|
103
|
+
// Tracks whether stats have already been counted by the
|
|
104
|
+
// WorkerJob API (`complete` / `fail`). Without this, both
|
|
105
|
+
// the callback and the wrapper's try/catch credit the same
|
|
106
|
+
// outcome, double-counting `stats.completed` /
|
|
107
|
+
// `stats.failed`. pg-boss itself handles ack/retry/DLQ via
|
|
108
|
+
// the handler's return-vs-throw — these callbacks exist
|
|
109
|
+
// purely for stats parity with the other worker adapters.
|
|
110
|
+
let settled = false;
|
|
111
|
+
const workerJob = {
|
|
112
|
+
id: job.id,
|
|
113
|
+
data: job.data,
|
|
114
|
+
headers: {},
|
|
115
|
+
queue: config.queue,
|
|
116
|
+
priority: config.priority ?? 0,
|
|
117
|
+
attempts: 0,
|
|
118
|
+
maxRetries: config.retries ?? 0,
|
|
119
|
+
createdAt: new Date(),
|
|
120
|
+
timeout: config.timeout,
|
|
121
|
+
raw: job,
|
|
122
|
+
complete: async () => {
|
|
123
|
+
if (settled)
|
|
124
|
+
return;
|
|
125
|
+
stats.completed += 1;
|
|
126
|
+
settled = true;
|
|
127
|
+
},
|
|
128
|
+
fail: async (err) => {
|
|
129
|
+
if (settled)
|
|
130
|
+
return;
|
|
131
|
+
stats.failed += 1;
|
|
132
|
+
settled = true;
|
|
133
|
+
// Re-throw so pg-boss's `boss.work` sees the handler
|
|
134
|
+
// failure and schedules a retry / drops to DLQ per
|
|
135
|
+
// the queue config — the contract is "handler throws
|
|
136
|
+
// => job failed".
|
|
137
|
+
throw err;
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
try {
|
|
141
|
+
await handler(workerJob);
|
|
142
|
+
if (!settled) {
|
|
143
|
+
stats.completed += 1;
|
|
144
|
+
settled = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
if (!settled) {
|
|
149
|
+
stats.failed += 1;
|
|
150
|
+
settled = true;
|
|
151
|
+
}
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
stats.active = Math.max(0, stats.active - 1);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async ensureQueue(queue) {
|
|
159
|
+
if (!this.boss)
|
|
160
|
+
return;
|
|
161
|
+
try {
|
|
162
|
+
await this.boss.createQueue(queue);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
// pg-boss v10's createQueue is idempotent but may throw on
|
|
166
|
+
// race conditions when multiple processes call it concurrently
|
|
167
|
+
// against a fresh schema — those errors are harmless once the
|
|
168
|
+
// queue exists. Swallow + let downstream send/work surface a
|
|
169
|
+
// real problem if the queue isn't usable.
|
|
170
|
+
const message = err.message ?? "";
|
|
171
|
+
if (!message.includes("already exists")) {
|
|
172
|
+
// Log the unexpected case but don't propagate — operators
|
|
173
|
+
// shouldn't see a queue-creation race blow up their
|
|
174
|
+
// trigger boot path.
|
|
175
|
+
console.warn(`[blok][pg-boss] ensureQueue(${queue}) warning:`, message);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async addJob(queue, data, opts) {
|
|
180
|
+
if (!this.connected || !this.boss)
|
|
181
|
+
throw new Error("[blok][pg-boss] not connected. Call connect() first.");
|
|
182
|
+
// pg-boss v10 requires the queue to exist before send. The
|
|
183
|
+
// call is idempotent — cheap to repeat per add.
|
|
184
|
+
await this.ensureQueue(queue);
|
|
185
|
+
// pg-boss v10's `attorney.checkSendArgs` rejects any explicitly
|
|
186
|
+
// undefined `priority` / `retryLimit` / `startAfter` /
|
|
187
|
+
// `expireInSeconds` / `singletonKey` with "X must be an integer".
|
|
188
|
+
// Build the options object with only the keys we actually want
|
|
189
|
+
// set — caught by the real-broker integration test in
|
|
190
|
+
// `__tests__/integration/pgboss-adapter.real-pg.test.ts`.
|
|
191
|
+
const sendOpts = {};
|
|
192
|
+
if (typeof opts?.priority === "number")
|
|
193
|
+
sendOpts.priority = opts.priority;
|
|
194
|
+
if (typeof opts?.delay === "number" && opts.delay > 0) {
|
|
195
|
+
sendOpts.startAfter = Math.ceil(opts.delay / 1000);
|
|
196
|
+
}
|
|
197
|
+
if (typeof opts?.retries === "number")
|
|
198
|
+
sendOpts.retryLimit = opts.retries;
|
|
199
|
+
if (typeof opts?.timeout === "number")
|
|
200
|
+
sendOpts.expireInSeconds = Math.ceil(opts.timeout / 1000);
|
|
201
|
+
if (typeof opts?.jobId === "string" && opts.jobId.length > 0)
|
|
202
|
+
sendOpts.singletonKey = opts.jobId;
|
|
203
|
+
const jobId = await this.boss.send(queue, data, sendOpts);
|
|
204
|
+
return jobId ?? opts?.jobId ?? uuid();
|
|
205
|
+
}
|
|
206
|
+
async stopProcessing(queue) {
|
|
207
|
+
if (!this.connected || !this.boss)
|
|
208
|
+
return;
|
|
209
|
+
try {
|
|
210
|
+
await this.boss.offWork(queue);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
/* ignore */
|
|
214
|
+
}
|
|
215
|
+
this.workIds.delete(queue);
|
|
216
|
+
}
|
|
217
|
+
isConnected() {
|
|
218
|
+
return this.connected;
|
|
219
|
+
}
|
|
220
|
+
async healthCheck() {
|
|
221
|
+
if (!this.connected || !this.boss)
|
|
222
|
+
return false;
|
|
223
|
+
try {
|
|
224
|
+
await this.boss.getQueueSize("__health_check__");
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// getQueueSize on a non-existent queue may throw — fall back to
|
|
229
|
+
// "connection is live" by checking the boss instance attribute.
|
|
230
|
+
return this.connected;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async getQueueStats(queue) {
|
|
234
|
+
const counters = this.stats.get(queue) ?? { completed: 0, failed: 0, active: 0 };
|
|
235
|
+
let waiting = 0;
|
|
236
|
+
try {
|
|
237
|
+
waiting = (await this.boss?.getQueueSize(queue)) ?? 0;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
/* ignore */
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
waiting,
|
|
244
|
+
active: counters.active,
|
|
245
|
+
completed: counters.completed,
|
|
246
|
+
failed: counters.failed,
|
|
247
|
+
delayed: 0,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGdCb3NzQWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9QZ0Jvc3NBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWtDbEMsTUFBTSxPQUFPLGFBQWE7SUFDaEIsUUFBUSxHQUFHLFNBQWtCLENBQUM7SUFDdEIsTUFBTSxDQUFlO0lBQzlCLElBQUksR0FBMEIsSUFBSSxDQUFDO0lBQ25DLE9BQU8sR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUN6QyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLEtBQUssR0FBb0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUUzRCxZQUFZLE1BQThCO1FBQ3pDLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDYixnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsZ0JBQWdCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksZ0NBQWdDO1lBQzFHLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLFFBQVE7U0FDaEUsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTztRQUNaLElBQUksSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPO1FBQzNCLElBQUksQ0FBQztZQUNKLDZEQUE2RDtZQUM3RCw4Q0FBOEM7WUFDOUMsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO1lBQzdCLDZFQUE2RTtZQUM3RSxNQUFNLEdBQUcsR0FBUSxNQUFNLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMxQyw2RUFBNkU7WUFDN0UsTUFBTSxNQUFNLEdBQVEsR0FBRyxDQUFDLE9BQU8sSUFBSSxHQUFHLENBQUM7WUFDdkMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJ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LE9BQU8sR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNSLFlBQVk7UUFDYixDQUFDO1FBQ0QsT0FBTztZQUNOLE9BQU87WUFDUCxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDdkIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTO1lBQzdCLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtZQUN2QixPQUFPLEVBQUUsQ0FBQztTQUNWLENBQUM7SUFDSCxDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBnQm9zc0FkYXB0ZXIg4oCUIHYwLjcgUFIgNSDigJQgV29ya2VyIGFkYXB0ZXIgYmFja2VkIGJ5IGBwZy1ib3NzYCxcbiAqIHdoaWNoIHN0b3JlcyBqb2JzIGluIFBvc3RncmVTUUwuIE9wZXJhdGlvbmFsbHkgYXR0cmFjdGl2ZSB3aGVuXG4gKiBQb3N0Z3JlcyBpcyBhbHJlYWR5IGluIHRoZSBzdGFjayDigJQgbm8gZXh0cmEgYnJva2VyIGluZnJhIG5lZWRlZC5cbiAqXG4gKiBTZW1hbnRpY3M6XG4gKiAgIC0gYHBnLWJvc3NgIGhhbmRsZXMgY29uY3VycmVuY3ksIHJldHJpZXMsIGRlYWQtbGV0dGVyLCBwcmlvcml0eSxcbiAqICAgICBkZWxheXMsIGFuZCBleGFjdGx5LW9uY2Ugc2NoZWR1bGluZyBuYXRpdmVseSDigJQgdGhlIGFkYXB0ZXJcbiAqICAgICBmb3J3YXJkcyBgY29uZmlnLmNvbmN1cnJlbmN5YCwgYGNvbmZpZy5yZXRyaWVzYCwgZXRjLiB0byB0aGVcbiAqICAgICBgYm9zcy53b3JrKHF1ZXVlLCBvcHRzLCBoYW5kbGVyKWAgYW5kIGBib3NzLnNlbmQocXVldWUsIGRhdGEsIG9wdHMpYFxuICogICAgIGNhbGxzIGRpcmVjdGx5LlxuICogICAtICoqU2luZ2xlIGNvbm5lY3Rpb24gcGVyIHByb2Nlc3MqKiDigJQgYHBnLWJvc3NgIG1hbmFnZXMgaXRzIG93blxuICogICAgIHBvb2w7IHdlIGluc3RhbnRpYXRlIG9uZSBgUGdCb3NzYCBpbnN0YW5jZSBwZXIgYFBnQm9zc0FkYXB0ZXJgLlxuICogICAtICoqU2NoZW1hKio6IGBwZy1ib3NzYCBjcmVhdGVzIGl0cyBvd24gc2NoZW1hIChgcGdib3NzYCBieVxuICogICAgIGRlZmF1bHQpIG9uIGZpcnN0IHN0YXJ0LiBUYWJsZXMgYXJlIG1pZ3JhdGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogUmVxdWlyZXMgYHBnLWJvc3NgIGFzIGEgcGVlciBkZXBlbmRlbmN5OlxuICpcbiAqICAgICBidW4gYWRkIHBnLWJvc3NcbiAqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gKiAgIC0gYERBVEFCQVNFX1VSTGAg4oCUIFBvc3RncmVzIGNvbm5lY3Rpb24gc3RyaW5nIChkZWZhdWx0XG4gKiAgICAgYHBvc3RncmVzOi8vbG9jYWxob3N0OjU0MzIvYmxva2ApLlxuICogICAtIGBQR19CT1NTX1NDSEVNQWAg4oCUIHNjaGVtYSBuYW1lIChkZWZhdWx0IGBcInBnYm9zc1wiYCkuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBXb3JrZXJUcmlnZ2VyT3B0cyB9IGZyb20gXCJAYmxva2pzL2hlbHBlclwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtlckFkYXB0ZXIsIFdvcmtlckpvYiwgV29ya2VyUXVldWVTdGF0cyB9IGZyb20gXCIuLi9Xb3JrZXJUcmlnZ2VyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGdCb3NzQ29uZmlnIHtcblx0Y29ubmVjdGlvblN0cmluZzogc3RyaW5nO1xuXHRzY2hlbWE/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBQZ0Jvc3NJbnN0YW5jZSB7XG5cdHN0YXJ0KCk6IFByb21pc2U8dW5rbm93bj47XG5cdHN0b3Aob3B0cz86IHsgZ3JhY2VmdWw/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+O1xuXHRjcmVhdGVRdWV1ZShxdWV1ZTogc3RyaW5nLCBvcHRzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPHVua25vd24+O1xuXHRzZW5kKHF1ZXVlOiBzdHJpbmcsIGRhdGE6IHVua25vd24sIG9wdHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFByb21pc2U8c3RyaW5nIHwgbnVsbD47XG5cdHdvcmsoXG5cdFx0cXVldWU6IHN0cmluZyxcblx0XHRvcHRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcblx0XHRoYW5kbGVyOiAoam9iOiBQZ0Jvc3NKb2IgfCBQZ0Jvc3NKb2JbXSkgPT4gUHJvbWlzZTx1bmtub3duPixcblx0KTogUHJvbWlzZTxzdHJpbmc+O1xuXHRvZmZXb3JrKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuXHRnZXRRdWV1ZVNpemUocXVldWU6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcbn1cblxuaW50ZXJmYWNlIFBnQm9zc0pvYiB7XG5cdGlkOiBzdHJpbmc7XG5cdGRhdGE6IHVua25vd247XG5cdG5hbWU6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFF1ZXVlU3RhdHNDb3VudGVycyB7XG5cdGNvbXBsZXRlZDogbnVtYmVyO1xuXHRmYWlsZWQ6IG51bWJlcjtcblx0YWN0aXZlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBQZ0Jvc3NBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJwZy1ib3NzXCIgYXMgY29uc3Q7XG5cdHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBQZ0Jvc3NDb25maWc7XG5cdHByaXZhdGUgYm9zczogUGdCb3NzSW5zdGFuY2UgfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSB3b3JrSWRzOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIGNvbm5lY3RlZCA9IGZhbHNlO1xuXHRwcml2YXRlIHN0YXRzOiBNYXA8c3RyaW5nLCBRdWV1ZVN0YXRzQ291bnRlcnM+ID0gbmV3IE1hcCgpO1xuXG5cdGNvbnN0cnVjdG9yKGNvbmZpZz86IFBhcnRpYWw8UGdCb3NzQ29uZmlnPikge1xuXHRcdHRoaXMuY29uZmlnID0ge1xuXHRcdFx0Y29ubmVjdGlvblN0cmluZzogY29uZmlnPy5jb25uZWN0aW9uU3RyaW5nID8/IHByb2Nlc3MuZW52LkRBVEFCQVNFX1VSTCA/PyBcInBvc3RncmVzOi8vbG9jYWxob3N0OjU0MzIvYmxva1wiLFxuXHRcdFx0c2NoZW1hOiBjb25maWc/LnNjaGVtYSA/PyBwcm9jZXNzLmVudi5QR19CT1NTX1NDSEVNQSA/PyBcInBnYm9zc1wiLFxuXHRcdH07XG5cdH1cblxuXHRhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh0aGlzLmNvbm5lY3RlZCkgcmV0dXJuO1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBJbmRpcmVjdCBzcGVjaWZpZXIgc28gdHNjIGRvZXNuJ3QgdHJ5IHRvIHJlc29sdmUgdHlwZXMgZm9yXG5cdFx0XHQvLyB0aGUgb3B0aW9uYWwgcGVlciBkZXBlbmRlbmN5IGF0IGJ1aWxkIHRpbWUuXG5cdFx0XHRjb25zdCBtb2R1bGVOYW1lID0gXCJwZy1ib3NzXCI7XG5cdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IHBnLWJvc3MgaXMgYSBydW50aW1lIHBlZXIgZGVwLlxuXHRcdFx0Y29uc3QgbW9kOiBhbnkgPSBhd2FpdCBpbXBvcnQobW9kdWxlTmFtZSk7XG5cdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IHBnLWJvc3MgaXMgYSBydW50aW1lIHBlZXIgZGVwLlxuXHRcdFx0Y29uc3QgUGdCb3NzOiBhbnkgPSBtb2QuZGVmYXVsdCA/PyBtb2Q7XG5cdFx0XHR0aGlzLmJvc3MgPSBuZXcgUGdCb3NzKHtcblx0XHRcdFx0Y29ubmVjdGlvblN0cmluZzogdGhpcy5jb25maWcuY29ubmVjdGlvblN0cmluZyxcblx0XHRcdFx0c2NoZW1hOiB0aGlzLmNvbmZpZy5zY2hlbWEsXG5cdFx0XHR9KSBhcyBQZ0Jvc3NJbnN0YW5jZTtcblx0XHRcdGF3YWl0IHRoaXMuYm9zcy5zdGFydCgpO1xuXHRcdFx0dGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgW2Jsb2tdW3BnLWJvc3NdIGNvbm5lY3QgZmFpbGVkOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9LiBJbnN0YWxsIHBnLWJvc3MgYXMgYSBwZWVyIGRlcGVuZGVuY3k6IGJ1biBhZGQgcGctYm9zc2AsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkgcmV0dXJuO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmJvc3M/LnN0b3AoeyBncmFjZWZ1bDogdHJ1ZSB9KTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8qIGlnbm9yZSAqL1xuXHRcdH1cblx0XHR0aGlzLndvcmtJZHMuY2xlYXIoKTtcblx0XHR0aGlzLmJvc3MgPSBudWxsO1xuXHRcdHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG5cdH1cblxuXHRhc3luYyBwcm9jZXNzKGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsIGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMuYm9zcykgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW3BnLWJvc3NdIG5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR0aGlzLnN0YXRzLnNldChjb25maWcucXVldWUsIHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9KTtcblx0XHRjb25zdCBzdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KGNvbmZpZy5xdWV1ZSkgYXMgUXVldWVTdGF0c0NvdW50ZXJzO1xuXG5cdFx0Ly8gcGctYm9zcyB2MTAgcmVxdWlyZXMgZXhwbGljaXQgcXVldWUgY3JlYXRpb24gYmVmb3JlIHNlbmQvd29yay5cblx0XHQvLyBUaGUgY2FsbCBpcyBpZGVtcG90ZW50IOKAlCBzdWNjZWVkcyB3aGV0aGVyIHRoZSBxdWV1ZSBleGlzdHMgb3Jcblx0XHQvLyBub3Qg4oCUIHNvIHRoaXMgaXMgc2FmZSB0byByZXBlYXQgYWNyb3NzIHJlLWVudHJpZXMuXG5cdFx0YXdhaXQgdGhpcy5lbnN1cmVRdWV1ZShjb25maWcucXVldWUpO1xuXG5cdFx0Ly8gcGctYm9zcyB2MTAncyBoYW5kbGVyIHJlY2VpdmVzIGFuIEFSUkFZIG9mIGpvYnMgKGJhdGNoKTsgdGhlXG5cdFx0Ly8gYGJhdGNoU2l6ZWAgb3B0aW9uIGNvbnRyb2xzIHRoZSBtYXguIFdlIGtlZXAgYGJhdGNoU2l6ZTogMWAgc29cblx0XHQvLyB0aGUgaXRlcmF0aW9uIGlzIGEgc2luZ2xlLWpvYiBsb29wIChtYXRjaGVzIHByZS12MTAgc2VtYW50aWNzXG5cdFx0Ly8gdGhlIGFkYXB0ZXIgd2FzIHdyaXR0ZW4gYWdhaW5zdCkuIGBwb2xsaW5nSW50ZXJ2YWxTZWNvbmRzYFxuXHRcdC8vIGRlZmF1bHRzIHRvIDJzIHdoaWNoIGFkZHMgfjJzIGxhdGVuY3kgb24gdGhlIGhhcHB5IHBhdGgg4oCUXG5cdFx0Ly8gdGlnaHRlbiBpdCBmb3IgbG93LWxhdGVuY3kgd29ya2xvYWRzIHZpYSB0aGUgd29ya2VyIGNvbmZpZy5cblx0XHRjb25zdCBpZCA9IGF3YWl0IHRoaXMuYm9zcy53b3JrKFxuXHRcdFx0Y29uZmlnLnF1ZXVlLFxuXHRcdFx0e1xuXHRcdFx0XHRiYXRjaFNpemU6IDEsXG5cdFx0XHRcdGluY2x1ZGVNZXRhZGF0YTogdHJ1ZSxcblx0XHRcdH0sXG5cdFx0XHRhc3luYyAoam9iT3JCYXRjaCkgPT4ge1xuXHRcdFx0XHRjb25zdCBqb2JzID0gQXJyYXkuaXNBcnJheShqb2JPckJhdGNoKSA/IGpvYk9yQmF0Y2ggOiBbam9iT3JCYXRjaF07XG5cdFx0XHRcdGZvciAoY29uc3Qgam9iIG9mIGpvYnMpIHtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnJ1bk9uZUpvYihjb25maWcsIGhhbmRsZXIsIHN0YXRzLCBqb2IpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdCk7XG5cdFx0dGhpcy53b3JrSWRzLnNldChjb25maWcucXVldWUsIGlkKTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgcnVuT25lSm9iKFxuXHRcdGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsXG5cdFx0aGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+LFxuXHRcdHN0YXRzOiBRdWV1ZVN0YXRzQ291bnRlcnMsXG5cdFx0am9iOiBQZ0Jvc3NKb2IsXG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdHN0YXRzLmFjdGl2ZSArPSAxO1xuXHRcdC8vIFRyYWNrcyB3aGV0aGVyIHN0YXRzIGhhdmUgYWxyZWFkeSBiZWVuIGNvdW50ZWQgYnkgdGhlXG5cdFx0Ly8gV29ya2VySm9iIEFQSSAoYGNvbXBsZXRlYCAvIGBmYWlsYCkuIFdpdGhvdXQgdGhpcywgYm90aFxuXHRcdC8vIHRoZSBjYWxsYmFjayBhbmQgdGhlIHdyYXBwZXIncyB0cnkvY2F0Y2ggY3JlZGl0IHRoZSBzYW1lXG5cdFx0Ly8gb3V0Y29tZSwgZG91YmxlLWNvdW50aW5nIGBzdGF0cy5jb21wbGV0ZWRgIC9cblx0XHQvLyBgc3RhdHMuZmFpbGVkYC4gcGctYm9zcyBpdHNlbGYgaGFuZGxlcyBhY2svcmV0cnkvRExRIHZpYVxuXHRcdC8vIHRoZSBoYW5kbGVyJ3MgcmV0dXJuLXZzLXRocm93IOKAlCB0aGVzZSBjYWxsYmFja3MgZXhpc3Rcblx0XHQvLyBwdXJlbHkgZm9yIHN0YXRzIHBhcml0eSB3aXRoIHRoZSBvdGhlciB3b3JrZXIgYWRhcHRlcnMuXG5cdFx0bGV0IHNldHRsZWQgPSBmYWxzZTtcblx0XHRjb25zdCB3b3JrZXJKb2I6IFdvcmtlckpvYiA9IHtcblx0XHRcdGlkOiBqb2IuaWQsXG5cdFx0XHRkYXRhOiBqb2IuZGF0YSxcblx0XHRcdGhlYWRlcnM6IHt9LFxuXHRcdFx0cXVldWU6IGNvbmZpZy5xdWV1ZSxcblx0XHRcdHByaW9yaXR5OiBjb25maWcucHJpb3JpdHkgPz8gMCxcblx0XHRcdGF0dGVtcHRzOiAwLFxuXHRcdFx0bWF4UmV0cmllczogY29uZmlnLnJldHJpZXMgPz8gMCxcblx0XHRcdGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcblx0XHRcdHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0LFxuXHRcdFx0cmF3OiBqb2IsXG5cdFx0XHRjb21wbGV0ZTogYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpZiAoc2V0dGxlZCkgcmV0dXJuO1xuXHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0c2V0dGxlZCA9IHRydWU7XG5cdFx0XHR9LFxuXHRcdFx0ZmFpbDogYXN5bmMgKGVycjogRXJyb3IpID0+IHtcblx0XHRcdFx0aWYgKHNldHRsZWQpIHJldHVybjtcblx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdHNldHRsZWQgPSB0cnVlO1xuXHRcdFx0XHQvLyBSZS10aHJvdyBzbyBwZy1ib3NzJ3MgYGJvc3Mud29ya2Agc2VlcyB0aGUgaGFuZGxlclxuXHRcdFx0XHQvLyBmYWlsdXJlIGFuZCBzY2hlZHVsZXMgYSByZXRyeSAvIGRyb3BzIHRvIERMUSBwZXJcblx0XHRcdFx0Ly8gdGhlIHF1ZXVlIGNvbmZpZyDigJQgdGhlIGNvbnRyYWN0IGlzIFwiaGFuZGxlciB0aHJvd3Ncblx0XHRcdFx0Ly8gPT4gam9iIGZhaWxlZFwiLlxuXHRcdFx0XHR0aHJvdyBlcnI7XG5cdFx0XHR9LFxuXHRcdH07XG5cdFx0dHJ5IHtcblx0XHRcdGF3YWl0IGhhbmRsZXIod29ya2VySm9iKTtcblx0XHRcdGlmICghc2V0dGxlZCkge1xuXHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0c2V0dGxlZCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRpZiAoIXNldHRsZWQpIHtcblx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdHNldHRsZWQgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0dGhyb3cgZXJyO1xuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRzdGF0cy5hY3RpdmUgPSBNYXRoLm1heCgwLCBzdGF0cy5hY3RpdmUgLSAxKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGVuc3VyZVF1ZXVlKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuYm9zcykgcmV0dXJuO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmJvc3MuY3JlYXRlUXVldWUocXVldWUpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Ly8gcGctYm9zcyB2MTAncyBjcmVhdGVRdWV1ZSBpcyBpZGVtcG90ZW50IGJ1dCBtYXkgdGhyb3cgb25cblx0XHRcdC8vIHJhY2UgY29uZGl0aW9ucyB3aGVuIG11bHRpcGxlIHByb2Nlc3NlcyBjYWxsIGl0IGNvbmN1cnJlbnRseVxuXHRcdFx0Ly8gYWdhaW5zdCBhIGZyZXNoIHNjaGVtYSDigJQgdGhvc2UgZXJyb3JzIGFyZSBoYXJtbGVzcyBvbmNlIHRoZVxuXHRcdFx0Ly8gcXVldWUgZXhpc3RzLiBTd2FsbG93ICsgbGV0IGRvd25zdHJlYW0gc2VuZC93b3JrIHN1cmZhY2UgYVxuXHRcdFx0Ly8gcmVhbCBwcm9ibGVtIGlmIHRoZSBxdWV1ZSBpc24ndCB1c2FibGUuXG5cdFx0XHRjb25zdCBtZXNzYWdlID0gKGVyciBhcyBFcnJvcikubWVzc2FnZSA/PyBcIlwiO1xuXHRcdFx0aWYgKCFtZXNzYWdlLmluY2x1ZGVzKFwiYWxyZWFkeSBleGlzdHNcIikpIHtcblx0XHRcdFx0Ly8gTG9nIHRoZSB1bmV4cGVjdGVkIGNhc2UgYnV0IGRvbid0IHByb3BhZ2F0ZSDigJQgb3BlcmF0b3JzXG5cdFx0XHRcdC8vIHNob3VsZG4ndCBzZWUgYSBxdWV1ZS1jcmVhdGlvbiByYWNlIGJsb3cgdXAgdGhlaXJcblx0XHRcdFx0Ly8gdHJpZ2dlciBib290IHBhdGguXG5cdFx0XHRcdGNvbnNvbGUud2FybihgW2Jsb2tdW3BnLWJvc3NdIGVuc3VyZVF1ZXVlKCR7cXVldWV9KSB3YXJuaW5nOmAsIG1lc3NhZ2UpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGFkZEpvYihcblx0XHRxdWV1ZTogc3RyaW5nLFxuXHRcdGRhdGE6IHVua25vd24sXG5cdFx0b3B0cz86IHsgcHJpb3JpdHk/OiBudW1iZXI7IGRlbGF5PzogbnVtYmVyOyByZXRyaWVzPzogbnVtYmVyOyB0aW1lb3V0PzogbnVtYmVyOyBqb2JJZD86IHN0cmluZyB9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMuYm9zcykgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW3BnLWJvc3NdIG5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHQvLyBwZy1ib3NzIHYxMCByZXF1aXJlcyB0aGUgcXVldWUgdG8gZXhpc3QgYmVmb3JlIHNlbmQuIFRoZVxuXHRcdC8vIGNhbGwgaXMgaWRlbXBvdGVudCDigJQgY2hlYXAgdG8gcmVwZWF0IHBlciBhZGQuXG5cdFx0YXdhaXQgdGhpcy5lbnN1cmVRdWV1ZShxdWV1ZSk7XG5cdFx0Ly8gcGctYm9zcyB2MTAncyBgYXR0b3JuZXkuY2hlY2tTZW5kQXJnc2AgcmVqZWN0cyBhbnkgZXhwbGljaXRseVxuXHRcdC8vIHVuZGVmaW5lZCBgcHJpb3JpdHlgIC8gYHJldHJ5TGltaXRgIC8gYHN0YXJ0QWZ0ZXJgIC9cblx0XHQvLyBgZXhwaXJlSW5TZWNvbmRzYCAvIGBzaW5nbGV0b25LZXlgIHdpdGggXCJYIG11c3QgYmUgYW4gaW50ZWdlclwiLlxuXHRcdC8vIEJ1aWxkIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIG9ubHkgdGhlIGtleXMgd2UgYWN0dWFsbHkgd2FudFxuXHRcdC8vIHNldCDigJQgY2F1Z2h0IGJ5IHRoZSByZWFsLWJyb2tlciBpbnRlZ3JhdGlvbiB0ZXN0IGluXG5cdFx0Ly8gYF9fdGVzdHNfXy9pbnRlZ3JhdGlvbi9wZ2Jvc3MtYWRhcHRlci5yZWFsLXBnLnRlc3QudHNgLlxuXHRcdGNvbnN0IHNlbmRPcHRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuXHRcdGlmICh0eXBlb2Ygb3B0cz8ucHJpb3JpdHkgPT09IFwibnVtYmVyXCIpIHNlbmRPcHRzLnByaW9yaXR5ID0gb3B0cy5wcmlvcml0eTtcblx0XHRpZiAodHlwZW9mIG9wdHM/LmRlbGF5ID09PSBcIm51bWJlclwiICYmIG9wdHMuZGVsYXkgPiAwKSB7XG5cdFx0XHRzZW5kT3B0cy5zdGFydEFmdGVyID0gTWF0aC5jZWlsKG9wdHMuZGVsYXkgLyAxMDAwKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBvcHRzPy5yZXRyaWVzID09PSBcIm51bWJlclwiKSBzZW5kT3B0cy5yZXRyeUxpbWl0ID0gb3B0cy5yZXRyaWVzO1xuXHRcdGlmICh0eXBlb2Ygb3B0cz8udGltZW91dCA9PT0gXCJudW1iZXJcIikgc2VuZE9wdHMuZXhwaXJlSW5TZWNvbmRzID0gTWF0aC5jZWlsKG9wdHMudGltZW91dCAvIDEwMDApO1xuXHRcdGlmICh0eXBlb2Ygb3B0cz8uam9iSWQgPT09IFwic3RyaW5nXCIgJiYgb3B0cy5qb2JJZC5sZW5ndGggPiAwKSBzZW5kT3B0cy5zaW5nbGV0b25LZXkgPSBvcHRzLmpvYklkO1xuXG5cdFx0Y29uc3Qgam9iSWQgPSBhd2FpdCB0aGlzLmJvc3Muc2VuZChxdWV1ZSwgZGF0YSwgc2VuZE9wdHMpO1xuXHRcdHJldHVybiBqb2JJZCA/PyBvcHRzPy5qb2JJZCA/PyB1dWlkKCk7XG5cdH1cblxuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCB8fCAhdGhpcy5ib3NzKSByZXR1cm47XG5cdFx0dHJ5IHtcblx0XHRcdGF3YWl0IHRoaXMuYm9zcy5vZmZXb3JrKHF1ZXVlKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8qIGlnbm9yZSAqL1xuXHRcdH1cblx0XHR0aGlzLndvcmtJZHMuZGVsZXRlKHF1ZXVlKTtcblx0fVxuXG5cdGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLmNvbm5lY3RlZDtcblx0fVxuXG5cdGFzeW5jIGhlYWx0aENoZWNrKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMuYm9zcykgcmV0dXJuIGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmJvc3MuZ2V0UXVldWVTaXplKFwiX19oZWFsdGhfY2hlY2tfX1wiKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0Ly8gZ2V0UXVldWVTaXplIG9uIGEgbm9uLWV4aXN0ZW50IHF1ZXVlIG1heSB0aHJvdyDigJQgZmFsbCBiYWNrIHRvXG5cdFx0XHQvLyBcImNvbm5lY3Rpb24gaXMgbGl2ZVwiIGJ5IGNoZWNraW5nIHRoZSBib3NzIGluc3RhbmNlIGF0dHJpYnV0ZS5cblx0XHRcdHJldHVybiB0aGlzLmNvbm5lY3RlZDtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRjb25zdCBjb3VudGVycyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKSA/PyB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwLCBhY3RpdmU6IDAgfTtcblx0XHRsZXQgd2FpdGluZyA9IDA7XG5cdFx0dHJ5IHtcblx0XHRcdHdhaXRpbmcgPSAoYXdhaXQgdGhpcy5ib3NzPy5nZXRRdWV1ZVNpemUocXVldWUpKSA/PyAwO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHR3YWl0aW5nLFxuXHRcdFx0YWN0aXZlOiBjb3VudGVycy5hY3RpdmUsXG5cdFx0XHRjb21wbGV0ZWQ6IGNvdW50ZXJzLmNvbXBsZXRlZCxcblx0XHRcdGZhaWxlZDogY291bnRlcnMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogMCxcblx0XHR9O1xuXHR9XG59XG4iXX0=
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RabbitMQAdapter — v0.7 PR 5 — Worker adapter backed by RabbitMQ via
|
|
3
|
+
* the `amqplib` driver. Direct-exchange / queue model — the `queue`
|
|
4
|
+
* field maps to an AMQP queue name; messages are consumed with
|
|
5
|
+
* manual ACK. The default exchange (`""`) is used for publishing.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Concurrency via `prefetch(N)` per channel.
|
|
9
|
+
* - Retries via `nack` with requeue=true until `retries` is hit, then
|
|
10
|
+
* drop or DLQ-route based on `deadLetterQueue` config.
|
|
11
|
+
* - Priorities via the `x-max-priority` queue arg (AMQP standard).
|
|
12
|
+
* - Delayed delivery via the `x-delayed-message` plugin when
|
|
13
|
+
* available; falls back to immediate dispatch otherwise.
|
|
14
|
+
*
|
|
15
|
+
* Requires `amqplib` as a peer dependency:
|
|
16
|
+
*
|
|
17
|
+
* bun add amqplib
|
|
18
|
+
*
|
|
19
|
+
* Environment variables:
|
|
20
|
+
* - `AMQP_URL` — full AMQP connection string (default `amqp://localhost`).
|
|
21
|
+
* - `AMQP_VHOST` — virtual host (default `/`).
|
|
22
|
+
*/
|
|
23
|
+
import type { WorkerTriggerOpts } from "@blokjs/helper";
|
|
24
|
+
import type { WorkerAdapter, WorkerJob, WorkerQueueStats } from "../WorkerTrigger";
|
|
25
|
+
export interface RabbitMQConfig {
|
|
26
|
+
url: string;
|
|
27
|
+
vhost?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare class RabbitMQAdapter implements WorkerAdapter {
|
|
30
|
+
readonly provider: "rabbitmq";
|
|
31
|
+
private readonly config;
|
|
32
|
+
private conn;
|
|
33
|
+
private channels;
|
|
34
|
+
private connected;
|
|
35
|
+
private stats;
|
|
36
|
+
constructor(config?: Partial<RabbitMQConfig>);
|
|
37
|
+
connect(): Promise<void>;
|
|
38
|
+
disconnect(): Promise<void>;
|
|
39
|
+
process(config: WorkerTriggerOpts, handler: (job: WorkerJob) => Promise<void>): Promise<void>;
|
|
40
|
+
addJob(queue: string, data: unknown, opts?: {
|
|
41
|
+
priority?: number;
|
|
42
|
+
delay?: number;
|
|
43
|
+
retries?: number;
|
|
44
|
+
timeout?: number;
|
|
45
|
+
jobId?: string;
|
|
46
|
+
}): Promise<string>;
|
|
47
|
+
stopProcessing(queue: string): Promise<void>;
|
|
48
|
+
isConnected(): boolean;
|
|
49
|
+
healthCheck(): Promise<boolean>;
|
|
50
|
+
getQueueStats(queue: string): Promise<WorkerQueueStats>;
|
|
51
|
+
}
|