@pipeline-builder/api-server 3.4.135 → 3.4.137

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.
@@ -1,6 +1,6 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { ErrorCode, createLogger, sendError } from '@pipeline-builder/api-core';
3
+ import { ErrorCode, createLogger, sendError, sendQuotaExceeded } from '@pipeline-builder/api-core';
4
4
  import { getContext } from './get-context.js';
5
5
  const logger = createLogger('check-quota');
6
6
  /** Human-readable labels for quota exceeded messages. */
@@ -51,7 +51,11 @@ export function checkQuota(quotaService, quotaType) {
51
51
  limit: quotaStatus.limit,
52
52
  used: quotaStatus.used,
53
53
  });
54
- sendError(res, 429, `${QUOTA_LABELS[quotaType]} quota exceeded. Please contact your administrator to increase your quota.`, ErrorCode.QUOTA_EXCEEDED, { quota: { type: quotaType, limit: quotaStatus.limit, used: quotaStatus.used, remaining: quotaStatus.remaining } });
54
+ // Route through the shared helper so the check-gate 429 emits the same
55
+ // Retry-After + X-Quota-* headers as the reserve-path 429 (the inline
56
+ // 429 this replaced omitted them). Custom message keeps the
57
+ // "contact your administrator" copy.
58
+ sendQuotaExceeded(res, quotaType, { type: quotaType, limit: quotaStatus.limit, used: quotaStatus.used, remaining: quotaStatus.remaining }, quotaStatus.resetAt, `${QUOTA_LABELS[quotaType]} quota exceeded. Please contact your administrator to increase your quota.`);
55
59
  return;
56
60
  }
57
61
  next();
@@ -67,4 +71,4 @@ export function checkQuota(quotaService, quotaType) {
67
71
  }
68
72
  };
69
73
  }
70
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stcXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NoZWNrLXF1b3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFHaEYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUUzQyx5REFBeUQ7QUFDekQsTUFBTSxZQUFZLEdBQThCO0lBQzlDLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFNBQVMsRUFBRSxVQUFVO0lBQ3JCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFlBQVksRUFBRSxrQkFBa0I7SUFDaEMsVUFBVSxFQUFFLFdBQVc7SUFDdkIsVUFBVSxFQUFFLFlBQVk7SUFDeEIsaUJBQWlCLEVBQUUsbUJBQW1CO0lBQ3RDLFVBQVUsRUFBRSxtQkFBbUI7Q0FDaEMsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQ3hCLFlBQTBCLEVBQzFCLFNBQW9CO0lBRXBCLE9BQU8sS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsSUFBa0IsRUFBaUIsRUFBRTtRQUM5RSxJQUFJLEtBQXlCLENBQUM7UUFDOUIsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QixLQUFLLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDM0IsVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsZ0VBQWdFO1lBQ2hFLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUNwRSxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw2Q0FBNkMsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMvRixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRTNFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLGlCQUFpQixFQUFFO29CQUN6QyxLQUFLO29CQUNMLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSztvQkFDeEIsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJO2lCQUN2QixDQUFDLENBQUM7Z0JBRUgsU0FBUyxDQUNQLEdBQUcsRUFDSCxHQUFHLEVBQ0gsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLDRFQUE0RSxFQUN0RyxTQUFTLENBQUMsY0FBYyxFQUN4QixFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNuSCxDQUFDO2dCQUNGLE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLGdFQUFnRTtZQUNoRSxNQUFNLENBQUMsSUFBSSxDQUFDLDBEQUEwRCxFQUFFO2dCQUN0RSxLQUFLO2dCQUNMLFNBQVM7Z0JBQ1QsS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7YUFDOUQsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBFcnJvckNvZGUsIGNyZWF0ZUxvZ2dlciwgc2VuZEVycm9yIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBRdW90YVR5cGUsIFF1b3RhU2VydmljZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NoZWNrLXF1b3RhJyk7XG5cbi8qKiBIdW1hbi1yZWFkYWJsZSBsYWJlbHMgZm9yIHF1b3RhIGV4Y2VlZGVkIG1lc3NhZ2VzLiAqL1xuY29uc3QgUVVPVEFfTEFCRUxTOiBSZWNvcmQ8UXVvdGFUeXBlLCBzdHJpbmc+ID0ge1xuICBhcGlDYWxsczogJ0FQSSBjYWxsJyxcbiAgYWlDYWxsczogJ0FJIGNhbGwnLFxuICBwaXBlbGluZXM6ICdQaXBlbGluZScsXG4gIHBsdWdpbnM6ICdQbHVnaW4nLFxuICBzdG9yYWdlQnl0ZXM6ICdSZWdpc3RyeSBzdG9yYWdlJyxcbiAgZGFzaGJvYXJkczogJ0Rhc2hib2FyZCcsXG4gIGFsZXJ0UnVsZXM6ICdBbGVydCBydWxlJyxcbiAgYWxlcnREZXN0aW5hdGlvbnM6ICdBbGVydCBkZXN0aW5hdGlvbicsXG4gIGlkcENvbmZpZ3M6ICdJZFAgY29uZmlndXJhdGlvbicsXG59O1xuXG4vKipcbiAqIENyZWF0ZSBtaWRkbGV3YXJlIHRoYXQgY2hlY2tzIGEgc3BlY2lmaWMgcXVvdGEgdHlwZSBiZWZvcmUgcHJvY2VlZGluZy5cbiAqXG4gKiBPbiBxdW90YSBleGNlZWRlZCwgcmV0dXJucyBhIDQyOSByZXNwb25zZSB3aXRoIHF1b3RhIGRldGFpbHMuXG4gKiBPbiBxdW90YSBzZXJ2aWNlIGZhaWx1cmUsIGZhaWxzIG9wZW4gKGFsbG93cyB0aGUgcmVxdWVzdCkuXG4gKlxuICogQHBhcmFtIHF1b3RhU2VydmljZSAtIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKiBAcGFyYW0gcXVvdGFUeXBlIC0gV2hpY2ggcXVvdGEgdG8gY2hlY2sgKGUuZy4gJ2FwaUNhbGxzJywgJ3BpcGVsaW5lcycsICdwbHVnaW5zJylcbiAqIEByZXR1cm5zIEV4cHJlc3MgbWlkZGxld2FyZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tRdW90YShcbiAgcXVvdGFTZXJ2aWNlOiBRdW90YVNlcnZpY2UsXG4gIHF1b3RhVHlwZTogUXVvdGFUeXBlLFxuKSB7XG4gIHJldHVybiBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBsZXQgb3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgYXV0aEhlYWRlciA9ICcnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN0eCA9IGdldENvbnRleHQocmVxKTtcbiAgICAgIG9yZ0lkID0gY3R4LmlkZW50aXR5Lm9yZ0lkO1xuICAgICAgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24gfHwgJyc7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDb250ZXh0IG1pZGRsZXdhcmUgbm90IGFwcGxpZWQg4oCUIGZhaWwgb3BlbiAobG9nIGFuZCBjb250aW51ZSlcbiAgICAgIGxvZ2dlci53YXJuKCdRdW90YSBjaGVjayBza2lwcGVkOiByZXF1ZXN0IGNvbnRleHQgbm90IGluaXRpYWxpemVkJyk7XG4gICAgICByZXR1cm4gbmV4dCgpO1xuICAgIH1cblxuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwMCwgJ09yZ2FuaXphdGlvbiBJRCBpcyByZXF1aXJlZCBmb3IgcXVvdGEgY2hlY2snLCBFcnJvckNvZGUuVkFMSURBVElPTl9FUlJPUik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1b3RhU3RhdHVzID0gYXdhaXQgcXVvdGFTZXJ2aWNlLmNoZWNrKG9yZ0lkLCBxdW90YVR5cGUsIGF1dGhIZWFkZXIpO1xuXG4gICAgICBpZiAoIXF1b3RhU3RhdHVzLmFsbG93ZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYCR7cXVvdGFUeXBlfSBxdW90YSBleGNlZWRlZGAsIHtcbiAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICBsaW1pdDogcXVvdGFTdGF0dXMubGltaXQsXG4gICAgICAgICAgdXNlZDogcXVvdGFTdGF0dXMudXNlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2VuZEVycm9yKFxuICAgICAgICAgIHJlcyxcbiAgICAgICAgICA0MjksXG4gICAgICAgICAgYCR7UVVPVEFfTEFCRUxTW3F1b3RhVHlwZV19IHF1b3RhIGV4Y2VlZGVkLiBQbGVhc2UgY29udGFjdCB5b3VyIGFkbWluaXN0cmF0b3IgdG8gaW5jcmVhc2UgeW91ciBxdW90YS5gLFxuICAgICAgICAgIEVycm9yQ29kZS5RVU9UQV9FWENFRURFRCxcbiAgICAgICAgICB7IHF1b3RhOiB7IHR5cGU6IHF1b3RhVHlwZSwgbGltaXQ6IHF1b3RhU3RhdHVzLmxpbWl0LCB1c2VkOiBxdW90YVN0YXR1cy51c2VkLCByZW1haW5pbmc6IHF1b3RhU3RhdHVzLnJlbWFpbmluZyB9IH0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbmV4dCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBGYWlsIG9wZW4g4oCUIGFsbG93IHRoZSByZXF1ZXN0IGlmIHF1b3RhIHNlcnZpY2UgaXMgdW5hdmFpbGFibGVcbiAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IFF1b3RhIGNoZWNrIGV4Y2VwdGlvbiwgYWxsb3dpbmcgcmVxdWVzdCcsIHtcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIHF1b3RhVHlwZSxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgIH0pO1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stcXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NoZWNrLXF1b3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFHbkcsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUUzQyx5REFBeUQ7QUFDekQsTUFBTSxZQUFZLEdBQThCO0lBQzlDLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFNBQVMsRUFBRSxVQUFVO0lBQ3JCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFlBQVksRUFBRSxrQkFBa0I7SUFDaEMsVUFBVSxFQUFFLFdBQVc7SUFDdkIsVUFBVSxFQUFFLFlBQVk7SUFDeEIsaUJBQWlCLEVBQUUsbUJBQW1CO0lBQ3RDLFVBQVUsRUFBRSxtQkFBbUI7Q0FDaEMsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQ3hCLFlBQTBCLEVBQzFCLFNBQW9CO0lBRXBCLE9BQU8sS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsSUFBa0IsRUFBaUIsRUFBRTtRQUM5RSxJQUFJLEtBQXlCLENBQUM7UUFDOUIsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QixLQUFLLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDM0IsVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsZ0VBQWdFO1lBQ2hFLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUNwRSxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw2Q0FBNkMsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMvRixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRTNFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLGlCQUFpQixFQUFFO29CQUN6QyxLQUFLO29CQUNMLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSztvQkFDeEIsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJO2lCQUN2QixDQUFDLENBQUM7Z0JBRUgsdUVBQXVFO2dCQUN2RSxzRUFBc0U7Z0JBQ3RFLDREQUE0RDtnQkFDNUQscUNBQXFDO2dCQUNyQyxpQkFBaUIsQ0FDZixHQUFHLEVBQ0gsU0FBUyxFQUNULEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsV0FBVyxDQUFDLFNBQVMsRUFBRSxFQUN2RyxXQUFXLENBQUMsT0FBTyxFQUNuQixHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsNEVBQTRFLENBQ3ZHLENBQUM7Z0JBQ0YsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLEVBQUUsQ0FBQztRQUNULENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsZ0VBQWdFO1lBQ2hFLE1BQU0sQ0FBQyxJQUFJLENBQUMsMERBQTBELEVBQUU7Z0JBQ3RFLEtBQUs7Z0JBQ0wsU0FBUztnQkFDVCxLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQzthQUM5RCxDQUFDLENBQUM7WUFDSCxJQUFJLEVBQUUsQ0FBQztRQUNULENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IEVycm9yQ29kZSwgY3JlYXRlTG9nZ2VyLCBzZW5kRXJyb3IsIHNlbmRRdW90YUV4Y2VlZGVkIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBRdW90YVR5cGUsIFF1b3RhU2VydmljZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NoZWNrLXF1b3RhJyk7XG5cbi8qKiBIdW1hbi1yZWFkYWJsZSBsYWJlbHMgZm9yIHF1b3RhIGV4Y2VlZGVkIG1lc3NhZ2VzLiAqL1xuY29uc3QgUVVPVEFfTEFCRUxTOiBSZWNvcmQ8UXVvdGFUeXBlLCBzdHJpbmc+ID0ge1xuICBhcGlDYWxsczogJ0FQSSBjYWxsJyxcbiAgYWlDYWxsczogJ0FJIGNhbGwnLFxuICBwaXBlbGluZXM6ICdQaXBlbGluZScsXG4gIHBsdWdpbnM6ICdQbHVnaW4nLFxuICBzdG9yYWdlQnl0ZXM6ICdSZWdpc3RyeSBzdG9yYWdlJyxcbiAgZGFzaGJvYXJkczogJ0Rhc2hib2FyZCcsXG4gIGFsZXJ0UnVsZXM6ICdBbGVydCBydWxlJyxcbiAgYWxlcnREZXN0aW5hdGlvbnM6ICdBbGVydCBkZXN0aW5hdGlvbicsXG4gIGlkcENvbmZpZ3M6ICdJZFAgY29uZmlndXJhdGlvbicsXG59O1xuXG4vKipcbiAqIENyZWF0ZSBtaWRkbGV3YXJlIHRoYXQgY2hlY2tzIGEgc3BlY2lmaWMgcXVvdGEgdHlwZSBiZWZvcmUgcHJvY2VlZGluZy5cbiAqXG4gKiBPbiBxdW90YSBleGNlZWRlZCwgcmV0dXJucyBhIDQyOSByZXNwb25zZSB3aXRoIHF1b3RhIGRldGFpbHMuXG4gKiBPbiBxdW90YSBzZXJ2aWNlIGZhaWx1cmUsIGZhaWxzIG9wZW4gKGFsbG93cyB0aGUgcmVxdWVzdCkuXG4gKlxuICogQHBhcmFtIHF1b3RhU2VydmljZSAtIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKiBAcGFyYW0gcXVvdGFUeXBlIC0gV2hpY2ggcXVvdGEgdG8gY2hlY2sgKGUuZy4gJ2FwaUNhbGxzJywgJ3BpcGVsaW5lcycsICdwbHVnaW5zJylcbiAqIEByZXR1cm5zIEV4cHJlc3MgbWlkZGxld2FyZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tRdW90YShcbiAgcXVvdGFTZXJ2aWNlOiBRdW90YVNlcnZpY2UsXG4gIHF1b3RhVHlwZTogUXVvdGFUeXBlLFxuKSB7XG4gIHJldHVybiBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBsZXQgb3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgYXV0aEhlYWRlciA9ICcnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN0eCA9IGdldENvbnRleHQocmVxKTtcbiAgICAgIG9yZ0lkID0gY3R4LmlkZW50aXR5Lm9yZ0lkO1xuICAgICAgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24gfHwgJyc7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDb250ZXh0IG1pZGRsZXdhcmUgbm90IGFwcGxpZWQg4oCUIGZhaWwgb3BlbiAobG9nIGFuZCBjb250aW51ZSlcbiAgICAgIGxvZ2dlci53YXJuKCdRdW90YSBjaGVjayBza2lwcGVkOiByZXF1ZXN0IGNvbnRleHQgbm90IGluaXRpYWxpemVkJyk7XG4gICAgICByZXR1cm4gbmV4dCgpO1xuICAgIH1cblxuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwMCwgJ09yZ2FuaXphdGlvbiBJRCBpcyByZXF1aXJlZCBmb3IgcXVvdGEgY2hlY2snLCBFcnJvckNvZGUuVkFMSURBVElPTl9FUlJPUik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1b3RhU3RhdHVzID0gYXdhaXQgcXVvdGFTZXJ2aWNlLmNoZWNrKG9yZ0lkLCBxdW90YVR5cGUsIGF1dGhIZWFkZXIpO1xuXG4gICAgICBpZiAoIXF1b3RhU3RhdHVzLmFsbG93ZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYCR7cXVvdGFUeXBlfSBxdW90YSBleGNlZWRlZGAsIHtcbiAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICBsaW1pdDogcXVvdGFTdGF0dXMubGltaXQsXG4gICAgICAgICAgdXNlZDogcXVvdGFTdGF0dXMudXNlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUm91dGUgdGhyb3VnaCB0aGUgc2hhcmVkIGhlbHBlciBzbyB0aGUgY2hlY2stZ2F0ZSA0MjkgZW1pdHMgdGhlIHNhbWVcbiAgICAgICAgLy8gUmV0cnktQWZ0ZXIgKyBYLVF1b3RhLSogaGVhZGVycyBhcyB0aGUgcmVzZXJ2ZS1wYXRoIDQyOSAodGhlIGlubGluZVxuICAgICAgICAvLyA0MjkgdGhpcyByZXBsYWNlZCBvbWl0dGVkIHRoZW0pLiBDdXN0b20gbWVzc2FnZSBrZWVwcyB0aGVcbiAgICAgICAgLy8gXCJjb250YWN0IHlvdXIgYWRtaW5pc3RyYXRvclwiIGNvcHkuXG4gICAgICAgIHNlbmRRdW90YUV4Y2VlZGVkKFxuICAgICAgICAgIHJlcyxcbiAgICAgICAgICBxdW90YVR5cGUsXG4gICAgICAgICAgeyB0eXBlOiBxdW90YVR5cGUsIGxpbWl0OiBxdW90YVN0YXR1cy5saW1pdCwgdXNlZDogcXVvdGFTdGF0dXMudXNlZCwgcmVtYWluaW5nOiBxdW90YVN0YXR1cy5yZW1haW5pbmcgfSxcbiAgICAgICAgICBxdW90YVN0YXR1cy5yZXNldEF0LFxuICAgICAgICAgIGAke1FVT1RBX0xBQkVMU1txdW90YVR5cGVdfSBxdW90YSBleGNlZWRlZC4gUGxlYXNlIGNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIHRvIGluY3JlYXNlIHlvdXIgcXVvdGEuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBuZXh0KCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhaWwgb3BlbiDigJQgYWxsb3cgdGhlIHJlcXVlc3QgaWYgcXVvdGEgc2VydmljZSBpcyB1bmF2YWlsYWJsZVxuICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgY2hlY2sgZXhjZXB0aW9uLCBhbGxvd2luZyByZXF1ZXN0Jywge1xuICAgICAgICBvcmdJZCxcbiAgICAgICAgcXVvdGFUeXBlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgICBuZXh0KCk7XG4gICAgfVxuICB9O1xufVxuIl19
@@ -2,6 +2,8 @@ export * from './middleware.js';
2
2
  export * from './middleware-factory.js';
3
3
  export * from './context-middleware.js';
4
4
  export * from './check-quota.js';
5
+ export * from './meter-quota.js';
6
+ export * from './rate-limit-by-org.js';
5
7
  export * from './require-org-id.js';
6
8
  export * from './tenant-context.js';
7
9
  export * from './get-context.js';
package/lib/api/index.js CHANGED
@@ -5,6 +5,8 @@ export * from './middleware.js';
5
5
  export * from './middleware-factory.js';
6
6
  export * from './context-middleware.js';
7
7
  export * from './check-quota.js';
8
+ export * from './meter-quota.js';
9
+ export * from './rate-limit-by-org.js';
8
10
  export * from './require-org-id.js';
9
11
  export * from './tenant-context.js';
10
12
  export * from './get-context.js';
@@ -29,4 +31,4 @@ export * from './readiness.js';
29
31
  export * from './route-wrapper.js';
30
32
  // Request/Response types
