UNPKG

@nota/nativescript-webview-ext

Version:

Extended WebView for NativeScript which adds 'x-local' scheme for local-files. events between WebView and native-layer, javascript execution, injecting CSS and JS-files.

417 lines 70.4 kB
"use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); var fs = require("tns-core-modules/file-system"); var view_1 = require("tns-core-modules/ui/core/view"); var nativescript_webview_bridge_loader_1 = require("./nativescript-webview-bridge-loader"); var file_system_1 = require("tns-core-modules/file-system"); exports.File = file_system_1.File; exports.knownFolders = file_system_1.knownFolders; exports.path = file_system_1.path; __export(require("tns-core-modules/ui//core/view")); exports.srcProperty = new view_1.Property({ name: "src" }); exports.autoInjectJSBridgeProperty = new view_1.Property({ name: "autoInjectJSBridge", defaultValue: true }); var WebViewExtBase = (function (_super) { __extends(WebViewExtBase, _super); function WebViewExtBase() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.autoInjectJSBridge = true; _this.autoInjectScriptFiles = []; _this.autoInjectStyleSheetFiles = []; _this.autoInjectJavaScriptBlocks = []; _this._tmpStopLoading = false; return _this; } Object.defineProperty(WebViewExtBase.prototype, "interceptScheme", { get: function () { return 'x-local'; }, enumerable: true, configurable: true }); WebViewExtBase.prototype._onLoadFinished = function (url, error) { var _this = this; if (!error) { try { this._tmpStopLoading = true; this.src = url; this._tmpStopLoading = false; } finally { this._tmpStopLoading = false; } } var args = { eventName: WebViewExtBase.loadFinishedEvent, object: this, url: url, navigationType: undefined, error: error, }; if (error) { this.notify(args); return Promise.reject(args); } else { this.writeTrace("WebViewExt._onLoadFinished(\"" + url + "\", " + (error || void 0) + ") - > Injecting webview-bridge JS code"); if (!this.autoInjectJSBridge) { return Promise.resolve(args); } return this.injectWebViewBridge() .then(function () { return args; }) .catch(function (error) { return __assign({}, args, { error: error }); }) .then(function (args) { _this.notify(args); return args; }); } }; WebViewExtBase.prototype._onLoadStarted = function (url, navigationType) { var args = { eventName: WebViewExtBase.loadStartedEvent, object: this, url: url, navigationType: navigationType, error: undefined }; this.notify(args); }; WebViewExtBase.prototype._loadUrl = function (src) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype._loadData = function (src) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.stopLoading = function () { throw new Error("Method not implemented."); }; Object.defineProperty(WebViewExtBase.prototype, "canGoBack", { get: function () { throw new Error("This member is abstract."); }, enumerable: true, configurable: true }); Object.defineProperty(WebViewExtBase.prototype, "canGoForward", { get: function () { throw new Error("This member is abstract."); }, enumerable: true, configurable: true }); WebViewExtBase.prototype.goBack = function () { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.goForward = function () { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.reload = function () { throw new Error("Method not implemented."); }; WebViewExtBase.prototype[exports.srcProperty.getDefault] = function () { return ""; }; WebViewExtBase.prototype[exports.srcProperty.setNative] = function (src) { if (!src || this._tmpStopLoading) { return; } var originSrc = src; this.stopLoading(); if (src.startsWith(this.interceptScheme)) { this.writeTrace("WebViewExt.src = " + originSrc + " resolve x-local file"); var fileparh = this.getRegistretLocalResource(src); if (fileparh) { src = "file://" + fileparh; this.writeTrace("WebViewExt.src = " + originSrc + " x-local resolved to " + src); } else { this.writeTrace("WebViewExt.src = " + originSrc + " x-local couldn't resolve to file", view_1.traceMessageType.error); this._onLoadFinished(src, 'unknown x-local-resource'); return; } } if (src.startsWith("~/")) { src = "file://" + fs.knownFolders.currentApp().path + "/" + src.substr(2); this.writeTrace("WebViewExt.src = " + originSrc + " startsWith ~/ resolved to " + src); } else if (src.startsWith("/")) { src = "file://" + src; this.writeTrace("WebViewExt.src = " + originSrc + " startsWith \"/\" resolved to " + src); } var lcSrc = src.toLowerCase(); if (lcSrc.startsWith("file:///")) { src = encodeURI(src); if (lcSrc !== src) { this.writeTrace("WebViewExt.src = " + originSrc + " escaped to " + src); } } if (lcSrc.startsWith("http://") || lcSrc.startsWith("https://") || lcSrc.startsWith("file:///")) { this._loadUrl(src); this.writeTrace("WebViewExt.src = " + originSrc + " - LoadUrl(" + src + ")}"); } else { this._loadData(src); this.writeTrace("WebViewExt.src = " + originSrc + " - LoadData(" + src + ")}"); } }; WebViewExtBase.prototype.resolveLocalResourceFilePath = function (filepath) { if (!filepath) { console.error('WebViewExt.resolveLocalResourceFilePath() no filepath'); return; } if (filepath.startsWith('~')) { filepath = fs.path.normalize(fs.knownFolders.currentApp().path + filepath.substr(1)); } if (!fs.File.exists(filepath)) { console.error("WebViewExt.resolveLocalResourceFilePath(\"" + filepath + "\") - no such file"); return; } return filepath; }; WebViewExtBase.prototype.registerLocalResource = function (name, filepath) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.unregisterLocalResource = function (name) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.getRegistretLocalResource = function (name) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.loadUrl = function (src) { var _this = this; if (!src) { return this._onLoadFinished(src, 'empty src'); } return new Promise(function (resolve, reject) { var loadFinishedEvent = function (args) { _this.off(WebViewExtBase.loadFinishedEvent, loadFinishedEvent); if (args.error) { reject(args); } else { resolve(args); } }; _this.on(WebViewExtBase.loadFinishedEvent, loadFinishedEvent); _this.src = src; }); }; WebViewExtBase.prototype.loadJavaScriptFile = function (scriptName, filepath) { return this.loadJavaScriptFiles([{ resourceName: scriptName, filepath: filepath, }]); }; WebViewExtBase.prototype.loadJavaScriptFiles = function (files) { if (!files || !files.length) { return Promise.resolve(); } var promiseScriptCodes = []; for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { var _a = files_1[_i], resourceName = _a.resourceName, filepath = _a.filepath; resourceName = this.fixLocalResourceName(resourceName); if (filepath) { this.registerLocalResource(resourceName, filepath); } var href = this.interceptScheme + "://" + resourceName; var scriptCode = this.generateLoadJavaScriptFileScriptCode(href); promiseScriptCodes.push(scriptCode); this.writeTrace("WebViewExt.loadJavaScriptFiles() - > Loading javascript file: \"" + resourceName + "\""); } if (promiseScriptCodes.length !== files.length) { this.writeTrace("WebViewExt.loadJavaScriptFiles() - > Num of generated scriptCodes " + promiseScriptCodes.length + " differ from num files " + files.length, view_1.traceMessageType.error); } if (!promiseScriptCodes.length) { this.writeTrace('WebViewExt.loadJavaScriptFiles() - > No files'); return Promise.resolve(); } if (!promiseScriptCodes.length) { return Promise.resolve(); } return this.executePromises(promiseScriptCodes).then(function () { return void 0; }); }; WebViewExtBase.prototype.loadStyleSheetFile = function (stylesheetName, filepath, insertBefore) { if (insertBefore === void 0) { insertBefore = true; } return this.loadStyleSheetFiles([{ resourceName: stylesheetName, filepath: filepath, insertBefore: insertBefore, }]); }; WebViewExtBase.prototype.loadStyleSheetFiles = function (files) { if (!files || !files.length) { return Promise.resolve(); } var promiseScriptCodes = []; for (var _i = 0, files_2 = files; _i < files_2.length; _i++) { var _a = files_2[_i], resourceName = _a.resourceName, filepath = _a.filepath, insertBefore = _a.insertBefore; resourceName = this.fixLocalResourceName(resourceName); if (filepath) { this.registerLocalResource(resourceName, filepath); } var href = this.interceptScheme + "://" + resourceName; var scriptCode = this.generaateLoadCSSFileScriptCode(href, insertBefore); promiseScriptCodes.push(scriptCode); this.writeTrace('WebViewExt.loadStyleSheetFiles() - > Loading stylesheet file: ' + href); } if (promiseScriptCodes.length !== files.length) { this.writeTrace("WebViewExt.loadStyleSheetFiles() - > Num of generated scriptCodes " + promiseScriptCodes.length + " differ from num files " + files.length, view_1.traceMessageType.error); } if (!promiseScriptCodes.length) { this.writeTrace('WebViewExt.loadStyleSheetFiles() - > No files'); return Promise.resolve(); } return this.executePromises(promiseScriptCodes).then(function () { return void 0; }); }; WebViewExtBase.prototype.autoLoadJavaScriptFile = function (resourceName, filepath) { if (this.src) { this.loadJavaScriptFile(resourceName, filepath).catch(function () { return void 0; }); } this.autoInjectScriptFiles.push({ resourceName: resourceName, filepath: filepath }); }; WebViewExtBase.prototype.removeAutoLoadJavaScriptFile = function (resourceName) { this.autoInjectScriptFiles = this.autoInjectScriptFiles.filter(function (data) { return data.resourceName !== resourceName; }); }; WebViewExtBase.prototype.autoLoadStyleSheetFile = function (resourceName, filepath, insertBefore) { if (this.src) { this.loadStyleSheetFile(resourceName, filepath, insertBefore).catch(function () { return void 0; }); } this.autoInjectStyleSheetFiles.push({ resourceName: resourceName, filepath: filepath, insertBefore: insertBefore }); }; WebViewExtBase.prototype.removeAutoLoadStyleSheetFile = function (resourceName) { this.autoInjectStyleSheetFiles = this.autoInjectStyleSheetFiles.filter(function (data) { return data.resourceName !== resourceName; }); }; WebViewExtBase.prototype.autoExecuteJavaScript = function (scriptCode, name) { if (this.src) { this.executePromise(scriptCode).catch(function () { return void 0; }); } this.removeAutoExecuteJavaScript(name); var fixedCodeBlock = scriptCode.trim(); this.autoInjectJavaScriptBlocks.push({ scriptCode: fixedCodeBlock, name: name }); }; WebViewExtBase.prototype.removeAutoExecuteJavaScript = function (name) { this.autoInjectJavaScriptBlocks = this.autoInjectJavaScriptBlocks.filter(function (data) { return data.name !== name; }); }; WebViewExtBase.prototype.executeJavaScript = function (scriptCode, stringifyResult) { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.executePromise = function (scriptCode, timeout) { if (timeout === void 0) { timeout = 500; } return this.executePromises([scriptCode], timeout).then(function (results) { return results && results[0]; }); }; WebViewExtBase.prototype.executePromises = function (scriptCodes, timeout) { var _this = this; if (timeout === void 0) { timeout = 500; } if (scriptCodes.length === 0) { return Promise.resolve(); } var reqId = "" + Math.round(Math.random() * 1000); var eventName = "tmp-promise-event-" + reqId; var scriptHeader = "(function() {\n var promises = [];\n var p = Promise.resolve();\n var i = 0;\n "; var scriptBody = []; for (var _i = 0, scriptCodes_1 = scriptCodes; _i < scriptCodes_1.length; _i++) { var scriptCode_1 = scriptCodes_1[_i]; scriptBody.push("\n p = p.then(function() {\n return " + scriptCode_1.trim() + ";\n });\n promises.push(p);\n "); } var scriptFooter = "\n return Promise.all(promises);\n })()"; var scriptCode = scriptHeader + "\n " + scriptBody.join(';') + "\n " + scriptFooter; var trimmedScriptCode = scriptCode.trim(); var promiseScriptCode = "\n var eventName = " + JSON.stringify(eventName) + ";\n try {\n var promise = (function() {return " + trimmedScriptCode + "})();\n window.nsWebViewBridge.executePromise(promise, eventName);\n } catch (err) {\n window.nsWebViewBridge.emitError(err, eventName);\n }\n "; return new Promise(function (resolve, reject) { var timer; var tmpPromiseEvent = function (args) { _this.off(eventName); var _a = args.data || {}, data = _a.data, err = _a.err; if (err) { var error = new Error(err.message || err); if (err.stack) { error.webStack = err.stack; } reject(error); return; } resolve(data); clearTimeout(timer); }; _this.on(eventName, tmpPromiseEvent); _this.executeJavaScript(promiseScriptCode, false); if (timeout > 0) { timer = setTimeout(function () { reject(new Error("Timed out after: " + timeout)); _this.off(eventName); }, timeout); } }); }; WebViewExtBase.prototype.generateLoadJavaScriptFileScriptCode = function (scriptHref) { return "window.nsWebViewBridge.injectJavaScriptFile(" + JSON.stringify(scriptHref) + ");"; }; WebViewExtBase.prototype.generaateLoadCSSFileScriptCode = function (stylesheetHref, insertBefore) { if (insertBefore === void 0) { insertBefore = false; } return "window.nsWebViewBridge.injectStyleSheetFile(" + JSON.stringify(stylesheetHref) + ", " + !!insertBefore + ");"; }; WebViewExtBase.prototype.injectWebViewBridge = function () { var _this = this; return nativescript_webview_bridge_loader_1.webViewBridgeJsCodePromise .then(function (webViewInterfaceJsCode) { return _this.executeJavaScript(webViewInterfaceJsCode, false); }) .then(function () { return _this.loadJavaScriptFiles(_this.autoInjectScriptFiles); }) .then(function () { return _this.loadStyleSheetFiles(_this.autoInjectStyleSheetFiles); }) .then(function () { return _this.executePromises(_this.autoInjectJavaScriptBlocks.map(function (data) { return data.scriptCode; }), -1); }); }; WebViewExtBase.prototype.parseWebViewJavascriptResult = function (result) { if (result === undefined) { return; } if (typeof result !== 'string') { return result; } try { return JSON.parse(result); } catch (err) { return result; } }; WebViewExtBase.prototype.writeTrace = function (message, type) { if (type === void 0) { type = view_1.traceMessageType.info; } if (view_1.traceEnabled()) { view_1.traceWrite(message, 'NOTA', type); } }; WebViewExtBase.prototype.emitToWebView = function (eventName, data) { var scriptCode = "\n window.nsWebViewBridge && nsWebViewBridge.onNativeEvent(" + JSON.stringify(eventName) + ", " + JSON.stringify(data) + ");\n "; this.executeJavaScript(scriptCode, false); }; WebViewExtBase.prototype.onWebViewEvent = function (eventName, data) { this.notify({ eventName: eventName, object: this, data: data, }); }; WebViewExtBase.prototype.getTitle = function () { throw new Error("Method not implemented."); }; WebViewExtBase.prototype.onUIWebViewEvent = function (url) { throw new Error('WebViewExt.onUIWebViewEvent() only available on iOS'); }; WebViewExtBase.prototype.fixLocalResourceName = function (resourceName) { if (resourceName.startsWith(this.interceptScheme)) { return resourceName.substr(this.interceptScheme.length + 3); } return resourceName; }; WebViewExtBase.loadStartedEvent = "loadStarted"; WebViewExtBase.loadFinishedEvent = "loadFinished"; return WebViewExtBase; }(view_1.View)); exports.WebViewExtBase = WebViewExtBase; exports.srcProperty.register(WebViewExtBase); exports.autoInjectJSBridgeProperty.register(WebViewExtBase); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vidmlldy1leHQtY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2Vidmlldy1leHQtY29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaURBQW1EO0FBQ25ELHNEQUFnSTtBQUdoSSwyRkFBa0Y7QUFFbEYsNERBQXdFO0FBQS9ELDZCQUFBLElBQUksQ0FBQTtBQUFFLHFDQUFBLFlBQVksQ0FBQTtBQUFFLDZCQUFBLElBQUksQ0FBQTtBQUNqQyxvREFBK0M7QUFFbEMsUUFBQSxXQUFXLEdBQUcsSUFBSSxlQUFRLENBQXlCLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7QUFDcEUsUUFBQSwwQkFBMEIsR0FBRyxJQUFJLGVBQVEsQ0FBMEIsRUFBRSxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFpRXBJO0lBQW9DLGtDQUFJO0lBQXhDO1FBQUEscUVBeW1CQztRQTdqQlUsd0JBQWtCLEdBQUcsSUFBSSxDQUFDO1FBS3ZCLDJCQUFxQixHQUFHLEVBQThCLENBQUM7UUFLdkQsK0JBQXlCLEdBQUcsRUFBOEIsQ0FBQztRQUUzRCxnQ0FBMEIsR0FBRyxFQUErQixDQUFDO1FBRTdELHFCQUFlLEdBQUcsS0FBSyxDQUFDOztJQStpQnRDLENBQUM7SUE3bEJHLHNCQUFXLDJDQUFlO2FBQTFCO1lBQ0ksTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNyQixDQUFDOzs7T0FBQTtJQThDTSx3Q0FBZSxHQUF0QixVQUF1QixHQUFXLEVBQUUsS0FBYztRQUFsRCxpQkF1Q0M7UUF0Q0csRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ1QsSUFBSSxDQUFDO2dCQUNELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO2dCQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztnQkFDZixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUss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QUMsY0FBYyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwidG5zLWNvcmUtbW9kdWxlcy9maWxlLXN5c3RlbVwiO1xuaW1wb3J0IHsgRXZlbnREYXRhLCBQcm9wZXJ0eSwgdHJhY2VFbmFibGVkLCB0cmFjZU1lc3NhZ2VUeXBlLCB0cmFjZVdyaXRlLCBWaWV3LCBWaWV3QmFzZSB9IGZyb20gXCJ0bnMtY29yZS1tb2R1bGVzL3VpL2NvcmUvdmlld1wiO1xuaW1wb3J0IHsgV2ViVmlld0V4dCBhcyBXZWJWaWV3RXh0RGVmaW5pdGlvbiB9IGZyb20gXCIuL1wiO1xuXG5pbXBvcnQgeyB3ZWJWaWV3QnJpZGdlSnNDb2RlUHJvbWlzZSB9IGZyb20gXCIuL25hdGl2ZXNjcmlwdC13ZWJ2aWV3LWJyaWRnZS1sb2FkZXJcIjtcblxuZXhwb3J0IHsgRmlsZSwga25vd25Gb2xkZXJzLCBwYXRoIH0gZnJvbSBcInRucy1jb3JlLW1vZHVsZXMvZmlsZS1zeXN0ZW1cIjtcbmV4cG9ydCAqIGZyb20gXCJ0bnMtY29yZS1tb2R1bGVzL3VpLy9jb3JlL3ZpZXdcIjtcblxuZXhwb3J0IGNvbnN0IHNyY1Byb3BlcnR5ID0gbmV3IFByb3BlcnR5PFdlYlZpZXdFeHRCYXNlLCBzdHJpbmc+KHsgbmFtZTogXCJzcmNcIiB9KTtcbmV4cG9ydCBjb25zdCBhdXRvSW5qZWN0SlNCcmlkZ2VQcm9wZXJ0eSA9IG5ldyBQcm9wZXJ0eTxXZWJWaWV3RXh0QmFzZSwgYm9vbGVhbj4oeyBuYW1lOiBcImF1dG9JbmplY3RKU0JyaWRnZVwiLCBkZWZhdWx0VmFsdWU6IHRydWUgfSk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZEphdmFTY3JpcHRSZXNvdXJjZSB7XG4gICAgcmVzb3VyY2VOYW1lOiBzdHJpbmc7XG4gICAgZmlsZXBhdGg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2FkU3R5bGVTaGVldFJlc291cmNlIHtcbiAgICByZXNvdXJjZU5hbWU6IHN0cmluZztcbiAgICBmaWxlcGF0aDogc3RyaW5nO1xuICAgIGluc2VydEJlZm9yZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5qZWN0RXhlY3V0ZUphdmFTY3JpcHQge1xuICAgIHNjcmlwdENvZGU6IHN0cmluZztcbiAgICBuYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRXZlbnQgZGF0YSBjb250YWluaW5nIGluZm9ybWF0aW9uIGZvciB0aGUgbG9hZGluZyBldmVudHMgb2YgYSBXZWJWaWV3LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvYWRFdmVudERhdGEgZXh0ZW5kcyBFdmVudERhdGEge1xuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHVybCBvZiB0aGUgd2ViLXZpZXcuXG4gICAgICovXG4gICAgdXJsOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuYXZpZ2F0aW9uIHR5cGUgb2YgdGhlIHdlYi12aWV3LlxuICAgICAqL1xuICAgIG5hdmlnYXRpb25UeXBlOiBOYXZpZ2F0aW9uVHlwZTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGVycm9yIChpZiBhbnkpLlxuICAgICAqL1xuICAgIGVycm9yOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZFN0YXJ0ZWRFdmVudERhdGEgZXh0ZW5kcyBMb2FkRXZlbnREYXRhIHtcbiAgICBldmVudE5hbWU6ICdsb2FkU3RhcnRlZCc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZEZpbmlzaGVkRXZlbnREYXRhIGV4dGVuZHMgTG9hZEV2ZW50RGF0YSB7XG4gICAgZXZlbnROYW1lOiAnbG9hZEZpbmlzaGVkJztcbn1cblxuLyoqXG4gKiBFdmVudCBkYXRhIGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gZm9yIHRoZSBsb2FkaW5nIGV2ZW50cyBvZiBhIFdlYlZpZXcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2ViVmlld0V2ZW50RGF0YSBleHRlbmRzIEV2ZW50RGF0YSB7XG4gICAgZGF0YT86IGFueTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIG5hdmlnYXRpb24gdHlwZVxuICovXG5leHBvcnQgdHlwZSBOYXZpZ2F0aW9uVHlwZSA9IFwibGlua0NsaWNrZWRcIiB8IFwiZm9ybVN1Ym1pdHRlZFwiIHwgXCJiYWNrRm9yd2FyZFwiIHwgXCJyZWxvYWRcIiB8IFwiZm9ybVJlc3VibWl0dGVkXCIgfCBcIm90aGVyXCIgfCB2b2lkO1xuXG4vKipcbiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciBvdmVycmlkZSBVUkwgbG9hZGluZy5cbiAqIEBwYXJhbSB1cmwgLSB1cmwgdG8gYmUgbG9hZGVkIGluIHRoZSBXZWJWaWV3XG4gKiBAcmV0dXJuIGJvb2xlYW4gLSB0cnVlIHRvIHByZXZlbnQgdXJsIGZyb20gYmVpbmcgbG9hZGVkLlxuICovXG5leHBvcnQgdHlwZSB1cmxPdmVycmlkZUhhbmRsZXJGbiA9ICh1cmw6IFN0cmluZykgPT4gYm9vbGVhbjtcblxuZXhwb3J0IGNsYXNzIFdlYlZpZXdFeHRCYXNlIGV4dGVuZHMgVmlldyB7XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmF0aXZlIFthbmRyb2lkIHdpZGdldF0oaHR0cDovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC93ZWJraXQvV2ViVmlldy5odG1sKSB0aGF0IHJlcHJlc2VudHMgdGhlIHVzZXIgaW50ZXJmYWNlIGZvciB0aGlzIGNvbXBvbmVudC4gVmFsaWQgb25seSB3aGVuIHJ1bm5pbmcgb24gQW5kcm9pZCBPUy5cbiAgICAgKi9cbiAgICBwdWJsaWMgYW5kcm9pZDogYW55IC8qIGFuZHJvaWQud2Via2l0LldlYlZpZXcgKi87XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuYXRpdmUgW1dLV2ViVmlld10oaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2RvY3VtZW50YXRpb24vd2Via2l0L3drd2Vidmlldy8pIHRoYXQgcmVwcmVzZW50cyB0aGUgdXNlciBpbnRlcmZhY2UgZm9yIHRoaXMgY29tcG9uZW50LiBWYWxpZCBvbmx5IHdoZW4gcnVubmluZyBvbiBpT1MgMTErLlxuICAgICAqIEdldHMgdGhlIG5hdGl2ZSBbVUlXZWJWaWV3XWh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9kb2N1bWVudGF0aW9uL3Vpa2l0L3Vpd2VidmlldyB0aGF0IHJlcHJlc2VudHMgdGhlIHVzZXIgaW50ZXJmYWNlIGZvciB0aGlzIGNvbXBvbmVudC4gVmFsaWQgb25seSB3aGVuIHJ1bm5pbmcgb24gaU9TIDwxMVxuICAgICAqL1xuICAgIHB1YmxpYyBpb3M6IGFueSAvKiBXS1dlYlZpZXcgfCBVSVdlYlZpZXcgKi87XG5cbiAgICBwdWJsaWMgZ2V0IGludGVyY2VwdFNjaGVtZSgpIHtcbiAgICAgICAgcmV0dXJuICd4LWxvY2FsJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdHJpbmcgdmFsdWUgdXNlZCB3aGVuIGhvb2tpbmcgdG8gbG9hZFN0YXJ0ZWQgZXZlbnQuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBsb2FkU3RhcnRlZEV2ZW50OiAnbG9hZFN0YXJ0ZWQnID0gXCJsb2FkU3RhcnRlZFwiO1xuXG4gICAgLyoqXG4gICAgICogU3RyaW5nIHZhbHVlIHVzZWQgd2hlbiBob29raW5nIHRvIGxvYWRGaW5pc2hlZCBldmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGxvYWRGaW5pc2hlZEV2ZW50OiAnbG9hZEZpbmlzaGVkJyA9IFwibG9hZEZpbmlzaGVkXCI7XG5cbiAgICAvKipcbiAgICAgKiBpT1MgPDExIHVzZXMgYSBVSVdlYnZpZXdcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNVSVdlYlZpZXc6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBpT1MgMTErIHVzZXMgYW4gV0tXZWJWaWV3XG4gICAgICovXG4gICAgcHVibGljIGlzV0tXZWJWaWV3OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSB1cmwsIGxvY2FsIGZpbGUgcGF0aCBvciBIVE1MIHN0cmluZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3JjOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBdXRvIEluamVjdCBXZWJWaWV3IEphdmFTY3JpcHQgQnJpZGdlIG9uIGxvYWQgZmluaXNoZWQ/IERlZmF1bHRzIHRvIHRydWUuXG4gICAgICovXG4gICAgcHVibGljIGF1dG9JbmplY3RKU0JyaWRnZSA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGpzLWZpbGVzIHRvIGJlIGF1dG8gaW5qZWN0ZWQgb24gbG9hZCBmaW5pc2hlZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBhdXRvSW5qZWN0U2NyaXB0RmlsZXMgPSBbXSBhcyBMb2FkSmF2YVNjcmlwdFJlc291cmNlW107XG5cbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGNzcy1maWxlcyB0byBiZSBhdXRvIGluamVjdGVkIG9uIGxvYWQgZmluaXNoZWRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYXV0b0luamVjdFN0eWxlU2hlZXRGaWxlcyA9IFtdIGFzIExvYWRTdHlsZVNoZWV0UmVzb3VyY2VbXTtcblxuICAgIHByb3RlY3RlZCBhdXRvSW5qZWN0SmF2YVNjcmlwdEJsb2NrcyA9IFtdIGFzIEluamVjdEV4ZWN1dGVKYXZhU2NyaXB0W107XG5cbiAgICBwcm90ZWN0ZWQgX3RtcFN0b3BMb2FkaW5nID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgX29uTG9hZEZpbmlzaGVkKHVybDogc3RyaW5nLCBlcnJvcj86IHN0cmluZyk6IFByb21pc2U8TG9hZEZpbmlzaGVkRXZlbnREYXRhPiB7XG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdG1wU3RvcExvYWRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuc3JjID0gdXJsO1xuICAgICAgICAgICAgICAgIHRoaXMuX3RtcFN0b3BMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RtcFN0b3BMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcmdzID0ge1xuICAgICAgICAgICAgZXZlbnROYW1lOiBXZWJWaWV3RXh0QmFzZS5sb2FkRmluaXNoZWRFdmVudCxcbiAgICAgICAgICAgIG9iamVjdDogdGhpcyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIG5hdmlnYXRpb25UeXBlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgfSBhcyBMb2FkRmluaXNoZWRFdmVudERhdGE7XG5cbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeShhcmdzKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChhcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMud3JpdGVUcmFjZShgV2ViVmlld0V4dC5fb25Mb2FkRmluaXNoZWQoXCIke3VybH1cIiwgJHtlcnJvciB8fCB2b2lkIDB9KSAtID4gSW5qZWN0aW5nIHdlYnZpZXctYnJpZGdlIEpTIGNvZGVgKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmF1dG9JbmplY3RKU0JyaWRnZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYXJncyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluamVjdFdlYlZpZXdCcmlkZ2UoKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IGFyZ3MpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gey4uLmFyZ3MsIGVycm9yfTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC50aGVuKChhcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5KGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBfb25Mb2FkU3RhcnRlZCh1cmw6IHN0cmluZywgbmF2aWdhdGlvblR5cGU6IE5hdmlnYXRpb25UeXBlKSB7XG4gICAgICAgIGxldCBhcmdzID0gPExvYWRTdGFydGVkRXZlbnREYXRhPntcbiAgICAgICAgICAgIGV2ZW50TmFtZTogV2ViVmlld0V4dEJhc2UubG9hZFN0YXJ0ZWRFdmVudCxcbiAgICAgICAgICAgIG9iamVjdDogdGhpcyxcbiAgICAgICAgICAgIHVybDogdXJsLFxuICAgICAgICAgICAgbmF2aWdhdGlvblR5cGU6IG5hdmlnYXRpb25UeXBlLFxuICAgICAgICAgICAgZXJyb3I6IHVuZGVmaW5lZFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubm90aWZ5KGFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBfbG9hZFVybChzcmM6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRob2Qgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgX2xvYWREYXRhKHNyYzogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGxvYWRpbmcgdGhlIGN1cnJlbnQgY29udGVudCAoaWYgYW55KS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RvcExvYWRpbmcoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIFdlYlZpZXcgY2FuIG5hdmlnYXRlIGJhY2suXG4gICAgICovXG4gICAgcHVibGljIGdldCBjYW5Hb0JhY2soKTogYm9vbGVhbiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgbWVtYmVyIGlzIGFic3RyYWN0LlwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBXZWJWaWV3IGNhbiBuYXZpZ2F0ZSBmb3J3YXJkLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY2FuR29Gb3J3YXJkKCk6IGJvb2xlYW4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1lbWJlciBpcyBhYnN0cmFjdC5cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIGJhY2suXG4gICAgICovXG4gICAgcHVibGljIGdvQmFjaygpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIGZvcndhcmQuXG4gICAgICovXG4gICAgcHVibGljIGdvRm9yd2FyZCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVsb2FkcyB0aGUgY3VycmVudCB1cmwuXG4gICAgICovXG4gICAgcHVibGljIHJlbG9hZCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGNhbGxiYWNrIGZ1bmN0aW9uIHRvIG92ZXJyaWRpbmcgVVJMIGxvYWRpbmcgaW4gdGhlIFdlYlZpZXcuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUsIHRoZSBVUkwgd2lsbCBub3QgYmUgbG9hZGVkIGJ5IHRoZSBXZWJWaWV3LlxuICAgICAqL1xuICAgIHB1YmxpYyB1cmxPdmVycmlkZUhhbmRsZXI6IHVybE92ZXJyaWRlSGFuZGxlckZuO1xuXG4gICAgW3NyY1Byb3BlcnR5LmdldERlZmF1bHRdKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cblxuICAgIFtzcmNQcm9wZXJ0eS5zZXROYXRpdmVdKHNyYzogc3RyaW5nKSB7XG4gICAgICAgIGlmICghc3JjIHx8IHRoaXMuX3RtcFN0b3BMb2FkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3JpZ2luU3JjID0gc3JjO1xuXG4gICAgICAgIHRoaXMuc3RvcExvYWRpbmcoKTtcblxuICAgICAgICBpZiAoc3JjLnN0YXJ0c1dpdGgodGhpcy5pbnRlcmNlcHRTY2hlbWUpKSB7XG4gICAgICAgICAgICB0aGlzLndyaXRlVHJhY2UoYFdlYlZpZXdFeHQuc3JjID0gJHtvcmlnaW5TcmN9IHJlc29sdmUgeC1sb2NhbCBmaWxlYCk7XG4gICAgICAgICAgICBjb25zdCBmaWxlcGFyaCA9IHRoaXMuZ2V0UmVnaXN0cmV0TG9jYWxSZXNvdXJjZShzcmMpO1xuICAgICAgICAgICAgaWYgKGZpbGVwYXJoKSB7XG4gICAgICAgICAgICAgICAgc3JjID0gYGZpbGU6Ly8ke2ZpbGVwYXJofWA7XG4gICAgICAgICAgICAgICAgdGhpcy53cml0ZVRyYWNlKGBXZWJWaWV3RXh0LnNyYyA9ICR7b3JpZ2luU3JjfSB4LWxvY2FsIHJlc29sdmVkIHRvICR7c3JjfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndyaXRlVHJhY2UoYFdlYlZpZXdFeHQuc3JjID0gJHtvcmlnaW5TcmN9IHgtbG9jYWwgY291bGRuJ3QgcmVzb2x2ZSB0byBmaWxlYCwgdHJhY2VNZXNzYWdlVHlwZS5lcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25Mb2FkRmluaXNoZWQoc3JjLCAndW5rbm93biB4LWxvY2FsLXJlc291cmNlJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGZpbGU6Ly8vIHByZWZpeCBmb3IgbG9jYWwgZmlsZXMuXG4gICAgICAgIC8vIFRoZXkgc2hvdWxkIGJlIGxvYWRlZCB3aXRoIF9sb2FkVXJsKCkgbWV0aG9kIGFzIGl0IGhhbmRsZXMgcXVlcnkgcGFyYW1zLlxuICAgICAgICBpZiAoc3JjLnN0YXJ0c1dpdGgoXCJ+L1wiKSkge1xuICAgICAgICAgICAgc3JjID0gYGZpbGU6Ly8ke2ZzLmtub3duRm9sZGVycy5jdXJyZW50QXBwKCkucGF0aH0vJHtzcmMuc3Vic3RyKDIpfWA7XG4gICAgICAgICAgICB0aGlzLndyaXRlVHJhY2UoYFdlYlZpZXdFeHQuc3JjID0gJHtvcmlnaW5TcmN9IHN0YXJ0c1dpdGggfi8gcmVzb2x2ZWQgdG8gJHtzcmN9YCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3JjLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICAgICAgICBzcmMgPSBcImZpbGU6Ly9cIiArIHNyYztcbiAgICAgICAgICAgIHRoaXMud3JpdGVUcmFjZShgV2ViVmlld0V4dC5zcmMgPSAke29yaWdpblNyY30gc3RhcnRzV2l0aCBcIi9cIiByZXNvbHZlZCB0byAke3NyY31gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxjU3Jj