1 | /**
|
---|
2 | * @license
|
---|
3 | * Copyright Google LLC All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
6 | * found in the LICENSE file at https://angular.io/license
|
---|
7 | */
|
---|
8 | /**
|
---|
9 | * @fileoverview
|
---|
10 | * A module to facilitate use of a Trusted Types policy within the JIT
|
---|
11 | * compiler. It lazily constructs the Trusted Types policy, providing helper
|
---|
12 | * utilities for promoting strings to Trusted Types. When Trusted Types are not
|
---|
13 | * available, strings are used as a fallback.
|
---|
14 | * @security All use of this module is security-sensitive and should go through
|
---|
15 | * security review.
|
---|
16 | */
|
---|
17 | import { global } from '../util';
|
---|
18 | /**
|
---|
19 | * The Trusted Types policy, or null if Trusted Types are not
|
---|
20 | * enabled/supported, or undefined if the policy has not been created yet.
|
---|
21 | */
|
---|
22 | let policy;
|
---|
23 | /**
|
---|
24 | * Returns the Trusted Types policy, or null if Trusted Types are not
|
---|
25 | * enabled/supported. The first call to this function will create the policy.
|
---|
26 | */
|
---|
27 | function getPolicy() {
|
---|
28 | if (policy === undefined) {
|
---|
29 | policy = null;
|
---|
30 | if (global.trustedTypes) {
|
---|
31 | try {
|
---|
32 | policy =
|
---|
33 | global.trustedTypes.createPolicy('angular#unsafe-jit', {
|
---|
34 | createScript: (s) => s,
|
---|
35 | });
|
---|
36 | }
|
---|
37 | catch (_a) {
|
---|
38 | // trustedTypes.createPolicy throws if called with a name that is
|
---|
39 | // already registered, even in report-only mode. Until the API changes,
|
---|
40 | // catch the error not to break the applications functionally. In such
|
---|
41 | // cases, the code will fall back to using strings.
|
---|
42 | }
|
---|
43 | }
|
---|
44 | }
|
---|
45 | return policy;
|
---|
46 | }
|
---|
47 | /**
|
---|
48 | * Unsafely promote a string to a TrustedScript, falling back to strings when
|
---|
49 | * Trusted Types are not available.
|
---|
50 | * @security In particular, it must be assured that the provided string will
|
---|
51 | * never cause an XSS vulnerability if used in a context that will be
|
---|
52 | * interpreted and executed as a script by a browser, e.g. when calling eval.
|
---|
53 | */
|
---|
54 | function trustedScriptFromString(script) {
|
---|
55 | var _a;
|
---|
56 | return ((_a = getPolicy()) === null || _a === void 0 ? void 0 : _a.createScript(script)) || script;
|
---|
57 | }
|
---|
58 | /**
|
---|
59 | * Unsafely call the Function constructor with the given string arguments.
|
---|
60 | * @security This is a security-sensitive function; any use of this function
|
---|
61 | * must go through security review. In particular, it must be assured that it
|
---|
62 | * is only called from the JIT compiler, as use in other code can lead to XSS
|
---|
63 | * vulnerabilities.
|
---|
64 | */
|
---|
65 | export function newTrustedFunctionForJIT(...args) {
|
---|
66 | if (!global.trustedTypes) {
|
---|
67 | // In environments that don't support Trusted Types, fall back to the most
|
---|
68 | // straightforward implementation:
|
---|
69 | return new Function(...args);
|
---|
70 | }
|
---|
71 | // Chrome currently does not support passing TrustedScript to the Function
|
---|
72 | // constructor. The following implements the workaround proposed on the page
|
---|
73 | // below, where the Chromium bug is also referenced:
|
---|
74 | // https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor
|
---|
75 | const fnArgs = args.slice(0, -1).join(',');
|
---|
76 | const fnBody = args[args.length - 1];
|
---|
77 | const body = `(function anonymous(${fnArgs}
|
---|
78 | ) { ${fnBody}
|
---|
79 | })`;
|
---|
80 | // Using eval directly confuses the compiler and prevents this module from
|
---|
81 | // being stripped out of JS binaries even if not used. The global['eval']
|
---|
82 | // indirection fixes that.
|
---|
83 | const fn = global['eval'](trustedScriptFromString(body));
|
---|
84 | if (fn.bind === undefined) {
|
---|
85 | // Workaround for a browser bug that only exists in Chrome 83, where passing
|
---|
86 | // a TrustedScript to eval just returns the TrustedScript back without
|
---|
87 | // evaluating it. In that case, fall back to the most straightforward
|
---|
88 | // implementation:
|
---|
89 | return new Function(...args);
|
---|
90 | }
|
---|
91 | // To completely mimic the behavior of calling "new Function", two more
|
---|
92 | // things need to happen:
|
---|
93 | // 1. Stringifying the resulting function should return its source code
|
---|
94 | fn.toString = () => body;
|
---|
95 | // 2. When calling the resulting function, `this` should refer to `global`
|
---|
96 | return fn.bind(global);
|
---|
97 | // When Trusted Types support in Function constructors is widely available,
|
---|
98 | // the implementation of this function can be simplified to:
|
---|
99 | // return new Function(...args.map(a => trustedScriptFromString(a)));
|
---|
100 | }
|
---|
101 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0X2ppdF90cnVzdGVkX3R5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL291dHB1dC9vdXRwdXRfaml0X3RydXN0ZWRfdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUg7Ozs7Ozs7O0dBUUc7QUFFSCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBbUMvQjs7O0dBR0c7QUFDSCxJQUFJLE1BQXdDLENBQUM7QUFFN0M7OztHQUdHO0FBQ0gsU0FBUyxTQUFTO0lBQ2hCLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtRQUN4QixNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ2QsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO1lBQ3ZCLElBQUk7Z0JBQ0YsTUFBTTtvQkFDRCxNQUFNLENBQUMsWUFBeUMsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLEVBQUU7d0JBQ25GLFlBQVksRUFBRSxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztxQkFDL0IsQ0FBQyxDQUFDO2FBQ1I7WUFBQyxXQUFNO2dCQUNOLGlFQUFpRTtnQkFDakUsdUVBQXVFO2dCQUN2RSxzRUFBc0U7Z0JBQ3RFLG1EQUFtRDthQUNwRDtTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyx1QkFBdUIsQ0FBQyxNQUFjOztJQUM3QyxPQUFPLENBQUEsTUFBQSxTQUFTLEVBQUUsMENBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFJLE1BQU0sQ0FBQztBQUNyRCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLHdCQUF3QixDQUFDLEdBQUcsSUFBYztJQUN4RCxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtRQUN4QiwwRUFBMEU7UUFDMUUsa0NBQWtDO1FBQ2xDLE9BQU8sSUFBSSxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztLQUM5QjtJQUVELDBFQUEwRTtJQUMxRSw0RUFBNEU7SUFDNUUsb0RBQW9EO0lBQ3BELDZGQUE2RjtJQUM3RixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNyQyxNQUFNLElBQUksR0FBRyx1QkFBdUIsTUFBTTtNQUN0QyxNQUFNO0dBQ1QsQ0FBQztJQUVGLDBFQUEwRTtJQUMxRSx5RUFBeUU7SUFDekUsMEJBQTBCO0lBQzFCLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQVcsQ0FBYSxDQUFDO0lBQy9FLElBQUksRUFBRSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUU7UUFDekIsNEVBQTRFO1FBQzVFLHNFQUFzRTtRQUN0RSxxRUFBcUU7UUFDckUsa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztLQUM5QjtJQUVELHVFQUF1RTtJQUN2RSx5QkFBeUI7SUFDekIsdUVBQXVFO0lBQ3ZFLEVBQUUsQ0FBQyxRQUFRLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO0lBQ3pCLDBFQUEwRTtJQUMxRSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFdkIsMkVBQTJFO0lBQzNFLDREQUE0RDtJQUM1RCxxRUFBcUU7QUFDdkUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG4vKipcbiAqIEBmaWxlb3ZlcnZpZXdcbiAqIEEgbW9kdWxlIHRvIGZhY2lsaXRhdGUgdXNlIG9mIGEgVHJ1c3RlZCBUeXBlcyBwb2xpY3kgd2l0aGluIHRoZSBKSVRcbiAqIGNvbXBpbGVyLiBJdCBsYXppbHkgY29uc3RydWN0cyB0aGUgVHJ1c3RlZCBUeXBlcyBwb2xpY3ksIHByb3ZpZGluZyBoZWxwZXJcbiAqIHV0aWxpdGllcyBmb3IgcHJvbW90aW5nIHN0cmluZ3MgdG8gVHJ1c3RlZCBUeXBlcy4gV2hlbiBUcnVzdGVkIFR5cGVzIGFyZSBub3RcbiAqIGF2YWlsYWJsZSwgc3RyaW5ncyBhcmUgdXNlZCBhcyBhIGZhbGxiYWNrLlxuICogQHNlY3VyaXR5IEFsbCB1c2Ugb2YgdGhpcyBtb2R1bGUgaXMgc2VjdXJpdHktc2Vuc2l0aXZlIGFuZCBzaG91bGQgZ28gdGhyb3VnaFxuICogc2VjdXJpdHkgcmV2aWV3LlxuICovXG5cbmltcG9ydCB7Z2xvYmFsfSBmcm9tICcuLi91dGlsJztcblxuLyoqXG4gKiBXaGlsZSBBbmd1bGFyIG9ubHkgdXNlcyBUcnVzdGVkIFR5cGVzIGludGVybmFsbHkgZm9yIHRoZSB0aW1lIGJlaW5nLFxuICogcmVmZXJlbmNlcyB0byBUcnVzdGVkIFR5cGVzIGNvdWxkIGxlYWsgaW50byBvdXIgY29yZS5kLnRzLCB3aGljaCB3b3VsZCBmb3JjZVxuICogYW55b25lIGNvbXBpbGluZyBhZ2FpbnN0IEBhbmd1bGFyL2NvcmUgdG8gcHJvdmlkZSB0aGUgQHR5cGVzL3RydXN0ZWQtdHlwZXNcbiAqIHBhY2thZ2UgaW4gdGhlaXIgY29tcGlsYXRpb24gdW5pdC5cbiAqXG4gKiBVbnRpbCBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzMwMDI0IGlzIHJlc29sdmVkLCB3ZVxuICogd2lsbCBrZWVwIEFuZ3VsYXIncyBwdWJsaWMgQVBJIHN1cmZhY2UgZnJlZSBvZiByZWZlcmVuY2VzIHRvIFRydXN0ZWQgVHlwZXMuXG4gKiBGb3IgaW50ZXJuYWwgYW5kIHNlbWktcHJpdmF0ZSBBUElzIHRoYXQgbmVlZCB0byByZWZlcmVuY2UgVHJ1c3RlZCBUeXBlcywgdGhlXG4gKiBtaW5pbWFsIHR5cGUgZGVmaW5pdGlvbnMgZm9yIHRoZSBUcnVzdGVkIFR5cGVzIEFQSSBwcm92aWRlZCBieSB0aGlzIG1vZHVsZVxuICogc2hvdWxkIGJlIHVzZWQgaW5zdGVhZC4gVGhleSBhcmUgbWFya2VkIGFzIFwiZGVjbGFyZVwiIHRvIHByZXZlbnQgdGhlbSBmcm9tXG4gKiBiZWluZyByZW5hbWVkIGJ5IGNvbXBpbGVyIG9wdGltaXphdGlvbi5cbiAqXG4gKiBBZGFwdGVkIGZyb21cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9EZWZpbml0ZWx5VHlwZWQvRGVmaW5pdGVseVR5cGVkL2Jsb2IvbWFzdGVyL3R5cGVzL3RydXN0ZWQtdHlwZXMvaW5kZXguZC50c1xuICogYnV0IHJlc3RyaWN0ZWQgdG8gdGhlIEFQSSBzdXJmYWNlIHVzZWQgd2l0aGluIEFuZ3VsYXIuXG4gKi9cblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIFRydXN0ZWRTY3JpcHQge1xuICBfX2JyYW5kX186ICdUcnVzdGVkU2NyaXB0Jztcbn1cblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIFRydXN0ZWRUeXBlUG9saWN5RmFjdG9yeSB7XG4gIGNyZWF0ZVBvbGljeShwb2xpY3lOYW1lOiBzdHJpbmcsIHBvbGljeU9wdGlvbnM6IHtcbiAgICBjcmVhdGVTY3JpcHQ/OiAoaW5wdXQ6IHN0cmluZykgPT4gc3RyaW5nLFxuICB9KTogVHJ1c3RlZFR5cGVQb2xpY3k7XG59XG5cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBUcnVzdGVkVHlwZVBvbGljeSB7XG4gIGNyZWF0ZVNjcmlwdChpbnB1dDogc3RyaW5nKTogVHJ1c3RlZFNjcmlwdDtcbn1cblxuXG4vKipcbiAqIFRoZSBUcnVzdGVkIFR5cGVzIHBvbGljeSwgb3IgbnVsbCBpZiBUcnVzdGVkIFR5cGVzIGFyZSBub3RcbiAqIGVuYWJsZWQvc3VwcG9ydGVkLCBvciB1bmRlZmluZWQgaWYgdGhlIHBvbGljeSBoYXMgbm90IGJlZW4gY3JlYXRlZCB5ZXQuXG4gKi9cbmxldCBwb2xpY3k6IFRydXN0ZWRUeXBlUG9saWN5fG51bGx8dW5kZWZpbmVkO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIFRydXN0ZWQgVHlwZXMgcG9saWN5LCBvciBudWxsIGlmIFRydXN0ZWQgVHlwZXMgYXJlIG5vdFxuICogZW5hYmxlZC9zdXBwb3J0ZWQuIFRoZSBmaXJzdCBjYWxsIHRvIHRoaXMgZnVuY3Rpb24gd2lsbCBjcmVhdGUgdGhlIHBvbGljeS5cbiAqL1xuZnVuY3Rpb24gZ2V0UG9saWN5KCk6IFRydXN0ZWRUeXBlUG9saWN5fG51bGwge1xuICBpZiAocG9saWN5ID09PSB1bmRlZmluZWQpIHtcbiAgICBwb2xpY3kgPSBudWxsO1xuICAgIGlmIChnbG9iYWwudHJ1c3RlZFR5cGVzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBwb2xpY3kgPVxuICAgICAgICAgICAgKGdsb2JhbC50cnVzdGVkVHlwZXMgYXMgVHJ1c3RlZFR5cGVQb2xpY3lGYWN0b3J5KS5jcmVhdGVQb2xpY3koJ2FuZ3VsYXIjdW5zYWZlLWppdCcsIHtcbiAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0OiAoczogc3RyaW5nKSA9PiBzLFxuICAgICAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gdHJ1c3RlZFR5cGVzLmNyZWF0ZVBvbGljeSB0aHJvd3MgaWYgY2FsbGVkIHdpdGggYSBuYW1lIHRoYXQgaXNcbiAgICAgICAgLy8gYWxyZWFkeSByZWdpc3RlcmVkLCBldmVuIGluIHJlcG9ydC1vbmx5IG1vZGUuIFVudGlsIHRoZSBBUEkgY2hhbmdlcyxcbiAgICAgICAgLy8gY2F0Y2ggdGhlIGVycm9yIG5vdCB0byBicmVhayB0aGUgYXBwbGljYXRpb25zIGZ1bmN0aW9uYWxseS4gSW4gc3VjaFxuICAgICAgICAvLyBjYXNlcywgdGhlIGNvZGUgd2lsbCBmYWxsIGJhY2sgdG8gdXNpbmcgc3RyaW5ncy5cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHBvbGljeTtcbn1cblxuLyoqXG4gKiBVbnNhZmVseSBwcm9tb3RlIGEgc3RyaW5nIHRvIGEgVHJ1c3RlZFNjcmlwdCwgZmFsbGluZyBiYWNrIHRvIHN0cmluZ3Mgd2hlblxuICogVHJ1c3RlZCBUeXBlcyBhcmUgbm90IGF2YWlsYWJsZS5cbiAqIEBzZWN1cml0eSBJbiBwYXJ0aWN1bGFyLCBpdCBtdXN0IGJlIGFzc3VyZWQgdGhhdCB0aGUgcHJvdmlkZWQgc3RyaW5nIHdpbGxcbiAqIG5ldmVyIGNhdXNlIGFuIFhTUyB2dWxuZXJhYmlsaXR5IGlmIHVzZWQgaW4gYSBjb250ZXh0IHRoYXQgd2lsbCBiZVxuICogaW50ZXJwcmV0ZWQgYW5kIGV4ZWN1dGVkIGFzIGEgc2NyaXB0IGJ5IGEgYnJvd3NlciwgZS5nLiB3aGVuIGNhbGxpbmcgZXZhbC5cbiAqL1xuZnVuY3Rpb24gdHJ1c3RlZFNjcmlwdEZyb21TdHJpbmcoc2NyaXB0OiBzdHJpbmcpOiBUcnVzdGVkU2NyaXB0fHN0cmluZyB7XG4gIHJldHVybiBnZXRQb2xpY3koKT8uY3JlYXRlU2NyaXB0KHNjcmlwdCkgfHwgc2NyaXB0O1xufVxuXG4vKipcbiAqIFVuc2FmZWx5IGNhbGwgdGhlIEZ1bmN0aW9uIGNvbnN0cnVjdG9yIHdpdGggdGhlIGdpdmVuIHN0cmluZyBhcmd1bWVudHMuXG4gKiBAc2VjdXJpdHkgVGhpcyBpcyBhIHNlY3VyaXR5LXNlbnNpdGl2ZSBmdW5jdGlvbjsgYW55IHVzZSBvZiB0aGlzIGZ1bmN0aW9uXG4gKiBtdXN0IGdvIHRocm91Z2ggc2VjdXJpdHkgcmV2aWV3LiBJbiBwYXJ0aWN1bGFyLCBpdCBtdXN0IGJlIGFzc3VyZWQgdGhhdCBpdFxuICogaXMgb25seSBjYWxsZWQgZnJvbSB0aGUgSklUIGNvbXBpbGVyLCBhcyB1c2UgaW4gb3RoZXIgY29kZSBjYW4gbGVhZCB0byBYU1NcbiAqIHZ1bG5lcmFiaWxpdGllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5ld1RydXN0ZWRGdW5jdGlvbkZvckpJVCguLi5hcmdzOiBzdHJpbmdbXSk6IEZ1bmN0aW9uIHtcbiAgaWYgKCFnbG9iYWwudHJ1c3RlZFR5cGVzKSB7XG4gICAgLy8gSW4gZW52aXJvbm1lbnRzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBUcnVzdGVkIFR5cGVzLCBmYWxsIGJhY2sgdG8gdGhlIG1vc3RcbiAgICAvLyBzdHJhaWdodGZvcndhcmQgaW1wbGVtZW50YXRpb246XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbiguLi5hcmdzKTtcbiAgfVxuXG4gIC8vIENocm9tZSBjdXJyZW50bHkgZG9lcyBub3Qgc3VwcG9ydCBwYXNzaW5nIFRydXN0ZWRTY3JpcHQgdG8gdGhlIEZ1bmN0aW9uXG4gIC8vIGNvbnN0cnVjdG9yLiBUaGUgZm9sbG93aW5nIGltcGxlbWVudHMgdGhlIHdvcmthcm91bmQgcHJvcG9zZWQgb24gdGhlIHBhZ2VcbiAgLy8gYmVsb3csIHdoZXJlIHRoZSBDaHJvbWl1bSBidWcgaXMgYWxzbyByZWZlcmVuY2VkOlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vdzNjL3dlYmFwcHNlYy10cnVzdGVkLXR5cGVzL3dpa2kvVHJ1c3RlZC1UeXBlcy1mb3ItZnVuY3Rpb24tY29uc3RydWN0b3JcbiAgY29uc3QgZm5BcmdzID0gYXJncy5zbGljZSgwLCAtMSkuam9pbignLCcpO1xuICBjb25zdCBmbkJvZHkgPSBhcmdzW2FyZ3MubGVuZ3RoIC0gMV07XG4gIGNvbnN0IGJvZHkgPSBgKGZ1bmN0aW9uIGFub255bW91cygke2ZuQXJnc31cbikgeyAke2ZuQm9keX1cbn0pYDtcblxuICAvLyBVc2luZyBldmFsIGRpcmVjdGx5IGNvbmZ1c2VzIHRoZSBjb21waWxlciBhbmQgcHJldmVudHMgdGhpcyBtb2R1bGUgZnJvbVxuICAvLyBiZWluZyBzdHJpcHBlZCBvdXQgb2YgSlMgYmluYXJpZXMgZXZlbiBpZiBub3QgdXNlZC4gVGhlIGdsb2JhbFsnZXZhbCddXG4gIC8vIGluZGlyZWN0aW9uIGZpeGVzIHRoYXQuXG4gIGNvbnN0IGZuID0gZ2xvYmFsWydldmFsJ10odHJ1c3RlZFNjcmlwdEZyb21TdHJpbmcoYm9keSkgYXMgc3RyaW5nKSBhcyBGdW5jdGlvbjtcbiAgaWYgKGZuLmJpbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIFdvcmthcm91bmQgZm9yIGEgYnJvd3NlciBidWcgdGhhdCBvbmx5IGV4aXN0cyBpbiBDaHJvbWUgODMsIHdoZXJlIHBhc3NpbmdcbiAgICAvLyBhIFRydXN0ZWRTY3JpcHQgdG8gZXZhbCBqdXN0IHJldHVybnMgdGhlIFRydXN0ZWRTY3JpcHQgYmFjayB3aXRob3V0XG4gICAgLy8gZXZhbHVhdGluZyBpdC4gSW4gdGhhdCBjYXNlLCBmYWxsIGJhY2sgdG8gdGhlIG1vc3Qgc3RyYWlnaHRmb3J3YXJkXG4gICAgLy8gaW1wbGVtZW50YXRpb246XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbiguLi5hcmdzKTtcbiAgfVxuXG4gIC8vIFRvIGNvbXBsZXRlbHkgbWltaWMgdGhlIGJlaGF2aW9yIG9mIGNhbGxpbmcgXCJuZXcgRnVuY3Rpb25cIiwgdHdvIG1vcmVcbiAgLy8gdGhpbmdzIG5lZWQgdG8gaGFwcGVuOlxuICAvLyAxLiBTdHJpbmdpZnlpbmcgdGhlIHJlc3VsdGluZyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIGl0cyBzb3VyY2UgY29kZVxuICBmbi50b1N0cmluZyA9ICgpID0+IGJvZHk7XG4gIC8vIDIuIFdoZW4gY2FsbGluZyB0aGUgcmVzdWx0aW5nIGZ1bmN0aW9uLCBgdGhpc2Agc2hvdWxkIHJlZmVyIHRvIGBnbG9iYWxgXG4gIHJldHVybiBmbi5iaW5kKGdsb2JhbCk7XG5cbiAgLy8gV2hlbiBUcnVzdGVkIFR5cGVzIHN1cHBvcnQgaW4gRnVuY3Rpb24gY29uc3RydWN0b3JzIGlzIHdpZGVseSBhdmFpbGFibGUsXG4gIC8vIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGNhbiBiZSBzaW1wbGlmaWVkIHRvOlxuICAvLyByZXR1cm4gbmV3IEZ1bmN0aW9uKC4uLmFyZ3MubWFwKGEgPT4gdHJ1c3RlZFNjcmlwdEZyb21TdHJpbmcoYSkpKTtcbn1cbiJdfQ== |
---|