@mnaoumov/typescript-lib 0.0.0 → 1.0.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/@types/debug/package.json +4 -0
- package/LICENSE +21 -0
- package/README.md +7 -1
- package/dist/lib/cjs/@types/debug.d.cts +21 -0
- package/dist/lib/cjs/abort-controller.cjs +202 -0
- package/dist/lib/cjs/abort-controller.d.cts +135 -0
- package/dist/lib/cjs/aggregate-error.cjs +98 -0
- package/dist/lib/cjs/aggregate-error.d.cts +24 -0
- package/dist/lib/cjs/array-buffer.cjs +96 -0
- package/dist/lib/cjs/array-buffer.d.cts +16 -0
- package/dist/lib/cjs/array.cjs +134 -0
- package/dist/lib/cjs/array.d.cts +46 -0
- package/dist/lib/cjs/async-events.cjs +466 -0
- package/dist/lib/cjs/async-events.d.cts +456 -0
- package/dist/lib/cjs/async-operation-hook.cjs +113 -0
- package/dist/lib/cjs/async-operation-hook.d.cts +59 -0
- package/dist/lib/cjs/async.cjs +521 -0
- package/dist/lib/cjs/async.d.cts +414 -0
- package/dist/lib/cjs/beeper.cjs +126 -0
- package/dist/lib/cjs/beeper.d.cts +21 -0
- package/dist/lib/cjs/blob.cjs +160 -0
- package/dist/lib/cjs/blob.d.cts +59 -0
- package/dist/lib/cjs/bytes.cjs +114 -0
- package/dist/lib/cjs/bytes.d.cts +17 -0
- package/dist/lib/cjs/debug-controller.cjs +80 -0
- package/dist/lib/cjs/debug-controller.d.cts +87 -0
- package/dist/lib/cjs/debug.cjs +235 -0
- package/dist/lib/cjs/debug.d.cts +66 -0
- package/dist/lib/cjs/desktop-zip-extractor.cjs +215 -0
- package/dist/lib/cjs/desktop-zip-extractor.d.cts +95 -0
- package/dist/lib/cjs/disposable.cjs +414 -0
- package/dist/lib/cjs/disposable.d.cts +387 -0
- package/dist/lib/cjs/enum.cjs +100 -0
- package/dist/lib/cjs/enum.d.cts +24 -0
- package/dist/lib/cjs/error.cjs +297 -0
- package/dist/lib/cjs/error.d.cts +181 -0
- package/dist/lib/cjs/function.cjs +141 -0
- package/dist/lib/cjs/function.d.cts +128 -0
- package/dist/lib/cjs/html-element.cjs +341 -0
- package/dist/lib/cjs/html-element.d.cts +199 -0
- package/dist/lib/cjs/index.cjs +195 -0
- package/dist/lib/cjs/index.d.cts +33 -0
- package/dist/lib/cjs/jpeg-metadata.cjs +228 -0
- package/dist/lib/cjs/jpeg-metadata.d.cts +42 -0
- package/dist/lib/cjs/library.cjs +158 -0
- package/dist/lib/cjs/library.d.cts +96 -0
- package/dist/lib/cjs/object-utils.cjs +617 -0
- package/dist/lib/cjs/object-utils.d.cts +298 -0
- package/dist/lib/cjs/path.cjs +202 -0
- package/dist/lib/cjs/path.d.cts +154 -0
- package/dist/lib/cjs/reg-exp.cjs +254 -0
- package/dist/lib/cjs/reg-exp.d.cts +87 -0
- package/dist/lib/cjs/string.cjs +326 -0
- package/dist/lib/cjs/string.d.cts +361 -0
- package/dist/lib/cjs/transformers/date-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/date-transformer.d.cts +39 -0
- package/dist/lib/cjs/transformers/group-transformer.cjs +173 -0
- package/dist/lib/cjs/transformers/group-transformer.d.cts +70 -0
- package/dist/lib/cjs/transformers/index.cjs +123 -0
- package/dist/lib/cjs/transformers/index.d.cts +9 -0
- package/dist/lib/cjs/transformers/map-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/map-transformer.d.cts +41 -0
- package/dist/lib/cjs/transformers/set-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/set-transformer.d.cts +39 -0
- package/dist/lib/cjs/transformers/skip-private-property-transformer.cjs +127 -0
- package/dist/lib/cjs/transformers/skip-private-property-transformer.d.cts +36 -0
- package/dist/lib/cjs/transformers/transformer.cjs +170 -0
- package/dist/lib/cjs/transformers/transformer.d.cts +70 -0
- package/dist/lib/cjs/transformers/two-way-map-transformer.cjs +130 -0
- package/dist/lib/cjs/transformers/two-way-map-transformer.d.cts +42 -0
- package/dist/lib/cjs/transformers/typed-transformer.cjs +94 -0
- package/dist/lib/cjs/transformers/typed-transformer.d.cts +39 -0
- package/dist/lib/cjs/two-way-map.cjs +208 -0
- package/dist/lib/cjs/two-way-map.d.cts +101 -0
- package/dist/lib/cjs/type-guards.cjs +128 -0
- package/dist/lib/cjs/type-guards.d.cts +84 -0
- package/dist/lib/cjs/type.cjs +121 -0
- package/dist/lib/cjs/type.d.cts +122 -0
- package/dist/lib/cjs/typescript-lib-state.cjs +126 -0
- package/dist/lib/cjs/typescript-lib-state.d.cts +56 -0
- package/dist/lib/cjs/url.cjs +136 -0
- package/dist/lib/cjs/url.d.cts +74 -0
- package/dist/lib/cjs/value-provider.cjs +100 -0
- package/dist/lib/cjs/value-provider.d.cts +28 -0
- package/dist/lib/cjs/value-wrapper.cjs +144 -0
- package/dist/lib/cjs/value-wrapper.d.cts +47 -0
- package/dist/lib/esm/@types/debug.d.mts +21 -0
- package/dist/lib/esm/abort-controller.d.mts +135 -0
- package/dist/lib/esm/abort-controller.mjs +159 -0
- package/dist/lib/esm/aggregate-error.d.mts +24 -0
- package/dist/lib/esm/aggregate-error.mjs +60 -0
- package/dist/lib/esm/array-buffer.d.mts +16 -0
- package/dist/lib/esm/array-buffer.mjs +58 -0
- package/dist/lib/esm/array.d.mts +46 -0
- package/dist/lib/esm/array.mjs +93 -0
- package/dist/lib/esm/async-events.d.mts +456 -0
- package/dist/lib/esm/async-events.mjs +427 -0
- package/dist/lib/esm/async-operation-hook.d.mts +59 -0
- package/dist/lib/esm/async-operation-hook.mjs +71 -0
- package/dist/lib/esm/async.d.mts +414 -0
- package/dist/lib/esm/async.mjs +479 -0
- package/dist/lib/esm/beeper.d.mts +21 -0
- package/dist/lib/esm/beeper.mjs +88 -0
- package/dist/lib/esm/blob.d.mts +59 -0
- package/dist/lib/esm/blob.mjs +121 -0
- package/dist/lib/esm/bytes.d.mts +17 -0
- package/dist/lib/esm/bytes.mjs +76 -0
- package/dist/lib/esm/debug-controller.d.mts +87 -0
- package/dist/lib/esm/debug-controller.mjs +50 -0
- package/dist/lib/esm/debug.d.mts +66 -0
- package/dist/lib/esm/debug.mjs +185 -0
- package/dist/lib/esm/desktop-zip-extractor.d.mts +95 -0
- package/dist/lib/esm/desktop-zip-extractor.mjs +180 -0
- package/dist/lib/esm/disposable.d.mts +387 -0
- package/dist/lib/esm/disposable.mjs +360 -0
- package/dist/lib/esm/enum.d.mts +24 -0
- package/dist/lib/esm/enum.mjs +61 -0
- package/dist/lib/esm/error.d.mts +181 -0
- package/dist/lib/esm/error.mjs +248 -0
- package/dist/lib/esm/function.d.mts +128 -0
- package/dist/lib/esm/function.mjs +96 -0
- package/dist/lib/esm/html-element.d.mts +199 -0
- package/dist/lib/esm/html-element.mjs +291 -0
- package/dist/lib/esm/index.d.mts +33 -0
- package/dist/lib/esm/index.mjs +116 -0
- package/dist/lib/esm/jpeg-metadata.d.mts +42 -0
- package/dist/lib/esm/jpeg-metadata.mjs +189 -0
- package/dist/lib/esm/library.d.mts +96 -0
- package/dist/lib/esm/library.mjs +118 -0
- package/dist/lib/esm/object-utils.d.mts +298 -0
- package/dist/lib/esm/object-utils.mjs +567 -0
- package/dist/lib/esm/path.d.mts +154 -0
- package/dist/lib/esm/path.mjs +139 -0
- package/dist/lib/esm/reg-exp.d.mts +87 -0
- package/dist/lib/esm/reg-exp.mjs +213 -0
- package/dist/lib/esm/string.d.mts +361 -0
- package/dist/lib/esm/string.mjs +274 -0
- package/dist/lib/esm/transformers/date-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/date-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/group-transformer.d.mts +70 -0
- package/dist/lib/esm/transformers/group-transformer.mjs +138 -0
- package/dist/lib/esm/transformers/index.d.mts +9 -0
- package/dist/lib/esm/transformers/index.mjs +68 -0
- package/dist/lib/esm/transformers/map-transformer.d.mts +41 -0
- package/dist/lib/esm/transformers/map-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/set-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/set-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/skip-private-property-transformer.d.mts +36 -0
- package/dist/lib/esm/transformers/skip-private-property-transformer.mjs +89 -0
- package/dist/lib/esm/transformers/transformer.d.mts +70 -0
- package/dist/lib/esm/transformers/transformer.mjs +132 -0
- package/dist/lib/esm/transformers/two-way-map-transformer.d.mts +42 -0
- package/dist/lib/esm/transformers/two-way-map-transformer.mjs +92 -0
- package/dist/lib/esm/transformers/typed-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/typed-transformer.mjs +56 -0
- package/dist/lib/esm/two-way-map.d.mts +101 -0
- package/dist/lib/esm/two-way-map.mjs +170 -0
- package/dist/lib/esm/type-guards.d.mts +84 -0
- package/dist/lib/esm/type-guards.mjs +85 -0
- package/dist/lib/esm/type.d.mts +122 -0
- package/dist/lib/esm/type.mjs +83 -0
- package/dist/lib/esm/typescript-lib-state.d.mts +56 -0
- package/dist/lib/esm/typescript-lib-state.mjs +84 -0
- package/dist/lib/esm/url.d.mts +74 -0
- package/dist/lib/esm/url.mjs +94 -0
- package/dist/lib/esm/value-provider.d.mts +28 -0
- package/dist/lib/esm/value-provider.mjs +62 -0
- package/dist/lib/esm/value-wrapper.d.mts +47 -0
- package/dist/lib/esm/value-wrapper.mjs +106 -0
- package/package.json +111 -13
- package/transformers/date-transformer/package.json +6 -0
- package/transformers/group-transformer/package.json +6 -0
- package/transformers/index/package.json +6 -0
- package/transformers/map-transformer/package.json +6 -0
- package/transformers/package.json +6 -0
- package/transformers/set-transformer/package.json +6 -0
- package/transformers/skip-private-property-transformer/package.json +6 -0
- package/transformers/transformer/package.json +6 -0
- package/transformers/two-way-map-transformer/package.json +6 -0
- package/transformers/typed-transformer/package.json +6 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/// <reference path="./library.d.mts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* Contains utility functions for error handling.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* A message of the AsyncWrapperError.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ASYNC_WRAPPER_ERROR_MESSAGE = "An unhandled error occurred executing async operation";
|
|
11
|
+
/**
|
|
12
|
+
* Parameters for the {@link CustomStackTraceError} constructor.
|
|
13
|
+
*/
|
|
14
|
+
export interface CustomStackTraceErrorConstructorParams {
|
|
15
|
+
/**
|
|
16
|
+
* The cause of the error.
|
|
17
|
+
*/
|
|
18
|
+
readonly cause: unknown;
|
|
19
|
+
/**
|
|
20
|
+
* The message of the error.
|
|
21
|
+
*/
|
|
22
|
+
readonly message: string;
|
|
23
|
+
/**
|
|
24
|
+
* The stack trace of the error.
|
|
25
|
+
*/
|
|
26
|
+
readonly stackTrace: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* An error that wraps an error with a custom stack trace.
|
|
30
|
+
*/
|
|
31
|
+
export declare class CustomStackTraceError extends Error {
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new CustomStackTraceError.
|
|
34
|
+
*
|
|
35
|
+
* @param params - The parameters for the error.
|
|
36
|
+
*/
|
|
37
|
+
constructor(params: CustomStackTraceErrorConstructorParams);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An error that wraps a non-`Error` value that was thrown, preserving the original value in `cause`.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ErrorWrapper extends Error {
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new ErrorWrapper.
|
|
45
|
+
*
|
|
46
|
+
* @param thrownValue - The original non-`Error` value that was thrown.
|
|
47
|
+
*/
|
|
48
|
+
constructor(thrownValue: unknown);
|
|
49
|
+
/**
|
|
50
|
+
* Normalizes any thrown value to an `Error`.
|
|
51
|
+
*
|
|
52
|
+
* Returns the value unchanged if it is already an `Error`, otherwise wraps it in an {@link ErrorWrapper}.
|
|
53
|
+
*
|
|
54
|
+
* @param thrownValue - The thrown value to normalize.
|
|
55
|
+
* @returns An `Error` instance: the original value if it is already an `Error`, otherwise an {@link ErrorWrapper}.
|
|
56
|
+
*/
|
|
57
|
+
static create(thrownValue: unknown): Error;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* An error that is not printed to the console.
|
|
61
|
+
*/
|
|
62
|
+
export declare class SilentError extends Error {
|
|
63
|
+
/**
|
|
64
|
+
* Creates a new SilentError.
|
|
65
|
+
*
|
|
66
|
+
* @param message - The message of the error.
|
|
67
|
+
*/
|
|
68
|
+
constructor(message: string);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Empties the collection window opened by {@link startCollectingUnhandledAsyncErrors} and returns what it
|
|
72
|
+
* held, leaving the window **open** so errors emitted afterwards keep being collected.
|
|
73
|
+
*
|
|
74
|
+
* This is what the test setup's (`@mnaoumov/typescript-test-toolkit/setup`) `beforeEach` / `afterEach` use, rather than
|
|
75
|
+
* {@link stopCollectingUnhandledAsyncErrors}: an async error emitted in the gap between two tests (e.g. by a
|
|
76
|
+
* `setTimeout` the test left pending) would otherwise land on a closed window and vanish unreported.
|
|
77
|
+
*
|
|
78
|
+
* @returns The unhandled async errors collected so far, or an empty array if no window is open.
|
|
79
|
+
*/
|
|
80
|
+
export declare function drainCollectedUnhandledAsyncErrors(): unknown[];
|
|
81
|
+
/**
|
|
82
|
+
* Emits an asynchronous error event.
|
|
83
|
+
*
|
|
84
|
+
* When a collection window is open (see {@link startCollectingUnhandledAsyncErrors}) the error is
|
|
85
|
+
* collected as unhandled unless it is ignored — either because `shouldIgnore` is `true` or an
|
|
86
|
+
* {@link startAsyncErrorIgnoreContext} scope is active. A registered consumer handler deliberately does
|
|
87
|
+
* **not** exempt the error: in production it shows the user a Notice, which is not a test asserting that
|
|
88
|
+
* the error was expected. {@link startAsyncErrorIgnoreContext} is the single, explicit opt-out.
|
|
89
|
+
*
|
|
90
|
+
* @param asyncError - The error to emit as an asynchronous error event.
|
|
91
|
+
* @param shouldIgnore - Whether to treat the error as expected and never collect it as unhandled, regardless of the active ignore context. Used to carry the schedule-time ignore decision of a deferred fire-and-forget rejection.
|
|
92
|
+
*/
|
|
93
|
+
export declare function emitAsyncErrorEvent(asyncError: unknown, shouldIgnore?: boolean): void;
|
|
94
|
+
/**
|
|
95
|
+
* Converts an error to a string representation, including nested causes and the aggregated errors of
|
|
96
|
+
* an `AggregateError`, with indentation.
|
|
97
|
+
*
|
|
98
|
+
* @param error - The error to convert to a string.
|
|
99
|
+
* @returns The string representation of the error.
|
|
100
|
+
*/
|
|
101
|
+
export declare function errorToString(error: unknown): string;
|
|
102
|
+
/**
|
|
103
|
+
* Gets the current stack trace as a string, excluding the current function call.
|
|
104
|
+
*
|
|
105
|
+
* @param framesToSkip - The number of frames to skip in the stack trace.
|
|
106
|
+
* @returns A string representation of the current stack trace, excluding the current function call.
|
|
107
|
+
*/
|
|
108
|
+
export declare function getStackTrace(framesToSkip?: number): string;
|
|
109
|
+
/**
|
|
110
|
+
* Checks whether an {@link startAsyncErrorIgnoreContext} scope is currently active.
|
|
111
|
+
*
|
|
112
|
+
* @returns `true` if at least one ignore context is active, `false` otherwise.
|
|
113
|
+
*/
|
|
114
|
+
export declare function isAsyncErrorIgnoreContextActive(): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Prints an error to the console, including nested causes and optional ANSI sequence clearing.
|
|
117
|
+
*
|
|
118
|
+
* @param error - The error to print.
|
|
119
|
+
* @param console - The console to print to (default: `globalThis.console`).
|
|
120
|
+
*/
|
|
121
|
+
export declare function printError(error: unknown, console?: Console): void;
|
|
122
|
+
/**
|
|
123
|
+
* Registers an event handler for asynchronous errors.
|
|
124
|
+
*
|
|
125
|
+
* Registering a handler does not mark the errors it receives as expected — see
|
|
126
|
+
* {@link emitAsyncErrorEvent}. A test that deliberately triggers an async error opens a
|
|
127
|
+
* {@link startAsyncErrorIgnoreContext} scope regardless of who is listening.
|
|
128
|
+
*
|
|
129
|
+
* @param handler - The handler function to be called when an asynchronous error event occurs.
|
|
130
|
+
* @returns A {@link Disposable} that unregisters the handler when disposed, for use with `using`.
|
|
131
|
+
*/
|
|
132
|
+
export declare function registerAsyncErrorEventHandler(handler: (asyncError: unknown) => void): Disposable;
|
|
133
|
+
/**
|
|
134
|
+
* Opens an ignore context in which async errors are treated as expected rather than unhandled, so the
|
|
135
|
+
* test harness does not fail the test.
|
|
136
|
+
*
|
|
137
|
+
* While the returned disposable is held, an async error emitted directly (see
|
|
138
|
+
* {@link emitAsyncErrorEvent}) is not collected as unhandled. Crucially, a fire-and-forget operation
|
|
139
|
+
* scheduled within the scope (e.g. via {@link async!invokeAsyncSafely}) is also ignored when it later
|
|
140
|
+
* rejects — even after the scope has exited — because {@link async!addErrorHandler} captures the active
|
|
141
|
+
* ignore context at schedule time. A test therefore does not need to drain the operation itself:
|
|
142
|
+
*
|
|
143
|
+
* ```ts
|
|
144
|
+
* it('does not fail', () => {
|
|
145
|
+
* using _ = startAsyncErrorIgnoreContext();
|
|
146
|
+
* invokeAsyncSafely(() => Promise.reject(new Error('deliberately swallowed')));
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*
|
|
150
|
+
* Contexts nest; the ignore only ends once every open context has been disposed.
|
|
151
|
+
*
|
|
152
|
+
* @returns A {@link Disposable} that closes the ignore context when disposed, for use with `using`.
|
|
153
|
+
*/
|
|
154
|
+
export declare function startAsyncErrorIgnoreContext(): Disposable;
|
|
155
|
+
/**
|
|
156
|
+
* Opens a window in which async errors emitted outside an ignore context are collected as unhandled
|
|
157
|
+
* (see {@link emitAsyncErrorEvent}), discarding anything collected by a previous window.
|
|
158
|
+
*
|
|
159
|
+
* Intended for the test harness only: the per-test setup opens a window before each test and empties it
|
|
160
|
+
* after each test via {@link drainCollectedUnhandledAsyncErrors}, closing it for good with
|
|
161
|
+
* {@link stopCollectingUnhandledAsyncErrors} once the file's last test has run. In production no window
|
|
162
|
+
* is open, so emitting an async error carries no bookkeeping overhead.
|
|
163
|
+
*/
|
|
164
|
+
export declare function startCollectingUnhandledAsyncErrors(): void;
|
|
165
|
+
/**
|
|
166
|
+
* Closes the window opened by {@link startCollectingUnhandledAsyncErrors} and returns the unhandled
|
|
167
|
+
* async errors collected while it was open.
|
|
168
|
+
*
|
|
169
|
+
* Use {@link drainCollectedUnhandledAsyncErrors} instead wherever collection must continue afterwards —
|
|
170
|
+
* once the window is closed, a later async error is not collected by anyone.
|
|
171
|
+
*
|
|
172
|
+
* @returns The collected unhandled async errors, or an empty array if no window was open.
|
|
173
|
+
*/
|
|
174
|
+
export declare function stopCollectingUnhandledAsyncErrors(): unknown[];
|
|
175
|
+
/**
|
|
176
|
+
* Throws an error with the specified message.
|
|
177
|
+
*
|
|
178
|
+
* @param error - The error to throw.
|
|
179
|
+
* @throws
|
|
180
|
+
*/
|
|
181
|
+
export declare function throwExpression(error: unknown): never;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function () {
|
|
7
|
+
function ensureDisposeSymbols(symbolConstructor = Symbol) {
|
|
8
|
+
symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
|
|
9
|
+
symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ensureBrowserProcess() {
|
|
13
|
+
const browserProcess = {
|
|
14
|
+
browser: true,
|
|
15
|
+
cwd() {
|
|
16
|
+
return '/';
|
|
17
|
+
},
|
|
18
|
+
env: {},
|
|
19
|
+
platform: 'android'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
|
|
23
|
+
const existingProcess = globalThis.process;
|
|
24
|
+
|
|
25
|
+
if (!existingProcess) {
|
|
26
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
27
|
+
globalThis.process = browserProcess;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (existingProcess.versions?.node) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const existingProcessRecord = existingProcess;
|
|
36
|
+
|
|
37
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
38
|
+
existingProcessRecord[key] ??= value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
existingProcessRecord['browser'] = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
(function initEsm() {
|
|
45
|
+
ensureDisposeSymbols();
|
|
46
|
+
ensureBrowserProcess();
|
|
47
|
+
})();
|
|
48
|
+
})();
|
|
49
|
+
|
|
50
|
+
import { AsyncEvents } from "./async-events.mjs";
|
|
51
|
+
import {
|
|
52
|
+
CallbackDisposable,
|
|
53
|
+
MultipleDisposeBehavior
|
|
54
|
+
} from "./disposable.mjs";
|
|
55
|
+
import { ensureNonNullable } from "./type-guards.mjs";
|
|
56
|
+
const errorAsyncEvents = new AsyncEvents();
|
|
57
|
+
errorAsyncEvents.on("asyncError", handleAsyncError);
|
|
58
|
+
const moduleState = {
|
|
59
|
+
asyncErrorIgnoreContextDepth: 0,
|
|
60
|
+
collectedUnhandledAsyncErrors: null
|
|
61
|
+
};
|
|
62
|
+
const ASYNC_WRAPPER_ERROR_MESSAGE = "An unhandled error occurred executing async operation";
|
|
63
|
+
const STACK_TRACE_PREFIX = " at";
|
|
64
|
+
const ERROR_HEADER_REG_EXP = /^\w*Error(?:: |$)/;
|
|
65
|
+
const STACK_HEADER_PROBE_MESSAGE = "stack header probe";
|
|
66
|
+
class CustomStackTraceError extends Error {
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new CustomStackTraceError.
|
|
69
|
+
*
|
|
70
|
+
* @param params - The parameters for the error.
|
|
71
|
+
*/
|
|
72
|
+
constructor(params) {
|
|
73
|
+
const { cause, message, stackTrace } = params;
|
|
74
|
+
super(message, { cause });
|
|
75
|
+
this.name = "CustomStackTraceError";
|
|
76
|
+
let rootCause = cause;
|
|
77
|
+
const parentCauses = /* @__PURE__ */ new Set();
|
|
78
|
+
while (rootCause instanceof CustomStackTraceError) {
|
|
79
|
+
if (parentCauses.has(rootCause)) {
|
|
80
|
+
throw new Error("Circular cause detected");
|
|
81
|
+
}
|
|
82
|
+
parentCauses.add(rootCause);
|
|
83
|
+
rootCause = rootCause.cause;
|
|
84
|
+
}
|
|
85
|
+
const stackLines = stackTrace.split("\n");
|
|
86
|
+
if (ERROR_HEADER_REG_EXP.test(ensureNonNullable(stackLines[0]))) {
|
|
87
|
+
stackLines.shift();
|
|
88
|
+
}
|
|
89
|
+
if (hasStackHeader()) {
|
|
90
|
+
stackLines.unshift(getErrorHeader(this));
|
|
91
|
+
}
|
|
92
|
+
this.stack = stackLines.join("\n");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
class ErrorWrapper extends Error {
|
|
96
|
+
/**
|
|
97
|
+
* Creates a new ErrorWrapper.
|
|
98
|
+
*
|
|
99
|
+
* @param thrownValue - The original non-`Error` value that was thrown.
|
|
100
|
+
*/
|
|
101
|
+
constructor(thrownValue) {
|
|
102
|
+
super(`A non-Error value was thrown: ${String(thrownValue)}`, { cause: thrownValue });
|
|
103
|
+
this.name = "ErrorWrapper";
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Normalizes any thrown value to an `Error`.
|
|
107
|
+
*
|
|
108
|
+
* Returns the value unchanged if it is already an `Error`, otherwise wraps it in an {@link ErrorWrapper}.
|
|
109
|
+
*
|
|
110
|
+
* @param thrownValue - The thrown value to normalize.
|
|
111
|
+
* @returns An `Error` instance: the original value if it is already an `Error`, otherwise an {@link ErrorWrapper}.
|
|
112
|
+
*/
|
|
113
|
+
static create(thrownValue) {
|
|
114
|
+
return thrownValue instanceof Error ? thrownValue : new ErrorWrapper(thrownValue);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
class SilentError extends Error {
|
|
118
|
+
/**
|
|
119
|
+
* Creates a new SilentError.
|
|
120
|
+
*
|
|
121
|
+
* @param message - The message of the error.
|
|
122
|
+
*/
|
|
123
|
+
constructor(message) {
|
|
124
|
+
super(message);
|
|
125
|
+
this.name = "SilentError";
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function drainCollectedUnhandledAsyncErrors() {
|
|
129
|
+
return moduleState.collectedUnhandledAsyncErrors?.splice(0) ?? [];
|
|
130
|
+
}
|
|
131
|
+
function emitAsyncErrorEvent(asyncError, shouldIgnore = false) {
|
|
132
|
+
const isIgnored = shouldIgnore || moduleState.asyncErrorIgnoreContextDepth > 0;
|
|
133
|
+
if (moduleState.collectedUnhandledAsyncErrors && !isIgnored) {
|
|
134
|
+
moduleState.collectedUnhandledAsyncErrors.push(asyncError);
|
|
135
|
+
}
|
|
136
|
+
errorAsyncEvents.trigger("asyncError", asyncError);
|
|
137
|
+
}
|
|
138
|
+
function errorToString(error) {
|
|
139
|
+
return getErrorLines(error).map((line) => line.text).join("\n");
|
|
140
|
+
}
|
|
141
|
+
function getStackTrace(framesToSkip = 0) {
|
|
142
|
+
const GET_STACK_TRACE_FRAME_COUNT = 1;
|
|
143
|
+
const additionalLinesToSkip = GET_STACK_TRACE_FRAME_COUNT + (hasStackHeader() ? 1 : 0);
|
|
144
|
+
const stack = ensureNonNullable(new Error().stack);
|
|
145
|
+
const lines = stack.split("\n");
|
|
146
|
+
return lines.slice(framesToSkip + additionalLinesToSkip).join("\n");
|
|
147
|
+
}
|
|
148
|
+
function isAsyncErrorIgnoreContextActive() {
|
|
149
|
+
return moduleState.asyncErrorIgnoreContextDepth > 0;
|
|
150
|
+
}
|
|
151
|
+
function printError(error, console) {
|
|
152
|
+
console ??= globalThis.console;
|
|
153
|
+
console.error(errorToString(error));
|
|
154
|
+
}
|
|
155
|
+
function registerAsyncErrorEventHandler(handler) {
|
|
156
|
+
const eventRef = errorAsyncEvents.on("asyncError", handler);
|
|
157
|
+
return new CallbackDisposable({
|
|
158
|
+
callback: () => {
|
|
159
|
+
errorAsyncEvents.offref(eventRef);
|
|
160
|
+
},
|
|
161
|
+
multipleDisposeBehavior: MultipleDisposeBehavior.Ignore
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function startAsyncErrorIgnoreContext() {
|
|
165
|
+
moduleState.asyncErrorIgnoreContextDepth++;
|
|
166
|
+
return new CallbackDisposable({
|
|
167
|
+
callback: () => {
|
|
168
|
+
moduleState.asyncErrorIgnoreContextDepth--;
|
|
169
|
+
},
|
|
170
|
+
multipleDisposeBehavior: MultipleDisposeBehavior.Ignore
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function startCollectingUnhandledAsyncErrors() {
|
|
174
|
+
moduleState.collectedUnhandledAsyncErrors = [];
|
|
175
|
+
}
|
|
176
|
+
function stopCollectingUnhandledAsyncErrors() {
|
|
177
|
+
const collectedErrors = moduleState.collectedUnhandledAsyncErrors ?? [];
|
|
178
|
+
moduleState.collectedUnhandledAsyncErrors = null;
|
|
179
|
+
return collectedErrors;
|
|
180
|
+
}
|
|
181
|
+
function throwExpression(error) {
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
function generateNestedErrorLines(nestedError, title) {
|
|
185
|
+
const lines = [toTitleLine(title), ...getErrorLines(nestedError).filter((line) => line.text.trim() !== "")];
|
|
186
|
+
return lines.map((line) => line.isFrame ? line : { isFrame: true, text: generateStackTraceLine(line.text) });
|
|
187
|
+
}
|
|
188
|
+
function generateStackTraceLine(title) {
|
|
189
|
+
return `${STACK_TRACE_PREFIX} --- ${title} --- (0)`;
|
|
190
|
+
}
|
|
191
|
+
function getErrorHeader(error) {
|
|
192
|
+
return error.message ? `${error.name}: ${error.message}` : error.name;
|
|
193
|
+
}
|
|
194
|
+
function getErrorLines(error) {
|
|
195
|
+
if (!(error instanceof Error)) {
|
|
196
|
+
return String(error).split("\n").map((text) => toTitleLine(text));
|
|
197
|
+
}
|
|
198
|
+
const lines = getOwnErrorLines(error);
|
|
199
|
+
if (error.cause !== void 0) {
|
|
200
|
+
lines.push(...generateNestedErrorLines(error.cause, "Caused by:"));
|
|
201
|
+
}
|
|
202
|
+
if (error instanceof AggregateError) {
|
|
203
|
+
const aggregatedErrors = error.errors;
|
|
204
|
+
for (const [index, aggregatedError] of aggregatedErrors.entries()) {
|
|
205
|
+
lines.push(...generateNestedErrorLines(aggregatedError, `Aggregated error #${String(index + 1)}:`));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return lines;
|
|
209
|
+
}
|
|
210
|
+
function getOwnErrorLines(error) {
|
|
211
|
+
const headerLines = getErrorHeader(error).split("\n").map((text) => toTitleLine(text));
|
|
212
|
+
if (error.stack === void 0) {
|
|
213
|
+
return headerLines;
|
|
214
|
+
}
|
|
215
|
+
const stackLines = error.stack.split("\n");
|
|
216
|
+
if (hasStackHeader()) {
|
|
217
|
+
return stackLines.map((text) => ({ isFrame: text.startsWith(STACK_TRACE_PREFIX), text }));
|
|
218
|
+
}
|
|
219
|
+
return [...headerLines, ...stackLines.filter((text) => text.trim() !== "").map((text) => ({ isFrame: true, text }))];
|
|
220
|
+
}
|
|
221
|
+
function handleAsyncError(asyncError) {
|
|
222
|
+
printError(asyncError);
|
|
223
|
+
}
|
|
224
|
+
function hasStackHeader() {
|
|
225
|
+
const firstLine = new Error(STACK_HEADER_PROBE_MESSAGE).stack?.split("\n", 1)[0];
|
|
226
|
+
return firstLine === `Error: ${STACK_HEADER_PROBE_MESSAGE}`;
|
|
227
|
+
}
|
|
228
|
+
function toTitleLine(text) {
|
|
229
|
+
return { isFrame: false, text };
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
ASYNC_WRAPPER_ERROR_MESSAGE,
|
|
233
|
+
CustomStackTraceError,
|
|
234
|
+
ErrorWrapper,
|
|
235
|
+
SilentError,
|
|
236
|
+
drainCollectedUnhandledAsyncErrors,
|
|
237
|
+
emitAsyncErrorEvent,
|
|
238
|
+
errorToString,
|
|
239
|
+
getStackTrace,
|
|
240
|
+
isAsyncErrorIgnoreContextActive,
|
|
241
|
+
printError,
|
|
242
|
+
registerAsyncErrorEventHandler,
|
|
243
|
+
startAsyncErrorIgnoreContext,
|
|
244
|
+
startCollectingUnhandledAsyncErrors,
|
|
245
|
+
stopCollectingUnhandledAsyncErrors,
|
|
246
|
+
throwExpression
|
|
247
|
+
};
|
|
248
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2Vycm9yLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIGVycm9yIGhhbmRsaW5nLlxuICovXG5cbmltcG9ydCB7IEFzeW5jRXZlbnRzIH0gZnJvbSAnLi9hc3luYy1ldmVudHMudHMnO1xuaW1wb3J0IHtcbiAgQ2FsbGJhY2tEaXNwb3NhYmxlLFxuICBNdWx0aXBsZURpc3Bvc2VCZWhhdmlvclxufSBmcm9tICcuL2Rpc3Bvc2FibGUudHMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuL3R5cGUtZ3VhcmRzLnRzJztcblxuaW50ZXJmYWNlIEVycm9yQXN5bmNFdmVudE1hcCB7XG4gIGFzeW5jRXJyb3I6IFtlcnJvcjogdW5rbm93bl07XG59XG5cbmNvbnN0IGVycm9yQXN5bmNFdmVudHMgPSBuZXcgQXN5bmNFdmVudHM8RXJyb3JBc3luY0V2ZW50TWFwPigpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbm8tdG9wLWxldmVsLXNpZGUtZWZmZWN0cyAtLSBJbnN0YWxsaW5nIHRoZSBkZWZhdWx0IGhhbmRsZXIgb24gaW1wb3J0IGlzIHdoYXQgdGhpcyBtb2R1bGUgaXMgZm9yLiBEZWZlcnJpbmcgaXQgYmVoaW5kIGEgY2FsbCB3b3VsZCBtZWFuIGV2ZXJ5IGNvbnN1bWVyIGhhZCB0byByZW1lbWJlciB0byBtYWtlIHRoYXQgY2FsbCBiZWZvcmUgdGhlIGZpcnN0IGFzeW5jIGVycm9yLCB3aGljaCBpcyBwcmVjaXNlbHkgdGhlIG1vbWVudCB0aGUgaGFuZGxlciBuZWVkcyB0byBhbHJlYWR5IGV4aXN0LlxuZXJyb3JBc3luY0V2ZW50cy5vbignYXN5bmNFcnJvcicsIGhhbmRsZUFzeW5jRXJyb3IpO1xuXG5pbnRlcmZhY2UgTW9kdWxlU3RhdGUge1xuICAvKipcbiAgICogVGhlIG5lc3RpbmcgZGVwdGggb2YgYWN0aXZlIHtAbGluayBzdGFydEFzeW5jRXJyb3JJZ25vcmVDb250ZXh0fSBzY29wZXMuIFdoaWxlIGdyZWF0ZXIgdGhhbiBgMGAsIGFuXG4gICAqIGFzeW5jIGVycm9yIGVtaXR0ZWQgKG9yIGEgZmlyZS1hbmQtZm9yZ2V0IG9wZXJhdGlvbiB3aG9zZSByZWplY3Rpb24gd2FzIGNhcHR1cmVkKSB3aXRoaW4gdGhlIHNjb3BlIGlzXG4gICAqIHRyZWF0ZWQgYXMgZXhwZWN0ZWQgYW5kIG5vdCBjb2xsZWN0ZWQgYXMgdW5oYW5kbGVkLlxuICAgKi9cbiAgYXN5bmNFcnJvcklnbm9yZUNvbnRleHREZXB0aDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgYnVmZmVyIHRoYXQgY29sbGVjdHMgdW5oYW5kbGVkIGFzeW5jIGVycm9ycyB3aGlsZSBhIGNvbGxlY3Rpb24gd2luZG93IGlzIG9wZW4sIG9yIGBudWxsYCB3aGVuXG4gICAqIG5vIHdpbmRvdyBpcyBvcGVuICh0aGUgZGVmYXVsdCBpbiBwcm9kdWN0aW9uKS4gT3BlbmVkIGJ5IHtAbGluayBzdGFydENvbGxlY3RpbmdVbmhhbmRsZWRBc3luY0Vycm9yc30sXG4gICAqIGVtcHRpZWQgd2l0aG91dCBjbG9zaW5nIGJ5IHtAbGluayBkcmFpbkNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzfSwgYW5kIGRyYWluZWQtYW5kLWNsb3NlZCBieVxuICAgKiB7QGxpbmsgc3RvcENvbGxlY3RpbmdVbmhhbmRsZWRBc3luY0Vycm9yc30gXHUyMDE0IHVzZWQgYnkgdGhlIHRlc3QgaGFybmVzcyB0byBmYWlsIGEgdGVzdCB0aGF0IHN3YWxsb3dlZFxuICAgKiBhbiBhc3luYyBlcnJvci5cbiAgICovXG4gIGNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzOiBudWxsIHwgdW5rbm93bltdO1xufVxuXG4vKipcbk1vZHVsZS1sZXZlbCBtdXRhYmxlIHN0YXRlLCBoZWxkIGluIG9uZSBvYmplY3Qgc28gZWFjaCBtdXRhdGlvbiBuYW1lcyBpdCBleHBsaWNpdGx5LlxuICovXG5jb25zdCBtb2R1bGVTdGF0ZTogTW9kdWxlU3RhdGUgPSB7XG4gIGFzeW5jRXJyb3JJZ25vcmVDb250ZXh0RGVwdGg6IDAsXG4gIGNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzOiBudWxsXG59O1xuLyoqXG4gKiBBIG1lc3NhZ2Ugb2YgdGhlIEFzeW5jV3JhcHBlckVycm9yLlxuICovXG5leHBvcnQgY29uc3QgQVNZTkNfV1JBUFBFUl9FUlJPUl9NRVNTQUdFID0gJ0FuIHVuaGFuZGxlZCBlcnJvciBvY2N1cnJlZCBleGVjdXRpbmcgYXN5bmMgb3BlcmF0aW9uJztcblxuY29uc3QgU1RBQ0tfVFJBQ0VfUFJFRklYID0gJyAgICBhdCc7XG5cbmNvbnN0IEVSUk9SX0hFQURFUl9SRUdfRVhQID0gL15cXHcqRXJyb3IoPzo6IHwkKS87XG5cbmNvbnN0IFNUQUNLX0hFQURFUl9QUk9CRV9NRVNTQUdFID0gJ3N0YWNrIGhlYWRlciBwcm9iZSc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3IgdGhlIHtAbGluayBDdXN0b21TdGFja1RyYWNlRXJyb3J9IGNvbnN0cnVjdG9yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbVN0YWNrVHJhY2VFcnJvckNvbnN0cnVjdG9yUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBjYXVzZSBvZiB0aGUgZXJyb3IuXG4gICAqL1xuICByZWFkb25seSBjYXVzZTogdW5rbm93bjtcblxuICAvKipcbiAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RhY2sgdHJhY2Ugb2YgdGhlIGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tUcmFjZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9uZSBsaW5lIG9mIGFuIGVycm9yJ3Mgc3RyaW5nIGZvcm0sIHRhZ2dlZCB3aXRoIHdoZXRoZXIgaXQgaXMgYSBzdGFjayBmcmFtZS5cbiAqXG4gKiBBIHRpdGxlIChhbiBlcnJvciBoZWFkZXIsIGEgYENhdXNlZCBieTpgIG1hcmtlciwgYSBsaW5lIG9mIGEgbXVsdGktbGluZSBtZXNzYWdlKSBpcyB3cmFwcGVkIGludG9cbiAqIHtAbGluayBnZW5lcmF0ZVN0YWNrVHJhY2VMaW5lfSdzIGZvcm0gd2hlbiB0aGUgZXJyb3IgaXQgYmVsb25ncyB0byBpcyBuZXN0ZWQ7IGEgZnJhbWUgaXMga2VwdCB2ZXJiYXRpbS5cbiAqL1xuaW50ZXJmYWNlIEVycm9yTGluZSB7XG4gIHJlYWRvbmx5IGlzRnJhbWU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBbiBlcnJvciB0aGF0IHdyYXBzIGFuIGVycm9yIHdpdGggYSBjdXN0b20gc3RhY2sgdHJhY2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBDdXN0b21TdGFja1RyYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEN1c3RvbVN0YWNrVHJhY2VFcnJvci5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBDdXN0b21TdGFja1RyYWNlRXJyb3JDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIGNvbnN0IHsgY2F1c2UsIG1lc3NhZ2UsIHN0YWNrVHJhY2UgfSA9IHBhcmFtcztcbiAgICBzdXBlcihtZXNzYWdlLCB7IGNhdXNlIH0pO1xuICAgIHRoaXMubmFtZSA9ICdDdXN0b21TdGFja1RyYWNlRXJyb3InO1xuXG4gICAgbGV0IHJvb3RDYXVzZSA9IGNhdXNlO1xuICAgIGNvbnN0IHBhcmVudENhdXNlcyA9IG5ldyBTZXQ8Q3VzdG9tU3RhY2tUcmFjZUVycm9yPigpO1xuICAgIHdoaWxlIChyb290Q2F1c2UgaW5zdGFuY2VvZiBDdXN0b21TdGFja1RyYWNlRXJyb3IpIHtcbiAgICAgIGlmIChwYXJlbnRDYXVzZXMuaGFzKHJvb3RDYXVzZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaXJjdWxhciBjYXVzZSBkZXRlY3RlZCcpO1xuICAgICAgfVxuICAgICAgcGFyZW50Q2F1c2VzLmFkZChyb290Q2F1c2UpO1xuICAgICAgcm9vdENhdXNlID0gcm9vdENhdXNlLmNhdXNlO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrTGluZXMgPSBzdGFja1RyYWNlLnNwbGl0KCdcXG4nKTtcbiAgICBpZiAoRVJST1JfSEVBREVSX1JFR19FWFAudGVzdChlbnN1cmVOb25OdWxsYWJsZShzdGFja0xpbmVzWzBdKSkpIHtcbiAgICAgIHN0YWNrTGluZXMuc2hpZnQoKTtcbiAgICB9XG4gICAgLy8gS2VlcCB0aGUgZW5naW5lJ3Mgb3duIGAuc3RhY2tgIHNoYXBlOiBhIGhlYWRlciBvbmx5IHdoZXJlIHRoZSBlbmdpbmUgd3JpdGVzIG9uZSAoVjgpLCBmcmFtZXMgb25seSB3aGVyZSBpdCBkb2VzIG5vdCAoSmF2YVNjcmlwdENvcmUsIFNwaWRlck1vbmtleSkuXG4gICAgaWYgKGhhc1N0YWNrSGVhZGVyKCkpIHtcbiAgICAgIHN0YWNrTGluZXMudW5zaGlmdChnZXRFcnJvckhlYWRlcih0aGlzKSk7XG4gICAgfVxuICAgIHRoaXMuc3RhY2sgPSBzdGFja0xpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhhdCB3cmFwcyBhIG5vbi1gRXJyb3JgIHZhbHVlIHRoYXQgd2FzIHRocm93biwgcHJlc2VydmluZyB0aGUgb3JpZ2luYWwgdmFsdWUgaW4gYGNhdXNlYC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVycm9yV3JhcHBlciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgRXJyb3JXcmFwcGVyLlxuICAgKlxuICAgKiBAcGFyYW0gdGhyb3duVmFsdWUgLSBUaGUgb3JpZ2luYWwgbm9uLWBFcnJvcmAgdmFsdWUgdGhhdCB3YXMgdGhyb3duLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHRocm93blZhbHVlOiB1bmtub3duKSB7XG4gICAgc3VwZXIoYEEgbm9uLUVycm9yIHZhbHVlIHdhcyB0aHJvd246ICR7U3RyaW5nKHRocm93blZhbHVlKX1gLCB7IGNhdXNlOiB0aHJvd25WYWx1ZSB9KTtcbiAgICB0aGlzLm5hbWUgPSAnRXJyb3JXcmFwcGVyJztcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIGFueSB0aHJvd24gdmFsdWUgdG8gYW4gYEVycm9yYC5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgdmFsdWUgdW5jaGFuZ2VkIGlmIGl0IGlzIGFscmVhZHkgYW4gYEVycm9yYCwgb3RoZXJ3aXNlIHdyYXBzIGl0IGluIGFuIHtAbGluayBFcnJvcldyYXBwZXJ9LlxuICAgKlxuICAgKiBAcGFyYW0gdGhyb3duVmFsdWUgLSBUaGUgdGhyb3duIHZhbHVlIHRvIG5vcm1hbGl6ZS5cbiAgICogQHJldHVybnMgQW4gYEVycm9yYCBpbnN0YW5jZTogdGhlIG9yaWdpbmFsIHZhbHVlIGlmIGl0IGlzIGFscmVhZHkgYW4gYEVycm9yYCwgb3RoZXJ3aXNlIGFuIHtAbGluayBFcnJvcldyYXBwZXJ9LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjcmVhdGUodGhyb3duVmFsdWU6IHVua25vd24pOiBFcnJvciB7XG4gICAgcmV0dXJuIHRocm93blZhbHVlIGluc3RhbmNlb2YgRXJyb3IgPyB0aHJvd25WYWx1ZSA6IG5ldyBFcnJvcldyYXBwZXIodGhyb3duVmFsdWUpO1xuICB9XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhhdCBpcyBub3QgcHJpbnRlZCB0byB0aGUgY29uc29sZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNpbGVudEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBTaWxlbnRFcnJvci5cbiAgICpcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSBvZiB0aGUgZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ1NpbGVudEVycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIEVtcHRpZXMgdGhlIGNvbGxlY3Rpb24gd2luZG93IG9wZW5lZCBieSB7QGxpbmsgc3RhcnRDb2xsZWN0aW5nVW5oYW5kbGVkQXN5bmNFcnJvcnN9IGFuZCByZXR1cm5zIHdoYXQgaXRcbiAqIGhlbGQsIGxlYXZpbmcgdGhlIHdpbmRvdyAqKm9wZW4qKiBzbyBlcnJvcnMgZW1pdHRlZCBhZnRlcndhcmRzIGtlZXAgYmVpbmcgY29sbGVjdGVkLlxuICpcbiAqIFRoaXMgaXMgd2hhdCB0aGUgdGVzdCBzZXR1cCdzIChgQG1uYW91bW92L3R5cGVzY3JpcHQtdGVzdC10b29sa2l0L3NldHVwYCkgYGJlZm9yZUVhY2hgIC8gYGFmdGVyRWFjaGAgdXNlLCByYXRoZXIgdGhhblxuICoge0BsaW5rIHN0b3BDb2xsZWN0aW5nVW5oYW5kbGVkQXN5bmNFcnJvcnN9OiBhbiBhc3luYyBlcnJvciBlbWl0dGVkIGluIHRoZSBnYXAgYmV0d2VlbiB0d28gdGVzdHMgKGUuZy4gYnkgYVxuICogYHNldFRpbWVvdXRgIHRoZSB0ZXN0IGxlZnQgcGVuZGluZykgd291bGQgb3RoZXJ3aXNlIGxhbmQgb24gYSBjbG9zZWQgd2luZG93IGFuZCB2YW5pc2ggdW5yZXBvcnRlZC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgdW5oYW5kbGVkIGFzeW5jIGVycm9ycyBjb2xsZWN0ZWQgc28gZmFyLCBvciBhbiBlbXB0eSBhcnJheSBpZiBubyB3aW5kb3cgaXMgb3Blbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyYWluQ29sbGVjdGVkVW5oYW5kbGVkQXN5bmNFcnJvcnMoKTogdW5rbm93bltdIHtcbiAgcmV0dXJuIG1vZHVsZVN0YXRlLmNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzPy5zcGxpY2UoMCkgPz8gW107XG59XG5cbi8qKlxuICogRW1pdHMgYW4gYXN5bmNocm9ub3VzIGVycm9yIGV2ZW50LlxuICpcbiAqIFdoZW4gYSBjb2xsZWN0aW9uIHdpbmRvdyBpcyBvcGVuIChzZWUge0BsaW5rIHN0YXJ0Q29sbGVjdGluZ1VuaGFuZGxlZEFzeW5jRXJyb3JzfSkgdGhlIGVycm9yIGlzXG4gKiBjb2xsZWN0ZWQgYXMgdW5oYW5kbGVkIHVubGVzcyBpdCBpcyBpZ25vcmVkIFx1MjAxNCBlaXRoZXIgYmVjYXVzZSBgc2hvdWxkSWdub3JlYCBpcyBgdHJ1ZWAgb3IgYW5cbiAqIHtAbGluayBzdGFydEFzeW5jRXJyb3JJZ25vcmVDb250ZXh0fSBzY29wZSBpcyBhY3RpdmUuIEEgcmVnaXN0ZXJlZCBjb25zdW1lciBoYW5kbGVyIGRlbGliZXJhdGVseSBkb2VzXG4gKiAqKm5vdCoqIGV4ZW1wdCB0aGUgZXJyb3I6IGluIHByb2R1Y3Rpb24gaXQgc2hvd3MgdGhlIHVzZXIgYSBOb3RpY2UsIHdoaWNoIGlzIG5vdCBhIHRlc3QgYXNzZXJ0aW5nIHRoYXRcbiAqIHRoZSBlcnJvciB3YXMgZXhwZWN0ZWQuIHtAbGluayBzdGFydEFzeW5jRXJyb3JJZ25vcmVDb250ZXh0fSBpcyB0aGUgc2luZ2xlLCBleHBsaWNpdCBvcHQtb3V0LlxuICpcbiAqIEBwYXJhbSBhc3luY0Vycm9yIC0gVGhlIGVycm9yIHRvIGVtaXQgYXMgYW4gYXN5bmNocm9ub3VzIGVycm9yIGV2ZW50LlxuICogQHBhcmFtIHNob3VsZElnbm9yZSAtIFdoZXRoZXIgdG8gdHJlYXQgdGhlIGVycm9yIGFzIGV4cGVjdGVkIGFuZCBuZXZlciBjb2xsZWN0IGl0IGFzIHVuaGFuZGxlZCwgcmVnYXJkbGVzcyBvZiB0aGUgYWN0aXZlIGlnbm9yZSBjb250ZXh0LiBVc2VkIHRvIGNhcnJ5IHRoZSBzY2hlZHVsZS10aW1lIGlnbm9yZSBkZWNpc2lvbiBvZiBhIGRlZmVycmVkIGZpcmUtYW5kLWZvcmdldCByZWplY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0QXN5bmNFcnJvckV2ZW50KGFzeW5jRXJyb3I6IHVua25vd24sIHNob3VsZElnbm9yZSA9IGZhbHNlKTogdm9pZCB7XG4gIGNvbnN0IGlzSWdub3JlZCA9IHNob3VsZElnbm9yZSB8fCBtb2R1bGVTdGF0ZS5hc3luY0Vycm9ySWdub3JlQ29udGV4dERlcHRoID4gMDtcbiAgaWYgKG1vZHVsZVN0YXRlLmNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzICYmICFpc0lnbm9yZWQpIHtcbiAgICBtb2R1bGVTdGF0ZS5jb2xsZWN0ZWRVbmhhbmRsZWRBc3luY0Vycm9ycy5wdXNoKGFzeW5jRXJyb3IpO1xuICB9XG4gIGVycm9yQXN5bmNFdmVudHMudHJpZ2dlcignYXN5bmNFcnJvcicsIGFzeW5jRXJyb3IpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIGVycm9yIHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLCBpbmNsdWRpbmcgbmVzdGVkIGNhdXNlcyBhbmQgdGhlIGFnZ3JlZ2F0ZWQgZXJyb3JzIG9mXG4gKiBhbiBgQWdncmVnYXRlRXJyb3JgLCB3aXRoIGluZGVudGF0aW9uLlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byBjb252ZXJ0IHRvIGEgc3RyaW5nLlxuICogQHJldHVybnMgVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcnJvclRvU3RyaW5nKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldEVycm9yTGluZXMoZXJyb3IpLm1hcCgobGluZSkgPT4gbGluZS50ZXh0KS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFzIGEgc3RyaW5nLCBleGNsdWRpbmcgdGhlIGN1cnJlbnQgZnVuY3Rpb24gY2FsbC5cbiAqXG4gKiBAcGFyYW0gZnJhbWVzVG9Ta2lwIC0gVGhlIG51bWJlciBvZiBmcmFtZXMgdG8gc2tpcCBpbiB0aGUgc3RhY2sgdHJhY2UuXG4gKiBAcmV0dXJucyBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCBzdGFjayB0cmFjZSwgZXhjbHVkaW5nIHRoZSBjdXJyZW50IGZ1bmN0aW9uIGNhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGFja1RyYWNlKGZyYW1lc1RvU2tpcCA9IDApOiBzdHJpbmcge1xuICAvLyBTa2lwcGluZyB0aGUgYGdldFN0YWNrVHJhY2VgIGZyYW1lIGl0c2VsZiwgcGx1cyB0aGUgYEVycm9yYCBoZWFkZXIgbGluZSBvbiBhbiBlbmdpbmUgdGhhdCB3cml0ZXMgb25lLlxuICBjb25zdCBHRVRfU1RBQ0tfVFJBQ0VfRlJBTUVfQ09VTlQgPSAxO1xuICBjb25zdCBhZGRpdGlvbmFsTGluZXNUb1NraXAgPSBHRVRfU1RBQ0tfVFJBQ0VfRlJBTUVfQ09VTlQgKyAoaGFzU3RhY2tIZWFkZXIoKSA/IDEgOiAwKTtcbiAgY29uc3Qgc3RhY2sgPSBlbnN1cmVOb25OdWxsYWJsZShuZXcgRXJyb3IoKS5zdGFjayk7XG4gIGNvbnN0IGxpbmVzID0gc3RhY2suc3BsaXQoJ1xcbicpO1xuICByZXR1cm4gbGluZXMuc2xpY2UoZnJhbWVzVG9Ta2lwICsgYWRkaXRpb25hbExpbmVzVG9Ta2lwKS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhbiB7QGxpbmsgc3RhcnRBc3luY0Vycm9ySWdub3JlQ29udGV4dH0gc2NvcGUgaXMgY3VycmVudGx5IGFjdGl2ZS5cbiAqXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgYXQgbGVhc3Qgb25lIGlnbm9yZSBjb250ZXh0IGlzIGFjdGl2ZSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FzeW5jRXJyb3JJZ25vcmVDb250ZXh0QWN0aXZlKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gbW9kdWxlU3RhdGUuYXN5bmNFcnJvcklnbm9yZUNvbnRleHREZXB0aCA+IDA7XG59XG5cbi8qKlxuICogUHJpbnRzIGFuIGVycm9yIHRvIHRoZSBjb25zb2xlLCBpbmNsdWRpbmcgbmVzdGVkIGNhdXNlcyBhbmQgb3B0aW9uYWwgQU5TSSBzZXF1ZW5jZSBjbGVhcmluZy5cbiAqXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gcHJpbnQuXG4gKiBAcGFyYW0gY29uc29sZSAtIFRoZSBjb25zb2xlIHRvIHByaW50IHRvIChkZWZhdWx0OiBgZ2xvYmFsVGhpcy5jb25zb2xlYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmludEVycm9yKGVycm9yOiB1bmtub3duLCBjb25zb2xlPzogQ29uc29sZSk6IHZvaWQge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW5tZC9uby1nbG9iYWwtdGhpcyAtLSBBY3RpdmVseSB1c2UgZ2xvYmFsVGhpcy5cbiAgY29uc29sZSA/Pz0gZ2xvYmFsVGhpcy5jb25zb2xlO1xuICBjb25zb2xlLmVycm9yKGVycm9yVG9TdHJpbmcoZXJyb3IpKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gZXZlbnQgaGFuZGxlciBmb3IgYXN5bmNocm9ub3VzIGVycm9ycy5cbiAqXG4gKiBSZWdpc3RlcmluZyBhIGhhbmRsZXIgZG9lcyBub3QgbWFyayB0aGUgZXJyb3JzIGl0IHJlY2VpdmVzIGFzIGV4cGVjdGVkIFx1MjAxNCBzZWVcbiAqIHtAbGluayBlbWl0QXN5bmNFcnJvckV2ZW50fS4gQSB0ZXN0IHRoYXQgZGVsaWJlcmF0ZWx5IHRyaWdnZXJzIGFuIGFzeW5jIGVycm9yIG9wZW5zIGFcbiAqIHtAbGluayBzdGFydEFzeW5jRXJyb3JJZ25vcmVDb250ZXh0fSBzY29wZSByZWdhcmRsZXNzIG9mIHdobyBpcyBsaXN0ZW5pbmcuXG4gKlxuICogQHBhcmFtIGhhbmRsZXIgLSBUaGUgaGFuZGxlciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiBhbiBhc3luY2hyb25vdXMgZXJyb3IgZXZlbnQgb2NjdXJzLlxuICogQHJldHVybnMgQSB7QGxpbmsgRGlzcG9zYWJsZX0gdGhhdCB1bnJlZ2lzdGVycyB0aGUgaGFuZGxlciB3aGVuIGRpc3Bvc2VkLCBmb3IgdXNlIHdpdGggYHVzaW5nYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyQXN5bmNFcnJvckV2ZW50SGFuZGxlcihoYW5kbGVyOiAoYXN5bmNFcnJvcjogdW5rbm93bikgPT4gdm9pZCk6IERpc3Bvc2FibGUge1xuICBjb25zdCBldmVudFJlZiA9IGVycm9yQXN5bmNFdmVudHMub24oJ2FzeW5jRXJyb3InLCBoYW5kbGVyKTtcbiAgcmV0dXJuIG5ldyBDYWxsYmFja0Rpc3Bvc2FibGUoe1xuICAgIGNhbGxiYWNrOiAoKTogdm9pZCA9PiB7XG4gICAgICBlcnJvckFzeW5jRXZlbnRzLm9mZnJlZihldmVudFJlZik7XG4gICAgfSxcbiAgICBtdWx0aXBsZURpc3Bvc2VCZWhhdmlvcjogTXVsdGlwbGVEaXNwb3NlQmVoYXZpb3IuSWdub3JlXG4gIH0pO1xufVxuXG4vKipcbiAqIE9wZW5zIGFuIGlnbm9yZSBjb250ZXh0IGluIHdoaWNoIGFzeW5jIGVycm9ycyBhcmUgdHJlYXRlZCBhcyBleHBlY3RlZCByYXRoZXIgdGhhbiB1bmhhbmRsZWQsIHNvIHRoZVxuICogdGVzdCBoYXJuZXNzIGRvZXMgbm90IGZhaWwgdGhlIHRlc3QuXG4gKlxuICogV2hpbGUgdGhlIHJldHVybmVkIGRpc3Bvc2FibGUgaXMgaGVsZCwgYW4gYXN5bmMgZXJyb3IgZW1pdHRlZCBkaXJlY3RseSAoc2VlXG4gKiB7QGxpbmsgZW1pdEFzeW5jRXJyb3JFdmVudH0pIGlzIG5vdCBjb2xsZWN0ZWQgYXMgdW5oYW5kbGVkLiBDcnVjaWFsbHksIGEgZmlyZS1hbmQtZm9yZ2V0IG9wZXJhdGlvblxuICogc2NoZWR1bGVkIHdpdGhpbiB0aGUgc2NvcGUgKGUuZy4gdmlhIHtAbGluayBhc3luYyFpbnZva2VBc3luY1NhZmVseX0pIGlzIGFsc28gaWdub3JlZCB3aGVuIGl0IGxhdGVyXG4gKiByZWplY3RzIFx1MjAxNCBldmVuIGFmdGVyIHRoZSBzY29wZSBoYXMgZXhpdGVkIFx1MjAxNCBiZWNhdXNlIHtAbGluayBhc3luYyFhZGRFcnJvckhhbmRsZXJ9IGNhcHR1cmVzIHRoZSBhY3RpdmVcbiAqIGlnbm9yZSBjb250ZXh0IGF0IHNjaGVkdWxlIHRpbWUuIEEgdGVzdCB0aGVyZWZvcmUgZG9lcyBub3QgbmVlZCB0byBkcmFpbiB0aGUgb3BlcmF0aW9uIGl0c2VsZjpcbiAqXG4gKiBgYGB0c1xuICogaXQoJ2RvZXMgbm90IGZhaWwnLCAoKSA9PiB7XG4gKiAgIHVzaW5nIF8gPSBzdGFydEFzeW5jRXJyb3JJZ25vcmVDb250ZXh0KCk7XG4gKiAgIGludm9rZUFzeW5jU2FmZWx5KCgpID0+IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignZGVsaWJlcmF0ZWx5IHN3YWxsb3dlZCcpKSk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIENvbnRleHRzIG5lc3Q7IHRoZSBpZ25vcmUgb25seSBlbmRzIG9uY2UgZXZlcnkgb3BlbiBjb250ZXh0IGhhcyBiZWVuIGRpc3Bvc2VkLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIERpc3Bvc2FibGV9IHRoYXQgY2xvc2VzIHRoZSBpZ25vcmUgY29udGV4dCB3aGVuIGRpc3Bvc2VkLCBmb3IgdXNlIHdpdGggYHVzaW5nYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0QXN5bmNFcnJvcklnbm9yZUNvbnRleHQoKTogRGlzcG9zYWJsZSB7XG4gIG1vZHVsZVN0YXRlLmFzeW5jRXJyb3JJZ25vcmVDb250ZXh0RGVwdGgrKztcbiAgcmV0dXJuIG5ldyBDYWxsYmFja0Rpc3Bvc2FibGUoe1xuICAgIGNhbGxiYWNrOiAoKTogdm9pZCA9PiB7XG4gICAgICBtb2R1bGVTdGF0ZS5hc3luY0Vycm9ySWdub3JlQ29udGV4dERlcHRoLS07XG4gICAgfSxcbiAgICBtdWx0aXBsZURpc3Bvc2VCZWhhdmlvcjogTXVsdGlwbGVEaXNwb3NlQmVoYXZpb3IuSWdub3JlXG4gIH0pO1xufVxuXG4vKipcbiAqIE9wZW5zIGEgd2luZG93IGluIHdoaWNoIGFzeW5jIGVycm9ycyBlbWl0dGVkIG91dHNpZGUgYW4gaWdub3JlIGNvbnRleHQgYXJlIGNvbGxlY3RlZCBhcyB1bmhhbmRsZWRcbiAqIChzZWUge0BsaW5rIGVtaXRBc3luY0Vycm9yRXZlbnR9KSwgZGlzY2FyZGluZyBhbnl0aGluZyBjb2xsZWN0ZWQgYnkgYSBwcmV2aW91cyB3aW5kb3cuXG4gKlxuICogSW50ZW5kZWQgZm9yIHRoZSB0ZXN0IGhhcm5lc3Mgb25seTogdGhlIHBlci10ZXN0IHNldHVwIG9wZW5zIGEgd2luZG93IGJlZm9yZSBlYWNoIHRlc3QgYW5kIGVtcHRpZXMgaXRcbiAqIGFmdGVyIGVhY2ggdGVzdCB2aWEge0BsaW5rIGRyYWluQ29sbGVjdGVkVW5oYW5kbGVkQXN5bmNFcnJvcnN9LCBjbG9zaW5nIGl0IGZvciBnb29kIHdpdGhcbiAqIHtAbGluayBzdG9wQ29sbGVjdGluZ1VuaGFuZGxlZEFzeW5jRXJyb3JzfSBvbmNlIHRoZSBmaWxlJ3MgbGFzdCB0ZXN0IGhhcyBydW4uIEluIHByb2R1Y3Rpb24gbm8gd2luZG93XG4gKiBpcyBvcGVuLCBzbyBlbWl0dGluZyBhbiBhc3luYyBlcnJvciBjYXJyaWVzIG5vIGJvb2trZWVwaW5nIG92ZXJoZWFkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRDb2xsZWN0aW5nVW5oYW5kbGVkQXN5bmNFcnJvcnMoKTogdm9pZCB7XG4gIG1vZHVsZVN0YXRlLmNvbGxlY3RlZFVuaGFuZGxlZEFzeW5jRXJyb3JzID0gW107XG59XG5cbi8qKlxuICogQ2xvc2VzIHRoZSB3aW5kb3cgb3BlbmVkIGJ5IHtAbGluayBzdGFydENvbGxlY3RpbmdVbmhhbmRsZWRBc3luY0Vycm9yc30gYW5kIHJldHVybnMgdGhlIHVuaGFuZGxlZFxuICogYXN5bmMgZXJyb3JzIGNvbGxlY3RlZCB3aGlsZSBpdCB3YXMgb3Blbi5cbiAqXG4gKiBVc2Uge0BsaW5rIGRyYWluQ29sbGVjdGVkVW5oYW5kbGVkQXN5bmNFcnJvcnN9IGluc3RlYWQgd2hlcmV2ZXIgY29sbGVjdGlvbiBtdXN0IGNvbnRpbnVlIGFmdGVyd2FyZHMgXHUyMDE0XG4gKiBvbmNlIHRoZSB3aW5kb3cgaXMgY2xvc2VkLCBhIGxhdGVyIGFzeW5jIGVycm9yIGlzIG5vdCBjb2xsZWN0ZWQgYnkgYW55b25lLlxuICpcbiAqIEByZXR1cm5zIFRoZSBjb2xsZWN0ZWQgdW5oYW5kbGVkIGFzeW5jIGVycm9ycywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgbm8gd2luZG93IHdhcyBvcGVuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RvcENvbGxlY3RpbmdVbmhhbmRsZWRBc3luY0Vycm9ycygpOiB1bmtub3duW10ge1xuICBjb25zdCBjb2xsZWN0ZWRFcnJvcnMgPSBtb2R1bGVTdGF0ZS5jb2xsZWN0ZWRVbmhhbmRsZWRBc3luY0Vycm9ycyA/PyBbXTtcbiAgbW9kdWxlU3RhdGUuY29sbGVjdGVkVW5oYW5kbGVkQXN5bmNFcnJvcnMgPSBudWxsO1xuICByZXR1cm4gY29sbGVjdGVkRXJyb3JzO1xufVxuXG4vKipcbiAqIFRocm93cyBhbiBlcnJvciB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gKiBAdGhyb3dzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aHJvd0V4cHJlc3Npb24oZXJyb3I6IHVua25vd24pOiBuZXZlciB7XG4gIHRocm93IGVycm9yO1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZU5lc3RlZEVycm9yTGluZXMobmVzdGVkRXJyb3I6IHVua25vd24sIHRpdGxlOiBzdHJpbmcpOiBFcnJvckxpbmVbXSB7XG4gIGNvbnN0IGxpbmVzID0gW3RvVGl0bGVMaW5lKHRpdGxlKSwgLi4uZ2V0RXJyb3JMaW5lcyhuZXN0ZWRFcnJvcikuZmlsdGVyKChsaW5lKSA9PiBsaW5lLnRleHQudHJpbSgpICE9PSAnJyldO1xuICByZXR1cm4gbGluZXMubWFwKChsaW5lKSA9PiBsaW5lLmlzRnJhbWUgPyBsaW5lIDogeyBpc0ZyYW1lOiB0cnVlLCB0ZXh0OiBnZW5lcmF0ZVN0YWNrVHJhY2VMaW5lKGxpbmUudGV4dCkgfSk7XG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlU3RhY2tUcmFjZUxpbmUodGl0bGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtTVEFDS19UUkFDRV9QUkVGSVh9IC0tLSAke3RpdGxlfSAtLS0gKDApYDtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGBOYW1lOiBtZXNzYWdlYCBoZWFkZXIgdGhlIHdheSBWOCB3cml0ZXMgaXQgaW50byBgLnN0YWNrYCAoYSBiYXJlIGBOYW1lYCBmb3IgYW4gZW1wdHkgbWVzc2FnZSkuXG4gKlxuICogQHBhcmFtIGVycm9yIC0gVGhlIGVycm9yLlxuICogQHJldHVybnMgVGhlIGhlYWRlciwgd2hpY2ggc3BhbnMgc2V2ZXJhbCBsaW5lcyB3aGVuIHRoZSBtZXNzYWdlIGRvZXMuXG4gKi9cbmZ1bmN0aW9uIGdldEVycm9ySGVhZGVyKGVycm9yOiBFcnJvcik6IHN0cmluZyB7XG4gIHJldHVybiBlcnJvci5tZXNzYWdlID8gYCR7ZXJyb3IubmFtZX06ICR7ZXJyb3IubWVzc2FnZX1gIDogZXJyb3IubmFtZTtcbn1cblxuZnVuY3Rpb24gZ2V0RXJyb3JMaW5lcyhlcnJvcjogdW5rbm93bik6IEVycm9yTGluZVtdIHtcbiAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICByZXR1cm4gU3RyaW5nKGVycm9yKS5zcGxpdCgnXFxuJykubWFwKCh0ZXh0KSA9PiB0b1RpdGxlTGluZSh0ZXh0KSk7XG4gIH1cblxuICBjb25zdCBsaW5lcyA9IGdldE93bkVycm9yTGluZXMoZXJyb3IpO1xuICBpZiAoZXJyb3IuY2F1c2UgIT09IHVuZGVmaW5lZCkge1xuICAgIGxpbmVzLnB1c2goLi4uZ2VuZXJhdGVOZXN0ZWRFcnJvckxpbmVzKGVycm9yLmNhdXNlLCAnQ2F1c2VkIGJ5OicpKTtcbiAgfVxuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgIGNvbnN0IGFnZ3JlZ2F0ZWRFcnJvcnM6IHJlYWRvbmx5IHVua25vd25bXSA9IGVycm9yLmVycm9ycztcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYWdncmVnYXRlZEVycm9yXSBvZiBhZ2dyZWdhdGVkRXJyb3JzLmVudHJpZXMoKSkge1xuICAgICAgbGluZXMucHVzaCguLi5nZW5lcmF0ZU5lc3RlZEVycm9yTGluZXMoYWdncmVnYXRlZEVycm9yLCBgQWdncmVnYXRlZCBlcnJvciAjJHtTdHJpbmcoaW5kZXggKyAxKX06YCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbGluZXM7XG59XG5cbmZ1bmN0aW9uIGdldE93bkVycm9yTGluZXMoZXJyb3I6IEVycm9yKTogRXJyb3JMaW5lW10ge1xuICBjb25zdCBoZWFkZXJMaW5lcyA9IGdldEVycm9ySGVhZGVyKGVycm9yKS5zcGxpdCgnXFxuJykubWFwKCh0ZXh0KSA9PiB0b1RpdGxlTGluZSh0ZXh0KSk7XG4gIGlmIChlcnJvci5zdGFjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGhlYWRlckxpbmVzO1xuICB9XG5cbiAgY29uc3Qgc3RhY2tMaW5lcyA9IGVycm9yLnN0YWNrLnNwbGl0KCdcXG4nKTtcbiAgaWYgKGhhc1N0YWNrSGVhZGVyKCkpIHtcbiAgICByZXR1cm4gc3RhY2tMaW5lcy5tYXAoKHRleHQpID0+ICh7IGlzRnJhbWU6IHRleHQuc3RhcnRzV2l0aChTVEFDS19UUkFDRV9QUkVGSVgpLCB0ZXh0IH0pKTtcbiAgfVxuXG4gIC8vIE9uIGFuIGVuZ2luZSB3aXRob3V0IGEgaGVhZGVyIGxpbmUsIHRoZSBgLnN0YWNrYCBpcyBmcmFtZXMgb25seSwgaW4gaXRzIG93biBgbmFtZUB1cmw6bGluZTpjb2xgIGZvcm0sIHNvIHRoZSBtZXNzYWdlIGlzIG5vd2hlcmUgaW4gaXQ6XG4gIC8vIFByZXBlbmQgdGhlIGhlYWRlciwgYW5kIHRha2UgZXZlcnkgc3RhY2sgbGluZSBhcyBhIGZyYW1lLlxuICByZXR1cm4gWy4uLmhlYWRlckxpbmVzLCAuLi5zdGFja0xpbmVzLmZpbHRlcigodGV4dCkgPT4gdGV4dC50cmltKCkgIT09ICcnKS5tYXAoKHRleHQpID0+ICh7IGlzRnJhbWU6IHRydWUsIHRleHQgfSkpXTtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGFzeW5jaHJvbm91cyBlcnJvcnMgYnkgcHJpbnRpbmcgdGhlbS5cbiAqXG4gKiBAcGFyYW0gYXN5bmNFcnJvciAtIFRoZSBhc3luY2hyb25vdXMgZXJyb3IgdG8gaGFuZGxlLlxuICovXG5mdW5jdGlvbiBoYW5kbGVBc3luY0Vycm9yKGFzeW5jRXJyb3I6IHVua25vd24pOiB2b2lkIHtcbiAgcHJpbnRFcnJvcihhc3luY0Vycm9yKTtcbn1cblxuLyoqXG4gKiBBbnN3ZXJzIHdoZXRoZXIgdGhpcyBlbmdpbmUncyBgLnN0YWNrYCBvcGVucyB3aXRoIHRoZSBlcnJvcidzIGBOYW1lOiBtZXNzYWdlYCBoZWFkZXIgbGluZS5cbiAqXG4gKiBWOCB3cml0ZXMgb25lOyBKYXZhU2NyaXB0Q29yZSAoZXZlcnkgQXBwbGUgcGxhdGZvcm0sIHNvIE9ic2lkaWFuIG9uIGlPUyBhbmQgaVBhZE9TKSBhbmQgU3BpZGVyTW9ua2V5IHdyaXRlIGZyYW1lcyBvbmx5LlxuICogVGhlIGFuc3dlciBiZWxvbmdzIHRvIHRoZSBlbmdpbmUsIG5vdCB0aGUgcGxhdGZvcm0sIHNvIGl0IGlzIHByb2JlZCByYXRoZXIgdGhhbiByZWFkIG9mZiBgUGxhdGZvcm1gLiBJdCBpcyBwcm9iZWQgb24gZXZlcnlcbiAqIGNhbGwgcmF0aGVyIHRoYW4gY2FjaGVkLCBiZWNhdXNlIGBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZWAgY2FuIHJlc2hhcGUgVjgncyBzdGFjayBhdCBydW50aW1lLCBhbmQgb25lIGV4dHJhIGBFcnJvcmAgY29zdHNcbiAqIG5vdGhpbmcgb24gYSBwYXRoIHRoYXQgaXMgYWxyZWFkeSBoYW5kbGluZyBvbmUuXG4gKlxuICogQHJldHVybnMgYHRydWVgIGlmIGAuc3RhY2tgIGNhcnJpZXMgdGhlIGhlYWRlciBsaW5lLlxuICovXG5mdW5jdGlvbiBoYXNTdGFja0hlYWRlcigpOiBib29sZWFuIHtcbiAgY29uc3QgZmlyc3RMaW5lID0gbmV3IEVycm9yKFNUQUNLX0hFQURFUl9QUk9CRV9NRVNTQUdFKS5zdGFjaz8uc3BsaXQoJ1xcbicsIDEpWzBdO1xuICByZXR1cm4gZmlyc3RMaW5lID09PSBgRXJyb3I6ICR7U1RBQ0tfSEVBREVSX1BST0JFX01FU1NBR0V9YDtcbn1cblxuZnVuY3Rpb24gdG9UaXRsZUxpbmUodGV4dDogc3RyaW5nKTogRXJyb3JMaW5lIHtcbiAgcmV0dXJuIHsgaXNGcmFtZTogZmFsc2UsIHRleHQgfTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFNQSxTQUFTLG1CQUFtQjtBQUM1QjtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMseUJBQXlCO0FBTWxDLE1BQU0sbUJBQW1CLElBQUksWUFBZ0M7QUFFN0QsaUJBQWlCLEdBQUcsY0FBYyxnQkFBZ0I7QUF1QmxELE1BQU0sY0FBMkI7QUFBQSxFQUMvQiw4QkFBOEI7QUFBQSxFQUM5QiwrQkFBK0I7QUFDakM7QUFJTyxNQUFNLDhCQUE4QjtBQUUzQyxNQUFNLHFCQUFxQjtBQUUzQixNQUFNLHVCQUF1QjtBQUU3QixNQUFNLDZCQUE2QjtBQW9DNUIsTUFBTSw4QkFBOEIsTUFBTTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU14QyxZQUFZLFFBQWdEO0FBQ2pFLFVBQU0sRUFBRSxPQUFPLFNBQVMsV0FBVyxJQUFJO0FBQ3ZDLFVBQU0sU0FBUyxFQUFFLE1BQU0sQ0FBQztBQUN4QixTQUFLLE9BQU87QUFFWixRQUFJLFlBQVk7QUFDaEIsVUFBTSxlQUFlLG9CQUFJLElBQTJCO0FBQ3BELFdBQU8scUJBQXFCLHVCQUF1QjtBQUNqRCxVQUFJLGFBQWEsSUFBSSxTQUFTLEdBQUc7QUFDL0IsY0FBTSxJQUFJLE1BQU0seUJBQXlCO0FBQUEsTUFDM0M7QUFDQSxtQkFBYSxJQUFJLFNBQVM7QUFDMUIsa0JBQVksVUFBVTtBQUFBLElBQ3hCO0FBRUEsVUFBTSxhQUFhLFdBQVcsTUFBTSxJQUFJO0FBQ3hDLFFBQUkscUJBQXFCLEtBQUssa0JBQWtCLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRztBQUMvRCxpQkFBVyxNQUFNO0FBQUEsSUFDbkI7QUFFQSxRQUFJLGVBQWUsR0FBRztBQUNwQixpQkFBVyxRQUFRLGVBQWUsSUFBSSxDQUFDO0FBQUEsSUFDekM7QUFDQSxTQUFLLFFBQVEsV0FBVyxLQUFLLElBQUk7QUFBQSxFQUNuQztBQUNGO0FBS08sTUFBTSxxQkFBcUIsTUFBTTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU0vQixZQUFZLGFBQXNCO0FBQ3ZDLFVBQU0saUNBQWlDLE9BQU8sV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLFlBQVksQ0FBQztBQUNwRixTQUFLLE9BQU87QUFBQSxFQUNkO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBVUEsT0FBYyxPQUFPLGFBQTZCO0FBQ2hELFdBQU8sdUJBQXVCLFFBQVEsY0FBYyxJQUFJLGFBQWEsV0FBVztBQUFBLEVBQ2xGO0FBQ0Y7QUFLTyxNQUFNLG9CQUFvQixNQUFNO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBTTlCLFlBQVksU0FBaUI7QUFDbEMsVUFBTSxPQUFPO0FBQ2IsU0FBSyxPQUFPO0FBQUEsRUFDZDtBQUNGO0FBWU8sU0FBUyxxQ0FBZ0Q7QUFDOUQsU0FBTyxZQUFZLCtCQUErQixPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ2xFO0FBY08sU0FBUyxvQkFBb0IsWUFBcUIsZUFBZSxPQUFhO0FBQ25GLFFBQU0sWUFBWSxnQkFBZ0IsWUFBWSwrQkFBK0I7QUFDN0UsTUFBSSxZQUFZLGlDQUFpQyxDQUFDLFdBQVc7QUFDM0QsZ0JBQVksOEJBQThCLEtBQUssVUFBVTtBQUFBLEVBQzNEO0FBQ0EsbUJBQWlCLFFBQVEsY0FBYyxVQUFVO0FBQ25EO0FBU08sU0FBUyxjQUFjLE9BQXdCO0FBQ3BELFNBQU8sY0FBYyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsS0FBSyxJQUFJLEVBQUUsS0FBSyxJQUFJO0FBQ2hFO0FBUU8sU0FBUyxjQUFjLGVBQWUsR0FBVztBQUV0RCxRQUFNLDhCQUE4QjtBQUNwQyxRQUFNLHdCQUF3QiwrQkFBK0IsZUFBZSxJQUFJLElBQUk7QUFDcEYsUUFBTSxRQUFRLGtCQUFrQixJQUFJLE1BQU0sRUFBRSxLQUFLO0FBQ2pELFFBQU0sUUFBUSxNQUFNLE1BQU0sSUFBSTtBQUM5QixTQUFPLE1BQU0sTUFBTSxlQUFlLHFCQUFxQixFQUFFLEtBQUssSUFBSTtBQUNwRTtBQU9PLFNBQVMsa0NBQTJDO0FBQ3pELFNBQU8sWUFBWSwrQkFBK0I7QUFDcEQ7QUFRTyxTQUFTLFdBQVcsT0FBZ0IsU0FBeUI7QUFFbEUsY0FBWSxXQUFXO0FBQ3ZCLFVBQVEsTUFBTSxjQUFjLEtBQUssQ0FBQztBQUNwQztBQVlPLFNBQVMsK0JBQStCLFNBQW9EO0FBQ2pHLFFBQU0sV0FBVyxpQkFBaUIsR0FBRyxjQUFjLE9BQU87QUFDMUQsU0FBTyxJQUFJLG1CQUFtQjtBQUFBLElBQzVCLFVBQVUsTUFBWTtBQUNwQix1QkFBaUIsT0FBTyxRQUFRO0FBQUEsSUFDbEM7QUFBQSxJQUNBLHlCQUF5Qix3QkFBd0I7QUFBQSxFQUNuRCxDQUFDO0FBQ0g7QUF1Qk8sU0FBUywrQkFBMkM7QUFDekQsY0FBWTtBQUNaLFNBQU8sSUFBSSxtQkFBbUI7QUFBQSxJQUM1QixVQUFVLE1BQVk7QUFDcEIsa0JBQVk7QUFBQSxJQUNkO0FBQUEsSUFDQSx5QkFBeUIsd0JBQXdCO0FBQUEsRUFDbkQsQ0FBQztBQUNIO0FBV08sU0FBUyxzQ0FBNEM7QUFDMUQsY0FBWSxnQ0FBZ0MsQ0FBQztBQUMvQztBQVdPLFNBQVMscUNBQWdEO0FBQzlELFFBQU0sa0JBQWtCLFlBQVksaUNBQWlDLENBQUM7QUFDdEUsY0FBWSxnQ0FBZ0M7QUFDNUMsU0FBTztBQUNUO0FBUU8sU0FBUyxnQkFBZ0IsT0FBdUI7QUFDckQsUUFBTTtBQUNSO0FBRUEsU0FBUyx5QkFBeUIsYUFBc0IsT0FBNEI7QUFDbEYsUUFBTSxRQUFRLENBQUMsWUFBWSxLQUFLLEdBQUcsR0FBRyxjQUFjLFdBQVcsRUFBRSxPQUFPLENBQUMsU0FBUyxLQUFLLEtBQUssS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUMxRyxTQUFPLE1BQU0sSUFBSSxDQUFDLFNBQVMsS0FBSyxVQUFVLE9BQU8sRUFBRSxTQUFTLE1BQU0sTUFBTSx1QkFBdUIsS0FBSyxJQUFJLEVBQUUsQ0FBQztBQUM3RztBQUVBLFNBQVMsdUJBQXVCLE9BQXVCO0FBQ3JELFNBQU8sR0FBRyxrQkFBa0IsUUFBUSxLQUFLO0FBQzNDO0FBUUEsU0FBUyxlQUFlLE9BQXNCO0FBQzVDLFNBQU8sTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLEtBQUssTUFBTSxPQUFPLEtBQUssTUFBTTtBQUNuRTtBQUVBLFNBQVMsY0FBYyxPQUE2QjtBQUNsRCxNQUFJLEVBQUUsaUJBQWlCLFFBQVE7QUFDN0IsV0FBTyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxZQUFZLElBQUksQ0FBQztBQUFBLEVBQ2xFO0FBRUEsUUFBTSxRQUFRLGlCQUFpQixLQUFLO0FBQ3BDLE1BQUksTUFBTSxVQUFVLFFBQVc7QUFDN0IsVUFBTSxLQUFLLEdBQUcseUJBQXlCLE1BQU0sT0FBTyxZQUFZLENBQUM7QUFBQSxFQUNuRTtBQUNBLE1BQUksaUJBQWlCLGdCQUFnQjtBQUNuQyxVQUFNLG1CQUF1QyxNQUFNO0FBQ25ELGVBQVcsQ0FBQyxPQUFPLGVBQWUsS0FBSyxpQkFBaUIsUUFBUSxHQUFHO0FBQ2pFLFlBQU0sS0FBSyxHQUFHLHlCQUF5QixpQkFBaUIscUJBQXFCLE9BQU8sUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQUEsSUFDcEc7QUFBQSxFQUNGO0FBQ0EsU0FBTztBQUNUO0FBRUEsU0FBUyxpQkFBaUIsT0FBMkI7QUFDbkQsUUFBTSxjQUFjLGVBQWUsS0FBSyxFQUFFLE1BQU0sSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLFlBQVksSUFBSSxDQUFDO0FBQ3JGLE1BQUksTUFBTSxVQUFVLFFBQVc7QUFDN0IsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLGFBQWEsTUFBTSxNQUFNLE1BQU0sSUFBSTtBQUN6QyxNQUFJLGVBQWUsR0FBRztBQUNwQixXQUFPLFdBQVcsSUFBSSxDQUFDLFVBQVUsRUFBRSxTQUFTLEtBQUssV0FBVyxrQkFBa0IsR0FBRyxLQUFLLEVBQUU7QUFBQSxFQUMxRjtBQUlBLFNBQU8sQ0FBQyxHQUFHLGFBQWEsR0FBRyxXQUFXLE9BQU8sQ0FBQyxTQUFTLEtBQUssS0FBSyxNQUFNLEVBQUUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsTUFBTSxLQUFLLEVBQUUsQ0FBQztBQUNySDtBQU9BLFNBQVMsaUJBQWlCLFlBQTJCO0FBQ25ELGFBQVcsVUFBVTtBQUN2QjtBQVlBLFNBQVMsaUJBQTBCO0FBQ2pDLFFBQU0sWUFBWSxJQUFJLE1BQU0sMEJBQTBCLEVBQUUsT0FBTyxNQUFNLE1BQU0sQ0FBQyxFQUFFLENBQUM7QUFDL0UsU0FBTyxjQUFjLFVBQVUsMEJBQTBCO0FBQzNEO0FBRUEsU0FBUyxZQUFZLE1BQXlCO0FBQzVDLFNBQU8sRUFBRSxTQUFTLE9BQU8sS0FBSztBQUNoQzsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/// <reference path="./library.d.mts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* Contains utility functions and types for working with functions.
|
|
6
|
+
*/
|
|
7
|
+
import type { Promisable } from 'type-fest';
|
|
8
|
+
/**
|
|
9
|
+
* Represents a generic async function.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam Arguments - The arguments of the function.
|
|
12
|
+
* @typeParam Return - The awaited return type of the function.
|
|
13
|
+
*/
|
|
14
|
+
export type GenericAsyncFunction<Arguments extends unknown[] = never[], Return = unknown> = GenericFunction<Arguments, Promise<Return>>;
|
|
15
|
+
/**
|
|
16
|
+
* Represents a generic async void function.
|
|
17
|
+
*
|
|
18
|
+
* @typeParam Arguments - The arguments of the function.
|
|
19
|
+
*/
|
|
20
|
+
export type GenericAsyncVoidFunction<Arguments extends unknown[] = never[]> = GenericAsyncFunction<Arguments, void>;
|
|
21
|
+
/**
|
|
22
|
+
* Represents a generic function.
|
|
23
|
+
*
|
|
24
|
+
* @typeParam Arguments - The arguments of the function.
|
|
25
|
+
* @typeParam Return - The return type of the function.
|
|
26
|
+
*/
|
|
27
|
+
export type GenericFunction<Arguments extends unknown[] = never[], Return = unknown> = (...$arguments: Arguments) => Return;
|
|
28
|
+
/**
|
|
29
|
+
* Represents a generic promisable function.
|
|
30
|
+
*
|
|
31
|
+
* @typeParam Arguments - The arguments of the function.
|
|
32
|
+
* @typeParam Return - The awaited return type of the function.
|
|
33
|
+
*/
|
|
34
|
+
export type GenericPromisableFunction<Arguments extends unknown[] = never[], Return = unknown> = GenericFunction<Arguments, Promisable<Return>>;
|
|
35
|
+
/**
|
|
36
|
+
* Represents a generic promisable void function.
|
|
37
|
+
*
|
|
38
|
+
* @typeParam Arguments - The arguments of the function.
|
|
39
|
+
*/
|
|
40
|
+
export type GenericPromisableVoidFunction<Arguments extends unknown[] = never[]> = GenericPromisableFunction<Arguments, void>;
|
|
41
|
+
/**
|
|
42
|
+
* Represents a generic void function.
|
|
43
|
+
*
|
|
44
|
+
* @typeParam Arguments - The arguments of the function.
|
|
45
|
+
*/
|
|
46
|
+
export type GenericVoidFunction<Arguments extends unknown[] = never[]> = GenericFunction<Arguments, void>;
|
|
47
|
+
/**
|
|
48
|
+
* Converts a function into a string that is a valid function expression.
|
|
49
|
+
*
|
|
50
|
+
* `Function.prototype.toString()` on a shorthand method like `{ fn() {} }`
|
|
51
|
+
* returns `"fn() {}"`, which is not a valid expression.
|
|
52
|
+
* This helper detects that form and prefixes it with `function `.
|
|
53
|
+
*
|
|
54
|
+
* @param $function - The function to convert.
|
|
55
|
+
* @returns A string that is a valid function expression.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getFunctionExpressionString($function: Function): string;
|
|
58
|
+
/**
|
|
59
|
+
* A function that does nothing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function noop(): void;
|
|
62
|
+
/**
|
|
63
|
+
* A singleton no-op promise.
|
|
64
|
+
*/
|
|
65
|
+
export declare const noopAsyncSingletonPromise: Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* A function that does nothing.
|
|
68
|
+
*
|
|
69
|
+
* @returns A promise that resolves when the function is complete.
|
|
70
|
+
*/
|
|
71
|
+
export declare function noopAsync(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Makes an async function that calls the original async function with the provided arguments and omits the return value.
|
|
74
|
+
*
|
|
75
|
+
* @typeParam Arguments - Arguments to be passed to the function.
|
|
76
|
+
* @param $function - Function to be called.
|
|
77
|
+
* @returns An async function that calls the original function with the provided arguments and omits the return value.
|
|
78
|
+
*/
|
|
79
|
+
export declare function omitAsyncReturnType<Arguments extends unknown[]>($function: GenericAsyncFunction<Arguments>): GenericAsyncVoidFunction<Arguments>;
|
|
80
|
+
type ArgumentNamesOf<T extends GenericFunction> = MapToArgumentNames<Parameters<T>>;
|
|
81
|
+
interface CreateFunctionArgumentlessParams {
|
|
82
|
+
readonly functionBody: string;
|
|
83
|
+
}
|
|
84
|
+
interface CreateFunctionParams<TFunction extends GenericFunction> extends CreateFunctionArgumentlessParams {
|
|
85
|
+
readonly argumentNames: ArgumentNamesOf<TFunction>;
|
|
86
|
+
}
|
|
87
|
+
type MapToArgumentNames<TArguments extends readonly unknown[]> = {
|
|
88
|
+
readonly [K in keyof TArguments]: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Clone a function by creating a new function that calls the original function.
|
|
92
|
+
*
|
|
93
|
+
* This is useful for creating a new instance of a function that has the same behavior but is not strictly equal to the original function.
|
|
94
|
+
*
|
|
95
|
+
* @typeParam TFunction - The type of the function to clone.
|
|
96
|
+
* @param $function - The function to clone.
|
|
97
|
+
* @returns A new function that has the same behavior as the original function.
|
|
98
|
+
*/
|
|
99
|
+
export declare function cloneFunction<TFunction extends GenericFunction>($function: TFunction): TFunction;
|
|
100
|
+
/**
|
|
101
|
+
* Creates a function from the provided parameters.
|
|
102
|
+
*
|
|
103
|
+
* Function is argumentless, so `argNames` is not needed.
|
|
104
|
+
*
|
|
105
|
+
* @typeParam TFunction - The type of the function to create.
|
|
106
|
+
* @param params - The parameters to create the function with.
|
|
107
|
+
* @returns A function created from the provided parameters.
|
|
108
|
+
*/
|
|
109
|
+
export declare function createFunction<TFunction extends () => unknown>(params: CreateFunctionArgumentlessParams): TFunction;
|
|
110
|
+
/**
|
|
111
|
+
* Creates a function from the provided parameters.
|
|
112
|
+
*
|
|
113
|
+
* Function has arguments, so `argNames` is required.
|
|
114
|
+
*
|
|
115
|
+
* @typeParam TFunction - The type of the function to create.
|
|
116
|
+
* @param params - The parameters to create the function with.
|
|
117
|
+
* @returns A function created from the provided parameters.
|
|
118
|
+
*/
|
|
119
|
+
export declare function createFunction<TFunction extends GenericFunction>(params: CreateFunctionParams<TFunction>): TFunction;
|
|
120
|
+
/**
|
|
121
|
+
* Makes a function that calls the original function with the provided arguments and omits the return value.
|
|
122
|
+
*
|
|
123
|
+
* @typeParam Arguments - Arguments to be passed to the function.
|
|
124
|
+
* @param $function - Function to be called.
|
|
125
|
+
* @returns A function that calls the original function with the provided arguments and omits the return value.
|
|
126
|
+
*/
|
|
127
|
+
export declare function omitReturnType<Arguments extends unknown[]>($function: GenericFunction<Arguments>): GenericVoidFunction<Arguments>;
|
|
128
|
+
export {};
|