31
33
  export * from './request-types.js';
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsYUFBYTtBQUNiLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsa0JBQWtCLENBQUM7QUFFakMsY0FBYztBQUNkLGNBQWMsa0JBQWtCLENBQUM7QUFFakMsdUJBQXVCO0FBQ3ZCLGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsMkRBQTJEO0FBQzNELGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsZ0JBQWdCO0FBQ2hCLGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsY0FBYztBQUNkLGNBQWMsNkJBQTZCLENBQUM7QUFFNUMsZ0JBQWdCO0FBQ2hCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsY0FBYyxDQUFDO0FBRTdCLG1CQUFtQjtBQUNuQixjQUFjLGFBQWEsQ0FBQztBQUU1QixxQ0FBcUM7QUFDckMsY0FBYyxnQkFBZ0IsQ0FBQztBQUUvQixnQkFBZ0I7QUFDaEIsY0FBYyxvQkFBb0IsQ0FBQztBQUVuQyx5QkFBeUI7QUFDekIsY0FBYyxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vLyBNaWRkbGV3YXJlXG5leHBvcnQgKiBmcm9tICcuL21pZGRsZXdhcmUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9taWRkbGV3YXJlLWZhY3RvcnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9jb250ZXh0LW1pZGRsZXdhcmUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9jaGVjay1xdW90YS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3JlcXVpcmUtb3JnLWlkLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuYW50LWNvbnRleHQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9nZXQtY29udGV4dC5qcyc7XG5cbi8vIEFwcCBmYWN0b3J5XG5leHBvcnQgKiBmcm9tICcuL2FwcC1mYWN0b3J5LmpzJztcblxuLy8gSGVhbHRoLWNoZWNrIGhlbHBlcnNcbmV4cG9ydCAqIGZyb20gJy4vaGVhbHRoLWNoZWNrcy5qcyc7XG5cbi8vIE1vbmdvREIgY29ubmVjdGlvbiBoZWxwZXIgKGRlcGVuZGVuY3ktaW5qZWN0ZWQgbW9uZ29vc2UpXG5leHBvcnQgKiBmcm9tICcuL21vbmdvLWNvbm5lY3QuanMnO1xuXG4vLyBRdW90YSBoZWxwZXJzXG5leHBvcnQgKiBmcm9tICcuL3F1b3RhLWhlbHBlcnMuanMnO1xuXG4vLyBJZGVtcG90ZW5jeVxuZXhwb3J0ICogZnJvbSAnLi9pZGVtcG90ZW5jeS1taWRkbGV3YXJlLmpzJztcblxuLy8gT2JzZXJ2YWJpbGl0eVxuZXhwb3J0ICogZnJvbSAnLi90cmFjaW5nLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vbWV0cmljcy5qcyc7XG5cbi8vIFNlcnZlciB1dGlsaXRpZXNcbmV4cG9ydCAqIGZyb20gJy4vc2VydmVyLmpzJztcblxuLy8gUmVhZGluZXNzIHN0YXRlICsgZ3VhcmQgbWlkZGxld2FyZVxuZXhwb3J0ICogZnJvbSAnLi9yZWFkaW5lc3MuanMnO1xuXG4vLyBSb3V0ZSB3cmFwcGVyXG5leHBvcnQgKiBmcm9tICcuL3JvdXRlLXdyYXBwZXIuanMnO1xuXG4vLyBSZXF1ZXN0L1Jlc3BvbnNlIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL3JlcXVlc3QtdHlwZXMuanMnO1xuIl19
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsYUFBYTtBQUNiLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxrQkFBa0IsQ0FBQztBQUNqQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGtCQUFrQixDQUFDO0FBRWpDLGNBQWM7QUFDZCxjQUFjLGtCQUFrQixDQUFDO0FBRWpDLHVCQUF1QjtBQUN2QixjQUFjLG9CQUFvQixDQUFDO0FBRW5DLDJEQUEyRDtBQUMzRCxjQUFjLG9CQUFvQixDQUFDO0FBRW5DLGdCQUFnQjtBQUNoQixjQUFjLG9CQUFvQixDQUFDO0FBRW5DLGNBQWM7QUFDZCxjQUFjLDZCQUE2QixDQUFDO0FBRTVDLGdCQUFnQjtBQUNoQixjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGNBQWMsQ0FBQztBQUU3QixtQkFBbUI7QUFDbkIsY0FBYyxhQUFhLENBQUM7QUFFNUIscUNBQXFDO0FBQ3JDLGNBQWMsZ0JBQWdCLENBQUM7QUFFL0IsZ0JBQWdCO0FBQ2hCLGNBQWMsb0JBQW9CLENBQUM7QUFFbkMseUJBQXlCO0FBQ3pCLGNBQWMsb0JBQW9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLy8gTWlkZGxld2FyZVxuZXhwb3J0ICogZnJvbSAnLi9taWRkbGV3YXJlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vbWlkZGxld2FyZS1mYWN0b3J5LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY29udGV4dC1taWRkbGV3YXJlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY2hlY2stcXVvdGEuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9tZXRlci1xdW90YS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3JhdGUtbGltaXQtYnktb3JnLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vcmVxdWlyZS1vcmctaWQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5hbnQtY29udGV4dC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2dldC1jb250ZXh0LmpzJztcblxuLy8gQXBwIGZhY3RvcnlcbmV4cG9ydCAqIGZyb20gJy4vYXBwLWZhY3RvcnkuanMnO1xuXG4vLyBIZWFsdGgtY2hlY2sgaGVscGVyc1xuZXhwb3J0ICogZnJvbSAnLi9oZWFsdGgtY2hlY2tzLmpzJztcblxuLy8gTW9uZ29EQiBjb25uZWN0aW9uIGhlbHBlciAoZGVwZW5kZW5jeS1pbmplY3RlZCBtb25nb29zZSlcbmV4cG9ydCAqIGZyb20gJy4vbW9uZ28tY29ubmVjdC5qcyc7XG5cbi8vIFF1b3RhIGhlbHBlcnNcbmV4cG9ydCAqIGZyb20gJy4vcXVvdGEtaGVscGVycy5qcyc7XG5cbi8vIElkZW1wb3RlbmN5XG5leHBvcnQgKiBmcm9tICcuL2lkZW1wb3RlbmN5LW1pZGRsZXdhcmUuanMnO1xuXG4vLyBPYnNlcnZhYmlsaXR5XG5leHBvcnQgKiBmcm9tICcuL3RyYWNpbmcuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9tZXRyaWNzLmpzJztcblxuLy8gU2VydmVyIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9zZXJ2ZXIuanMnO1xuXG4vLyBSZWFkaW5lc3Mgc3RhdGUgKyBndWFyZCBtaWRkbGV3YXJlXG5leHBvcnQgKiBmcm9tICcuL3JlYWRpbmVzcy5qcyc7XG5cbi8vIFJvdXRlIHdyYXBwZXJcbmV4cG9ydCAqIGZyb20gJy4vcm91dGUtd3JhcHBlci5qcyc7XG5cbi8vIFJlcXVlc3QvUmVzcG9uc2UgdHlwZXNcbmV4cG9ydCAqIGZyb20gJy4vcmVxdWVzdC10eXBlcy5qcyc7XG4iXX0=
@@ -0,0 +1,32 @@
1
+ import type { QuotaType, QuotaService } from '@pipeline-builder/api-core';
2
+ import type { Request, Response, NextFunction } from 'express';
3
+ /**
4
+ * Middleware that METERS (increments) a quota counter once per SUCCESSFUL
5
+ * request, on response `finish`.
6
+ *
7
+ * The complement to {@link checkQuota}: `checkQuota` only GATES (reads current
8
+ * usage and 429s when over) — it never increments, so a service that mounts it
9
+ * but never calls `incrementQuota` checks against a counter that its own traffic
10
+ * never moves (the metering gap this fixes for the compliance service). Mount
11
+ * this ALONGSIDE the auth/org chain to close the loop with one line instead of
12
+ * threading `quotaService` + a manual `incrementQuotaFromCtx` through every
13
+ * route factory and handler.
14
+ *
15
+ * Fire-and-forget + fail-safe by construction:
16
+ * - runs in a `finish` listener, so it never blocks or fails the response;
17
+ * - `incrementQuota` swallows its own errors (logs a warning);
18
+ * - only 2xx responses are metered (a rejected/errored request costs nothing);
19
+ * - a request with no VERIFIED org (`req.user.organizationId` — set by
20
+ * requireAuth, never the spoofable header identity) is skipped
21
+ * (unauthenticated / health / early-terminated);
22
+ * - SERVICE-PRINCIPAL callers are skipped: internal service-to-service traffic
23
+ * (e.g. a peer calling compliance `validate`) must not burn a tenant's quota —
24
+ * the originating service already meters the user action that triggered it.
25
+ *
26
+ * Do NOT combine this with a handler that already calls `incrementQuotaFromCtx`
27
+ * for the same quota type on the same route — that double-counts.
28
+ *
29
+ * @param quotaService - Quota service client
30
+ * @param quotaType - Which quota to meter (e.g. 'apiCalls')
31
+ */
32
+ export declare function meterQuotaOnSuccess(quotaService: QuotaService, quotaType: QuotaType): (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,58 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { incrementQuota, isServicePrincipal, createLogger } from '@pipeline-builder/api-core';
4
+ const logger = createLogger('meter-quota');
5
+ /**
6
+ * Middleware that METERS (increments) a quota counter once per SUCCESSFUL
7
+ * request, on response `finish`.
8
+ *
9
+ * The complement to {@link checkQuota}: `checkQuota` only GATES (reads current
10
+ * usage and 429s when over) — it never increments, so a service that mounts it
11
+ * but never calls `incrementQuota` checks against a counter that its own traffic
12
+ * never moves (the metering gap this fixes for the compliance service). Mount
13
+ * this ALONGSIDE the auth/org chain to close the loop with one line instead of
14
+ * threading `quotaService` + a manual `incrementQuotaFromCtx` through every
15
+ * route factory and handler.
16
+ *
17
+ * Fire-and-forget + fail-safe by construction:
18
+ * - runs in a `finish` listener, so it never blocks or fails the response;
19
+ * - `incrementQuota` swallows its own errors (logs a warning);
20
+ * - only 2xx responses are metered (a rejected/errored request costs nothing);
21
+ * - a request with no VERIFIED org (`req.user.organizationId` — set by
22
+ * requireAuth, never the spoofable header identity) is skipped
23
+ * (unauthenticated / health / early-terminated);
24
+ * - SERVICE-PRINCIPAL callers are skipped: internal service-to-service traffic
25
+ * (e.g. a peer calling compliance `validate`) must not burn a tenant's quota —
26
+ * the originating service already meters the user action that triggered it.
27
+ *
28
+ * Do NOT combine this with a handler that already calls `incrementQuotaFromCtx`
29
+ * for the same quota type on the same route — that double-counts.
30
+ *
31
+ * @param quotaService - Quota service client
32
+ * @param quotaType - Which quota to meter (e.g. 'apiCalls')
33
+ */
34
+ export function meterQuotaOnSuccess(quotaService, quotaType) {
35
+ return (req, res, next) => {
36
+ res.on('finish', () => {
37
+ try {
38
+ // Only successful responses are billable.
39
+ if (res.statusCode < 200 || res.statusCode >= 300)
40
+ return;
41
+ // Prefer the VERIFIED auth org over the spoofable header identity.
42
+ const orgId = req.user?.organizationId;
43
+ if (!orgId)
44
+ return;
45
+ // Internal service-to-service calls must not consume a tenant's quota.
46
+ if (isServicePrincipal(req))
47
+ return;
48
+ incrementQuota(quotaService, orgId, quotaType, req.headers.authorization || '', (message, data) => logger.warn(message, data));
49
+ }
50
+ catch {
51
+ // Metering must never affect the response; a missing user/context just
52
+ // means an unauthenticated or early-terminated request — skip silently.
53
+ }
54
+ });
55
+ next();
56
+ };
57
+ }
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0ZXItcXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL21ldGVyLXF1b3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUk5RixNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFM0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Qkc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsWUFBMEIsRUFBRSxTQUFvQjtJQUNsRixPQUFPLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDL0QsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1lBQ3BCLElBQUksQ0FBQztnQkFDSCwwQ0FBMEM7Z0JBQzFDLElBQUksR0FBRyxDQUFDLFVBQVUsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLFVBQVUsSUFBSSxHQUFHO29CQUFFLE9BQU87Z0JBQzFELG1FQUFtRTtnQkFDbkUsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxLQUFLO29CQUFFLE9BQU87Z0JBQ25CLHVFQUF1RTtnQkFDdkUsSUFBSSxrQkFBa0IsQ0FBQyxHQUFHLENBQUM7b0JBQUUsT0FBTztnQkFDcEMsY0FBYyxDQUNaLFlBQVksRUFDWixLQUFLLEVBQ0wsU0FBUyxFQUNULEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFJLEVBQUUsRUFDL0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUErQixDQUFDLENBQ3pFLENBQUM7WUFDSixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLHVFQUF1RTtnQkFDdkUsd0VBQXdFO1lBQzFFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksRUFBRSxDQUFDO0lBQ1QsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBpbmNyZW1lbnRRdW90YSwgaXNTZXJ2aWNlUHJpbmNpcGFsLCBjcmVhdGVMb2dnZXIgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgdHlwZSB7IFF1b3RhVHlwZSwgUXVvdGFTZXJ2aWNlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSwgTmV4dEZ1bmN0aW9uIH0gZnJvbSAnZXhwcmVzcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignbWV0ZXItcXVvdGEnKTtcblxuLyoqXG4gKiBNaWRkbGV3YXJlIHRoYXQgTUVURVJTIChpbmNyZW1lbnRzKSBhIHF1b3RhIGNvdW50ZXIgb25jZSBwZXIgU1VDQ0VTU0ZVTFxuICogcmVxdWVzdCwgb24gcmVzcG9uc2UgYGZpbmlzaGAuXG4gKlxuICogVGhlIGNvbXBsZW1lbnQgdG8ge0BsaW5rIGNoZWNrUXVvdGF9OiBgY2hlY2tRdW90YWAgb25seSBHQVRFUyAocmVhZHMgY3VycmVudFxuICogdXNhZ2UgYW5kIDQyOXMgd2hlbiBvdmVyKSDigJQgaXQgbmV2ZXIgaW5jcmVtZW50cywgc28gYSBzZXJ2aWNlIHRoYXQgbW91bnRzIGl0XG4gKiBidXQgbmV2ZXIgY2FsbHMgYGluY3JlbWVudFF1b3RhYCBjaGVja3MgYWdhaW5zdCBhIGNvdW50ZXIgdGhhdCBpdHMgb3duIHRyYWZmaWNcbiAqIG5ldmVyIG1vdmVzICh0aGUgbWV0ZXJpbmcgZ2FwIHRoaXMgZml4ZXMgZm9yIHRoZSBjb21wbGlhbmNlIHNlcnZpY2UpLiBNb3VudFxuICogdGhpcyBBTE9OR1NJREUgdGhlIGF1dGgvb3JnIGNoYWluIHRvIGNsb3NlIHRoZSBsb29wIHdpdGggb25lIGxpbmUgaW5zdGVhZCBvZlxuICogdGhyZWFkaW5nIGBxdW90YVNlcnZpY2VgICsgYSBtYW51YWwgYGluY3JlbWVudFF1b3RhRnJvbUN0eGAgdGhyb3VnaCBldmVyeVxuICogcm91dGUgZmFjdG9yeSBhbmQgaGFuZGxlci5cbiAqXG4gKiBGaXJlLWFuZC1mb3JnZXQgKyBmYWlsLXNhZmUgYnkgY29uc3RydWN0aW9uOlxuICogLSBydW5zIGluIGEgYGZpbmlzaGAgbGlzdGVuZXIsIHNvIGl0IG5ldmVyIGJsb2NrcyBvciBmYWlscyB0aGUgcmVzcG9uc2U7XG4gKiAtIGBpbmNyZW1lbnRRdW90YWAgc3dhbGxvd3MgaXRzIG93biBlcnJvcnMgKGxvZ3MgYSB3YXJuaW5nKTtcbiAqIC0gb25seSAyeHggcmVzcG9uc2VzIGFyZSBtZXRlcmVkIChhIHJlamVjdGVkL2Vycm9yZWQgcmVxdWVzdCBjb3N0cyBub3RoaW5nKTtcbiAqIC0gYSByZXF1ZXN0IHdpdGggbm8gVkVSSUZJRUQgb3JnIChgcmVxLnVzZXIub3JnYW5pemF0aW9uSWRgIOKAlCBzZXQgYnlcbiAqICAgcmVxdWlyZUF1dGgsIG5ldmVyIHRoZSBzcG9vZmFibGUgaGVhZGVyIGlkZW50aXR5KSBpcyBza2lwcGVkXG4gKiAgICh1bmF1dGhlbnRpY2F0ZWQgLyBoZWFsdGggLyBlYXJseS10ZXJtaW5hdGVkKTtcbiAqIC0gU0VSVklDRS1QUklOQ0lQQUwgY2FsbGVycyBhcmUgc2tpcHBlZDogaW50ZXJuYWwgc2VydmljZS10by1zZXJ2aWNlIHRyYWZmaWNcbiAqICAgKGUuZy4gYSBwZWVyIGNhbGxpbmcgY29tcGxpYW5jZSBgdmFsaWRhdGVgKSBtdXN0IG5vdCBidXJuIGEgdGVuYW50J3MgcXVvdGEg4oCUXG4gKiAgIHRoZSBvcmlnaW5hdGluZyBzZXJ2aWNlIGFscmVhZHkgbWV0ZXJzIHRoZSB1c2VyIGFjdGlvbiB0aGF0IHRyaWdnZXJlZCBpdC5cbiAqXG4gKiBEbyBOT1QgY29tYmluZSB0aGlzIHdpdGggYSBoYW5kbGVyIHRoYXQgYWxyZWFkeSBjYWxscyBgaW5jcmVtZW50UXVvdGFGcm9tQ3R4YFxuICogZm9yIHRoZSBzYW1lIHF1b3RhIHR5cGUgb24gdGhlIHNhbWUgcm91dGUg4oCUIHRoYXQgZG91YmxlLWNvdW50cy5cbiAqXG4gKiBAcGFyYW0gcXVvdGFTZXJ2aWNlIC0gUXVvdGEgc2VydmljZSBjbGllbnRcbiAqIEBwYXJhbSBxdW90YVR5cGUgLSBXaGljaCBxdW90YSB0byBtZXRlciAoZS5nLiAnYXBpQ2FsbHMnKVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWV0ZXJRdW90YU9uU3VjY2VzcyhxdW90YVNlcnZpY2U6IFF1b3RhU2VydmljZSwgcXVvdGFUeXBlOiBRdW90YVR5cGUpIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIHJlcy5vbignZmluaXNoJywgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gT25seSBzdWNjZXNzZnVsIHJlc3BvbnNlcyBhcmUgYmlsbGFibGUuXG4gICAgICAgIGlmIChyZXMuc3RhdHVzQ29kZSA8IDIwMCB8fCByZXMuc3RhdHVzQ29kZSA+PSAzMDApIHJldHVybjtcbiAgICAgICAgLy8gUHJlZmVyIHRoZSBWRVJJRklFRCBhdXRoIG9yZyBvdmVyIHRoZSBzcG9vZmFibGUgaGVhZGVyIGlkZW50aXR5LlxuICAgICAgICBjb25zdCBvcmdJZCA9IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZDtcbiAgICAgICAgaWYgKCFvcmdJZCkgcmV0dXJuO1xuICAgICAgICAvLyBJbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbHMgbXVzdCBub3QgY29uc3VtZSBhIHRlbmFudCdzIHF1b3RhLlxuICAgICAgICBpZiAoaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHJldHVybjtcbiAgICAgICAgaW5jcmVtZW50UXVvdGEoXG4gICAgICAgICAgcXVvdGFTZXJ2aWNlLFxuICAgICAgICAgIG9yZ0lkLFxuICAgICAgICAgIHF1b3RhVHlwZSxcbiAgICAgICAgICByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uIHx8ICcnLFxuICAgICAgICAgIChtZXNzYWdlLCBkYXRhKSA9PiBsb2dnZXIud2FybihtZXNzYWdlLCBkYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBNZXRlcmluZyBtdXN0IG5ldmVyIGFmZmVjdCB0aGUgcmVzcG9uc2U7IGEgbWlzc2luZyB1c2VyL2NvbnRleHQganVzdFxuICAgICAgICAvLyBtZWFucyBhbiB1bmF1dGhlbnRpY2F0ZWQgb3IgZWFybHktdGVybWluYXRlZCByZXF1ZXN0IOKAlCBza2lwIHNpbGVudGx5LlxuICAgICAgfVxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,29 @@
1
+ /** Config for a {@link rateLimitByOrg} limiter. */
2
+ export interface OrgRateLimitOptions {
3
+ /** Unique name — namespaces the Redis bucket + labels logs. */
4
+ name: string;
5
+ /** Max requests per window per org (or per client IP when unauthenticated). */
6
+ max: number;
7
+ /** Window length in ms. */
8
+ windowMs: number;
9
+ /** Optional 429 message override. */
10
+ message?: string;
11
+ }
12
+ /**
13
+ * Per-ORGANIZATION rate limiter for a specific hot/expensive route, keyed on the
14
+ * VERIFIED auth org — the complement to the coarse global per-IP limiter in
15
+ * `createApp` (which a whole org behind one NAT shares, and a distributed
16
+ * attacker spreads across IP buckets to evade).
17
+ *
18
+ * MUST be mounted AFTER `requireAuth` so `req.user.organizationId` is populated;
19
+ * an unauthenticated caller falls back to a client-IP bucket (never a spoofable
20
+ * header) so it stays bounded. Verified internal service principals are exempt
21
+ * (they carry a signed service JWT). Uses the shared env Redis store
22
+ * (cross-replica, namespaced by `name`) when configured, else in-memory.
23
+ *
24
+ * @example
25
+ * router.post('/', ...createAuthenticatedWithOrgRoute(), requirePermission('messages:write'),
26
+ * rateLimitByOrg({ name: 'message-send', max: 60, windowMs: 60_000 }),
27
+ * withRoute(handler));
28
+ */
29
+ export declare function rateLimitByOrg(opts: OrgRateLimitOptions): import("express-rate-limit").RateLimitRequestHandler;
@@ -0,0 +1,64 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { sendError, ErrorCode, createLogger, verifyServicePrincipal, createEnvRedisClient, safeCreateRequire } from '@pipeline-builder/api-core';
4
+ import rateLimit, { ipKeyGenerator } from 'express-rate-limit';
5
+ const logger = createLogger('rate-limit-by-org');
6
+ /**
7
+ * Per-ORGANIZATION rate limiter for a specific hot/expensive route, keyed on the
8
+ * VERIFIED auth org — the complement to the coarse global per-IP limiter in
9
+ * `createApp` (which a whole org behind one NAT shares, and a distributed
10
+ * attacker spreads across IP buckets to evade).
11
+ *
12
+ * MUST be mounted AFTER `requireAuth` so `req.user.organizationId` is populated;
13
+ * an unauthenticated caller falls back to a client-IP bucket (never a spoofable
14
+ * header) so it stays bounded. Verified internal service principals are exempt
15
+ * (they carry a signed service JWT). Uses the shared env Redis store
16
+ * (cross-replica, namespaced by `name`) when configured, else in-memory.
17
+ *
18
+ * @example
19
+ * router.post('/', ...createAuthenticatedWithOrgRoute(), requirePermission('messages:write'),
20
+ * rateLimitByOrg({ name: 'message-send', max: 60, windowMs: 60_000 }),
21
+ * withRoute(handler));
22
+ */
23
+ export function rateLimitByOrg(opts) {
24
+ const { name, max, windowMs, message } = opts;
25
+ const options = {
26
+ max,
27
+ windowMs,
28
+ standardHeaders: true,
29
+ legacyHeaders: false,
30
+ // Exempt cryptographically-verified internal service callers (signed JWT).
31
+ skip: (req) => verifyServicePrincipal(req),
32
+ // Bucket by VERIFIED org (set by requireAuth), NOT the spoofable `x-org-id`
33
+ // header. Fall back to a normalized client-IP bucket when unauthenticated so
34
+ // the limiter still bounds pre-auth traffic. Namespaced (`org:`/`ip:`) so an
35
+ // IP literal can never collide with an org id.
36
+ keyGenerator: (req) => {
37
+ const orgId = req.user?.organizationId;
38
+ return orgId ? `org:${orgId.toLowerCase()}` : `ip:${ipKeyGenerator(req.ip || 'anon', 64)}`;
39
+ },
40
+ handler: (_req, res) => {
41
+ sendError(res, 429, message ?? `Too many ${name} requests, please slow down.`, ErrorCode.RATE_LIMIT_EXCEEDED);
42
+ },
43
+ };
44
+ // Shared Redis store for cross-replica buckets when Redis is configured;
45
+ // namespaced per limiter so distinct limiters don't share a bucket. Fail-open:
46
+ // no Redis / a load failure falls back to per-process in-memory limiting.
47
+ const redis = createEnvRedisClient(`rate-limit-${name}`);
48
+ if (redis) {
49
+ try {
50
+ const require = safeCreateRequire(import.meta.url);
51
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
52
+ const { RedisStore } = require('rate-limit-redis');
53
+ options.store = new RedisStore({
54
+ prefix: `rl:${name}:`,
55
+ sendCommand: (...args) => redis.call(...args),
56
+ });
57
+ }
58
+ catch {
59
+ logger.warn('Redis store unavailable; per-org limiter falls back to in-memory', { name });
60
+ }
61
+ }
62
+ return rateLimit(options);
63
+ }
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0ZS1saW1pdC1ieS1vcmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JhdGUtbGltaXQtYnktb3JnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLHNCQUFzQixFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFakosT0FBTyxTQUFTLEVBQUUsRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUvRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQWNqRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBeUI7SUFDdEQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztJQUU5QyxNQUFNLE9BQU8sR0FBb0M7UUFDL0MsR0FBRztRQUNILFFBQVE7UUFDUixlQUFlLEVBQUUsSUFBSTtRQUNyQixhQUFhLEVBQUUsS0FBSztRQUNwQiwyRUFBMkU7UUFDM0UsSUFBSSxFQUFFLENBQUMsR0FBWSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUM7UUFDbkQsNEVBQTRFO1FBQzVFLDZFQUE2RTtRQUM3RSw2RUFBNkU7UUFDN0UsK0NBQStDO1FBQy9DLFlBQVksRUFBRSxDQUFDLEdBQVksRUFBVSxFQUFFO1lBQ3JDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDO1lBQ3ZDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzdGLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFhLEVBQUUsR0FBYSxFQUFRLEVBQUU7WUFDOUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxJQUFJLFlBQVksSUFBSSw4QkFBOEIsRUFBRSxTQUFTLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNoSCxDQUFDO0tBQ0YsQ0FBQztJQUVGLHlFQUF5RTtJQUN6RSwrRUFBK0U7SUFDL0UsMEVBQTBFO0lBQzFFLE1BQU0sS0FBSyxHQUFHLG9CQUFvQixDQUFxRCxjQUFjLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0csSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNWLElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25ELGlFQUFpRTtZQUNqRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDbkQsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQztnQkFDN0IsTUFBTSxFQUFFLE1BQU0sSUFBSSxHQUFHO2dCQUNyQixXQUFXLEVBQUUsQ0FBQyxHQUFHLElBQWMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQzthQUN4RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsTUFBTSxDQUFDLElBQUksQ0FBQyxrRUFBa0UsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHNlbmRFcnJvciwgRXJyb3JDb2RlLCBjcmVhdGVMb2dnZXIsIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwsIGNyZWF0ZUVudlJlZGlzQ2xpZW50LCBzYWZlQ3JlYXRlUmVxdWlyZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCByYXRlTGltaXQsIHsgaXBLZXlHZW5lcmF0b3IgfSBmcm9tICdleHByZXNzLXJhdGUtbGltaXQnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JhdGUtbGltaXQtYnktb3JnJyk7XG5cbi8qKiBDb25maWcgZm9yIGEge0BsaW5rIHJhdGVMaW1pdEJ5T3JnfSBsaW1pdGVyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmdSYXRlTGltaXRPcHRpb25zIHtcbiAgLyoqIFVuaXF1ZSBuYW1lIOKAlCBuYW1lc3BhY2VzIHRoZSBSZWRpcyBidWNrZXQgKyBsYWJlbHMgbG9ncy4gKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogTWF4IHJlcXVlc3RzIHBlciB3aW5kb3cgcGVyIG9yZyAob3IgcGVyIGNsaWVudCBJUCB3aGVuIHVuYXV0aGVudGljYXRlZCkuICovXG4gIG1heDogbnVtYmVyO1xuICAvKiogV2luZG93IGxlbmd0aCBpbiBtcy4gKi9cbiAgd2luZG93TXM6IG51bWJlcjtcbiAgLyoqIE9wdGlvbmFsIDQyOSBtZXNzYWdlIG92ZXJyaWRlLiAqL1xuICBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBlci1PUkdBTklaQVRJT04gcmF0ZSBsaW1pdGVyIGZvciBhIHNwZWNpZmljIGhvdC9leHBlbnNpdmUgcm91dGUsIGtleWVkIG9uIHRoZVxuICogVkVSSUZJRUQgYXV0aCBvcmcg4oCUIHRoZSBjb21wbGVtZW50IHRvIHRoZSBjb2Fyc2UgZ2xvYmFsIHBlci1JUCBsaW1pdGVyIGluXG4gKiBgY3JlYXRlQXBwYCAod2hpY2ggYSB3aG9sZSBvcmcgYmVoaW5kIG9uZSBOQVQgc2hhcmVzLCBhbmQgYSBkaXN0cmlidXRlZFxuICogYXR0YWNrZXIgc3ByZWFkcyBhY3Jvc3MgSVAgYnVja2V0cyB0byBldmFkZSkuXG4gKlxuICogTVVTVCBiZSBtb3VudGVkIEFGVEVSIGByZXF1aXJlQXV0aGAgc28gYHJlcS51c2VyLm9yZ2FuaXphdGlvbklkYCBpcyBwb3B1bGF0ZWQ7XG4gKiBhbiB1bmF1dGhlbnRpY2F0ZWQgY2FsbGVyIGZhbGxzIGJhY2sgdG8gYSBjbGllbnQtSVAgYnVja2V0IChuZXZlciBhIHNwb29mYWJsZVxuICogaGVhZGVyKSBzbyBpdCBzdGF5cyBib3VuZGVkLiBWZXJpZmllZCBpbnRlcm5hbCBzZXJ2aWNlIHByaW5jaXBhbHMgYXJlIGV4ZW1wdFxuICogKHRoZXkgY2FycnkgYSBzaWduZWQgc2VydmljZSBKV1QpLiBVc2VzIHRoZSBzaGFyZWQgZW52IFJlZGlzIHN0b3JlXG4gKiAoY3Jvc3MtcmVwbGljYSwgbmFtZXNwYWNlZCBieSBgbmFtZWApIHdoZW4gY29uZmlndXJlZCwgZWxzZSBpbi1tZW1vcnkuXG4gKlxuICogQGV4YW1wbGVcbiAqICAgcm91dGVyLnBvc3QoJy8nLCAuLi5jcmVhdGVBdXRoZW50aWNhdGVkV2l0aE9yZ1JvdXRlKCksIHJlcXVpcmVQZXJtaXNzaW9uKCdtZXNzYWdlczp3cml0ZScpLFxuICogICAgIHJhdGVMaW1pdEJ5T3JnKHsgbmFtZTogJ21lc3NhZ2Utc2VuZCcsIG1heDogNjAsIHdpbmRvd01zOiA2MF8wMDAgfSksXG4gKiAgICAgd2l0aFJvdXRlKGhhbmRsZXIpKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhdGVMaW1pdEJ5T3JnKG9wdHM6IE9yZ1JhdGVMaW1pdE9wdGlvbnMpIHtcbiAgY29uc3QgeyBuYW1lLCBtYXgsIHdpbmRvd01zLCBtZXNzYWdlIH0gPSBvcHRzO1xuXG4gIGNvbnN0IG9wdGlvbnM6IFBhcmFtZXRlcnM8dHlwZW9mIHJhdGVMaW1pdD5bMF0gPSB7XG4gICAgbWF4LFxuICAgIHdpbmRvd01zLFxuICAgIHN0YW5kYXJkSGVhZGVyczogdHJ1ZSxcbiAgICBsZWdhY3lIZWFkZXJzOiBmYWxzZSxcbiAgICAvLyBFeGVtcHQgY3J5cHRvZ3JhcGhpY2FsbHktdmVyaWZpZWQgaW50ZXJuYWwgc2VydmljZSBjYWxsZXJzIChzaWduZWQgSldUKS5cbiAgICBza2lwOiAocmVxOiBSZXF1ZXN0KSA9PiB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcSksXG4gICAgLy8gQnVja2V0IGJ5IFZFUklGSUVEIG9yZyAoc2V0IGJ5IHJlcXVpcmVBdXRoKSwgTk9UIHRoZSBzcG9vZmFibGUgYHgtb3JnLWlkYFxuICAgIC8vIGhlYWRlci4gRmFsbCBiYWNrIHRvIGEgbm9ybWFsaXplZCBjbGllbnQtSVAgYnVja2V0IHdoZW4gdW5hdXRoZW50aWNhdGVkIHNvXG4gICAgLy8gdGhlIGxpbWl0ZXIgc3RpbGwgYm91bmRzIHByZS1hdXRoIHRyYWZmaWMuIE5hbWVzcGFjZWQgKGBvcmc6YC9gaXA6YCkgc28gYW5cbiAgICAvLyBJUCBsaXRlcmFsIGNhbiBuZXZlciBjb2xsaWRlIHdpdGggYW4gb3JnIGlkLlxuICAgIGtleUdlbmVyYXRvcjogKHJlcTogUmVxdWVzdCk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBvcmdJZCA9IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZDtcbiAgICAgIHJldHVybiBvcmdJZCA/IGBvcmc6JHtvcmdJZC50b0xvd2VyQ2FzZSgpfWAgOiBgaXA6JHtpcEtleUdlbmVyYXRvcihyZXEuaXAgfHwgJ2Fub24nLCA2NCl9YDtcbiAgICB9LFxuICAgIGhhbmRsZXI6IChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKTogdm9pZCA9PiB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MjksIG1lc3NhZ2UgPz8gYFRvbyBtYW55ICR7bmFtZX0gcmVxdWVzdHMsIHBsZWFzZSBzbG93IGRvd24uYCwgRXJyb3JDb2RlLlJBVEVfTElNSVRfRVhDRUVERUQpO1xuICAgIH0sXG4gIH07XG5cbiAgLy8gU2hhcmVkIFJlZGlzIHN0b3JlIGZvciBjcm9zcy1yZXBsaWNhIGJ1Y2tldHMgd2hlbiBSZWRpcyBpcyBjb25maWd1cmVkO1xuICAvLyBuYW1lc3BhY2VkIHBlciBsaW1pdGVyIHNvIGRpc3RpbmN0IGxpbWl0ZXJzIGRvbid0IHNoYXJlIGEgYnVja2V0LiBGYWlsLW9wZW46XG4gIC8vIG5vIFJlZGlzIC8gYSBsb2FkIGZhaWx1cmUgZmFsbHMgYmFjayB0byBwZXItcHJvY2VzcyBpbi1tZW1vcnkgbGltaXRpbmcuXG4gIGNvbnN0IHJlZGlzID0gY3JlYXRlRW52UmVkaXNDbGllbnQ8eyBjYWxsOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+IH0+KGByYXRlLWxpbWl0LSR7bmFtZX1gKTtcbiAgaWYgKHJlZGlzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVpcmUgPSBzYWZlQ3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgIGNvbnN0IHsgUmVkaXNTdG9yZSB9ID0gcmVxdWlyZSgncmF0ZS1saW1pdC1yZWRpcycpO1xuICAgICAgb3B0aW9ucy5zdG9yZSA9IG5ldyBSZWRpc1N0b3JlKHtcbiAgICAgICAgcHJlZml4OiBgcmw6JHtuYW1lfTpgLFxuICAgICAgICBzZW5kQ29tbWFuZDogKC4uLmFyZ3M6IHN0cmluZ1tdKSA9PiByZWRpcy5jYWxsKC4uLmFyZ3MpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBsb2dnZXIud2FybignUmVkaXMgc3RvcmUgdW5hdmFpbGFibGU7IHBlci1vcmcgbGltaXRlciBmYWxscyBiYWNrIHRvIGluLW1lbW9yeScsIHsgbmFtZSB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmF0ZUxpbWl0KG9wdGlvbnMpO1xufVxuIl19
@@ -1,7 +1,7 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { randomBytes } from 'node:crypto';
4
- import { createLogger, SSE_TICKET_TTL_MS } from '@pipeline-builder/api-core';
4
+ import { createLogger, SSE_TICKET_TTL_MS, writeSseHeaders } from '@pipeline-builder/api-core';
5
5
  import { CoreConstants } from '@pipeline-builder/pipeline-core';
6
6
  import { v7 as uuid } from 'uuid';
7
7
  import { createMemoryTicketStore } from './sse-ticket-store.js';
@@ -537,10 +537,7 @@ export class SSEManager {
537
537
  res.status(429).end('Too many SSE connections for this organization');
538
538
  return;
539
539
  }
540
- res.setHeader('Content-Type', 'text/event-stream');
541
- res.setHeader('Cache-Control', 'no-cache');
542
- res.setHeader('Connection', 'keep-alive');
543
- res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering
540
+ writeSseHeaders(res);
544
541
  res.flushHeaders();
545
542
  // Headers are flushed — we can no longer send a 429. addClient re-checks
546
543
  // the caps (including the process-wide total-clients cap, which the
@@ -633,4 +630,4 @@ export class SSEManager {
633
630
  logger.info('SSE Manager shut down');
634
631
  }
635
632
  }
