fetch-retrier 0.2.10 → 0.3.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.
- package/README.md +49 -23
- package/lib/index.d.ts +57 -16
- package/lib/index.js +41 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Fetch Retrier
|
|
2
2
|
|
|
3
|
-
A lightweight wrapper around `fetch` that adds **retries**, **timeout**, and **full jitter** backoff.
|
|
3
|
+
A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeout**, and **full jitter** backoff. Pass standard `RequestInit` options (`method`, `body`, `credentials`, and more) for POST/PUT APIs and other HTTP calls that may be rate-limited (429) or temporarily unavailable (5xx).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
6
6
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
@@ -10,11 +10,14 @@ A lightweight wrapper around `fetch` that adds **retries**, **timeout**, and **f
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
12
|
- **Configurable retries** – Set the maximum number of attempts per request.
|
|
13
|
-
- **Per-
|
|
13
|
+
- **Per-attempt timeout** – Abort each attempt when it exceeds a given duration.
|
|
14
14
|
- **Full jitter backoff** – Exponential backoff with random jitter (AWS-style) between retries.
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
15
|
+
- **RequestInit forwarding** – Pass `method`, `body`, `credentials`, `redirect`, and other `fetch` options via `init` on every attempt.
|
|
16
|
+
- **Header shorthand** – Optional top-level `headers` override `init.headers` when both are set.
|
|
17
|
+
- **Custom retry predicate** – Control which responses trigger a retry (default: 429, 500, 502, 503, 504).
|
|
18
|
+
- **External cancellation** – Pass an `AbortSignal` to cancel in-flight requests.
|
|
19
|
+
- **Typed errors** – `FetchRetrierHttpError`, `FetchRetrierNetworkError`, `FetchRetrierAbortError`, and related classes.
|
|
20
|
+
- **TypeScript** – Exported types including `RequestOptions` and `FetchInitOptions`.
|
|
18
21
|
|
|
19
22
|
## Installation
|
|
20
23
|
|
|
@@ -32,6 +35,8 @@ yarn add fetch-retrier
|
|
|
32
35
|
|
|
33
36
|
## Usage
|
|
34
37
|
|
|
38
|
+
### GET request
|
|
39
|
+
|
|
35
40
|
```typescript
|
|
36
41
|
import { fetchRetrier, RequestOptions } from 'fetch-retrier';
|
|
37
42
|
|
|
@@ -40,7 +45,7 @@ const options: RequestOptions = {
|
|
|
40
45
|
timeoutMs: 5000,
|
|
41
46
|
baseBackoffMs: 1000,
|
|
42
47
|
headers: {
|
|
43
|
-
|
|
48
|
+
Authorization: 'Bearer token',
|
|
44
49
|
},
|
|
45
50
|
};
|
|
46
51
|
|
|
@@ -48,20 +53,30 @@ const response = await fetchRetrier('https://api.example.com/data', options);
|
|
|
48
53
|
|
|
49
54
|
if (response.ok) {
|
|
50
55
|
const data = await response.json();
|
|
51
|
-
// ...
|
|
52
56
|
}
|
|
53
57
|
```
|
|
54
58
|
|
|
55
|
-
###
|
|
59
|
+
### POST with JSON body (`init`)
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
```typescript
|
|
62
|
+
import { fetchRetrier } from 'fetch-retrier';
|
|
63
|
+
|
|
64
|
+
const response = await fetchRetrier('https://api.example.com/items', {
|
|
65
|
+
retries: 3,
|
|
66
|
+
timeoutMs: 5000,
|
|
67
|
+
baseBackoffMs: 1000,
|
|
68
|
+
init: {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: { 'Content-Type': 'application/json' },
|
|
71
|
+
body: JSON.stringify({ name: 'example' }),
|
|
72
|
+
credentials: 'include',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const item = await response.json();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The same `init` (including `body`) is applied on every retry attempt. Per-attempt `signal` and timeout are managed internally.
|
|
65
80
|
|
|
66
81
|
### Custom retry logic
|
|
67
82
|
|
|
@@ -71,7 +86,6 @@ const response = await fetchRetrier('https://api.example.com/data', {
|
|
|
71
86
|
timeoutMs: 10000,
|
|
72
87
|
baseBackoffMs: 500,
|
|
73
88
|
shouldRetry: (res, body) => {
|
|
74
|
-
// Retry on rate limit or server errors, or when body indicates "retry later"
|
|
75
89
|
if ([429, 500, 502, 503].includes(res.status)) return true;
|
|
76
90
|
if (res.status === 200 && body.includes('"retry": true')) return true;
|
|
77
91
|
return false;
|
|
@@ -94,19 +108,31 @@ await fetchRetrier('https://api.example.com/data', {
|
|
|
94
108
|
});
|
|
95
109
|
```
|
|
96
110
|
|
|
97
|
-
|
|
111
|
+
### Retry and error behavior
|
|
98
112
|
|
|
99
113
|
- **Success** – If `response.ok` is true, the response is returned immediately.
|
|
100
114
|
- **Retriable failure** – If the response is not OK and `shouldRetry(response, body)` returns true, the client waits (full jitter backoff) and retries until `retries` is exhausted. On the last attempt, `FetchRetrierHttpError` is thrown (includes `status`).
|
|
101
|
-
- **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately (e.g.
|
|
102
|
-
- **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried
|
|
103
|
-
- **Network/TypeError** – Network errors
|
|
104
|
-
- **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown
|
|
115
|
+
- **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately (e.g. `Non-retriable HTTP error: 404`).
|
|
116
|
+
- **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried until `retries` is exhausted; the final failure is `FetchRetrierAbortError`.
|
|
117
|
+
- **Network / TypeError** – Network errors are retried with backoff; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
|
|
118
|
+
- **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown (no attempt is made).
|
|
119
|
+
|
|
120
|
+
## Options
|
|
121
|
+
|
|
122
|
+
| Option | Type | Required | Description |
|
|
123
|
+
|--------|------|----------|-------------|
|
|
124
|
+
| `retries` | `number` | Yes | Maximum number of attempts (including the first request). |
|
|
125
|
+
| `timeoutMs` | `number` | Yes | Timeout in milliseconds for each attempt. Exceeded attempts are aborted and retried. |
|
|
126
|
+
| `baseBackoffMs` | `number` | Yes | Base delay in milliseconds for backoff. Delay is capped at `baseBackoffMs * 2^attempt` and randomized (full jitter). |
|
|
127
|
+
| `init` | `FetchInitOptions` | No | `fetch` options forwarded to every attempt: `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, etc. `signal` is reserved for internal timeout and cancellation. |
|
|
128
|
+
| `headers` | `Record<string, string>` | No | Headers sent on every attempt. Overrides `init.headers` when both are set. |
|
|
129
|
+
| `signal` | `AbortSignal` | No | External abort signal. If already aborted, `FetchRetrierAlreadyAbortedError` is thrown. If aborted during an attempt, the request is aborted and retried until `retries` is exhausted. |
|
|
130
|
+
| `shouldRetry` | `(response: Response, body: string) => boolean` | No | Called after `response.text()` when `response.ok` is false. Return `true` to retry. Default: 429, 500, 502, 503, 504. |
|
|
105
131
|
|
|
106
132
|
## Requirements
|
|
107
133
|
|
|
108
134
|
- **Node.js** >= 20.0.0
|
|
109
|
-
- Uses the global `fetch` (available in Node 18+)
|
|
135
|
+
- Uses the global `fetch` (available in Node 18+)
|
|
110
136
|
|
|
111
137
|
## License
|
|
112
138
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, and typed errors.
|
|
3
|
+
*
|
|
4
|
+
* @module fetch-retrier
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* `fetch` options forwarded to every attempt, excluding `signal`.
|
|
8
|
+
*
|
|
9
|
+
* Use for `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, and other
|
|
10
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/RequestInit | RequestInit} fields.
|
|
11
|
+
* Per-attempt abort and timeout are handled internally via `signal` and must not be set here.
|
|
12
|
+
*/
|
|
13
|
+
export type FetchInitOptions = Omit<RequestInit, 'signal'>;
|
|
14
|
+
/**
|
|
15
|
+
* Options for {@link fetchRetrier}: retry policy, timeout, backoff, request payload, and cancellation.
|
|
16
|
+
*
|
|
17
|
+
* Request shape is built as `{ ...init, headers?, signal }` on each attempt. Top-level `headers`
|
|
18
|
+
* override `init.headers` when both are provided.
|
|
3
19
|
*/
|
|
4
20
|
export interface RequestOptions {
|
|
5
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* HTTP headers sent on every attempt.
|
|
23
|
+
* When `init.headers` is also set, these values take precedence for duplicate keys.
|
|
24
|
+
*/
|
|
6
25
|
headers?: Record<string, string>;
|
|
26
|
+
/**
|
|
27
|
+
* Additional {@link FetchInitOptions} merged into each `fetch` call (e.g. POST `method` and JSON `body`).
|
|
28
|
+
* The same `init` is reused across retries.
|
|
29
|
+
*/
|
|
30
|
+
init?: FetchInitOptions;
|
|
7
31
|
/** Maximum number of attempts, including the first. */
|
|
8
32
|
retries: number;
|
|
9
33
|
/** Per-attempt timeout in milliseconds; uses an internal {@link AbortController} when exceeded. */
|
|
@@ -18,12 +42,18 @@ export interface RequestOptions {
|
|
|
18
42
|
*/
|
|
19
43
|
signal?: AbortSignal;
|
|
20
44
|
/**
|
|
21
|
-
*
|
|
45
|
+
* Invoked after `response.text()` when `response.ok` is false.
|
|
46
|
+
* Return `true` to schedule another attempt (until `retries` is exhausted).
|
|
22
47
|
* Default: retry on status 429, 500, 502, 503, or 504.
|
|
48
|
+
*
|
|
49
|
+
* @param response - Non-OK response from the current attempt
|
|
50
|
+
* @param body - Response body text from `response.text()`
|
|
23
51
|
*/
|
|
24
52
|
shouldRetry?: (response: Response, body: string) => boolean;
|
|
25
53
|
}
|
|
26
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}.
|
|
56
|
+
*/
|
|
27
57
|
export declare class FetchRetrierAbortError extends Error {
|
|
28
58
|
readonly name: string;
|
|
29
59
|
/**
|
|
@@ -41,29 +71,37 @@ export declare class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortEr
|
|
|
41
71
|
*/
|
|
42
72
|
constructor(message?: string);
|
|
43
73
|
}
|
|
44
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
|
|
76
|
+
*
|
|
77
|
+
* @property status - HTTP status code from the last non-OK response
|
|
78
|
+
*/
|
|
45
79
|
export declare class FetchRetrierHttpError extends Error {
|
|
46
80
|
readonly status: number;
|
|
47
81
|
readonly name: string;
|
|
48
82
|
/**
|
|
49
83
|
* @param message - Error description
|
|
50
|
-
* @param status - HTTP status code from the response
|
|
84
|
+
* @param status - HTTP status code from the last non-OK response
|
|
51
85
|
*/
|
|
52
86
|
constructor(message: string, status: number);
|
|
53
87
|
}
|
|
54
88
|
/**
|
|
55
89
|
* Error thrown when a fetch fails with a network-level error (e.g. DNS failure, connection refused).
|
|
90
|
+
*
|
|
91
|
+
* @property cause - Original error from the underlying `fetch`, when available
|
|
56
92
|
*/
|
|
57
93
|
export declare class FetchRetrierNetworkError extends Error {
|
|
58
94
|
readonly cause?: unknown | undefined;
|
|
59
95
|
readonly name: string;
|
|
60
96
|
/**
|
|
61
97
|
* @param message - Human-readable reason (default: `'Network error'`)
|
|
62
|
-
* @param cause - Original error
|
|
98
|
+
* @param cause - Original error from the underlying `fetch`, when available
|
|
63
99
|
*/
|
|
64
100
|
constructor(message?: string, cause?: unknown | undefined);
|
|
65
101
|
}
|
|
66
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Error thrown when an internal invariant fails (should not happen in normal use).
|
|
104
|
+
*/
|
|
67
105
|
export declare class FetchRetrierUnreachableError extends Error {
|
|
68
106
|
readonly name: string;
|
|
69
107
|
/**
|
|
@@ -72,17 +110,20 @@ export declare class FetchRetrierUnreachableError extends Error {
|
|
|
72
110
|
constructor(message?: string);
|
|
73
111
|
}
|
|
74
112
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
113
|
+
* Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
|
|
114
|
+
*
|
|
115
|
+
* Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
|
|
116
|
+
* {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
|
|
117
|
+
* `true` (default: 429 and 5xx). The same {@link FetchInitOptions} (including `body`) is reused
|
|
118
|
+
* on every attempt.
|
|
78
119
|
*
|
|
79
|
-
* @param url - Request URL
|
|
80
|
-
* @param options -
|
|
81
|
-
* @returns The first
|
|
120
|
+
* @param url - Request URL passed to `fetch`
|
|
121
|
+
* @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
|
|
122
|
+
* @returns The first {@link Response} for which `ok` is `true`
|
|
82
123
|
* @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
|
|
83
124
|
* @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
|
|
84
|
-
* @throws {FetchRetrierNetworkError} On a network
|
|
85
|
-
* @throws {FetchRetrierAbortError} On timeout or external abort
|
|
125
|
+
* @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
|
|
126
|
+
* @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
|
|
86
127
|
* @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
|
|
87
128
|
*/
|
|
88
129
|
export declare const fetchRetrier: (url: string, options: RequestOptions) => Promise<Response>;
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, and typed errors.
|
|
4
|
+
*
|
|
5
|
+
* @module fetch-retrier
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.fetchRetrier = exports.FetchRetrierUnreachableError = exports.FetchRetrierNetworkError = exports.FetchRetrierHttpError = exports.FetchRetrierAlreadyAbortedError = exports.FetchRetrierAbortError = void 0;
|
|
4
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}.
|
|
11
|
+
*/
|
|
5
12
|
class FetchRetrierAbortError extends Error {
|
|
6
13
|
/**
|
|
7
14
|
* @param message - Human-readable reason (default: `'Aborted'`)
|
|
@@ -27,11 +34,15 @@ class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortError {
|
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
exports.FetchRetrierAlreadyAbortedError = FetchRetrierAlreadyAbortedError;
|
|
30
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
|
|
39
|
+
*
|
|
40
|
+
* @property status - HTTP status code from the last non-OK response
|
|
41
|
+
*/
|
|
31
42
|
class FetchRetrierHttpError extends Error {
|
|
32
43
|
/**
|
|
33
44
|
* @param message - Error description
|
|
34
|
-
* @param status - HTTP status code from the response
|
|
45
|
+
* @param status - HTTP status code from the last non-OK response
|
|
35
46
|
*/
|
|
36
47
|
constructor(message, status) {
|
|
37
48
|
super(message);
|
|
@@ -43,11 +54,13 @@ class FetchRetrierHttpError extends Error {
|
|
|
43
54
|
exports.FetchRetrierHttpError = FetchRetrierHttpError;
|
|
44
55
|
/**
|
|
45
56
|
* Error thrown when a fetch fails with a network-level error (e.g. DNS failure, connection refused).
|
|
57
|
+
*
|
|
58
|
+
* @property cause - Original error from the underlying `fetch`, when available
|
|
46
59
|
*/
|
|
47
60
|
class FetchRetrierNetworkError extends Error {
|
|
48
61
|
/**
|
|
49
62
|
* @param message - Human-readable reason (default: `'Network error'`)
|
|
50
|
-
* @param cause - Original error
|
|
63
|
+
* @param cause - Original error from the underlying `fetch`, when available
|
|
51
64
|
*/
|
|
52
65
|
constructor(message = 'Network error', cause) {
|
|
53
66
|
super(message);
|
|
@@ -57,7 +70,9 @@ class FetchRetrierNetworkError extends Error {
|
|
|
57
70
|
}
|
|
58
71
|
}
|
|
59
72
|
exports.FetchRetrierNetworkError = FetchRetrierNetworkError;
|
|
60
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Error thrown when an internal invariant fails (should not happen in normal use).
|
|
75
|
+
*/
|
|
61
76
|
class FetchRetrierUnreachableError extends Error {
|
|
62
77
|
/**
|
|
63
78
|
* @param message - Human-readable reason (default: `'Unreachable'`)
|
|
@@ -70,27 +85,33 @@ class FetchRetrierUnreachableError extends Error {
|
|
|
70
85
|
}
|
|
71
86
|
exports.FetchRetrierUnreachableError = FetchRetrierUnreachableError;
|
|
72
87
|
/**
|
|
73
|
-
* Default {@link RequestOptions.shouldRetry}
|
|
88
|
+
* Default {@link RequestOptions.shouldRetry}: retry on HTTP 429, 500, 502, 503, or 504.
|
|
89
|
+
*
|
|
90
|
+
* @param res - Response from the failed attempt
|
|
91
|
+
* @returns `true` when another attempt should be scheduled
|
|
74
92
|
*/
|
|
75
93
|
const defaultShouldRetry = (res) => {
|
|
76
94
|
return [429, 500, 502, 503, 504].includes(res.status);
|
|
77
95
|
};
|
|
78
96
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
97
|
+
* Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
|
|
98
|
+
*
|
|
99
|
+
* Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
|
|
100
|
+
* {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
|
|
101
|
+
* `true` (default: 429 and 5xx). The same {@link FetchInitOptions} (including `body`) is reused
|
|
102
|
+
* on every attempt.
|
|
82
103
|
*
|
|
83
|
-
* @param url - Request URL
|
|
84
|
-
* @param options -
|
|
85
|
-
* @returns The first
|
|
104
|
+
* @param url - Request URL passed to `fetch`
|
|
105
|
+
* @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
|
|
106
|
+
* @returns The first {@link Response} for which `ok` is `true`
|
|
86
107
|
* @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
|
|
87
108
|
* @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
|
|
88
|
-
* @throws {FetchRetrierNetworkError} On a network
|
|
89
|
-
* @throws {FetchRetrierAbortError} On timeout or external abort
|
|
109
|
+
* @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
|
|
110
|
+
* @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
|
|
90
111
|
* @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
|
|
91
112
|
*/
|
|
92
113
|
const fetchRetrier = async (url, options) => {
|
|
93
|
-
const { headers, retries, timeoutMs, baseBackoffMs, signal: externalSignal, shouldRetry = defaultShouldRetry } = options;
|
|
114
|
+
const { headers, init, retries, timeoutMs, baseBackoffMs, signal: externalSignal, shouldRetry = defaultShouldRetry, } = options;
|
|
94
115
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
95
116
|
if (externalSignal?.aborted) {
|
|
96
117
|
throw new FetchRetrierAlreadyAbortedError();
|
|
@@ -106,7 +127,8 @@ const fetchRetrier = async (url, options) => {
|
|
|
106
127
|
}
|
|
107
128
|
try {
|
|
108
129
|
const res = await fetch(url, {
|
|
109
|
-
|
|
130
|
+
...init,
|
|
131
|
+
...(headers !== undefined ? { headers } : {}),
|
|
110
132
|
signal: controller.signal,
|
|
111
133
|
});
|
|
112
134
|
clearTimeout(timer);
|
|
@@ -148,6 +170,8 @@ const fetchRetrier = async (url, options) => {
|
|
|
148
170
|
};
|
|
149
171
|
exports.fetchRetrier = fetchRetrier;
|
|
150
172
|
/**
|
|
173
|
+
* Delays execution for the given duration (used between retry attempts).
|
|
174
|
+
*
|
|
151
175
|
* @param ms - Delay in milliseconds
|
|
152
176
|
* @returns A promise that resolves after `ms`
|
|
153
177
|
*/
|
|
@@ -165,4 +189,4 @@ const fullJitter = (base, attempt) => {
|
|
|
165
189
|
const cap = base * Math.pow(2, attempt);
|
|
166
190
|
return Math.floor(Math.random() * cap);
|
|
167
191
|
};
|
|
168
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMEJBLDhGQUE4RjtBQUM5RixNQUFhLHNCQUF1QixTQUFRLEtBQUs7SUFFL0M7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyxTQUFTO1FBQzdCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUxDLFNBQUksR0FBVyx3QkFBd0IsQ0FBQztRQU14RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRSxDQUFDO0NBQ0Y7QUFURCx3REFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxzQkFBc0I7SUFFekU7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyw0QkFBNEI7UUFDaEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLGlDQUFpQyxDQUFDO1FBTWpFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRjtBQVRELDBFQVNDO0FBRUQsbUdBQW1HO0FBQ25HLE1BQWEscUJBQXNCLFNBQVEsS0FBSztJQUU5Qzs7O09BR0c7SUFDSCxZQUNFLE9BQWUsRUFDQyxNQUFjO1FBRTlCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUZDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFQZCxTQUFJLEdBQVcsdUJBQXVCLENBQUM7UUFVdkQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0QsQ0FBQztDQUNGO0FBYkQsc0RBYUM7QUFFRDs7R0FFRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsS0FBSztJQUVqRDs7O09BR0c7SUFDSCxZQUFZLE9BQU8sR0FBRyxlQUFlLEVBQWtCLEtBQWU7UUFDcEUs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Q3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQVUsRUFBRTtJQUMzRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqIE9wdGlvbmFsIEhUVFAgaGVhZGVycyBzZW50IHdpdGggZWFjaCBhdHRlbXB0LiAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLCBpbmNsdWRpbmcgdGhlIGZpcnN0LiAqL1xuICByZXRyaWVzOiBudW1iZXI7XG4gIC8qKiBQZXItYXR0ZW1wdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQWJvcnRDb250cm9sbGVyfSB3aGVuIGV4Y2VlZGVkLiAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHMgZm9yIGZ1bGwgaml0dGVyLiBUaGUgY2FwIGZvciBhdHRlbXB0IGBuYCBpcyBgYmFzZUJhY2tvZmZNcyAqIDJebmAuXG4gICAqL1xuICBiYXNlQmFja29mZk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiBXaGVuIGFib3J0ZWQsIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCBpcyBhYm9ydGVkOyBvbiB0aGVcbiAgICogZmluYWwgYXR0ZW1wdCwgY2FuY2VsbGF0aW9uIHN1cmZhY2VzIGFzIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogUmV0dXJuIGB0cnVlYCB0byBzY2hlZHVsZSBhbm90aGVyIGF0dGVtcHQgZm9yIHRoaXMgbm9uLU9LIHJlc3BvbnNlLlxuICAgKiBEZWZhdWx0OiByZXRyeSBvbiBzdGF0dXMgNDI5LCA1MDAsIDUwMiwgNTAzLCBvciA1MDQuXG4gICAqL1xuICBzaG91bGRSZXRyeT86IChyZXNwb25zZTogUmVzcG9uc2UsIGJvZHk6IHN0cmluZykgPT4gYm9vbGVhbjtcbn1cblxuLyoqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBjYW5jZWxsZWQgYnkgdGltZW91dCBvciBhbiBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFib3J0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJBYm9ydEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ0Fib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnQWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4ge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNpZ25hbH0gaXMgYWxyZWFkeSBhYm9ydGVkIGJlZm9yZSBhbiBhdHRlbXB0IHN0YXJ0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJBYm9ydEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKiogRXJyb3IgdGhyb3duIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgbm9uLU9LIEhUVFAgc3RhdHVzIGFuZCBubyBmdXJ0aGVyIHJldHJ5IGlzIHBlcmZvcm1lZC4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJIdHRwRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJIdHRwRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBFcnJvciBkZXNjcmlwdGlvblxuICAgKiBAcGFyYW0gc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSByZXNwb25zZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGF0dXM6IG51bWJlcixcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckh0dHBFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gYSBmZXRjaCBmYWlscyB3aXRoIGEgbmV0d29yay1sZXZlbCBlcnJvciAoZS5nLiBETlMgZmFpbHVyZSwgY29ubmVjdGlvbiByZWZ1c2VkKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllck5ldHdvcmtFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdOZXR3b3JrIGVycm9yJ2ApXG4gICAqIEBwYXJhbSBjYXVzZSAtIE9yaWdpbmFsIGVycm9yLCBpZiBhbnlcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnTmV0d29yayBlcnJvcicsIHB1YmxpYyByZWFkb25seSBjYXVzZT86IHVua25vd24pIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqIEVycm9yIHRocm93biB3aGVuIGFuIGludGVybmFsIGludmFyaWFudCBmYWlscyAoc2hvdWxkIG5vdCBoYXBwZW4gaW4gbm9ybWFsIHVzZSkuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnVW5yZWFjaGFibGUnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVW5yZWFjaGFibGUnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIERlZmF1bHQge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNob3VsZFJldHJ5fSBpbXBsZW1lbnRhdGlvbjogcmV0cnkgb24gSFRUUCA0MjksIDUwMCwgNTAyLCA1MDMsIDUwNC5cbiAqL1xuY29uc3QgZGVmYXVsdFNob3VsZFJldHJ5ID0gKHJlczogUmVzcG9uc2UpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIFs0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF0uaW5jbHVkZXMocmVzLnN0YXR1cyk7XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIGBmZXRjaGAgd2l0aCByZXRyaWVzLCBhIHBlci1hdHRlbXB0IHRpbWVvdXQsIGV4cG9uZW50aWFsIGJhY2tvZmYgd2l0aCBmdWxsIGppdHRlcixcbiAqIG9wdGlvbmFsIHtAbGluayBSZXF1ZXN0T3B0aW9ucy5zaWduYWx9IGNhbmNlbGxhdGlvbiwgYW5kIGEgY29uZmlndXJhYmxlIHJldHJ5IHByZWRpY2F0ZSBmb3JcbiAqIG5vbi1PSyByZXNwb25zZXMuXG4gKlxuICogQHBhcmFtIHVybCAtIFJlcXVlc3QgVVJMXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFJldHJpZXMsIGJhY2tvZmYsIHRpbWVvdXQsIG9wdGlvbmFsIGFib3J0IHNpZ25hbCwgYW5kIG9wdGlvbmFsIHJldHJ5IHByZWRpY2F0ZVxuICogQHJldHVybnMgVGhlIGZpcnN0IHN1Y2Nlc3NmdWwgKE9LKSB7QGxpbmsgUmVzcG9uc2V9XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfSBJZiBgb3B0aW9ucy5zaWduYWxgIGlzIGFscmVhZHkgYWJvcnRlZCBiZWZvcmUgYW4gYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVySHR0cEVycm9yfSBPbiBhIG5vbi1PSyByZXNwb25zZSB0aGF0IGlzIG5vdCByZXRyaWVkIG9yIGFmdGVyIHRoZSBsYXN0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcn0gT24gYSBuZXR3b3JrIGVycm9yIG9uIHRoZSBmaW5hbCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBYm9ydEVycm9yfSBPbiB0aW1lb3V0IG9yIGV4dGVybmFsIGFib3J0IG9uIHRoZSBmaW5hbCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yfSBJZiB0aGUgcmV0cnkgbG9vcCBleGl0cyB3aXRob3V0IHJldHVybmluZyAoaW50ZXJuYWwgYnVnKVxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hSZXRyaWVyID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgY29uc3QgeyBoZWFkZXJzLCByZXRyaWVzLCB0aW1lb3V0TXMsIGJhc2VCYWNrb2ZmTXMsIHNpZ25hbDogZXh0ZXJuYWxTaWduYWwsIHNob3VsZFJldHJ5ID0gZGVmYXVsdFNob3VsZFJldHJ5IH0gPSBvcHRpb25zO1xuXG4gIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IHJldHJpZXM7IGF0dGVtcHQrKykge1xuICAgIGlmIChleHRlcm5hbFNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBvbkV4dGVybmFsQWJvcnQgPSAoKTogdm9pZCA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgIH07XG5cbiAgICBpZiAoZXh0ZXJuYWxTaWduYWwpIHtcbiAgICAgIGV4dGVybmFsU2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25FeHRlcm5hbEFib3J0KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgICB9KTtcblxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG5cbiAgICAgIGlmIChyZXMub2spIHtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG4gICAgICBjb25zdCBpc0NvbnRpbnVlID0gc2hvdWxkUmV0cnkocmVzLCB0ZXh0KTtcblxuICAgICAgaWYgKGlzQ29udGludWUpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVySHR0cEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c31gLCByZXMuc3RhdHVzKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgTm9uLXJldHJpYWJsZSBIVFRQIGVycm9yOiAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgZXh0ZXJuYWxTaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25FeHRlcm5hbEFib3J0KTtcblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IGVyciBpbnN0YW5jZW9mIEZldGNoUmV0cmllckFib3J0RXJyb3IgPyBlcnIgOiBuZXcgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcigpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFR5cGVFcnJvcikge1xuICAgICAgICBpZiAoYXR0ZW1wdCA9PT0gcmV0cmllcykgdGhyb3cgbmV3IEZldGNoUmV0cmllck5ldHdvcmtFcnJvcignTmV0d29yayBlcnJvcicsIGVycik7XG4gICAgICAgIGF3YWl0IHdhaXQoZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0KSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IoKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIG1zIC0gRGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBgbXNgXG4gKi9cbmNvbnN0IHdhaXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn07XG5cbi8qKlxuICogRnVsbCBqaXR0ZXIgYmFja29mZjogcmFuZG9tIGRlbGF5IGluIGBbMCwgYmFzZSAqIDJeYXR0ZW1wdClgIG1zIChBV1MtcmVjb21tZW5kZWQgcGF0dGVybikuXG4gKlxuICogQHBhcmFtIGJhc2UgLSBCYXNlIGJhY2tvZmYgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gYXR0ZW1wdCAtIDEtYmFzZWQgYXR0ZW1wdCBpbmRleCAoZmlyc3QgcmV0cnkgdXNlcyBgYXR0ZW1wdCA9PT0gMWApXG4gKiBAcmV0dXJucyBXYWl0IGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIG5leHQgYXR0ZW1wdFxuICovXG5jb25zdCBmdWxsSml0dGVyID0gKGJhc2U6IG51bWJlciwgYXR0ZW1wdDogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgY29uc3QgY2FwID0gYmFzZSAqIE1hdGgucG93KDIsIGF0dGVtcHQpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY2FwKTtcbn07XG4iXX0=
|
|
192
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQW9ESDs7R0FFRztBQUNILE1BQWEsc0JBQXVCLFNBQVEsS0FBSztJQUUvQzs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLFNBQVM7UUFDN0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLHdCQUF3QixDQUFDO1FBTXhELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7Q0FDRjtBQVRELHdEQVNDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLCtCQUFnQyxTQUFRLHNCQUFzQjtJQUV6RTs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLDRCQUE0QjtRQUNoRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsaUNBQWlDLENBQUM7UUFNakUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBVEQsMEVBU0M7QUFFRDs7OztHQUlHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxLQUFLO0lBRTlDOzs7T0FHRztJQUNILFlBQ0UsT0FBZSxFQUNDLE1BQWM7UUFFOUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRkMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVBkLFNBQUksR0FBVyx1QkFBdUIsQ0FBQztRQVV2RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxDQUFDO0NBQ0Y7QUFiRCxzREFhQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLEtBQUs7SUFFakQ7OztPQUdHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsZUFBZSxFQUFr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QUFNLElBQUksNEJBQTRCLEVBQUUsQ0FBQztBQUMzQyxDQUFDLENBQUM7QUExRVcsUUFBQSxZQUFZLGdCQTBFdkI7QUFFRjs7Ozs7R0FLRztBQUNILE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBVSxFQUFpQixFQUFFO0lBQ3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQVUsRUFBRTtJQUMzRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJldHJ5LWVuYWJsZWQgYGZldGNoYCB3cmFwcGVyIHdpdGggcGVyLWF0dGVtcHQgdGltZW91dCwgZnVsbC1qaXR0ZXIgYmFja29mZiwgYW5kIHR5cGVkIGVycm9ycy5cbiAqXG4gKiBAbW9kdWxlIGZldGNoLXJldHJpZXJcbiAqL1xuXG4vKipcbiAqIGBmZXRjaGAgb3B0aW9ucyBmb3J3YXJkZWQgdG8gZXZlcnkgYXR0ZW1wdCwgZXhjbHVkaW5nIGBzaWduYWxgLlxuICpcbiAqIFVzZSBmb3IgYG1ldGhvZGAsIGBib2R5YCwgYGNyZWRlbnRpYWxzYCwgYHJlZGlyZWN0YCwgYG1vZGVgLCBgY2FjaGVgLCBhbmQgb3RoZXJcbiAqIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdEluaXQgfCBSZXF1ZXN0SW5pdH0gZmllbGRzLlxuICogUGVyLWF0dGVtcHQgYWJvcnQgYW5kIHRpbWVvdXQgYXJlIGhhbmRsZWQgaW50ZXJuYWxseSB2aWEgYHNpZ25hbGAgYW5kIG11c3Qgbm90IGJlIHNldCBoZXJlLlxuICovXG5leHBvcnQgdHlwZSBGZXRjaEluaXRPcHRpb25zID0gT21pdDxSZXF1ZXN0SW5pdCwgJ3NpZ25hbCc+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9OiByZXRyeSBwb2xpY3ksIHRpbWVvdXQsIGJhY2tvZmYsIHJlcXVlc3QgcGF5bG9hZCwgYW5kIGNhbmNlbGxhdGlvbi5cbiAqXG4gKiBSZXF1ZXN0IHNoYXBlIGlzIGJ1aWx0IGFzIGB7IC4uLmluaXQsIGhlYWRlcnM/LCBzaWduYWwgfWAgb24gZWFjaCBhdHRlbXB0LiBUb3AtbGV2ZWwgYGhlYWRlcnNgXG4gKiBvdmVycmlkZSBgaW5pdC5oZWFkZXJzYCB3aGVuIGJvdGggYXJlIHByb3ZpZGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUVFAgaGVhZGVycyBzZW50IG9uIGV2ZXJ5IGF0dGVtcHQuXG4gICAqIFdoZW4gYGluaXQuaGVhZGVyc2AgaXMgYWxzbyBzZXQsIHRoZXNlIHZhbHVlcyB0YWtlIHByZWNlZGVuY2UgZm9yIGR1cGxpY2F0ZSBrZXlzLlxuICAgKi9cbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHtAbGluayBGZXRjaEluaXRPcHRpb25zfSBtZXJnZWQgaW50byBlYWNoIGBmZXRjaGAgY2FsbCAoZS5nLiBQT1NUIGBtZXRob2RgIGFuZCBKU09OIGBib2R5YCkuXG4gICAqIFRoZSBzYW1lIGBpbml0YCBpcyByZXVzZWQgYWNyb3NzIHJldHJpZXMuXG4gICAqL1xuICBpbml0PzogRmV0Y2hJbml0T3B0aW9ucztcbiAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLCBpbmNsdWRpbmcgdGhlIGZpcnN0LiAqL1xuICByZXRyaWVzOiBudW1iZXI7XG4gIC8qKiBQZXItYXR0ZW1wdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQWJvcnRDb250cm9sbGVyfSB3aGVuIGV4Y2VlZGVkLiAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHMgZm9yIGZ1bGwgaml0dGVyLiBUaGUgY2FwIGZvciBhdHRlbXB0IGBuYCBpcyBgYmFzZUJhY2tvZmZNcyAqIDJebmAuXG4gICAqL1xuICBiYXNlQmFja29mZk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiBXaGVuIGFib3J0ZWQsIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCBpcyBhYm9ydGVkOyBvbiB0aGVcbiAgICogZmluYWwgYXR0ZW1wdCwgY2FuY2VsbGF0aW9uIHN1cmZhY2VzIGFzIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogSW52b2tlZCBhZnRlciBgcmVzcG9uc2UudGV4dCgpYCB3aGVuIGByZXNwb25zZS5va2AgaXMgZmFsc2UuXG4gICAqIFJldHVybiBgdHJ1ZWAgdG8gc2NoZWR1bGUgYW5vdGhlciBhdHRlbXB0ICh1bnRpbCBgcmV0cmllc2AgaXMgZXhoYXVzdGVkKS5cbiAgICogRGVmYXVsdDogcmV0cnkgb24gc3RhdHVzIDQyOSwgNTAwLCA1MDIsIDUwMywgb3IgNTA0LlxuICAgKlxuICAgKiBAcGFyYW0gcmVzcG9uc2UgLSBOb24tT0sgcmVzcG9uc2UgZnJvbSB0aGUgY3VycmVudCBhdHRlbXB0XG4gICAqIEBwYXJhbSBib2R5IC0gUmVzcG9uc2UgYm9keSB0ZXh0IGZyb20gYHJlc3BvbnNlLnRleHQoKWBcbiAgICovXG4gIHNob3VsZFJldHJ5PzogKHJlc3BvbnNlOiBSZXNwb25zZSwgYm9keTogc3RyaW5nKSA9PiBib29sZWFuO1xufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBjYW5jZWxsZWQgYnkgdGltZW91dCBvciBhbiBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFib3J0RXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnQWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdBYm9ydGVkJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJBYm9ydEVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2lnbmFsfSBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHQgc3RhcnRzLlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvciBleHRlbmRzIEZldGNoUmV0cmllckFib3J0RXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgbm9uLU9LIEhUVFAgc3RhdHVzIGFuZCBubyBmdXJ0aGVyIHJldHJ5IGlzIHBlcmZvcm1lZC5cbiAqXG4gKiBAcHJvcGVydHkgc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSBsYXN0IG5vbi1PSyByZXNwb25zZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVySHR0cEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVySHR0cEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gRXJyb3IgZGVzY3JpcHRpb25cbiAgICogQHBhcmFtIHN0YXR1cyAtIEhUVFAgc3RhdHVzIGNvZGUgZnJvbSB0aGUgbGFzdCBub24tT0sgcmVzcG9uc2VcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXIsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJIdHRwRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgZmV0Y2ggZmFpbHMgd2l0aCBhIG5ldHdvcmstbGV2ZWwgZXJyb3IgKGUuZy4gRE5TIGZhaWx1cmUsIGNvbm5lY3Rpb24gcmVmdXNlZCkuXG4gKlxuICogQHByb3BlcnR5IGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ05ldHdvcmsgZXJyb3InYClcbiAgICogQHBhcmFtIGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdOZXR3b3JrIGVycm9yJywgcHVibGljIHJlYWRvbmx5IGNhdXNlPzogdW5rbm93bikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGFuIGludGVybmFsIGludmFyaWFudCBmYWlscyAoc2hvdWxkIG5vdCBoYXBwZW4gaW4gbm9ybWFsIHVzZSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdVbnJlYWNoYWJsZSdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdVbnJlYWNoYWJsZScpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRGVmYXVsdCB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2hvdWxkUmV0cnl9OiByZXRyeSBvbiBIVFRQIDQyOSwgNTAwLCA1MDIsIDUwMywgb3IgNTA0LlxuICpcbiAqIEBwYXJhbSByZXMgLSBSZXNwb25zZSBmcm9tIHRoZSBmYWlsZWQgYXR0ZW1wdFxuICogQHJldHVybnMgYHRydWVgIHdoZW4gYW5vdGhlciBhdHRlbXB0IHNob3VsZCBiZSBzY2hlZHVsZWRcbiAqL1xuY29uc3QgZGVmYXVsdFNob3VsZFJldHJ5ID0gKHJlczogUmVzcG9uc2UpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIFs0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF0uaW5jbHVkZXMocmVzLnN0YXR1cyk7XG59O1xuXG4vKipcbiAqIFdyYXBzIGBmZXRjaGAgd2l0aCByZXRyaWVzLCBwZXItYXR0ZW1wdCB0aW1lb3V0LCBmdWxsLWppdHRlciBiYWNrb2ZmLCBhbmQgb3B0aW9uYWwgY2FuY2VsbGF0aW9uLlxuICpcbiAqIEVhY2ggYXR0ZW1wdCBjYWxscyBgZmV0Y2godXJsLCB7IC4uLm9wdGlvbnMuaW5pdCwgaGVhZGVycz8sIHNpZ25hbCB9KWAgd2l0aCBhbiBpbnRlcm5hbFxuICoge0BsaW5rIEFib3J0U2lnbmFsfSBmb3IgYHRpbWVvdXRNc2AuIE5vbi1PSyByZXNwb25zZXMgYXJlIHJldHJpZWQgd2hlbiBgc2hvdWxkUmV0cnlgIHJldHVybnNcbiAqIGB0cnVlYCAoZGVmYXVsdDogNDI5IGFuZCA1eHgpLiBUaGUgc2FtZSB7QGxpbmsgRmV0Y2hJbml0T3B0aW9uc30gKGluY2x1ZGluZyBgYm9keWApIGlzIHJldXNlZFxuICogb24gZXZlcnkgYXR0ZW1wdC5cbiAqXG4gKiBAcGFyYW0gdXJsIC0gUmVxdWVzdCBVUkwgcGFzc2VkIHRvIGBmZXRjaGBcbiAqIEBwYXJhbSBvcHRpb25zIC0ge0BsaW5rIFJlcXVlc3RPcHRpb25zfSBjb250cm9sbGluZyByZXRyaWVzLCB0aW1lb3V0LCByZXF1ZXN0IGluaXQsIGFuZCBjYW5jZWxsYXRpb25cbiAqIEByZXR1cm5zIFRoZSBmaXJzdCB7QGxpbmsgUmVzcG9uc2V9IGZvciB3aGljaCBgb2tgIGlzIGB0cnVlYFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcn0gSWYgYG9wdGlvbnMuc2lnbmFsYCBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckh0dHBFcnJvcn0gT24gYSBub24tT0sgcmVzcG9uc2UgdGhhdCBpcyBub3QgcmV0cmllZCBvciBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3J9IE9uIGEgbmV0d29yayBgVHlwZUVycm9yYCBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBYm9ydEVycm9yfSBPbiB0aW1lb3V0IG9yIGV4dGVybmFsIGFib3J0IGFmdGVyIHRoZSBsYXN0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3J9IElmIHRoZSByZXRyeSBsb29wIGV4aXRzIHdpdGhvdXQgcmV0dXJuaW5nIChpbnRlcm5hbCBidWcpXG4gKi9cbmV4cG9ydCBjb25zdCBmZXRjaFJldHJpZXIgPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4gPT4ge1xuICBjb25zdCB7XG4gICAgaGVhZGVycyxcbiAgICBpbml0LFxuICAgIHJldHJpZXMsXG4gICAgdGltZW91dE1zLFxuICAgIGJhc2VCYWNrb2ZmTXMsXG4gICAgc2lnbmFsOiBleHRlcm5hbFNpZ25hbCxcbiAgICBzaG91bGRSZXRyeSA9IGRlZmF1bHRTaG91bGRSZXRyeSxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgaWYgKGV4dGVybmFsU2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcblxuICAgIGNvbnN0IG9uRXh0ZXJuYWxBYm9ydCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgfTtcblxuICAgIGlmIChleHRlcm5hbFNpZ25hbCkge1xuICAgICAgZXh0ZXJuYWxTaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgLi4uaW5pdCxcbiAgICAgICAgLi4uKGhlYWRlcnMgIT09IHVuZGVmaW5lZCA/IHsgaGVhZGVycyB9IDoge30pLFxuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfSk7XG5cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBleHRlcm5hbFNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuXG4gICAgICBpZiAocmVzLm9rKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgY29uc3QgaXNDb250aW51ZSA9IHNob3VsZFJldHJ5KHJlcywgdGV4dCk7XG5cbiAgICAgIGlmIChpc0NvbnRpbnVlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgSFRUUCAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cyk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJIdHRwRXJyb3IoYE5vbi1yZXRyaWFibGUgSFRUUCBlcnJvcjogJHtyZXMuc3RhdHVzfWAsIHJlcy5zdGF0dXMpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB0aHJvdyBlcnIgaW5zdGFuY2VvZiBGZXRjaFJldHJpZXJBYm9ydEVycm9yID8gZXJyIDogbmV3IEZldGNoUmV0cmllckFib3J0RXJyb3IoKTtcbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBUeXBlRXJyb3IpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IG5ldyBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IoJ05ldHdvcmsgZXJyb3InLCBlcnIpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yKCk7XG59O1xuXG4vKipcbiAqIERlbGF5cyBleGVjdXRpb24gZm9yIHRoZSBnaXZlbiBkdXJhdGlvbiAodXNlZCBiZXR3ZWVuIHJldHJ5IGF0dGVtcHRzKS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBEZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGBtc2BcbiAqL1xuY29uc3Qgd2FpdCA9IChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufTtcblxuLyoqXG4gKiBGdWxsIGppdHRlciBiYWNrb2ZmOiByYW5kb20gZGVsYXkgaW4gYFswLCBiYXNlICogMl5hdHRlbXB0KWAgbXMgKEFXUy1yZWNvbW1lbmRlZCBwYXR0ZXJuKS5cbiAqXG4gKiBAcGFyYW0gYmFzZSAtIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSBhdHRlbXB0IC0gMS1iYXNlZCBhdHRlbXB0IGluZGV4IChmaXJzdCByZXRyeSB1c2VzIGBhdHRlbXB0ID09PSAxYClcbiAqIEByZXR1cm5zIFdhaXQgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgbmV4dCBhdHRlbXB0XG4gKi9cbmNvbnN0IGZ1bGxKaXR0ZXIgPSAoYmFzZTogbnVtYmVyLCBhdHRlbXB0OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICBjb25zdCBjYXAgPSBiYXNlICogTWF0aC5wb3coMiwgYXR0ZW1wdCk7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjYXApO1xufTtcbiJdfQ==
|