@nlabs/rip-hunter 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,46 @@
1
+ # Rip Hunter: AI Coding Guidelines
2
+
3
+ ## Project Overview
4
+ Rip Hunter is an ESM-first TypeScript HTTP client library supporting REST APIs, GraphQL queries/mutations/subscriptions, and Server-Sent Events (SSE). Key features include request caching, deduplication, timeouts, and automatic reconnection for real-time features.
5
+
6
+ ## Architecture
7
+ - **Core Exports**: `get`, `post`, `put`, `del`, `ajax` for REST; `query`, `mutation`, `subscribe` for GraphQL; `subscribeSSE` for SSE
8
+ - **Error Handling**: Use `ApiError` class from `./errors/ApiError.js` - extends Error with `source` and `errors` array
9
+ - **Request Deduplication**: Automatic via `requestCache` Map using base64-encoded keys from method/URL/params/options
10
+ - **Caching**: GET requests cached by default when `cache: true` in options
11
+ - **Real-time**: GraphQL subscriptions use WebSocket with `graphql-ws` protocol; SSE uses EventSource (install `eventsource` for Node.js)
12
+
13
+ ## Development Workflow
14
+ - **Build**: `npm run build` (lex compile --remove) outputs to `lib/` with .d.ts declarations
15
+ - **Test**: `npm run test` (lex test) uses Jest with @nlabs/fetch-mock; reset mocks in beforeEach/afterEach
16
+ - **Lint**: `npm run lint` (lex lint --fix) enforces code style
17
+ - **Benchmark**: `npm run benchmark` tests utility function performance
18
+
19
+ ## Code Patterns
20
+ - **Imports**: Use ESM imports with `.js` extensions (e.g., `import { get } from './index.js'`)
21
+ - **TypeScript**: Interfaces prefixed with `Hunter*Type` (e.g., `HunterOptionsType`)
22
+ - **Utilities**: `toGql()` converts objects to GraphQL literals; `queryString()` encodes URL params; `removeSpaces()` cleans GraphQL strings
23
+ - **Options**: Pass `token` for auth, `timeout` in ms, `variables` for GraphQL, `headers` as Headers object
24
+ - **GraphQL Variables**: Use `variables` object; convert to GQL with `toGql(input)` in mutations
25
+ - **Subscriptions**: Return unsubscribe function; handle `onNext`, `onError`, `onComplete`, `onReconnect`
26
+
27
+ ## Examples
28
+ ```typescript
29
+ // REST with caching
30
+ const data = await get(url, params, { cache: true, token: 'jwt' });
31
+
32
+ // GraphQL query
33
+ const result = await query(url, '{ user { id name } }', { timeout: 10000 });
34
+
35
+ // Subscription
36
+ const unsubscribe = subscribe(wsUrl, 'subscription { userUpdated { id name } }', {
37
+ onNext: data => console.log(data.userUpdated)
38
+ }, { token: 'jwt', maxReconnectAttempts: 10 });
39
+ ```
40
+
41
+ ## Key Files
42
+ - `src/index.ts`: Main implementation with all exports
43
+ - `src/errors/ApiError.ts`: Custom error class
44
+ - `src/index.test.ts`: Comprehensive Jest tests with fetch mocking
45
+ - `package.json`: ESM exports for main and errors subpaths</content>
46
+ <parameter name="filePath">/Users/nitrog7/Development/rip-hunter/.github/copilot-instructions.md
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  ---
15
15
 
16
- ## 🚀 Why rip-hunter?
16
+ ## Why rip-hunter?
17
17
 
18
18
  - **Unified API**: One package for both REST and GraphQL endpoints
19
19
  - **ESM & TypeScript Native**: Modern, type-safe, and tree-shakable
@@ -25,10 +25,11 @@
25
25
  - **Timeout Support**: Configurable request timeouts
26
26
  - **Request Deduplication**: Prevents duplicate requests
27
27
  - **Real-time Updates**: Server-Sent Events (SSE) support
28
+ - **GraphQL Subscriptions**: WebSocket-based subscriptions with automatic reconnection
28
29
 
29
30
  ---
30
31
 
31
- ## 📦 Installation
32
+ ## Installation
32
33
 
33
34
  ```bash
34
35
  npm install @nlabs/rip-hunter
@@ -77,6 +78,50 @@ const mutationGql = `mutation { createUser(input: ${toGql(input)}) { id name } }
77
78
  const created = await mutation(url, mutationGql, { timeout: 5000 });
78
79
  ```
79
80
 
81
+ ### GraphQL Subscription Example
82
+
83
+ ```js
84
+ import { subscribe } from '@nlabs/rip-hunter';
85
+
86
+ // Subscribe to real-time GraphQL updates
87
+ const unsubscribe = subscribe(
88
+ 'wss://api.example.com/graphql',
89
+ `
90
+ subscription {
91
+ userUpdated {
92
+ id
93
+ name
94
+ email
95
+ }
96
+ }
97
+ `,
98
+ {
99
+ onNext: (data) => {
100
+ console.log('User updated:', data.userUpdated);
101
+ },
102
+ onError: (error) => {
103
+ console.error('Subscription error:', error);
104
+ },
105
+ onComplete: () => {
106
+ console.log('Subscription completed');
107
+ },
108
+ onReconnect: (attempt) => {
109
+ console.log(`Reconnecting... (attempt ${attempt})`);
110
+ }
111
+ },
112
+ {
113
+ token: 'your_jwt_token',
114
+ variables: { userId: '123' },
115
+ connectionParams: { clientId: 'my-client' },
116
+ maxReconnectAttempts: 10,
117
+ reconnectInterval: 1000
118
+ }
119
+ );
120
+
121
+ // Later, to unsubscribe:
122
+ unsubscribe();
123
+ ```
124
+
80
125
  ### SSE Example
81
126
 
82
127
  ```js