636
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEUsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbEMsT0FBTyxFQUFFLHVCQUF1QixFQUF1QixNQUFNLHVCQUF1QixDQUFDO0FBRXJGLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQWlHM0M7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLHFFQUFxRSxDQUFDO0FBZ0J2Rzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztJQUNqRDs7MkNBRXVDO0lBQy9CLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNwRDs7aUZBRTZFO0lBQzVELFdBQVcsQ0FBaUI7SUFDNUIsb0JBQW9CLENBQVM7SUFDN0IsZUFBZSxDQUFTO0lBQ3hCLGdCQUFnQixDQUFTO0lBQ3pCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixXQUFXLENBQVM7SUFDcEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ2pDLGVBQWUsR0FBMEIsSUFBSSxDQUFDO0lBQ3RELCtEQUErRDtJQUM5QyxLQUFLLENBQVk7SUFDbEMsa0ZBQWtGO0lBQ2pFLE1BQU0sR0FBRyxX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LEdBQXlCLENBQUMsQ0FBQyxDQUFDO1FBRWhFLE1BQU0sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIsIFNTRV9USUNLRVRfVFRMX01TIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHR5cGUgeyBTU0VSZWxheSwgU1NFUmVsYXlNZXNzYWdlIH0gZnJvbSAnLi9zc2UtcmVsYXkuanMnO1xuaW1wb3J0IHsgY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUsIHR5cGUgU1NFVGlja2V0U3RvcmUgfSBmcm9tICcuL3NzZS10aWNrZXQtc3RvcmUuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBsaXZlICh1bmNvbnN1bWVkLCB1bmV4cGlyZWQpIFNTRSB0aWNrZXRzIGFjcm9zcyB0aGVcbiAgICogcHJvY2Vzcy4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLiBCb3VuZHMgbWVtb3J5XG4gICAqIHVuZGVyIGFidXNlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH1gXG4gICAqIG9uY2UgcmVhY2hlZC5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgU1NFIHRpY2tldHMuIERlZmF1bHRzIHRvIDEwIGZyb21cbiAgICogYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gUHJldmVudHMgYSBzaW5nbGUgdGVuYW50IGZyb20gc2F0dXJhdGluZyB0aGVcbiAgICogdGlja2V0IHRhYmxlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnLWxpbWl0JyB9YFxuICAgKiBvbmNlIHJlYWNoZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQuIERlZmF1bHRzIHRvIGFuIGluLW1lbW9yeSBzdG9yZSAoY29ycmVjdFxuICAgKiBzaW5nbGUtcmVwbGljYSBvbmx5KS4gSW5qZWN0IGBjcmVhdGVFbnZSZWRpc1RpY2tldFN0b3JlKClgIChvciBhIGJlc3Bva2VcbiAgICogYFNTRVRpY2tldFN0b3JlYCkgc28gdGlja2V0IG1pbnQvcmVkZWVtIEFORCBzdHJlYW0gb3duZXJzaGlwIHdvcmsgYWNyb3NzXG4gICAqIGhvcml6b250YWxseS1zY2FsZWQgcG9kcyBhbmQg4oCUIGNyaXRpY2FsbHkg4oCUIHNvIHRoZSBwbGF0Zm9ybSBzdHJlYW0gcHJvZHVjZXJcbiAgICogKGEgZGlmZmVyZW50IHNlcnZpY2UpIGNhbiBiaW5kIG93bmVyc2hpcCB0aGF0IHRoaXMgc2VydmljZSByZWFkcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU1NFVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0OiBgU1NFX1NUUkVBTV9PV05FUl9UVExfTVNgIGVudiBvclxuICAgKiAxaCkuIExvbmcgZW5vdWdoIHRvIG91dGxpdmUgYSBidWlsZDsgdGhlIHByb2R1Y2VyIHJlLWJpbmRzIGFzIG5lZWRlZC5cbiAgICovXG4gIHN0cmVhbU93bmVyVHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDcm9zcy1wb2QgZmFuLW91dCBidXMgZm9yIGBzZW5kKClgL2Bicm9hZGNhc3QoKWAuIE9wdGlvbmFsIOKAlCB3aGVuIG9taXR0ZWQsXG4gICAqIGRlbGl2ZXJ5IGlzIExPQ0FMLU9OTFkgKGNvcnJlY3Qgc2luZ2xlLXJlcGxpY2E7IHRvZGF5J3MgYmVoYXZpb3IpLiBJbmplY3RcbiAgICogYGNyZWF0ZUVudlJlZGlzU1NFUmVsYXkoKWAgc28gYSBmcmFtZSBwcm9kdWNlZCBvbiBvbmUgcG9kIHJlYWNoZXMgYW5cbiAgICogRXZlbnRTb3VyY2UgYXR0YWNoZWQgb24gYSBESUZGRVJFTlQgcG9kLiBEZWdyYWRlcyB0byBsb2NhbC1vbmx5IGF1dG9tYXRpY2FsbHlcbiAgICogd2hlbiBSZWRpcyBpcyB1bnNldCAodGhlIGZhY3RvcnkgcmV0dXJucyBudWxsKSBvciBkdXJpbmcgYSBSZWRpcyBvdXRhZ2UuXG4gICAqL1xuICByZWxheT86IFNTRVJlbGF5O1xufVxuXG4vKipcbiAqIEEgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IGlkOiBlaXRoZXIgYSBkYXNoZWQgVVVJRCAoYXBpLXNlcnZlcidzIGB1dWlkKClgKVxuICogb3IgbmdpbngncyBgJHJlcXVlc3RfaWRgIOKAlCAxNiByYW5kb20gYnl0ZXMgcmVuZGVyZWQgYXMgMzIgaGV4IGNoYXJzIHdpdGggTk9cbiAqIGRhc2hlcy4gQWNjZXB0IGJvdGggYnkgbWFraW5nIHRoZSBncm91cCBzZXBhcmF0b3JzIG9wdGlvbmFsOyBzdGlsbCBzdHJpY3RseVxuICogMzIgaGV4IGNoYXJzIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiAvIHBhdGgtdHJhdmVyc2FsIHBheWxvYWQgaW50byB0aGVcbiAqIFNTRSBzdWJqZWN0LiBTaGFyZWQgYnkgdGhlIHRpY2tldC1taW50IHJvdXRlIGFuZCB0aGUgc3RyZWFtIG1pZGRsZXdhcmUgc29cbiAqIGJvdGggdmFsaWRhdGUgdGhlIHN1YmplY3QgaWRlbnRpY2FsbHkuXG4gKi9cbmV4cG9ydCBjb25zdCBTU0VfUkVRVUVTVF9JRF9SRSA9IC9eWzAtOWEtZl17OH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezEyfSQvaTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU1NFTWFuYWdlci5jcmVhdGVUaWNrZXR9LiAqL1xuZXhwb3J0IHR5cGUgQ3JlYXRlVGlja2V0UmVzdWx0ID1cbiAgfCB7IG9rOiB0cnVlOyB0aWNrZXQ6IHN0cmluZyB9XG4gIHwgeyBvazogZmFsc2U7IHJlYXNvbjogJ29yZy1saW1pdCcgfCAnY2FwYWNpdHknIHwgJ2ZvcmJpZGRlbicgfTtcblxuLyoqXG4gKiBTU0UgTWFuYWdlciBzdGF0aXN0aWNzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlclN0YXRzIHtcbiAgdG90YWxSZXF1ZXN0czogbnVtYmVyO1xuICB0b3RhbENsaWVudHM6IG51bWJlcjtcbiAgb2xkZXN0Q29ubmVjdGlvbk1zOiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIFNTRSBoZWxwZXIgY2xhc3Mgd2l0aCBtZW1vcnkgbGVhayBwcm90ZWN0aW9uXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIENsaWVudCBsaW1pdHMgcGVyIHJlcXVlc3QgSURcbiAqIC0gQXV0b21hdGljIHRpbWVvdXQgZm9yIGlkbGUgY29ubmVjdGlvbnNcbiAqIC0gUGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICogLSBDb25uZWN0aW9uIHN0YXRpc3RpY3NcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHsgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IDUgfSk7XG4gKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICpcbiAqIC8vIFNlbmQgZXZlbnRzXG4gKiBzc2VNYW5hZ2VyLnNlbmQoJ3JlcXVlc3QtMTIzJywgJ0lORk8nLCAnUHJvY2Vzc2luZy4uLicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTU0VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjbGllbnRzID0gbmV3IE1hcDxzdHJpbmcsIFNTRUNsaWVudFtdPigpO1xuICAvKiogUGVyLW9yZyBvcGVuLWNsaWVudCBjb3VudGVycy4gRGVjcmVtZW50ZWQgb24gcmVtb3ZlQ2xpZW50L2NsZWFudXAgc28gdGhlXG4gICAqICBtYXAgbWlycm9ycyBgY2xpZW50c1tdLm9yZ0lkYCBjb3VudHMgYXQgYWxsIHRpbWVzLiBPcmdzIHJlYWNoIHplcm8gYXJlXG4gICAqICBkZWxldGVkIHRvIGtlZXAgdGhlIG1hcCBib3VuZGVkLiAqL1xuICBwcml2YXRlIG9yZ0NsaWVudENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQgKGluLW1lbW9yeSBkZWZhdWx0OyBSZWRpcyBmb3IgbXVsdGktcG9kKS5cbiAgICogIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgLyBgbWF4VGlja2V0c1Blck9yZ2AsIGVuZm9yY2VkIGluIGNyZWF0ZVRpY2tldDtcbiAgICogIGV4cGlyeSBpcyB2YWxpZGF0ZWQgYXQgY29uc3VtZSB0aW1lIGFuZCBzd2VwdCBvbiB0aGUgY2xlYW51cCBpbnRlcnZhbC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0aWNrZXRTdG9yZTogU1NFVGlja2V0U3RvcmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VG90YWxUaWNrZXRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VGlja2V0c1Blck9yZzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtT3duZXJUdGxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIGNsZWFudXBJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyAodW5kZWZpbmVkIOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWxheT86IFNTRVJlbGF5O1xuICAvKiogVGhpcyBtYW5hZ2VyIGluc3RhbmNlJ3MgaWQg4oCUIHRhZ3MgcmVsYXllZCBmcmFtZXMgc28gd2UgaWdub3JlIG91ciBvd24gZWNoby4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBub2RlSWQgPSByYW5kb21CeXRlcyg4KS50b1N0cmluZygnaGV4Jyk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU1NFTWFuYWdlck9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QgPSBvcHRpb25zLm1heENsaWVudHNQZXJSZXF1ZXN0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfUkVRVUVTVCB8fCAnMTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbENsaWVudHMgPSBvcHRpb25zLm1heFRvdGFsQ2xpZW50cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX0NMSUVOVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhDbGllbnRzUGVyT3JnID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfT1JHIHx8ICc1MCcsIDEwKTtcbiAgICB0aGlzLm1heFRvdGFsVGlja2V0cyA9IG9wdGlvbnMubWF4VG90YWxUaWNrZXRzID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVE9UQUxfVElDS0VUUyB8fCAnMTAwMCcsIDEwKTtcbiAgICB0aGlzLm1heFRpY2tldHNQZXJPcmcgPSBvcHRpb25zLm1heFRpY2tldHNQZXJPcmcgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9USUNLRVRTX1BFUl9PUkcgfHwgJzEwJywgMTApO1xuICAgIHRoaXMudGlja2V0VHRsTXMgPSBvcHRpb25zLnRpY2tldFR0bE1zID8/IFNTRV9USUNLRVRfVFRMX01TO1xuICAgIHRoaXMuc3RyZWFtT3duZXJUdGxNcyA9IG9wdGlvbnMuc3RyZWFtT3duZXJUdGxNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfU1RSRUFNX09XTkVSX1RUTF9NUyB8fCAnMzYwMDAwMCcsIDEwKTsgLy8gMSBob3VyXG4gICAgdGhpcy50aWNrZXRTdG9yZSA9IG9wdGlvbnMudGlja2V0U3RvcmUgPz8gY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUoKTtcbiAgICB0aGlzLmNsaWVudFRpbWVvdXRNcyA9IG9wdGlvbnMuY2xpZW50VGltZW91dE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTElFTlRfVElNRU9VVF9NUyB8fCAnMTgwMDAwMCcsIDEwKTsgLy8gMzAgbWludXRlc1xuXG4gICAgY29uc3QgY2xlYW51cEludGVydmFsTXMgPSBvcHRpb25zLmNsZWFudXBJbnRlcnZhbE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTEVBTlVQX0lOVEVSVkFMX01TIHx8ICczMDAwMDAnLCAxMCk7IC8vIDUgbWludXRlc1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwSW50ZXJ2YWwoY2xlYW51cEludGVydmFsTXMpO1xuXG4gICAgLy8gV2lyZSB0aGUgY3Jvc3MtcG9kIHJlbGF5OiBzdWJzY3JpYmUgb25jZSBvbiBzdGFydHVwIHNvIGZyYW1lcyBQVUJMSVNIRUQgYnlcbiAgICAvLyBhbnkgb3RoZXIgcG9kIGFyZSByZS1lbWl0dGVkIHRvIFRISVMgcG9kJ3MgbG9jYWwgY2xpZW50cy4gRnJhbWVzIHdlXG4gICAgLy8gcHVibGlzaGVkIG91cnNlbHZlcyBhcmUgaWdub3JlZCAob3JpZ2luID09PSBub2RlSWQpIOKAlCB3ZSBhbHJlYWR5IHdyb3RlIHRoZW1cbiAgICAvLyBsb2NhbGx5LiBGYWlsLXNhZmU6IG5vIHJlbGF5IOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5IChzaW5nbGUtcmVwbGljYSBkZWZhdWx0KS5cbiAgICB0aGlzLnJlbGF5ID0gb3B0aW9ucy5yZWxheTtcbiAgICB0aGlzLnJlbGF5Py5zdWJzY3JpYmUoKG1zZykgPT4gdGhpcy5vblJlbGF5TWVzc2FnZShtc2cpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgYSBmcmFtZSByZWNlaXZlZCBmcm9tIGFub3RoZXIgcG9kIHZpYSB0aGUgcmVsYXkuIFdlIGFscmVhZHkgZGVsaXZlcmVkXG4gICAqIG91ciBPV04gZnJhbWVzIHRvIGxvY2FsIGNsaWVudHMgYmVmb3JlIHB1Ymxpc2hpbmcsIHNvIGlnbm9yZSBvdXIgZWNoby4gQVxuICAgKiBgc2VuZGAgcmUtZW1pdHMgdG8gdGhlIHN1YmplY3QncyBsb2NhbCBjbGllbnRzOyBhIGBicm9hZGNhc3RgIHRvIGFsbCBvZiB0aGVtLlxuICAgKiBQdXJlbHkgbG9jYWwg4oCUIG5ldmVyIHJlLXB1Ymxpc2hlcywgc28gdGhlcmUgaXMgbm8gZmFuLW91dCBsb29wLlxuICAgKi9cbiAgcHJpdmF0ZSBvblJlbGF5TWVzc2FnZShtc2c6IFNTRVJlbGF5TWVzc2FnZSk6IHZvaWQge1xuICAgIGlmICghbXNnIHx8IG1zZy5vcmlnaW4gPT09IHRoaXMubm9kZUlkKSByZXR1cm47XG4gICAgaWYgKG1zZy5raW5kID09PSAnYnJvYWRjYXN0Jykge1xuICAgICAgdGhpcy5icm9hZGNhc3RMb2NhbChtc2cucGF5bG9hZCk7XG4gICAgfSBlbHNlIGlmIChtc2cucmVxdWVzdElkKSB7XG4gICAgICB0aGlzLnNlbmRMb2NhbChtc2cucmVxdWVzdElkLCBtc2cucGF5bG9hZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRvdGFsIG9wZW4gY29ubmVjdGlvbnMgYWNyb3NzIGFsbCByZXF1ZXN0cy4gKi9cbiAgcHJpdmF0ZSB0b3RhbENsaWVudHMoKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgbiArPSBjbGllbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbjtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IG9wZW4tc3RyZWFtIGNvdW50IGZvciBhbiBvcmcgKDAgaWYgdW5zZWVuKS4gKi9cbiAgZ2V0T3JnQ2xpZW50Q291bnQob3JnSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhIHJlcXVlc3RJZCBmb3IgZXF1YWxpdHkgY2hlY2tzOiBkYXNoZXMgc3RyaXBwZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQsIHNvIHRoZSBkYXNoZWQgKGFwaS1zZXJ2ZXIgYHV1aWQoKWApIGFuZCB1bmRhc2hlZCAobmdpbnhcbiAgICogYCRyZXF1ZXN0X2lkYCkgcmVuZGVyaW5ncyBvZiB0aGUgc2FtZSBpZCBjb21wYXJlIGVxdWFsLiBDYWxsZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBoYXZlIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBhZ2FpbnN0IHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhbiBvcmdJZCBmb3Igb3duZXJzaGlwIGVxdWFsaXR5IGNoZWNrczogdHJpbW1lZCBhbmRcbiAgICogbG93ZXJjYXNlZC4gVGhlIHN0cmVhbSBQUk9EVUNFUiAoYmluZFN0cmVhbU93bmVyKSBhbmQgdGhlIHRpY2tldC1taW50aW5nXG4gICAqIENPTlNVTUVSIChjcmVhdGVUaWNrZXQpIHJ1biBpbiBkaWZmZXJlbnQgc2VydmljZXMsIHNvIGEgY2FzaW5nIC8gd2hpdGVzcGFjZVxuICAgKiBkcmlmdCBiZXR3ZWVuIGhvdyBlYWNoIHJlbmRlcnMgdGhlIHNhbWUgb3JnIHdvdWxkIG90aGVyd2lzZSBtYWtlIHRoZSBvd25lclxuICAgKiBjb21wYXJpc29uIGluIHtAbGluayBjcmVhdGVUaWNrZXR9IGZhbHNlLWBmb3JiaWRkZW5gIHRoZSByZWFsIG93bmVyLlxuICAgKiBOb3JtYWxpemluZyBib3RoIHNpZGVzIOKAlCBtaXJyb3Jpbmcge0BsaW5rIG5vcm1hbGl6ZVJlcXVlc3RJZH0g4oCUIGNsb3NlcyB0aGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplT3JnSWQob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9yZ0lkLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCB0aGUgb3JnIHRoYXQgT1dOUyBhIHN0cmVhbSBzdWJqZWN0LiBUaGUgc3RyZWFtIFBST0RVQ0VSIGNhbGxzIHRoaXNcbiAgICogd2hlbiBpdCBjcmVhdGVzIGEgYnVpbGQtbG9nIHN0cmVhbSBzbyB0aGF0IHRpY2tldCBtaW50aW5nIGNhbiBhc3NlcnQgdGhlXG4gICAqIGNhbGxlcidzIG9yZyBvd25zIHRoZSBzdWJqZWN0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0pLiBCYWNrZWQgYnkgdGhlXG4gICAqIGluamVjdGVkIHRpY2tldCBzdG9yZSwgc28gd2hlbiBhIFJlZGlzIHN0b3JlIGlzIHdpcmVkIHRoZSBwbGF0Zm9ybSBwcm9kdWNlclxuICAgKiAoYSBkaWZmZXJlbnQgc2VydmljZSBzaGFyaW5nIHRoZSBzYW1lIFJlZGlzKSBjYW4gYmluZCBvd25lcnNoaXAgdGhhdCB0aGlzXG4gICAqIHNlcnZpY2UgcmVhZHMg4oCUIGNsb3NpbmcgdGhlIGNyb3NzLXRlbmFudCBhdHRhY2ggZ2FwIHdoZXJlIGFueSBvcmcgY291bGQgbWludFxuICAgKiBhIHRpY2tldCBmb3IgYSBndWVzc2VkIHJlcXVlc3RJZC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCAoZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyKS5cbiAgICogQHBhcmFtIG9yZ0lkIC0gVGhlIG93bmluZyBvcmcgKG5vcm1hbGl6ZWQgaW50ZXJuYWxseSB2aWEgbm9ybWFsaXplT3JnSWQpLlxuICAgKi9cbiAgYXN5bmMgYmluZFN0cmVhbU93bmVyKHJlcXVlc3RJZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5iaW5kU3RyZWFtT3duZXIoXG4gICAgICBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpLFxuICAgICAgU1NFTWFuYWdlci5ub3JtYWxpemVPcmdJZChvcmdJZCksXG4gICAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW50IGEgc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCBhIHNwZWNpZmljXG4gICAqIHN0cmVhbSBzdWJqZWN0IChgcmVxdWVzdElkYCkuIENsaWVudHMgUE9TVCB0byBvYnRhaW4gb25lIChKV1QtYXV0aGVudGljYXRlZClcbiAgICogZm9yIHRoZSBleGFjdCBzdHJlYW0gdGhleSBpbnRlbmQgdG8gb3BlbiwgdGhlbiBvcGVuIHRoZSBFdmVudFNvdXJjZSB3aXRoXG4gICAqIGA/dGlja2V0PTx0PmAgc28gdGhlIEpXVCBuZXZlciBsYW5kcyBpbiBhIHF1ZXJ5IHN0cmluZyAvIGFjY2VzcyBsb2cuIFRoZVxuICAgKiB0aWNrZXQgY2FuIHRoZW4gb25seSBiZSBjb25zdW1lZCB0byBvcGVuIHRoYXQgb25lIHN1YmplY3QncyBzdHJlYW0g4oCUIHNlZVxuICAgKiB7QGxpbmsgY29uc3VtZVRpY2tldH0g4oCUIHdoaWNoIGlzIHdoYXQgZW5mb3JjZXMgcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogT1JHLU9XTkVSU0hJUDogaWYgYSBzdHJlYW0gb3duZXIgaGFzIGJlZW4gYm91bmQgZm9yIHRoaXMgc3ViamVjdCAodmlhXG4gICAqIHtAbGluayBiaW5kU3RyZWFtT3duZXJ9KSBhbmQgaXQgaXMgYSBESUZGRVJFTlQgb3JnLCBtaW50aW5nIGlzIHJlZnVzZWRcbiAgICogKGByZWFzb246ICdmb3JiaWRkZW4nYCkg4oCUIGFuIG9yZyBjYW5ub3QgbWludCBhIHRpY2tldCBmb3IgYW5vdGhlciBvcmcnc1xuICAgKiBzdHJlYW0gZXZlbiBpZiBpdCBndWVzc2VzIHRoZSByZXF1ZXN0SWQuIFdoZW4gbm8gb3duZXIgaXMgYm91bmQgKHByb2R1Y2VyXG4gICAqIHdpcmluZyBub3QgeWV0IHByZXNlbnQpLCBtaW50aW5nIGZhbGxzIGJhY2sgdG8gYmluZGluZyB0aGUgdGlja2V0IHRvIHRoZVxuICAgKiBjYWxsZXIncyBvd24gb3JnLCBwcmVzZXJ2aW5nIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAqXG4gICAqIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgKHByb2Nlc3Mtd2lkZSkgYW5kIGBtYXhUaWNrZXRzUGVyT3JnYFxuICAgKiAocGVyLXRlbmFudCkuIE1pcnJvcnMgdGhlIG1lc3NhZ2Utc2VydmljZSBub3RpZmljYXRpb25zIHRpY2tldCBzdG9yZS5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIC0gT3duaW5nIG9yZyAobm9ybWFsaXplZCBpbnRlcm5hbGx5IHZpYSBub3JtYWxpemVPcmdJZCkuXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBUaGUgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IHRoaXMgdGlja2V0IGF1dGhvcml6ZXMuXG4gICAqICAgVGhlIGNhbGxlciBtdXN0IGhhdmUgZm9ybWF0LXZhbGlkYXRlZCBpdCAoc2VlIHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0pLlxuICAgKiBAcmV0dXJucyBgeyBvazogdHJ1ZSwgdGlja2V0IH1gIG9uIHN1Y2Nlc3MsIG9yIGB7IG9rOiBmYWxzZSwgcmVhc29uIH1gXG4gICAqICAgd2hlcmUgcmVhc29uIGlzIGAnb3JnLWxpbWl0J2AsIGAnY2FwYWNpdHknYCwgb3IgYCdmb3JiaWRkZW4nYC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVRpY2tldChvcmdJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q3JlYXRlVGlja2V0UmVzdWx0PiB7XG4gICAgLy8gT3duZXJzaGlwIGdhdGUgZmlyc3Qg4oCUIGEgY3Jvc3MtdGVuYW50IG1pbnQgYXR0ZW1wdCBzaG91bGQgbmV2ZXIgZXZlblxuICAgIC8vIGNvbnN1bWUgY2FwIGJ1ZGdldC4gT25seSBlbmZvcmNlZCB3aGVuIGFuIG93bmVyIGlzIGFjdHVhbGx5IGJvdW5kLiBCb3RoXG4gICAgLy8gc2lkZXMgYXJlIG9yZy1ub3JtYWxpemVkIHNvIGEgcHJvZHVjZXIvY29uc3VtZXIgY2FzaW5nIGRyaWZ0IGNhbid0XG4gICAgLy8gZmFsc2UtYGZvcmJpZGRlbmAgdGhlIHJlYWwgb3duZXIgKG1pcnJvcnMgcmVxdWVzdElkIG5vcm1hbGl6YXRpb24pLlxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRPcmcgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZU9yZ0lkKG9yZ0lkKTtcbiAgICBjb25zdCBvd25lciA9IGF3YWl0IHRoaXMudGlja2V0U3RvcmUuZ2V0U3RyZWFtT3duZXIobm9ybWFsaXplZCk7XG4gICAgaWYgKG93bmVyICYmIG93bmVyICE9PSBub3JtYWxpemVkT3JnKSB7XG4gICAgICBsb2dnZXIud2FybihgU1NFIHRpY2tldCByZWZ1c2VkOiBvcmcgJHtub3JtYWxpemVkT3JnfSBkb2VzIG5vdCBvd24gc3RyZWFtIHN1YmplY3RgKTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnZm9yYmlkZGVuJyB9O1xuICAgIH1cblxuICAgIC8vIFRvdGFsIGNhcCBuZXh0IOKAlCBwcm90ZWN0cyBwcm9jZXNzIG1lbW9yeSBldmVuIHdoZW4gYSBzaW5nbGUgb3JnIGlzXG4gICAgLy8gdGhlIG9mZmVuZGVyLiBUaGVuIHRoZSBwZXItb3JnIGNhcCBmb3IgZmFpci1zaGFyZS5cbiAgICBpZiAoKGF3YWl0IHRoaXMudGlja2V0U3RvcmUudG90YWwoKSkgPj0gdGhpcy5tYXhUb3RhbFRpY2tldHMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBTU0UgdGlja2V0IGNhcCByZWFjaGVkIChtYXg6ICR7dGhpcy5tYXhUb3RhbFRpY2tldHN9KTsgcmVqZWN0aW5nIHRpY2tldCByZXF1ZXN0YCk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ2NhcGFjaXR5JyB9O1xuICAgIH1cbiAgICBpZiAoKGF3YWl0IHRoaXMudGlja2V0U3RvcmUuY291bnRGb3JPcmcobm9ybWFsaXplZE9yZykpID49IHRoaXMubWF4VGlja2V0c1Blck9yZykge1xuICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIHRpY2tldCBjYXAgcmVhY2hlZCBmb3IgJHtub3JtYWxpemVkT3JnfSAobWF4OiAke3RoaXMubWF4VGlja2V0c1Blck9yZ30pYCk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZy1saW1pdCcgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrZXQgPSByYW5kb21CeXRlcygyNCkudG9TdHJpbmcoJ2Jhc2U2NHVybCcpO1xuICAgIGF3YWl0IHRoaXMudGlja2V0U3RvcmUucHV0KHRpY2tldCwgeyBvcmdJZDogbm9ybWFsaXplZE9yZywgcmVxdWVzdElkOiBub3JtYWxpemVkIH0sIHRoaXMudGlja2V0VHRsTXMpO1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgQ09OU1VNRSBhIHRpY2tldCBmb3IgYSBzcGVjaWZpYyBzdHJlYW0gc3ViamVjdC4gU2luZ2xlLXVzZTpcbiAgICogdGhlIHRpY2tldCBpcyBkZWxldGVkIHdoZXRoZXIgb3Igbm90IGl0IHR1cm5zIG91dCB0byBiZSB2YWxpZCwgc28gYSByZXBsYXlcbiAgICogb2YgdGhlIHNhbWUgdmFsdWUgYWx3YXlzIGZhaWxzLiBSZXR1cm5zIHRoZSBib3VuZCBvcmcgb24gc3VjY2Vzcywgb3IgbnVsbFxuICAgKiB3aGVuIHRoZSB0aWNrZXQgaXMgdW5rbm93biAvIGFscmVhZHktdXNlZCAvIGV4cGlyZWQgLyBPUiB3YXMgbWludGVkIGZvciBhXG4gICAqIERJRkZFUkVOVCBgcmVxdWVzdElkYCB0aGFuIHRoZSBvbmUgYmVpbmcgb3BlbmVkLlxuICAgKlxuICAgKiBUaGUgc3ViamVjdCBjaGVjayBpcyB0aGUgYXV0aG9yaXphdGlvbiBmaXg6IHdpdGhvdXQgaXQsIGEgdGlja2V0IG1pbnRlZCBmb3JcbiAgICogb25lIHN0cmVhbSBjb3VsZCBiZSBwcmVzZW50ZWQgdG8gb3BlbiBBTlkgc3RyZWFtIHRoZSBob2xkZXIncyBvcmcgY291bGRcbiAgICogbmFtZSwgbGV0dGluZyBhbiBhdXRoZW50aWNhdGVkIG9yZyBhdHRhY2ggdG8gYW5vdGhlciBvcmcncyBsb2cgc3RyZWFtIGJ5XG4gICAqIGd1ZXNzaW5nIGl0cyByZXF1ZXN0SWQuIFRoZSBnZW5lcmljIDQwMSB0aGUgY2FsbGVyIHJldHVybnMgZG9lcyBub3RcbiAgICogZGlzdGluZ3Vpc2ggXCJ1bmtub3duIHRpY2tldFwiIGZyb20gXCJ3cm9uZyBzdWJqZWN0XCIsIHNvIGl0IGxlYWtzIG5vdGhpbmdcbiAgICogYWJvdXQgd2hpY2ggcmVxdWVzdElkcyBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHRpY2tldElkIC0gVGhlIG9wYXF1ZSB0aWNrZXQgdmFsdWUgZnJvbSBgP3RpY2tldD1gLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIHN0cmVhbSBzdWJqZWN0IGZyb20gdGhlIFVSTCBwYXRoIChgOnJlcXVlc3RJZGApLFxuICAgKiAgIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyLlxuICAgKi9cbiAgYXN5bmMgY29uc3VtZVRpY2tldCh0aWNrZXRJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgY29uc3QgdGlja2V0ID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb25zdW1lKHRpY2tldElkKTsgLy8gc2luZ2xlLXVzZVxuICAgIGlmICghdGlja2V0KSByZXR1cm4gbnVsbDtcbiAgICAvLyBTdWJqZWN0IGJpbmRpbmcg4oCUIHJlamVjdCBhIHRpY2tldCBwcmVzZW50ZWQgZm9yIGEgc3ViamVjdCBpdCB3YXMgbm90XG4gICAgLy8gbWludGVkIGZvci4gQm90aCBzaWRlcyBhcmUgbm9ybWFsaXplZCBzbyBkYXNoZWQvdW5kYXNoZWQgZm9ybXMgbWF0Y2guXG4gICAgaWYgKHRpY2tldC5yZXF1ZXN0SWQgIT09IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7IG9yZ0lkOiB0aWNrZXQub3JnSWQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2xpZW50IHRvIHRoZSBTU0UgbWFuYWdlclxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVW5pcXVlIHJlcXVlc3QgSURcbiAgICogQHBhcmFtIHJlcyAtIEV4cHJlc3MgUmVzcG9uc2Ugb2JqZWN0XG4gICAqIEBwYXJhbSBvcmdJZCAtIEF1dGhlbnRpY2F0ZWQgb3JnIGlkIChvcHRpb25hbCkuIFdoZW4gc2V0LCBlbmZvcmNlcyB0aGVcbiAgICogICBwZXItb3JnIGNhcCBhbmQgdGhlIGNvdW50ZXIgaXMgZGVjcmVtZW50ZWQgb24gZGlzY29ubmVjdC9jbGVhbnVwLlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIGNsaWVudCB3YXMgYWRkZWQsIGZhbHNlIGlmIHJlamVjdGVkIChsaW1pdCByZWFjaGVkKVxuICAgKi9cbiAgYWRkQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCByZXM6IFJlc3BvbnNlLCBvcmdJZD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdO1xuXG4gICAgLy8gQ2hlY2sgY2xpZW50IGxpbWl0XG4gICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+PSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KSB7XG4gICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdH0pYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUHJvY2Vzcy13aWRlIGNhcDogcHJvdGVjdHMgZmQgdGFibGUgKyBtZW1vcnkgZnJvbSBydW5hd2F5IGRhc2hib2FyZHMuXG4gICAgaWYgKHRoaXMudG90YWxDbGllbnRzKCkgPj0gdGhpcy5tYXhUb3RhbENsaWVudHMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBUb3RhbCBTU0UgY2xpZW50IGNhcCByZWFjaGVkIChtYXg6ICR7dGhpcy5tYXhUb3RhbENsaWVudHN9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUGVyLW9yZyBjYXA6IHByZXZlbnRzIG9uZSBub2lzeSBvcmcgZnJvbSBtb25vcG9saXppbmcgcHJvY2Vzcy13aWRlXG4gICAgLy8gc2xvdHMuIEVuZm9yY2VkIG9ubHkgd2hlbiBvcmdJZCBpcyBrbm93biDigJQgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91c1xuICAgIC8vIHN0cmVhbXMgdGhhdCBuZXZlciBpZGVudGlmeSB3aXRoIGFuIG9yZ0lkIHN0YXkgc3ViamVjdCB0byB0aGUgZ2xvYmFsXG4gICAgLy8gY2VpbGluZ3MgYWJvdmUuIFJlc2VydmUgYXRvbWljYWxseSBiZWZvcmUgaW5zZXJ0IHNvIHR3byBjb25jdXJyZW50XG4gICAgLy8gcmVxdWVzdHMgYXQgdGhlIGxpbWl0IGNhbid0IGJvdGggc3VjY2VlZC5cbiAgICBpZiAob3JnSWQpIHtcbiAgICAgIGNvbnN0IG9yZ0N1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgICBpZiAob3JnQ3VycmVudCA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3JnQ2xpZW50Q291bnRzLnNldChvcmdJZCwgb3JnQ3VycmVudCArIDEpO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSB0aW1lb3V0IGZvciB0aGlzIGNsaWVudFxuICAgIGNvbnN0IGNsaWVudElkID0gdXVpZCgpO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IHRpbWVkIG91dCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gdGltZW91dCcsIHsgcmVxdWVzdElkLCBjbGllbnRJZCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLmNsaWVudFRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBjbGllbnQ6IFNTRUNsaWVudCA9IHtcbiAgICAgIGlkOiBjbGllbnRJZCxcbiAgICAgIHJlcyxcbiAgICAgIGNvbm5lY3RlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgdGltZW91dCxcbiAgICAgIGJhY2twcmVzc3VyZUNvdW50OiAwLFxuICAgICAgb3JnSWQsXG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBkaXNjb25uZWN0aW9uXG4gICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgcmVzLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihgU1NFIGNsaWVudCBlcnJvciBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH06YCwgZXJyKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgZXhpc3RpbmcucHVzaChjbGllbnQpO1xuICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCBleGlzdGluZyk7XG5cbiAgICBsb2dnZXIuZGVidWcoYENsaWVudCAke2NsaWVudElkfSBjb25uZWN0ZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICh0b3RhbDogJHtleGlzdGluZy5sZW5ndGh9KWApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIERyb3Agb25lIGZyb20gdGhlIHBlci1vcmcgY291bnRlci4gSWRlbXBvdGVudDogYSBjb3VudGVyIGF0IDAgc3RheXMgYXQgMFxuICAgKiAgYW5kIHRoZSBvcmcga2V5IGlzIHJlbW92ZWQgZnJvbSB0aGUgbWFwLiAqL1xuICBwcml2YXRlIGRlY3JlbWVudE9yZ0NvdW50KG9yZ0lkPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFvcmdJZCkgcmV0dXJuO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgaWYgKGN1cnJlbnQgPD0gMSkgdGhpcy5vcmdDbGllbnRDb3VudHMuZGVsZXRlKG9yZ0lkKTtcbiAgICBlbHNlIHRoaXMub3JnQ2xpZW50Q291bnRzLnNldChvcmdJZCwgY3VycmVudCAtIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBjbGllbnQgZnJvbSB0aGUgbWFuYWdlclxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVDbGllbnQocmVxdWVzdElkOiBzdHJpbmcsIGNsaWVudElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpO1xuICAgIGlmICghY2xpZW50cykgcmV0dXJuO1xuXG4gICAgY29uc3QgcmVtYWluaW5nID0gY2xpZW50cy5maWx0ZXIoYyA9PiB7XG4gICAgICBpZiAoYy5pZCA9PT0gY2xpZW50SWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGMudGltZW91dCk7XG4gICAgICAgIC8vIE1pcnJvciB0aGUgcGVyLW9yZyBjb3VudGVyIOKAlCBtdXN0IGRlY3JlbWVudCBoZXJlLCBub3QganVzdCBpbiB0aGVcbiAgICAgICAgLy8gZXhwbGljaXQgY2xvc2UgcGF0aHMsIHNpbmNlICdjbG9zZScvJ2Vycm9yJyBldmVudCBoYW5kbGVycyBhcmUgdGhlXG4gICAgICAgIC8vIHByaW1hcnkgZGlzY29ubmVjdCBzaWduYWwgaW4gcHJhY3RpY2UuXG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoYy5vcmdJZCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuXG4gICAgaWYgKHJlbWFpbmluZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQWxsIGNsaWVudHMgZGlzY29ubmVjdGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgcmVtYWluaW5nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGFsbCBTU0UgY2xpZW50cyBmb3IgYSByZXF1ZXN0SWRcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFJlcXVlc3QgSURcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgTnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIHNlbmQocmVxdWVzdElkOiBzdHJpbmcsIHR5cGU6IFNTRUV2ZW50VHlwZSwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IG51bWJlciB7XG4gICAgY29uc3QgcGF5bG9hZDogU1NFUGF5bG9hZCA9IHtcbiAgICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0eXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRhdGEsXG4gICAgfTtcblxuICAgIC8vIERlbGl2ZXIgdG8gTE9DQUwgY2xpZW50cyBmaXJzdCwgdGhlbiByZWxheSB0aGUgU0FNRSBwYXlsb2FkIHRvIG90aGVyIHBvZHNcbiAgICAvLyBzbyBhbiBFdmVudFNvdXJjZSBhdHRhY2hlZCBvbiBhIGRpZmZlcmVudCByZXBsaWNhIGFsc28gcmVjZWl2ZXMgaXQuIFRoZVxuICAgIC8vIHJlbGF5IGlzIGZpcmUtYW5kLWZvcmdldCBhbmQgZmFpbC1zYWZlOiBubyByZWxheSAvIFJlZGlzIGRvd24g4oeSIGxvY2FsLW9ubHkuXG4gICAgY29uc3Qgc2VudENvdW50ID0gdGhpcy5zZW5kTG9jYWwocmVxdWVzdElkLCBwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdzZW5kJywgcmVxdWVzdElkLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byB0aGlzIHBvZCdzIExPQ0FMIGNsaWVudHMgZm9yIGByZXF1ZXN0SWRgLiBTaGFyZWRcbiAgICogYnkge0BsaW5rIHNlbmR9IChsb2NhbCBoYWxmKSBhbmQgdGhlIHJlbGF5IHJlLWVtaXQgcGF0aCAoe0BsaW5rIG9uUmVsYXlNZXNzYWdlfSksXG4gICAqIHNvIGEgcmVsYXllZCBmcmFtZSByZXVzZXMgdGhlIHByb2R1Y2VyJ3Mgb3JpZ2luYWwgYHRzYCByYXRoZXIgdGhhbiBhIG5ldyBvbmUuXG4gICAqIE5ldmVyIHJlbGF5cyDigJQgY2FsbGVycyBkZWNpZGUgd2hldGhlciB0byBwdWJsaXNoLlxuICAgKi9cbiAgcHJpdmF0ZSBzZW5kTG9jYWwocmVxdWVzdElkOiBzdHJpbmcsIHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIGNvbnN0IGNsaWVudHMgPSBbLi4uKHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXSldO1xuICAgIGxldCBzZW50Q291bnQgPSAwO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShwYXlsb2FkKX1cXG5cXG5gO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQmFja3ByZXNzdXJlOiBza2lwIGNsaWVudHMgd2hvc2Ugd3JpdGUgYnVmZmVyIGlzIGZ1bGxcbiAgICAgICAgaWYgKGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYW5Xcml0ZSA9IGNsaWVudC5yZXMud3JpdGUoc2VyaWFsaXplZCk7XG4gICAgICAgIGlmICghY2FuV3JpdGUpIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQrKztcbiAgICAgICAgICAvLyBEaXNjb25uZWN0IGNsaWVudHMgdGhhdCBjb25zaXN0ZW50bHkgY2FuJ3Qga2VlcCB1cCAoMTAgY29uc2VjdXRpdmUgYmFja3ByZXNzdXJlIGV2ZW50cylcbiAgICAgICAgICBpZiAoY2xpZW50LmJhY2twcmVzc3VyZUNvdW50ID49IENvcmVDb25zdGFudHMuU1NFX0JBQ0tQUkVTU1VSRV9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKGBEaXNjb25uZWN0aW5nIHNsb3cgY2xpZW50ICR7Y2xpZW50LmlkfSBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKCR7Y2xpZW50LmJhY2twcmVzc3VyZUNvdW50fSBiYWNrcHJlc3N1cmUgZXZlbnRzKWApO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQgPSAwOyAvLyBSZXNldCBvbiBzdWNjZXNzZnVsIHdyaXRlXG4gICAgICAgIH1cbiAgICAgICAgc2VudENvdW50Kys7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzZW5kIHRvIGNsaWVudCAke2NsaWVudC5pZH06YCwgZXJyb3IpO1xuICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbnRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCcm9hZGNhc3QgYSBtZXNzYWdlIHRvIGFsbCBjb25uZWN0ZWQgY2xpZW50cyBhY3Jvc3MgYWxsIHJlcXVlc3RzXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gRXZlbnQgdHlwZVxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIE1lc3NhZ2Ugc3RyaW5nXG4gICAqIEBwYXJhbSBkYXRhIC0gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gICAqIEByZXR1cm5zIFRvdGFsIG51bWJlciBvZiBjbGllbnRzIHRoZSBtZXNzYWdlIHdhcyBzZW50IHRvXG4gICAqL1xuICBicm9hZGNhc3QodHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuICAgIC8vIERlbGl2ZXIgdG8gbG9jYWwgY2xpZW50cywgdGhlbiByZWxheSBhIHNpbmdsZSBicm9hZGNhc3QgZnJhbWUgc28gRVZFUlkgcG9kXG4gICAgLy8gcmUtZW1pdHMgdG8gQUxMIG9mIGl0cyBvd24gY2xpZW50cyDigJQgYSBwZXItcmVxdWVzdElkIHJlbGF5IHdvdWxkIG1pc3NcbiAgICAvLyBzdWJqZWN0cyB0aGF0IG9ubHkgZXhpc3Qgb24gb3RoZXIgcmVwbGljYXMuXG4gICAgY29uc3QgdG90YWxTZW50ID0gdGhpcy5icm9hZGNhc3RMb2NhbChwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdicm9hZGNhc3QnLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiB0b3RhbFNlbnQ7XG4gIH1cblxuICAvKiogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byBhbGwgTE9DQUwgY2xpZW50cyBhY3Jvc3MgZXZlcnkgcmVxdWVzdC4gKi9cbiAgcHJpdmF0ZSBicm9hZGNhc3RMb2NhbChwYXlsb2FkOiBTU0VQYXlsb2FkKTogbnVtYmVyIHtcbiAgICBsZXQgdG90YWxTZW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RJZCBvZiBbLi4udGhpcy5jbGllbnRzLmtleXMoKV0pIHtcbiAgICAgIHRvdGFsU2VudCArPSB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICByZXR1cm4gdG90YWxTZW50O1xuICB9XG5cbiAgLyoqIEZpcmUtYW5kLWZvcmdldCByZWxheSBwdWJsaXNoLiBOby1vcCAobG9jYWwtb25seSkgd2hlbiBubyByZWxheSBpcyB3aXJlZC4gKi9cbiAgcHJpdmF0ZSBwdWJsaXNoUmVsYXkobXNnOiBTU0VSZWxheU1lc3NhZ2UpOiB2b2lkIHtcbiAgICB0aGlzLnJlbGF5Py5wdWJsaXNoKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgYWxsIGNsaWVudHMgZm9yIGEgc3BlY2lmaWMgcmVxdWVzdFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRCB0byBjbG9zZVxuICAgKiBAcGFyYW0gZmluYWxNZXNzYWdlIC0gT3B0aW9uYWwgZmluYWwgbWVzc2FnZSB0byBzZW5kIGJlZm9yZSBjbG9zaW5nXG4gICAqL1xuICBjbG9zZVJlcXVlc3QocmVxdWVzdElkOiBzdHJpbmcsIGZpbmFsTWVzc2FnZT86IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk7XG4gICAgaWYgKCFjbGllbnRzKSByZXR1cm47XG5cbiAgICBpZiAoZmluYWxNZXNzYWdlKSB7XG4gICAgICB0aGlzLnNlbmQocmVxdWVzdElkLCAnQ09NUExFVEVEJywgZmluYWxNZXNzYWdlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICBjbGVhclRpbWVvdXQoY2xpZW50LnRpbWVvdXQpO1xuICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xpZW50LnJlcy5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Jlc3BvbnNlIGFscmVhZHkgY2xvc2VkIG9uIHJlcXVlc3QgY2xvc2UnLCB7IHJlcXVlc3RJZCwgY2xpZW50SWQ6IGNsaWVudC5pZCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbG9zZWQgYWxsIGNsaWVudHMgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3MgYWJvdXQgY3VycmVudCBjb25uZWN0aW9uc1xuICAgKi9cbiAgZ2V0U3RhdHMoKTogU1NFTWFuYWdlclN0YXRzIHtcbiAgICBsZXQgdG90YWxDbGllbnRzID0gMDtcbiAgICBsZXQgb2xkZXN0Q29ubmVjdGlvbjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIHtcbiAgICAgIHRvdGFsQ2xpZW50cyArPSBjbGllbnRzLmxlbmd0aDtcbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgICAgY29uc3QgYWdlID0gbm93IC0gY2xpZW50LmNvbm5lY3RlZEF0O1xuICAgICAgICBpZiAob2xkZXN0Q29ubmVjdGlvbiA9PT0gbnVsbCB8fCBhZ2UgPiBvbGRlc3RDb25uZWN0aW9uKSB7XG4gICAgICAgICAgb2xkZXN0Q29ubmVjdGlvbiA9IGFnZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbFJlcXVlc3RzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHRvdGFsQ2xpZW50cyxcbiAgICAgIG9sZGVzdENvbm5lY3Rpb25Nczogb2xkZXN0Q29ubmVjdGlvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgcmVxdWVzdCBoYXMgYW55IGNvbm5lY3RlZCBjbGllbnRzXG4gICAqL1xuICBoYXNDbGllbnRzKHJlcXVlc3RJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICByZXR1cm4gY2xpZW50cyAhPT0gdW5kZWZpbmVkICYmIGNsaWVudHMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBjbGllbnRzIGZvciBhIHNwZWNpZmljIHJlcXVlc3RcbiAgICovXG4gIGdldENsaWVudENvdW50KHJlcXVlc3RJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpPy5sZW5ndGggPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaWRkbGV3YXJlIHRvIGluaXRpYWxpemUgYSB0aWNrZXQtYXV0aGVudGljYXRlZCBTU0UgY29ubmVjdGlvbi5cbiAgICpcbiAgICogVGhlIHN0cmVhbSBpcyBOT1Qgb3BlbiB0byB0aGUgd29ybGQ6IHRoZSBjYWxsZXIgbXVzdCBmaXJzdCBleGNoYW5nZSBpdHNcbiAgICogSldUIGZvciBhIHNob3J0LWxpdmVkIHNpbmdsZS11c2UgdGlja2V0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0sIHdpcmVkIHRvXG4gICAqIGBQT1NUIC9sb2dzL3RpY2tldGApIGFuZCBwYXNzIGl0IGFzIGA/dGlja2V0PTx0PmAuIFRoZSBtaWRkbGV3YXJlIHZhbGlkYXRlc1xuICAgKiArIGNvbnN1bWVzIHRoZSB0aWNrZXQsIGJpbmRzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSB0aWNrZXQncyBvcmcsIGFuZFxuICAgKiBlbmZvcmNlcyB0aGUgcGVyLW9yZyBjb25uZWN0aW9uIGNhcC4gQSBtaXNzaW5nIC8gaW52YWxpZCAvIGV4cGlyZWQgL1xuICAgKiBhbHJlYWR5LXVzZWQgdGlja2V0IGlzIHJlamVjdGVkIHdpdGggNDAxIGJlZm9yZSBhbnkgU1NFIGhlYWRlcnMgZmx1c2guXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXBwLmdldCgnL2xvZ3MvOnJlcXVlc3RJZCcsIHNzZU1hbmFnZXIubWlkZGxld2FyZSgpKTtcbiAgICogYGBgXG4gICAqL1xuICBtaWRkbGV3YXJlKCkge1xuICAgIHJldHVybiBhc3luYyAocmVxOiB7IHBhcmFtczogeyByZXF1ZXN0SWQ6IHN0cmluZyB9OyBxdWVyeT86IHsgdGlja2V0PzogdW5rbm93biB9IH0sIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IHsgcmVxdWVzdElkIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICBpZiAoIVNTRV9SRVFVRVNUX0lEX1JFLnRlc3QocmVxdWVzdElkKSkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMCkuZW5kKCdJbnZhbGlkIHJlcXVlc3RJZCBmb3JtYXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUaWNrZXQgYXV0aCDigJQgcmVxdWlyZWQuIFJlc29sdmUgYD90aWNrZXQ9PHQ+YCwgdGhlbiB2YWxpZGF0ZSArIGNvbnN1bWVcbiAgICAgIC8vIGl0IChzaW5nbGUtdXNlKSBGT1IgVEhJUyBTVUJKRUNULiBBbiBhbm9ueW1vdXMsIG1hbGZvcm1lZCwgdW5rbm93bixcbiAgICAgIC8vIGV4cGlyZWQsIGFscmVhZHktY29uc3VtZWQsIG9yIHdyb25nLXN1YmplY3QgdGlja2V0IGlzIGEgNDAxLiBUaGUgb3JnIGlzXG4gICAgICAvLyB0YWtlbiBmcm9tIHRoZSB0aWNrZXQsIHNvIHRoZSBzdHJlYW0gaXMgYWx3YXlzIGJvdW5kIHRvIGEgdmVyaWZpZWRcbiAgICAgIC8vIHRlbmFudCBBTkQgdG8gdGhlIGV4YWN0IHN1YmplY3QgdGhlIHRpY2tldCB3YXMgbWludGVkIGZvciAobm8gYW5vbnltb3VzXG4gICAgICAvLyBzdHJlYW1zLCBubyBjcm9zcy1zdWJqZWN0IGF0dGFjaCkuXG4gICAgICBjb25zdCB0aWNrZXRJZCA9IHJlcS5xdWVyeT8udGlja2V0O1xuICAgICAgaWYgKHR5cGVvZiB0aWNrZXRJZCAhPT0gJ3N0cmluZycgfHwgdGlja2V0SWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ01pc3NpbmcgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbnN1bWVkID0gYXdhaXQgdGhpcy5jb25zdW1lVGlja2V0KHRpY2tldElkLCByZXF1ZXN0SWQpO1xuICAgICAgaWYgKCFjb25zdW1lZCkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMSkuZW5kKCdJbnZhbGlkIG9yIGV4cGlyZWQgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9yZ0lkID0gY29uc3VtZWQub3JnSWQ7XG5cbiAgICAgIC8vIFByZS1mbGlnaHQgcGVyLXJlcXVlc3QgY2FwIHNvIHdlIGNhbiByZXR1cm4gNDI5IGJlZm9yZSBmbHVzaGluZ1xuICAgICAgLy8gU1NFIGhlYWRlcnMgKGFmdGVyIGhlYWRlcnMgYXJlIGZsdXNoZWQgdGhlIGNsaWVudCBjYW4ndCByZWFkIGEgNDI5KS5cbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdO1xuICAgICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+PSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBDbGllbnQgbGltaXQgcmVhY2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0fSlgKTtcbiAgICAgICAgcmVzLnN0YXR1cyg0MjkpLmVuZCgnVG9vIG1hbnkgY29ubmVjdGlvbnMgZm9yIHRoaXMgcmVxdWVzdCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFNhbWUgZm9yIHRoZSBwZXItb3JnIGNhcCDigJQgYmV0dGVyIHRvIHNlbmQgNDI5IHRoYW4gb3BlbiB0aGUgc3RyZWFtIGFuZFxuICAgICAgLy8gaW1tZWRpYXRlbHkgY2xvc2UgaXQuIFRoZSB0aWNrZXQgZ3VhcmFudGVlcyBhIHZlcmlmaWVkIG9yZyBpZCwgc28gdGhlXG4gICAgICAvLyBwZXItb3JnIGNlaWxpbmcgaXMgYWx3YXlzIGVuZm9yY2VkIGZvciB0aGUgL2xvZ3Mgc3RyZWFtLlxuICAgICAgaWYgKCh0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDApID49IHRoaXMubWF4Q2xpZW50c1Blck9yZykge1xuICAgICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgY2xpZW50IGNhcCByZWFjaGVkIGZvciAke29yZ0lkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1Blck9yZ30pYCk7XG4gICAgICAgIHJlcy5zdGF0dXMoNDI5KS5lbmQoJ1RvbyBtYW55IFNTRSBjb25uZWN0aW9ucyBmb3IgdGhpcyBvcmdhbml6YXRpb24nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9ldmVudC1zdHJlYW0nKTtcbiAgICAgIHJlcy5zZXRIZWFkZXIoJ0NhY2hlLUNvbnRyb2wnLCAnbm8tY2FjaGUnKTtcbiAgICAgIHJlcy5zZXRIZWFkZXIoJ0Nvbm5lY3Rpb24nLCAna2VlcC1hbGl2ZScpO1xuICAgICAgcmVzLnNldEhlYWRlcignWC1BY2NlbC1CdWZmZXJpbmcnLCAnbm8nKTsgLy8gRGlzYWJsZSBuZ2lueCBidWZmZXJpbmdcbiAgICAgIHJlcy5mbHVzaEhlYWRlcnMoKTtcblxuICAgICAgLy8gSGVhZGVycyBhcmUgZmx1c2hlZCDigJQgd2UgY2FuIG5vIGxvbmdlciBzZW5kIGEgNDI5LiBhZGRDbGllbnQgcmUtY2hlY2tzXG4gICAgICAvLyB0aGUgY2FwcyAoaW5jbHVkaW5nIHRoZSBwcm9jZXNzLXdpZGUgdG90YWwtY2xpZW50cyBjYXAsIHdoaWNoIHRoZVxuICAgICAgLy8gcHJlLWZsaWdodCBhYm92ZSBkb2VzIG5vdCkgYW5kIGNhbiBzdGlsbCByZWplY3Qgb24gYSByYWNlOiBhIGNvbmN1cnJlbnRcbiAgICAgIC8vIGNvbm5lY3Rpb24gbWF5IGhhdmUgZmlsbGVkIGEgY2FwIGJldHdlZW4gdGhlIHByZS1mbGlnaHQgY2hlY2sgYW5kIGhlcmUuXG4gICAgICAvLyBPbiByZWplY3Rpb24sIGNsb3NlIHRoZSBub3ctZGFuZ2xpbmcgcmVzcG9uc2UgaW5zdGVhZCBvZiBsZWF2aW5nIGFuXG4gICAgICAvLyBvcGVuIHNvY2tldCB3aXRoIG5vIGNsaWVudCByZWNvcmQgKHdoaWNoIHdvdWxkIGxlYWsgYW4gZmQgKyBuZXZlciBlbWl0XG4gICAgICAvLyBzdHJlYW0gZGF0YSkuXG4gICAgICBjb25zdCBhZGRlZCA9IHRoaXMuYWRkQ2xpZW50KHJlcXVlc3RJZCwgcmVzLCBvcmdJZCk7XG4gICAgICBpZiAoIWFkZGVkKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBTU0UgYWRkQ2xpZW50IHJlamVjdGVkIGFmdGVyIGhlYWRlcnMgZmx1c2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH07IGNsb3NpbmcgZGFuZ2xpbmcgcmVzcG9uc2VgKTtcbiAgICAgICAgdHJ5IHsgcmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgcGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGFydENsZWFudXBJbnRlcnZhbChpbnRlcnZhbE1zOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFudXBJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgIH0sIGludGVydmFsTXMpO1xuXG4gICAgLy8gRG9uJ3QgcHJldmVudCBwcm9jZXNzIGV4aXRcbiAgICB0aGlzLmNsZWFudXBJbnRlcnZhbC51bnJlZigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFuIHVwIHN0YWxlIGNvbm5lY3Rpb25zIHVzaW5nIHNpbmdsZS1wYXNzIHBhcnRpdGlvbi5cbiAgICogTyhSIMOXIEMpIGluc3RlYWQgb2YgTyhSIMOXIEPCsiksIGFuZCBhdm9pZHMgbXV0YXRpb24tZHVyaW5nLWl0ZXJhdGlvbi5cbiAgICovXG4gIHByaXZhdGUgY2xlYW51cCgpOiB2b2lkIHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCBjbGVhbmVkID0gMDtcblxuICAgIC8vIFN3ZWVwIGV4cGlyZWQgdGlja2V0cy9vd25lcnMgc28gYW4gaW4tbWVtb3J5IHN0b3JlIHN0YXlzIGJvdW5kZWQgZXZlbiB3aGVuXG4gICAgLy8gdGlja2V0cyBhcmUgbWludGVkIGJ1dCBuZXZlciBjb25zdW1lZCAoY2xpZW50IGNsb3NlZCB0aGUgdGFiIGJlZm9yZVxuICAgIC8vIGNvbm5lY3RpbmcpLiBDb25zdW1lLXRpbWUgc3RpbGwgcmUtY2hlY2tzIGV4cGlyeSwgc28gdGhpcyBpcyBtZW1vcnlcbiAgICAvLyBoeWdpZW5lIG9ubHk7IHRoZSBSZWRpcyBzdG9yZSByZWxpZXMgb24gbmF0aXZlIGtleSBUVEwgKHN3ZWVwIGlzIGEgbm8tb3ApLlxuICAgIHZvaWQgdGhpcy50aWNrZXRTdG9yZS5zd2VlcD8uKCk7XG5cbiAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIGNsaWVudHNdIG9mIHRoaXMuY2xpZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHN0YWxlOiBTU0VDbGllbnRbXSA9IFtdO1xuICAgICAgY29uc3QgYWN0aXZlOiBTU0VDbGllbnRbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIC8vIFRpbWUtYmFzZWQgZXZpY3Rpb24gT1IgYSBzb2NrZXQgdGhhdCBzaWxlbnRseSBjbG9zZWQgKG5vICdjbG9zZSdcbiAgICAgICAgLy8gZXZlbnQpIOKAlCBOb2RlIHNvbWV0aW1lcyBkcm9wcyBzb2NrZXRzIHdpdGhvdXQgZmlyaW5nIHRoZSBldmVudCxcbiAgICAgICAgLy8gc28gd2UgZXhwbGljaXRseSBjaGVjayB3cml0YWJsZUVuZGVkL2Rlc3Ryb3llZCBoZXJlLlxuICAgICAgICBjb25zdCBhZ2VTdGFsZSA9IG5vdyAtIGNsaWVudC5jb25uZWN0ZWRBdCA+IHRoaXMuY2xpZW50VGltZW91dE1zO1xuICAgICAgICBjb25zdCBzb2NrZXREZWFkID0gY2xpZW50LnJlcy53cml0YWJsZUVuZGVkIHx8IChjbGllbnQucmVzIGFzIHsgZGVzdHJveWVkPzogYm9vbGVhbiB9KS5kZXN0cm95ZWQgPT09IHRydWU7XG4gICAgICAgIGlmIChhZ2VTdGFsZSB8fCBzb2NrZXREZWFkKSB7XG4gICAgICAgICAgc3RhbGUucHVzaChjbGllbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjdGl2ZS5wdXNoKGNsaWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2Ygc3RhbGUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICBjbGVhbmVkKys7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3RpdmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhbGUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYW5lZCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICAvLyBUZWFyIGRvd24gdGhlIHJlbGF5J3MgUmVkaXMgY29ubmVjdGlvbnMgKGJlc3QtZWZmb3J0OyBuZXZlciB0aHJvd3MpLlxuICAgIHZvaWQgdGhpcy5yZWxheT8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7IC8qIGFscmVhZHkgY2xvc2luZyAqLyB9KTtcblxuICAgIGxvZ2dlci5pbmZvKCdTU0UgTWFuYWdlciBzaHV0IGRvd24nKTtcbiAgfVxufVxuIl19
633
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSx1QkFBdUIsRUFBdUIsTUFBTSx1QkFBdUIsQ0FBQztBQUVyRixNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFpRzNDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxxRUFBcUUsQ0FBQztBQWdCdkc7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDYixPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7SUFDakQ7OzJDQUV1QztJQUMvQixlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDcEQ7O2lGQUU2RTtJQUM1RCxXQUFXLENBQWlCO0lBQzVCLG9CQUFvQixDQUFTO0lBQzdCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixlQUFlLENBQVM7SUFDeEIsZ0JBQWdCLENBQVM7SUFDekIsV0FBVyxDQUFTO0lBQ3BCLGdCQUFnQixDQUFTO0lBQ3pCLGVBQWUsQ0FBUztJQUNqQyxlQUFlLEdBQTBCLElBQUksQ0FBQztJQUN0RCwrREFBK0Q7SUFDOUMsS0FBSyxDQUFZO0lBQ2xDLGtGQUFrRjtJQUNqRSxN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WUFDWixDQUFDO1lBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqQyxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLE9BQU8sd0JBQXdCLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDcEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQztRQUVELEtBQUssTUFBTSxTQUFTLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELHVFQUF1RTtRQUN2RSxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUF5QixDQUFDLENBQUMsQ0FBQztRQUVoRSxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBTU0VfVElDS0VUX1RUTF9NUywgd3JpdGVTc2VIZWFkZXJzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHR5cGUgeyBTU0VSZWxheSwgU1NFUmVsYXlNZXNzYWdlIH0gZnJvbSAnLi9zc2UtcmVsYXkuanMnO1xuaW1wb3J0IHsgY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUsIHR5cGUgU1NFVGlja2V0U3RvcmUgfSBmcm9tICcuL3NzZS10aWNrZXQtc3RvcmUuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBsaXZlICh1bmNvbnN1bWVkLCB1bmV4cGlyZWQpIFNTRSB0aWNrZXRzIGFjcm9zcyB0aGVcbiAgICogcHJvY2Vzcy4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLiBCb3VuZHMgbWVtb3J5XG4gICAqIHVuZGVyIGFidXNlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH1gXG4gICAqIG9uY2UgcmVhY2hlZC5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgU1NFIHRpY2tldHMuIERlZmF1bHRzIHRvIDEwIGZyb21cbiAgICogYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gUHJldmVudHMgYSBzaW5nbGUgdGVuYW50IGZyb20gc2F0dXJhdGluZyB0aGVcbiAgICogdGlja2V0IHRhYmxlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnLWxpbWl0JyB9YFxuICAgKiBvbmNlIHJlYWNoZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQuIERlZmF1bHRzIHRvIGFuIGluLW1lbW9yeSBzdG9yZSAoY29ycmVjdFxuICAgKiBzaW5nbGUtcmVwbGljYSBvbmx5KS4gSW5qZWN0IGBjcmVhdGVFbnZSZWRpc1RpY2tldFN0b3JlKClgIChvciBhIGJlc3Bva2VcbiAgICogYFNTRVRpY2tldFN0b3JlYCkgc28gdGlja2V0IG1pbnQvcmVkZWVtIEFORCBzdHJlYW0gb3duZXJzaGlwIHdvcmsgYWNyb3NzXG4gICAqIGhvcml6b250YWxseS1zY2FsZWQgcG9kcyBhbmQg4oCUIGNyaXRpY2FsbHkg4oCUIHNvIHRoZSBwbGF0Zm9ybSBzdHJlYW0gcHJvZHVjZXJcbiAgICogKGEgZGlmZmVyZW50IHNlcnZpY2UpIGNhbiBiaW5kIG93bmVyc2hpcCB0aGF0IHRoaXMgc2VydmljZSByZWFkcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU1NFVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0OiBgU1NFX1NUUkVBTV9PV05FUl9UVExfTVNgIGVudiBvclxuICAgKiAxaCkuIExvbmcgZW5vdWdoIHRvIG91dGxpdmUgYSBidWlsZDsgdGhlIHByb2R1Y2VyIHJlLWJpbmRzIGFzIG5lZWRlZC5cbiAgICovXG4gIHN0cmVhbU93bmVyVHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDcm9zcy1wb2QgZmFuLW91dCBidXMgZm9yIGBzZW5kKClgL2Bicm9hZGNhc3QoKWAuIE9wdGlvbmFsIOKAlCB3aGVuIG9taXR0ZWQsXG4gICAqIGRlbGl2ZXJ5IGlzIExPQ0FMLU9OTFkgKGNvcnJlY3Qgc2luZ2xlLXJlcGxpY2E7IHRvZGF5J3MgYmVoYXZpb3IpLiBJbmplY3RcbiAgICogYGNyZWF0ZUVudlJlZGlzU1NFUmVsYXkoKWAgc28gYSBmcmFtZSBwcm9kdWNlZCBvbiBvbmUgcG9kIHJlYWNoZXMgYW5cbiAgICogRXZlbnRTb3VyY2UgYXR0YWNoZWQgb24gYSBESUZGRVJFTlQgcG9kLiBEZWdyYWRlcyB0byBsb2NhbC1vbmx5IGF1dG9tYXRpY2FsbHlcbiAgICogd2hlbiBSZWRpcyBpcyB1bnNldCAodGhlIGZhY3RvcnkgcmV0dXJucyBudWxsKSBvciBkdXJpbmcgYSBSZWRpcyBvdXRhZ2UuXG4gICAqL1xuICByZWxheT86IFNTRVJlbGF5O1xufVxuXG4vKipcbiAqIEEgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IGlkOiBlaXRoZXIgYSBkYXNoZWQgVVVJRCAoYXBpLXNlcnZlcidzIGB1dWlkKClgKVxuICogb3IgbmdpbngncyBgJHJlcXVlc3RfaWRgIOKAlCAxNiByYW5kb20gYnl0ZXMgcmVuZGVyZWQgYXMgMzIgaGV4IGNoYXJzIHdpdGggTk9cbiAqIGRhc2hlcy4gQWNjZXB0IGJvdGggYnkgbWFraW5nIHRoZSBncm91cCBzZXBhcmF0b3JzIG9wdGlvbmFsOyBzdGlsbCBzdHJpY3RseVxuICogMzIgaGV4IGNoYXJzIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiAvIHBhdGgtdHJhdmVyc2FsIHBheWxvYWQgaW50byB0aGVcbiAqIFNTRSBzdWJqZWN0LiBTaGFyZWQgYnkgdGhlIHRpY2tldC1taW50IHJvdXRlIGFuZCB0aGUgc3RyZWFtIG1pZGRsZXdhcmUgc29cbiAqIGJvdGggdmFsaWRhdGUgdGhlIHN1YmplY3QgaWRlbnRpY2FsbHkuXG4gKi9cbmV4cG9ydCBjb25zdCBTU0VfUkVRVUVTVF9JRF9SRSA9IC9eWzAtOWEtZl17OH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezEyfSQvaTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU1NFTWFuYWdlci5jcmVhdGVUaWNrZXR9LiAqL1xuZXhwb3J0IHR5cGUgQ3JlYXRlVGlja2V0UmVzdWx0ID1cbiAgfCB7IG9rOiB0cnVlOyB0aWNrZXQ6IHN0cmluZyB9XG4gIHwgeyBvazogZmFsc2U7IHJlYXNvbjogJ29yZy1saW1pdCcgfCAnY2FwYWNpdHknIHwgJ2ZvcmJpZGRlbicgfTtcblxuLyoqXG4gKiBTU0UgTWFuYWdlciBzdGF0aXN0aWNzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlclN0YXRzIHtcbiAgdG90YWxSZXF1ZXN0czogbnVtYmVyO1xuICB0b3RhbENsaWVudHM6IG51bWJlcjtcbiAgb2xkZXN0Q29ubmVjdGlvbk1zOiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIFNTRSBoZWxwZXIgY2xhc3Mgd2l0aCBtZW1vcnkgbGVhayBwcm90ZWN0aW9uXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIENsaWVudCBsaW1pdHMgcGVyIHJlcXVlc3QgSURcbiAqIC0gQXV0b21hdGljIHRpbWVvdXQgZm9yIGlkbGUgY29ubmVjdGlvbnNcbiAqIC0gUGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICogLSBDb25uZWN0aW9uIHN0YXRpc3RpY3NcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHsgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IDUgfSk7XG4gKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICpcbiAqIC8vIFNlbmQgZXZlbnRzXG4gKiBzc2VNYW5hZ2VyLnNlbmQoJ3JlcXVlc3QtMTIzJywgJ0lORk8nLCAnUHJvY2Vzc2luZy4uLicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTU0VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjbGllbnRzID0gbmV3IE1hcDxzdHJpbmcsIFNTRUNsaWVudFtdPigpO1xuICAvKiogUGVyLW9yZyBvcGVuLWNsaWVudCBjb3VudGVycy4gRGVjcmVtZW50ZWQgb24gcmVtb3ZlQ2xpZW50L2NsZWFudXAgc28gdGhlXG4gICAqICBtYXAgbWlycm9ycyBgY2xpZW50c1tdLm9yZ0lkYCBjb3VudHMgYXQgYWxsIHRpbWVzLiBPcmdzIHJlYWNoIHplcm8gYXJlXG4gICAqICBkZWxldGVkIHRvIGtlZXAgdGhlIG1hcCBib3VuZGVkLiAqL1xuICBwcml2YXRlIG9yZ0NsaWVudENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQgKGluLW1lbW9yeSBkZWZhdWx0OyBSZWRpcyBmb3IgbXVsdGktcG9kKS5cbiAgICogIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgLyBgbWF4VGlja2V0c1Blck9yZ2AsIGVuZm9yY2VkIGluIGNyZWF0ZVRpY2tldDtcbiAgICogIGV4cGlyeSBpcyB2YWxpZGF0ZWQgYXQgY29uc3VtZSB0aW1lIGFuZCBzd2VwdCBvbiB0aGUgY2xlYW51cCBpbnRlcnZhbC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0aWNrZXRTdG9yZTogU1NFVGlja2V0U3RvcmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VG90YWxUaWNrZXRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VGlja2V0c1Blck9yZzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtT3duZXJUdGxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIGNsZWFudXBJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyAodW5kZWZpbmVkIOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWxheT86IFNTRVJlbGF5O1xuICAvKiogVGhpcyBtYW5hZ2VyIGluc3RhbmNlJ3MgaWQg4oCUIHRhZ3MgcmVsYXllZCBmcmFtZXMgc28gd2UgaWdub3JlIG91ciBvd24gZWNoby4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBub2RlSWQgPSByYW5kb21CeXRlcyg4KS50b1N0cmluZygnaGV4Jyk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU1NFTWFuYWdlck9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QgPSBvcHRpb25zLm1heENsaWVudHNQZXJSZXF1ZXN0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfUkVRVUVTVCB8fCAnMTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbENsaWVudHMgPSBvcHRpb25zLm1heFRvdGFsQ2xpZW50cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX0NMSUVOVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhDbGllbnRzUGVyT3JnID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfT1JHIHx8ICc1MCcsIDEwKTtcbiAgICB0aGlzLm1heFRvdGFsVGlja2V0cyA9IG9wdGlvbnMubWF4VG90YWxUaWNrZXRzID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVE9UQUxfVElDS0VUUyB8fCAnMTAwMCcsIDEwKTtcbiAgICB0aGlzLm1heFRpY2tldHNQZXJPcmcgPSBvcHRpb25zLm1heFRpY2tldHNQZXJPcmcgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9USUNLRVRTX1BFUl9PUkcgfHwgJzEwJywgMTApO1xuICAgIHRoaXMudGlja2V0VHRsTXMgPSBvcHRpb25zLnRpY2tldFR0bE1zID8/IFNTRV9USUNLRVRfVFRMX01TO1xuICAgIHRoaXMuc3RyZWFtT3duZXJUdGxNcyA9IG9wdGlvbnMuc3RyZWFtT3duZXJUdGxNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfU1RSRUFNX09XTkVSX1RUTF9NUyB8fCAnMzYwMDAwMCcsIDEwKTsgLy8gMSBob3VyXG4gICAgdGhpcy50aWNrZXRTdG9yZSA9IG9wdGlvbnMudGlja2V0U3RvcmUgPz8gY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUoKTtcbiAgICB0aGlzLmNsaWVudFRpbWVvdXRNcyA9IG9wdGlvbnMuY2xpZW50VGltZW91dE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTElFTlRfVElNRU9VVF9NUyB8fCAnMTgwMDAwMCcsIDEwKTsgLy8gMzAgbWludXRlc1xuXG4gICAgY29uc3QgY2xlYW51cEludGVydmFsTXMgPSBvcHRpb25zLmNsZWFudXBJbnRlcnZhbE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTEVBTlVQX0lOVEVSVkFMX01TIHx8ICczMDAwMDAnLCAxMCk7IC8vIDUgbWludXRlc1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwSW50ZXJ2YWwoY2xlYW51cEludGVydmFsTXMpO1xuXG4gICAgLy8gV2lyZSB0aGUgY3Jvc3MtcG9kIHJlbGF5OiBzdWJzY3JpYmUgb25jZSBvbiBzdGFydHVwIHNvIGZyYW1lcyBQVUJMSVNIRUQgYnlcbiAgICAvLyBhbnkgb3RoZXIgcG9kIGFyZSByZS1lbWl0dGVkIHRvIFRISVMgcG9kJ3MgbG9jYWwgY2xpZW50cy4gRnJhbWVzIHdlXG4gICAgLy8gcHVibGlzaGVkIG91cnNlbHZlcyBhcmUgaWdub3JlZCAob3JpZ2luID09PSBub2RlSWQpIOKAlCB3ZSBhbHJlYWR5IHdyb3RlIHRoZW1cbiAgICAvLyBsb2NhbGx5LiBGYWlsLXNhZmU6IG5vIHJlbGF5IOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5IChzaW5nbGUtcmVwbGljYSBkZWZhdWx0KS5cbiAgICB0aGlzLnJlbGF5ID0gb3B0aW9ucy5yZWxheTtcbiAgICB0aGlzLnJlbGF5Py5zdWJzY3JpYmUoKG1zZykgPT4gdGhpcy5vblJlbGF5TWVzc2FnZShtc2cpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgYSBmcmFtZSByZWNlaXZlZCBmcm9tIGFub3RoZXIgcG9kIHZpYSB0aGUgcmVsYXkuIFdlIGFscmVhZHkgZGVsaXZlcmVkXG4gICAqIG91ciBPV04gZnJhbWVzIHRvIGxvY2FsIGNsaWVudHMgYmVmb3JlIHB1Ymxpc2hpbmcsIHNvIGlnbm9yZSBvdXIgZWNoby4gQVxuICAgKiBgc2VuZGAgcmUtZW1pdHMgdG8gdGhlIHN1YmplY3QncyBsb2NhbCBjbGllbnRzOyBhIGBicm9hZGNhc3RgIHRvIGFsbCBvZiB0aGVtLlxuICAgKiBQdXJlbHkgbG9jYWwg4oCUIG5ldmVyIHJlLXB1Ymxpc2hlcywgc28gdGhlcmUgaXMgbm8gZmFuLW91dCBsb29wLlxuICAgKi9cbiAgcHJpdmF0ZSBvblJlbGF5TWVzc2FnZShtc2c6IFNTRVJlbGF5TWVzc2FnZSk6IHZvaWQge1xuICAgIGlmICghbXNnIHx8IG1zZy5vcmlnaW4gPT09IHRoaXMubm9kZUlkKSByZXR1cm47XG4gICAgaWYgKG1zZy5raW5kID09PSAnYnJvYWRjYXN0Jykge1xuICAgICAgdGhpcy5icm9hZGNhc3RMb2NhbChtc2cucGF5bG9hZCk7XG4gICAgfSBlbHNlIGlmIChtc2cucmVxdWVzdElkKSB7XG4gICAgICB0aGlzLnNlbmRMb2NhbChtc2cucmVxdWVzdElkLCBtc2cucGF5bG9hZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRvdGFsIG9wZW4gY29ubmVjdGlvbnMgYWNyb3NzIGFsbCByZXF1ZXN0cy4gKi9cbiAgcHJpdmF0ZSB0b3RhbENsaWVudHMoKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgbiArPSBjbGllbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbjtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IG9wZW4tc3RyZWFtIGNvdW50IGZvciBhbiBvcmcgKDAgaWYgdW5zZWVuKS4gKi9cbiAgZ2V0T3JnQ2xpZW50Q291bnQob3JnSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhIHJlcXVlc3RJZCBmb3IgZXF1YWxpdHkgY2hlY2tzOiBkYXNoZXMgc3RyaXBwZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQsIHNvIHRoZSBkYXNoZWQgKGFwaS1zZXJ2ZXIgYHV1aWQoKWApIGFuZCB1bmRhc2hlZCAobmdpbnhcbiAgICogYCRyZXF1ZXN0X2lkYCkgcmVuZGVyaW5ncyBvZiB0aGUgc2FtZSBpZCBjb21wYXJlIGVxdWFsLiBDYWxsZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBoYXZlIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBhZ2FpbnN0IHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhbiBvcmdJZCBmb3Igb3duZXJzaGlwIGVxdWFsaXR5IGNoZWNrczogdHJpbW1lZCBhbmRcbiAgICogbG93ZXJjYXNlZC4gVGhlIHN0cmVhbSBQUk9EVUNFUiAoYmluZFN0cmVhbU93bmVyKSBhbmQgdGhlIHRpY2tldC1taW50aW5nXG4gICAqIENPTlNVTUVSIChjcmVhdGVUaWNrZXQpIHJ1biBpbiBkaWZmZXJlbnQgc2VydmljZXMsIHNvIGEgY2FzaW5nIC8gd2hpdGVzcGFjZVxuICAgKiBkcmlmdCBiZXR3ZWVuIGhvdyBlYWNoIHJlbmRlcnMgdGhlIHNhbWUgb3JnIHdvdWxkIG90aGVyd2lzZSBtYWtlIHRoZSBvd25lclxuICAgKiBjb21wYXJpc29uIGluIHtAbGluayBjcmVhdGVUaWNrZXR9IGZhbHNlLWBmb3JiaWRkZW5gIHRoZSByZWFsIG93bmVyLlxuICAgKiBOb3JtYWxpemluZyBib3RoIHNpZGVzIOKAlCBtaXJyb3Jpbmcge0BsaW5rIG5vcm1hbGl6ZVJlcXVlc3RJZH0g4oCUIGNsb3NlcyB0aGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplT3JnSWQob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9yZ0lkLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCB0aGUgb3JnIHRoYXQgT1dOUyBhIHN0cmVhbSBzdWJqZWN0LiBUaGUgc3RyZWFtIFBST0RVQ0VSIGNhbGxzIHRoaXNcbiAgICogd2hlbiBpdCBjcmVhdGVzIGEgYnVpbGQtbG9nIHN0cmVhbSBzbyB0aGF0IHRpY2tldCBtaW50aW5nIGNhbiBhc3NlcnQgdGhlXG4gICAqIGNhbGxlcidzIG9yZyBvd25zIHRoZSBzdWJqZWN0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0pLiBCYWNrZWQgYnkgdGhlXG4gICAqIGluamVjdGVkIHRpY2tldCBzdG9yZSwgc28gd2hlbiBhIFJlZGlzIHN0b3JlIGlzIHdpcmVkIHRoZSBwbGF0Zm9ybSBwcm9kdWNlclxuICAgKiAoYSBkaWZmZXJlbnQgc2VydmljZSBzaGFyaW5nIHRoZSBzYW1lIFJlZGlzKSBjYW4gYmluZCBvd25lcnNoaXAgdGhhdCB0aGlzXG4gICAqIHNlcnZpY2UgcmVhZHMg4oCUIGNsb3NpbmcgdGhlIGNyb3NzLXRlbmFudCBhdHRhY2ggZ2FwIHdoZXJlIGFueSBvcmcgY291bGQgbWludFxuICAgKiBhIHRpY2tldCBmb3IgYSBndWVzc2VkIHJlcXVlc3RJZC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCAoZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyKS5cbiAgICogQHBhcmFtIG9yZ0lkIC0gVGhlIG93bmluZyBvcmcgKG5vcm1hbGl6ZWQgaW50ZXJuYWxseSB2aWEgbm9ybWFsaXplT3JnSWQpLlxuICAgKi9cbiAgYXN5bmMgYmluZFN0cmVhbU93bmVyKHJlcXVlc3RJZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5iaW5kU3RyZWFtT3duZXIoXG4gICAgICBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpLFxuICAgICAgU1NFTWFuYWdlci5ub3JtYWxpemVPcmdJZChvcmdJZCksXG4gICAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW50IGEgc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCBhIHNwZWNpZmljXG4gICAqIHN0cmVhbSBzdWJqZWN0IChgcmVxdWVzdElkYCkuIENsaWVudHMgUE9TVCB0byBvYnRhaW4gb25lIChKV1QtYXV0aGVudGljYXRlZClcbiAgICogZm9yIHRoZSBleGFjdCBzdHJlYW0gdGhleSBpbnRlbmQgdG8gb3BlbiwgdGhlbiBvcGVuIHRoZSBFdmVudFNvdXJjZSB3aXRoXG4gICAqIGA/dGlja2V0PTx0PmAgc28gdGhlIEpXVCBuZXZlciBsYW5kcyBpbiBhIHF1ZXJ5IHN0cmluZyAvIGFjY2VzcyBsb2cuIFRoZVxuICAgKiB0aWNrZXQgY2FuIHRoZW4gb25seSBiZSBjb25zdW1lZCB0byBvcGVuIHRoYXQgb25lIHN1YmplY3QncyBzdHJlYW0g4oCUIHNlZVxuICAgKiB7QGxpbmsgY29uc3VtZVRpY2tldH0g4oCUIHdoaWNoIGlzIHdoYXQgZW5mb3JjZXMgcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogT1JHLU9XTkVSU0hJUDogaWYgYSBzdHJlYW0gb3duZXIgaGFzIGJlZW4gYm91bmQgZm9yIHRoaXMgc3ViamVjdCAodmlhXG4gICAqIHtAbGluayBiaW5kU3RyZWFtT3duZXJ9KSBhbmQgaXQgaXMgYSBESUZGRVJFTlQgb3JnLCBtaW50aW5nIGlzIHJlZnVzZWRcbiAgICogKGByZWFzb246ICdmb3JiaWRkZW4nYCkg4oCUIGFuIG9yZyBjYW5ub3QgbWludCBhIHRpY2tldCBmb3IgYW5vdGhlciBvcmcnc1xuICAgKiBzdHJlYW0gZXZlbiBpZiBpdCBndWVzc2VzIHRoZSByZXF1ZXN0SWQuIFdoZW4gbm8gb3duZXIgaXMgYm91bmQgKHByb2R1Y2VyXG4gICAqIHdpcmluZyBub3QgeWV0IHByZXNlbnQpLCBtaW50aW5nIGZhbGxzIGJhY2sgdG8gYmluZGluZyB0aGUgdGlja2V0IHRvIHRoZVxuICAgKiBjYWxsZXIncyBvd24gb3JnLCBwcmVzZXJ2aW5nIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAqXG4gICAqIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgKHByb2Nlc3Mtd2lkZSkgYW5kIGBtYXhUaWNrZXRzUGVyT3JnYFxuICAgKiAocGVyLXRlbmFudCkuIE1pcnJvcnMgdGhlIG1lc3NhZ2Utc2VydmljZSBub3RpZmljYXRpb25zIHRpY2tldCBzdG9yZS5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIC0gT3duaW5nIG9yZyAobm9ybWFsaXplZCBpbnRlcm5hbGx5IHZpYSBub3JtYWxpemVPcmdJZCkuXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBUaGUgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IHRoaXMgdGlja2V0IGF1dGhvcml6ZXMuXG4gICAqICAgVGhlIGNhbGxlciBtdXN0IGhhdmUgZm9ybWF0LXZhbGlkYXRlZCBpdCAoc2VlIHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0pLlxuICAgKiBAcmV0dXJucyBgeyBvazogdHJ1ZSwgdGlja2V0IH1gIG9uIHN1Y2Nlc3MsIG9yIGB7IG9rOiBmYWxzZSwgcmVhc29uIH1gXG4gICAqICAgd2hlcmUgcmVhc29uIGlzIGAnb3JnLWxpbWl0J2AsIGAnY2FwYWNpdHknYCwgb3IgYCdmb3JiaWRkZW4nYC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVRpY2tldChvcmdJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q3JlYXRlVGlja2V0UmVzdWx0PiB7XG4gICAgLy8gT3duZXJzaGlwIGdhdGUgZmlyc3Qg4oCUIGEgY3Jvc3MtdGVuYW50IG1pbnQgYXR0ZW1wdCBzaG91bGQgbmV2ZXIgZXZlblxuICAgIC8vIGNvbnN1bWUgY2FwIGJ1ZGdldC4gT25seSBlbmZvcmNlZCB3aGVuIGFuIG93bmVyIGlzIGFjdHVhbGx5IGJvdW5kLiBCb3RoXG4gICAgLy8gc2lkZXMgYXJlIG9yZy1ub3JtYWxpemVkIHNvIGEgcHJvZHVjZXIvY29uc3VtZXIgY2FzaW5nIGRyaWZ0IGNhbid0XG4gICAgLy8gZmFsc2UtYGZvcmJpZGRlbmAgdGhlIHJlYWwgb3duZXIgKG1pcnJvcnMgcmVxdWVzdElkIG5vcm1hbGl6YXRpb24pLlxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRPcmcgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZU9yZ0lkKG9yZ0lkKTtcbiAgICBjb25zdCBvd25lciA9IGF3YWl0IHRoaXMudGlja2V0U3RvcmUuZ2V0U3RyZWFtT3duZXIobm9ybWFsaXplZCk7XG4gICAgaWYgKG93bmVyICYmIG93bmVyICE9PSBub3JtYWxpemVkT3JnKSB7XG4gICAgICBsb2dnZXIud2FybihgU1NFIHRpY2tldCByZWZ1c2VkOiBvcmcgJHtub3JtYWxpemVkT3JnfSBkb2VzIG5vdCBvd24gc3RyZWFtIHN1YmplY3RgKTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnZm9yYmlkZGVuJyB9O1xuICAgIH1cblxuICAgIC8vIFRvdGFsIGNhcCBuZXh0IOKAlCBwcm90ZWN0cyBwcm9jZXNzIG1lbW9yeSBldmVuIHdoZW4gYSBzaW5nbGUgb3JnIGlzXG4gICAgLy8gdGhlIG9mZmVuZGVyLiBUaGVuIHRoZSBwZXItb3JnIGNhcCBmb3IgZmFpci1zaGFyZS5cbiAgICBpZiAoKGF3YWl0IHRoaXMudGlja2V0U3RvcmUudG90YWwoKSkgPj0gdGhpcy5tYXhUb3RhbFRpY2tldHMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBTU0UgdGlja2V0IGNhcCByZWFjaGVkIChtYXg6ICR7dGhpcy5tYXhUb3RhbFRpY2tldHN9KTsgcmVqZWN0aW5nIHRpY2tldCByZXF1ZXN0YCk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ2NhcGFjaXR5JyB9O1xuICAgIH1cbiAgICBpZiAoKGF3YWl0IHRoaXMudGlja2V0U3RvcmUuY291bnRGb3JPcmcobm9ybWFsaXplZE9yZykpID49IHRoaXMubWF4VGlja2V0c1Blck9yZykge1xuICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIHRpY2tldCBjYXAgcmVhY2hlZCBmb3IgJHtub3JtYWxpemVkT3JnfSAobWF4OiAke3RoaXMubWF4VGlja2V0c1Blck9yZ30pYCk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZy1saW1pdCcgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrZXQgPSByYW5kb21CeXRlcygyNCkudG9TdHJpbmcoJ2Jhc2U2NHVybCcpO1xuICAgIGF3YWl0IHRoaXMudGlja2V0U3RvcmUucHV0KHRpY2tldCwgeyBvcmdJZDogbm9ybWFsaXplZE9yZywgcmVxdWVzdElkOiBub3JtYWxpemVkIH0sIHRoaXMudGlja2V0VHRsTXMpO1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgQ09OU1VNRSBhIHRpY2tldCBmb3IgYSBzcGVjaWZpYyBzdHJlYW0gc3ViamVjdC4gU2luZ2xlLXVzZTpcbiAgICogdGhlIHRpY2tldCBpcyBkZWxldGVkIHdoZXRoZXIgb3Igbm90IGl0IHR1cm5zIG91dCB0byBiZSB2YWxpZCwgc28gYSByZXBsYXlcbiAgICogb2YgdGhlIHNhbWUgdmFsdWUgYWx3YXlzIGZhaWxzLiBSZXR1cm5zIHRoZSBib3VuZCBvcmcgb24gc3VjY2Vzcywgb3IgbnVsbFxuICAgKiB3aGVuIHRoZSB0aWNrZXQgaXMgdW5rbm93biAvIGFscmVhZHktdXNlZCAvIGV4cGlyZWQgLyBPUiB3YXMgbWludGVkIGZvciBhXG4gICAqIERJRkZFUkVOVCBgcmVxdWVzdElkYCB0aGFuIHRoZSBvbmUgYmVpbmcgb3BlbmVkLlxuICAgKlxuICAgKiBUaGUgc3ViamVjdCBjaGVjayBpcyB0aGUgYXV0aG9yaXphdGlvbiBmaXg6IHdpdGhvdXQgaXQsIGEgdGlja2V0IG1pbnRlZCBmb3JcbiAgICogb25lIHN0cmVhbSBjb3VsZCBiZSBwcmVzZW50ZWQgdG8gb3BlbiBBTlkgc3RyZWFtIHRoZSBob2xkZXIncyBvcmcgY291bGRcbiAgICogbmFtZSwgbGV0dGluZyBhbiBhdXRoZW50aWNhdGVkIG9yZyBhdHRhY2ggdG8gYW5vdGhlciBvcmcncyBsb2cgc3RyZWFtIGJ5XG4gICAqIGd1ZXNzaW5nIGl0cyByZXF1ZXN0SWQuIFRoZSBnZW5lcmljIDQwMSB0aGUgY2FsbGVyIHJldHVybnMgZG9lcyBub3RcbiAgICogZGlzdGluZ3Vpc2ggXCJ1bmtub3duIHRpY2tldFwiIGZyb20gXCJ3cm9uZyBzdWJqZWN0XCIsIHNvIGl0IGxlYWtzIG5vdGhpbmdcbiAgICogYWJvdXQgd2hpY2ggcmVxdWVzdElkcyBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHRpY2tldElkIC0gVGhlIG9wYXF1ZSB0aWNrZXQgdmFsdWUgZnJvbSBgP3RpY2tldD1gLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIHN0cmVhbSBzdWJqZWN0IGZyb20gdGhlIFVSTCBwYXRoIChgOnJlcXVlc3RJZGApLFxuICAgKiAgIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyLlxuICAgKi9cbiAgYXN5bmMgY29uc3VtZVRpY2tldCh0aWNrZXRJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgY29uc3QgdGlja2V0ID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb25zdW1lKHRpY2tldElkKTsgLy8gc2luZ2xlLXVzZVxuICAgIGlmICghdGlja2V0KSByZXR1cm4gbnVsbDtcbiAgICAvLyBTdWJqZWN0IGJpbmRpbmcg4oCUIHJlamVjdCBhIHRpY2tldCBwcmVzZW50ZWQgZm9yIGEgc3ViamVjdCBpdCB3YXMgbm90XG4gICAgLy8gbWludGVkIGZvci4gQm90aCBzaWRlcyBhcmUgbm9ybWFsaXplZCBzbyBkYXNoZWQvdW5kYXNoZWQgZm9ybXMgbWF0Y2guXG4gICAgaWYgKHRpY2tldC5yZXF1ZXN0SWQgIT09IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7IG9yZ0lkOiB0aWNrZXQub3JnSWQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2xpZW50IHRvIHRoZSBTU0UgbWFuYWdlclxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVW5pcXVlIHJlcXVlc3QgSURcbiAgICogQHBhcmFtIHJlcyAtIEV4cHJlc3MgUmVzcG9uc2Ugb2JqZWN0XG4gICAqIEBwYXJhbSBvcmdJZCAtIEF1dGhlbnRpY2F0ZWQgb3JnIGlkIChvcHRpb25hbCkuIFdoZW4gc2V0LCBlbmZvcmNlcyB0aGVcbiAgICogICBwZXItb3JnIGNhcCBhbmQgdGhlIGNvdW50ZXIgaXMgZGVjcmVtZW50ZWQgb24gZGlzY29ubmVjdC9jbGVhbnVwLlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIGNsaWVudCB3YXMgYWRkZWQsIGZhbHNlIGlmIHJlamVjdGVkIChsaW1pdCByZWFjaGVkKVxuICAgKi9cbiAgYWRkQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCByZXM6IFJlc3BvbnNlLCBvcmdJZD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdO1xuXG4gICAgLy8gQ2hlY2sgY2xpZW50IGxpbWl0XG4gICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+PSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KSB7XG4gICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdH0pYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUHJvY2Vzcy13aWRlIGNhcDogcHJvdGVjdHMgZmQgdGFibGUgKyBtZW1vcnkgZnJvbSBydW5hd2F5IGRhc2hib2FyZHMuXG4gICAgaWYgKHRoaXMudG90YWxDbGllbnRzKCkgPj0gdGhpcy5tYXhUb3RhbENsaWVudHMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBUb3RhbCBTU0UgY2xpZW50IGNhcCByZWFjaGVkIChtYXg6ICR7dGhpcy5tYXhUb3RhbENsaWVudHN9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUGVyLW9yZyBjYXA6IHByZXZlbnRzIG9uZSBub2lzeSBvcmcgZnJvbSBtb25vcG9saXppbmcgcHJvY2Vzcy13aWRlXG4gICAgLy8gc2xvdHMuIEVuZm9yY2VkIG9ubHkgd2hlbiBvcmdJZCBpcyBrbm93biDigJQgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91c1xuICAgIC8vIHN0cmVhbXMgdGhhdCBuZXZlciBpZGVudGlmeSB3aXRoIGFuIG9yZ0lkIHN0YXkgc3ViamVjdCB0byB0aGUgZ2xvYmFsXG4gICAgLy8gY2VpbGluZ3MgYWJvdmUuIFJlc2VydmUgYXRvbWljYWxseSBiZWZvcmUgaW5zZXJ0IHNvIHR3byBjb25jdXJyZW50XG4gICAgLy8gcmVxdWVzdHMgYXQgdGhlIGxpbWl0IGNhbid0IGJvdGggc3VjY2VlZC5cbiAgICBpZiAob3JnSWQpIHtcbiAgICAgIGNvbnN0IG9yZ0N1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgICBpZiAob3JnQ3VycmVudCA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3JnQ2xpZW50Q291bnRzLnNldChvcmdJZCwgb3JnQ3VycmVudCArIDEpO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSB0aW1lb3V0IGZvciB0aGlzIGNsaWVudFxuICAgIGNvbnN0IGNsaWVudElkID0gdXVpZCgpO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IHRpbWVkIG91dCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gdGltZW91dCcsIHsgcmVxdWVzdElkLCBjbGllbnRJZCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLmNsaWVudFRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBjbGllbnQ6IFNTRUNsaWVudCA9IHtcbiAgICAgIGlkOiBjbGllbnRJZCxcbiAgICAgIHJlcyxcbiAgICAgIGNvbm5lY3RlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgdGltZW91dCxcbiAgICAgIGJhY2twcmVzc3VyZUNvdW50OiAwLFxuICAgICAgb3JnSWQsXG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBkaXNjb25uZWN0aW9uXG4gICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgcmVzLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihgU1NFIGNsaWVudCBlcnJvciBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH06YCwgZXJyKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgZXhpc3RpbmcucHVzaChjbGllbnQpO1xuICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCBleGlzdGluZyk7XG5cbiAgICBsb2dnZXIuZGVidWcoYENsaWVudCAke2NsaWVudElkfSBjb25uZWN0ZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICh0b3RhbDogJHtleGlzdGluZy5sZW5ndGh9KWApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIERyb3Agb25lIGZyb20gdGhlIHBlci1vcmcgY291bnRlci4gSWRlbXBvdGVudDogYSBjb3VudGVyIGF0IDAgc3RheXMgYXQgMFxuICAgKiAgYW5kIHRoZSBvcmcga2V5IGlzIHJlbW92ZWQgZnJvbSB0aGUgbWFwLiAqL1xuICBwcml2YXRlIGRlY3JlbWVudE9yZ0NvdW50KG9yZ0lkPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFvcmdJZCkgcmV0dXJuO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgaWYgKGN1cnJlbnQgPD0gMSkgdGhpcy5vcmdDbGllbnRDb3VudHMuZGVsZXRlKG9yZ0lkKTtcbiAgICBlbHNlIHRoaXMub3JnQ2xpZW50Q291bnRzLnNldChvcmdJZCwgY3VycmVudCAtIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBjbGllbnQgZnJvbSB0aGUgbWFuYWdlclxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVDbGllbnQocmVxdWVzdElkOiBzdHJpbmcsIGNsaWVudElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpO1xuICAgIGlmICghY2xpZW50cykgcmV0dXJuO1xuXG4gICAgY29uc3QgcmVtYWluaW5nID0gY2xpZW50cy5maWx0ZXIoYyA9PiB7XG4gICAgICBpZiAoYy5pZCA9PT0gY2xpZW50SWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGMudGltZW91dCk7XG4gICAgICAgIC8vIE1pcnJvciB0aGUgcGVyLW9yZyBjb3VudGVyIOKAlCBtdXN0IGRlY3JlbWVudCBoZXJlLCBub3QganVzdCBpbiB0aGVcbiAgICAgICAgLy8gZXhwbGljaXQgY2xvc2UgcGF0aHMsIHNpbmNlICdjbG9zZScvJ2Vycm9yJyBldmVudCBoYW5kbGVycyBhcmUgdGhlXG4gICAgICAgIC8vIHByaW1hcnkgZGlzY29ubmVjdCBzaWduYWwgaW4gcHJhY3RpY2UuXG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoYy5vcmdJZCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuXG4gICAgaWYgKHJlbWFpbmluZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQWxsIGNsaWVudHMgZGlzY29ubmVjdGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgcmVtYWluaW5nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGFsbCBTU0UgY2xpZW50cyBmb3IgYSByZXF1ZXN0SWRcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFJlcXVlc3QgSURcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgTnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIHNlbmQocmVxdWVzdElkOiBzdHJpbmcsIHR5cGU6IFNTRUV2ZW50VHlwZSwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IG51bWJlciB7XG4gICAgY29uc3QgcGF5bG9hZDogU1NFUGF5bG9hZCA9IHtcbiAgICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0eXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRhdGEsXG4gICAgfTtcblxuICAgIC8vIERlbGl2ZXIgdG8gTE9DQUwgY2xpZW50cyBmaXJzdCwgdGhlbiByZWxheSB0aGUgU0FNRSBwYXlsb2FkIHRvIG90aGVyIHBvZHNcbiAgICAvLyBzbyBhbiBFdmVudFNvdXJjZSBhdHRhY2hlZCBvbiBhIGRpZmZlcmVudCByZXBsaWNhIGFsc28gcmVjZWl2ZXMgaXQuIFRoZVxuICAgIC8vIHJlbGF5IGlzIGZpcmUtYW5kLWZvcmdldCBhbmQgZmFpbC1zYWZlOiBubyByZWxheSAvIFJlZGlzIGRvd24g4oeSIGxvY2FsLW9ubHkuXG4gICAgY29uc3Qgc2VudENvdW50ID0gdGhpcy5zZW5kTG9jYWwocmVxdWVzdElkLCBwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdzZW5kJywgcmVxdWVzdElkLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byB0aGlzIHBvZCdzIExPQ0FMIGNsaWVudHMgZm9yIGByZXF1ZXN0SWRgLiBTaGFyZWRcbiAgICogYnkge0BsaW5rIHNlbmR9IChsb2NhbCBoYWxmKSBhbmQgdGhlIHJlbGF5IHJlLWVtaXQgcGF0aCAoe0BsaW5rIG9uUmVsYXlNZXNzYWdlfSksXG4gICAqIHNvIGEgcmVsYXllZCBmcmFtZSByZXVzZXMgdGhlIHByb2R1Y2VyJ3Mgb3JpZ2luYWwgYHRzYCByYXRoZXIgdGhhbiBhIG5ldyBvbmUuXG4gICAqIE5ldmVyIHJlbGF5cyDigJQgY2FsbGVycyBkZWNpZGUgd2hldGhlciB0byBwdWJsaXNoLlxuICAgKi9cbiAgcHJpdmF0ZSBzZW5kTG9jYWwocmVxdWVzdElkOiBzdHJpbmcsIHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIGNvbnN0IGNsaWVudHMgPSBbLi4uKHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXSldO1xuICAgIGxldCBzZW50Q291bnQgPSAwO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShwYXlsb2FkKX1cXG5cXG5gO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQmFja3ByZXNzdXJlOiBza2lwIGNsaWVudHMgd2hvc2Ugd3JpdGUgYnVmZmVyIGlzIGZ1bGxcbiAgICAgICAgaWYgKGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYW5Xcml0ZSA9IGNsaWVudC5yZXMud3JpdGUoc2VyaWFsaXplZCk7XG4gICAgICAgIGlmICghY2FuV3JpdGUpIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQrKztcbiAgICAgICAgICAvLyBEaXNjb25uZWN0IGNsaWVudHMgdGhhdCBjb25zaXN0ZW50bHkgY2FuJ3Qga2VlcCB1cCAoMTAgY29uc2VjdXRpdmUgYmFja3ByZXNzdXJlIGV2ZW50cylcbiAgICAgICAgICBpZiAoY2xpZW50LmJhY2twcmVzc3VyZUNvdW50ID49IENvcmVDb25zdGFudHMuU1NFX0JBQ0tQUkVTU1VSRV9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKGBEaXNjb25uZWN0aW5nIHNsb3cgY2xpZW50ICR7Y2xpZW50LmlkfSBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKCR7Y2xpZW50LmJhY2twcmVzc3VyZUNvdW50fSBiYWNrcHJlc3N1cmUgZXZlbnRzKWApO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQgPSAwOyAvLyBSZXNldCBvbiBzdWNjZXNzZnVsIHdyaXRlXG4gICAgICAgIH1cbiAgICAgICAgc2VudENvdW50Kys7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzZW5kIHRvIGNsaWVudCAke2NsaWVudC5pZH06YCwgZXJyb3IpO1xuICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbnRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCcm9hZGNhc3QgYSBtZXNzYWdlIHRvIGFsbCBjb25uZWN0ZWQgY2xpZW50cyBhY3Jvc3MgYWxsIHJlcXVlc3RzXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gRXZlbnQgdHlwZVxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIE1lc3NhZ2Ugc3RyaW5nXG4gICAqIEBwYXJhbSBkYXRhIC0gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gICAqIEByZXR1cm5zIFRvdGFsIG51bWJlciBvZiBjbGllbnRzIHRoZSBtZXNzYWdlIHdhcyBzZW50IHRvXG4gICAqL1xuICBicm9hZGNhc3QodHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuICAgIC8vIERlbGl2ZXIgdG8gbG9jYWwgY2xpZW50cywgdGhlbiByZWxheSBhIHNpbmdsZSBicm9hZGNhc3QgZnJhbWUgc28gRVZFUlkgcG9kXG4gICAgLy8gcmUtZW1pdHMgdG8gQUxMIG9mIGl0cyBvd24gY2xpZW50cyDigJQgYSBwZXItcmVxdWVzdElkIHJlbGF5IHdvdWxkIG1pc3NcbiAgICAvLyBzdWJqZWN0cyB0aGF0IG9ubHkgZXhpc3Qgb24gb3RoZXIgcmVwbGljYXMuXG4gICAgY29uc3QgdG90YWxTZW50ID0gdGhpcy5icm9hZGNhc3RMb2NhbChwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdicm9hZGNhc3QnLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiB0b3RhbFNlbnQ7XG4gIH1cblxuICAvKiogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byBhbGwgTE9DQUwgY2xpZW50cyBhY3Jvc3MgZXZlcnkgcmVxdWVzdC4gKi9cbiAgcHJpdmF0ZSBicm9hZGNhc3RMb2NhbChwYXlsb2FkOiBTU0VQYXlsb2FkKTogbnVtYmVyIHtcbiAgICBsZXQgdG90YWxTZW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RJZCBvZiBbLi4udGhpcy5jbGllbnRzLmtleXMoKV0pIHtcbiAgICAgIHRvdGFsU2VudCArPSB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICByZXR1cm4gdG90YWxTZW50O1xuICB9XG5cbiAgLyoqIEZpcmUtYW5kLWZvcmdldCByZWxheSBwdWJsaXNoLiBOby1vcCAobG9jYWwtb25seSkgd2hlbiBubyByZWxheSBpcyB3aXJlZC4gKi9cbiAgcHJpdmF0ZSBwdWJsaXNoUmVsYXkobXNnOiBTU0VSZWxheU1lc3NhZ2UpOiB2b2lkIHtcbiAgICB0aGlzLnJlbGF5Py5wdWJsaXNoKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgYWxsIGNsaWVudHMgZm9yIGEgc3BlY2lmaWMgcmVxdWVzdFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRCB0byBjbG9zZVxuICAgKiBAcGFyYW0gZmluYWxNZXNzYWdlIC0gT3B0aW9uYWwgZmluYWwgbWVzc2FnZSB0byBzZW5kIGJlZm9yZSBjbG9zaW5nXG4gICAqL1xuICBjbG9zZVJlcXVlc3QocmVxdWVzdElkOiBzdHJpbmcsIGZpbmFsTWVzc2FnZT86IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk7XG4gICAgaWYgKCFjbGllbnRzKSByZXR1cm47XG5cbiAgICBpZiAoZmluYWxNZXNzYWdlKSB7XG4gICAgICB0aGlzLnNlbmQocmVxdWVzdElkLCAnQ09NUExFVEVEJywgZmluYWxNZXNzYWdlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICBjbGVhclRpbWVvdXQoY2xpZW50LnRpbWVvdXQpO1xuICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xpZW50LnJlcy5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Jlc3BvbnNlIGFscmVhZHkgY2xvc2VkIG9uIHJlcXVlc3QgY2xvc2UnLCB7IHJlcXVlc3RJZCwgY2xpZW50SWQ6IGNsaWVudC5pZCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbG9zZWQgYWxsIGNsaWVudHMgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3MgYWJvdXQgY3VycmVudCBjb25uZWN0aW9uc1xuICAgKi9cbiAgZ2V0U3RhdHMoKTogU1NFTWFuYWdlclN0YXRzIHtcbiAgICBsZXQgdG90YWxDbGllbnRzID0gMDtcbiAgICBsZXQgb2xkZXN0Q29ubmVjdGlvbjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIHtcbiAgICAgIHRvdGFsQ2xpZW50cyArPSBjbGllbnRzLmxlbmd0aDtcbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgICAgY29uc3QgYWdlID0gbm93IC0gY2xpZW50LmNvbm5lY3RlZEF0O1xuICAgICAgICBpZiAob2xkZXN0Q29ubmVjdGlvbiA9PT0gbnVsbCB8fCBhZ2UgPiBvbGRlc3RDb25uZWN0aW9uKSB7XG4gICAgICAgICAgb2xkZXN0Q29ubmVjdGlvbiA9IGFnZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbFJlcXVlc3RzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHRvdGFsQ2xpZW50cyxcbiAgICAgIG9sZGVzdENvbm5lY3Rpb25Nczogb2xkZXN0Q29ubmVjdGlvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgcmVxdWVzdCBoYXMgYW55IGNvbm5lY3RlZCBjbGllbnRzXG4gICAqL1xuICBoYXNDbGllbnRzKHJlcXVlc3RJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICByZXR1cm4gY2xpZW50cyAhPT0gdW5kZWZpbmVkICYmIGNsaWVudHMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBjbGllbnRzIGZvciBhIHNwZWNpZmljIHJlcXVlc3RcbiAgICovXG4gIGdldENsaWVudENvdW50KHJlcXVlc3RJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpPy5sZW5ndGggPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaWRkbGV3YXJlIHRvIGluaXRpYWxpemUgYSB0aWNrZXQtYXV0aGVudGljYXRlZCBTU0UgY29ubmVjdGlvbi5cbiAgICpcbiAgICogVGhlIHN0cmVhbSBpcyBOT1Qgb3BlbiB0byB0aGUgd29ybGQ6IHRoZSBjYWxsZXIgbXVzdCBmaXJzdCBleGNoYW5nZSBpdHNcbiAgICogSldUIGZvciBhIHNob3J0LWxpdmVkIHNpbmdsZS11c2UgdGlja2V0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0sIHdpcmVkIHRvXG4gICAqIGBQT1NUIC9sb2dzL3RpY2tldGApIGFuZCBwYXNzIGl0IGFzIGA/dGlja2V0PTx0PmAuIFRoZSBtaWRkbGV3YXJlIHZhbGlkYXRlc1xuICAgKiArIGNvbnN1bWVzIHRoZSB0aWNrZXQsIGJpbmRzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSB0aWNrZXQncyBvcmcsIGFuZFxuICAgKiBlbmZvcmNlcyB0aGUgcGVyLW9yZyBjb25uZWN0aW9uIGNhcC4gQSBtaXNzaW5nIC8gaW52YWxpZCAvIGV4cGlyZWQgL1xuICAgKiBhbHJlYWR5LXVzZWQgdGlja2V0IGlzIHJlamVjdGVkIHdpdGggNDAxIGJlZm9yZSBhbnkgU1NFIGhlYWRlcnMgZmx1c2guXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXBwLmdldCgnL2xvZ3MvOnJlcXVlc3RJZCcsIHNzZU1hbmFnZXIubWlkZGxld2FyZSgpKTtcbiAgICogYGBgXG4gICAqL1xuICBtaWRkbGV3YXJlKCkge1xuICAgIHJldHVybiBhc3luYyAocmVxOiB7IHBhcmFtczogeyByZXF1ZXN0SWQ6IHN0cmluZyB9OyBxdWVyeT86IHsgdGlja2V0PzogdW5rbm93biB9IH0sIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IHsgcmVxdWVzdElkIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICBpZiAoIVNTRV9SRVFVRVNUX0lEX1JFLnRlc3QocmVxdWVzdElkKSkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMCkuZW5kKCdJbnZhbGlkIHJlcXVlc3RJZCBmb3JtYXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUaWNrZXQgYXV0aCDigJQgcmVxdWlyZWQuIFJlc29sdmUgYD90aWNrZXQ9PHQ+YCwgdGhlbiB2YWxpZGF0ZSArIGNvbnN1bWVcbiAgICAgIC8vIGl0IChzaW5nbGUtdXNlKSBGT1IgVEhJUyBTVUJKRUNULiBBbiBhbm9ueW1vdXMsIG1hbGZvcm1lZCwgdW5rbm93bixcbiAgICAgIC8vIGV4cGlyZWQsIGFscmVhZHktY29uc3VtZWQsIG9yIHdyb25nLXN1YmplY3QgdGlja2V0IGlzIGEgNDAxLiBUaGUgb3JnIGlzXG4gICAgICAvLyB0YWtlbiBmcm9tIHRoZSB0aWNrZXQsIHNvIHRoZSBzdHJlYW0gaXMgYWx3YXlzIGJvdW5kIHRvIGEgdmVyaWZpZWRcbiAgICAgIC8vIHRlbmFudCBBTkQgdG8gdGhlIGV4YWN0IHN1YmplY3QgdGhlIHRpY2tldCB3YXMgbWludGVkIGZvciAobm8gYW5vbnltb3VzXG4gICAgICAvLyBzdHJlYW1zLCBubyBjcm9zcy1zdWJqZWN0IGF0dGFjaCkuXG4gICAgICBjb25zdCB0aWNrZXRJZCA9IHJlcS5xdWVyeT8udGlja2V0O1xuICAgICAgaWYgKHR5cGVvZiB0aWNrZXRJZCAhPT0gJ3N0cmluZycgfHwgdGlja2V0SWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ01pc3NpbmcgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbnN1bWVkID0gYXdhaXQgdGhpcy5jb25zdW1lVGlja2V0KHRpY2tldElkLCByZXF1ZXN0SWQpO1xuICAgICAgaWYgKCFjb25zdW1lZCkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMSkuZW5kKCdJbnZhbGlkIG9yIGV4cGlyZWQgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9yZ0lkID0gY29uc3VtZWQub3JnSWQ7XG5cbiAgICAgIC8vIFByZS1mbGlnaHQgcGVyLXJlcXVlc3QgY2FwIHNvIHdlIGNhbiByZXR1cm4gNDI5IGJlZm9yZSBmbHVzaGluZ1xuICAgICAgLy8gU1NFIGhlYWRlcnMgKGFmdGVyIGhlYWRlcnMgYXJlIGZsdXNoZWQgdGhlIGNsaWVudCBjYW4ndCByZWFkIGEgNDI5KS5cbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdO1xuICAgICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+PSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBDbGllbnQgbGltaXQgcmVhY2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0fSlgKTtcbiAgICAgICAgcmVzLnN0YXR1cyg0MjkpLmVuZCgnVG9vIG1hbnkgY29ubmVjdGlvbnMgZm9yIHRoaXMgcmVxdWVzdCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFNhbWUgZm9yIHRoZSBwZXItb3JnIGNhcCDigJQgYmV0dGVyIHRvIHNlbmQgNDI5IHRoYW4gb3BlbiB0aGUgc3RyZWFtIGFuZFxuICAgICAgLy8gaW1tZWRpYXRlbHkgY2xvc2UgaXQuIFRoZSB0aWNrZXQgZ3VhcmFudGVlcyBhIHZlcmlmaWVkIG9yZyBpZCwgc28gdGhlXG4gICAgICAvLyBwZXItb3JnIGNlaWxpbmcgaXMgYWx3YXlzIGVuZm9yY2VkIGZvciB0aGUgL2xvZ3Mgc3RyZWFtLlxuICAgICAgaWYgKCh0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDApID49IHRoaXMubWF4Q2xpZW50c1Blck9yZykge1xuICAgICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgY2xpZW50IGNhcCByZWFjaGVkIGZvciAke29yZ0lkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1Blck9yZ30pYCk7XG4gICAgICAgIHJlcy5zdGF0dXMoNDI5KS5lbmQoJ1RvbyBtYW55IFNTRSBjb25uZWN0aW9ucyBmb3IgdGhpcyBvcmdhbml6YXRpb24nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3cml0ZVNzZUhlYWRlcnMocmVzKTtcbiAgICAgIHJlcy5mbHVzaEhlYWRlcnMoKTtcblxuICAgICAgLy8gSGVhZGVycyBhcmUgZmx1c2hlZCDigJQgd2UgY2FuIG5vIGxvbmdlciBzZW5kIGEgNDI5LiBhZGRDbGllbnQgcmUtY2hlY2tzXG4gICAgICAvLyB0aGUgY2FwcyAoaW5jbHVkaW5nIHRoZSBwcm9jZXNzLXdpZGUgdG90YWwtY2xpZW50cyBjYXAsIHdoaWNoIHRoZVxuICAgICAgLy8gcHJlLWZsaWdodCBhYm92ZSBkb2VzIG5vdCkgYW5kIGNhbiBzdGlsbCByZWplY3Qgb24gYSByYWNlOiBhIGNvbmN1cnJlbnRcbiAgICAgIC8vIGNvbm5lY3Rpb24gbWF5IGhhdmUgZmlsbGVkIGEgY2FwIGJldHdlZW4gdGhlIHByZS1mbGlnaHQgY2hlY2sgYW5kIGhlcmUuXG4gICAgICAvLyBPbiByZWplY3Rpb24sIGNsb3NlIHRoZSBub3ctZGFuZ2xpbmcgcmVzcG9uc2UgaW5zdGVhZCBvZiBsZWF2aW5nIGFuXG4gICAgICAvLyBvcGVuIHNvY2tldCB3aXRoIG5vIGNsaWVudCByZWNvcmQgKHdoaWNoIHdvdWxkIGxlYWsgYW4gZmQgKyBuZXZlciBlbWl0XG4gICAgICAvLyBzdHJlYW0gZGF0YSkuXG4gICAgICBjb25zdCBhZGRlZCA9IHRoaXMuYWRkQ2xpZW50KHJlcXVlc3RJZCwgcmVzLCBvcmdJZCk7XG4gICAgICBpZiAoIWFkZGVkKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBTU0UgYWRkQ2xpZW50IHJlamVjdGVkIGFmdGVyIGhlYWRlcnMgZmx1c2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH07IGNsb3NpbmcgZGFuZ2xpbmcgcmVzcG9uc2VgKTtcbiAgICAgICAgdHJ5IHsgcmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgcGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGFydENsZWFudXBJbnRlcnZhbChpbnRlcnZhbE1zOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFudXBJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgIH0sIGludGVydmFsTXMpO1xuXG4gICAgLy8gRG9uJ3QgcHJldmVudCBwcm9jZXNzIGV4aXRcbiAgICB0aGlzLmNsZWFudXBJbnRlcnZhbC51bnJlZigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFuIHVwIHN0YWxlIGNvbm5lY3Rpb25zIHVzaW5nIHNpbmdsZS1wYXNzIHBhcnRpdGlvbi5cbiAgICogTyhSIMOXIEMpIGluc3RlYWQgb2YgTyhSIMOXIEPCsiksIGFuZCBhdm9pZHMgbXV0YXRpb24tZHVyaW5nLWl0ZXJhdGlvbi5cbiAgICovXG4gIHByaXZhdGUgY2xlYW51cCgpOiB2b2lkIHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCBjbGVhbmVkID0gMDtcblxuICAgIC8vIFN3ZWVwIGV4cGlyZWQgdGlja2V0cy9vd25lcnMgc28gYW4gaW4tbWVtb3J5IHN0b3JlIHN0YXlzIGJvdW5kZWQgZXZlbiB3aGVuXG4gICAgLy8gdGlja2V0cyBhcmUgbWludGVkIGJ1dCBuZXZlciBjb25zdW1lZCAoY2xpZW50IGNsb3NlZCB0aGUgdGFiIGJlZm9yZVxuICAgIC8vIGNvbm5lY3RpbmcpLiBDb25zdW1lLXRpbWUgc3RpbGwgcmUtY2hlY2tzIGV4cGlyeSwgc28gdGhpcyBpcyBtZW1vcnlcbiAgICAvLyBoeWdpZW5lIG9ubHk7IHRoZSBSZWRpcyBzdG9yZSByZWxpZXMgb24gbmF0aXZlIGtleSBUVEwgKHN3ZWVwIGlzIGEgbm8tb3ApLlxuICAgIHZvaWQgdGhpcy50aWNrZXRTdG9yZS5zd2VlcD8uKCk7XG5cbiAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIGNsaWVudHNdIG9mIHRoaXMuY2xpZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHN0YWxlOiBTU0VDbGllbnRbXSA9IFtdO1xuICAgICAgY29uc3QgYWN0aXZlOiBTU0VDbGllbnRbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIC8vIFRpbWUtYmFzZWQgZXZpY3Rpb24gT1IgYSBzb2NrZXQgdGhhdCBzaWxlbnRseSBjbG9zZWQgKG5vICdjbG9zZSdcbiAgICAgICAgLy8gZXZlbnQpIOKAlCBOb2RlIHNvbWV0aW1lcyBkcm9wcyBzb2NrZXRzIHdpdGhvdXQgZmlyaW5nIHRoZSBldmVudCxcbiAgICAgICAgLy8gc28gd2UgZXhwbGljaXRseSBjaGVjayB3cml0YWJsZUVuZGVkL2Rlc3Ryb3llZCBoZXJlLlxuICAgICAgICBjb25zdCBhZ2VTdGFsZSA9IG5vdyAtIGNsaWVudC5jb25uZWN0ZWRBdCA+IHRoaXMuY2xpZW50VGltZW91dE1zO1xuICAgICAgICBjb25zdCBzb2NrZXREZWFkID0gY2xpZW50LnJlcy53cml0YWJsZUVuZGVkIHx8IChjbGllbnQucmVzIGFzIHsgZGVzdHJveWVkPzogYm9vbGVhbiB9KS5kZXN0cm95ZWQgPT09IHRydWU7XG4gICAgICAgIGlmIChhZ2VTdGFsZSB8fCBzb2NrZXREZWFkKSB7XG4gICAgICAgICAgc3RhbGUucHVzaChjbGllbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjdGl2ZS5wdXNoKGNsaWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2Ygc3RhbGUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICBjbGVhbmVkKys7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3RpdmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhbGUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYW5lZCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICAvLyBUZWFyIGRvd24gdGhlIHJlbGF5J3MgUmVkaXMgY29ubmVjdGlvbnMgKGJlc3QtZWZmb3J0OyBuZXZlciB0aHJvd3MpLlxuICAgIHZvaWQgdGhpcy5yZWxheT8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7IC8qIGFscmVhZHkgY2xvc2luZyAqLyB9KTtcblxuICAgIGxvZ2dlci5pbmZvKCdTU0UgTWFuYWdlciBzaHV0IGRvd24nKTtcbiAgfVxufVxuIl19
package/package.json CHANGED
@@ -44,9 +44,9 @@
44
44
  "rate-limit-redis": "6.0.0",
45
45
  "swagger-ui-express": "5.0.1",
46
46
  "uuid": "14.0.1",
47
- "@pipeline-builder/pipeline-data": "3.4.115",
48
- "@pipeline-builder/api-core": "3.4.110",
49
- "@pipeline-builder/pipeline-core": "3.4.129"
47
+ "@pipeline-builder/api-core": "3.4.112",
48
+ "@pipeline-builder/pipeline-data": "3.4.117",
49
+ "@pipeline-builder/pipeline-core": "3.4.131"
50
50
  },
51
51
  "keywords": [
52
52
  "ci-cd",
@@ -102,7 +102,7 @@
102
102
  "access": "public",
103
103
  "registry": "https://registry.npmjs.org/"
104
104
  },
105
- "version": "3.4.135",
105
+ "version": "3.4.137",
106
106
  "bugs": {
107
107
  "url": "https://github.com/mwashburn160/pipeline-builder/issues"
108
108
  },