@techextensor/tab-core-utility 2.2.184 → 2.2.187

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.
Files changed (73) hide show
  1. package/esm2022/index.mjs +1 -5
  2. package/esm2022/lib/tab-core-utility/app/constants/api-constants.mjs +13 -24
  3. package/esm2022/lib/tab-core-utility/app/constants/common.mjs +50 -14
  4. package/esm2022/lib/tab-core-utility/app/constants/storage-constants.mjs +2 -2
  5. package/esm2022/lib/tab-core-utility/app/crud/tab-crud.service.mjs +49 -38
  6. package/esm2022/lib/tab-core-utility/app/crud/tab-delete.service.mjs +30 -81
  7. package/esm2022/lib/tab-core-utility/app/crud/tab-formio.service.mjs +12 -141
  8. package/esm2022/lib/tab-core-utility/app/crud/tab-get.service.mjs +35 -136
  9. package/esm2022/lib/tab-core-utility/app/crud/tab-insert.service.mjs +38 -89
  10. package/esm2022/lib/tab-core-utility/app/crud/tab-update.service.mjs +131 -152
  11. package/esm2022/lib/tab-core-utility/app/enums/query.enum.mjs +7 -7
  12. package/esm2022/lib/tab-core-utility/app/helpers/common/app.helpers.mjs +17 -6
  13. package/esm2022/lib/tab-core-utility/app/helpers/common/dsq.helpers.mjs +11 -9
  14. package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +13 -13
  15. package/esm2022/lib/tab-core-utility/app/helpers/common/req-res.helpers.mjs +45 -7
  16. package/esm2022/lib/tab-core-utility/app/helpers/common/where-clause.helpers.mjs +76 -79
  17. package/esm2022/lib/tab-core-utility/app/helpers/screen/grid.helpers.mjs +4 -8
  18. package/esm2022/lib/tab-core-utility/app/helpers/screen/screen.helpers.mjs +33 -8
  19. package/esm2022/lib/tab-core-utility/app/interfaces/common.interface.mjs +1 -1
  20. package/esm2022/lib/tab-core-utility/app/models/api-query.class.mjs +1 -39
  21. package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +7 -36
  22. package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +47 -84
  23. package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +13 -24
  24. package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +23 -57
  25. package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +10 -21
  26. package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +6 -12
  27. package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +4 -11
  28. package/esm2022/lib/tab-core-utility/app/utils/json.util.mjs +16 -17
  29. package/esm2022/lib/tab-core-utility/app/utils/req-res.util.mjs +55 -1
  30. package/esm2022/lib/tab-core-utility/app/utils/tab-app.util.mjs +164 -1
  31. package/esm2022/lib/tab-core-utility/core/http-client/api.service.mjs +1 -63
  32. package/index.d.ts +0 -4
  33. package/lib/tab-core-utility/app/constants/api-constants.d.ts +10 -13
  34. package/lib/tab-core-utility/app/constants/common.d.ts +0 -9
  35. package/lib/tab-core-utility/app/constants/storage-constants.d.ts +1 -1
  36. package/lib/tab-core-utility/app/crud/tab-crud.service.d.ts +1 -8
  37. package/lib/tab-core-utility/app/crud/tab-delete.service.d.ts +10 -20
  38. package/lib/tab-core-utility/app/crud/tab-formio.service.d.ts +6 -33
  39. package/lib/tab-core-utility/app/crud/tab-get.service.d.ts +3 -45
  40. package/lib/tab-core-utility/app/crud/tab-insert.service.d.ts +21 -16
  41. package/lib/tab-core-utility/app/crud/tab-update.service.d.ts +19 -34
  42. package/lib/tab-core-utility/app/enums/query.enum.d.ts +6 -3
  43. package/lib/tab-core-utility/app/helpers/common/app.helpers.d.ts +8 -3
  44. package/lib/tab-core-utility/app/helpers/common/dsq.helpers.d.ts +0 -3
  45. package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +3 -3
  46. package/lib/tab-core-utility/app/helpers/common/req-res.helpers.d.ts +51 -7
  47. package/lib/tab-core-utility/app/helpers/common/where-clause.helpers.d.ts +0 -1
  48. package/lib/tab-core-utility/app/helpers/screen/grid.helpers.d.ts +1 -2
  49. package/lib/tab-core-utility/app/helpers/screen/screen.helpers.d.ts +0 -1
  50. package/lib/tab-core-utility/app/interfaces/common.interface.d.ts +2 -50
  51. package/lib/tab-core-utility/app/models/api-query.class.d.ts +9 -54
  52. package/lib/tab-core-utility/app/models/app-field.model.d.ts +2 -4
  53. package/lib/tab-core-utility/app/models/app-object.model.d.ts +3 -5
  54. package/lib/tab-core-utility/app/models/app-screen.model.d.ts +2 -2
  55. package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +2 -7
  56. package/lib/tab-core-utility/app/models/filter.model.d.ts +2 -2
  57. package/lib/tab-core-utility/app/models/parameter.model.d.ts +2 -2
  58. package/lib/tab-core-utility/app/models/sort.model.d.ts +1 -1
  59. package/lib/tab-core-utility/app/utils/json.util.d.ts +2 -3
  60. package/lib/tab-core-utility/app/utils/req-res.util.d.ts +9 -1
  61. package/lib/tab-core-utility/app/utils/tab-app.util.d.ts +61 -0
  62. package/lib/tab-core-utility/core/http-client/api.service.d.ts +0 -37
  63. package/package.json +2 -3
  64. package/esm2022/lib/tab-core-utility/app/helpers/response.adapter.mjs +0 -38
  65. package/esm2022/lib/tab-core-utility/app/interfaces/signalr.interface.mjs +0 -42
  66. package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +0 -82
  67. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +0 -252
  68. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +0 -207
  69. package/lib/tab-core-utility/app/helpers/response.adapter.d.ts +0 -22
  70. package/lib/tab-core-utility/app/interfaces/signalr.interface.d.ts +0 -80
  71. package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +0 -40
  72. package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +0 -68
  73. package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +0 -122
@@ -1,5 +1,6 @@
1
1
  import { HttpHeaders } from '@angular/common/http';
2
2
  import { AppObject } from '../models/app-object.class';
3
+ import { AppFields } from '../models/data-source-queries.class';
3
4
  /**
4
5
  * Delete a key from the response object
5
6
  *
@@ -36,7 +37,7 @@ export declare function getHeaders(headers?: any): any;
36
37
  * @param appObject - The AppObject
37
38
  * @returns AppFields[] | null - The array of primary key fields or null
38
39
  */
39
- export declare function getPrimaryKeyFields(appObject: AppObject): import("@techextensor/tab-core-utility").AppFields[] | null;
40
+ export declare function getPrimaryKeyFields(appObject: AppObject): AppFields[] | null;
40
41
  /**
41
42
  * Get the edit record ID from the response object
42
43
  *
@@ -45,6 +46,13 @@ export declare function getPrimaryKeyFields(appObject: AppObject): import("@tech
45
46
  * @returns any - The edit record ID
46
47
  */
47
48
  export declare function getEditRecordId(response: any, fieldName: any): any;