@@ -178,6 +223,27 @@ Send a GraphQL mutation.
178
223
  - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }`
179
224
  - **Returns**: `Promise<any>`
180
225
 
226
+ #### `subscribe(url, query, callbacks, options?)`
227
+
228
+ Subscribe to a GraphQL subscription over WebSocket (graphql-ws protocol).
229
+
230
+ - **url**: `string` – WebSocket URL (ws:// or wss://)
231
+ - **query**: `string` – GraphQL subscription query string
232
+ - **callbacks**: `HunterSubscriptionCallbackType` – Event handlers
233
+ - `onNext?: (data: any) => void` – Called when new data arrives
234
+ - `onError?: (error: Error | Event) => void` – Called on errors
235
+ - `onComplete?: () => void` – Called when subscription completes
236
+ - `onReconnect?: (attempt: number) => void` – Called during reconnection attempts
237
+ - **options**: `HunterSubscriptionOptionsType`
238
+ - `token?: string` – Authentication token
239
+ - `variables?: Record<string, unknown>` – GraphQL variables
240
+ - `connectionParams?: Record<string, unknown>` – WebSocket connection parameters
241
+ - `maxReconnectAttempts?: number` – Maximum reconnection attempts (default: 5)
242
+ - `reconnectInterval?: number` – Delay between reconnection attempts in ms (default: 1000)
243
+ - `timeout?: number` – Connection timeout
244
+ - `headers?: Headers` – Custom headers
245
+ - **Returns**: `() => void` – Unsubscribe function
246
+
181
247
  #### `graphqlQuery(url, query, options?)`
182
248
 
183
249
  Low-level GraphQL request.
@@ -254,7 +320,7 @@ All errors are wrapped in a consistent `ApiError` object for easy handling.
254
320
 
255
321
  ---
256
322
 
257
- ## 💡 Advanced Usage
323
+ ## Advanced Usage
258
324
 
259
325
  ### Request Caching
260
326
 
@@ -319,7 +385,7 @@ const unsubscribe = subscribeSSE('/api/notifications', {
319
385
 
320
386
  ---
321
387
 
322
- ## 🚀 Performance Features
388
+ ## Performance Features
323
389
 
324
390
  - **Request Deduplication**: Prevents duplicate requests to the same endpoint
325
391
  - **Built-in Caching**: Automatic caching for GET requests with 5-minute TTL
@@ -330,7 +396,7 @@ const unsubscribe = subscribeSSE('/api/notifications', {
330
396
 
331
397
  ---
332
398
 
333
- ## 🌐 Environment Support
399
+ ## Environment Support
334
400
 
335
401
  - **Browser**: Full support for all features including SSE
336
402
  - **Node.js**: Full REST/GraphQL support, SSE requires `eventsource` package
@@ -338,11 +404,11 @@ const unsubscribe = subscribeSSE('/api/notifications', {
338
404
 
339
405
  ---
340
406
 
341
- ## 🤝 Contributing
407
+ ## Contributing
342
408
 
343
409
  PRs and issues welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
344
410
 
345
- ## 📄 License
411
+ ## License
346
412
 
347
413
  MIT © Nitrogen Labs, Inc.
348
414
 
@@ -7,3 +7,4 @@ export declare class ApiError extends Error {
7
7
  errors: string[];
8
8
  constructor(list: any, error: any);
9
9
  }
10
+ //# sourceMappingURL=ApiError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiError.d.ts","sourceRoot":"","sources":["../../src/errors/ApiError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,MAAM,EAAE,KAAK,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;gBAEL,IAAI,KAAA,EAAE,KAAK,KAAA;CAKxB"}
@@ -1,2 +1,14 @@
1
- class t extends Error{source;errors;constructor(r,s){super("API Error"),this.source=s,this.errors=r?r.map(o=>o.message):[]}}export{t as ApiError};
2
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2Vycm9ycy9BcGlFcnJvci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTctUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBBcGlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgc291cmNlOiBFcnJvcjtcbiAgZXJyb3JzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihsaXN0LCBlcnJvcikge1xuICAgIHN1cGVyKCdBUEkgRXJyb3InKTtcbiAgICB0aGlzLnNvdXJjZSA9IGVycm9yO1xuICAgIHRoaXMuZXJyb3JzID0gbGlzdCA/IGxpc3QubWFwKChlcnJvckl0ZW06IEVycm9yKSA9PiBlcnJvckl0ZW0ubWVzc2FnZSkgOiBbXTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBSU8sTUFBTUEsVUFBaUIsS0FBTSxDQUNsQyxPQUNBLE9BRUEsWUFBWUMsRUFBTUMsRUFBTyxDQUN2QixNQUFNLFdBQVcsRUFDakIsS0FBSyxPQUFTQSxFQUNkLEtBQUssT0FBU0QsRUFBT0EsRUFBSyxJQUFLRSxHQUFxQkEsRUFBVSxPQUFPLEVBQUksQ0FBQyxDQUM1RSxDQUNGIiwKICAibmFtZXMiOiBbIkFwaUVycm9yIiwgImxpc3QiLCAiZXJyb3IiLCAiZXJyb3JJdGVtIl0KfQo=
1
+ /**
2
+ * Copyright (c) 2017-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ export class ApiError extends Error {
5
+ source;
6
+ errors;
7
+ constructor(list, error){
8
+ super('API Error');
9
+ this.source = error;
10
+ this.errors = list ? list.map((errorItem)=>errorItem.message) : [];
11
+ }
12
+ }
13
+
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JpcC1odW50ZXIvc3JjL2Vycm9ycy9BcGlFcnJvci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEFwaUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzb3VyY2U6IEVycm9yO1xuICBlcnJvcnM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKGxpc3QsIGVycm9yKSB7XG4gICAgc3VwZXIoJ0FQSSBFcnJvcicpO1xuICAgIHRoaXMuc291cmNlID0gZXJyb3I7XG4gICAgdGhpcy5lcnJvcnMgPSBsaXN0ID8gbGlzdC5tYXAoKGVycm9ySXRlbTogRXJyb3IpID0+IGVycm9ySXRlbS5tZXNzYWdlKSA6IFtdO1xuICB9XG59XG4iXSwibmFtZXMiOlsiQXBpRXJyb3IiLCJFcnJvciIsInNvdXJjZSIsImVycm9ycyIsImxpc3QiLCJlcnJvciIsIm1hcCIsImVycm9ySXRlbSIsIm1lc3NhZ2UiXSwibWFwcGluZ3MiOiJBQUFBOzs7Q0FHQyxHQUNELE9BQU8sTUFBTUEsaUJBQWlCQztJQUM1QkMsT0FBYztJQUNkQyxPQUFpQjtJQUVqQixZQUFZQyxJQUFJLEVBQUVDLEtBQUssQ0FBRTtRQUN2QixLQUFLLENBQUM7UUFDTixJQUFJLENBQUNILE1BQU0sR0FBR0c7UUFDZCxJQUFJLENBQUNGLE1BQU0sR0FBR0MsT0FBT0EsS0FBS0UsR0FBRyxDQUFDLENBQUNDLFlBQXFCQSxVQUFVQyxPQUFPLElBQUksRUFBRTtJQUM3RTtBQUNGIn0=
package/lib/index.d.ts CHANGED
@@ -32,6 +32,21 @@ export interface HunterSSECallbackType {
32
32
  onError?: (error: Error | Event) => void;
33
33
  onRetry?: (attempt: number, delay: number) => void;
34
34
  }
35
+ export interface HunterSubscriptionOptionsType {
36
+ readonly headers?: Headers;
37
+ readonly token?: string;
38
+ readonly variables?: Record<string, unknown>;
39
+ readonly connectionParams?: Record<string, unknown>;
40
+ readonly reconnectInterval?: number;
41
+ readonly maxReconnectAttempts?: number;
42
+ readonly timeout?: number;
43
+ }
44
+ export interface HunterSubscriptionCallbackType {
45
+ onNext?: (data: any) => void;
46
+ onError?: (error: Error | Event) => void;
47
+ onComplete?: () => void;
48
+ onReconnect?: (attempt: number) => void;
49
+ }
35
50
  export declare const removeSpaces: (str: string) => string;
36
51
  export declare const queryString: (json: any) => string;
37
52
  export declare const ajax: (url: string, method: string, params?: any, options?: HunterOptionsType) => Promise<any>;
@@ -43,5 +58,7 @@ export declare const toGql: (obj: any) => string;
43
58
  export declare const graphqlQuery: (url: string, query: HunterQueryType | HunterQueryType[], options?: HunterOptionsType) => Promise<any>;
44
59
  export declare const query: (url: string, body: string, options?: HunterOptionsType) => Promise<any>;
45
60
  export declare const mutation: (url: string, body: string, options?: HunterOptionsType) => Promise<any>;
61
+ export declare const subscribe: (url: string, query: string, callbacks: HunterSubscriptionCallbackType, options?: HunterSubscriptionOptionsType) => (() => void);
46
62
  export declare const subscribeSSE: (url: string, callbacks: HunterSSECallbackType, options?: HunterSSEOptionsType) => (() => void);
47
63
  export { ApiError } from './errors/ApiError.js';
64
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,2 +1,550 @@
1
- import{ApiError as l}from"./errors/ApiError.js";import{ApiError as B}from"./errors/ApiError.js";const v=e=>Array.isArray(e),q=e=>typeof e=="string",P=e=>e!==null&&typeof e=="object"&&!v(e),H=e=>e==null||e==="",C=e=>e===null,R=e=>e===void 0,w=/application\/json/i,S=new Map,A=e=>e.replace(/\s+(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/gm,""),J=e=>Object.keys(e).map(r=>`${encodeURIComponent(r)}=${encodeURIComponent(e[r])}`).join("&"),x=e=>new Promise((r,t)=>setTimeout(()=>t(new Error("Request timeout")),e)),O=(e,r,t,i)=>{const a=JSON.stringify({method:r,options:i,params:t,url:e});return btoa(a).slice(0,50)},N=(e,r)=>{if(typeof EventSource<"u")return new EventSource(e);throw new Error('EventSource not available in this environment. For Node.js support, install the "eventsource" package and import it manually.')},T=(e,r,t,i={})=>{const{headers:a,token:c,timeout:m=3e4,cache:f=!1}=i;let p=(e||"").trim();const d=(c||"").trim(),n=a||new Headers,u=(r||"GET").toUpperCase();let s;if(t&&u==="GET"?(p=`${p}?${J(t)}`,s=null):t?(n.set("Accept","application/json"),n.set("Content-Type","application/json"),s=JSON.stringify(t)):s=t,H(d)||n.set("Authorization",`Bearer ${d}`),f&&u==="GET"){const o=O(p,u,t,i),E=S.get(o);if(E)return E}const y=fetch(p,{body:s,headers:n,method:u}).then(o=>w.test(o.headers.get("Content-Type")||"")?o.json():o.text()).then(o=>o).catch(o=>(o||{}).message==="only absolute urls are supported"?Promise.reject(new l([{message:"invalid_url"}],o)):Promise.reject(new l([{message:"network_error"}],o))),g=m>0?Promise.race([y,x(m)]):y;if(f&&u==="GET"){const o=O(p,u,t,i);S.set(o,g),setTimeout(()=>S.delete(o),3e5)}return g},j=(e,r,t)=>T(e,"GET",r,t),b=(e,r,t)=>T(e,"POST",r,t),U=(e,r,t)=>T(e,"PUT",r,t),G=(e,r,t)=>T(e,"DELETE",r,t),h=e=>{if(q(e))return JSON.stringify(e);if(P(e)){const r=[];for(const i in e)if(e.hasOwnProperty(i)){const a=e[i];if(R(a)||C(a))continue;if(P(a))r.push(`${i}: ${h(a)}`);else if(v(a)){const c=a.map(m=>h(m));r.push(`${i}: [${c.join(", ")}]`)}else{const c=JSON.stringify(a);c&&r.push(`${i}: ${c}`)}}return r.join(", ")===""?'""':`{${r.join(", ")}}`}else if(v(e))return`[${e.map(r=>h(r)).join(", ")}]`;return String(e)},$=(e,r,t={})=>{const{headers:i,token:a,timeout:c=3e4}=t,m=e?e.trim():"",f=(a||"").trim(),p=i||new Headers({"Content-Type":"application/json"});H(f)||p.set("Authorization",`Bearer ${f}`);const d=fetch(m,{body:JSON.stringify(r),headers:p,method:"post"}).then(n=>w.test(n.headers.get("Content-Type")||"")&&n.body?n.json():null).catch(n=>(n||{}).message==="only absolute urls are supported"?Promise.reject(new l([{message:"invalid_url"}],n)):Promise.reject(new l([{message:"network_error"}],n))).then(n=>{if(!n||n.errors){if(n){if((n.errors||[]).some(u=>u.message==="Must provide query string."))return Promise.reject(new l([{message:"required_query"}],new Error))}else return Promise.reject(new l([{message:"api_error"}],new Error));return n.errors?Promise.reject(new l(n.errors,new Error)):{}}return n.data||{}}).catch(n=>Promise.reject(n.source?n:new l([{message:"network_error"}],n)));return c>0?Promise.race([d,x(c)]):d},I=(e,r,t={})=>$(e,{query:r},t),M=(e,r,t={})=>$(e,{query:r},t),Q=(e,r,t={})=>{const{headers:i,token:a,timeout:c=3e4,retryInterval:m=1e3,maxRetries:f=5}=t,p=(e||"").trim(),d=(a||"").trim(),n=i||new Headers;H(d)||n.set("Authorization",`Bearer ${d}`);let u=0,s=null,y=null;const g=()=>{try{s=N(p,{headers:n}),c>0&&(y=setTimeout(()=>{s&&(s.close(),r.onError&&r.onError(new Error("SSE connection timeout")))},c)),s.onopen=o=>{y&&(clearTimeout(y),y=null),u=0,r.onOpen&&r.onOpen(o)},s.onmessage=o=>{if(r.onMessage){const E={data:o.data,id:o.lastEventId,retry:o.data.includes("retry:")?parseInt(o.data.split("retry:")[1]):void 0,type:o.type};r.onMessage(E)}},s.onerror=o=>{y&&(clearTimeout(y),y=null),s&&s.readyState===EventSource.CLOSED?u<f?(u++,r.onRetry&&r.onRetry(u,m),setTimeout(g,m)):r.onError&&r.onError(new Error("SSE connection failed after max retries")):r.onError&&r.onError(o)}}catch(o){r.onError&&r.onError(o instanceof Error?o:new Error("Failed to create SSE connection"))}};return g(),()=>{y&&(clearTimeout(y),y=null),s&&(s.close(),s=null)}};export{B as ApiError,T as ajax,G as del,j as get,$ as graphqlQuery,M as mutation,b as post,U as put,I as query,J as queryString,A as removeSpaces,Q as subscribeSSE,h as toGql};
2
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuXG5pbXBvcnQge0FwaUVycm9yfSBmcm9tICcuL2Vycm9ycy9BcGlFcnJvci5qcyc7XG5cbmNvbnN0IGlzQXJyYXkgPSAodmFsdWU6IGFueSk6IHZhbHVlIGlzIGFueVtdID0+IEFycmF5LmlzQXJyYXkodmFsdWUpO1xuY29uc3QgaXNTdHJpbmcgPSAodmFsdWU6IGFueSk6IHZhbHVlIGlzIHN0cmluZyA9PiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnO1xuY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWx1ZTogYW55KTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgYW55PiA9PlxuICB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICFpc0FycmF5KHZhbHVlKTtcbmNvbnN0IGlzRW1wdHkgPSAodmFsdWU6IGFueSk6IGJvb2xlYW4gPT5cbiAgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJyc7XG5jb25zdCBpc051bGwgPSAodmFsdWU6IGFueSk6IGJvb2xlYW4gPT4gdmFsdWUgPT09IG51bGw7XG5jb25zdCBpc1VuZGVmaW5lZCA9ICh2YWx1ZTogYW55KTogYm9vbGVhbiA9PiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuXG4vLyBDYWNoZSBmb3IgY29tcGlsZWQgcmVnZXggcGF0dGVybnNcbmNvbnN0IEpTT05fQ09OVEVOVF9UWVBFX1JFR0VYID0gL2FwcGxpY2F0aW9uXFwvanNvbi9pO1xuXG4vLyBSZXF1ZXN0IGNhY2hlIGZvciBkZWR1cGxpY2F0aW9uXG5jb25zdCByZXF1ZXN0Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxhbnk+PigpO1xuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlck9wdGlvbnNUeXBlIHtcbiAgcmVhZG9ubHkgaGVhZGVycz86IEhlYWRlcnM7XG4gIHJlYWRvbmx5IHRva2VuPzogc3RyaW5nO1xuICByZWFkb25seSB2YXJpYWJsZXM/OiBhbnk7XG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNhY2hlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJRdWVyeVR5cGUge1xuICByZWFkb25seSBxdWVyeTogc3RyaW5nO1xuICByZWFkb25seSB2YXJpYWJsZXM/OiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSHVudGVyU1NFT3B0aW9uc1R5cGUge1xuICByZWFkb25seSBoZWFkZXJzPzogSGVhZGVycztcbiAgcmVhZG9ubHkgdG9rZW4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHJldHJ5SW50ZXJ2YWw/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heFJldHJpZXM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSHVudGVyU1NFRXZlbnRUeXBlIHtcbiAgcmVhZG9ubHkgZGF0YTogc3RyaW5nO1xuICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuICByZWFkb25seSByZXRyeT86IG51bWJlciB8IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJTU0VDYWxsYmFja1R5cGUge1xuICBvbk1lc3NhZ2U/OiAoZXZlbnQ6IEh1bnRlclNTRUV2ZW50VHlwZSkgPT4gdm9pZDtcbiAgb25PcGVuPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcbiAgb25FcnJvcj86IChlcnJvcjogRXJyb3IgfCBFdmVudCkgPT4gdm9pZDtcbiAgb25SZXRyeT86IChhdHRlbXB0OiBudW1iZXIsIGRlbGF5OiBudW1iZXIpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCByZW1vdmVTcGFjZXMgPSAoc3RyOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgc3RyLnJlcGxhY2UoL1xccysoPz0oPzpbXidcIl0qWydcIl1bXidcIl0qWydcIl0pKlteJ1wiXSokKS9nbSwgJycpO1xuXG5leHBvcnQgY29uc3QgcXVlcnlTdHJpbmcgPSAoanNvbjogYW55KTogc3RyaW5nID0+XG4gIE9iamVjdC5rZXlzKGpzb24pXG4gICAgLm1hcChcbiAgICAgIChrZXk6IHN0cmluZykgPT5cbiAgICAgICAgYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KGpzb25ba2V5XSl9YFxuICAgIClcbiAgICAuam9pbignJicpO1xuXG4vLyBDcmVhdGUgYSB0aW1lb3V0IHByb21pc2VcbmNvbnN0IGNyZWF0ZVRpbWVvdXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8bmV2ZXI+ID0+XG4gIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+XG4gICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKCdSZXF1ZXN0IHRpbWVvdXQnKSksIG1zKVxuICApO1xuXG4vLyBHZW5lcmF0ZSBjYWNoZSBrZXkgZm9yIHJlcXVlc3QgZGVkdXBsaWNhdGlvblxuY29uc3QgZ2VuZXJhdGVDYWNoZUtleSA9ICh1cmw6IHN0cmluZywgbWV0aG9kOiBzdHJpbmcsIHBhcmFtcz86IGFueSwgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlKTogc3RyaW5nID0+IHtcbiAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkoe21ldGhvZCwgb3B0aW9ucywgcGFyYW1zLCB1cmx9KTtcbiAgcmV0dXJuIGJ0b2Eoa2V5KS5zbGljZSgwLCA1MCk7IC8vIFRydW5jYXRlIHRvIHJlYXNvbmFibGUgbGVuZ3RoXG59O1xuXG4vLyBTU0UgRXZlbnRTb3VyY2UgcG9seWZpbGwgZm9yIE5vZGUuanNcbmNvbnN0IGNyZWF0ZUV2ZW50U291cmNlID0gKHVybDogc3RyaW5nLCBvcHRpb25zPzogSHVudGVyU1NFT3B0aW9uc1R5cGUpOiBFdmVudFNvdXJjZSA9PiB7XG4gIGlmKHR5cGVvZiBFdmVudFNvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50U291cmNlKHVybCk7XG4gIH1cblxuICAvLyBGb3IgTm9kZS5qcywgd2UnbGwgdGhyb3cgYW4gZXJyb3Igc3VnZ2VzdGluZyB0aGUgdXNlciBpbnN0YWxsIGV2ZW50c291cmNlXG4gIHRocm93IG5ldyBFcnJvcignRXZlbnRTb3VyY2Ugbm90IGF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50LiBGb3IgTm9kZS5qcyBzdXBwb3J0LCBpbnN0YWxsIHRoZSBcImV2ZW50c291cmNlXCIgcGFja2FnZSBhbmQgaW1wb3J0IGl0IG1hbnVhbGx5LicpO1xufTtcblxuLy8gQUpBWFxuZXhwb3J0IGNvbnN0IGFqYXggPSAoXG4gIHVybDogc3RyaW5nLFxuICBtZXRob2Q6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9uczogSHVudGVyT3B0aW9uc1R5cGUgPSB7fVxuKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgY29uc3Qge2hlYWRlcnMsIHRva2VuLCB0aW1lb3V0ID0gMzAwMDAsIGNhY2hlID0gZmFsc2V9ID0gb3B0aW9ucztcblxuICBsZXQgZm9ybWF0VXJsOiBzdHJpbmcgPSAodXJsIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdFRva2VuOiBzdHJpbmcgPSAodG9rZW4gfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0SGVhZGVyczogSGVhZGVycyA9IGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoKTtcblxuICAvLyBNZXRob2RcbiAgY29uc3QgZm9ybWF0TWV0aG9kOiBzdHJpbmcgPSAobWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpO1xuICBsZXQgZm9ybWF0UGFyYW1zO1xuXG4gIC8vIFBhcmFtZXRlcnNcbiAgaWYocGFyYW1zICYmIGZvcm1hdE1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICBmb3JtYXRVcmwgPSBgJHtmb3JtYXRVcmx9PyR7cXVlcnlTdHJpbmcocGFyYW1zKX1gO1xuICAgIGZvcm1hdFBhcmFtcyA9IG51bGw7XG4gIH0gZWxzZSBpZihwYXJhbXMpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICBmb3JtYXRQYXJhbXMgPSBKU09OLnN0cmluZ2lmeShwYXJhbXMpO1xuICB9IGVsc2Uge1xuICAgIGZvcm1hdFBhcmFtcyA9IHBhcmFtcztcbiAgfVxuXG4gIC8vIEF1dGhlbnRpY2F0aW9uIHRva2VuXG4gIGlmKCFpc0VtcHR5KGZvcm1hdFRva2VuKSkge1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdBdXRob3JpemF0aW9uJywgYEJlYXJlciAke2Zvcm1hdFRva2VufWApO1xuICB9XG5cbiAgLy8gQ2hlY2sgY2FjaGUgZm9yIEdFVCByZXF1ZXN0c1xuICBpZihjYWNoZSAmJiBmb3JtYXRNZXRob2QgPT09ICdHRVQnKSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBnZW5lcmF0ZUNhY2hlS2V5KGZvcm1hdFVybCwgZm9ybWF0TWV0aG9kLCBwYXJhbXMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGNhY2hlZCA9IHJlcXVlc3RDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIGlmKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgdGhlIHJlcXVlc3QgcHJvbWlzZVxuICBjb25zdCByZXF1ZXN0UHJvbWlzZSA9IGZldGNoKGZvcm1hdFVybCwge1xuICAgIGJvZHk6IGZvcm1hdFBhcmFtcyxcbiAgICBoZWFkZXJzOiBmb3JtYXRIZWFkZXJzLFxuICAgIG1ldGhvZDogZm9ybWF0TWV0aG9kXG4gIH0pXG4gICAgLnRoZW4oKHJlc3BvbnNlOiBSZXNwb25zZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgcmVzcG9uc2UgaXMganNvbiB1c2luZyBjYWNoZWQgcmVnZXhcbiAgICAgIGNvbnN0IGlzUmVzcG9uc2VKc29uID0gSlNPTl9DT05URU5UX1RZUEVfUkVHRVgudGVzdChcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnXG4gICAgICApO1xuXG4gICAgICBpZihpc1Jlc3BvbnNlSnNvbikge1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKHJlc3VsdHMpID0+IHJlc3VsdHMpIC8vIFNpbXBsaWZpZWQgLSBubyBuZWVkIGZvciByZWR1bmRhbnQgY2hlY2tcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpZigoZXJyb3IgfHwge30pLm1lc3NhZ2UgPT09ICdvbmx5IGFic29sdXRlIHVybHMgYXJlIHN1cHBvcnRlZCcpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgIG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICdpbnZhbGlkX3VybCd9XSwgZXJyb3IpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IEFwaUVycm9yKFt7bWVzc2FnZTogJ25ldHdvcmtfZXJyb3InfV0sIGVycm9yKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAvLyBBZGQgdGltZW91dCBpZiBzcGVjaWZpZWRcbiAgY29uc3QgZmluYWxQcm9taXNlID0gdGltZW91dCA+IDBcbiAgICA/IFByb21pc2UucmFjZShbcmVxdWVzdFByb21pc2UsIGNyZWF0ZVRpbWVvdXQodGltZW91dCldKVxuICAgIDogcmVxdWVzdFByb21pc2U7XG5cbiAgLy8gQ2FjaGUgdGhlIHByb21pc2UgZm9yIEdFVCByZXF1ZXN0c1xuICBpZihjYWNoZSAmJiBmb3JtYXRNZXRob2QgPT09ICdHRVQnKSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBnZW5lcmF0ZUNhY2hlS2V5KGZvcm1hdFVybCwgZm9ybWF0TWV0aG9kLCBwYXJhbXMsIG9wdGlvbnMpO1xuICAgIHJlcXVlc3RDYWNoZS5zZXQoY2FjaGVLZXksIGZpbmFsUHJvbWlzZSk7XG5cbiAgICAvLyBDbGVhbiB1cCBjYWNoZSBhZnRlciA1IG1pbnV0ZXNcbiAgICBzZXRUaW1lb3V0KCgpID0+IHJlcXVlc3RDYWNoZS5kZWxldGUoY2FjaGVLZXkpLCAzMDAwMDApO1xuICB9XG5cbiAgcmV0dXJuIGZpbmFsUHJvbWlzZTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXQgPSAoXG4gIHVybDogc3RyaW5nLFxuICBwYXJhbXM/LFxuICBvcHRpb25zPzogSHVudGVyT3B0aW9uc1R5cGVcbik6IFByb21pc2U8YW55PiA9PiBhamF4KHVybCwgJ0dFVCcsIHBhcmFtcywgb3B0aW9ucyk7XG5cbmV4cG9ydCBjb25zdCBwb3N0ID0gKFxuICB1cmw6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlXG4pOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdQT1NUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IHB1dCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHBhcmFtcz8sXG4gIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZVxuKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnUFVUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IGRlbCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHBhcmFtcz8sXG4gIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZVxuKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnREVMRVRFJywgcGFyYW1zLCBvcHRpb25zKTtcblxuLy8gT3B0aW1pemVkIHRvR3FsIGZ1bmN0aW9uXG5leHBvcnQgY29uc3QgdG9HcWwgPSAob2JqOiBhbnkpOiBzdHJpbmcgPT4ge1xuICBpZihpc1N0cmluZyhvYmopKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9iaik7XG4gIH0gZWxzZSBpZihpc1BsYWluT2JqZWN0KG9iaikpIHtcbiAgICAvLyBGaWx0ZXIgb3V0IHVuZGVmaW5lZCBhbmQgbnVsbCB2YWx1ZXMgaW4gb25lIHBhc3NcbiAgICBjb25zdCBncWxQcm9wczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvcihjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgICBpZihvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBjb25zdCBpdGVtID0gb2JqW2tleV07XG5cbiAgICAgICAgLy8gU2tpcCB1bmRlZmluZWQgYW5kIG51bGwgdmFsdWVzXG4gICAgICAgIGlmKGlzVW5kZWZpbmVkKGl0ZW0pIHx8IGlzTnVsbChpdGVtKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoaXNQbGFpbk9iamVjdChpdGVtKSkge1xuICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogJHt0b0dxbChpdGVtKX1gKTtcbiAgICAgICAgfSBlbHNlIGlmKGlzQXJyYXkoaXRlbSkpIHtcbiAgICAgICAgICBjb25zdCBsaXN0ID0gaXRlbS5tYXAoKGxpc3RJdGVtKSA9PiB0b0dxbChsaXN0SXRlbSkpO1xuICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogWyR7bGlzdC5qb2luKCcsICcpfV1gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB2YWwgPSBKU09OLnN0cmluZ2lmeShpdGVtKTtcbiAgICAgICAgICBpZih2YWwpIHtcbiAgICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogJHt2YWx9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gZ3FsUHJvcHMuam9pbignLCAnKTtcbiAgICByZXR1cm4gdmFsdWVzID09PSAnJyA/ICdcIlwiJyA6IGB7JHtncWxQcm9wcy5qb2luKCcsICcpfX1gO1xuICB9IGVsc2UgaWYoaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIGBbJHtvYmoubWFwKChvYmpJdGVtKSA9PiB0b0dxbChvYmpJdGVtKSkuam9pbignLCAnKX1dYDtcbiAgfVxuXG4gIHJldHVybiBTdHJpbmcob2JqKTtcbn07XG5cbmV4cG9ydCBjb25zdCBncmFwaHFsUXVlcnkgPSAoXG4gIHVybDogc3RyaW5nLFxuICBxdWVyeTogSHVudGVyUXVlcnlUeXBlIHwgSHVudGVyUXVlcnlUeXBlW10sXG4gIG9wdGlvbnM6IEh1bnRlck9wdGlvbnNUeXBlID0ge31cbik6IFByb21pc2U8YW55PiA9PiB7XG4gIGNvbnN0IHtoZWFkZXJzLCB0b2tlbiwgdGltZW91dCA9IDMwMDAwfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZvcm1hdFVybDogc3RyaW5nID0gdXJsID8gdXJsLnRyaW0oKSA6ICcnO1xuICBjb25zdCBmb3JtYXRUb2tlbjogc3RyaW5nID0gKHRva2VuIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdEhlYWRlcnM6IEhlYWRlcnMgPVxuICAgIGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoeydDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbid9KTtcblxuICBpZighaXNFbXB0eShmb3JtYXRUb2tlbikpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHtmb3JtYXRUb2tlbn1gKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3RQcm9taXNlID0gZmV0Y2goZm9ybWF0VXJsLCB7XG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkocXVlcnkpLFxuICAgIGhlYWRlcnM6IGZvcm1hdEhlYWRlcnMsXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgfSlcbiAgICAudGhlbigocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCBpc0pzb246IGJvb2xlYW4gPSBKU09OX0NPTlRFTlRfVFlQRV9SRUdFWC50ZXN0KFxuICAgICAgICByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJykgfHwgJydcbiAgICAgICk7XG5cbiAgICAgIGlmKGlzSnNvbiAmJiByZXNwb25zZS5ib2R5KSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgaWYoKGVycm9yIHx8IHt9KS5tZXNzYWdlID09PSAnb25seSBhYnNvbHV0ZSB1cmxzIGFyZSBzdXBwb3J0ZWQnKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnaW52YWxpZF91cmwnfV0sIGVycm9yKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICduZXR3b3JrX2Vycm9yJ31dLCBlcnJvcilcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbigoanNvbikgPT4ge1xuICAgICAgaWYoIWpzb24gfHwganNvbi5lcnJvcnMpIHtcbiAgICAgICAgaWYoIWpzb24pIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnYXBpX2Vycm9yJ31dLCBuZXcgRXJyb3IoKSlcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYoXG4gICAgICAgICAgKGpzb24uZXJyb3JzIHx8IFtdKS5zb21lKFxuICAgICAgICAgICAgKGVycm9yKSA9PiBlcnJvci5tZXNzYWdlID09PSAnTXVzdCBwcm92aWRlIHF1ZXJ5IHN0cmluZy4nXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAncmVxdWlyZWRfcXVlcnknfV0sIG5ldyBFcnJvcigpKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ganNvbi5lcnJvcnNcbiAgICAgICAgICA/IFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihqc29uLmVycm9ycywgbmV3IEVycm9yKCkpKVxuICAgICAgICAgIDoge307XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBqc29uLmRhdGEgfHwge307XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yOiBBcGlFcnJvcikgPT5cbiAgICAgIC8vIFNpbXBsaWZpZWQgZXJyb3IgaGFuZGxpbmcgLSBubyBuZWVkIHRvIGNyZWF0ZSBuZXcgZXJyb3IgaWYgc291cmNlIGV4aXN0c1xuICAgICAgUHJvbWlzZS5yZWplY3QoZXJyb3Iuc291cmNlID8gZXJyb3IgOiBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnbmV0d29ya19lcnJvcid9XSwgZXJyb3IpKVxuICAgICk7XG5cbiAgLy8gQWRkIHRpbWVvdXQgaWYgc3BlY2lmaWVkXG4gIHJldHVybiB0aW1lb3V0ID4gMFxuICAgID8gUHJvbWlzZS5yYWNlKFtyZXF1ZXN0UHJvbWlzZSwgY3JlYXRlVGltZW91dCh0aW1lb3V0KV0pXG4gICAgOiByZXF1ZXN0UHJvbWlzZTtcbn07XG5cbi8vIEFkZCBxdWVyeSBhbmQgbXV0YXRpb24gZnVuY3Rpb25zIGZvciBiZXR0ZXIgQVBJIGNvbnNpc3RlbmN5XG5leHBvcnQgY29uc3QgcXVlcnkgPSAoXG4gIHVybDogc3RyaW5nLFxuICBib2R5OiBzdHJpbmcsXG4gIG9wdGlvbnM6IEh1bnRlck9wdGlvbnNUeXBlID0ge31cbik6IFByb21pc2U8YW55PiA9PiBncmFwaHFsUXVlcnkodXJsLCB7cXVlcnk6IGJvZHl9LCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IG11dGF0aW9uID0gKFxuICB1cmw6IHN0cmluZyxcbiAgYm9keTogc3RyaW5nLFxuICBvcHRpb25zOiBIdW50ZXJPcHRpb25zVHlwZSA9IHt9XG4pOiBQcm9taXNlPGFueT4gPT4gZ3JhcGhxbFF1ZXJ5KHVybCwge3F1ZXJ5OiBib2R5fSwgb3B0aW9ucyk7XG5cbi8vIFNTRSBTdXBwb3J0XG5leHBvcnQgY29uc3Qgc3Vic2NyaWJlU1NFID0gKFxuICB1cmw6IHN0cmluZyxcbiAgY2FsbGJhY2tzOiBIdW50ZXJTU0VDYWxsYmFja1R5cGUsXG4gIG9wdGlvbnM6IEh1bnRlclNTRU9wdGlvbnNUeXBlID0ge31cbik6ICgoKSA9PiB2b2lkKSA9PiB7XG4gIGNvbnN0IHtoZWFkZXJzLCB0b2tlbiwgdGltZW91dCA9IDMwMDAwLCByZXRyeUludGVydmFsID0gMTAwMCwgbWF4UmV0cmllcyA9IDV9ID0gb3B0aW9ucztcbiAgY29uc3QgZm9ybWF0VXJsOiBzdHJpbmcgPSAodXJsIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdFRva2VuOiBzdHJpbmcgPSAodG9rZW4gfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0SGVhZGVyczogSGVhZGVycyA9IGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoKTtcblxuICAvLyBBZGQgYXV0aG9yaXphdGlvbiBoZWFkZXIgaWYgdG9rZW4gcHJvdmlkZWRcbiAgaWYoIWlzRW1wdHkoZm9ybWF0VG9rZW4pKSB7XG4gICAgZm9ybWF0SGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7Zm9ybWF0VG9rZW59YCk7XG4gIH1cblxuICBsZXQgcmV0cnlDb3VudCA9IDA7XG4gIGxldCBldmVudFNvdXJjZTogRXZlbnRTb3VyY2UgfCBudWxsID0gbnVsbDtcbiAgbGV0IHRpbWVvdXRJZDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcblxuICBjb25zdCBjb25uZWN0ID0gKCk6IHZvaWQgPT4ge1xuICAgIHRyeSB7XG4gICAgICBldmVudFNvdXJjZSA9IGNyZWF0ZUV2ZW50U291cmNlKGZvcm1hdFVybCwge2hlYWRlcnM6IGZvcm1hdEhlYWRlcnN9KTtcblxuICAgICAgLy8gU2V0IHVwIHRpbWVvdXRcbiAgICAgIGlmKHRpbWVvdXQgPiAwKSB7XG4gICAgICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlmKGV2ZW50U291cmNlKSB7XG4gICAgICAgICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTU0UgY29ubmVjdGlvbiB0aW1lb3V0JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgdGltZW91dCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV2ZW50IGhhbmRsZXJzXG4gICAgICBldmVudFNvdXJjZS5vbm9wZW4gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYodGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXRyeUNvdW50ID0gMDsgLy8gUmVzZXQgcmV0cnkgY291bnQgb24gc3VjY2Vzc2Z1bCBjb25uZWN0aW9uXG4gICAgICAgIGlmKGNhbGxiYWNrcy5vbk9wZW4pIHtcbiAgICAgICAgICBjYWxsYmFja3Mub25PcGVuKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgZXZlbnRTb3VyY2Uub25tZXNzYWdlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmKGNhbGxiYWNrcy5vbk1lc3NhZ2UpIHtcbiAgICAgICAgICBjb25zdCBzc2VFdmVudDogSHVudGVyU1NFRXZlbnRUeXBlID0ge1xuICAgICAgICAgICAgZGF0YTogZXZlbnQuZGF0YSxcbiAgICAgICAgICAgIGlkOiBldmVudC5sYXN0RXZlbnRJZCxcbiAgICAgICAgICAgIHJldHJ5OiBldmVudC5kYXRhLmluY2x1ZGVzKCdyZXRyeTonKSA/IHBhcnNlSW50KGV2ZW50LmRhdGEuc3BsaXQoJ3JldHJ5OicpWzFdKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGVcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNhbGxiYWNrcy5vbk1lc3NhZ2Uoc3NlRXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBldmVudFNvdXJjZS5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmKHRpbWVvdXRJZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZihldmVudFNvdXJjZSAmJiBldmVudFNvdXJjZS5yZWFkeVN0YXRlID09PSBFdmVudFNvdXJjZS5DTE9TRUQpIHtcbiAgICAgICAgICAvLyBDb25uZWN0aW9uIGNsb3NlZCwgYXR0ZW1wdCByZXRyeSBpZiB3aXRoaW4gbGltaXRzXG4gICAgICAgICAgaWYocmV0cnlDb3VudCA8IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgIHJldHJ5Q291bnQrKztcbiAgICAgICAgICAgIGlmKGNhbGxiYWNrcy5vblJldHJ5KSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrcy5vblJldHJ5KHJldHJ5Q291bnQsIHJldHJ5SW50ZXJ2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2V0VGltZW91dChjb25uZWN0LCByZXRyeUludGVydmFsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTU0UgY29ubmVjdGlvbiBmYWlsZWQgYWZ0ZXIgbWF4IHJldHJpZXMnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgIGNhbGxiYWNrcy5vbkVycm9yKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBTU0UgY29ubmVjdGlvbicpKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gU3RhcnQgdGhlIGNvbm5lY3Rpb25cbiAgY29ubmVjdCgpO1xuXG4gIC8vIFJldHVybiBjbGVhbnVwIGZ1bmN0aW9uXG4gIHJldHVybiAoKSA9PiB7XG4gICAgaWYodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgfVxuICAgIGlmKGV2ZW50U291cmNlKSB7XG4gICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgZXZlbnRTb3VyY2UgPSBudWxsO1xuICAgIH1cbiAgfTtcbn07XG5cbmV4cG9ydCB7QXBpRXJyb3J9IGZyb20gJy4vZXJyb3JzL0FwaUVycm9yLmpzJztcbiJdLAogICJtYXBwaW5ncyI6ICJBQUtBLE9BQVEsWUFBQUEsTUFBZSx1QkFxYnZCLE9BQVEsWUFBQUEsTUFBZSx1QkFuYnZCLE1BQU1DLEVBQVdDLEdBQStCLE1BQU0sUUFBUUEsQ0FBSyxFQUM3REMsRUFBWUQsR0FBZ0MsT0FBT0EsR0FBVSxTQUM3REUsRUFBaUJGLEdBQ3JCQSxJQUFVLE1BQVEsT0FBT0EsR0FBVSxVQUFZLENBQUNELEVBQVFDLENBQUssRUFDekRHLEVBQVdILEdBQ2ZB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QUFRRyxFQUFZRixDQUFhLEVBRTdDLFdBQVdLLEVBQVNMLENBQWEsR0FFOUJELEVBQVUsU0FDWEEsRUFBVSxRQUFRLElBQUksTUFBTSx5Q0FBeUMsQ0FBQyxFQUl2RUEsRUFBVSxTQUNYQSxFQUFVLFFBQVFPLENBQUssQ0FHN0IsQ0FDRixPQUFRMUIsRUFBTyxDQUNWbUIsRUFBVSxTQUNYQSxFQUFVLFFBQVFuQixhQUFpQixNQUFRQSxFQUFRLElBQUksTUFBTSxpQ0FBaUMsQ0FBQyxDQUVuRyxDQUNGLEVBR0EsT0FBQXlCLEVBQVEsRUFHRCxJQUFNLENBQ1JELElBQ0QsYUFBYUEsQ0FBUyxFQUN0QkEsRUFBWSxNQUVYRCxJQUNEQSxFQUFZLE1BQU0sRUFDbEJBLEVBQWMsS0FFbEIsQ0FDRiIsCiAgIm5hbWVzIjogWyJBcGlFcnJvciIsICJpc0FycmF5IiwgInZhbHVlIiwgImlzU3RyaW5nIiwgImlzUGxhaW5PYmplY3QiLCAiaXNFbXB0eSIsICJpc051bGwiLCAiaXNVbmRlZmluZWQiLCAiSlNPTl9DT05URU5UX1RZUEVfUkVHRVgiLCAicmVxdWVzdENhY2hlIiwgInJlbW92ZVNwYWNlcyIsICJzdHIiLCAicXVlcnlTdHJpbmciLCAianNvbiIsICJrZXkiLCAiY3JlYXRlVGltZW91dCIsICJtcyIsICJfIiwgInJlamVjdCIsICJnZW5lcmF0ZUNhY2hlS2V5IiwgInVybCIsICJtZXRob2QiLCAicGFyYW1zIiwgIm9wdGlvbnMiLCAiY3JlYXRlRXZlbnRTb3VyY2UiLCAiYWpheCIsICJoZWFkZXJzIiwgInRva2VuIiwgInRpbWVvdXQiLCAiY2FjaGUiLCAiZm9ybWF0VXJsIiwgImZvcm1hdFRva2VuIiwgImZvcm1hdEhlYWRlcnMiLCAiZm9ybWF0TWV0aG9kIiwgImZvcm1hdFBhcmFtcyIsICJjYWNoZUtleSIsICJjYWNoZWQiLCAicmVxdWVzdFByb21pc2UiLCAicmVzcG9uc2UiLCAicmVzdWx0cyIsICJlcnJvciIsICJmaW5hbFByb21pc2UiLCAiZ2V0IiwgInBvc3QiLCAicHV0IiwgImRlbCIsICJ0b0dxbCIsICJvYmoiLCAiZ3FsUHJvcHMiLCAiaXRlbSIsICJsaXN0IiwgImxpc3RJdGVtIiwgInZhbCIsICJvYmpJdGVtIiwgImdyYXBocWxRdWVyeSIsICJxdWVyeSIsICJib2R5IiwgIm11dGF0aW9uIiwgInN1YnNjcmliZVNTRSIsICJjYWxsYmFja3MiLCAicmV0cnlJbnRlcnZhbCIsICJtYXhSZXRyaWVzIiwgInJldHJ5Q291bnQiLCAiZXZlbnRTb3VyY2UiLCAidGltZW91dElkIiwgImNvbm5lY3QiLCAiZXZlbnQiLCAic3NlRXZlbnQiXQp9Cg==
1
+ /**
2
+ * Copyright (c) 2017-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { ApiError } from './errors/ApiError.js';
5
+ const isArray = (value)=>Array.isArray(value);
6
+ const isString = (value)=>typeof value === 'string';
7
+ const isPlainObject = (value)=>value !== null && typeof value === 'object' && !isArray(value);
8
+ const isEmpty = (value)=>value === null || value === undefined || value === '';
9
+ const isNull = (value)=>value === null;
10
+ const isUndefined = (value)=>value === undefined;
11
+ // Cache for compiled regex patterns
12
+ const JSON_CONTENT_TYPE_REGEX = /application\/json/i;
13
+ // Request cache for deduplication
14
+ const requestCache = new Map();
15
+ export const removeSpaces = (str)=>str.replace(/\s+(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/gm, '');
16
+ export const queryString = (json)=>Object.keys(json).map((key)=>`${encodeURIComponent(key)}=${encodeURIComponent(json[key])}`).join('&');
17
+ // Create a timeout promise
18
+ const createTimeout = (ms)=>new Promise((_, reject)=>setTimeout(()=>reject(new Error('Request timeout')), ms));
19
+ // Generate cache key for request deduplication
20
+ const generateCacheKey = (url, method, params, options)=>{
21
+ const key = JSON.stringify({
22
+ method,
23
+ options,
24
+ params,
25
+ url
26
+ });
27
+ return btoa(key).slice(0, 50); // Truncate to reasonable length
28
+ };
29
+ // SSE EventSource polyfill for Node.js
30
+ const createEventSource = (url, options)=>{
31
+ if (typeof EventSource !== 'undefined') {
32
+ return new EventSource(url);
33
+ }
34
+ // For Node.js, we'll throw an error suggesting the user install eventsource
35
+ throw new Error('EventSource not available in this environment. For Node.js support, install the "eventsource" package and import it manually.');
36
+ };
37
+ // WebSocket client for GraphQL subscriptions (graphql-ws protocol)
38
+ class GraphQLSubscriptionClient {
39
+ ws = null;
40
+ url;
41
+ options;
42
+ reconnectAttempts = 0;
43
+ reconnectTimer = null;
44
+ messageQueue = [];
45
+ isConnecting = false;
46
+ isConnected = false;
47
+ subscriptions = new Map();
48
+ messageHandlers = new Map();
49
+ constructor(url, options = {}){
50
+ this.url = url;
51
+ this.options = options;
52
+ }
53
+ convertToWebSocketUrl(url) {
54
+ return url.replace(/^http/, 'ws').replace(/^https/, 'wss');
55
+ }
56
+ connect() {
57
+ return new Promise((resolve, reject)=>{
58
+ if (this.isConnecting) {
59
+ return;
60
+ }
61
+ this.isConnecting = true;
62
+ try {
63
+ const wsUrl = this.convertToWebSocketUrl(this.url);
64
+ if (typeof WebSocket === 'undefined') {
65
+ this.isConnecting = false;
66
+ reject(new Error('WebSocket not available in this environment. For Node.js support, you may need to install a WebSocket library.'));
67
+ return;
68
+ }
69
+ this.ws = new WebSocket(wsUrl, 'graphql-ws');
70
+ this.ws.onopen = ()=>{
71
+ this.isConnecting = false;
72
+ this.isConnected = true;
73
+ this.reconnectAttempts = 0;
74
+ const initMessage = {
75
+ type: 'connection_init',
76
+ payload: this.options.connectionParams || {}
77
+ };
78
+ this.send(JSON.stringify(initMessage));
79
+ while(this.messageQueue.length > 0){
80
+ const message = this.messageQueue.shift();
81
+ if (message && this.ws?.readyState === WebSocket.OPEN) {
82
+ this.ws.send(message);
83
+ }
84
+ }
85
+ resolve();
86
+ };
87
+ this.ws.onerror = (error)=>{
88
+ this.isConnecting = false;
89
+ if (!this.isConnected) {
90
+ reject(error);
91
+ }
92
+ };
93
+ this.ws.onclose = ()=>{
94
+ this.isConnecting = false;
95
+ this.isConnected = false;
96
+ this.handleReconnect();
97
+ };
98
+ this.ws.onmessage = (event)=>{
99
+ try {
100
+ const message = JSON.parse(event.data);
101
+ if (message.type === 'connection_ack') {
102
+ return;
103
+ }
104
+ if (message.type === 'connection_error') {
105
+ const error = new Error(message.payload?.message || 'Connection error');
106
+ this.subscriptions.forEach((callbacks)=>{
107
+ if (callbacks.onError) {
108
+ callbacks.onError(error);
109
+ }
110
+ });
111
+ return;
112
+ }
113
+ const subscriptionId = message.id;
114
+ const callbacks = this.subscriptions.get(subscriptionId);
115
+ if (callbacks) {
116
+ switch(message.type){
117
+ case 'data':
118
+ if (callbacks.onNext) {
119
+ callbacks.onNext(message.payload?.data || message.payload);
120
+ }
121
+ break;
122
+ case 'error':
123
+ if (callbacks.onError) {
124
+ const error = new ApiError(Array.isArray(message.payload) ? message.payload : [
125
+ message.payload
126
+ ], new Error('GraphQL subscription error'));
127
+ callbacks.onError(error);
128
+ }
129
+ break;
130
+ case 'complete':
131
+ if (callbacks.onComplete) {
132
+ callbacks.onComplete();
133
+ }
134
+ this.subscriptions.delete(subscriptionId);
135
+ const handler = this.messageHandlers.get(subscriptionId);
136
+ if (handler && this.ws) {
137
+ this.ws.removeEventListener('message', handler);
138
+ this.messageHandlers.delete(subscriptionId);
139
+ }
140
+ break;
141
+ }
142
+ }
143
+ } catch (error) {
144
+ this.subscriptions.forEach((callbacks)=>{
145
+ if (callbacks.onError) {
146
+ callbacks.onError(error instanceof Error ? error : new Error('Parse error'));
147
+ }
148
+ });
149
+ }
150
+ };
151
+ } catch (error) {
152
+ this.isConnecting = false;
153
+ reject(error);
154
+ }
155
+ });
156
+ }
157
+ handleReconnect() {
158
+ const { maxReconnectAttempts = 5, reconnectInterval = 1000 } = this.options;
159
+ if (this.reconnectAttempts < maxReconnectAttempts && this.subscriptions.size > 0) {
160
+ this.reconnectAttempts++;
161
+ this.subscriptions.forEach((callbacks)=>{
162
+ if (callbacks.onReconnect) {
163
+ callbacks.onReconnect(this.reconnectAttempts);
164
+ }
165
+ });
166
+ this.reconnectTimer = setTimeout(()=>{
167
+ this.connect().catch(()=>{});
168
+ }, reconnectInterval);
169
+ } else if (this.subscriptions.size > 0) {
170
+ const error = new Error('WebSocket reconnection failed after max attempts');
171
+ this.subscriptions.forEach((callbacks)=>{
172
+ if (callbacks.onError) {
173
+ callbacks.onError(error);
174
+ }
175
+ });
176
+ }
177
+ }
178
+ send(message) {
179
+ if (this.ws?.readyState === WebSocket.OPEN) {
180
+ this.ws.send(message);
181
+ } else {
182
+ this.messageQueue.push(message);
183
+ if (!this.isConnecting && !this.isConnected) {
184
+ this.connect().catch(()=>{});
185
+ }
186
+ }
187
+ }
188
+ subscribe(query, variables, callbacks) {
189
+ const subscriptionId = `sub_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
190
+ this.subscriptions.set(subscriptionId, callbacks);
191
+ const startMessage = {
192
+ id: subscriptionId,
193
+ type: 'start',
194
+ payload: {
195
+ query,
196
+ variables: variables || {}
197
+ }
198
+ };
199
+ const ensureConnection = ()=>{
200
+ if (!this.isConnected && !this.isConnecting) {
201
+ this.connect().then(()=>{
202
+ this.send(JSON.stringify(startMessage));
203
+ }).catch((error)=>{
204
+ if (callbacks.onError) {
205
+ callbacks.onError(error);
206
+ }
207
+ });
208
+ } else if (this.isConnected) {
209
+ this.send(JSON.stringify(startMessage));
210
+ }
211
+ };
212
+ ensureConnection();
213
+ return ()=>{
214
+ const stopMessage = {
215
+ id: subscriptionId,
216
+ type: 'stop'
217
+ };
218
+ this.send(JSON.stringify(stopMessage));
219
+ this.subscriptions.delete(subscriptionId);
220
+ const handler = this.messageHandlers.get(subscriptionId);
221
+ if (handler && this.ws) {
222
+ this.ws.removeEventListener('message', handler);
223
+ this.messageHandlers.delete(subscriptionId);
224
+ }
225
+ };
226
+ }
227
+ close() {
228
+ if (this.reconnectTimer) {
229
+ clearTimeout(this.reconnectTimer);
230
+ this.reconnectTimer = null;
231
+ }
232
+ if (this.ws) {
233
+ this.ws.close();
234
+ this.ws = null;
235
+ }
236
+ this.messageQueue = [];
237
+ this.subscriptions.clear();
238
+ this.messageHandlers.clear();
239
+ this.isConnected = false;
240
+ this.isConnecting = false;
241
+ }
242
+ }
243
+ // Subscription client cache
244
+ const subscriptionClients = new Map();
245
+ // AJAX
246
+ export const ajax = (url, method, params, options = {})=>{
247
+ const { headers, token, timeout = 30000, cache = false } = options;
248
+ let formatUrl = (url || '').trim();
249
+ const formatToken = (token || '').trim();
250
+ const formatHeaders = headers || new Headers();
251
+ // Method
252
+ const formatMethod = (method || 'GET').toUpperCase();
253
+ let formatParams;
254
+ // Parameters
255
+ if (params && formatMethod === 'GET') {
256
+ formatUrl = `${formatUrl}?${queryString(params)}`;
257
+ formatParams = null;
258
+ } else if (params) {
259
+ formatHeaders.set('Accept', 'application/json');
260
+ formatHeaders.set('Content-Type', 'application/json');
261
+ formatParams = JSON.stringify(params);
262
+ } else {
263
+ formatParams = params;
264
+ }
265
+ // Authentication token
266
+ if (!isEmpty(formatToken)) {
267
+ formatHeaders.set('Authorization', `Bearer ${formatToken}`);
268
+ }
269
+ // Check cache for GET requests
270
+ if (cache && formatMethod === 'GET') {
271
+ const cacheKey = generateCacheKey(formatUrl, formatMethod, params, options);
272
+ const cached = requestCache.get(cacheKey);
273
+ if (cached) {
274
+ return cached;
275
+ }
276
+ }
277
+ // Create the request promise
278
+ const requestPromise = fetch(formatUrl, {
279
+ body: formatParams,
280
+ headers: formatHeaders,
281
+ method: formatMethod
282
+ }).then((response)=>{
283
+ // Check if response is json using cached regex
284
+ const isResponseJson = JSON_CONTENT_TYPE_REGEX.test(response.headers.get('Content-Type') || '');
285
+ if (isResponseJson) {
286
+ return response.json();
287
+ }
288
+ return response.text();
289
+ }).then((results)=>results) // Simplified - no need for redundant check
290
+ .catch((error)=>{
291
+ if ((error || {}).message === 'only absolute urls are supported') {
292
+ return Promise.reject(new ApiError([
293
+ {
294
+ message: 'invalid_url'
295
+ }
296
+ ], error));
297
+ }
298
+ return Promise.reject(new ApiError([
299
+ {
300
+ message: 'network_error'
301
+ }
302
+ ], error));
303
+ });
304
+ // Add timeout if specified
305
+ const finalPromise = timeout > 0 ? Promise.race([
306
+ requestPromise,
307
+ createTimeout(timeout)
308
+ ]) : requestPromise;
309
+ // Cache the promise for GET requests
310
+ if (cache && formatMethod === 'GET') {
311
+ const cacheKey = generateCacheKey(formatUrl, formatMethod, params, options);
312
+ requestCache.set(cacheKey, finalPromise);
313
+ // Clean up cache after 5 minutes
314
+ setTimeout(()=>requestCache.delete(cacheKey), 300000);
315
+ }
316
+ return finalPromise;
317
+ };
318
+ export const get = (url, params, options)=>ajax(url, 'GET', params, options);
319
+ export const post = (url, params, options)=>ajax(url, 'POST', params, options);
320
+ export const put = (url, params, options)=>ajax(url, 'PUT', params, options);
321
+ export const del = (url, params, options)=>ajax(url, 'DELETE', params, options);
322
+ // Optimized toGql function
323
+ export const toGql = (obj)=>{
324
+ if (isString(obj)) {
325
+ return JSON.stringify(obj);
326
+ } else if (isPlainObject(obj)) {
327
+ // Filter out undefined and null values in one pass
328
+ const gqlProps = [];
329
+ for(const key in obj){
330
+ if (obj.hasOwnProperty(key)) {
331
+ const item = obj[key];
332
+ // Skip undefined and null values
333
+ if (isUndefined(item) || isNull(item)) {
334
+ continue;
335
+ }
336
+ if (isPlainObject(item)) {
337
+ gqlProps.push(`${key}: ${toGql(item)}`);
338
+ } else if (isArray(item)) {
339
+ const list = item.map((listItem)=>toGql(listItem));
340
+ gqlProps.push(`${key}: [${list.join(', ')}]`);
341
+ } else {
342
+ const val = JSON.stringify(item);
343
+ if (val) {
344
+ gqlProps.push(`${key}: ${val}`);
345
+ }
346
+ }
347
+ }
348
+ }
349
+ const values = gqlProps.join(', ');
350
+ return values === '' ? '""' : `{${gqlProps.join(', ')}}`;
351
+ } else if (isArray(obj)) {
352
+ return `[${obj.map((objItem)=>toGql(objItem)).join(', ')}]`;
353
+ }
354
+ return String(obj);
355
+ };
356
+ export const graphqlQuery = (url, query, options = {})=>{
357
+ const { headers, token, timeout = 30000 } = options;
358
+ const formatUrl = url ? url.trim() : '';
359
+ const formatToken = (token || '').trim();
360
+ const formatHeaders = headers || new Headers({
361
+ 'Content-Type': 'application/json'
362
+ });
363
+ if (!isEmpty(formatToken)) {
364
+ formatHeaders.set('Authorization', `Bearer ${formatToken}`);
365
+ }
366
+ const requestPromise = fetch(formatUrl, {
367
+ body: JSON.stringify(query),
368
+ headers: formatHeaders,
369
+ method: 'post'
370
+ }).then((response)=>{
371
+ const isJson = JSON_CONTENT_TYPE_REGEX.test(response.headers.get('Content-Type') || '');
372
+ if (isJson && response.body) {
373
+ return response.json();
374
+ }
375
+ return null;
376
+ }).catch((error)=>{
377
+ if ((error || {}).message === 'only absolute urls are supported') {
378
+ return Promise.reject(new ApiError([
379
+ {
380
+ message: 'invalid_url'
381
+ }
382
+ ], error));
383
+ }
384
+ return Promise.reject(new ApiError([
385
+ {
386
+ message: 'network_error'
387
+ }
388
+ ], error));
389
+ }).then((json)=>{
390
+ if (!json || json.errors) {
391
+ if (!json) {
392
+ return Promise.reject(new ApiError([
393
+ {
394
+ message: 'api_error'
395
+ }
396
+ ], new Error()));
397
+ } else if ((json.errors || []).some((error)=>error.message === 'Must provide query string.')) {
398
+ return Promise.reject(new ApiError([
399
+ {
400
+ message: 'required_query'
401
+ }
402
+ ], new Error()));
403
+ }
404
+ return json.errors ? Promise.reject(new ApiError(json.errors, new Error())) : {};
405
+ }
406
+ return json.data || {};
407
+ }).catch((error)=>// Simplified error handling - no need to create new error if source exists
408
+ Promise.reject(error.source ? error : new ApiError([
409
+ {
410
+ message: 'network_error'
411
+ }
412
+ ], error)));
413
+ // Add timeout if specified
414
+ return timeout > 0 ? Promise.race([
415
+ requestPromise,
416
+ createTimeout(timeout)
417
+ ]) : requestPromise;
418
+ };
419
+ // Add query and mutation functions for better API consistency
420
+ export const query = (url, body, options = {})=>graphqlQuery(url, {
421
+ query: body
422
+ }, options);
423
+ export const mutation = (url, body, options = {})=>graphqlQuery(url, {
424
+ query: body
425
+ }, options);
426
+ // GraphQL Subscriptions
427
+ export const subscribe = (url, query, callbacks, options = {})=>{
428
+ const { token, variables, connectionParams, headers } = options;
429
+ const formatUrl = (url || '').trim();
430
+ const formatToken = (token || '').trim();
431
+ if (!formatUrl) {
432
+ if (callbacks.onError) {
433
+ callbacks.onError(new Error('Subscription URL is required'));
434
+ }
435
+ return ()=>{};
436
+ }
437
+ let client = subscriptionClients.get(formatUrl);
438
+ if (!client) {
439
+ const clientOptions = {
440
+ ...options,
441
+ connectionParams: {
442
+ ...connectionParams,
443
+ ...formatToken ? {
444
+ authorization: `Bearer ${formatToken}`
445
+ } : {}
446
+ }
447
+ };
448
+ client = new GraphQLSubscriptionClient(formatUrl, clientOptions);
449
+ subscriptionClients.set(formatUrl, client);
450
+ }
451
+ return client.subscribe(query, variables, callbacks);
452
+ };
453
+ // SSE Support
454
+ export const subscribeSSE = (url, callbacks, options = {})=>{
455
+ const { headers, token, timeout = 30000, retryInterval = 1000, maxRetries = 5 } = options;
456
+ const formatUrl = (url || '').trim();
457
+ const formatToken = (token || '').trim();
458
+ const formatHeaders = headers || new Headers();
459
+ // Add authorization header if token provided
460
+ if (!isEmpty(formatToken)) {
461
+ formatHeaders.set('Authorization', `Bearer ${formatToken}`);
462
+ }
463
+ let retryCount = 0;
464
+ let eventSource = null;
465
+ let timeoutId = null;
466
+ const connect = ()=>{
467
+ try {
468
+ eventSource = createEventSource(formatUrl, {
469
+ headers: formatHeaders
470
+ });
471
+ // Set up timeout
472
+ if (timeout > 0) {
473
+ timeoutId = setTimeout(()=>{
474
+ if (eventSource) {
475
+ eventSource.close();
476
+ if (callbacks.onError) {
477
+ callbacks.onError(new Error('SSE connection timeout'));
478
+ }
479
+ }
480
+ }, timeout);
481
+ }
482
+ // Event handlers
483
+ eventSource.onopen = (event)=>{
484
+ if (timeoutId) {
485
+ clearTimeout(timeoutId);
486
+ timeoutId = null;
487
+ }
488
+ retryCount = 0; // Reset retry count on successful connection
489
+ if (callbacks.onOpen) {
490
+ callbacks.onOpen(event);
491
+ }
492
+ };
493
+ eventSource.onmessage = (event)=>{
494
+ if (callbacks.onMessage) {
495
+ const sseEvent = {
496
+ data: event.data,
497
+ id: event.lastEventId,
498
+ retry: event.data.includes('retry:') ? parseInt(event.data.split('retry:')[1]) : undefined,
499
+ type: event.type
500
+ };
501
+ callbacks.onMessage(sseEvent);
502
+ }
503
+ };
504
+ eventSource.onerror = (event)=>{
505
+ if (timeoutId) {
506
+ clearTimeout(timeoutId);
507
+ timeoutId = null;
508
+ }
509
+ if (eventSource && eventSource.readyState === EventSource.CLOSED) {
510
+ // Connection closed, attempt retry if within limits
511
+ if (retryCount < maxRetries) {
512
+ retryCount++;
513
+ if (callbacks.onRetry) {
514
+ callbacks.onRetry(retryCount, retryInterval);
515
+ }
516
+ setTimeout(connect, retryInterval);
517
+ } else {
518
+ if (callbacks.onError) {
519
+ callbacks.onError(new Error('SSE connection failed after max retries'));
520
+ }
521
+ }
522
+ } else {
523
+ if (callbacks.onError) {
524
+ callbacks.onError(event);
525
+ }
526
+ }
527
+ };
528
+ } catch (error) {
529
+ if (callbacks.onError) {
530
+ callbacks.onError(error instanceof Error ? error : new Error('Failed to create SSE connection'));
531
+ }
532
+ }
533
+ };
534
+ // Start the connection
535
+ connect();
536
+ // Return cleanup function
537
+ return ()=>{
538
+ if (timeoutId) {
539
+ clearTimeout(timeoutId);
540
+ timeoutId = null;
541
+ }
542
+ if (eventSource) {
543
+ eventSource.close();
544
+ eventSource = null;
545
+ }
546
+ };
547
+ };
548
+ export { ApiError } from './errors/ApiError.js';
549
+
550
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JpcC1odW50ZXIvc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5cbmltcG9ydCB7QXBpRXJyb3J9IGZyb20gJy4vZXJyb3JzL0FwaUVycm9yLmpzJztcblxuY29uc3QgaXNBcnJheSA9ICh2YWx1ZTogYW55KTogdmFsdWUgaXMgYW55W10gPT4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG5jb25zdCBpc1N0cmluZyA9ICh2YWx1ZTogYW55KTogdmFsdWUgaXMgc3RyaW5nID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG5jb25zdCBpc1BsYWluT2JqZWN0ID0gKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0+XG4gIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgIWlzQXJyYXkodmFsdWUpO1xuY29uc3QgaXNFbXB0eSA9ICh2YWx1ZTogYW55KTogYm9vbGVhbiA9PlxuICB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJztcbmNvbnN0IGlzTnVsbCA9ICh2YWx1ZTogYW55KTogYm9vbGVhbiA9PiB2YWx1ZSA9PT0gbnVsbDtcbmNvbnN0IGlzVW5kZWZpbmVkID0gKHZhbHVlOiBhbnkpOiBib29sZWFuID0+IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbi8vIENhY2hlIGZvciBjb21waWxlZCByZWdleCBwYXR0ZXJuc1xuY29uc3QgSlNPTl9DT05URU5UX1RZUEVfUkVHRVggPSAvYXBwbGljYXRpb25cXC9qc29uL2k7XG5cbi8vIFJlcXVlc3QgY2FjaGUgZm9yIGRlZHVwbGljYXRpb25cbmNvbnN0IHJlcXVlc3RDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPGFueT4+KCk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSHVudGVyT3B0aW9uc1R5cGUge1xuICByZWFkb25seSBoZWFkZXJzPzogSGVhZGVycztcbiAgcmVhZG9ubHkgdG9rZW4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcmlhYmxlcz86IGFueTtcbiAgcmVhZG9ubHkgdGltZW91dD86IG51bWJlcjtcbiAgcmVhZG9ubHkgY2FjaGU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlclF1ZXJ5VHlwZSB7XG4gIHJlYWRvbmx5IHF1ZXJ5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcmlhYmxlcz86IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJTU0VPcHRpb25zVHlwZSB7XG4gIHJlYWRvbmx5IGhlYWRlcnM/OiBIZWFkZXJzO1xuICByZWFkb25seSB0b2tlbj86IHN0cmluZztcbiAgcmVhZG9ubHkgdGltZW91dD86IG51bWJlcjtcbiAgcmVhZG9ubHkgcmV0cnlJbnRlcnZhbD86IG51bWJlcjtcbiAgcmVhZG9ubHkgbWF4UmV0cmllcz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJTU0VFdmVudFR5cGUge1xuICByZWFkb25seSBkYXRhOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHR5cGU6IHN0cmluZztcbiAgcmVhZG9ubHkgaWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJldHJ5PzogbnVtYmVyIHwgdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlclNTRUNhbGxiYWNrVHlwZSB7XG4gIG9uTWVzc2FnZT86IChldmVudDogSHVudGVyU1NFRXZlbnRUeXBlKSA9PiB2b2lkO1xuICBvbk9wZW4/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICBvbkVycm9yPzogKGVycm9yOiBFcnJvciB8IEV2ZW50KSA9PiB2b2lkO1xuICBvblJldHJ5PzogKGF0dGVtcHQ6IG51bWJlciwgZGVsYXk6IG51bWJlcikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJTdWJzY3JpcHRpb25PcHRpb25zVHlwZSB7XG4gIHJlYWRvbmx5IGhlYWRlcnM/OiBIZWFkZXJzO1xuICByZWFkb25seSB0b2tlbj86IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyaWFibGVzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25QYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgcmVhZG9ubHkgcmVjb25uZWN0SW50ZXJ2YWw/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heFJlY29ubmVjdEF0dGVtcHRzPzogbnVtYmVyO1xuICByZWFkb25seSB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlclN1YnNjcmlwdGlvbkNhbGxiYWNrVHlwZSB7XG4gIG9uTmV4dD86IChkYXRhOiBhbnkpID0+IHZvaWQ7XG4gIG9uRXJyb3I/OiAoZXJyb3I6IEVycm9yIHwgRXZlbnQpID0+IHZvaWQ7XG4gIG9uQ29tcGxldGU/OiAoKSA9PiB2b2lkO1xuICBvblJlY29ubmVjdD86IChhdHRlbXB0OiBudW1iZXIpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCByZW1vdmVTcGFjZXMgPSAoc3RyOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgc3RyLnJlcGxhY2UoL1xccysoPz0oPzpbXidcIl0qWydcIl1bXidcIl0qWydcIl0pKlteJ1wiXSokKS9nbSwgJycpO1xuXG5leHBvcnQgY29uc3QgcXVlcnlTdHJpbmcgPSAoanNvbjogYW55KTogc3RyaW5nID0+XG4gIE9iamVjdC5rZXlzKGpzb24pXG4gICAgLm1hcChcbiAgICAgIChrZXk6IHN0cmluZykgPT5cbiAgICAgICAgYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KGpzb25ba2V5XSl9YFxuICAgIClcbiAgICAuam9pbignJicpO1xuXG4vLyBDcmVhdGUgYSB0aW1lb3V0IHByb21pc2VcbmNvbnN0IGNyZWF0ZVRpbWVvdXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8bmV2ZXI+ID0+XG4gIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+XG4gICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKCdSZXF1ZXN0IHRpbWVvdXQnKSksIG1zKVxuICApO1xuXG4vLyBHZW5lcmF0ZSBjYWNoZSBrZXkgZm9yIHJlcXVlc3QgZGVkdXBsaWNhdGlvblxuY29uc3QgZ2VuZXJhdGVDYWNoZUtleSA9ICh1cmw6IHN0cmluZywgbWV0aG9kOiBzdHJpbmcsIHBhcmFtcz86IGFueSwgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlKTogc3RyaW5nID0+IHtcbiAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkoe21ldGhvZCwgb3B0aW9ucywgcGFyYW1zLCB1cmx9KTtcbiAgcmV0dXJuIGJ0b2Eoa2V5KS5zbGljZSgwLCA1MCk7IC8vIFRydW5jYXRlIHRvIHJlYXNvbmFibGUgbGVuZ3RoXG59O1xuXG4vLyBTU0UgRXZlbnRTb3VyY2UgcG9seWZpbGwgZm9yIE5vZGUuanNcbmNvbnN0IGNyZWF0ZUV2ZW50U291cmNlID0gKHVybDogc3RyaW5nLCBvcHRpb25zPzogSHVudGVyU1NFT3B0aW9uc1R5cGUpOiBFdmVudFNvdXJjZSA9PiB7XG4gIGlmKHR5cGVvZiBFdmVudFNvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50U291cmNlKHVybCk7XG4gIH1cblxuICAvLyBGb3IgTm9kZS5qcywgd2UnbGwgdGhyb3cgYW4gZXJyb3Igc3VnZ2VzdGluZyB0aGUgdXNlciBpbnN0YWxsIGV2ZW50c291cmNlXG4gIHRocm93IG5ldyBFcnJvcignRXZlbnRTb3VyY2Ugbm90IGF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50LiBGb3IgTm9kZS5qcyBzdXBwb3J0LCBpbnN0YWxsIHRoZSBcImV2ZW50c291cmNlXCIgcGFja2FnZSBhbmQgaW1wb3J0IGl0IG1hbnVhbGx5LicpO1xufTtcblxuLy8gV2ViU29ja2V0IGNsaWVudCBmb3IgR3JhcGhRTCBzdWJzY3JpcHRpb25zIChncmFwaHFsLXdzIHByb3RvY29sKVxuY2xhc3MgR3JhcGhRTFN1YnNjcmlwdGlvbkNsaWVudCB7XG4gIHByaXZhdGUgd3M6IFdlYlNvY2tldCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVybDogc3RyaW5nO1xuICBwcml2YXRlIG9wdGlvbnM6IEh1bnRlclN1YnNjcmlwdGlvbk9wdGlvbnNUeXBlO1xuICBwcml2YXRlIHJlY29ubmVjdEF0dGVtcHRzID0gMDtcbiAgcHJpdmF0ZSByZWNvbm5lY3RUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBtZXNzYWdlUXVldWU6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zID0gbmV3IE1hcDxzdHJpbmcsIEh1bnRlclN1YnNjcmlwdGlvbkNhbGxiYWNrVHlwZT4oKTtcbiAgcHJpdmF0ZSBtZXNzYWdlSGFuZGxlcnMgPSBuZXcgTWFwPHN0cmluZywgKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcsIG9wdGlvbnM6IEh1bnRlclN1YnNjcmlwdGlvbk9wdGlvbnNUeXBlID0ge30pIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0VG9XZWJTb2NrZXRVcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwucmVwbGFjZSgvXmh0dHAvLCAnd3MnKS5yZXBsYWNlKC9eaHR0cHMvLCAnd3NzJyk7XG4gIH1cblxuICBwcml2YXRlIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmKHRoaXMuaXNDb25uZWN0aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gdHJ1ZTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgd3NVcmwgPSB0aGlzLmNvbnZlcnRUb1dlYlNvY2tldFVybCh0aGlzLnVybCk7XG5cbiAgICAgICAgaWYodHlwZW9mIFdlYlNvY2tldCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aGlzLmlzQ29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1dlYlNvY2tldCBub3QgYXZhaWxhYmxlIGluIHRoaXMgZW52aXJvbm1lbnQuIEZvciBOb2RlLmpzIHN1cHBvcnQsIHlvdSBtYXkgbmVlZCB0byBpbnN0YWxsIGEgV2ViU29ja2V0IGxpYnJhcnkuJykpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMud3MgPSBuZXcgV2ViU29ja2V0KHdzVXJsLCAnZ3JhcGhxbC13cycpO1xuXG4gICAgICAgIHRoaXMud3Mub25vcGVuID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5pc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgdGhpcy5yZWNvbm5lY3RBdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICBjb25zdCBpbml0TWVzc2FnZSA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdjb25uZWN0aW9uX2luaXQnLFxuICAgICAgICAgICAgcGF5bG9hZDogdGhpcy5vcHRpb25zLmNvbm5lY3Rpb25QYXJhbXMgfHwge31cbiAgICAgICAgICB9O1xuICAgICAgICAgIHRoaXMuc2VuZChKU09OLnN0cmluZ2lmeShpbml0TWVzc2FnZSkpO1xuXG4gICAgICAgICAgd2hpbGUodGhpcy5tZXNzYWdlUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IHRoaXMubWVzc2FnZVF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICBpZihtZXNzYWdlICYmIHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgICAgICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy53cy5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0Nvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy53cy5vbmNsb3NlID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuaGFuZGxlUmVjb25uZWN0KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy53cy5vbm1lc3NhZ2UgPSAoZXZlbnQ6IE1lc3NhZ2VFdmVudCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gSlNPTi5wYXJzZShldmVudC5kYXRhKTtcblxuICAgICAgICAgICAgaWYobWVzc2FnZS50eXBlID09PSAnY29ubmVjdGlvbl9hY2snKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYobWVzc2FnZS50eXBlID09PSAnY29ubmVjdGlvbl9lcnJvcicpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZS5wYXlsb2FkPy5tZXNzYWdlIHx8ICdDb25uZWN0aW9uIGVycm9yJyk7XG4gICAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChjYWxsYmFja3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZihjYWxsYmFja3Mub25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uSWQgPSBtZXNzYWdlLmlkO1xuICAgICAgICAgICAgY29uc3QgY2FsbGJhY2tzID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChzdWJzY3JpcHRpb25JZCk7XG5cbiAgICAgICAgICAgIGlmKGNhbGxiYWNrcykge1xuICAgICAgICAgICAgICBzd2l0Y2gobWVzc2FnZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICAgICAgICBpZihjYWxsYmFja3Mub25OZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrcy5vbk5leHQobWVzc2FnZS5wYXlsb2FkPy5kYXRhIHx8IG1lc3NhZ2UucGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgICAgICAgICAgICBpZihjYWxsYmFja3Mub25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBBcGlFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KG1lc3NhZ2UucGF5bG9hZCkgPyBtZXNzYWdlLnBheWxvYWQgOiBbbWVzc2FnZS5wYXlsb2FkXSxcbiAgICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoJ0dyYXBoUUwgc3Vic2NyaXB0aW9uIGVycm9yJylcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY29tcGxldGUnOlxuICAgICAgICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uQ29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMubWVzc2FnZUhhbmRsZXJzLmdldChzdWJzY3JpcHRpb25JZCk7XG4gICAgICAgICAgICAgICAgICBpZihoYW5kbGVyICYmIHRoaXMud3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53cy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzLmRlbGV0ZShzdWJzY3JpcHRpb25JZCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChjYWxsYmFja3MpID0+IHtcbiAgICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoJ1BhcnNlIGVycm9yJykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlY29ubmVjdCgpOiB2b2lkIHtcbiAgICBjb25zdCB7bWF4UmVjb25uZWN0QXR0ZW1wdHMgPSA1LCByZWNvbm5lY3RJbnRlcnZhbCA9IDEwMDB9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYodGhpcy5yZWNvbm5lY3RBdHRlbXB0cyA8IG1heFJlY29ubmVjdEF0dGVtcHRzICYmIHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplID4gMCkge1xuICAgICAgdGhpcy5yZWNvbm5lY3RBdHRlbXB0cysrO1xuXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgoY2FsbGJhY2tzKSA9PiB7XG4gICAgICAgIGlmKGNhbGxiYWNrcy5vblJlY29ubmVjdCkge1xuICAgICAgICAgIGNhbGxiYWNrcy5vblJlY29ubmVjdCh0aGlzLnJlY29ubmVjdEF0dGVtcHRzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5jb25uZWN0KCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICB9KTtcbiAgICAgIH0sIHJlY29ubmVjdEludGVydmFsKTtcbiAgICB9IGVsc2UgaWYodGhpcy5zdWJzY3JpcHRpb25zLnNpemUgPiAwKSB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignV2ViU29ja2V0IHJlY29ubmVjdGlvbiBmYWlsZWQgYWZ0ZXIgbWF4IGF0dGVtcHRzJyk7XG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgoY2FsbGJhY2tzKSA9PiB7XG4gICAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNlbmQobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYodGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU4pIHtcbiAgICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tZXNzYWdlUXVldWUucHVzaChtZXNzYWdlKTtcbiAgICAgIGlmKCF0aGlzLmlzQ29ubmVjdGluZyAmJiAhdGhpcy5pc0Nvbm5lY3RlZCkge1xuICAgICAgICB0aGlzLmNvbm5lY3QoKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN1YnNjcmliZShcbiAgICBxdWVyeTogc3RyaW5nLFxuICAgIHZhcmlhYmxlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQsXG4gICAgY2FsbGJhY2tzOiBIdW50ZXJTdWJzY3JpcHRpb25DYWxsYmFja1R5cGVcbiAgKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSWQgPSBgc3ViXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgOSl9YDtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5zZXQoc3Vic2NyaXB0aW9uSWQsIGNhbGxiYWNrcyk7XG5cbiAgICBjb25zdCBzdGFydE1lc3NhZ2UgPSB7XG4gICAgICBpZDogc3Vic2NyaXB0aW9uSWQsXG4gICAgICB0eXBlOiAnc3RhcnQnLFxuICAgICAgcGF5bG9hZDoge1xuICAgICAgICBxdWVyeSxcbiAgICAgICAgdmFyaWFibGVzOiB2YXJpYWJsZXMgfHwge31cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgZW5zdXJlQ29ubmVjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkICYmICF0aGlzLmlzQ29ubmVjdGluZykge1xuICAgICAgICB0aGlzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoc3RhcnRNZXNzYWdlKSk7XG4gICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZih0aGlzLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgIHRoaXMuc2VuZChKU09OLnN0cmluZ2lmeShzdGFydE1lc3NhZ2UpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZW5zdXJlQ29ubmVjdGlvbigpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3BNZXNzYWdlID0ge1xuICAgICAgICBpZDogc3Vic2NyaXB0aW9uSWQsXG4gICAgICAgIHR5cGU6ICdzdG9wJ1xuICAgICAgfTtcbiAgICAgIHRoaXMuc2VuZChKU09OLnN0cmluZ2lmeShzdG9wTWVzc2FnZSkpO1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb25JZCk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5tZXNzYWdlSGFuZGxlcnMuZ2V0KHN1YnNjcmlwdGlvbklkKTtcbiAgICAgIGlmKGhhbmRsZXIgJiYgdGhpcy53cykge1xuICAgICAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlcnMuZGVsZXRlKHN1YnNjcmlwdGlvbklkKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgY2xvc2UoKTogdm9pZCB7XG4gICAgaWYodGhpcy5yZWNvbm5lY3RUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVjb25uZWN0VGltZXIpO1xuICAgICAgdGhpcy5yZWNvbm5lY3RUaW1lciA9IG51bGw7XG4gICAgfVxuICAgIGlmKHRoaXMud3MpIHtcbiAgICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLm1lc3NhZ2VRdWV1ZSA9IFtdO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5jbGVhcigpO1xuICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzLmNsZWFyKCk7XG4gICAgdGhpcy5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gIH1cbn1cblxuLy8gU3Vic2NyaXB0aW9uIGNsaWVudCBjYWNoZVxuY29uc3Qgc3Vic2NyaXB0aW9uQ2xpZW50cyA9IG5ldyBNYXA8c3RyaW5nLCBHcmFwaFFMU3Vic2NyaXB0aW9uQ2xpZW50PigpO1xuXG4vLyBBSkFYXG5leHBvcnQgY29uc3QgYWpheCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIG1ldGhvZDogc3RyaW5nLFxuICBwYXJhbXM/LFxuICBvcHRpb25zOiBIdW50ZXJPcHRpb25zVHlwZSA9IHt9XG4pOiBQcm9taXNlPGFueT4gPT4ge1xuICBjb25zdCB7aGVhZGVycywgdG9rZW4sIHRpbWVvdXQgPSAzMDAwMCwgY2FjaGUgPSBmYWxzZX0gPSBvcHRpb25zO1xuXG4gIGxldCBmb3JtYXRVcmw6IHN0cmluZyA9ICh1cmwgfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0VG9rZW46IHN0cmluZyA9ICh0b2tlbiB8fCAnJykudHJpbSgpO1xuICBjb25zdCBmb3JtYXRIZWFkZXJzOiBIZWFkZXJzID0gaGVhZGVycyB8fCBuZXcgSGVhZGVycygpO1xuXG4gIC8vIE1ldGhvZFxuICBjb25zdCBmb3JtYXRNZXRob2Q6IHN0cmluZyA9IChtZXRob2QgfHwgJ0dFVCcpLnRvVXBwZXJDYXNlKCk7XG4gIGxldCBmb3JtYXRQYXJhbXM7XG5cbiAgLy8gUGFyYW1ldGVyc1xuICBpZihwYXJhbXMgJiYgZm9ybWF0TWV0aG9kID09PSAnR0VUJykge1xuICAgIGZvcm1hdFVybCA9IGAke2Zvcm1hdFVybH0/JHtxdWVyeVN0cmluZyhwYXJhbXMpfWA7XG4gICAgZm9ybWF0UGFyYW1zID0gbnVsbDtcbiAgfSBlbHNlIGlmKHBhcmFtcykge1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIGZvcm1hdFBhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gIH0gZWxzZSB7XG4gICAgZm9ybWF0UGFyYW1zID0gcGFyYW1zO1xuICB9XG5cbiAgLy8gQXV0aGVudGljYXRpb24gdG9rZW5cbiAgaWYoIWlzRW1wdHkoZm9ybWF0VG9rZW4pKSB7XG4gICAgZm9ybWF0SGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7Zm9ybWF0VG9rZW59YCk7XG4gIH1cblxuICAvLyBDaGVjayBjYWNoZSBmb3IgR0VUIHJlcXVlc3RzXG4gIGlmKGNhY2hlICYmIGZvcm1hdE1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGdlbmVyYXRlQ2FjaGVLZXkoZm9ybWF0VXJsLCBmb3JtYXRNZXRob2QsIHBhcmFtcywgb3B0aW9ucyk7XG4gICAgY29uc3QgY2FjaGVkID0gcmVxdWVzdENhY2hlLmdldChjYWNoZUtleSk7XG4gICAgaWYoY2FjaGVkKSB7XG4gICAgICByZXR1cm4gY2FjaGVkO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSB0aGUgcmVxdWVzdCBwcm9taXNlXG4gIGNvbnN0IHJlcXVlc3RQcm9taXNlID0gZmV0Y2goZm9ybWF0VXJsLCB7XG4gICAgYm9keTogZm9ybWF0UGFyYW1zLFxuICAgIGhlYWRlcnM6IGZvcm1hdEhlYWRlcnMsXG4gICAgbWV0aG9kOiBmb3JtYXRNZXRob2RcbiAgfSlcbiAgICAudGhlbigocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAvLyBDaGVjayBpZiByZXNwb25zZSBpcyBqc29uIHVzaW5nIGNhY2hlZCByZWdleFxuICAgICAgY29uc3QgaXNSZXNwb25zZUpzb24gPSBKU09OX0NPTlRFTlRfVFlQRV9SRUdFWC50ZXN0KFxuICAgICAgICByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJykgfHwgJydcbiAgICAgICk7XG5cbiAgICAgIGlmKGlzUmVzcG9uc2VKc29uKSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG4gICAgfSlcbiAgICAudGhlbigocmVzdWx0cykgPT4gcmVzdWx0cykgLy8gU2ltcGxpZmllZCAtIG5vIG5lZWQgZm9yIHJlZHVuZGFudCBjaGVja1xuICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIGlmKChlcnJvciB8fCB7fSkubWVzc2FnZSA9PT0gJ29ubHkgYWJzb2x1dGUgdXJscyBhcmUgc3VwcG9ydGVkJykge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgbmV3IEFwaUVycm9yKFt7bWVzc2FnZTogJ2ludmFsaWRfdXJsJ31dLCBlcnJvcilcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnbmV0d29ya19lcnJvcid9XSwgZXJyb3IpXG4gICAgICApO1xuICAgIH0pO1xuXG4gIC8vIEFkZCB0aW1lb3V0IGlmIHNwZWNpZmllZFxuICBjb25zdCBmaW5hbFByb21pc2UgPSB0aW1lb3V0ID4gMFxuICAgID8gUHJvbWlzZS5yYWNlKFtyZXF1ZXN0UHJvbWlzZSwgY3JlYXRlVGltZW91dCh0aW1lb3V0KV0pXG4gICAgOiByZXF1ZXN0UHJvbWlzZTtcblxuICAvLyBDYWNoZSB0aGUgcHJvbWlzZSBmb3IgR0VUIHJlcXVlc3RzXG4gIGlmKGNhY2hlICYmIGZvcm1hdE1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGdlbmVyYXRlQ2FjaGVLZXkoZm9ybWF0VXJsLCBmb3JtYXRNZXRob2QsIHBhcmFtcywgb3B0aW9ucyk7XG4gICAgcmVxdWVzdENhY2hlLnNldChjYWNoZUtleSwgZmluYWxQcm9taXNlKTtcblxuICAgIC8vIENsZWFuIHVwIGNhY2hlIGFmdGVyIDUgbWludXRlc1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcmVxdWVzdENhY2hlLmRlbGV0ZShjYWNoZUtleSksIDMwMDAwMCk7XG4gIH1cblxuICByZXR1cm4gZmluYWxQcm9taXNlO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHBhcmFtcz8sXG4gIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZVxuKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnR0VUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IHBvc3QgPSAoXG4gIHVybDogc3RyaW5nLFxuICBwYXJhbXM/LFxuICBvcHRpb25zPzogSHVudGVyT3B0aW9uc1R5cGVcbik6IFByb21pc2U8YW55PiA9PiBhamF4KHVybCwgJ1BPU1QnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG5leHBvcnQgY29uc3QgcHV0ID0gKFxuICB1cmw6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlXG4pOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdQVVQnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG5leHBvcnQgY29uc3QgZGVsID0gKFxuICB1cmw6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlXG4pOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdERUxFVEUnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG4vLyBPcHRpbWl6ZWQgdG9HcWwgZnVuY3Rpb25cbmV4cG9ydCBjb25zdCB0b0dxbCA9IChvYmo6IGFueSk6IHN0cmluZyA9PiB7XG4gIGlmKGlzU3RyaW5nKG9iaikpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqKTtcbiAgfSBlbHNlIGlmKGlzUGxhaW5PYmplY3Qob2JqKSkge1xuICAgIC8vIEZpbHRlciBvdXQgdW5kZWZpbmVkIGFuZCBudWxsIHZhbHVlcyBpbiBvbmUgcGFzc1xuICAgIGNvbnN0IGdxbFByb3BzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICAgIGlmKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBvYmpba2V5XTtcblxuICAgICAgICAvLyBTa2lwIHVuZGVmaW5lZCBhbmQgbnVsbCB2YWx1ZXNcbiAgICAgICAgaWYoaXNVbmRlZmluZWQoaXRlbSkgfHwgaXNOdWxsKGl0ZW0pKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZihpc1BsYWluT2JqZWN0KGl0ZW0pKSB7XG4gICAgICAgICAgZ3FsUHJvcHMucHVzaChgJHtrZXl9OiAke3RvR3FsKGl0ZW0pfWApO1xuICAgICAgICB9IGVsc2UgaWYoaXNBcnJheShpdGVtKSkge1xuICAgICAgICAgIGNvbnN0IGxpc3QgPSBpdGVtLm1hcCgobGlzdEl0ZW0pID0+IHRvR3FsKGxpc3RJdGVtKSk7XG4gICAgICAgICAgZ3FsUHJvcHMucHVzaChgJHtrZXl9OiBbJHtsaXN0LmpvaW4oJywgJyl9XWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHZhbCA9IEpTT04uc3RyaW5naWZ5KGl0ZW0pO1xuICAgICAgICAgIGlmKHZhbCkge1xuICAgICAgICAgICAgZ3FsUHJvcHMucHVzaChgJHtrZXl9OiAke3ZhbH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZXMgPSBncWxQcm9wcy5qb2luKCcsICcpO1xuICAgIHJldHVybiB2YWx1ZXMgPT09ICcnID8gJ1wiXCInIDogYHske2dxbFByb3BzLmpvaW4oJywgJyl9fWA7XG4gIH0gZWxzZSBpZihpc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gYFske29iai5tYXAoKG9iakl0ZW0pID0+IHRvR3FsKG9iakl0ZW0pKS5qb2luKCcsICcpfV1gO1xuICB9XG5cbiAgcmV0dXJuIFN0cmluZyhvYmopO1xufTtcblxuZXhwb3J0IGNvbnN0IGdyYXBocWxRdWVyeSA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHF1ZXJ5OiBIdW50ZXJRdWVyeVR5cGUgfCBIdW50ZXJRdWVyeVR5cGVbXSxcbiAgb3B0aW9uczogSHVudGVyT3B0aW9uc1R5cGUgPSB7fVxuKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgY29uc3Qge2hlYWRlcnMsIHRva2VuLCB0aW1lb3V0ID0gMzAwMDB9ID0gb3B0aW9ucztcbiAgY29uc3QgZm9ybWF0VXJsOiBzdHJpbmcgPSB1cmwgPyB1cmwudHJpbSgpIDogJyc7XG4gIGNvbnN0IGZvcm1hdFRva2VuOiBzdHJpbmcgPSAodG9rZW4gfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0SGVhZGVyczogSGVhZGVycyA9IGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoeydDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbid9KTtcblxuICBpZighaXNFbXB0eShmb3JtYXRUb2tlbikpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHtmb3JtYXRUb2tlbn1gKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3RQcm9taXNlID0gZmV0Y2goZm9ybWF0VXJsLCB7XG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkocXVlcnkpLFxuICAgIGhlYWRlcnM6IGZvcm1hdEhlYWRlcnMsXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgfSlcbiAgICAudGhlbigocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCBpc0pzb246IGJvb2xlYW4gPSBKU09OX0NPTlRFTlRfVFlQRV9SRUdFWC50ZXN0KFxuICAgICAgICByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJykgfHwgJydcbiAgICAgICk7XG5cbiAgICAgIGlmKGlzSnNvbiAmJiByZXNwb25zZS5ib2R5KSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgaWYoKGVycm9yIHx8IHt9KS5tZXNzYWdlID09PSAnb25seSBhYnNvbHV0ZSB1cmxzIGFyZSBzdXBwb3J0ZWQnKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnaW52YWxpZF91cmwnfV0sIGVycm9yKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICduZXR3b3JrX2Vycm9yJ31dLCBlcnJvcilcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbigoanNvbikgPT4ge1xuICAgICAgaWYoIWpzb24gfHwganNvbi5lcnJvcnMpIHtcbiAgICAgICAgaWYoIWpzb24pIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnYXBpX2Vycm9yJ31dLCBuZXcgRXJyb3IoKSlcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYoXG4gICAgICAgICAgKGpzb24uZXJyb3JzIHx8IFtdKS5zb21lKFxuICAgICAgICAgICAgKGVycm9yKSA9PiBlcnJvci5tZXNzYWdlID09PSAnTXVzdCBwcm92aWRlIHF1ZXJ5IHN0cmluZy4nXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAncmVxdWlyZWRfcXVlcnknfV0sIG5ldyBFcnJvcigpKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ganNvbi5lcnJvcnNcbiAgICAgICAgICA/IFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihqc29uLmVycm9ycywgbmV3IEVycm9yKCkpKVxuICAgICAgICAgIDoge307XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBqc29uLmRhdGEgfHwge307XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yOiBBcGlFcnJvcikgPT5cbiAgICAgIC8vIFNpbXBsaWZpZWQgZXJyb3IgaGFuZGxpbmcgLSBubyBuZWVkIHRvIGNyZWF0ZSBuZXcgZXJyb3IgaWYgc291cmNlIGV4aXN0c1xuICAgICAgUHJvbWlzZS5yZWplY3QoZXJyb3Iuc291cmNlID8gZXJyb3IgOiBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnbmV0d29ya19lcnJvcid9XSwgZXJyb3IpKVxuICAgICk7XG5cbiAgLy8gQWRkIHRpbWVvdXQgaWYgc3BlY2lmaWVkXG4gIHJldHVybiB0aW1lb3V0ID4gMFxuICAgID8gUHJvbWlzZS5yYWNlKFtyZXF1ZXN0UHJvbWlzZSwgY3JlYXRlVGltZW91dCh0aW1lb3V0KV0pXG4gICAgOiByZXF1ZXN0UHJvbWlzZTtcbn07XG5cbi8vIEFkZCBxdWVyeSBhbmQgbXV0YXRpb24gZnVuY3Rpb25zIGZvciBiZXR0ZXIgQVBJIGNvbnNpc3RlbmN5XG5leHBvcnQgY29uc3QgcXVlcnkgPSAoXG4gIHVybDogc3RyaW5nLFxuICBib2R5OiBzdHJpbmcsXG4gIG9wdGlvbnM6IEh1bnRlck9wdGlvbnNUeXBlID0ge31cbik6IFByb21pc2U8YW55PiA9PiBncmFwaHFsUXVlcnkodXJsLCB7cXVlcnk6IGJvZHl9LCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IG11dGF0aW9uID0gKFxuICB1cmw6IHN0cmluZyxcbiAgYm9keTogc3RyaW5nLFxuICBvcHRpb25zOiBIdW50ZXJPcHRpb25zVHlwZSA9IHt9XG4pOiBQcm9taXNlPGFueT4gPT4gZ3JhcGhxbFF1ZXJ5KHVybCwge3F1ZXJ5OiBib2R5fSwgb3B0aW9ucyk7XG5cbi8vIEdyYXBoUUwgU3Vic2NyaXB0aW9uc1xuZXhwb3J0IGNvbnN0IHN1YnNjcmliZSA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHF1ZXJ5OiBzdHJpbmcsXG4gIGNhbGxiYWNrczogSHVudGVyU3Vic2NyaXB0aW9uQ2FsbGJhY2tUeXBlLFxuICBvcHRpb25zOiBIdW50ZXJTdWJzY3JpcHRpb25PcHRpb25zVHlwZSA9IHt9XG4pOiAoKCkgPT4gdm9pZCkgPT4ge1xuICBjb25zdCB7dG9rZW4sIHZhcmlhYmxlcywgY29ubmVjdGlvblBhcmFtcywgaGVhZGVyc30gPSBvcHRpb25zO1xuICBjb25zdCBmb3JtYXRVcmw6IHN0cmluZyA9ICh1cmwgfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0VG9rZW46IHN0cmluZyA9ICh0b2tlbiB8fCAnJykudHJpbSgpO1xuXG4gIGlmKCFmb3JtYXRVcmwpIHtcbiAgICBpZihjYWxsYmFja3Mub25FcnJvcikge1xuICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTdWJzY3JpcHRpb24gVVJMIGlzIHJlcXVpcmVkJykpO1xuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge307XG4gIH1cblxuICBsZXQgY2xpZW50ID0gc3Vic2NyaXB0aW9uQ2xpZW50cy5nZXQoZm9ybWF0VXJsKTtcbiAgaWYoIWNsaWVudCkge1xuICAgIGNvbnN0IGNsaWVudE9wdGlvbnM6IEh1bnRlclN1YnNjcmlwdGlvbk9wdGlvbnNUeXBlID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGNvbm5lY3Rpb25QYXJhbXM6IHtcbiAgICAgICAgLi4uY29ubmVjdGlvblBhcmFtcyxcbiAgICAgICAgLi4uKGZvcm1hdFRva2VuID8ge2F1dGhvcml6YXRpb246IGBCZWFyZXIgJHtmb3JtYXRUb2tlbn1gfSA6IHt9KVxuICAgICAgfVxuICAgIH07XG4gICAgY2xpZW50ID0gbmV3IEdyYXBoUUxTdWJzY3JpcHRpb25DbGllbnQoZm9ybWF0VXJsLCBjbGllbnRPcHRpb25zKTtcbiAgICBzdWJzY3JpcHRpb25DbGllbnRzLnNldChmb3JtYXRVcmwsIGNsaWVudCk7XG4gIH1cblxuICByZXR1cm4gY2xpZW50LnN1YnNjcmliZShxdWVyeSwgdmFyaWFibGVzLCBjYWxsYmFja3MpO1xufTtcblxuLy8gU1NFIFN1cHBvcnRcbmV4cG9ydCBjb25zdCBzdWJzY3JpYmVTU0UgPSAoXG4gIHVybDogc3RyaW5nLFxuICBjYWxsYmFja3M6IEh1bnRlclNTRUNhbGxiYWNrVHlwZSxcbiAgb3B0aW9uczogSHVudGVyU1NFT3B0aW9uc1R5cGUgPSB7fVxuKTogKCgpID0+IHZvaWQpID0+IHtcbiAgY29uc3Qge2hlYWRlcnMsIHRva2VuLCB0aW1lb3V0ID0gMzAwMDAsIHJldHJ5SW50ZXJ2YWwgPSAxMDAwLCBtYXhSZXRyaWVzID0gNX0gPSBvcHRpb25zO1xuICBjb25zdCBmb3JtYXRVcmw6IHN0cmluZyA9ICh1cmwgfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0VG9rZW46IHN0cmluZyA9ICh0b2tlbiB8fCAnJykudHJpbSgpO1xuICBjb25zdCBmb3JtYXRIZWFkZXJzOiBIZWFkZXJzID0gaGVhZGVycyB8fCBuZXcgSGVhZGVycygpO1xuXG4gIC8vIEFkZCBhdXRob3JpemF0aW9uIGhlYWRlciBpZiB0b2tlbiBwcm92aWRlZFxuICBpZighaXNFbXB0eShmb3JtYXRUb2tlbikpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHtmb3JtYXRUb2tlbn1gKTtcbiAgfVxuXG4gIGxldCByZXRyeUNvdW50ID0gMDtcbiAgbGV0IGV2ZW50U291cmNlOiBFdmVudFNvdXJjZSB8IG51bGwgPSBudWxsO1xuICBsZXQgdGltZW91dElkOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IGNvbm5lY3QgPSAoKTogdm9pZCA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGV2ZW50U291cmNlID0gY3JlYXRlRXZlbnRTb3VyY2UoZm9ybWF0VXJsLCB7aGVhZGVyczogZm9ybWF0SGVhZGVyc30pO1xuXG4gICAgICAvLyBTZXQgdXAgdGltZW91dFxuICAgICAgaWYodGltZW91dCA+IDApIHtcbiAgICAgICAgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYoZXZlbnRTb3VyY2UpIHtcbiAgICAgICAgICAgIGV2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICAgICAgICBpZihjYWxsYmFja3Mub25FcnJvcikge1xuICAgICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihuZXcgRXJyb3IoJ1NTRSBjb25uZWN0aW9uIHRpbWVvdXQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgIH1cblxuICAgICAgLy8gRXZlbnQgaGFuZGxlcnNcbiAgICAgIGV2ZW50U291cmNlLm9ub3BlbiA9IChldmVudCkgPT4ge1xuICAgICAgICBpZih0aW1lb3V0SWQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgICB0aW1lb3V0SWQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHJ5Q291bnQgPSAwOyAvLyBSZXNldCByZXRyeSBjb3VudCBvbiBzdWNjZXNzZnVsIGNvbm5lY3Rpb25cbiAgICAgICAgaWYoY2FsbGJhY2tzLm9uT3Blbikge1xuICAgICAgICAgIGNhbGxiYWNrcy5vbk9wZW4oZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBldmVudFNvdXJjZS5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYoY2FsbGJhY2tzLm9uTWVzc2FnZSkge1xuICAgICAgICAgIGNvbnN0IHNzZUV2ZW50OiBIdW50ZXJTU0VFdmVudFR5cGUgPSB7XG4gICAgICAgICAgICBkYXRhOiBldmVudC5kYXRhLFxuICAgICAgICAgICAgaWQ6IGV2ZW50Lmxhc3RFdmVudElkLFxuICAgICAgICAgICAgcmV0cnk6IGV2ZW50LmRhdGEuaW5jbHVkZXMoJ3JldHJ5OicpID8gcGFyc2VJbnQoZXZlbnQuZGF0YS5zcGxpdCgncmV0cnk6JylbMV0pIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdHlwZTogZXZlbnQudHlwZVxuICAgICAgICAgIH07XG4gICAgICAgICAgY2FsbGJhY2tzLm9uTWVzc2FnZShzc2VFdmVudCk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGV2ZW50U291cmNlLm9uZXJyb3IgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYodGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGV2ZW50U291cmNlICYmIGV2ZW50U291cmNlLnJlYWR5U3RhdGUgPT09IEV2ZW50U291cmNlLkNMT1NFRCkge1xuICAgICAgICAgIC8vIENvbm5lY3Rpb24gY2xvc2VkLCBhdHRlbXB0IHJldHJ5IGlmIHdpdGhpbiBsaW1pdHNcbiAgICAgICAgICBpZihyZXRyeUNvdW50IDwgbWF4UmV0cmllcykge1xuICAgICAgICAgICAgcmV0cnlDb3VudCsrO1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uUmV0cnkpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uUmV0cnkocmV0cnlDb3VudCwgcmV0cnlJbnRlcnZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGNvbm5lY3QsIHJldHJ5SW50ZXJ2YWwpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZihjYWxsYmFja3Mub25FcnJvcikge1xuICAgICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihuZXcgRXJyb3IoJ1NTRSBjb25uZWN0aW9uIGZhaWxlZCBhZnRlciBtYXggcmV0cmllcycpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5vbkVycm9yKGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIFNTRSBjb25uZWN0aW9uJykpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBTdGFydCB0aGUgY29ubmVjdGlvblxuICBjb25uZWN0KCk7XG5cbiAgLy8gUmV0dXJuIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuICgpID0+IHtcbiAgICBpZih0aW1lb3V0SWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICB9XG4gICAgaWYoZXZlbnRTb3VyY2UpIHtcbiAgICAgIGV2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICBldmVudFNvdXJjZSA9IG51bGw7XG4gICAgfVxuICB9O1xufTtcblxuZXhwb3J0IHtBcGlFcnJvcn0gZnJvbSAnLi9lcnJvcnMvQXBpRXJyb3IuanMnO1xuIl0sIm5hbWVzIjpbIkFwaUVycm9yIiwiaXNBcnJheSIsInZhbHVlIiwiQXJyYXkiLCJpc1N0cmluZyIsImlzUGxhaW5PYmplY3QiLCJpc0VtcHR5IiwidW5kZWZpbmVkIiwiaXNOdWxsIiwiaXNVbmRlZmluZWQiLCJKU09OX0NPTlRFTlRfVFlQRV9SRUdFWCIsInJlcXVlc3RDYWNoZSIsIk1hcCIsInJlbW92ZVNwYWNlcyIsInN0ciIsInJlcGxhY2UiLCJxdWVyeVN0cmluZyIsImpzb24iLCJPYmplY3QiLCJrZXlzIiwibWFwIiwia2V5IiwiZW5jb2RlVVJJQ29tcG9uZW50Iiwiam9pbiIsImNyZWF0ZVRpbWVvdXQiLCJtcyIsIlByb21pc2UiLCJfIiwicmVqZWN0Iiwic2V0VGltZW91dCIsIkVycm9yIiwiZ2VuZXJhdGVDYWNoZUtleSIsInVybCIsIm1ldGhvZCIsInBhcmFtcyIsIm9wdGlvbnMiLCJKU09OIiwic3RyaW5naWZ5IiwiYnRvYSIsInNsaWNlIiwiY3JlYXRlRXZlbnRTb3VyY2UiLCJFdmVudFNvdXJjZSIsIkdyYXBoUUxTdWJzY3JpcHRpb25DbGllbnQiLCJ3cyIsInJlY29ubmVjdEF0dGVtcHRzIiwicmVjb25uZWN0VGltZXIiLCJtZXNzYWdlUXVldWUiLCJpc0Nvbm5lY3RpbmciLCJpc0Nvbm5lY3RlZCIsInN1YnNjcmlwdGlvbnMiLCJtZXNzYWdlSGFuZGxlcnMiLCJjb252ZXJ0VG9XZWJTb2NrZXRVcmwiLCJjb25uZWN0IiwicmVzb2x2ZSIsIndzVXJsIiwiV2ViU29ja2V0Iiwib25vcGVuIiwiaW5pdE1lc3NhZ2UiLCJ0eXBlIiwicGF5bG9hZCIsImNvbm5lY3Rpb25QYXJhbXMiLCJzZW5kIiwibGVuZ3RoIiwibWVzc2FnZSIsInNoaWZ0IiwicmVhZHlTdGF0ZSIsIk9QRU4iLCJvbmVycm9yIiwiZXJyb3IiLCJvbmNsb3NlIiwiaGFuZGxlUmVjb25uZWN0Iiwib25tZXNzYWdlIiwiZXZlbnQiLCJwYXJzZSIsImRhdGEiLCJmb3JFYWNoIiwiY2FsbGJhY2tzIiwib25FcnJvciIsInN1YnNjcmlwdGlvbklkIiwiaWQiLCJnZXQiLCJvbk5leHQiLCJvbkNvbXBsZXRlIiwiZGVsZXRlIiwiaGFuZGxlciIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJtYXhSZWNvbm5lY3RBdHRlbXB0cyIsInJlY29ubmVjdEludGVydmFsIiwic2l6ZSIsIm9uUmVjb25uZWN0IiwiY2F0Y2giLCJwdXNoIiwic3Vic2NyaWJlIiwicXVlcnkiLCJ2YXJpYWJsZXMiLCJEYXRlIiwibm93IiwiTWF0aCIsInJhbmRvbSIsInRvU3RyaW5nIiwic3Vic3RyIiwic2V0Iiwic3RhcnRNZXNzYWdlIiwiZW5zdXJlQ29ubmVjdGlvbiIsInRoZW4iLCJzdG9wTWVzc2FnZSIsImNsb3NlIiwiY2xlYXJUaW1lb3V0IiwiY2xlYXIiLCJzdWJzY3JpcHRpb25DbGllbnRzIiwiYWpheCIsImhlYWRlcnMiLCJ0b2tlbiIsInRpbWVvdXQiLCJjYWNoZSIsImZvcm1hdFVybCIsInRyaW0iLCJmb3JtYXRUb2tlbiIsImZvcm1hdEhlYWRlcnMiLCJIZWFkZXJzIiwiZm9ybWF0TWV0aG9kIiwidG9VcHBlckNhc2UiLCJmb3JtYXRQYXJhbXMiLCJjYWNoZUtleSIsImNhY2hlZCIsInJlcXVlc3RQcm9taXNlIiwiZmV0Y2giLCJib2R5IiwicmVzcG9uc2UiLCJpc1Jlc3BvbnNlSnNvbiIsInRlc3QiLCJ0ZXh0IiwicmVzdWx0cyIsImZpbmFsUHJvbWlzZSIsInJhY2UiLCJwb3N0IiwicHV0IiwiZGVsIiwidG9HcWwiLCJvYmoiLCJncWxQcm9wcyIsImhhc093blByb3BlcnR5IiwiaXRlbSIsImxpc3QiLCJsaXN0SXRlbSIsInZhbCIsInZhbHVlcyIsIm9iakl0ZW0iLCJTdHJpbmciLCJncmFwaHFsUXVlcnkiLCJpc0pzb24iLCJlcnJvcnMiLCJzb21lIiwic291cmNlIiwibXV0YXRpb24iLCJjbGllbnQiLCJjbGllbnRPcHRpb25zIiwiYXV0aG9yaXphdGlvbiIsInN1YnNjcmliZVNTRSIsInJldHJ5SW50ZXJ2YWwiLCJtYXhSZXRyaWVzIiwicmV0cnlDb3VudCIsImV2ZW50U291cmNlIiwidGltZW91dElkIiwib25PcGVuIiwib25NZXNzYWdlIiwic3NlRXZlbnQiLCJsYXN0RXZlbnRJZCIsInJldHJ5IiwiaW5jbHVkZXMiLCJwYXJzZUludCIsInNwbGl0IiwiQ0xPU0VEIiwib25SZXRyeSJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBRUQsU0FBUUEsUUFBUSxRQUFPLHVCQUF1QjtBQUU5QyxNQUFNQyxVQUFVLENBQUNDLFFBQStCQyxNQUFNRixPQUFPLENBQUNDO0FBQzlELE1BQU1FLFdBQVcsQ0FBQ0YsUUFBZ0MsT0FBT0EsVUFBVTtBQUNuRSxNQUFNRyxnQkFBZ0IsQ0FBQ0gsUUFDckJBLFVBQVUsUUFBUSxPQUFPQSxVQUFVLFlBQVksQ0FBQ0QsUUFBUUM7QUFDMUQsTUFBTUksVUFBVSxDQUFDSixRQUNmQSxVQUFVLFFBQVFBLFVBQVVLLGFBQWFMLFVBQVU7QUFDckQsTUFBTU0sU0FBUyxDQUFDTixRQUF3QkEsVUFBVTtBQUNsRCxNQUFNTyxjQUFjLENBQUNQLFFBQXdCQSxVQUFVSztBQUV2RCxvQ0FBb0M7QUFDcEMsTUFBTUcsMEJBQTBCO0FBRWhDLGtDQUFrQztBQUNsQyxNQUFNQyxlQUFlLElBQUlDO0FBc0R6QixPQUFPLE1BQU1DLGVBQWUsQ0FBQ0MsTUFDM0JBLElBQUlDLE9BQU8sQ0FBQyw2Q0FBNkMsSUFBSTtBQUUvRCxPQUFPLE1BQU1DLGNBQWMsQ0FBQ0MsT0FDMUJDLE9BQU9DLElBQUksQ0FBQ0YsTUFDVEcsR0FBRyxDQUNGLENBQUNDLE1BQ0MsR0FBR0MsbUJBQW1CRCxLQUFLLENBQUMsRUFBRUMsbUJBQW1CTCxJQUFJLENBQUNJLElBQUksR0FBRyxFQUVoRUUsSUFBSSxDQUFDLEtBQUs7QUFFZiwyQkFBMkI7QUFDM0IsTUFBTUMsZ0JBQWdCLENBQUNDLEtBQ3JCLElBQUlDLFFBQVEsQ0FBQ0MsR0FBR0MsU0FDZEMsV0FBVyxJQUFNRCxPQUFPLElBQUlFLE1BQU0scUJBQXFCTDtBQUczRCwrQ0FBK0M7QUFDL0MsTUFBTU0sbUJBQW1CLENB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlabs/rip-hunter",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "JS utilities for AJAX and GraphQL",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -64,14 +64,24 @@
64
64
  "benchmark": "node --experimental-modules ./benchmark.js"
65
65
  },
66
66
  "optionalDependencies": {
67
- "eventsource": "^2.0.2"
67
+ "eventsource": "^4.1.0"
68
68
  },
69
69
  "devDependencies": {
70
- "@jest/globals": "30.0.4",
71
- "@nlabs/lex": "1.47.2",
70
+ "@jest/globals": "30.2.0",
72
71
  "@nlabs/fetch-mock": "1.0.2",
72
+ "@nlabs/lex": "1.53.2",
73
73
  "@types/jest": "30.0.0",
74
- "@types/node": "24.0.12",
75
- "typescript": "5.8.3"
74
+ "@types/node": "25.0.8",
75
+ "jest-websocket-mock": "^2.5.0",
76
+ "typescript": "5.9.3"
77
+ },
78
+ "overrides": {
79
+ "cross-spawn": "^7.0.6",
80
+ "got": "^14.6.6",
81
+ "http-cache-semantics": "^4.2.0",
82
+ "http-proxy-middleware": "^3.0.5",
83
+ "postcss": "^8.5.6",
84
+ "semver-regex": "^4.0.5",
85
+ "tmp": "^0.2.5"
76
86
  }
77
87
  }