UNPKG

@tensorflow/tfjs-core

Version:

Hardware-accelerated JavaScript library for machine intelligence

136 lines 21.5 kB
/** * @license * Copyright 2019 Google LLC. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================================= */ import { env } from '../environment'; import { BROWSER_ENVS, describeWithFlags } from '../jasmine_util'; import { PlatformBrowser } from './platform_browser'; describeWithFlags('PlatformBrowser', BROWSER_ENVS, async () => { it('fetch calls window.fetch', async () => { const response = new Response(); spyOn(self, 'fetch').and.returnValue(Promise.resolve(response)); const platform = new PlatformBrowser(); await platform.fetch('test/url', { method: 'GET' }); expect(self.fetch).toHaveBeenCalledWith('test/url', { method: 'GET' }); }); it('now should use performance.now', async () => { const platform = new PlatformBrowser(); const ms = 1234567; spyOn(performance, 'now').and.returnValue(ms); expect(platform.now()).toEqual(ms); }); it('encodeUTF8 single string', () => { const platform = new PlatformBrowser(); const bytes = platform.encode('hello', 'utf-8'); expect(bytes.length).toBe(5); expect(bytes).toEqual(new Uint8Array([104, 101, 108, 108, 111])); }); it('encodeUTF8 two strings delimited', () => { const platform = new PlatformBrowser(); const bytes = platform.encode('hello\x00world', 'utf-8'); expect(bytes.length).toBe(11); expect(bytes).toEqual(new Uint8Array([104, 101, 108, 108, 111, 0, 119, 111, 114, 108, 100])); }); it('encodeUTF8 cyrillic', () => { const platform = new PlatformBrowser(); const bytes = platform.encode('Здраво', 'utf-8'); expect(bytes.length).toBe(12); expect(bytes).toEqual(new Uint8Array([208, 151, 208, 180, 209, 128, 208, 176, 208, 178, 208, 190])); }); it('decode single string', () => { const platform = new PlatformBrowser(); const s = platform.decode(new Uint8Array([104, 101, 108, 108, 111]), 'utf-8'); expect(s.length).toBe(5); expect(s).toEqual('hello'); }); it('decode two strings delimited', () => { const platform = new PlatformBrowser(); const s = platform.decode(new Uint8Array([104, 101, 108, 108, 111, 0, 119, 111, 114, 108, 100]), 'utf-8'); expect(s.length).toBe(11); expect(s).toEqual('hello\x00world'); }); it('decode cyrillic', () => { const platform = new PlatformBrowser(); const s = platform.decode(new Uint8Array([208, 151, 208, 180, 209, 128, 208, 176, 208, 178, 208, 190]), 'utf-8'); expect(s.length).toBe(6); expect(s).toEqual('Здраво'); }); }); describeWithFlags('setTimeout', BROWSER_ENVS, () => { const totalCount = 100; // Skip the first few samples because the browser does not clamp the timeout const skipCount = 5; it('setTimeout', (done) => { let count = 0; let startTime = performance.now(); let totalTime = 0; setTimeout(_testSetTimeout, 0); function _testSetTimeout() { const endTime = performance.now(); count++; if (count > skipCount) { totalTime += endTime - startTime; } if (count === totalCount) { const averageTime = totalTime / (totalCount - skipCount); console.log(`averageTime of setTimeout is ${averageTime} ms`); expect(averageTime).toBeGreaterThan(4); done(); return; } startTime = performance.now(); setTimeout(_testSetTimeout, 0); } }); it('setTimeoutCustom', (done) => { let count = 0; let startTime = performance.now(); let totalTime = 0; let originUseSettimeoutcustom; originUseSettimeoutcustom = env().getBool('USE_SETTIMEOUTCUSTOM'); env().set('USE_SETTIMEOUTCUSTOM', true); env().platform.setTimeoutCustom(_testSetTimeoutCustom, 0); function _testSetTimeoutCustom() { const endTime = performance.now(); count++; if (count > skipCount) { totalTime += endTime - startTime; } if (count === totalCount) { const averageTime = totalTime / (totalCount - skipCount); console.log(`averageTime of setTimeoutCustom is ${averageTime} ms`); expect(averageTime).toBeLessThan(4); done(); env().set('USE_SETTIMEOUTCUSTOM', originUseSettimeoutcustom); return; } startTime = performance.now(); env().platform.setTimeoutCustom(_testSetTimeoutCustom, 0); } }); it('isTypedArray returns false if not a typed array', () => { const platform = new PlatformBrowser(); expect(platform.isTypedArray([1, 2, 3])).toBeFalse(); }); for (const typedArrayConstructor of [Float32Array, Int32Array, Uint8Array, Uint8ClampedArray]) { it(`isTypedArray returns true if it is a ${typedArrayConstructor.name}`, () => { const platform = new PlatformBrowser(); const array = new typedArrayConstructor([1, 2, 3]); expect(platform.isTypedArray(array)).toBeTrue(); }); } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm1fYnJvd3Nlcl90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9wbGF0Zm9ybXMvcGxhdGZvcm1fYnJvd3Nlcl90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuQyxPQUFPLEVBQUMsWUFBWSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFaEUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRW5ELGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLFlBQVksRUFBRSxLQUFLLElBQUksRUFBRTtJQUM1RCxFQUFFLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDeEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNoQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sUUFBUSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFFdkMsTUFBTSxRQUFRLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO1FBRWxELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7SUFDdkUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDOUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUV2QyxNQUFN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QUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN2RCxDQUFDLENBQUMsQ0FBQztJQUVILEtBQUssTUFBTSxxQkFBcUIsSUFBSSxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsVUFBVTtRQUNyRSxpQkFBaUIsQ0FBQyxFQUFFO1FBQ3RCLEVBQUUsQ0FBQyx3Q0FBd0MscUJBQXFCLENBQUMsSUFBSSxFQUFFLEVBQ3BFLEdBQUcsRUFBRTtZQUNILE1BQU0sUUFBUSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7WUFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO0tBQ1A7QUFDSCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0IHtlbnZ9IGZyb20gJy4uL2Vudmlyb25tZW50JztcbmltcG9ydCB7QlJPV1NFUl9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcblxuaW1wb3J0IHtQbGF0Zm9ybUJyb3dzZXJ9IGZyb20gJy4vcGxhdGZvcm1fYnJvd3Nlcic7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdQbGF0Zm9ybUJyb3dzZXInLCBCUk9XU0VSX0VOVlMsIGFzeW5jICgpID0+IHtcbiAgaXQoJ2ZldGNoIGNhbGxzIHdpbmRvdy5mZXRjaCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IG5ldyBSZXNwb25zZSgpO1xuICAgIHNweU9uKHNlbGYsICdmZXRjaCcpLmFuZC5yZXR1cm5WYWx1ZShQcm9taXNlLnJlc29sdmUocmVzcG9uc2UpKTtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcblxuICAgIGF3YWl0IHBsYXRmb3JtLmZldGNoKCd0ZXN0L3VybCcsIHttZXRob2Q6ICdHRVQnfSk7XG5cbiAgICBleHBlY3Qoc2VsZi5mZXRjaCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3Rlc3QvdXJsJywge21ldGhvZDogJ0dFVCd9KTtcbiAgfSk7XG5cbiAgaXQoJ25vdyBzaG91bGQgdXNlIHBlcmZvcm1hbmNlLm5vdycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcblxuICAgIGNvbnN0IG1zID0gMTIzNDU2NztcbiAgICBzcHlPbihwZXJmb3JtYW5jZSwgJ25vdycpLmFuZC5yZXR1cm5WYWx1ZShtcyk7XG4gICAgZXhwZWN0KHBsYXRmb3JtLm5vdygpKS50b0VxdWFsKG1zKTtcbiAgfSk7XG5cbiAgaXQoJ2VuY29kZVVURjggc2luZ2xlIHN0cmluZycsICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcbiAgICBjb25zdCBieXRlcyA9IHBsYXRmb3JtLmVuY29kZSgnaGVsbG8nLCAndXRmLTgnKTtcbiAgICBleHBlY3QoYnl0ZXMubGVuZ3RoKS50b0JlKDUpO1xuICAgIGV4cGVjdChieXRlcykudG9FcXVhbChuZXcgVWludDhBcnJheShbMTA0LCAxMDEsIDEwOCwgMTA4LCAxMTFdKSk7XG4gIH0pO1xuXG4gIGl0KCdlbmNvZGVVVEY4IHR3byBzdHJpbmdzIGRlbGltaXRlZCcsICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcbiAgICBjb25zdCBieXRlcyA9IHBsYXRmb3JtLmVuY29kZSgnaGVsbG9cXHgwMHdvcmxkJywgJ3V0Zi04Jyk7XG4gICAgZXhwZWN0KGJ5dGVzLmxlbmd0aCkudG9CZSgxMSk7XG4gICAgZXhwZWN0KGJ5dGVzKS50b0VxdWFsKFxuICAgICAgICBuZXcgVWludDhBcnJheShbMTA0LCAxMDEsIDEwOCwgMTA4LCAxMTEsIDAsIDExOSwgMTExLCAxMTQsIDEwOCwgMTAwXSkpO1xuICB9KTtcblxuICBpdCgnZW5jb2RlVVRGOCBjeXJpbGxpYycsICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcbiAgICBjb25zdCBieXRlcyA9IHBsYXRmb3JtLmVuY29kZSgn0JfQtNGA0LDQstC+JywgJ3V0Zi04Jyk7XG4gICAgZXhwZWN0KGJ5dGVzLmxlbmd0aCkudG9CZSgxMik7XG4gICAgZXhwZWN0KGJ5dGVzKS50b0VxdWFsKG5ldyBVaW50OEFycmF5KFxuICAgICAgICBbMjA4LCAxNTEsIDIwOCwgMTgwLCAyMDksIDEyOCwgMjA4LCAxNzYsIDIwOCwgMTc4LCAyMDgsIDE5MF0pKTtcbiAgfSk7XG5cbiAgaXQoJ2RlY29kZSBzaW5nbGUgc3RyaW5nJywgKCkgPT4ge1xuICAgIGNvbnN0IHBsYXRmb3JtID0gbmV3IFBsYXRmb3JtQnJvd3NlcigpO1xuICAgIGNvbnN0IHMgPVxuICAgICAgICBwbGF0Zm9ybS5kZWNvZGUobmV3IFVpbnQ4QXJyYXkoWzEwNCwgMTAxLCAxMDgsIDEwOCwgMTExXSksICd1dGYtOCcpO1xuICAgIGV4cGVjdChzLmxlbmd0aCkudG9CZSg1KTtcbiAgICBleHBlY3QocykudG9FcXVhbCgnaGVsbG8nKTtcbiAgfSk7XG5cbiAgaXQoJ2RlY29kZSB0d28gc3RyaW5ncyBkZWxpbWl0ZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgcGxhdGZvcm0gPSBuZXcgUGxhdGZvcm1Ccm93c2VyKCk7XG4gICAgY29uc3QgcyA9IHBsYXRmb3JtLmRlY29kZShcbiAgICAgICAgbmV3IFVpbnQ4QXJyYXkoWzEwNCwgMTAxLCAxMDgsIDEwOCwgMTExLCAwLCAxMTksIDExMSwgMTE0LCAxMDgsIDEwMF0pLFxuICAgICAgICAndXRmLTgnKTtcbiAgICBleHBlY3Qocy5sZW5ndGgpLnRvQmUoMTEpO1xuICAgIGV4cGVjdChzKS50b0VxdWFsKCdoZWxsb1xceDAwd29ybGQnKTtcbiAgfSk7XG5cbiAgaXQoJ2RlY29kZSBjeXJpbGxpYycsICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcbiAgICBjb25zdCBzID0gcGxhdGZvcm0uZGVjb2RlKFxuICAgICAgICBuZXcgVWludDhBcnJheShcbiAgICAgICAgICAgIFsyMDgsIDE1MSwgMjA4LCAxODAsIDIwOSwgMTI4LCAyMDgsIDE3NiwgMjA4LCAxNzgsIDIwOCwgMTkwXSksXG4gICAgICAgICd1dGYtOCcpO1xuICAgIGV4cGVjdChzLmxlbmd0aCkudG9CZSg2KTtcbiAgICBleHBlY3QocykudG9FcXVhbCgn0JfQtNGA0LDQstC+Jyk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdzZXRUaW1lb3V0JywgQlJPV1NFUl9FTlZTLCAoKSA9PiB7XG4gIGNvbnN0IHRvdGFsQ291bnQgPSAxMDA7XG4gIC8vIFNraXAgdGhlIGZpcnN0IGZldyBzYW1wbGVzIGJlY2F1c2UgdGhlIGJyb3dzZXIgZG9lcyBub3QgY2xhbXAgdGhlIHRpbWVvdXRcbiAgY29uc3Qgc2tpcENvdW50ID0gNTtcblxuICBpdCgnc2V0VGltZW91dCcsIChkb25lKSA9PiB7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBsZXQgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgbGV0IHRvdGFsVGltZSA9IDA7XG4gICAgc2V0VGltZW91dChfdGVzdFNldFRpbWVvdXQsIDApO1xuXG4gICAgZnVuY3Rpb24gX3Rlc3RTZXRUaW1lb3V0KCkge1xuICAgICAgY29uc3QgZW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgY291bnQrKztcbiAgICAgIGlmIChjb3VudCA+IHNraXBDb3VudCkge1xuICAgICAgICB0b3RhbFRpbWUgKz0gZW5kVGltZSAtIHN0YXJ0VGltZTtcbiAgICAgIH1cbiAgICAgIGlmIChjb3VudCA9PT0gdG90YWxDb3VudCkge1xuICAgICAgICBjb25zdCBhdmVyYWdlVGltZSA9IHRvdGFsVGltZSAvICh0b3RhbENvdW50IC0gc2tpcENvdW50KTtcbiAgICAgICAgY29uc29sZS5sb2coYGF2ZXJhZ2VUaW1lIG9mIHNldFRpbWVvdXQgaXMgJHthdmVyYWdlVGltZX0gbXNgKTtcbiAgICAgICAgZXhwZWN0KGF2ZXJhZ2VUaW1lKS50b0JlR3JlYXRlclRoYW4oNCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICBzZXRUaW1lb3V0KF90ZXN0U2V0VGltZW91dCwgMCk7XG4gICAgfVxuICB9KTtcblxuICBpdCgnc2V0VGltZW91dEN1c3RvbScsIChkb25lKSA9PiB7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBsZXQgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgbGV0IHRvdGFsVGltZSA9IDA7XG4gICAgbGV0IG9yaWdpblVzZVNldHRpbWVvdXRjdXN0b206IGJvb2xlYW47XG5cbiAgICBvcmlnaW5Vc2VTZXR0aW1lb3V0Y3VzdG9tID0gZW52KCkuZ2V0Qm9vbCgnVVNFX1NFVFRJTUVPVVRDVVNUT00nKTtcbiAgICBlbnYoKS5zZXQoJ1VTRV9TRVRUSU1FT1VUQ1VTVE9NJywgdHJ1ZSk7XG4gICAgZW52KCkucGxhdGZvcm0uc2V0VGltZW91dEN1c3RvbShfdGVzdFNldFRpbWVvdXRDdXN0b20sIDApO1xuXG4gICAgZnVuY3Rpb24gX3Rlc3RTZXRUaW1lb3V0Q3VzdG9tKCkge1xuICAgICAgY29uc3QgZW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgY291bnQrKztcbiAgICAgIGlmIChjb3VudCA+IHNraXBDb3VudCkge1xuICAgICAgICB0b3RhbFRpbWUgKz0gZW5kVGltZSAtIHN0YXJ0VGltZTtcbiAgICAgIH1cbiAgICAgIGlmIChjb3VudCA9PT0gdG90YWxDb3VudCkge1xuICAgICAgICBjb25zdCBhdmVyYWdlVGltZSA9IHRvdGFsVGltZSAvICh0b3RhbENvdW50IC0gc2tpcENvdW50KTtcbiAgICAgICAgY29uc29sZS5sb2coYGF2ZXJhZ2VUaW1lIG9mIHNldFRpbWVvdXRDdXN0b20gaXMgJHthdmVyYWdlVGltZX0gbXNgKTtcbiAgICAgICAgZXhwZWN0KGF2ZXJhZ2VUaW1lKS50b0JlTGVzc1RoYW4oNCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgICAgZW52KCkuc2V0KCdVU0VfU0VUVElNRU9VVENVU1RPTScsIG9yaWdpblVzZVNldHRpbWVvdXRjdXN0b20pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgIGVudigpLnBsYXRmb3JtLnNldFRpbWVvdXRDdXN0b20oX3Rlc3RTZXRUaW1lb3V0Q3VzdG9tLCAwKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdpc1R5cGVkQXJyYXkgcmV0dXJucyBmYWxzZSBpZiBub3QgYSB0eXBlZCBhcnJheScsICgpID0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IG5ldyBQbGF0Zm9ybUJyb3dzZXIoKTtcbiAgICBleHBlY3QocGxhdGZvcm0uaXNUeXBlZEFycmF5KFsxLCAyLCAzXSkpLnRvQmVGYWxzZSgpO1xuICB9KTtcblxuICBmb3IgKGNvbnN0IHR5cGVkQXJyYXlDb25zdHJ1Y3RvciBvZiBbRmxvYXQzMkFycmF5LCBJbnQzMkFycmF5LCBVaW50OEFycmF5LFxuICAgICAgVWludDhDbGFtcGVkQXJyYXldKSB7XG4gICAgaXQoYGlzVHlwZWRBcnJheSByZXR1cm5zIHRydWUgaWYgaXQgaXMgYSAke3R5cGVkQXJyYXlDb25zdHJ1Y3Rvci5uYW1lfWAsXG4gICAgICAgKCkgPT4ge1xuICAgICAgICAgY29uc3QgcGxhdGZvcm0gPSBuZXcgUGxhdGZvcm1Ccm93c2VyKCk7XG4gICAgICAgICBjb25zdCBhcnJheSA9IG5ldyB0eXBlZEFycmF5Q29uc3RydWN0b3IoWzEsMiwzXSk7XG4gICAgICAgICBleHBlY3QocGxhdGZvcm0uaXNUeXBlZEFycmF5KGFycmF5KSkudG9CZVRydWUoKTtcbiAgICAgICB9KTtcbiAgfVxufSk7XG4iXX0=