49
+ /**
50
+ * Generate the fields schema based on the AppFields
51
+ *
52
+ * @param fields - The AppFields object
53
+ * @returns any - The generated fields schema
54
+ */
55
+ export declare function generateFieldsSchema(url: any, fields: AppFields): {};
48
56
  /**
49
57
  * Get the HttpHeaders for form data requests
50
58
  *
@@ -1,4 +1,36 @@
1
1
  import { AppObject } from '../models/app-object.class';
2
+ /** Get the DataSourceQuery ID from the selected AppObject's DataSourceQuery array
3
+ * @param dsqList - The list of DataSourceQueries
4
+ * @param table - The table name
5
+ * @param like - The like string
6
+ * @returns string - The ID of the DataSourceQuery
7
+ */
8
+ export declare function getDsqIdfromSelectedAppObjectDSQArray(dsqList: any, table: string, like: string): any;
9
+ /** Get the AppObject based on the provided ID
10
+ * @param id - The ID of the AppObject
11
+ * @returns AppObject | null - The found AppObject or null
12
+ */
13
+ export declare function getAppObject(id: string): any;
14
+ /**
15
+ * Get the AppObject from the DataSourceQuery ID
16
+ * @param dsqId - The DataSourceQuery ID
17
+ * @returns AppObject | null - The found AppObject or null
18
+ */
19
+ export declare function getAppObjectFromDataSourceQueryID(dsqId: string): any;
20
+ /**
21
+ * Get the DataSourceQuery ID from the QueryName and table
22
+ * @param table - The table name
23
+ * @param dsq - The DataSourceQuery name
24
+ * @returns any - The found DataSourceQuery
25
+ */
26
+ export declare function getDsqIDFromQueryName(table: string, dsq: string): any;
27
+ /**
28
+ * Get the Data from the DataSourceQuery ID
29
+ *
30
+ * @param dsqId - The DataSourceQuery ID
31
+ * @returns any - The found Data
32
+ */
33
+ export declare function getDataFromDataSourceQueryID(dsqId: string): any;
2
34
  /**
3
35
  * Synchronize AppObject fields with the response
4
36
  *
@@ -7,3 +39,32 @@ import { AppObject } from '../models/app-object.class';
7
39
  * @returns any - The synchronized response object
8
40
  */
9
41
  export declare function syncAppObjectFields(response: any, appObject: AppObject): any;
42
+ /**
43
+ * Get the AppObject based on the SystemDBTableName
44
+ *
45
+ * @param tableName - The SystemDBTableName
46
+ * @returns AppObject | null - The found AppObject or null
47
+ */
48
+ export declare function getAppObjectFromSystemDBTableName(tableName: string): any;
49
+ /**
50
+ * Get the fields based on the appobjectid
51
+ *
52
+ * @param appObjectId - The appobjectid
53
+ * @returns AppObject | null - The found AppObject or null
54
+ */
55
+ export declare function getAppfieldsFromAppObjectId(appObjectId: string): any;
56
+ export declare function getLookupAppfieldsFromAppObjectId(appObjectId: string): any;
57
+ export declare function getViewAppObjectDetailsFromDSQID(dsqID: string): any;
58
+ /**
59
+ * Retrieves all appObjects and their DSQs in a single list
60
+ * suitable for tree view representation.
61
+ * @author : Parth B Thakkar
62
+ * @Usage : HTTP Request
63
+ * @returns Array<{ id: string; name: string; hasChildren: boolean; parentID: string | null }>
64
+ */
65
+ export declare function getAllAppObjectsForTreeViewJson(): {
66
+ id: string;
67
+ name: string;
68
+ hasChildren: boolean;
69
+ parentID: string | null;
70
+ }[];
@@ -1,6 +1,5 @@
1
1
  import { HttpParams, HttpHeaders } from '@angular/common/http';
2
2
  import { Observable } from 'rxjs';
3
- import { APIServiceName, CommonApiResponse } from '../../app/interfaces/common.interface';
4
3
  import * as i0 from "@angular/core";
