@blokjs/trigger-worker 0.4.0 → 0.6.2
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
|
@@ -70,8 +70,14 @@ export class InMemoryAdapter {
|
|
|
70
70
|
if (!this.connected) {
|
|
71
71
|
throw new Error("Not connected. Call connect() first.");
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
// Get-or-init the per-queue job list. Same pattern as `stats`
|
|
74
|
+
// below — the previous code used `set-if-absent` then `.get()!`,
|
|
75
|
+
// but that non-null assertion is what biome flags. Pulling the
|
|
76
|
+
// reference once and seeding when missing keeps the type exact.
|
|
77
|
+
let jobs = this.jobs.get(queue);
|
|
78
|
+
if (!jobs) {
|
|
79
|
+
jobs = [];
|
|
80
|
+
this.jobs.set(queue, jobs);
|
|
75
81
|
}
|
|
76
82
|
if (!this.stats.has(queue)) {
|
|
77
83
|
this.stats.set(queue, { completed: 0, failed: 0 });
|
|
@@ -91,7 +97,6 @@ export class InMemoryAdapter {
|
|
|
91
97
|
if (job.status === "delayed") {
|
|
92
98
|
job.scheduledAt = new Date(Date.now() + job.delay);
|
|
93
99
|
}
|
|
94
|
-
const jobs = this.jobs.get(queue);
|
|
95
100
|
// Insert sorted by priority (higher first)
|
|
96
101
|
const insertIdx = jobs.findIndex((j) => j.status === "waiting" && j.priority < job.priority);
|
|
97
102
|
if (insertIdx >= 0) {
|
|
@@ -182,7 +187,7 @@ export class InMemoryAdapter {
|
|
|
182
187
|
internalJob.error = error;
|
|
183
188
|
if (requeue && internalJob.attempts < internalJob.maxRetries) {
|
|
184
189
|
// Requeue with backoff
|
|
185
|
-
const backoff = Math.min(1000 *
|
|
190
|
+
const backoff = Math.min(1000 * 2 ** internalJob.attempts, 30000);
|
|
186
191
|
internalJob.status = "delayed";
|
|
187
192
|
internalJob.scheduledAt = new Date(Date.now() + backoff);
|
|
188
193
|
}
|
|
@@ -217,4 +222,4 @@ export class InMemoryAdapter {
|
|
|
217
222
|
}
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5NZW1vcnlBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0luTWVtb3J5QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWdDbEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNsQixRQUFRLEdBQUcsV0FBb0IsQ0FBQztJQUNqQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLElBQUksR0FBK0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM3QyxVQUFVLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDcEQsS0FBSyxHQUF1RCxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTlFLEtBQUssQ0FBQyxPQUFPO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ2Ysc0JBQXNCO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEQsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNGLENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8s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UUFDcEIsQ0FBQztJQUNGLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW5NZW1vcnlBZGFwdGVyIC0gV29ya2VyIGFkYXB0ZXIgdXNpbmcgaW4tcHJvY2VzcyBxdWV1ZXNcbiAqXG4gKiBJZGVhbCBmb3I6XG4gKiAtIERldmVsb3BtZW50IGFuZCB0ZXN0aW5nXG4gKiAtIFNpbXBsZSBiYWNrZ3JvdW5kIGpvYiBwcm9jZXNzaW5nXG4gKiAtIFNpbmdsZS1pbnN0YW5jZSBkZXBsb3ltZW50c1xuICpcbiAqIExpbWl0YXRpb25zOlxuICogLSBKb2JzIGFyZSBsb3N0IG9uIHByb2Nlc3MgcmVzdGFydFxuICogLSBObyBkaXN0cmlidXRlZCBwcm9jZXNzaW5nXG4gKiAtIE5vIHBlcnNpc3RlbmNlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgSW5NZW1vcnlBZGFwdGVyKCk7XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9ranMvaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuLyoqXG4gKiBJbnRlcm5hbCBqb2IgcmVwcmVzZW50YXRpb25cbiAqL1xuaW50ZXJmYWNlIEludGVybmFsSm9iIHtcblx0aWQ6IHN0cmluZztcblx0ZGF0YTogdW5rbm93bjtcblx0cXVldWU6IHN0cmluZztcblx0cHJpb3JpdHk6IG51bWJlcjtcblx0YXR0ZW1wdHM6IG51bWJlcjtcblx0bWF4UmV0cmllczogbnVtYmVyO1xuXHRjcmVhdGVkQXQ6IERhdGU7XG5cdGRlbGF5OiBudW1iZXI7XG5cdHRpbWVvdXQ6IG51bWJlcjtcblx0c3RhdHVzOiBcIndhaXRpbmdcIiB8IFwiYWN0aXZlXCIgfCBcImNvbXBsZXRlZFwiIHwgXCJmYWlsZWRcIiB8IFwiZGVsYXllZFwiO1xuXHRzY2hlZHVsZWRBdD86IERhdGU7XG5cdGVycm9yPzogRXJyb3I7XG59XG5cbi8qKlxuICogUXVldWUgcHJvY2Vzc29yIGVudHJ5XG4gKi9cbmludGVyZmFjZSBRdWV1ZVByb2Nlc3NvciB7XG5cdGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHM7XG5cdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPjtcblx0YWN0aXZlOiBudW1iZXI7XG5cdHJ1bm5pbmc6IGJvb2xlYW47XG5cdHRpbWVyPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xufVxuXG4vKipcbiAqIEluTWVtb3J5QWRhcHRlciAtIFNpbXBsZSBpbi1wcm9jZXNzIHdvcmtlciBxdWV1ZVxuICovXG5leHBvcnQgY2xhc3MgSW5NZW1vcnlBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJpbi1tZW1vcnlcIiBhcyBjb25zdDtcblx0cHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBqb2JzOiBNYXA8c3RyaW5nLCBJbnRlcm5hbEpvYltdPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBwcm9jZXNzb3JzOiBNYXA8c3RyaW5nLCBRdWV1ZVByb2Nlc3Nvcj4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIHsgY29tcGxldGVkOiBudW1iZXI7IGZhaWxlZDogbnVtYmVyIH0+ID0gbmV3IE1hcCgpO1xuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXHR9XG5cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBTdG9wIGFsbCBwcm9jZXNzb3JzXG5cdFx0Zm9yIChjb25zdCBbcXVldWUsIHByb2Nlc3Nvcl0gb2YgdGhpcy5wcm9jZXNzb3JzKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMucHJvY2Vzc29ycy5jbGVhcigpO1xuXHRcdHRoaXMuam9icy5jbGVhcigpO1xuXHRcdHRoaXMuc3RhdHMuY2xlYXIoKTtcblx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHR9XG5cblx0YXN5bmMgcHJvY2Vzcyhjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLCBoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLmpvYnMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdHRoaXMuam9icy5zZXQoY29uZmlnLnF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMoY29uZmlnLnF1ZXVlKSkge1xuXHRcdFx0dGhpcy5zdGF0cy5zZXQoY29uZmlnLnF1ZXVlLCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IHByb2Nlc3NvcjogUXVldWVQcm9jZXNzb3IgPSB7XG5cdFx0XHRjb25maWcsXG5cdFx0XHRoYW5kbGVyLFxuXHRcdFx0YWN0aXZlOiAwLFxuXHRcdFx0cnVubmluZzogdHJ1ZSxcblx0XHR9O1xuXG5cdFx0dGhpcy5wcm9jZXNzb3JzLnNldChjb25maWcucXVldWUsIHByb2Nlc3Nvcik7XG5cblx0XHQvLyBTdGFydCBwb2xsaW5nIGZvciBqb2JzXG5cdFx0cHJvY2Vzc29yLnRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuXHRcdFx0dGhpcy5wcm9jZXNzTmV4dChjb25maWcucXVldWUpLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihgW0luTWVtb3J5QWRhcHRlcl0gRXJyb3IgcHJvY2Vzc2luZyAke2NvbmZpZy5xdWV1ZX06ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblx0XHRcdH0pO1xuXHRcdH0sIDUwKTsgLy8gUG9sbCBldmVyeSA1MG1zXG5cdH1cblxuXHRhc3luYyBhZGRKb2IoXG5cdFx0cXVldWU6IHN0cmluZyxcblx0XHRkYXRhOiB1bmtub3duLFxuXHRcdG9wdHM/OiB7XG5cdFx0XHRwcmlvcml0eT86IG51bWJlcjtcblx0XHRcdGRlbGF5PzogbnVtYmVyO1xuXHRcdFx0cmV0cmllcz86IG51bWJlcjtcblx0XHRcdHRpbWVvdXQ/OiBudW1iZXI7XG5cdFx0XHRqb2JJZD86IHN0cmluZztcblx0XHR9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIk5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuam9icy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLmpvYnMuc2V0KHF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLnN0YXRzLnNldChxdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9KTtcblx0XHR9XG5cblx0XHRjb25zdCBqb2I6IEludGVybmFsSm9iID0ge1xuXHRcdFx0aWQ6IG9wdHM/LmpvYklkIHx8IHV1aWQoKSxcblx0XHRcdGRhdGEsXG5cdFx0XHRxdWV1ZSxcblx0XHRcdHByaW9yaXR5OiBvcHRzPy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0YXR0ZW1wdHM6IDAsXG5cdFx0XHRtYXhSZXRyaWVzOiBvcHRzPy5yZXRyaWVzID8/IDMsXG5cdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG5cdFx0XHRkZWxheTogb3B0cz8uZGVsYXkgPz8gMCxcblx0XHRcdHRpbWVvdXQ6IG9wdHM/LnRpbWVvdXQgPz8gMCxcblx0XHRcdHN0YXR1czogb3B0cz8uZGVsYXkgJiYgb3B0cy5kZWxheSA+IDAgPyBcImRlbGF5ZWRcIiA6IFwid2FpdGluZ1wiLFxuXHRcdH07XG5cblx0XHRpZiAoam9iLnN0YXR1cyA9PT0gXCJkZWxheWVkXCIpIHtcblx0XHRcdGpvYi5zY2hlZHVsZWRBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBqb2IuZGVsYXkpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGpvYnMgPSB0aGlzLmpvYnMuZ2V0KHF1ZXVlKSE7XG5cblx0XHQvLyBJbnNlcnQgc29ydGVkIGJ5IHByaW9yaXR5IChoaWdoZXIgZmlyc3QpXG5cdFx0Y29uc3QgaW5zZXJ0SWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIiAmJiBqLnByaW9yaXR5IDwgam9iLnByaW9yaXR5KTtcblx0XHRpZiAoaW5zZXJ0SWR4ID49IDApIHtcblx0XHRcdGpvYnMuc3BsaWNlKGluc2VydElkeCwgMCwgam9iKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0am9icy5wdXNoKGpvYik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpvYi5pZDtcblx0fVxuXG5cdGFzeW5jIHN0b3BQcm9jZXNzaW5nKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBwcm9jZXNzb3IgPSB0aGlzLnByb2Nlc3NvcnMuZ2V0KHF1ZXVlKTtcblx0XHRpZiAocHJvY2Vzc29yKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb2Nlc3NvcnMuZGVsZXRlKHF1ZXVlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRjb25zdCBqb2JzID0gdGhpcy5qb2JzLmdldChxdWV1ZSkgfHwgW107XG5cdFx0Y29uc3QgcXVldWVTdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKSB8fCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH07XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0d2FpdGluZzogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIikubGVuZ3RoLFxuXHRcdFx0YWN0aXZlOiBqb2JzLmZpbHRlcigoaikgPT4gai5zdGF0dXMgPT09IFwiYWN0aXZlXCIpLmxlbmd0aCxcblx0XHRcdGNvbXBsZXRlZDogcXVldWVTdGF0cy5jb21wbGV0ZWQsXG5cdFx0XHRmYWlsZWQ6IHF1ZXVlU3RhdHMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcImRlbGF5ZWRcIikubGVuZ3RoLFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogUHJvY2VzcyB0aGUgbmV4dCBhdmFpbGFibGUgam9iIGZyb20gYSBxdWV1ZVxuXHQgKi9cblx0cHJpdmF0ZSBhc3luYyBwcm9jZXNzTmV4dChxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKCFwcm9jZXNzb3IgfHwgIXByb2Nlc3Nvci5ydW5uaW5nKSByZXR1cm47XG5cblx0XHRjb25zdCBjb25jdXJyZW5jeSA9IHByb2Nlc3Nvci5jb25maWcuY29uY3VycmVuY3kgPz8gMTtcblx0XHRpZiAocHJvY2Vzc29yLmFjdGl2ZSA+PSBjb25jdXJyZW5jeSkgcmV0dXJuO1xuXG5cdFx0Y29uc3Qgam9icyA9IHRoaXMuam9icy5nZXQocXVldWUpO1xuXHRcdGlmICgham9icyB8fCBqb2JzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGRlbGF5ZWQgam9icyB0aGF0IGFyZSByZWFkeVxuXHRcdGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cdFx0Zm9yIChjb25zdCBqb2Igb2Ygam9icykge1xuXHRcdFx0aWYgKGpvYi5zdGF0dXMgPT09IFwiZGVsYXllZFwiICYmIGpvYi5zY2hlZHVsZWRBdCAmJiBqb2Iuc2NoZWR1bGVkQXQuZ2V0VGltZSgpIDw9IG5vdykge1xuXHRcdFx0XHRqb2Iuc3RhdHVzID0gXCJ3YWl0aW5nXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmluZCBuZXh0IHdhaXRpbmcgam9iXG5cdFx0Y29uc3Qgam9iSWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIik7XG5cdFx0aWYgKGpvYklkeCA8IDApIHJldHVybjtcblxuXHRcdGNvbnN0IGludGVybmFsSm9iID0gam9ic1tqb2JJZHhdO1xuXHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiYWN0aXZlXCI7XG5cdFx0cHJvY2Vzc29yLmFjdGl2ZSsrO1xuXG5cdFx0Y29uc3Qgd29ya2VySm9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRpZDogaW50ZXJuYWxKb2IuaWQsXG5cdFx0XHRkYXRhOiBpbnRlcm5hbEpvYi5kYXRhLFxuXHRcdFx0aGVhZGVyczoge30sXG5cdFx0XHRxdWV1ZTogaW50ZXJuYWxKb2IucXVldWUsXG5cdFx0XHRwcmlvcml0eTogaW50ZXJuYWxKb2IucHJpb3JpdHksXG5cdFx0XHRhdHRlbXB0czogaW50ZXJuYWxKb2IuYXR0ZW1wdHMsXG5cdFx0XHRtYXhSZXRyaWVzOiBpbnRlcm5hbEpvYi5tYXhSZXRyaWVzLFxuXHRcdFx0Y3JlYXRlZEF0OiBpbnRlcm5hbEpvYi5jcmVhdGVkQXQsXG5cdFx0XHRkZWxheTogaW50ZXJuYWxKb2IuZGVsYXksXG5cdFx0XHR0aW1lb3V0OiBpbnRlcm5hbEpvYi50aW1lb3V0LFxuXHRcdFx0cmF3OiBpbnRlcm5hbEpvYixcblx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiY29tcGxldGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuY29tcGxldGVkKys7XG5cdFx0XHR9LFxuXHRcdFx0ZmFpbDogYXN5bmMgKGVycm9yOiBFcnJvciwgcmVxdWV1ZT86IGJvb2xlYW4pID0+IHtcblx0XHRcdFx0aW50ZXJuYWxKb2IuYXR0ZW1wdHMrKztcblx0XHRcdFx0aW50ZXJuYWxKb2IuZXJyb3IgPSBlcnJvcjtcblxuXHRcdFx0XHRpZiAocmVxdWV1ZSAmJiBpbnRlcm5hbEpvYi5hdHRlbXB0cyA8IGludGVybmFsSm9iLm1heFJldHJpZXMpIHtcblx0XHRcdFx0XHQvLyBSZXF1ZXVlIHdpdGggYmFja29mZlxuXHRcdFx0XHRcdGNvbnN0IGJhY2tvZmYgPSBNYXRoLm1pbigxMDAwICogTWF0aC5wb3coMiwgaW50ZXJuYWxKb2IuYXR0ZW1wdHMpLCAzMDAwMCk7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJkZWxheWVkXCI7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc2NoZWR1bGVkQXQgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgYmFja29mZik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJmYWlsZWRcIjtcblx0XHRcdFx0XHRjb25zdCBpZHggPSBqb2JzLmluZGV4T2YoaW50ZXJuYWxKb2IpO1xuXHRcdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0XHRjb25zdCBzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpO1xuXHRcdFx0XHRcdGlmIChzKSBzLmZhaWxlZCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH07XG5cblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgcHJvY2Vzc29yLmhhbmRsZXIod29ya2VySm9iKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8vIEhhbmRsZXIgdGhyZXcgLSB0cmVhdCBhcyBmYWlsdXJlXG5cdFx0XHRpZiAoaW50ZXJuYWxKb2Iuc3RhdHVzID09PSBcImFjdGl2ZVwiKSB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiZmFpbGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuZmFpbGVkKys7XG5cdFx0XHR9XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdHByb2Nlc3Nvci5hY3RpdmUtLTtcblx0XHR9XG5cdH1cbn1cbiJdfQ==
|
|
225
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5NZW1vcnlBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0luTWVtb3J5QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWdDbEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNsQixRQUFRLEdBQUcsV0FBb0IsQ0FBQztJQUNqQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLElBQUksR0FBK0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM3QyxVQUFVLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDcEQsS0FBSyxHQUF1RCxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTlFLEtBQUssQ0FBQyxPQUFPO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ2Ysc0JBQXNCO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEQsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNGLENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8s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LE1BQU0sRUFBRSxDQUFDO1FBQ3BCLENBQUM7SUFDRixDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEluTWVtb3J5QWRhcHRlciAtIFdvcmtlciBhZGFwdGVyIHVzaW5nIGluLXByb2Nlc3MgcXVldWVzXG4gKlxuICogSWRlYWwgZm9yOlxuICogLSBEZXZlbG9wbWVudCBhbmQgdGVzdGluZ1xuICogLSBTaW1wbGUgYmFja2dyb3VuZCBqb2IgcHJvY2Vzc2luZ1xuICogLSBTaW5nbGUtaW5zdGFuY2UgZGVwbG95bWVudHNcbiAqXG4gKiBMaW1pdGF0aW9uczpcbiAqIC0gSm9icyBhcmUgbG9zdCBvbiBwcm9jZXNzIHJlc3RhcnRcbiAqIC0gTm8gZGlzdHJpYnV0ZWQgcHJvY2Vzc2luZ1xuICogLSBObyBwZXJzaXN0ZW5jZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IEluTWVtb3J5QWRhcHRlcigpO1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBXb3JrZXJUcmlnZ2VyT3B0cyB9IGZyb20gXCJAYmxva2pzL2hlbHBlclwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtlckFkYXB0ZXIsIFdvcmtlckpvYiwgV29ya2VyUXVldWVTdGF0cyB9IGZyb20gXCIuLi9Xb3JrZXJUcmlnZ2VyXCI7XG5cbi8qKlxuICogSW50ZXJuYWwgam9iIHJlcHJlc2VudGF0aW9uXG4gKi9cbmludGVyZmFjZSBJbnRlcm5hbEpvYiB7XG5cdGlkOiBzdHJpbmc7XG5cdGRhdGE6IHVua25vd247XG5cdHF1ZXVlOiBzdHJpbmc7XG5cdHByaW9yaXR5OiBudW1iZXI7XG5cdGF0dGVtcHRzOiBudW1iZXI7XG5cdG1heFJldHJpZXM6IG51bWJlcjtcblx0Y3JlYXRlZEF0OiBEYXRlO1xuXHRkZWxheTogbnVtYmVyO1xuXHR0aW1lb3V0OiBudW1iZXI7XG5cdHN0YXR1czogXCJ3YWl0aW5nXCIgfCBcImFjdGl2ZVwiIHwgXCJjb21wbGV0ZWRcIiB8IFwiZmFpbGVkXCIgfCBcImRlbGF5ZWRcIjtcblx0c2NoZWR1bGVkQXQ/OiBEYXRlO1xuXHRlcnJvcj86IEVycm9yO1xufVxuXG4vKipcbiAqIFF1ZXVlIHByb2Nlc3NvciBlbnRyeVxuICovXG5pbnRlcmZhY2UgUXVldWVQcm9jZXNzb3Ige1xuXHRjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzO1xuXHRoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD47XG5cdGFjdGl2ZTogbnVtYmVyO1xuXHRydW5uaW5nOiBib29sZWFuO1xuXHR0aW1lcj86IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPjtcbn1cblxuLyoqXG4gKiBJbk1lbW9yeUFkYXB0ZXIgLSBTaW1wbGUgaW4tcHJvY2VzcyB3b3JrZXIgcXVldWVcbiAqL1xuZXhwb3J0IGNsYXNzIEluTWVtb3J5QWRhcHRlciBpbXBsZW1lbnRzIFdvcmtlckFkYXB0ZXIge1xuXHRyZWFkb25seSBwcm92aWRlciA9IFwiaW4tbWVtb3J5XCIgYXMgY29uc3Q7XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgam9iczogTWFwPHN0cmluZywgSW50ZXJuYWxKb2JbXT4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgcHJvY2Vzc29yczogTWFwPHN0cmluZywgUXVldWVQcm9jZXNzb3I+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIHN0YXRzOiBNYXA8c3RyaW5nLCB7IGNvbXBsZXRlZDogbnVtYmVyOyBmYWlsZWQ6IG51bWJlciB9PiA9IG5ldyBNYXAoKTtcblxuXHRhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0fVxuXG5cdGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Ly8gU3RvcCBhbGwgcHJvY2Vzc29yc1xuXHRcdGZvciAoY29uc3QgW3F1ZXVlLCBwcm9jZXNzb3JdIG9mIHRoaXMucHJvY2Vzc29ycykge1xuXHRcdFx0cHJvY2Vzc29yLnJ1bm5pbmcgPSBmYWxzZTtcblx0XHRcdGlmIChwcm9jZXNzb3IudGltZXIpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChwcm9jZXNzb3IudGltZXIpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnByb2Nlc3NvcnMuY2xlYXIoKTtcblx0XHR0aGlzLmpvYnMuY2xlYXIoKTtcblx0XHR0aGlzLnN0YXRzLmNsZWFyKCk7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcblx0fVxuXG5cdGFzeW5jIHByb2Nlc3MoY29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cywgaGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdH1cblxuXHRcdGlmICghdGhpcy5qb2JzLmhhcyhjb25maWcucXVldWUpKSB7XG5cdFx0XHR0aGlzLmpvYnMuc2V0KGNvbmZpZy5xdWV1ZSwgW10pO1xuXHRcdH1cblx0XHRpZiAoIXRoaXMuc3RhdHMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdHRoaXMuc3RhdHMuc2V0KGNvbmZpZy5xdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9KTtcblx0XHR9XG5cblx0XHRjb25zdCBwcm9jZXNzb3I6IFF1ZXVlUHJvY2Vzc29yID0ge1xuXHRcdFx0Y29uZmlnLFxuXHRcdFx0aGFuZGxlcixcblx0XHRcdGFjdGl2ZTogMCxcblx0XHRcdHJ1bm5pbmc6IHRydWUsXG5cdFx0fTtcblxuXHRcdHRoaXMucHJvY2Vzc29ycy5zZXQoY29uZmlnLnF1ZXVlLCBwcm9jZXNzb3IpO1xuXG5cdFx0Ly8gU3RhcnQgcG9sbGluZyBmb3Igam9ic1xuXHRcdHByb2Nlc3Nvci50aW1lciA9IHNldEludGVydmFsKCgpID0+IHtcblx0XHRcdHRoaXMucHJvY2Vzc05leHQoY29uZmlnLnF1ZXVlKS5jYXRjaCgoZXJyKSA9PiB7XG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoYFtJbk1lbW9yeUFkYXB0ZXJdIEVycm9yIHByb2Nlc3NpbmcgJHtjb25maWcucXVldWV9OiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0XHR9KTtcblx0XHR9LCA1MCk7IC8vIFBvbGwgZXZlcnkgNTBtc1xuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzoge1xuXHRcdFx0cHJpb3JpdHk/OiBudW1iZXI7XG5cdFx0XHRkZWxheT86IG51bWJlcjtcblx0XHRcdHJldHJpZXM/OiBudW1iZXI7XG5cdFx0XHR0aW1lb3V0PzogbnVtYmVyO1xuXHRcdFx0am9iSWQ/OiBzdHJpbmc7XG5cdFx0fSxcblx0KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0Ly8gR2V0LW9yLWluaXQgdGhlIHBlci1xdWV1ZSBqb2IgbGlzdC4gU2FtZSBwYXR0ZXJuIGFzIGBzdGF0c2Bcblx0XHQvLyBiZWxvdyDigJQgdGhlIHByZXZpb3VzIGNvZGUgdXNlZCBgc2V0LWlmLWFic2VudGAgdGhlbiBgLmdldCgpIWAsXG5cdFx0Ly8gYnV0IHRoYXQgbm9uLW51bGwgYXNzZXJ0aW9uIGlzIHdoYXQgYmlvbWUgZmxhZ3MuIFB1bGxpbmcgdGhlXG5cdFx0Ly8gcmVmZXJlbmNlIG9uY2UgYW5kIHNlZWRpbmcgd2hlbiBtaXNzaW5nIGtlZXBzIHRoZSB0eXBlIGV4YWN0LlxuXHRcdGxldCBqb2JzID0gdGhpcy5qb2JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKCFqb2JzKSB7XG5cdFx0XHRqb2JzID0gW107XG5cdFx0XHR0aGlzLmpvYnMuc2V0KHF1ZXVlLCBqb2JzKTtcblx0XHR9XG5cdFx0aWYgKCF0aGlzLnN0YXRzLmhhcyhxdWV1ZSkpIHtcblx0XHRcdHRoaXMuc3RhdHMuc2V0KHF1ZXVlLCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IGpvYjogSW50ZXJuYWxKb2IgPSB7XG5cdFx0XHRpZDogb3B0cz8uam9iSWQgfHwgdXVpZCgpLFxuXHRcdFx0ZGF0YSxcblx0XHRcdHF1ZXVlLFxuXHRcdFx0cHJpb3JpdHk6IG9wdHM/LnByaW9yaXR5ID8/IDAsXG5cdFx0XHRhdHRlbXB0czogMCxcblx0XHRcdG1heFJldHJpZXM6IG9wdHM/LnJldHJpZXMgPz8gMyxcblx0XHRcdGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcblx0XHRcdGRlbGF5OiBvcHRzPy5kZWxheSA/PyAwLFxuXHRcdFx0dGltZW91dDogb3B0cz8udGltZW91dCA/PyAwLFxuXHRcdFx0c3RhdHVzOiBvcHRzPy5kZWxheSAmJiBvcHRzLmRlbGF5ID4gMCA/IFwiZGVsYXllZFwiIDogXCJ3YWl0aW5nXCIsXG5cdFx0fTtcblxuXHRcdGlmIChqb2Iuc3RhdHVzID09PSBcImRlbGF5ZWRcIikge1xuXHRcdFx0am9iLnNjaGVkdWxlZEF0ID0gbmV3IERhdGUoRGF0ZS5ub3coKSArIGpvYi5kZWxheSk7XG5cdFx0fVxuXG5cdFx0Ly8gSW5zZXJ0IHNvcnRlZCBieSBwcmlvcml0eSAoaGlnaGVyIGZpcnN0KVxuXHRcdGNvbnN0IGluc2VydElkeCA9IGpvYnMuZmluZEluZGV4KChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIgJiYgai5wcmlvcml0eSA8IGpvYi5wcmlvcml0eSk7XG5cdFx0aWYgKGluc2VydElkeCA+PSAwKSB7XG5cdFx0XHRqb2JzLnNwbGljZShpbnNlcnRJZHgsIDAsIGpvYik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpvYnMucHVzaChqb2IpO1xuXHRcdH1cblxuXHRcdHJldHVybiBqb2IuaWQ7XG5cdH1cblxuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKHByb2Nlc3Nvcikge1xuXHRcdFx0cHJvY2Vzc29yLnJ1bm5pbmcgPSBmYWxzZTtcblx0XHRcdGlmIChwcm9jZXNzb3IudGltZXIpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChwcm9jZXNzb3IudGltZXIpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wcm9jZXNzb3JzLmRlbGV0ZShxdWV1ZSk7XG5cdFx0fVxuXHR9XG5cblx0aXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0YXN5bmMgaGVhbHRoQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0YXN5bmMgZ2V0UXVldWVTdGF0cyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTxXb3JrZXJRdWV1ZVN0YXRzPiB7XG5cdFx0Y29uc3Qgam9icyA9IHRoaXMuam9icy5nZXQocXVldWUpIHx8IFtdO1xuXHRcdGNvbnN0IHF1ZXVlU3RhdHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSkgfHwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9O1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHdhaXRpbmc6IGpvYnMuZmlsdGVyKChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIpLmxlbmd0aCxcblx0XHRcdGFjdGl2ZTogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcImFjdGl2ZVwiKS5sZW5ndGgsXG5cdFx0XHRjb21wbGV0ZWQ6IHF1ZXVlU3RhdHMuY29tcGxldGVkLFxuXHRcdFx0ZmFpbGVkOiBxdWV1ZVN0YXRzLmZhaWxlZCxcblx0XHRcdGRlbGF5ZWQ6IGpvYnMuZmlsdGVyKChqKSA9PiBqLnN0YXR1cyA9PT0gXCJkZWxheWVkXCIpLmxlbmd0aCxcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIFByb2Nlc3MgdGhlIG5leHQgYXZhaWxhYmxlIGpvYiBmcm9tIGEgcXVldWVcblx0ICovXG5cdHByaXZhdGUgYXN5bmMgcHJvY2Vzc05leHQocXVldWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHByb2Nlc3NvciA9IHRoaXMucHJvY2Vzc29ycy5nZXQocXVldWUpO1xuXHRcdGlmICghcHJvY2Vzc29yIHx8ICFwcm9jZXNzb3IucnVubmluZykgcmV0dXJuO1xuXG5cdFx0Y29uc3QgY29uY3VycmVuY3kgPSBwcm9jZXNzb3IuY29uZmlnLmNvbmN1cnJlbmN5ID8/IDE7XG5cdFx0aWYgKHByb2Nlc3Nvci5hY3RpdmUgPj0gY29uY3VycmVuY3kpIHJldHVybjtcblxuXHRcdGNvbnN0IGpvYnMgPSB0aGlzLmpvYnMuZ2V0KHF1ZXVlKTtcblx0XHRpZiAoIWpvYnMgfHwgam9icy5sZW5ndGggPT09IDApIHJldHVybjtcblxuXHRcdC8vIENoZWNrIGZvciBkZWxheWVkIGpvYnMgdGhhdCBhcmUgcmVhZHlcblx0XHRjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXHRcdGZvciAoY29uc3Qgam9iIG9mIGpvYnMpIHtcblx0XHRcdGlmIChqb2Iuc3RhdHVzID09PSBcImRlbGF5ZWRcIiAmJiBqb2Iuc2NoZWR1bGVkQXQgJiYgam9iLnNjaGVkdWxlZEF0LmdldFRpbWUoKSA8PSBub3cpIHtcblx0XHRcdFx0am9iLnN0YXR1cyA9IFwid2FpdGluZ1wiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpbmQgbmV4dCB3YWl0aW5nIGpvYlxuXHRcdGNvbnN0IGpvYklkeCA9IGpvYnMuZmluZEluZGV4KChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIpO1xuXHRcdGlmIChqb2JJZHggPCAwKSByZXR1cm47XG5cblx0XHRjb25zdCBpbnRlcm5hbEpvYiA9IGpvYnNbam9iSWR4XTtcblx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImFjdGl2ZVwiO1xuXHRcdHByb2Nlc3Nvci5hY3RpdmUrKztcblxuXHRcdGNvbnN0IHdvcmtlckpvYjogV29ya2VySm9iID0ge1xuXHRcdFx0aWQ6IGludGVybmFsSm9iLmlkLFxuXHRcdFx0ZGF0YTogaW50ZXJuYWxKb2IuZGF0YSxcblx0XHRcdGhlYWRlcnM6IHt9LFxuXHRcdFx0cXVldWU6IGludGVybmFsSm9iLnF1ZXVlLFxuXHRcdFx0cHJpb3JpdHk6IGludGVybmFsSm9iLnByaW9yaXR5LFxuXHRcdFx0YXR0ZW1wdHM6IGludGVybmFsSm9iLmF0dGVtcHRzLFxuXHRcdFx0bWF4UmV0cmllczogaW50ZXJuYWxKb2IubWF4UmV0cmllcyxcblx0XHRcdGNyZWF0ZWRBdDogaW50ZXJuYWxKb2IuY3JlYXRlZEF0LFxuXHRcdFx0ZGVsYXk6IGludGVybmFsSm9iLmRlbGF5LFxuXHRcdFx0dGltZW91dDogaW50ZXJuYWxKb2IudGltZW91dCxcblx0XHRcdHJhdzogaW50ZXJuYWxKb2IsXG5cdFx0XHRjb21wbGV0ZTogYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImNvbXBsZXRlZFwiO1xuXHRcdFx0XHRjb25zdCBpZHggPSBqb2JzLmluZGV4T2YoaW50ZXJuYWxKb2IpO1xuXHRcdFx0XHRpZiAoaWR4ID49IDApIGpvYnMuc3BsaWNlKGlkeCwgMSk7XG5cdFx0XHRcdGNvbnN0IHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSk7XG5cdFx0XHRcdGlmIChzKSBzLmNvbXBsZXRlZCsrO1xuXHRcdFx0fSxcblx0XHRcdGZhaWw6IGFzeW5jIChlcnJvcjogRXJyb3IsIHJlcXVldWU/OiBib29sZWFuKSA9PiB7XG5cdFx0XHRcdGludGVybmFsSm9iLmF0dGVtcHRzKys7XG5cdFx0XHRcdGludGVybmFsSm9iLmVycm9yID0gZXJyb3I7XG5cblx0XHRcdFx0aWYgKHJlcXVldWUgJiYgaW50ZXJuYWxKb2IuYXR0ZW1wdHMgPCBpbnRlcm5hbEpvYi5tYXhSZXRyaWVzKSB7XG5cdFx0XHRcdFx0Ly8gUmVxdWV1ZSB3aXRoIGJhY2tvZmZcblx0XHRcdFx0XHRjb25zdCBiYWNrb2ZmID0gTWF0aC5taW4oMTAwMCAqIDIgKiogaW50ZXJuYWxKb2IuYXR0ZW1wdHMsIDMwMDAwKTtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImRlbGF5ZWRcIjtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zY2hlZHVsZWRBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBiYWNrb2ZmKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImZhaWxlZFwiO1xuXHRcdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdFx0aWYgKGlkeCA+PSAwKSBqb2JzLnNwbGljZShpZHgsIDEpO1xuXHRcdFx0XHRcdGNvbnN0IHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSk7XG5cdFx0XHRcdFx0aWYgKHMpIHMuZmFpbGVkKys7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0fTtcblxuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCBwcm9jZXNzb3IuaGFuZGxlcih3b3JrZXJKb2IpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0Ly8gSGFuZGxlciB0aHJldyAtIHRyZWF0IGFzIGZhaWx1cmVcblx0XHRcdGlmIChpbnRlcm5hbEpvYi5zdGF0dXMgPT09IFwiYWN0aXZlXCIpIHtcblx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJmYWlsZWRcIjtcblx0XHRcdFx0Y29uc3QgaWR4ID0gam9icy5pbmRleE9mKGludGVybmFsSm9iKTtcblx0XHRcdFx0aWYgKGlkeCA+PSAwKSBqb2JzLnNwbGljZShpZHgsIDEpO1xuXHRcdFx0XHRjb25zdCBzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpO1xuXHRcdFx0XHRpZiAocykgcy5mYWlsZWQrKztcblx0XHRcdH1cblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0cHJvY2Vzc29yLmFjdGl2ZS0tO1xuXHRcdH1cblx0fVxufVxuIl19
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KafkaAdapter — v0.7 PR 5 — Worker adapter backed by Apache Kafka via
|
|
3
|
+
* `kafkajs`. Consumes from a topic (the `queue` field) with a
|
|
4
|
+
* consumer-group identifier; produces via the same client.
|
|
5
|
+
*
|
|
6
|
+
* Kafka is fundamentally a streaming platform — not a queue — so a
|
|
7
|
+
* few semantics differ from BullMQ/SQS/RabbitMQ:
|
|
8
|
+
*
|
|
9
|
+
* - **Ordering**: per-partition, not per-topic. Set the partition
|
|
10
|
+
* key via the `dedupId` field on `addJob` to keep related
|
|
11
|
+
* messages on the same partition.
|
|
12
|
+
* - **Retries**: Kafka doesn't have a broker-side retry concept.
|
|
13
|
+
* The adapter re-throws on handler failure; offset commit is
|
|
14
|
+
* suppressed so the consumer re-polls the message on the next
|
|
15
|
+
* cycle. For real retry semantics, layer a dead-letter topic.
|
|
16
|
+
* - **Stats**: KafkaJS exposes consumer-group lag via its admin
|
|
17
|
+
* client; the lag count is reported as `waiting`. Other stats
|
|
18
|
+
* are tracked locally per consumer.
|
|
19
|
+
*
|
|
20
|
+
* Requires `kafkajs` as a peer dependency:
|
|
21
|
+
*
|
|
22
|
+
* bun add kafkajs
|
|
23
|
+
*
|
|
24
|
+
* Environment variables (read at adapter construction):
|
|
25
|
+
* - `KAFKA_BROKERS` — comma-separated list (default `localhost:9092`).
|
|
26
|
+
* - `KAFKA_CLIENT_ID` — client.id (default `"blok-worker"`).
|
|
27
|
+
* - `KAFKA_SASL_USERNAME` — SASL/PLAIN username (optional).
|
|
28
|
+
* - `KAFKA_SASL_PASSWORD` — SASL/PLAIN password (optional).
|
|
29
|
+
* - `KAFKA_SSL` — when `"true"`, enable TLS.
|
|
30
|
+
*/
|
|
31
|
+
import type { WorkerTriggerOpts } from "@blokjs/helper";
|
|
32
|
+
import type { WorkerAdapter, WorkerJob, WorkerQueueStats } from "../WorkerTrigger";
|
|
33
|
+
export interface KafkaConfig {
|
|
34
|
+
brokers: string[];
|
|
35
|
+
clientId: string;
|
|
36
|
+
saslUsername?: string;
|
|
37
|
+
saslPassword?: string;
|
|
38
|
+
ssl: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare class KafkaAdapter implements WorkerAdapter {
|
|
41
|
+
readonly provider: "kafka";
|
|
42
|
+
private readonly config;
|
|
43
|
+
private kafka;
|
|
44
|
+
private handle;
|
|
45
|
+
private connected;
|
|
46
|
+
private stats;
|
|
47
|
+
constructor(config?: Partial<KafkaConfig>);
|
|
48
|
+
connect(): Promise<void>;
|
|
49
|
+
disconnect(): Promise<void>;
|
|
50
|
+
process(config: WorkerTriggerOpts, handler: (job: WorkerJob) => Promise<void>): Promise<void>;
|
|
51
|
+
addJob(queue: string, data: unknown, opts?: {
|
|
52
|
+
priority?: number;
|
|
53
|
+
delay?: number;
|
|
54
|
+
retries?: number;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
jobId?: string;
|
|
57
|
+
}): Promise<string>;
|
|
58
|
+
stopProcessing(queue: string): Promise<void>;
|
|
59
|
+
isConnected(): boolean;
|
|
60
|
+
healthCheck(): Promise<boolean>;
|
|
61
|
+
getQueueStats(queue: string): Promise<WorkerQueueStats>;
|
|
62
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KafkaAdapter — v0.7 PR 5 — Worker adapter backed by Apache Kafka via
|
|
3
|
+
* `kafkajs`. Consumes from a topic (the `queue` field) with a
|
|
4
|
+
* consumer-group identifier; produces via the same client.
|
|
5
|
+
*
|
|
6
|
+
* Kafka is fundamentally a streaming platform — not a queue — so a
|
|
7
|
+
* few semantics differ from BullMQ/SQS/RabbitMQ:
|
|
8
|
+
*
|
|
9
|
+
* - **Ordering**: per-partition, not per-topic. Set the partition
|
|
10
|
+
* key via the `dedupId` field on `addJob` to keep related
|
|
11
|
+
* messages on the same partition.
|
|
12
|
+
* - **Retries**: Kafka doesn't have a broker-side retry concept.
|
|
13
|
+
* The adapter re-throws on handler failure; offset commit is
|
|
14
|
+
* suppressed so the consumer re-polls the message on the next
|
|
15
|
+
* cycle. For real retry semantics, layer a dead-letter topic.
|
|
16
|
+
* - **Stats**: KafkaJS exposes consumer-group lag via its admin
|
|
17
|
+
* client; the lag count is reported as `waiting`. Other stats
|
|
18
|
+
* are tracked locally per consumer.
|
|
19
|
+
*
|
|
20
|
+
* Requires `kafkajs` as a peer dependency:
|
|
21
|
+
*
|
|
22
|
+
* bun add kafkajs
|
|
23
|
+
*
|
|
24
|
+
* Environment variables (read at adapter construction):
|
|
25
|
+
* - `KAFKA_BROKERS` — comma-separated list (default `localhost:9092`).
|
|
26
|
+
* - `KAFKA_CLIENT_ID` — client.id (default `"blok-worker"`).
|
|
27
|
+
* - `KAFKA_SASL_USERNAME` — SASL/PLAIN username (optional).
|
|
28
|
+
* - `KAFKA_SASL_PASSWORD` — SASL/PLAIN password (optional).
|
|
29
|
+
* - `KAFKA_SSL` — when `"true"`, enable TLS.
|
|
30
|
+
*/
|
|
31
|
+
import { v4 as uuid } from "uuid";
|
|
32
|
+
export class KafkaAdapter {
|
|
33
|
+
provider = "kafka";
|
|
34
|
+
config;
|
|
35
|
+
// biome-ignore lint/suspicious/noExplicitAny: kafkajs's exported `Kafka` constructor is loosely typed.
|
|
36
|
+
kafka = null;
|
|
37
|
+
handle = { consumers: new Map() };
|
|
38
|
+
connected = false;
|
|
39
|
+
stats = new Map();
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.config = {
|
|
42
|
+
brokers: config?.brokers ?? (process.env.KAFKA_BROKERS ?? "localhost:9092").split(",").map((s) => s.trim()),
|
|
43
|
+
clientId: config?.clientId ?? process.env.KAFKA_CLIENT_ID ?? "blok-worker",
|
|
44
|
+
saslUsername: config?.saslUsername ?? process.env.KAFKA_SASL_USERNAME,
|
|
45
|
+
saslPassword: config?.saslPassword ?? process.env.KAFKA_SASL_PASSWORD,
|
|
46
|
+
ssl: config?.ssl ?? process.env.KAFKA_SSL === "true",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async connect() {
|
|
50
|
+
if (this.connected)
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: kafkajs is a runtime-loaded peer dep.
|
|
54
|
+
const kafkajs = await import("kafkajs");
|
|
55
|
+
const sasl = this.config.saslUsername && this.config.saslPassword
|
|
56
|
+
? { mechanism: "plain", username: this.config.saslUsername, password: this.config.saslPassword }
|
|
57
|
+
: undefined;
|
|
58
|
+
this.kafka = new kafkajs.Kafka({
|
|
59
|
+
clientId: this.config.clientId,
|
|
60
|
+
brokers: this.config.brokers,
|
|
61
|
+
ssl: this.config.ssl,
|
|
62
|
+
sasl,
|
|
63
|
+
});
|
|
64
|
+
this.handle.producer = this.kafka.producer();
|
|
65
|
+
await this.handle.producer?.connect();
|
|
66
|
+
this.handle.admin = this.kafka.admin();
|
|
67
|
+
await this.handle.admin?.connect();
|
|
68
|
+
this.connected = true;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw new Error(`[blok][kafka] connect failed: ${err.message}. Install kafkajs as a peer dependency: bun add kafkajs`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async disconnect() {
|
|
75
|
+
if (!this.connected)
|
|
76
|
+
return;
|
|
77
|
+
for (const [, consumer] of this.handle.consumers) {
|
|
78
|
+
try {
|
|
79
|
+
await consumer.disconnect();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
/* ignore */
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
this.handle.consumers.clear();
|
|
86
|
+
try {
|
|
87
|
+
await this.handle.producer?.disconnect();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* ignore */
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
await this.handle.admin?.disconnect();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* ignore */
|
|
97
|
+
}
|
|
98
|
+
this.connected = false;
|
|
99
|
+
}
|
|
100
|
+
async process(config, handler) {
|
|
101
|
+
if (!this.connected)
|
|
102
|
+
throw new Error("[blok][kafka] not connected. Call connect() first.");
|
|
103
|
+
const groupId = config.consumerGroup ?? `${config.queue}-group`;
|
|
104
|
+
const consumer = this.kafka.consumer({ groupId });
|
|
105
|
+
await consumer.connect();
|
|
106
|
+
await consumer.subscribe({ topic: config.queue, fromBeginning: config.fromBeginning === true });
|
|
107
|
+
this.handle.consumers.set(config.queue, consumer);
|
|
108
|
+
this.stats.set(config.queue, { completed: 0, failed: 0, active: 0 });
|
|
109
|
+
const stats = this.stats.get(config.queue);
|
|
110
|
+
await consumer.run({
|
|
111
|
+
autoCommit: config.ack !== false,
|
|
112
|
+
eachMessage: async ({ message, }) => {
|
|
113
|
+
const payloadString = message.value?.toString("utf8") ?? "";
|
|
114
|
+
let data;
|
|
115
|
+
try {
|
|
116
|
+
data = payloadString.length > 0 ? JSON.parse(payloadString) : null;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
data = payloadString;
|
|
120
|
+
}
|
|
121
|
+
const headers = {};
|
|
122
|
+
if (message.headers) {
|
|
123
|
+
for (const [k, v] of Object.entries(message.headers))
|
|
124
|
+
headers[k] = v?.toString("utf8") ?? "";
|
|
125
|
+
}
|
|
126
|
+
const job = {
|
|
127
|
+
id: message.key?.toString("utf8") ?? `${config.queue}:${message.offset}`,
|
|
128
|
+
data,
|
|
129
|
+
headers,
|
|
130
|
+
queue: config.queue,
|
|
131
|
+
priority: config.priority ?? 0,
|
|
132
|
+
attempts: 0,
|
|
133
|
+
maxRetries: config.retries ?? 0,
|
|
134
|
+
createdAt: new Date(Number.parseInt(message.timestamp, 10)),
|
|
135
|
+
timeout: config.timeout,
|
|
136
|
+
raw: message,
|
|
137
|
+
complete: async () => {
|
|
138
|
+
stats.completed += 1;
|
|
139
|
+
},
|
|
140
|
+
fail: async (_err) => {
|
|
141
|
+
stats.failed += 1;
|
|
142
|
+
throw _err;
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
stats.active += 1;
|
|
146
|
+
try {
|
|
147
|
+
await handler(job);
|
|
148
|
+
stats.completed += 1;
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
stats.failed += 1;
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
stats.active = Math.max(0, stats.active - 1);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async addJob(queue, data, opts) {
|
|
161
|
+
if (!this.connected)
|
|
162
|
+
throw new Error("[blok][kafka] not connected. Call connect() first.");
|
|
163
|
+
if (!this.handle.producer)
|
|
164
|
+
throw new Error("[blok][kafka] producer not initialized");
|
|
165
|
+
const key = opts?.jobId ?? uuid();
|
|
166
|
+
const payload = typeof data === "string" ? data : JSON.stringify(data);
|
|
167
|
+
await this.handle.producer.send({
|
|
168
|
+
topic: queue,
|
|
169
|
+
messages: [
|
|
170
|
+
{
|
|
171
|
+
key,
|
|
172
|
+
value: payload,
|
|
173
|
+
headers: opts?.delay ? { "x-blok-delay-ms": String(opts.delay) } : undefined,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
return key;
|
|
178
|
+
}
|
|
179
|
+
async stopProcessing(queue) {
|
|
180
|
+
const consumer = this.handle.consumers.get(queue);
|
|
181
|
+
if (consumer) {
|
|
182
|
+
try {
|
|
183
|
+
await consumer.stop();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
/* ignore */
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
await consumer.disconnect();
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
/* ignore */
|
|
193
|
+
}
|
|
194
|
+
this.handle.consumers.delete(queue);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
isConnected() {
|
|
198
|
+
return this.connected;
|
|
199
|
+
}
|
|
200
|
+
async healthCheck() {
|
|
201
|
+
if (!this.connected || !this.handle.admin)
|
|
202
|
+
return false;
|
|
203
|
+
try {
|
|
204
|
+
await this.handle.admin.fetchTopicOffsets("__consumer_offsets");
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async getQueueStats(queue) {
|
|
212
|
+
const counters = this.stats.get(queue) ?? { completed: 0, failed: 0, active: 0 };
|
|
213
|
+
let waiting = 0;
|
|
214
|
+
if (this.handle.admin) {
|
|
215
|
+
try {
|
|
216
|
+
const offsets = await this.handle.admin.fetchTopicOffsets(queue);
|
|
217
|
+
// Approximate: total committed offsets across partitions. Real lag
|
|
218
|
+
// requires admin.fetchOffsets({ groupId }) — skipped here to keep
|
|
219
|
+
// the call cheap; production deployments should use Kafka's
|
|
220
|
+
// dedicated lag metrics anyway.
|
|
221
|
+
waiting = offsets.reduce((sum, p) => sum + Number.parseInt(p.offset, 10), 0);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
waiting = 0;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
waiting,
|
|
229
|
+
active: counters.active,
|
|
230
|
+
completed: counters.completed,
|
|
231
|
+
failed: counters.failed,
|
|
232
|
+
delayed: 0,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2Fma2FBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0thZmthQWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQXNDbEMsTUFBTSxPQUFPLFlBQVk7SUFDZixRQUFRLEdBQUcsT0FBZ0IsQ0FBQztJQUNwQixNQUFNLENBQWM7SUFDckMsdUdBQXVHO0lBQy9GLEtBQUssR0FBUSxJQUFJLENBQUM7SUFDbEIsTUFBTSxHQUFrQixFQUFFLFNBQVMsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7SUFDakQsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixLQUFLLEdBQW9DLElBQUksR0FBRyxFQUFFLENBQUM7SUFFM0QsWUFBWSxNQUE2QjtRQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ2IsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMzRyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsSUFBSSxhQUFhO1lBQzFFLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CO1lBQ3JFLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CO1lBQ3JFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxLQUFLLE1BQU07U0FDcEQsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTztRQUNaLElBQUksSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPO1FBQzNCLElBQUksQ0FBQztZQUNKLG9GQUFvRjtZQUNwRixNQUFNLE9BQU8sR0FBUSxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM3QyxNQUFNLElBQUksR0FDVCxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVk7Z0JBQ25ELENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtnQkFDaEcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNkLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDO2dCQUM5QixRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO2dCQUM5QixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPO2dCQUM1QixHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHO2dCQUNwQixJQUFJO2FBQ0osQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN2QixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQ2QsaUNBQWtDLEdBQWEsQ0FBQyxPQUFPLHlEQUF5RCxDQUNoSCxDQUFDO1FBQ0gsQ0FBQztJQUNGLENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVTtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU87UUFDNUIsS0FBSyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQztnQkFDSixNQUFNLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUM3QixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNSLFlBQVk7WUFDYixDQUFDO1FBQ0YsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQztZQUNKLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLENBQUM7UUFDMUMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNSLFlBQVk7UUFDYixDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0osTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztRQUN2QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1IsWUFBWTtRQUNiLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUF5QixFQUFFLE9BQTBDO1FBQ2xGLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUMzRixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsYUFBYSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1FBQ2hFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNsRCxNQUFNLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN6QixNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWEsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBdUIsQ0FBQztRQUVqRSxNQUFNLFFBQVEsQ0FBQyxHQUFHLENBQUM7WUFDbEIsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLEtBQUssS0FBSztZQUNoQyxXQUFXLEVBQUUsS0FBSyxFQUFFLEVBQ25CLE9BQU8sR0FHUCxFQUFFLEVBQUU7Z0JBQ0osTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUM1RCxJQUFJLElBQWEsQ0FBQztnQkFDbEIsSUFBSSxDQUFDO29CQUNKLElBQUksR0FBRyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNwRSxDQUFDO2dCQUFDLE1BQU0sQ0FBQztvQkFDUixJQUFJLEdBQUcsYUFBYSxDQUFDO2dCQUN0QixDQUFDO2dCQUNELE1BQU0sT0FBTyxHQUEyQixFQUFFLENBQUM7Z0JBQzNDLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNyQixLQUFLLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO3dCQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDOUYsQ0FBQztnQkFDRCxNQUFNLEdBQUcsR0FBYztvQkFDdEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO29CQUN4RSxJQUFJO29CQUNKLE9BQU87b0JBQ1AsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO29CQUNuQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsSUFBSSxDQUFDO29CQUM5QixRQUFRLEVBQUUsQ0FBQztvQkFDWCxVQUFVLEVBQUUsTUFBTSxDQUFDLE9BQU8sSUFBSSxDQUFDO29CQUMvQixTQUFTLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUMzRCxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87b0JBQ3ZCLEdBQUcsRUFBRSxPQUFPO29CQUNaLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTt3QkFDcEIsS0FBSyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUM7b0JBQ3RCLENBQUM7b0JBQ0QsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFXLEVBQUUsRUFBRTt3QkFDM0IsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7d0JBQ2xCLE1BQU0sSUFBSSxDQUFDO29CQUNaLENBQUM7aUJBQ0QsQ0FBQztnQkFDRixLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxDQUFDO29CQUNKLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNuQixLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztnQkFDdEIsQ0FBQztnQkFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO29CQUNkLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO29CQUNsQixNQUFNLEdBQUcsQ0FBQztnQkFDWCxDQUFDO3dCQUFTLENBQUM7b0JBQ1YsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUM5QyxDQUFDO1lBQ0YsQ0FBQztTQUNELENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUNYLEtBQWEsRUFDYixJQUFhLEVBQ2IsSUFBZ0c7UUFFaEcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQzNGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVE7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDckYsTUFBTSxHQUFHLEdBQUcsSUFBSSxFQUFFLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNsQyxNQUFNLE9BQU8sR0FBRyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RSxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztZQUMvQixLQUFLLEVBQUUsS0FBSztZQUNaLFFBQVEsRUFBRTtnQkFDVDtvQkFDQyxHQUFHO29CQUNILEtBQUssRUFBRSxPQUFPO29CQUNkLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUztpQkFDNUU7YUFDRDtTQUNELENBQUMsQ0FBQztRQUNILE9BQU8sR0FBRyxDQUFDO0lBQ1osQ0FBQztJQUVELEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYTtRQUNqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQztnQkFDSixNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN2QixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNSLFlBQVk7WUFDYixDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNKLE1BQU0sUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzdCLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1IsWUFBWTtZQUNiLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckMsQ0FBQztJQUNGLENBQUM7SUFFRCxXQUFXO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3hELElBQUksQ0FBQztZQUNKLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNoRSxPQUFPLElBQUksQ0FBQztRQUNiLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUixPQUFPLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDRixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFhO1FBQ2hDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNqRixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQztnQkFDSixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqRSxtRUFBbUU7Z0JBQ25FLGtFQUFrRTtnQkFDbEUsNERBQTREO2dCQUM1RCxnQ0FBZ0M7Z0JBQ2hDLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RSxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNSLE9BQU8sR0FBRyxDQUFDLENBQUM7WUFDYixDQUFDO1FBQ0YsQ0FBQztRQUNELE9BQU87WUFDTixPQUFPO1lBQ1AsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1lBQ3ZCLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztZQUM3QixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDdkIsT0FBTyxFQUFFLENBQUM7U0FDVixDQUFDO0lBQ0gsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBLYWZrYUFkYXB0ZXIg4oCUIHYwLjcgUFIgNSDigJQgV29ya2VyIGFkYXB0ZXIgYmFja2VkIGJ5IEFwYWNoZSBLYWZrYSB2aWFcbiAqIGBrYWZrYWpzYC4gQ29uc3VtZXMgZnJvbSBhIHRvcGljICh0aGUgYHF1ZXVlYCBmaWVsZCkgd2l0aCBhXG4gKiBjb25zdW1lci1ncm91cCBpZGVudGlmaWVyOyBwcm9kdWNlcyB2aWEgdGhlIHNhbWUgY2xpZW50LlxuICpcbiAqIEthZmthIGlzIGZ1bmRhbWVudGFsbHkgYSBzdHJlYW1pbmcgcGxhdGZvcm0g4oCUIG5vdCBhIHF1ZXVlIOKAlCBzbyBhXG4gKiBmZXcgc2VtYW50aWNzIGRpZmZlciBmcm9tIEJ1bGxNUS9TUVMvUmFiYml0TVE6XG4gKlxuICogICAtICoqT3JkZXJpbmcqKjogcGVyLXBhcnRpdGlvbiwgbm90IHBlci10b3BpYy4gU2V0IHRoZSBwYXJ0aXRpb25cbiAqICAgICBrZXkgdmlhIHRoZSBgZGVkdXBJZGAgZmllbGQgb24gYGFkZEpvYmAgdG8ga2VlcCByZWxhdGVkXG4gKiAgICAgbWVzc2FnZXMgb24gdGhlIHNhbWUgcGFydGl0aW9uLlxuICogICAtICoqUmV0cmllcyoqOiBLYWZrYSBkb2Vzbid0IGhhdmUgYSBicm9rZXItc2lkZSByZXRyeSBjb25jZXB0LlxuICogICAgIFRoZSBhZGFwdGVyIHJlLXRocm93cyBvbiBoYW5kbGVyIGZhaWx1cmU7IG9mZnNldCBjb21taXQgaXNcbiAqICAgICBzdXBwcmVzc2VkIHNvIHRoZSBjb25zdW1lciByZS1wb2xscyB0aGUgbWVzc2FnZSBvbiB0aGUgbmV4dFxuICogICAgIGN5Y2xlLiBGb3IgcmVhbCByZXRyeSBzZW1hbnRpY3MsIGxheWVyIGEgZGVhZC1sZXR0ZXIgdG9waWMuXG4gKiAgIC0gKipTdGF0cyoqOiBLYWZrYUpTIGV4cG9zZXMgY29uc3VtZXItZ3JvdXAgbGFnIHZpYSBpdHMgYWRtaW5cbiAqICAgICBjbGllbnQ7IHRoZSBsYWcgY291bnQgaXMgcmVwb3J0ZWQgYXMgYHdhaXRpbmdgLiBPdGhlciBzdGF0c1xuICogICAgIGFyZSB0cmFja2VkIGxvY2FsbHkgcGVyIGNvbnN1bWVyLlxuICpcbiAqIFJlcXVpcmVzIGBrYWZrYWpzYCBhcyBhIHBlZXIgZGVwZW5kZW5jeTpcbiAqXG4gKiAgICAgYnVuIGFkZCBrYWZrYWpzXG4gKlxuICogRW52aXJvbm1lbnQgdmFyaWFibGVzIChyZWFkIGF0IGFkYXB0ZXIgY29uc3RydWN0aW9uKTpcbiAqICAgLSBgS0FGS0FfQlJPS0VSU2AgICAgICAgICAgIOKAlCBjb21tYS1zZXBhcmF0ZWQgbGlzdCAoZGVmYXVsdCBgbG9jYWxob3N0OjkwOTJgKS5cbiAqICAgLSBgS0FGS0FfQ0xJRU5UX0lEYCAgICAgICAgIOKAlCBjbGllbnQuaWQgKGRlZmF1bHQgYFwiYmxvay13b3JrZXJcImApLlxuICogICAtIGBLQUZLQV9TQVNMX1VTRVJOQU1FYCAgICAg4oCUIFNBU0wvUExBSU4gdXNlcm5hbWUgKG9wdGlvbmFsKS5cbiAqICAgLSBgS0FGS0FfU0FTTF9QQVNTV09SRGAgICAgIOKAlCBTQVNML1BMQUlOIHBhc3N3b3JkIChvcHRpb25hbCkuXG4gKiAgIC0gYEtBRktBX1NTTGAgICAgICAgICAgICAgICDigJQgd2hlbiBgXCJ0cnVlXCJgLCBlbmFibGUgVExTLlxuICovXG5cbmltcG9ydCB0eXBlIHsgV29ya2VyVHJpZ2dlck9wdHMgfSBmcm9tIFwiQGJsb2tqcy9oZWxwZXJcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHR5cGUgeyBXb3JrZXJBZGFwdGVyLCBXb3JrZXJKb2IsIFdvcmtlclF1ZXVlU3RhdHMgfSBmcm9tIFwiLi4vV29ya2VyVHJpZ2dlclwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEthZmthQ29uZmlnIHtcblx0YnJva2Vyczogc3RyaW5nW107XG5cdGNsaWVudElkOiBzdHJpbmc7XG5cdHNhc2xVc2VybmFtZT86IHN0cmluZztcblx0c2FzbFBhc3N3b3JkPzogc3RyaW5nO1xuXHRzc2w6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBLYWZrYUpzSGFuZGxlIHtcblx0cHJvZHVjZXI/OiB7XG5cdFx0Y29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRkaXNjb25uZWN0OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdHNlbmQ6IChhcmdzOiB1bmtub3duKSA9PiBQcm9taXNlPHVua25vd24+O1xuXHR9O1xuXHRjb25zdW1lcnM6IE1hcDxcblx0XHRzdHJpbmcsXG5cdFx0e1xuXHRcdFx0ZGlzY29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRcdHN0b3A6ICgpID0+IFByb21pc2U8dm9pZD47XG5cdFx0XHRydW46IChvcHRzOiB1bmtub3duKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdH1cblx0Pjtcblx0YWRtaW4/OiB7XG5cdFx0Y29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRkaXNjb25uZWN0OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdGZldGNoVG9waWNPZmZzZXRzOiAodG9waWM6IHN0cmluZykgPT4gUHJvbWlzZTxBcnJheTx7IHBhcnRpdGlvbjogbnVtYmVyOyBvZmZzZXQ6IHN0cmluZyB9Pj47XG5cdH07XG59XG5cbmludGVyZmFjZSBRdWV1ZVN0YXRzQ291bnRlcnMge1xuXHRjb21wbGV0ZWQ6IG51bWJlcjtcblx0ZmFpbGVkOiBudW1iZXI7XG5cdGFjdGl2ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgS2Fma2FBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJrYWZrYVwiIGFzIGNvbnN0O1xuXHRwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogS2Fma2FDb25maWc7XG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueToga2Fma2FqcydzIGV4cG9ydGVkIGBLYWZrYWAgY29uc3RydWN0b3IgaXMgbG9vc2VseSB0eXBlZC5cblx0cHJpdmF0ZSBrYWZrYTogYW55ID0gbnVsbDtcblx0cHJpdmF0ZSBoYW5kbGU6IEthZmthSnNIYW5kbGUgPSB7IGNvbnN1bWVyczogbmV3IE1hcCgpIH07XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIFF1ZXVlU3RhdHNDb3VudGVycz4gPSBuZXcgTWFwKCk7XG5cblx0Y29uc3RydWN0b3IoY29uZmlnPzogUGFydGlhbDxLYWZrYUNvbmZpZz4pIHtcblx0XHR0aGlzLmNvbmZpZyA9IHtcblx0XHRcdGJyb2tlcnM6IGNvbmZpZz8uYnJva2VycyA/PyAocHJvY2Vzcy5lbnYuS0FGS0FfQlJPS0VSUyA/PyBcImxvY2FsaG9zdDo5MDkyXCIpLnNwbGl0KFwiLFwiKS5tYXAoKHMpID0+IHMudHJpbSgpKSxcblx0XHRcdGNsaWVudElkOiBjb25maWc/LmNsaWVudElkID8/IHByb2Nlc3MuZW52LktBRktBX0NMSUVOVF9JRCA/PyBcImJsb2std29ya2VyXCIsXG5cdFx0XHRzYXNsVXNlcm5hbWU6IGNvbmZpZz8uc2FzbFVzZXJuYW1lID8/IHByb2Nlc3MuZW52LktBRktBX1NBU0xfVVNFUk5BTUUsXG5cdFx0XHRzYXNsUGFzc3dvcmQ6IGNvbmZpZz8uc2FzbFBhc3N3b3JkID8/IHByb2Nlc3MuZW52LktBRktBX1NBU0xfUEFTU1dPUkQsXG5cdFx0XHRzc2w6IGNvbmZpZz8uc3NsID8/IHByb2Nlc3MuZW52LktBRktBX1NTTCA9PT0gXCJ0cnVlXCIsXG5cdFx0fTtcblx0fVxuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueToga2Fma2FqcyBpcyBhIHJ1bnRpbWUtbG9hZGVkIHBlZXIgZGVwLlxuXHRcdFx0Y29uc3Qga2Fma2FqczogYW55ID0gYXdhaXQgaW1wb3J0KFwia2Fma2Fqc1wiKTtcblx0XHRcdGNvbnN0IHNhc2wgPVxuXHRcdFx0XHR0aGlzLmNvbmZpZy5zYXNsVXNlcm5hbWUgJiYgdGhpcy5jb25maWcuc2FzbFBhc3N3b3JkXG5cdFx0XHRcdFx0PyB7IG1lY2hhbmlzbTogXCJwbGFpblwiLCB1c2VybmFtZTogdGhpcy5jb25maWcuc2FzbFVzZXJuYW1lLCBwYXNzd29yZDogdGhpcy5jb25maWcuc2FzbFBhc3N3b3JkIH1cblx0XHRcdFx0XHQ6IHVuZGVmaW5lZDtcblx0XHRcdHRoaXMua2Fma2EgPSBuZXcga2Fma2Fqcy5LYWZrYSh7XG5cdFx0XHRcdGNsaWVudElkOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcblx0XHRcdFx0YnJva2VyczogdGhpcy5jb25maWcuYnJva2Vycyxcblx0XHRcdFx0c3NsOiB0aGlzLmNvbmZpZy5zc2wsXG5cdFx0XHRcdHNhc2wsXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuaGFuZGxlLnByb2R1Y2VyID0gdGhpcy5rYWZrYS5wcm9kdWNlcigpO1xuXHRcdFx0YXdhaXQgdGhpcy5oYW5kbGUucHJvZHVjZXI/LmNvbm5lY3QoKTtcblx0XHRcdHRoaXMuaGFuZGxlLmFkbWluID0gdGhpcy5rYWZrYS5hZG1pbigpO1xuXHRcdFx0YXdhaXQgdGhpcy5oYW5kbGUuYWRtaW4/LmNvbm5lY3QoKTtcblx0XHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YFtibG9rXVtrYWZrYV0gY29ubmVjdCBmYWlsZWQ6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX0uIEluc3RhbGwga2Fma2FqcyBhcyBhIHBlZXIgZGVwZW5kZW5jeTogYnVuIGFkZCBrYWZrYWpzYCxcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cdFx0Zm9yIChjb25zdCBbLCBjb25zdW1lcl0gb2YgdGhpcy5oYW5kbGUuY29uc3VtZXJzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5kaXNjb25uZWN0KCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuaGFuZGxlLmNvbnN1bWVycy5jbGVhcigpO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5wcm9kdWNlcj8uZGlzY29ubmVjdCgpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbj8uZGlzY29ubmVjdCgpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG5cdH1cblxuXHRhc3luYyBwcm9jZXNzKGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsIGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHRocm93IG5ldyBFcnJvcihcIltibG9rXVtrYWZrYV0gbm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdGNvbnN0IGdyb3VwSWQgPSBjb25maWcuY29uc3VtZXJHcm91cCA/PyBgJHtjb25maWcucXVldWV9LWdyb3VwYDtcblx0XHRjb25zdCBjb25zdW1lciA9IHRoaXMua2Fma2EuY29uc3VtZXIoeyBncm91cElkIH0pO1xuXHRcdGF3YWl0IGNvbnN1bWVyLmNvbm5lY3QoKTtcblx0XHRhd2FpdCBjb25zdW1lci5zdWJzY3JpYmUoeyB0b3BpYzogY29uZmlnLnF1ZXVlLCBmcm9tQmVnaW5uaW5nOiBjb25maWcuZnJvbUJlZ2lubmluZyA9PT0gdHJ1ZSB9KTtcblx0XHR0aGlzLmhhbmRsZS5jb25zdW1lcnMuc2V0KGNvbmZpZy5xdWV1ZSwgY29uc3VtZXIpO1xuXHRcdHRoaXMuc3RhdHMuc2V0KGNvbmZpZy5xdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCwgYWN0aXZlOiAwIH0pO1xuXHRcdGNvbnN0IHN0YXRzID0gdGhpcy5zdGF0cy5nZXQoY29uZmlnLnF1ZXVlKSBhcyBRdWV1ZVN0YXRzQ291bnRlcnM7XG5cblx0XHRhd2FpdCBjb25zdW1lci5ydW4oe1xuXHRcdFx0YXV0b0NvbW1pdDogY29uZmlnLmFjayAhPT0gZmFsc2UsXG5cdFx0XHRlYWNoTWVzc2FnZTogYXN5bmMgKHtcblx0XHRcdFx0bWVzc2FnZSxcblx0XHRcdH06IHtcblx0XHRcdFx0bWVzc2FnZTogeyBrZXk/OiBCdWZmZXI7IHZhbHVlPzogQnVmZmVyOyBvZmZzZXQ6IHN0cmluZzsgdGltZXN0YW1wOiBzdHJpbmc7IGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBCdWZmZXI+IH07XG5cdFx0XHR9KSA9PiB7XG5cdFx0XHRcdGNvbnN0IHBheWxvYWRTdHJpbmcgPSBtZXNzYWdlLnZhbHVlPy50b1N0cmluZyhcInV0ZjhcIikgPz8gXCJcIjtcblx0XHRcdFx0bGV0IGRhdGE6IHVua25vd247XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0ZGF0YSA9IHBheWxvYWRTdHJpbmcubGVuZ3RoID4gMCA/IEpTT04ucGFyc2UocGF5bG9hZFN0cmluZykgOiBudWxsO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRkYXRhID0gcGF5bG9hZFN0cmluZztcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdFx0XHRcdGlmIChtZXNzYWdlLmhlYWRlcnMpIHtcblx0XHRcdFx0XHRmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhtZXNzYWdlLmhlYWRlcnMpKSBoZWFkZXJzW2tdID0gdj8udG9TdHJpbmcoXCJ1dGY4XCIpID8/IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29uc3Qgam9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRcdFx0aWQ6IG1lc3NhZ2Uua2V5Py50b1N0cmluZyhcInV0ZjhcIikgPz8gYCR7Y29uZmlnLnF1ZXVlfToke21lc3NhZ2Uub2Zmc2V0fWAsXG5cdFx0XHRcdFx0ZGF0YSxcblx0XHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRcdHF1ZXVlOiBjb25maWcucXVldWUsXG5cdFx0XHRcdFx0cHJpb3JpdHk6IGNvbmZpZy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0XHRcdGF0dGVtcHRzOiAwLFxuXHRcdFx0XHRcdG1heFJldHJpZXM6IGNvbmZpZy5yZXRyaWVzID8/IDAsXG5cdFx0XHRcdFx0Y3JlYXRlZEF0OiBuZXcgRGF0ZShOdW1iZXIucGFyc2VJbnQobWVzc2FnZS50aW1lc3RhbXAsIDEwKSksXG5cdFx0XHRcdFx0dGltZW91dDogY29uZmlnLnRpbWVvdXQsXG5cdFx0XHRcdFx0cmF3OiBtZXNzYWdlLFxuXHRcdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGZhaWw6IGFzeW5jIChfZXJyOiBFcnJvcikgPT4ge1xuXHRcdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0XHR0aHJvdyBfZXJyO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdH07XG5cdFx0XHRcdHN0YXRzLmFjdGl2ZSArPSAxO1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGF3YWl0IGhhbmRsZXIoam9iKTtcblx0XHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdHN0YXRzLmFjdGl2ZSA9IE1hdGgubWF4KDAsIHN0YXRzLmFjdGl2ZSAtIDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzogeyBwcmlvcml0eT86IG51bWJlcjsgZGVsYXk/OiBudW1iZXI7IHJldHJpZXM/OiBudW1iZXI7IHRpbWVvdXQ/OiBudW1iZXI7IGpvYklkPzogc3RyaW5nIH0sXG5cdCk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW2thZmthXSBub3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0aWYgKCF0aGlzLmhhbmRsZS5wcm9kdWNlcikgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW2thZmthXSBwcm9kdWNlciBub3QgaW5pdGlhbGl6ZWRcIik7XG5cdFx0Y29uc3Qga2V5ID0gb3B0cz8uam9iSWQgPz8gdXVpZCgpO1xuXHRcdGNvbnN0IHBheWxvYWQgPSB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiA/IGRhdGEgOiBKU09OLnN0cmluZ2lmeShkYXRhKTtcblx0XHRhd2FpdCB0aGlzLmhhbmRsZS5wcm9kdWNlci5zZW5kKHtcblx0XHRcdHRvcGljOiBxdWV1ZSxcblx0XHRcdG1lc3NhZ2VzOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRrZXksXG5cdFx0XHRcdFx0dmFsdWU6IHBheWxvYWQsXG5cdFx0XHRcdFx0aGVhZGVyczogb3B0cz8uZGVsYXkgPyB7IFwieC1ibG9rLWRlbGF5LW1zXCI6IFN0cmluZyhvcHRzLmRlbGF5KSB9IDogdW5kZWZpbmVkLFxuXHRcdFx0XHR9LFxuXHRcdFx0XSxcblx0XHR9KTtcblx0XHRyZXR1cm4ga2V5O1xuXHR9XG5cblx0YXN5bmMgc3RvcFByb2Nlc3NpbmcocXVldWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGNvbnN1bWVyID0gdGhpcy5oYW5kbGUuY29uc3VtZXJzLmdldChxdWV1ZSk7XG5cdFx0aWYgKGNvbnN1bWVyKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5zdG9wKCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5kaXNjb25uZWN0KCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmhhbmRsZS5jb25zdW1lcnMuZGVsZXRlKHF1ZXVlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkIHx8ICF0aGlzLmhhbmRsZS5hZG1pbikgcmV0dXJuIGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbi5mZXRjaFRvcGljT2Zmc2V0cyhcIl9fY29uc3VtZXJfb2Zmc2V0c1wiKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGdldFF1ZXVlU3RhdHMocXVldWU6IHN0cmluZyk6IFByb21pc2U8V29ya2VyUXVldWVTdGF0cz4ge1xuXHRcdGNvbnN0IGNvdW50ZXJzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpID8/IHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9O1xuXHRcdGxldCB3YWl0aW5nID0gMDtcblx0XHRpZiAodGhpcy5oYW5kbGUuYWRtaW4pIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGNvbnN0IG9mZnNldHMgPSBhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbi5mZXRjaFRvcGljT2Zmc2V0cyhxdWV1ZSk7XG5cdFx0XHRcdC8vIEFwcHJveGltYXRlOiB0b3RhbCBjb21taXR0ZWQgb2Zmc2V0cyBhY3Jvc3MgcGFydGl0aW9ucy4gUmVhbCBsYWdcblx0XHRcdFx0Ly8gcmVxdWlyZXMgYWRtaW4uZmV0Y2hPZmZzZXRzKHsgZ3JvdXBJZCB9KSDigJQgc2tpcHBlZCBoZXJlIHRvIGtlZXBcblx0XHRcdFx0Ly8gdGhlIGNhbGwgY2hlYXA7IHByb2R1Y3Rpb24gZGVwbG95bWVudHMgc2hvdWxkIHVzZSBLYWZrYSdzXG5cdFx0XHRcdC8vIGRlZGljYXRlZCBsYWcgbWV0cmljcyBhbnl3YXkuXG5cdFx0XHRcdHdhaXRpbmcgPSBvZmZzZXRzLnJlZHVjZSgoc3VtLCBwKSA9PiBzdW0gKyBOdW1iZXIucGFyc2VJbnQocC5vZmZzZXQsIDEwKSwgMCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0d2FpdGluZyA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHR3YWl0aW5nLFxuXHRcdFx0YWN0aXZlOiBjb3VudGVycy5hY3RpdmUsXG5cdFx0XHRjb21wbGV0ZWQ6IGNvdW50ZXJzLmNvbXBsZXRlZCxcblx0XHRcdGZhaWxlZDogY291bnRlcnMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogMCxcblx0XHR9O1xuXHR9XG59XG4iXX0=
|