5
4
  export declare class ApiService {
6
5
  private readonly http;
@@ -82,42 +81,6 @@ export declare class ApiService {
82
81
  * @returns An Observable emitting the response data of type T.
83
82
  */
84
83
  deleteByUrl<T>(url: string, options?: any): Observable<any>;
85
- /**
86
- * Makes an HTTP GET request to a specific microservice
87
- * @param serviceName - Name of the microservice (e.g., 'crudService', 'metadataService')
88
- * @param endPointName - Endpoint path relative to the service
89
- * @param params - Query parameters for the request
90
- * @param reqHeader - Custom headers for the request
91
- * @returns An Observable emitting the response data (auto-normalized to CommonApiResponse format)
92
- */
93
- getFromService(serviceName: APIServiceName, endPointName: string, params?: HttpParams, reqHeader?: HttpHeaders): Observable<CommonApiResponse>;
94
- /**
95
- * Makes an HTTP POST request to a specific microservice
96
- * @param serviceName - Name of the microservice (e.g., 'crudService', 'formioService')
97
- * @param endPointName - Endpoint path relative to the service
98
- * @param data - Data to send with the request
99
- * @param reqHeader - Custom headers for the request
100
- * @returns An Observable emitting the response data (auto-normalized to CommonApiResponse format)
101
- */
102
- postToService<T, D>(serviceName: APIServiceName, endPointName: string, data?: D, reqHeader?: HttpHeaders): Observable<CommonApiResponse>;
103
- /**
104
- * Makes an HTTP PUT request to a specific microservice
105
- * @param serviceName - Name of the microservice
106
- * @param endPointName - Endpoint path relative to the service
107
- * @param data - Data to send with the request
108
- * @param reqHeader - Custom headers for the request
109
- * @returns An Observable emitting the response data (auto-normalized to CommonApiResponse format)
110
- */
111
- putToService<T, D>(serviceName: APIServiceName, endPointName: string, data: D, reqHeader?: HttpHeaders): Observable<CommonApiResponse>;
112
- /**
113
- * Makes an HTTP DELETE request to a specific microservice
114
- * @param serviceName - Name of the microservice
115
- * @param endPointName - Endpoint path relative to the service
116
- * @param data - Data to send with the request (optional, for DELETE with body)
117
- * @param reqHeader - Custom headers for the request
118
- * @returns An Observable emitting the response data (auto-normalized to CommonApiResponse format)
119
- */
120
- deleteFromService<D>(serviceName: APIServiceName, endPointName: string, data?: D, reqHeader?: HttpHeaders): Observable<CommonApiResponse>;
121
84
  static ɵfac: i0.ɵɵFactoryDeclaration<ApiService, never>;
122
85
  static ɵprov: i0.ɵɵInjectableDeclaration<ApiService>;
123
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techextensor/tab-core-utility",
3
- "version": "2.2.184",
3
+ "version": "2.2.187",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.2.15",
6
6
  "@angular/core": "^19.2.15",
@@ -11,8 +11,7 @@
11
11
  "idb": "^8.0.2",
12
12
  "liquidjs": "^10.20.3",
13
13
  "cypress": "^13.17.0",
14
- "crypto-js": "^4.2.0",
15
- "@microsoft/signalr": "^10.0.0"
14
+ "crypto-js": "^4.2.0"
16
15
  },
17
16
  "dependencies": {
18
17
  "tslib": "^2.8.1"
@@ -1,38 +0,0 @@
1
- /**
2
- * ResponseAdapter - Transforms new API response format to legacy format
3
- *
4
- * This adapter maintains backward compatibility by converting the new camelCase
5
- * response format from the backend to the old PascalCase format expected by
6
- * existing application code.
7
- *
8
- * @example
9
- * // Auto-detect and normalize response
10
- * return this.apiService.postToService(...).pipe(
11
- * map(response => ResponseAdapter.normalize(response))
12
- * );
13
- */
14
- export class ResponseAdapter {
15
- /**
16
- * Normalizes a StandardApiResponse to CommonApiResponse format.
17
- * @param newResponse The response object in the new API format.
18
- * @returns The normalized response in the legacy format.
19
- */
20
- static normalize(newResponse) {
21
- return {
22
- IsSuccess: newResponse?.isSuccess || false,
23
- Result: newResponse?.result || null,
24
- RecordAffectted: newResponse?.affectedRecords ?? 0,
25
- TotalRecords: newResponse?.totalRecords ?? 0,
26
- TotalExecutionTime: newResponse?.executionTimeMs ?? 0,
27
- Log: newResponse?.logs ?? [],
28
- Errors: newResponse?.error
29
- ? [
30
- newResponse.error?.message,
31
- ...(newResponse.error?.details ? [newResponse.error?.details] : [])
32
- ]
33
- : [],
34
- CorrelationId: newResponse?.correlationId // Preserve correlationId for async operations
35
- };
36
- }
37
- }
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0YS1hY2Nlc3Mvc3JjL2xpYi90YWItY29yZS11dGlsaXR5L2FwcC9oZWxwZXJzL3Jlc3BvbnNlLmFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0E7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFFMUI7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBZ0M7UUFDL0MsT0FBTztZQUNMLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxJQUFJLEtBQUs7WUFDMUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLElBQUksSUFBSTtZQUNuQyxlQUFlLEVBQUUsV0FBVyxFQUFFLGVBQWUsSUFBSSxDQUFDO1lBQ2xELFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxJQUFJLENBQUM7WUFDNUMsa0JBQWtCLEVBQUUsV0FBVyxFQUFFLGVBQWUsSUFBSSxDQUFDO1lBQ3JELEdBQUcsRUFBRSxXQUFXLEVBQUUsSUFBSSxJQUFJLEVBQUU7WUFDNUIsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLO2dCQUN4QixDQUFDLENBQUM7b0JBQ0UsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPO29CQUMxQixHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2lCQUNwRTtnQkFDSCxDQUFDLENBQUMsRUFBRTtZQUNOLGFBQWEsRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFFLDhDQUE4QztTQUMxRixDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xyXG5pbXBvcnQgeyBDb21tb25BcGlSZXNwb25zZSwgU3RhbmRhcmRBcGlSZXNwb25zZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29tbW9uLmludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogUmVzcG9uc2VBZGFwdGVyIC0gVHJhbnNmb3JtcyBuZXcgQVBJIHJlc3BvbnNlIGZvcm1hdCB0byBsZWdhY3kgZm9ybWF0XHJcbiAqXHJcbiAqIFRoaXMgYWRhcHRlciBtYWludGFpbnMgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBieSBjb252ZXJ0aW5nIHRoZSBuZXcgY2FtZWxDYXNlXHJcbiAqIHJlc3BvbnNlIGZvcm1hdCBmcm9tIHRoZSBiYWNrZW5kIHRvIHRoZSBvbGQgUGFzY2FsQ2FzZSBmb3JtYXQgZXhwZWN0ZWQgYnlcclxuICogZXhpc3RpbmcgYXBwbGljYXRpb24gY29kZS5cclxuICpcclxuICogQGV4YW1wbGVcclxuICogLy8gQXV0by1kZXRlY3QgYW5kIG5vcm1hbGl6ZSByZXNwb25zZVxyXG4gKiByZXR1cm4gdGhpcy5hcGlTZXJ2aWNlLnBvc3RUb1NlcnZpY2UoLi4uKS5waXBlKFxyXG4gKiAgIG1hcChyZXNwb25zZSA9PiBSZXNwb25zZUFkYXB0ZXIubm9ybWFsaXplKHJlc3BvbnNlKSlcclxuICogKTtcclxuICovXHJcbmV4cG9ydCBjbGFzcyBSZXNwb25zZUFkYXB0ZXIge1xyXG5cclxuICAvKipcclxuICAgKiBOb3JtYWxpemVzIGEgU3RhbmRhcmRBcGlSZXNwb25zZSB0byBDb21tb25BcGlSZXNwb25zZSBmb3JtYXQuXHJcbiAgICogQHBhcmFtIG5ld1Jlc3BvbnNlIFRoZSByZXNwb25zZSBvYmplY3QgaW4gdGhlIG5ldyBBUEkgZm9ybWF0LlxyXG4gICAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIHJlc3BvbnNlIGluIHRoZSBsZWdhY3kgZm9ybWF0LlxyXG4gICAqL1xyXG4gIHN0YXRpYyBub3JtYWxpemUobmV3UmVzcG9uc2U6IFN0YW5kYXJkQXBpUmVzcG9uc2UpOiBDb21tb25BcGlSZXNwb25zZSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBJc1N1Y2Nlc3M6IG5ld1Jlc3BvbnNlPy5pc1N1Y2Nlc3MgfHwgZmFsc2UsXHJcbiAgICAgIFJlc3VsdDogbmV3UmVzcG9uc2U/LnJlc3VsdCB8fCBudWxsLFxyXG4gICAgICBSZWNvcmRBZmZlY3R0ZWQ6IG5ld1Jlc3BvbnNlPy5hZmZlY3RlZFJlY29yZHMgPz8gMCxcclxuICAgICAgVG90YWxSZWNvcmRzOiBuZXdSZXNwb25zZT8udG90YWxSZWNvcmRzID8/IDAsXHJcbiAgICAgIFRvdGFsRXhlY3V0aW9uVGltZTogbmV3UmVzcG9uc2U/LmV4ZWN1dGlvblRpbWVNcyA/PyAwLFxyXG4gICAgICBMb2c6IG5ld1Jlc3BvbnNlPy5sb2dzID8/IFtdLFxyXG4gICAgICBFcnJvcnM6IG5ld1Jlc3BvbnNlPy5lcnJvclxyXG4gICAgICAgID8gW1xyXG4gICAgICAgICAgICBuZXdSZXNwb25zZS5lcnJvcj8ubWVzc2FnZSxcclxuICAgICAgICAgICAgLi4uKG5ld1Jlc3BvbnNlLmVycm9yPy5kZXRhaWxzID8gW25ld1Jlc3BvbnNlLmVycm9yPy5kZXRhaWxzXSA6IFtdKVxyXG4gICAgICAgICAgXVxyXG4gICAgICAgIDogW10sXHJcbiAgICAgIENvcnJlbGF0aW9uSWQ6IG5ld1Jlc3BvbnNlPy5jb3JyZWxhdGlvbklkICAvLyBQcmVzZXJ2ZSBjb3JyZWxhdGlvbklkIGZvciBhc3luYyBvcGVyYXRpb25zXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iXX0=
@@ -1,42 +0,0 @@
1
- // ============= CONSTANTS =============
2
- /**
3
- * SignalR hub method names
4
- */
5
- export const SIGNALR_HUB_METHODS = {
6
- JOIN_GROUP: 'JoinGroupAsync',
7
- LEAVE_GROUP: 'LeaveGroupAsync',
8
- };
9
- /**
10
- * SignalR event names from backend
11
- */
12
- export const SIGNALR_EVENTS = {
13
- INSERT_COMPLETED: 'InsertOperationCompleted',
14
- UPDATE_COMPLETED: 'UpdateOperationCompleted',
15
- DELETE_COMPLETED: 'DeleteOperationCompleted',
16
- };
17
- /**
18
- * CRUD operation types
19
- */
20
- export const CRUD_OPERATION = {
21
- INSERT: 'INSERT',
22
- UPDATE: 'UPDATE',
23
- DELETE: 'DELETE',
24
- };
25
- /**
26
- * SignalR connection states
27
- */
28
- export const CONNECTION_STATE = {
29
- DISCONNECTED: 'Disconnected',
30
- CONNECTING: 'Connecting',
31
- CONNECTED: 'Connected',
32
- RECONNECTING: 'Reconnecting',
33
- FAILED: 'Failed',
34
- };
35
- /**
36
- * SignalR configuration constants
37
- */
38
- export const SIGNALR_CONFIG = {
39
- DEFAULT_TIMEOUT: 120000, // 2 minutes
40
- RECONNECT_DELAYS: [0, 2000, 10000, 30000, 60000], // Exponential backoff
41
- };
42
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci5pbnRlcmZhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2RhdGEtYWNjZXNzL3NyYy9saWIvdGFiLWNvcmUtdXRpbGl0eS9hcHAvaW50ZXJmYWNlcy9zaWduYWxyLmludGVyZmFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFnREEsd0NBQXdDO0FBRXhDOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7SUFDakMsVUFBVSxFQUFFLGdCQUFnQjtJQUM1QixXQUFXLEVBQUUsaUJBQWlCO0NBQ3RCLENBQUM7QUFFWDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRztJQUM1QixnQkFBZ0IsRUFBRSwwQkFBMEI7SUFDNUMsZ0JBQWdCLEVBQUUsMEJBQTBCO0lBQzVDLGdCQUFnQixFQUFFLDBCQUEwQjtDQUNwQyxDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUc7SUFDNUIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsTUFBTSxFQUFFLFFBQVE7Q0FDUixDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztJQUM5QixZQUFZLEVBQUUsY0FBYztJQUM1QixVQUFVLEVBQUUsWUFBWTtJQUN4QixTQUFTLEVBQUUsV0FBVztJQUN0QixZQUFZLEVBQUUsY0FBYztJQUM1QixNQUFNLEVBQUUsUUFBUTtDQUNSLENBQUM7QUFFWDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRztJQUM1QixlQUFlLEVBQUUsTUFBTSxFQUFFLFlBQVk7SUFDckMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsc0JBQXNCO0NBQ2hFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQ1JVRCBub3RpZmljYXRpb24gcGF5bG9hZCByZWNlaXZlZCBmcm9tIFNpZ25hbFIgaHViXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIENydWROb3RpZmljYXRpb24ge1xyXG4gIC8vIEJhY2tlbmQgZmllbGRzXHJcbiAgaXNTdWNjZXNzOiBib29sZWFuO1xyXG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZztcclxuICByZWNvcmRJZDogc3RyaW5nO1xyXG4gIGVudGl0eU5hbWU6IHN0cmluZztcclxuICBhcHBPYmplY3RJZDogc3RyaW5nO1xyXG4gIGV4ZWN1dGlvblRpbWVNczogbnVtYmVyO1xyXG4gIGFmZmVjdGVkUmVjb3JkczogbnVtYmVyO1xyXG4gIGVycm9yTWVzc2FnZT86IHN0cmluZztcclxuICBlcnJvckNvZGU/OiBzdHJpbmc7XHJcblxyXG4gIC8vIEZyb250ZW5kIGFkZGl0aW9uc1xyXG4gIG9wZXJhdGlvbj86IENydWRPcGVyYXRpb247XHJcbiAgcmVjZWl2ZWRBdD86IERhdGU7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBQZW5kaW5nIGFzeW5jIG9wZXJhdGlvbiB0cmFja2VkIGJ5IE9wZXJhdGlvblRyYWNrZXJTZXJ2aWNlXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFBlbmRpbmdPcGVyYXRpb24ge1xyXG4gIHJlcXVlc3RJZDogc3RyaW5nOyAvLyBGcm9udGVuZCBnZW5lcmF0ZWQgdW5pcXVlIElEXHJcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nOyAvLyBCYWNrZW5kIGNvcnJlbGF0aW9uIElEXHJcbiAgb3BlcmF0aW9uOiBDcnVkT3BlcmF0aW9uO1xyXG4gIGFwcE9iamVjdElkPzogc3RyaW5nO1xyXG4gIHBheWxvYWQ/OiBhbnk7XHJcbiAgdGltZXN0YW1wOiBEYXRlO1xyXG4gIHRpbWVvdXQ6IG51bWJlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENhbGxiYWNrIGZ1bmN0aW9uIHR5cGUgZm9yIGNvbXBvbmVudCBub3RpZmljYXRpb25zXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25DYWxsYmFjayA9IChub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pID0+IHZvaWQ7XHJcblxyXG4vKipcclxuICogQ1JVRCBvcGVyYXRpb24gdHlwZXNcclxuICovXHJcbmV4cG9ydCB0eXBlIENydWRPcGVyYXRpb24gPSB0eXBlb2YgQ1JVRF9PUEVSQVRJT05ba2V5b2YgdHlwZW9mIENSVURfT1BFUkFUSU9OXTtcclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIGNvbm5lY3Rpb24gc3RhdGUgdHlwZXNcclxuICovXHJcbmV4cG9ydCB0eXBlIENvbm5lY3Rpb25TdGF0ZSA9IHR5cGVvZiBDT05ORUNUSU9OX1NUQVRFW2tleW9mIHR5cGVvZiBDT05ORUNUSU9OX1NUQVRFXTtcclxuXHJcbi8vID09PT09PT09PT09PT0gQ09OU1RBTlRTID09PT09PT09PT09PT1cclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIGh1YiBtZXRob2QgbmFtZXNcclxuICovXHJcbmV4cG9ydCBjb25zdCBTSUdOQUxSX0hVQl9NRVRIT0RTID0ge1xyXG4gIEpPSU5fR1JPVVA6ICdKb2luR3JvdXBBc3luYycsXHJcbiAgTEVBVkVfR1JPVVA6ICdMZWF2ZUdyb3VwQXN5bmMnLFxyXG59IGFzIGNvbnN0O1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgZXZlbnQgbmFtZXMgZnJvbSBiYWNrZW5kXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgU0lHTkFMUl9FVkVOVFMgPSB7XHJcbiAgSU5TRVJUX0NPTVBMRVRFRDogJ0luc2VydE9wZXJhdGlvbkNvbXBsZXRlZCcsXHJcbiAgVVBEQVRFX0NPTVBMRVRFRDogJ1VwZGF0ZU9wZXJhdGlvbkNvbXBsZXRlZCcsXHJcbiAgREVMRVRFX0NPTVBMRVRFRDogJ0RlbGV0ZU9wZXJhdGlvbkNvbXBsZXRlZCcsXHJcbn0gYXMgY29uc3Q7XHJcblxyXG4vKipcclxuICogQ1JVRCBvcGVyYXRpb24gdHlwZXNcclxuICovXHJcbmV4cG9ydCBjb25zdCBDUlVEX09QRVJBVElPTiA9IHtcclxuICBJTlNFUlQ6ICdJTlNFUlQnLFxyXG4gIFVQREFURTogJ1VQREFURScsXHJcbiAgREVMRVRFOiAnREVMRVRFJyxcclxufSBhcyBjb25zdDtcclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIGNvbm5lY3Rpb24gc3RhdGVzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgQ09OTkVDVElPTl9TVEFURSA9IHtcclxuICBESVNDT05ORUNURUQ6ICdEaXNjb25uZWN0ZWQnLFxyXG4gIENPTk5FQ1RJTkc6ICdDb25uZWN0aW5nJyxcclxuICBDT05ORUNURUQ6ICdDb25uZWN0ZWQnLFxyXG4gIFJFQ09OTkVDVElORzogJ1JlY29ubmVjdGluZycsXHJcbiAgRkFJTEVEOiAnRmFpbGVkJyxcclxufSBhcyBjb25zdDtcclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIGNvbmZpZ3VyYXRpb24gY29uc3RhbnRzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgU0lHTkFMUl9DT05GSUcgPSB7XHJcbiAgREVGQVVMVF9USU1FT1VUOiAxMjAwMDAsIC8vIDIgbWludXRlc1xyXG4gIFJFQ09OTkVDVF9ERUxBWVM6IFswLCAyMDAwLCAxMDAwMCwgMzAwMDAsIDYwMDAwXSwgLy8gRXhwb25lbnRpYWwgYmFja29mZlxyXG59IGFzIGNvbnN0OyJdfQ==
@@ -1,82 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { Subject, throwError, TimeoutError } from 'rxjs';
3
- import { filter, take, timeout, catchError } from 'rxjs/operators';
4
- import { SIGNALR_CONFIG, } from '../../../app/interfaces/signalr.interface';
5
- import * as i0 from "@angular/core";
6
- /**
7
- * Operation Tracker Service
8
- * Tracks async operations by correlationId and matches them with SignalR notifications
9
- * Used by TabFormioService for handling async processRequest operations
10
- */
11
- export class OperationTrackerService {
12
- constructor() {
13
- // Map<correlationId, PendingOperation>
14
- this.pendingOperations = new Map();
15
- // Observable for completed operations
16
- this.operationCompleted$ = new Subject();
17
- }
18
- /**
19
- * Register an async operation for tracking
20
- */
21
- registerOperation(operation) {
22
- this.pendingOperations.set(operation.correlationId, operation);
23
- // Auto-cleanup after timeout
24
- setTimeout(() => {
25
- if (this.pendingOperations.has(operation.correlationId)) {
26
- this.pendingOperations.delete(operation.correlationId);
27
- }
28
- }, operation.timeout || SIGNALR_CONFIG.DEFAULT_TIMEOUT);
29
- }
30
- /**
31
- * Wait for operation to complete via SignalR notification
32
- * Returns Observable that emits when notification with matching correlationId is received
33
- */
34
- waitForOperation(correlationId, timeoutMs = SIGNALR_CONFIG.DEFAULT_TIMEOUT) {
35
- return this.operationCompleted$.pipe(filter((notification) => notification.correlationId === correlationId), take(1), timeout(timeoutMs), catchError((error) => {
36
- // Cleanup on timeout
37
- this.pendingOperations.delete(correlationId);
38
- if (error instanceof TimeoutError) {
39
- return throwError(() => new Error('Operation timed out'));
40
- }
41
- return throwError(() => error);
42
- }));
43
- }
44
- /**
45
- * Handle incoming SignalR notification
46
- * Called by SignalRService when notification is received
47
- */
48
- handleNotification(notification) {
49
- const operation = this.pendingOperations.get(notification.correlationId);
50
- if (operation) {
51
- // Emit to observers waiting for this operation
52
- this.operationCompleted$.next(notification);
53
- // Cleanup
54
- this.pendingOperations.delete(notification.correlationId);
55
- }
56
- }
57
- /**
58
- * Check if operation is pending
59
- */
60
- isPending(correlationId) {
61
- return this.pendingOperations.has(correlationId);
62
- }
63
- /**
64
- * Get pending operations count (for debugging)
65
- */
66
- getPendingCount() {
67
- return this.pendingOperations.size;
68
- }
69
- /**
70
- * Get all pending operations (for debugging)
71
- */
72
- getAllPending() {
73
- return Array.from(this.pendingOperations.values());
74
- }
75
- static { this.ɵfac = function OperationTrackerService_Factory(t) { return new (t || OperationTrackerService)(); }; }
76
- static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: OperationTrackerService, factory: OperationTrackerService.ɵfac, providedIn: 'root' }); }
77
- }
78
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(OperationTrackerService, [{
79
- type: Injectable,
80
- args: [{ providedIn: 'root' }]
81
- }], null, null); })();
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0YS1hY2Nlc3Mvc3JjL2xpYi90YWItY29yZS11dGlsaXR5L2NvcmUvc2VydmljZS9zaWduYWxyL29wZXJhdGlvbi10cmFja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25FLE9BQU8sRUFHTCxjQUFjLEdBQ2YsTUFBTSwyQ0FBMkMsQ0FBQzs7QUFFbkQ7Ozs7R0FJRztBQUVILE1BQU0sT0FBTyx1QkFBdUI7SUFEcEM7UUFFRSx1Q0FBdUM7UUFDL0Isc0JBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQTRCLENBQUM7UUFFaEUsc0NBQXNDO1FBQzlCLHdCQUFtQixHQUFHLElBQUksT0FBTyxFQUFvQixDQUFDO0tBeUUvRDtJQXZFQzs7T0FFRztJQUNILGlCQUFpQixDQUFDLFNBQTJCO1FBQzNDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUUvRCw2QkFBNkI7UUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsRUFBRSxTQUFTLENBQUMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZ0JBQWdCLENBQUMsYUFBcUIsRUFBRSxZQUFvQixjQUFjLENBQUMsZUFBZTtRQUN4RixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQ2xDLE1BQU0sQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLGFBQWEsS0FBSyxhQUFhLENBQUMsRUFDdEUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFDbEIsVUFBVSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDbkIscUJBQXFCO1lBQ3JCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7WUFFN0MsSUFBSSxLQUFLLFlBQVksWUFBWSxFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDO1lBQ0QsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0IsQ0FBQyxZQUE4QjtRQUMvQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUV6RSxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2QsK0NBQStDO1lBQy9DLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFNUMsVUFBVTtZQUNWLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzVELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLENBQUMsYUFBcUI7UUFDN0IsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNILGVBQWU7UUFDYixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYTtRQUNYLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNyRCxDQUFDO3dGQTdFVSx1QkFBdUI7dUVBQXZCLHVCQUF1QixXQUF2Qix1QkFBdUIsbUJBRFYsTUFBTTs7aUZBQ25CLHVCQUF1QjtjQURuQyxVQUFVO2VBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0aHJvd0Vycm9yLCBUaW1lb3V0RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlsdGVyLCB0YWtlLCB0aW1lb3V0LCBjYXRjaEVycm9yIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQge1xyXG4gIENydWROb3RpZmljYXRpb24sXHJcbiAgUGVuZGluZ09wZXJhdGlvbixcclxuICBTSUdOQUxSX0NPTkZJRyxcclxufSBmcm9tICcuLi8uLi8uLi9hcHAvaW50ZXJmYWNlcy9zaWduYWxyLmludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogT3BlcmF0aW9uIFRyYWNrZXIgU2VydmljZVxyXG4gKiBUcmFja3MgYXN5bmMgb3BlcmF0aW9ucyBieSBjb3JyZWxhdGlvbklkIGFuZCBtYXRjaGVzIHRoZW0gd2l0aCBTaWduYWxSIG5vdGlmaWNhdGlvbnNcclxuICogVXNlZCBieSBUYWJGb3JtaW9TZXJ2aWNlIGZvciBoYW5kbGluZyBhc3luYyBwcm9jZXNzUmVxdWVzdCBvcGVyYXRpb25zXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxyXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9uVHJhY2tlclNlcnZpY2Uge1xyXG4gIC8vIE1hcDxjb3JyZWxhdGlvbklkLCBQZW5kaW5nT3BlcmF0aW9uPlxyXG4gIHByaXZhdGUgcGVuZGluZ09wZXJhdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgUGVuZGluZ09wZXJhdGlvbj4oKTtcclxuXHJcbiAgLy8gT2JzZXJ2YWJsZSBmb3IgY29tcGxldGVkIG9wZXJhdGlvbnNcclxuICBwcml2YXRlIG9wZXJhdGlvbkNvbXBsZXRlZCQgPSBuZXcgU3ViamVjdDxDcnVkTm90aWZpY2F0aW9uPigpO1xyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBhbiBhc3luYyBvcGVyYXRpb24gZm9yIHRyYWNraW5nXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPcGVyYXRpb24ob3BlcmF0aW9uOiBQZW5kaW5nT3BlcmF0aW9uKTogdm9pZCB7XHJcbiAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLnNldChvcGVyYXRpb24uY29ycmVsYXRpb25JZCwgb3BlcmF0aW9uKTtcclxuXHJcbiAgICAvLyBBdXRvLWNsZWFudXAgYWZ0ZXIgdGltZW91dFxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhvcGVyYXRpb24uY29ycmVsYXRpb25JZCkpIHtcclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShvcGVyYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICAgIH1cclxuICAgIH0sIG9wZXJhdGlvbi50aW1lb3V0IHx8IFNJR05BTFJfQ09ORklHLkRFRkFVTFRfVElNRU9VVCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBXYWl0IGZvciBvcGVyYXRpb24gdG8gY29tcGxldGUgdmlhIFNpZ25hbFIgbm90aWZpY2F0aW9uXHJcbiAgICogUmV0dXJucyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBub3RpZmljYXRpb24gd2l0aCBtYXRjaGluZyBjb3JyZWxhdGlvbklkIGlzIHJlY2VpdmVkXHJcbiAgICovXHJcbiAgd2FpdEZvck9wZXJhdGlvbihjb3JyZWxhdGlvbklkOiBzdHJpbmcsIHRpbWVvdXRNczogbnVtYmVyID0gU0lHTkFMUl9DT05GSUcuREVGQVVMVF9USU1FT1VUKTogT2JzZXJ2YWJsZTxDcnVkTm90aWZpY2F0aW9uPiB7XHJcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25Db21wbGV0ZWQkLnBpcGUoXHJcbiAgICAgIGZpbHRlcigobm90aWZpY2F0aW9uKSA9PiBub3RpZmljYXRpb24uY29ycmVsYXRpb25JZCA9PT0gY29ycmVsYXRpb25JZCksXHJcbiAgICAgIHRha2UoMSksXHJcbiAgICAgIHRpbWVvdXQodGltZW91dE1zKSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAvLyBDbGVhbnVwIG9uIHRpbWVvdXRcclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShjb3JyZWxhdGlvbklkKTtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoJ09wZXJhdGlvbiB0aW1lZCBvdXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgaW5jb21pbmcgU2lnbmFsUiBub3RpZmljYXRpb25cclxuICAgKiBDYWxsZWQgYnkgU2lnbmFsUlNlcnZpY2Ugd2hlbiBub3RpZmljYXRpb24gaXMgcmVjZWl2ZWRcclxuICAgKi9cclxuICBoYW5kbGVOb3RpZmljYXRpb24obm90aWZpY2F0aW9uOiBDcnVkTm90aWZpY2F0aW9uKTogdm9pZCB7XHJcbiAgICBjb25zdCBvcGVyYXRpb24gPSB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmdldChub3RpZmljYXRpb24uY29ycmVsYXRpb25JZCk7XHJcblxyXG4gICAgaWYgKG9wZXJhdGlvbikge1xyXG4gICAgICAvLyBFbWl0IHRvIG9ic2VydmVycyB3YWl0aW5nIGZvciB0aGlzIG9wZXJhdGlvblxyXG4gICAgICB0aGlzLm9wZXJhdGlvbkNvbXBsZXRlZCQubmV4dChub3RpZmljYXRpb24pO1xyXG5cclxuICAgICAgLy8gQ2xlYW51cFxyXG4gICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShub3RpZmljYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiBvcGVyYXRpb24gaXMgcGVuZGluZ1xyXG4gICAqL1xyXG4gIGlzUGVuZGluZyhjb3JyZWxhdGlvbklkOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhjb3JyZWxhdGlvbklkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBwZW5kaW5nIG9wZXJhdGlvbnMgY291bnQgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0UGVuZGluZ0NvdW50KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5zaXplO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFsbCBwZW5kaW5nIG9wZXJhdGlvbnMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWxsUGVuZGluZygpOiBQZW5kaW5nT3BlcmF0aW9uW10ge1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5wZW5kaW5nT3BlcmF0aW9ucy52YWx1ZXMoKSk7XHJcbiAgfVxyXG59Il19
@@ -1,252 +0,0 @@
1
- import { inject, Injectable, signal } from '@angular/core';
2
- import * as signalR from '@microsoft/signalr';
3
- import { Subject } from 'rxjs';
4
- import { Common } from '../../../app/constants/common';
5
- import { SIGNALR_HUB_METHODS, SIGNALR_EVENTS, CRUD_OPERATION, CONNECTION_STATE, } from '../../../app/interfaces/signalr.interface';
6
- import { StorageConstants } from '../../../app/constants/storage-constants';
7
- import { SessionStorageService } from '../../../auth/session-storage.service';
8
- import { LocalStorageService } from '../../../auth/local-storage.service';
9
- import * as i0 from "@angular/core";
10
- /**
11
- * SignalR Infrastructure Service
12
- * Handles low-level WebSocket connection, group management, and reconnection
13
- * Internal use only - components should use SignalRService instead
14
- */
15
- export class SignalRInfrastructure {
16
- constructor() {
17
- this.hubConnection = null;
18
- // Session storage
19
- this.sessionStorageService = inject(SessionStorageService);
20
- // local storage
21
- this.localStorageService = inject(LocalStorageService);
22
- // Connection state as signal
23
- this.connectionState = signal(CONNECTION_STATE.DISCONNECTED);
24
- // Notification stream (internal - emits to SignalRService)
25
- this.notifications$ = new Subject();
26
- // Track active groups to rejoin after reconnection
27
- this.activeGroups = new Set();
28
- }
29
- /**
30
- * Helper method to get value from storage
31
- * @param type The type of storage, 'Session' or 'Local'
32
- * @param key The key to retrieve the value for
33
- * @returns The value from storage, or null if not available
34
- */
35
- getFromStorage(type, key) {
36
- try {
37
- let info = null;
38
- if (type === 'Session') {
39
- // Get value from session storage
40
- info = this.sessionStorageService.getSessionStorage(key);
41
- }
42
- if (type === 'Local') {
43
- // Get value from local storage
44
- info = this.localStorageService.getLocalStorage(key);
45
- }
46
- if (info && typeof info === 'string') {
47
- // Parse the value if it's a string
48
- info = JSON.parse(info);
49
- }
50
- return info;
51
- }
52
- catch (error) {
53
- // Log error if failed to get value from storage
54
- console.warn('Failed to get current app ID from session:', error);
55
- return null;
56
- }
57
- }
58
- get appId() {
59
- const appInfo = this.getFromStorage('Session', StorageConstants.appInfo);
60
- return appInfo?.Id || null;
61
- }
62
- get environmentId() {
63
- const envInfo = this.getFromStorage('Session', StorageConstants.environmentInfo);
64
- return envInfo?.Id || null;
65
- }
66
- get tenantId() {
67
- const tenantInfo = this.getFromStorage('Local', StorageConstants.orgInfo);
68
- return tenantInfo?.Id || null;
69
- }
70
- get token() {
71
- const authInfo = this.getFromStorage('Local', StorageConstants.tokenInfo);
72
- return authInfo?.token || null;
73
- }
74
- /**
75
- * Connect to SignalR hub
76
- */
77
- async connect() {
78
- if (this.hubConnection?.state === signalR.HubConnectionState.Connected) {
79
- return;
80
- }
81
- // Get hub URL from Common (set during app initialization via Common.init())
82
- const hubUrl = Common.signalRHubUrl;
83
- if (!hubUrl) {
84
- console.error('[SignalR] Hub URL not configured. Make sure Common.init() is called with environment.');
85
- return;
86
- }
87
- try {
88
- this.connectionState.set(CONNECTION_STATE.CONNECTING);
89
- this.hubConnection = new signalR.HubConnectionBuilder()
90
- .withUrl(hubUrl, {
91
- accessTokenFactory: () => this.token || '',
92
- skipNegotiation: false,
93
- transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.ServerSentEvents,
94
- })
95
- .withAutomaticReconnect({
96
- nextRetryDelayInMilliseconds: (retryContext) => {
97
- // Exponential backoff: 0s, 2s, 10s, 30s, max 60s
98
- if (retryContext.elapsedMilliseconds < 60000) {
99
- return Math.min(1000 * Math.pow(2, retryContext.previousRetryCount), 60000);
100
- }
101
- return null; // Stop retrying after 1 minute
102
- },
103
- })
104
- .configureLogging(signalR.LogLevel.Information)
105
- .build();
106
- this.registerEventHandlers();
107
- this.registerConnectionLifecycle();
108
- await this.hubConnection.start();
109
- this.connectionState.set(CONNECTION_STATE.CONNECTED);
110
- }
111
- catch (error) {
112
- this.connectionState.set(CONNECTION_STATE.FAILED);
113
- // Retry after 1 minute
114
- setTimeout(() => this.connect(), 60 * 1000);
115
- }
116
- }
117
- /**
118
- * Register SignalR event handlers for CRUD notifications
119
- */
120
- registerEventHandlers() {
121
- if (!this.hubConnection)
122
- return;
123
- // INSERT notifications
124
- this.hubConnection.on(SIGNALR_EVENTS.INSERT_COMPLETED, (notification) => {
125
- const enriched = { ...notification, operation: CRUD_OPERATION.INSERT, receivedAt: new Date() };
126
- this.notifications$.next(enriched);
127
- });
128
- // UPDATE notifications
129
- this.hubConnection.on(SIGNALR_EVENTS.UPDATE_COMPLETED, (notification) => {
130
- const enriched = { ...notification, operation: CRUD_OPERATION.UPDATE, receivedAt: new Date() };
131
- this.notifications$.next(enriched);
132
- });
133
- // DELETE notifications
134
- this.hubConnection.on(SIGNALR_EVENTS.DELETE_COMPLETED, (notification) => {
135
- const enriched = { ...notification, operation: CRUD_OPERATION.DELETE, receivedAt: new Date() };
136
- this.notifications$.next(enriched);
137
- });
138
- }
139
- /**
140
- * Register connection lifecycle handlers
141
- */
142
- registerConnectionLifecycle() {
143
- if (!this.hubConnection)
144
- return;
145
- this.hubConnection.onreconnecting(() => {
146
- this.connectionState.set(CONNECTION_STATE.RECONNECTING);
147
- });
148
- this.hubConnection.onreconnected(() => {
149
- this.connectionState.set(CONNECTION_STATE.CONNECTED);
150
- // Rejoin all groups after reconnection
151
- this.rejoinGroups();
152
- });
153
- this.hubConnection.onclose(() => {
154
- this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
155
- // Try to reconnect
156
- setTimeout(() => this.connect(), 60 * 1000);
157
- });
158
- }
159
- /**
160
- * Join SignalR group for an AppObject
161
- */
162
- async joinGroup(appObjectId) {
163
- if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
164
- return;
165
- }
166
- try {
167
- if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
168
- return;
169
- }
170
- await this.hubConnection.invoke(SIGNALR_HUB_METHODS.JOIN_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
171
- // Track this group for reconnection
172
- this.activeGroups.add(appObjectId);
173
- }
174
- catch (error) {
175
- console.error(`[SignalR] Failed to join group: ${appObjectId}`, error);
176
- }
177
- }
178
- /**
179
- * Leave SignalR group
180
- */
181
- async leaveGroup(appObjectId) {
182
- if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
183
- // Remove from tracking even if not connected
184
- this.activeGroups.delete(appObjectId);
185
- return;
186
- }
187
- if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
188
- return;
189
- }
190
- try {
191
- await this.hubConnection.invoke(SIGNALR_HUB_METHODS.LEAVE_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
192
- // Remove from tracking
193
- this.activeGroups.delete(appObjectId);
194
- }
195
- catch (error) {
196
- console.error(`[SignalR] Failed to leave group: ${appObjectId}`, error);
197
- }
198
- }
199
- /**
200
- * Rejoin all active groups after reconnection
201
- * This ensures components continue receiving notifications after network interruption
202
- */
203
- async rejoinGroups() {
204
- if (this.activeGroups.size === 0) {
205
- return;
206
- }
207
- // Get list of groups to rejoin
208
- const groups = Array.from(this.activeGroups);
209
- // Clear the set (will be re-added during joinGroup)
210
- this.activeGroups.clear();
211
- // Rejoin each group
212
- for (const appObjectId of groups) {
213
- await this.joinGroup(appObjectId);
214
- }
215
- }
216
- /**
217
- * Check if connected
218
- */
219
- isConnected() {
220
- return this.hubConnection?.state === signalR.HubConnectionState.Connected;
221
- }
222
- /**
223
- * Disconnect from SignalR hub (cleanup)
224
- */
225
- async disconnect() {
226
- if (this.hubConnection) {
227
- try {
228
- await this.hubConnection.stop();
229
- this.hubConnection = null;
230
- this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
231
- }
232
- catch (error) {
233
- console.error('[SignalR] Error during disconnect:', error);
234
- }
235
- }
236
- }
237
- /**
238
- * Get active groups (for debugging)
239
- */
240
- getActiveGroups() {
241
- return Array.from(this.activeGroups);
242
- }
243
- static { this.ɵfac = function SignalRInfrastructure_Factory(t) { return new (t || SignalRInfrastructure)(); }; }
244
- static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRInfrastructure, factory: SignalRInfrastructure.ɵfac, providedIn: 'root' }); }
245
- }
246
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRInfrastructure, [{
247
- type: Injectable,
248
- args: [{
249
- providedIn: 'root',
250
- }]
251
- }], null, null); })();
252
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFHTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQs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YixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7c0ZBdFJVLHFCQUFxQjt1RUFBckIscUJBQXFCLFdBQXJCLHFCQUFxQixtQkFGcEIsTUFBTTs7aUZBRVAscUJBQXFCO2NBSGpDLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIHNpZ25hbFIgZnJvbSAnQG1pY3Jvc29mdC9zaWduYWxyJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBDb21tb24gfSBmcm9tICcuLi8uLi8uLi9hcHAvY29uc3RhbnRzL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29ubmVjdGlvblN0YXRlLFxyXG4gIENydWROb3RpZmljYXRpb24sXHJcbiAgU0lHTkFMUl9IVUJfTUVUSE9EUyxcclxuICBTSUdOQUxSX0VWRU5UUyxcclxuICBDUlVEX09QRVJBVElPTixcclxuICBDT05ORUNUSU9OX1NUQVRFLFxyXG59IGZyb20gJy4uLy4uLy4uL2FwcC9pbnRlcmZhY2VzL3NpZ25hbHIuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgU3RvcmFnZUNvbnN0YW50cyB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvc3RvcmFnZS1jb25zdGFudHMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hdXRoL3Nlc3Npb24tc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTG9jYWxTdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvbG9jYWwtc3RvcmFnZS5zZXJ2aWNlJztcclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIEluZnJhc3RydWN0dXJlIFNlcnZpY2VcclxuICogSGFuZGxlcyBsb3ctbGV2ZWwgV2ViU29ja2V0IGNvbm5lY3Rpb24sIGdyb3VwIG1hbmFnZW1lbnQsIGFuZCByZWNvbm5lY3Rpb25cclxuICogSW50ZXJuYWwgdXNlIG9ubHkgLSBjb21wb25lbnRzIHNob3VsZCB1c2UgU2lnbmFsUlNlcnZpY2UgaW5zdGVhZFxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNpZ25hbFJJbmZyYXN0cnVjdHVyZSB7XHJcbiAgcHJpdmF0ZSBodWJDb25uZWN0aW9uOiBzaWduYWxSLkh1YkNvbm5lY3Rpb24gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gU2Vzc2lvbiBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KFNlc3Npb25TdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIGxvY2FsIHN0b3JhZ2VcclxuICByZWFkb25seSBsb2NhbFN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KExvY2FsU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBDb25uZWN0aW9uIHN0YXRlIGFzIHNpZ25hbFxyXG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25TdGF0ZSA9IHNpZ25hbDxDb25uZWN0aW9uU3RhdGU+KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgLy8gTm90aWZpY2F0aW9uIHN0cmVhbSAoaW50ZXJuYWwgLSBlbWl0cyB0byBTaWduYWxSU2VydmljZSlcclxuICByZWFkb25seSBub3RpZmljYXRpb25zJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIFRyYWNrIGFjdGl2ZSBncm91cHMgdG8gcmVqb2luIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gIHByaXZhdGUgYWN0aXZlR3JvdXBzID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHN0b3JhZ2UsICdTZXNzaW9uJyBvciAnTG9jYWwnXHJcbiAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3JcclxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgZnJvbSBzdG9yYWdlLCBvciBudWxsIGlmIG5vdCBhdmFpbGFibGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldEZyb21TdG9yYWdlKHR5cGU6IHN0cmluZywga2V5OiBzdHJpbmcpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBpbmZvOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdTZXNzaW9uJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIHNlc3Npb24gc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLnNlc3Npb25TdG9yYWdlU2VydmljZS5nZXRTZXNzaW9uU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ0xvY2FsJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldExvY2FsU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaW5mbyAmJiB0eXBlb2YgaW5mbyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAvLyBQYXJzZSB0aGUgdmFsdWUgaWYgaXQncyBhIHN0cmluZ1xyXG4gICAgICAgIGluZm8gPSBKU09OLnBhcnNlKGluZm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gaW5mbztcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIC8vIExvZyBlcnJvciBpZiBmYWlsZWQgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBnZXQgY3VycmVudCBhcHAgSUQgZnJvbSBzZXNzaW9uOicsIGVycm9yKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwSWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhcHBJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuYXBwSW5mbyk7XHJcbiAgICByZXR1cm4gYXBwSW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBlbnZpcm9ubWVudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgZW52SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmVudmlyb25tZW50SW5mbyk7XHJcbiAgICByZXR1cm4gZW52SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0ZW5hbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IHRlbmFudEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMub3JnSW5mbyk7XHJcbiAgICByZXR1cm4gdGVuYW50SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0b2tlbigpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGF1dGhJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLnRva2VuSW5mbyk7XHJcbiAgICByZXR1cm4gYXV0aEluZm8/LnRva2VuIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25uZWN0IHRvIFNpZ25hbFIgaHViXHJcbiAgICovXHJcbiAgYXN5bmMgY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmh1YkNvbm5lY3Rpb24/LnN0YXRlID09PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBodWIgVVJMIGZyb20gQ29tbW9uIChzZXQgZHVyaW5nIGFwcCBpbml0aWFsaXphdGlvbiB2aWEgQ29tbW9uLmluaXQoKSlcclxuICAgIGNvbnN0IGh1YlVybCA9IENvbW1vbi5zaWduYWxSSHViVXJsO1xyXG5cclxuICAgIGlmICghaHViVXJsKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tTaWduYWxSXSBIdWIgVVJMIG5vdCBjb25maWd1cmVkLiBNYWtlIHN1cmUgQ29tbW9uLmluaXQoKSBpcyBjYWxsZWQgd2l0aCBlbnZpcm9ubWVudC4nKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RJTkcpO1xyXG5cclxuICAgICAgdGhpcy5odWJDb25uZWN0aW9uID0gbmV3IHNpZ25hbFIuSHViQ29ubmVjdGlvbkJ1aWxkZXIoKVxyXG4gICAgICAgIC53aXRoVXJsKGh1YlVybCwge1xyXG4gICAgICAgICAgYWNjZXNzVG9rZW5GYWN0b3J5OiAoKSA9PiB0aGlzLnRva2VuIHx8ICcnLFxyXG4gICAgICAgICAgc2tpcE5lZ290aWF0aW9uOiBmYWxzZSxcclxuICAgICAgICAgIHRyYW5zcG9ydDogc2lnbmFsUi5IdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzIHwgc2lnbmFsUi5IdHRwVHJhbnNwb3J0VHlwZS5TZXJ2ZXJTZW50RXZlbnRzLFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLndpdGhBdXRvbWF0aWNSZWNvbm5lY3Qoe1xyXG4gICAgICAgICAgbmV4dFJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kczogKHJldHJ5Q29udGV4dDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEV4cG9uZW50aWFsIGJhY2tvZmY6IDBzLCAycywgMTBzLCAzMHMsIG1heCA2MHNcclxuICAgICAgICAgICAgaWYgKHJldHJ5Q29udGV4dC5lbGFwc2VkTWlsbGlzZWNvbmRzIDwgNjAwMDApIHtcclxuICAgICAgICAgICAgICByZXR1cm4gTWF0aC5taW4oMTAwMCAqIE1hdGgucG93KDIsIHJldHJ5Q29udGV4dC5wcmV2aW91c1JldHJ5Q291bnQpLCA2MDAwMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFN0b3AgcmV0cnlpbmcgYWZ0ZXIgMSBtaW51dGVcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgICAuY29uZmlndXJlTG9nZ2luZyhzaWduYWxSLkxvZ0xldmVsLkluZm9ybWF0aW9uKVxyXG4gICAgICAgIC5idWlsZCgpO1xyXG5cclxuICAgICAgdGhpcy5yZWdpc3RlckV2ZW50SGFuZGxlcnMoKTtcclxuICAgICAgdGhpcy5yZWdpc3RlckNvbm5lY3Rpb25MaWZlY3ljbGUoKTtcclxuXHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdGFydCgpO1xyXG5cclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkZBSUxFRCk7XHJcblxyXG4gICAgICAvLyBSZXRyeSBhZnRlciAxIG1pbnV0ZVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY29ubmVjdCgpLCA2MCAqIDEwMDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgU2lnbmFsUiBldmVudCBoYW5kbGVycyBmb3IgQ1JVRCBub3RpZmljYXRpb25zXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWdpc3RlckV2ZW50SGFuZGxlcnMoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbikgcmV0dXJuO1xyXG5cclxuICAgIC8vIElOU0VSVCBub3RpZmljYXRpb25zXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub24oU0lHTkFMUl9FVkVOVFMuSU5TRVJUX0NPTVBMRVRFRCwgKG5vdGlmaWNhdGlvbjogQ3J1ZE5vdGlmaWNhdGlvbikgPT4ge1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAobm90aWZpY2F0aW9uOiBDcnVkTm90aWZpY2F0aW9uKSA9PiB7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uVVBEQVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBERUxFVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLkRFTEVURV9DT01QTEVURUQsIChub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pID0+IHtcclxuICAgICAgY29uc3QgZW5yaWNoZWQgPSB7IC4uLm5vdGlmaWNhdGlvbiwgb3BlcmF0aW9uOiBDUlVEX09QRVJBVElPTi5ERUxFVEUsIHJlY2VpdmVkQXQ6IG5ldyBEYXRlKCkgfTtcclxuICAgICAgdGhpcy5ub3RpZmljYXRpb25zJC5uZXh0KGVucmljaGVkKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgY29ubmVjdGlvbiBsaWZlY3ljbGUgaGFuZGxlcnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyQ29ubmVjdGlvbkxpZmVjeWNsZSgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0aW5nKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuUkVDT05ORUNUSU5HKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbnJlY29ubmVjdGVkKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEKTtcclxuXHJcbiAgICAgIC8vIFJlam9pbiBhbGwgZ3JvdXBzIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gICAgICB0aGlzLnJlam9pbkdyb3VwcygpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uY2xvc2UoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gVHJ5IHRvIHJlY29ubmVjdFxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY29ubmVjdCgpLCA2MCAqIDEwMDApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBKb2luIFNpZ25hbFIgZ3JvdXAgZm9yIGFuIEFwcE9iamVjdFxyXG4gICAqL1xyXG4gIGFzeW5jIGpvaW5Hcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuSk9JTl9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBUcmFjayB0aGlzIGdyb3VwIGZvciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuYWRkKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gam9pbiBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMZWF2ZSBTaWduYWxSIGdyb3VwXHJcbiAgICovXHJcbiAgYXN5bmMgbGVhdmVHcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZyBldmVuIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkxFQVZFX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGxlYXZlIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlam9pbiBhbGwgYWN0aXZlIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgKiBUaGlzIGVuc3VyZXMgY29tcG9uZW50cyBjb250aW51ZSByZWNlaXZpbmcgbm90aWZpY2F0aW9ucyBhZnRlciBuZXR3b3JrIGludGVycnVwdGlvblxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVqb2luR3JvdXBzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBzLnNpemUgPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBsaXN0IG9mIGdyb3VwcyB0byByZWpvaW5cclxuICAgIGNvbnN0IGdyb3VwcyA9IEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG5cclxuICAgIC8vIENsZWFyIHRoZSBzZXQgKHdpbGwgYmUgcmUtYWRkZWQgZHVyaW5nIGpvaW5Hcm91cClcclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcblxyXG4gICAgLy8gUmVqb2luIGVhY2ggZ3JvdXBcclxuICAgIGZvciAoY29uc3QgYXBwT2JqZWN0SWQgb2YgZ3JvdXBzKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuam9pbkdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2Nvbm5lY3QgZnJvbSBTaWduYWxSIGh1YiAoY2xlYW51cClcclxuICAgKi9cclxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgICAgdGhpcy5odWJDb25uZWN0aW9uID0gbnVsbDtcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tTaWduYWxSXSBFcnJvciBkdXJpbmcgZGlzY29ubmVjdDonLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhY3RpdmUgZ3JvdXBzIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldEFjdGl2ZUdyb3VwcygpOiBzdHJpbmdbXSB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmFjdGl2ZUdyb3Vwcyk7XHJcbiAgfVxyXG59Il19