From a11a0065e1e1c4f196698ea5b7b5363b19634884 Mon Sep 17 00:00:00 2001 From: Wei Ouyang Date: Wed, 29 Nov 2023 14:17:34 +0100 Subject: [PATCH] Fix jupyterlab extension --- .gitignore | 3 + README.md | 1 + imjoy-jupyterlab-extension/__init__.py | 16 - imjoy-jupyterlab-extension/_version.py | 19 - .../labextension/package.json | 69 - .../static/747.08ecd031b9c0861222d4.js | 224 -- .../static/754.c64924bf041548ec3401.js | 516 ----- .../static/942.c4b692e5941010f31829.js | 1864 ----------------- .../942.c4b692e5941010f31829.js.LICENSE.txt | 93 - .../remoteEntry.e497db13d4c9b20fbbbf.js | 438 ---- .../labextension/static/style.js | 4 - .../static/third-party-licenses.json | 22 - package.json | 2 +- publish.sh | 6 +- pyproject.toml | 1 + src/comm-connection.js | 236 +++ src/imjoy-extension.js | 313 +++ src/index.ts | 38 +- src/utils.js | 206 ++ tsconfig.json | 1 + 20 files changed, 796 insertions(+), 3276 deletions(-) delete mode 100644 imjoy-jupyterlab-extension/__init__.py delete mode 100644 imjoy-jupyterlab-extension/_version.py delete mode 100644 imjoy-jupyterlab-extension/labextension/package.json delete mode 100644 imjoy-jupyterlab-extension/labextension/static/747.08ecd031b9c0861222d4.js delete mode 100644 imjoy-jupyterlab-extension/labextension/static/754.c64924bf041548ec3401.js delete mode 100644 imjoy-jupyterlab-extension/labextension/static/942.c4b692e5941010f31829.js delete mode 100644 imjoy-jupyterlab-extension/labextension/static/942.c4b692e5941010f31829.js.LICENSE.txt delete mode 100644 imjoy-jupyterlab-extension/labextension/static/remoteEntry.e497db13d4c9b20fbbbf.js delete mode 100644 imjoy-jupyterlab-extension/labextension/static/style.js delete mode 100644 imjoy-jupyterlab-extension/labextension/static/third-party-licenses.json create mode 100644 src/comm-connection.js create mode 100644 src/imjoy-extension.js create mode 100644 src/utils.js diff --git a/.gitignore b/.gitignore index bfe9731..a3ec51f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.ipynb +imjoy-jupyterlab-extension .pypirc *.bundle.* lib/ @@ -6,6 +8,7 @@ node_modules/ .eslintcache .stylelintcache *.egg-info/ + .ipynb_checkpoints *.tsbuildinfo imjoy_jupyterlab_extension/labextension diff --git a/README.md b/README.md index c12afc7..e2c7a3e 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ The `jlpm` command is JupyterLab's pinned version of ```bash # Clone the repo to your local environment # Change directory to the imjoy_jupyterlab_extension directory +npm run build # Install package in development mode pip install -e "." # Link your development version of the extension with JupyterLab diff --git a/imjoy-jupyterlab-extension/__init__.py b/imjoy-jupyterlab-extension/__init__.py deleted file mode 100644 index e8c52f0..0000000 --- a/imjoy-jupyterlab-extension/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -import json -from pathlib import Path - -from ._version import __version__ - -HERE = Path(__file__).parent.resolve() - -with (HERE / "labextension" / "package.json").open() as fid: - data = json.load(fid) - -def _jupyter_labextension_paths(): - return [{ - "src": "labextension", - "dest": data["name"] - }] diff --git a/imjoy-jupyterlab-extension/_version.py b/imjoy-jupyterlab-extension/_version.py deleted file mode 100644 index b96d38b..0000000 --- a/imjoy-jupyterlab-extension/_version.py +++ /dev/null @@ -1,19 +0,0 @@ -import json -from pathlib import Path - -__all__ = ["__version__"] - -def _fetchVersion(): - HERE = Path(__file__).parent.resolve() - - for settings in HERE.rglob("package.json"): - try: - with settings.open() as f: - return json.load(f)["version"] - except FileNotFoundError: - pass - - raise FileNotFoundError(f"Could not find package.json under dir {HERE!s}") - -__version__ = _fetchVersion() - diff --git a/imjoy-jupyterlab-extension/labextension/package.json b/imjoy-jupyterlab-extension/labextension/package.json deleted file mode 100644 index 680235a..0000000 --- a/imjoy-jupyterlab-extension/labextension/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "imjoy-jupyterlab-extension", - "version": "0.1.13", - "description": "Run ImJoy plugins in JupyterLab", - "keywords": [ - "jupyter", - "jupyterlab", - "jupyterlab-extension" - ], - "homepage": "https://github.com/imjoy-team/imjoy-jupyterlab-extension", - "bugs": { - "url": "https://github.com/imjoy-team/imjoy-jupyterlab-extension/issues" - }, - "license": "BSD-3-Clause", - "author": { - "name": "Wei Ouyang", - "email": "oeway007@gmail.com" - }, - "files": [ - "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", - "style/**/*.{css,.js,eot,gif,html,jpg,json,png,svg,woff2,ttf}" - ], - "main": "lib/index.js", - "style": "style/index.css", - "repository": { - "type": "git", - "url": "https://github.com/imjoy-team/imjoy-jupyterlab-extension.git" - }, - "scripts": { - "build": "jlpm run build:labextension:dev", - "build:prod": "jlpm run build:labextension", - "build:labextension": "jupyter labextension build .", - "build:labextension:dev": "jupyter labextension build --development True .", - "clean:labextension": "rimraf imjoy-jupyterlab-extension/labextension", - "clean:all": "jlpm run clean:labextension", - "install:extension": "jupyter labextension develop --overwrite .", - "prepare": "jlpm run build:prod", - "prettier": "prettier --write \"**/*{.js,.jsx,.css,.json,.md}\"", - "watch": "jlpm run watch:labextension", - "watch:labextension": "jupyter labextension watch ." - }, - "dependencies": { - "@jupyterlab/application": "^3.2.4", - "@jupyterlab/apputils": "^3.2.4", - "@jupyterlab/docregistry": "^3.2.4", - "@jupyterlab/notebook": "^3.2.4", - "@phosphor/disposable": "^1.3.1", - "imjoy-core": "^0.14.2" - }, - "devDependencies": { - "@jupyterlab/builder": "^3.0.0", - "prettier": "^2.1.1", - "rimraf": "^3.0.2" - }, - "sideEffects": [ - "style/*.css", - "style/index.js" - ], - "styleModule": "style/index.js", - "jupyterlab": { - "extension": true, - "outputDir": "imjoy-jupyterlab-extension/labextension", - "_build": { - "load": "static/remoteEntry.e497db13d4c9b20fbbbf.js", - "extension": "./extension", - "style": "./style" - } - } -} diff --git a/imjoy-jupyterlab-extension/labextension/static/747.08ecd031b9c0861222d4.js b/imjoy-jupyterlab-extension/labextension/static/747.08ecd031b9c0861222d4.js deleted file mode 100644 index d2ea56c..0000000 --- a/imjoy-jupyterlab-extension/labextension/static/747.08ecd031b9c0861222d4.js +++ /dev/null @@ -1,224 +0,0 @@ -'use strict'; -(self.webpackChunkimjoy_jupyterlab_extension = - self.webpackChunkimjoy_jupyterlab_extension || []).push([ - [747], - { - 150: (e, n, t) => { - t.d(n, { Z: () => o }); - var r = t(645), - i = t.n(r)()(function (e) { - return e[1]; - }); - i.push([e.id, '', '']); - const o = i; - }, - 645: e => { - e.exports = function (e) { - var n = []; - return ( - (n.toString = function () { - return this.map(function (n) { - var t = e(n); - return n[2] ? '@media '.concat(n[2], ' {').concat(t, '}') : t; - }).join(''); - }), - (n.i = function (e, t, r) { - 'string' == typeof e && (e = [[null, e, '']]); - var i = {}; - if (r) - for (var o = 0; o < this.length; o++) { - var a = this[o][0]; - null != a && (i[a] = !0); - } - for (var c = 0; c < e.length; c++) { - var s = [].concat(e[c]); - (r && i[s[0]]) || - (t && - (s[2] - ? (s[2] = ''.concat(t, ' and ').concat(s[2])) - : (s[2] = t)), - n.push(s)); - } - }), - n - ); - }; - }, - 379: (e, n, t) => { - var r, - i = (function () { - var e = {}; - return function (n) { - if (void 0 === e[n]) { - var t = document.querySelector(n); - if ( - window.HTMLIFrameElement && - t instanceof window.HTMLIFrameElement - ) - try { - t = t.contentDocument.head; - } catch (e) { - t = null; - } - e[n] = t; - } - return e[n]; - }; - })(), - o = []; - function a(e) { - for (var n = -1, t = 0; t < o.length; t++) - if (o[t].identifier === e) { - n = t; - break; - } - return n; - } - function c(e, n) { - for (var t = {}, r = [], i = 0; i < e.length; i++) { - var c = e[i], - s = n.base ? c[0] + n.base : c[0], - u = t[s] || 0, - l = ''.concat(s, ' ').concat(u); - t[s] = u + 1; - var f = a(l), - d = { css: c[1], media: c[2], sourceMap: c[3] }; - -1 !== f - ? (o[f].references++, o[f].updater(d)) - : o.push({ identifier: l, updater: v(d, n), references: 1 }), - r.push(l); - } - return r; - } - function s(e) { - var n = document.createElement('style'), - r = e.attributes || {}; - if (void 0 === r.nonce) { - var o = t.nc; - o && (r.nonce = o); - } - if ( - (Object.keys(r).forEach(function (e) { - n.setAttribute(e, r[e]); - }), - 'function' == typeof e.insert) - ) - e.insert(n); - else { - var a = i(e.insert || 'head'); - if (!a) - throw new Error( - "Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid." - ); - a.appendChild(n); - } - return n; - } - var u, - l = - ((u = []), - function (e, n) { - return (u[e] = n), u.filter(Boolean).join('\n'); - }); - function f(e, n, t, r) { - var i = t - ? '' - : r.media - ? '@media '.concat(r.media, ' {').concat(r.css, '}') - : r.css; - if (e.styleSheet) e.styleSheet.cssText = l(n, i); - else { - var o = document.createTextNode(i), - a = e.childNodes; - a[n] && e.removeChild(a[n]), - a.length ? e.insertBefore(o, a[n]) : e.appendChild(o); - } - } - function d(e, n, t) { - var r = t.css, - i = t.media, - o = t.sourceMap; - if ( - (i ? e.setAttribute('media', i) : e.removeAttribute('media'), - o && - 'undefined' != typeof btoa && - (r += '\n/*# sourceMappingURL=data:application/json;base64,'.concat( - btoa(unescape(encodeURIComponent(JSON.stringify(o)))), - ' */' - )), - e.styleSheet) - ) - e.styleSheet.cssText = r; - else { - for (; e.firstChild; ) e.removeChild(e.firstChild); - e.appendChild(document.createTextNode(r)); - } - } - var p = null, - h = 0; - function v(e, n) { - var t, r, i; - if (n.singleton) { - var o = h++; - (t = p || (p = s(n))), - (r = f.bind(null, t, o, !1)), - (i = f.bind(null, t, o, !0)); - } else - (t = s(n)), - (r = d.bind(null, t, n)), - (i = function () { - !(function (e) { - if (null === e.parentNode) return !1; - e.parentNode.removeChild(e); - })(t); - }); - return ( - r(e), - function (n) { - if (n) { - if ( - n.css === e.css && - n.media === e.media && - n.sourceMap === e.sourceMap - ) - return; - r((e = n)); - } else i(); - } - ); - } - e.exports = function (e, n) { - (n = n || {}).singleton || - 'boolean' == typeof n.singleton || - (n.singleton = - (void 0 === r && - (r = Boolean(window && document && document.all && !window.atob)), - r)); - var t = c((e = e || []), n); - return function (e) { - if ( - ((e = e || []), - '[object Array]' === Object.prototype.toString.call(e)) - ) { - for (var r = 0; r < t.length; r++) { - var i = a(t[r]); - o[i].references--; - } - for (var s = c(e, n), u = 0; u < t.length; u++) { - var l = a(t[u]); - 0 === o[l].references && (o[l].updater(), o.splice(l, 1)); - } - t = s; - } - }; - }; - }, - 747: (e, n, t) => { - t.r(n); - var r = t(379), - i = t.n(r), - o = t(150); - i()(o.Z, { insert: 'head', singleton: !1 }), o.Z.locals; - } - } -]); diff --git a/imjoy-jupyterlab-extension/labextension/static/754.c64924bf041548ec3401.js b/imjoy-jupyterlab-extension/labextension/static/754.c64924bf041548ec3401.js deleted file mode 100644 index 50b6865..0000000 --- a/imjoy-jupyterlab-extension/labextension/static/754.c64924bf041548ec3401.js +++ /dev/null @@ -1,516 +0,0 @@ -'use strict'; -(self.webpackChunkimjoy_jupyterlab_extension = - self.webpackChunkimjoy_jupyterlab_extension || []).push([ - [754], - { - 754: (e, t, n) => { - n.r(t), n.d(t, { default: () => g }); - var o = n(703), - s = n(967); - const r = /^(?:\w+:)?\/\/([\s\S]+)$/, - i = /^localhost[\:?\d]*(?:[^\:?\d][\s\S]*)?$/, - a = /^[^\s\.]+\.[\s\S]{2,}$/, - l = /(?:(?:[^:]+:)?[/][/])?(?:.+@)?([^/]+)([/][^?#]+)/; - async function c(e, t) { - if (e.includes('gist.github.com')) { - const n = e.split('/').slice(-1)[0], - o = await fetch('https://api.github.com/gists/' + n).then(e => - e.blob() - ), - s = JSON.parse(await new Response(o).text()); - if (t) { - const e = Object.values(s.files).filter(e => - e.filename.endsWith(t) - )[0]; - return e && e.raw_url; - } - return s.files[Object.values(s.files)[0]].raw_url; - } - if (!e.includes('blob') || !e.includes('github')) return null; - var n = (function (e, t) { - var n = {}; - if (((t = t || {}), !e)) return null; - if ((e.url && (e = e.url), 'string' != typeof e)) return null; - var o = e.match(/^([\w-_]+)\/([\w-_\.]+)(?:#([\w-_\.]+))?$/), - s = e.match(/^github:([\w-_]+)\/([\w-_\.]+)(?:#([\w-_\.]+))?$/), - c = e.match(/^git@[\w-_\.]+:([\w-_]+)\/([\w-_\.]+)$/); - if (o) - (n.user = o[1]), - (n.repo = o[2]), - (n.branch = o[3] || 'master'), - (n.host = 'github.com'); - else if (s) - (n.user = s[1]), - (n.repo = s[2]), - (n.branch = s[3] || 'master'), - (n.host = 'github.com'); - else if (c) - (n.user = c[1]), - (n.repo = c[2].replace(/\.git$/i, '')), - (n.branch = 'master'), - (n.host = 'github.com'); - else { - if ( - !(function (e) { - if ('string' != typeof e) return !1; - var t = e.match(r); - if (!t) return !1; - var n = t[1]; - return !(!n || (!i.test(n) && !a.test(n))); - })((e = e.replace(/^git\+/, ''))) - ) - return null; - const [, o, s] = e.match(l) || []; - if (!o) return null; - if ('github.com' !== o && 'www.github.com' !== o && !t.enterprise) - return null; - var p = s.match( - /^\/([\w-_]+)\/([\w-_\.]+)(\/tree\/[\w-_\.\/]+)?(\/blob\/[\s\w-_\.\/]+)?/ - ); - if (!p) return null; - (n.user = p[1]), - (n.repo = p[2].replace(/\.git$/i, '')), - (n.host = o || 'github.com'), - p[3] && /^\/tree\/master\//.test(p[3]) - ? ((n.branch = 'master'), (n.path = p[3].replace(/\/$/, ''))) - : p[3] - ? (n.branch = p[3] - .replace(/^\/tree\//, '') - .match(/[\w-_.]+\/{0,1}[\w-_]+/)[0]) - : p[4] - ? (n.branch = p[4] - .replace(/^\/blob\//, '') - .match(/[\w-_.]+\/{0,1}[\w-_]+/)[0]) - : (n.branch = 'master'); - } - return ( - 'github.com' === n.host - ? (n.apiHost = 'api.github.com') - : (n.apiHost = `${n.host}/api/v3`), - (n.tarball_url = `https://${n.apiHost}/repos/${n.user}/${n.repo}/tarball/${n.branch}`), - (n.clone_url = `https://${n.host}/${n.user}/${n.repo}`), - 'master' === n.branch - ? ((n.https_url = `https://${n.host}/${n.user}/${n.repo}`), - (n.travis_url = `https://travis-ci.org/${n.user}/${n.repo}`), - (n.zip_url = `https://${n.host}/${n.user}/${n.repo}/archive/master.zip`)) - : ((n.https_url = `https://${n.host}/${n.user}/${n.repo}/blob/${n.branch}`), - (n.travis_url = `https://travis-ci.org/${n.user}/${n.repo}?branch=${n.branch}`), - (n.zip_url = `https://${n.host}/${n.user}/${n.repo}/archive/${n.branch}.zip`)), - n.path && (n.https_url += n.path), - (n.api_url = `https://${n.apiHost}/repos/${n.user}/${n.repo}`), - n - ); - })(e), - o = n.user, - s = n.repo, - c = new RegExp('^https://github.com/' + o + '/' + s + '/blob/', 'g'); - return ( - 'https://raw.githubusercontent.com/' + - o + - '/' + - s + - '/' + - e.replace(c, '') - ); - } - async function p(e) { - const t = - /https?:\/\/zenodo.org\/record\/([a-zA-Z0-9-]+)\/files\/(.*)/g.exec( - e - ); - if (!t || 3 !== t.length) throw new Error('Invalid zenodo url'); - const [n, o, s] = t, - r = await fetch(`https://zenodo.org/api/records/${o}`).then(e => - e.blob() - ), - i = JSON.parse(await new Response(r).text()), - a = s.split('?')[0]; - return i.files.filter(e => e.key === a)[0].links.self; - } - var h = n(322), - u = n(502), - d = n(777), - f = n(543), - _ = n(923); - class m extends class { - constructor(e) { - (this._event_handlers = {}), - (this._once_handlers = {}), - (this._debug = e); - } - emit() { - throw new Error('emit is not implemented'); - } - on(e, t) { - this._event_handlers[e] || (this._event_handlers[e] = []), - this._event_handlers[e].push(t); - } - once(e, t) { - (t.___event_run_once = !0), this.on(e, t); - } - off(e, t) { - if (e || t) { - if (e && !t) - this._event_handlers[e] && (this._event_handlers[e] = []); - else if (this._event_handlers[e]) { - const n = this._event_handlers[e].indexOf(t); - n >= 0 && this._event_handlers[e].splice(n, 1); - } - } else this._event_handlers = {}; - } - _fire(e, t) { - if (this._event_handlers[e]) { - let n = this._event_handlers[e].length; - for (; n--; ) { - const o = this._event_handlers[e][n]; - try { - o(t); - } catch (e) { - console.error(e); - } finally { - o.___event_run_once && this._event_handlers[e].splice(n, 1); - } - } - } else this._debug && console.warn('unhandled event', e, t); - } - } { - constructor(e) { - super(e && e.debug); - const t = e.kernel.createComm('imjoy_rpc'); - t.open({}), - (t.onMsg = e => { - const { data: t } = e.content, - n = t.__buffer_paths__ || []; - delete t.__buffer_paths__, - (function (e, t, n) { - n = n.map(e => - e instanceof DataView - ? e.buffer - : e instanceof ArrayBuffer - ? e - : e.buffer - ); - for (let o = 0; o < t.length; o++) { - const s = t[o]; - let r = e; - for (let e = 0; e < s.length - 1; e++) r = r[s[e]]; - r[s[s.length - 1]] = n[o]; - } - })(t, n, e.buffers || []), - 'log' === t.type || 'info' === t.type - ? console.log(t.message) - : 'error' === t.type - ? console.error(t.message) - : (t.peer_id && (this._peer_id = t.peer_id), - this._fire(t.type, t)); - }), - (this.comm = t); - } - connect() {} - disconnect() {} - emit(e) { - e.peer_id = this._peer_id; - const t = (function (e) { - const t = [], - n = []; - return { - state: (function e(o, s) { - var r, i; - if ( - ('object' == typeof (r = o) && - r && - r.toJSON && - (o = o.toJSON()), - Array.isArray(o)) - ) { - let r = !1; - for (let i = 0; i < o.length; i++) { - const a = o[i]; - if (a) - if (a instanceof ArrayBuffer || ArrayBuffer.isView(a)) - r || ((o = o.slice()), (r = !0)), - t.push(ArrayBuffer.isView(a) ? a.buffer : a), - n.push(s.concat([i])), - (o[i] = null); - else { - const t = e(a, s.concat([i])); - t !== a && - (r || ((o = o.slice()), (r = !0)), (o[i] = t)); - } - } - } else if ( - (i = o) && - 'object' == typeof i && - i.constructor === Object - ) - for (const r of Object.keys(o)) { - let i = !1; - if (Object.prototype.hasOwnProperty.call(o, r)) { - const a = o[r]; - if (a) - if (a instanceof ArrayBuffer || ArrayBuffer.isView(a)) - i || ((o = { ...o }), (i = !0)), - t.push(ArrayBuffer.isView(a) ? a.buffer : a), - n.push(s.concat([r])), - delete o[r]; - else { - const t = e(a, s.concat([r])); - t !== a && - (i || ((o = { ...o }), (i = !0)), (o[r] = t)); - } - } - } - return o; - })(e, []), - buffers: t, - buffer_paths: n - }; - })(e); - (t.state.__buffer_paths__ = t.buffer_paths), - this.comm.send(t.state, {}, {}, t.buffers); - } - } - async function w(e) { - if ('pyodide' === (await e.info).implementation) { - const t = `\nimport os\nimport ipykernel\nimport micropip\nimport sys\n\nawait micropip.install([ "imjoy-rpc"])\nimport imjoy_rpc\n\nif 'imjoy' not in sys.modules:\n sys.modules['imjoy'] = sys.modules['imjoy_rpc']\n\nif 'IMJOY_RPC_CONNECTION' not in os.environ:\n os.environ['IMJOY_RPC_CONNECTION'] = 'jupyter'\n\nclass Connect():\n def __init__(self, kernel_id):\n self.kernel_id = kernel_id\n\n def get_connection_file(self):\n return f"kernel-{self.kernel_id}.json"\n\nif not hasattr(ipykernel, 'connect'):\n ipykernel.connect = Connect("${e.id}")\n`, - n = e.requestExecute({ code: t }); - await n.done, console.log('Pyodide kernel patch applied'); - } - } - class y { - constructor(e, t, n) { - this.baseUrl = e; - const r = window.self !== window.top; - this.notebookHandlerPromise = new Promise((e, t) => { - (this.resolveNotebookHandler = e), (this.rejectNotebookHandler = t); - }); - const i = document.createElement('div'); - let a; - (i.id = 'window-container'), - document.body.appendChild(i), - (0, o.loadImJoyBasicApp)({ - process_url_query: !0, - show_window_title: !1, - show_progress_bar: !0, - show_empty_window: !0, - menu_style: { position: 'absolute', right: 0, top: '2px' }, - window_style: { width: '100%', height: '100%' }, - main_container: null, - menu_container: null, - expose_api: !1, - imjoy_api: { - async createWindow(e, t, n) { - if ( - !document.getElementById(t.window_id) && - !t.dialog && - document.getElementById(e.id) - ) { - const n = document.createElement('div'); - (n.id = t.window_id), - n.classList.add('imjoy-inline-window'), - document.getElementById(e.id).appendChild(n); - } - return await a.pm.createWindow(e, t, n); - } - } - }) - .then(async e => { - console.log('ImJoy Basic App loaded!'), (a = e.imjoy); - const o = {}; - async function i(e) { - if (!o[e]) - return void console.warn('Kernel is not ready: ' + e); - const t = o[e].kernel; - await t.ready; - const n = await a.pm.connectPlugin(new m({ kernel: t })); - o[e].plugin = n; - } - async function l(t) { - if (o[t]) - try { - const n = o[t].plugin; - if (n && n.api.run) { - let t = {}; - n.config.ui && - n.config.ui.indexOf('{') > -1 && - (t = await e.imjoy.pm.imjoy_api.showDialog( - n, - n.config - )), - await n.api.run({ config: t, data: {} }); - } - } catch (t) { - console.error(t), - e.showMessage(`Failed to load the plugin, error: ${t}`); - } - else console.warn('Kernel is not ready: ' + t); - } - r && - (await (0, s.setupRPC)({ name: 'JupyterLite' })).export({ - setup() {}, - run(e) { - ((e = e || {}).config = e.config || {}), - (e.config.left_collapsed = - void 0 === e.config.left_collapsed), - e.config.left_collapsed - ? t.shell.leftCollapsed || - t.commands.execute('application:toggle-left-area') - : t.shell.leftCollapsed && - t.commands.execute('application:toggle-left-area'); - }, - async fileExists(e) { - try { - return ( - await n.model.manager.services.contents.get(e), !0 - ); - } catch (e) { - return !1; - } - }, - getFile: async e => - await n.model.manager.services.contents.get(e), - removeFile: async e => await n.model.manager.deleteFile(e), - async loadFile(e, t, o) { - const s = new File([t], e, { type: o }); - return (await n.model.upload(s)).path; - }, - async openFile(e) { - await t.commands.execute('docmanager:open', { path: e }); - }, - async closeLeft() { - t.shell.leftCollapsed || - t.commands.execute('application:toggle-left-area'); - }, - async openLeft() { - t.shell.leftCollapsed && - t.commands.execute('application:toggle-left-area'); - } - }), - (window.connectPlugin = async e => { - e - ? (await i(e), await l(e)) - : console.warn( - 'Please upgrade imjoy-rpc(>=0.3.35) by running `pip install -U imjoy-rpc`' - ); - }), - (window._connectPlugin = async e => { - await i(e); - }), - (window._runPluginOnly = async e => { - await l(e); - }), - this.resolveNotebookHandler(async (e, t, n) => { - const { kernel: s } = e.session; - n.style.minWidth = '25px'; - const r = new d.Spinner(); - (r.node.firstChild.style.width = '20px'), - (r.node.firstChild.style.height = '20px'), - e.kernelChanged.connect(() => { - n.appendChild(r.node), - w(s) - .finally(() => { - n.removeChild(r.node); - }) - .catch(() => { - console.error('Failed to apply pyodide patch'); - }); - }, e), - n.appendChild(r.node); - try { - await w(s); - } catch (e) { - throw e; - } finally { - n.removeChild(r.node); - } - (o[s._id] = { kernel: s }), - (n.firstChild.innerHTML = - ''), - (n.firstChild.onclick = () => { - l(s._id); - }); - }); - }) - .catch(e => { - console.error(e), this.rejectNotebookHandler(e); - }); - } - createNew(e, t) { - const n = new d.ToolbarButton({ - tooltip: 'ImJoy JupyterLab Extension (version: 0.1.13)' - }); - return ( - e.toolbar.insertItem(0, 'Run ImJoy Plugin', n), - t.sessionContext.ready.then(async () => { - (await this.notebookHandlerPromise)( - t.sessionContext, - e.node, - n.node - ); - }), - new _.DisposableDelegate(() => { - n.dispose(); - }) - ); - } - } - const g = { - id: 'imjoy-jupyterlab-extension', - requires: [h.IFileBrowserFactory, u.ITranslator], - autoStart: !0, - activate: async function (e, t, n) { - const o = n.load('jupyterlab'), - { defaultBrowser: s } = t, - r = e.serviceManager.settings.serverSettings.baseUrl; - e.docRegistry.addWidgetExtension('Notebook', new y(r, e, s)), - console.log( - 'JupyterLab extension imjoy-jupyterlab-extension is activated!' - ); - const i = new URL(window.location); - e.started.then(() => { - (async function (e, t, n, o) { - const s = new URLSearchParams(e), - r = s.getAll('load'); - let i = null; - for (let e of r) { - let t, - s = ''; - try { - e = e.includes('//zenodo.org/record') - ? await p(e) - : (await c(e, '.ipynb')) || e; - const r = await fetch(e); - (t = await r.blob()), - (s = r.headers.get('Content-Type') ?? ''); - try { - const o = f.PathExt.basename(e).split('?')[0], - r = new File([t], o, { type: s }), - a = await n.model.upload(r); - (i = a.path), console.log('File uploaded: ' + a.path); - } catch (e) { - (0, d.showErrorMessage)( - o._p('showErrorMessage', 'Upload Error'), - e - ); - } - } catch (t) { - return ( - t.response && - 200 !== t.response.status && - (t.message = o.__('Could not open URL: %1', e)), - (0, d.showErrorMessage)(o.__('Cannot fetch'), t) - ); - } - } - let a = s.get('open'); - '1' === a && (a = i), - a && (await t.commands.execute('docmanager:open', { path: a })); - })(window.location.search, e, s, o).finally(() => { - window.history.pushState(null, '', i); - }); - }); - } - }; - } - } -]); diff --git a/imjoy-jupyterlab-extension/labextension/static/942.c4b692e5941010f31829.js b/imjoy-jupyterlab-extension/labextension/static/942.c4b692e5941010f31829.js deleted file mode 100644 index 3cbfbc4..0000000 --- a/imjoy-jupyterlab-extension/labextension/static/942.c4b692e5941010f31829.js +++ /dev/null @@ -1,1864 +0,0 @@ -/*! For license information please see 942.c4b692e5941010f31829.js.LICENSE.txt */ -(self.webpackChunkimjoy_jupyterlab_extension = - self.webpackChunkimjoy_jupyterlab_extension || []).push([ - [942], - { - 703: module => { - var factory; - window, - (factory = function () { - return (function (e) { - var n = {}; - function t(r) { - if (n[r]) return n[r].exports; - var i = (n[r] = { i: r, l: !1, exports: {} }); - return ( - e[r].call(i.exports, i, i.exports, t), (i.l = !0), i.exports - ); - } - return ( - (t.m = e), - (t.c = n), - (t.d = function (e, n, r) { - t.o(e, n) || - Object.defineProperty(e, n, { enumerable: !0, get: r }); - }), - (t.r = function (e) { - 'undefined' != typeof Symbol && - Symbol.toStringTag && - Object.defineProperty(e, Symbol.toStringTag, { - value: 'Module' - }), - Object.defineProperty(e, '__esModule', { value: !0 }); - }), - (t.t = function (e, n) { - if ((1 & n && (e = t(e)), 8 & n)) return e; - if (4 & n && 'object' == typeof e && e && e.__esModule) - return e; - var r = Object.create(null); - if ( - (t.r(r), - Object.defineProperty(r, 'default', { - enumerable: !0, - value: e - }), - 2 & n && 'string' != typeof e) - ) - for (var i in e) - t.d( - r, - i, - function (n) { - return e[n]; - }.bind(null, i) - ); - return r; - }), - (t.n = function (e) { - var n = - e && e.__esModule - ? function () { - return e.default; - } - : function () { - return e; - }; - return t.d(n, 'a', n), n; - }), - (t.o = function (e, n) { - return Object.prototype.hasOwnProperty.call(e, n); - }), - (t.p = ''), - t((t.s = './src/imjoyLoader.js')) - ); - })({ - './node_modules/webpack/buildin/amd-options.js': function ( - module, - exports - ) { - eval( - '/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */\nmodule.exports = __webpack_amd_options__;\n\n/* WEBPACK VAR INJECTION */}.call(this, {}))\n\n//# sourceURL=webpack://%5Bname%5D/(webpack)/buildin/amd-options.js?' - ); - }, - './package.json': function (module) { - eval( - 'module.exports = JSON.parse("{\\"name\\":\\"imjoy-core\\",\\"version\\":\\"0.14.2\\",\\"private\\":false,\\"description\\":\\"The core library for ImJoy -- a sandboxed plugin framework for computational web applications.\\",\\"author\\":\\"imjoy-team \\",\\"license\\":\\"MIT\\",\\"repository\\":{\\"type\\":\\"git\\",\\"url\\":\\"git+https://github.com/imjoy-team/imjoy-core.git\\"},\\"keywords\\":[\\"ImJoy\\",\\"PWA\\",\\"Deep Learning\\"],\\"bugs\\":{\\"url\\":\\"https://github.com/imjoy-team/ImJoy/issues\\"},\\"homepage\\":\\"https://imjoy.io\\",\\"module\\":\\"index.js\\",\\"scripts\\":{\\"serve\\":\\"webpack-dev-server --config webpack.config.js --mode development\\",\\"build\\":\\"rm -rf dist && npm run build-prod && npm run build-dev\\",\\"build-prod\\":\\"NODE_ENV=production webpack --config webpack.config.js --mode production --devtool source-map\\",\\"build-dev\\":\\"NODE_ENV=development webpack --config webpack.config.js --mode development\\",\\"watch\\":\\"webpack --watch --progress --config webpack.config.js --mode development\\",\\"check-format\\":\\"prettier --check \\\\\\"{src,tests}/**/**\\\\\\"\\",\\"format\\":\\"prettier --write \\\\\\"{src,tests}/**/**\\\\\\"\\",\\"lint\\":\\"eslint \\\\\\"{src,tests}/**/**\\\\\\"\\",\\"check\\":\\"eslint \\\\\\"{src,tests}/**/**\\\\\\" && prettier --check \\\\\\"{src,tests}/**/**\\\\\\"\\",\\"test\\":\\"karma start --single-run --browsers ChromeHeadless,FirefoxHeadless karma.conf.js\\",\\"test-watch\\":\\"karma start --auto-watch --browsers Chrome,FirefoxHeadless karma.conf.js --debug\\",\\"deploy\\":\\"npm run build && node deploy-site.js\\",\\"publish-npm\\":\\"npm install && npm run build && npm publish\\"},\\"dependencies\\":{\\"ajv\\":\\"^6.9.1\\",\\"axios\\":\\"^0.21.1\\",\\"dompurify\\":\\"^2.0.8\\",\\"file-saver\\":\\"^1.3.3\\",\\"imjoy-rpc\\":\\"^0.3.35\\",\\"js-yaml\\":\\"^3.13.1\\",\\"lodash\\":\\"^4.17.15\\",\\"lz-string\\":\\"^1.4.4\\",\\"minibus\\":\\"^3.1.0\\",\\"pouchdb-browser\\":\\"^7.2.2\\",\\"socket.io-client\\":\\"^2.3.0\\",\\"spark-md5\\":\\"^3.0.0\\"},\\"devDependencies\\":{\\"@babel/core\\":\\"^7.0.0-beta.39\\",\\"@babel/plugin-syntax-dynamic-import\\":\\"^7.0.0-beta.39\\",\\"@babel/polyfill\\":\\"^7.0.0-beta.39\\",\\"@babel/preset-env\\":\\"^7.0.0-beta.39\\",\\"@types/requirejs\\":\\"^2.1.28\\",\\"babel-core\\":\\"^6.26.0\\",\\"babel-eslint\\":\\"^10.1.0\\",\\"babel-loader\\":\\"^8.1.0\\",\\"babel-plugin-lodash\\":\\"^3.3.4\\",\\"babel-runtime\\":\\"^6.26.0\\",\\"chai\\":\\"^4.1.2\\",\\"cname-webpack-plugin\\":\\"^1.0.3\\",\\"copy-webpack-plugin\\":\\"^5.1.1\\",\\"create-file-webpack\\":\\"^1.0.2\\",\\"cross-env\\":\\"^5.0.1\\",\\"cross-spawn\\":\\"^5.0.1\\",\\"eslint\\":\\"^6.8.0\\",\\"eslint-config-prettier\\":\\"^4.2.0\\",\\"gh-pages\\":\\"^2.0.1\\",\\"husky\\":\\"^4.2.3\\",\\"karma\\":\\"^6.1.1\\",\\"karma-chrome-launcher\\":\\"^3.1.0\\",\\"karma-firefox-launcher\\":\\"^1.3.0\\",\\"karma-mocha\\":\\"^1.3.0\\",\\"karma-spec-reporter\\":\\"0.0.32\\",\\"karma-webpack\\":\\"^4.0.2\\",\\"lint-staged\\":\\"^10.0.8\\",\\"mocha\\":\\"^7.1.0\\",\\"postcss-import\\":\\"^11.0.0\\",\\"postcss-loader\\":\\"^2.0.8\\",\\"postcss-url\\":\\"^7.2.1\\",\\"prettier\\":\\"1.17.0\\",\\"raw-loader\\":\\"^1.0.0\\",\\"rename-output-webpack-plugin\\":\\"^1.0.1\\",\\"uglify-es\\":\\"github:mishoo/UglifyJS2#harmony\\",\\"uglify-js\\":\\"^2.8.29\\",\\"url-loader\\":\\"^1.1.2\\",\\"webpack\\":\\"^4.42.0\\",\\"webpack-bundle-analyzer\\":\\"^3.7.0\\",\\"webpack-cli\\":\\"^3.3.6\\",\\"webpack-dev-server\\":\\"^3.1.1\\",\\"worker-loader\\":\\"^2.0.0\\"},\\"eslintConfig\\":{\\"root\\":true,\\"env\\":{\\"browser\\":true,\\"node\\":true,\\"es6\\":true},\\"extends\\":[\\"eslint:recommended\\"],\\"rules\\":{\\"no-console\\":\\"off\\",\\"no-debugger\\":\\"off\\",\\"no-empty\\":[\\"error\\",{\\"allowEmptyCatch\\":true}]},\\"parserOptions\\":{\\"parser\\":\\"babel-eslint\\",\\"ecmaVersion\\":2017,\\"sourceType\\":\\"module\\",\\"ecmaFeatures\\":{\\"modules\\":true}}},\\"prettier\\":{\\"trailingComma\\":\\"es5\\"},\\"postcss\\":{\\"plugins\\":{\\"autoprefixer\\":{}}},\\"browserslist\\":[\\"> 1%\\",\\"last 2 versions\\",\\"not ie <= 8\\"],\\"husky\\":{\\"hooks\\":{\\"pre-commit\\":\\"lint-staged\\"}},\\"lint-staged\\":{\\"{src,tests}/**/**}\\":\\"prettier --write\\"}}");\n\n//# sourceURL=webpack://%5Bname%5D/./package.json?' - ); - }, - './src/imjoyBasicApp.js': function ( - module, - __webpack_exports__, - __webpack_require__ - ) { - 'use strict'; - eval( - '__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "injectScript", function() { return injectScript; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadImJoyBasicApp", function() { return loadImJoyBasicApp; });\n/* harmony import */ var _imjoyBasicApp_template_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./imjoyBasicApp.template.css */ "./src/imjoyBasicApp.template.css");\n/* harmony import */ var _imjoyBasicApp_template_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_imjoyBasicApp_template_css__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _imjoyBasicApp_template_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./imjoyBasicApp.template.html */ "./src/imjoyBasicApp.template.html");\n/* harmony import */ var _imjoyBasicApp_template_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_imjoyBasicApp_template_html__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _imjoyBasicAppMenu_template_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./imjoyBasicAppMenu.template.html */ "./src/imjoyBasicAppMenu.template.html");\n/* harmony import */ var _imjoyBasicAppMenu_template_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_imjoyBasicAppMenu_template_html__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _imjoyBasicAppWindows_template_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./imjoyBasicAppWindows.template.html */ "./src/imjoyBasicAppWindows.template.html");\n/* harmony import */ var _imjoyBasicAppWindows_template_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_imjoyBasicAppWindows_template_html__WEBPACK_IMPORTED_MODULE_3__);\n\n\n\n\nfunction injectScript(src) {\n return new Promise((resolve, reject) => {\n const script = document.createElement("script");\n script.src = src;\n script.addEventListener("load", resolve);\n script.addEventListener("error", () => {\n document.head.removeChild(script);\n reject("Error loading script: " + src);\n });\n script.addEventListener("abort", () => reject("Script loading aborted."));\n document.head.appendChild(script);\n });\n}\n\nfunction getUrlParameter(name) {\n name = name.replace(/[\\[]/, "\\\\[").replace(/[\\]]/, "\\\\]");\n var regex = new RegExp("[\\\\?&]" + name + "=([^&#]*)");\n var results = regex.exec(location.search);\n return results === null ? "" : decodeURIComponent(results[1].replace(/\\+/g, " "));\n}\n\nfunction loadCss(url) {\n const fileref = document.createElement("link");\n fileref.setAttribute("rel", "stylesheet");\n fileref.setAttribute("type", "text/css");\n fileref.setAttribute("href", url);\n document.getElementsByTagName("head")[0].appendChild(fileref);\n}\n\nasync function loadImJoyBasicApp(config) {\n await injectScript("https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js");\n await injectScript("https://imjoy-team.github.io/vue-js-modal/index.js");\n loadCss("https://imjoy-team.github.io/vue-js-modal/styles.css");\n await injectScript("https://cdn.jsdelivr.net/npm/@oeway/vue-window@2.4.1-a/lib/index.js");\n config = config || {};\n let app;\n const imjoy_api = {\n showDialog(plugin, cfg, extra_cfg) {\n extra_cfg = extra_cfg || {};\n extra_cfg.dialog = true;\n return imjoy.pm.createWindow(plugin, cfg, extra_cfg);\n },\n\n createWindow(plugin, cfg, extra_cfg) {\n extra_cfg = extra_cfg || {};\n if (!config.window_manager_container) extra_cfg.dialog = true;\n return imjoy.pm.createWindow(plugin, cfg, extra_cfg);\n },\n\n showSnackbar(plugin, msg, duration) {\n app.showSnackbar(msg, duration);\n },\n\n showMessage(plugin, msg) {\n app.showSnackbar(msg, 5);\n },\n\n showStatus(plugin, msg) {\n app.showSnackbar(msg, 5);\n },\n\n showProgress(plugin, progress) {\n progress = progress || 0;\n if (progress < 1) progress = progress * 100;\n app.progress = progress;\n app.$forceUpdate();\n }\n\n };\n\n if (config.imjoy_api) {\n for (let k of Object.keys(config.imjoy_api)) {\n imjoy_api[k] = config.imjoy_api[k];\n }\n }\n\n const imjoyCore = await loadImJoyCore(config);\n const imjoy = new imjoyCore.ImJoy({\n imjoy_api\n });\n await imjoy.start(config);\n console.log("ImJoy Core started successfully!");\n Vue.use(window["vue-js-modal"].default);\n Vue.use(window.VueWindow);\n let elem;\n\n if (config.main_container) {\n if (typeof config.main_container === "string") elem = document.getElementById(config.main_container);else elem = config.main_container;\n } else {\n elem = document.createElement("div");\n document.body.appendChild(elem);\n }\n\n elem.style.visibility = "hidden";\n elem.innerHTML = _imjoyBasicApp_template_html__WEBPACK_IMPORTED_MODULE_1___default.a;\n document.head.insertAdjacentHTML("beforeend", ``);\n let windowManager;\n\n if (config.window_manager_container) {\n let windowsElem;\n if (typeof config.window_manager_container === "string") windowsElem = document.getElementById(config.window_manager_container);else windowsElem = config.window_manager_container;\n windowsElem.innerHTML = _imjoyBasicAppWindows_template_html__WEBPACK_IMPORTED_MODULE_3___default.a;\n windowManager = new Vue({\n el: windowsElem,\n data: {\n type: config.window_manager_type || "standard",\n windowSizePosChanging: false,\n windowStyle: config.window_style || {},\n showEmpty: config.show_empty_window || false,\n showWindowTitle: config.show_window_title || false,\n windows: [],\n activeWindow: null\n },\n watch: {\n windowSizePosChanging: function (newVal) {\n app.$emit("window-size-pos-changing", newVal);\n }\n },\n methods: {\n closeWindow(w) {\n this.windowSizePosChanging = false;\n w.hidden = true;\n this.$forceUpdate();\n w.close();\n }\n\n }\n });\n }\n\n let menuManager;\n\n if (config.menu_container) {\n let menuElem;\n if (typeof config.menu_container === "string") menuElem = document.getElementById(config.menu_container);else menuElem = config.menu_container;\n menuElem.innerHTML = _imjoyBasicAppMenu_template_html__WEBPACK_IMPORTED_MODULE_2___default.a;\n menuElem.style.minHeight = "30px";\n menuManager = new Vue({\n el: menuElem,\n data: {\n menuPos: config.menu_pos || "right",\n menuStyle: config.menu_style || {\n "z-index": 999\n },\n activeWindow: null,\n closeWindow: null,\n showAboutImJoy: null,\n extraMenuItems: [],\n loadedPlugins: [],\n allWindows: [],\n showContent: true\n },\n\n mounted() {\n this.menuStyle = this.menuStyle || {};\n this.menuStyle.float = this.menuPos === "left" ? "left" : "right";\n },\n\n methods: {\n menuClicked() {\n // force closing the menu for touch screen devices\n this.showContent = false;\n this.$forceUpdate();\n setTimeout(() => {\n this.showContent = true;\n this.$forceUpdate();\n }, 0);\n }\n\n }\n });\n }\n\n app = new Vue({\n el: elem,\n data: {\n dialogWindows: [],\n selectedDialogWindow: null,\n selectedWindowsStack: [],\n selectedRegularWindow: null,\n fullscreen: false,\n loading: false,\n snackBarContent: false,\n snackBarTimer: null,\n progress: 0,\n loadedPlugins: [],\n allWindows: [],\n extraMenuItems: [],\n showProgressBar: config.show_progress_bar,\n showLoader: config.show_loader,\n showWindows: config.show_windows\n },\n\n mounted() {\n this.$el.style.visibility = "visible";\n imjoy.event_bus.on("close_window", w => {\n this.closeWindow(w);\n this.$forceUpdate();\n });\n imjoy.event_bus.on("add_window", w => {\n this.allWindows.push(w);\n this.addWindow(w);\n });\n this.imjoy = imjoy;\n\n if (config.process_url_query) {\n this.processURLQuery();\n }\n\n if (menuManager) {\n menuManager.closeWindow = w => {\n this.closeWindow(w);\n };\n\n if (!config.hide_about_imjoy) {\n menuManager.showAboutImJoy = () => {\n imjoy.api.showDialog({\n src: "https://imjoy.io/docs/",\n passive: true\n });\n };\n }\n }\n },\n\n computed: {\n regularWindows: function () {\n return this.allWindows.filter(w => !this.dialogWindows.includes(w) && !w.inline);\n }\n },\n watch: {\n regularWindows: function (newVal) {\n if (windowManager) {\n windowManager.windows = newVal;\n windowManager.$forceUpdate();\n }\n },\n selectedRegularWindow: function (newVal) {\n if (windowManager) {\n windowManager.activeWindow = newVal;\n windowManager.$forceUpdate();\n }\n\n if (menuManager && config.window_manager_type === "simple") {\n menuManager.activeWindow = newVal;\n menuManager.$forceUpdate();\n }\n },\n extraMenuItems: function (newVal) {\n if (menuManager) {\n menuManager.extraMenuItems = newVal;\n menuManager.$forceUpdate();\n }\n },\n allWindows: function (newVal) {\n if (menuManager) {\n menuManager.allWindows = newVal;\n menuManager.$forceUpdate();\n }\n },\n loadedPlugins: function (newVal) {\n if (menuManager) {\n menuManager.loadedPlugins = newVal;\n menuManager.$forceUpdate();\n }\n }\n },\n methods: {\n async processURLQuery() {\n const engine = getUrlParameter("engine");\n const p = getUrlParameter("plugin") || getUrlParameter("p");\n const binder = getUrlParameter("binder");\n\n if (engine) {\n const token = getUrlParameter("token");\n const name = getUrlParameter("name");\n await this.setupPluginEngine(engine, token, name);\n }\n\n if (binder) {\n const name = getUrlParameter("name");\n const spec = getUrlParameter("spec");\n await this.setupBinderEngine(binder, spec, name);\n }\n\n if (p) {\n this.loadPlugin(p).then(plugin => {\n let config = {},\n data = {},\n tmp;\n tmp = getUrlParameter("data");\n if (tmp) data = JSON.parse(tmp);\n tmp = getUrlParameter("config");\n if (tmp) config = JSON.parse(tmp);\n this.runPlugin(plugin, config, data);\n });\n }\n },\n\n async runPlugin(plugin, config, data) {\n if (!config && plugin.config.ui && plugin.config.ui.indexOf("{") > -1) {\n config = await imjoy.pm.imjoy_api.showDialog(plugin, plugin.config);\n }\n\n data = data || {};\n return await plugin.api.run({\n config: config,\n data: data\n });\n },\n\n async setupPluginEngine(engine, token, name) {\n try {\n console.log("Loading Jupyter-Engine-Manager from Gist...");\n\n if (!imjoy.em.getFactory("Jupyter-Engine")) {\n await imjoy.pm.reloadPluginRecursively({\n uri: "https://imjoy-team.github.io/jupyter-engine-manager/Jupyter-Engine-Manager.imjoy.html"\n });\n console.log("Jupyter-Engine-Manager loaded.");\n await imjoy.em.unregister("https://mybinder.org");\n }\n\n const factory = imjoy.em.getFactory("Jupyter-Engine");\n await factory.addEngine({\n name: name,\n url: engine,\n nbUrl: engine + "?token=" + token\n });\n console.log("plugin engine added:", engine);\n } catch (e) {\n console.error(e);\n alert(`Failed to connect to the engine: ${e}`);\n }\n },\n\n async setupBinderEngine(url, spec, name) {\n try {\n console.log("Loading Jupyter-Engine-Manager from Gist...");\n\n if (!imjoy.em.getFactory("MyBinder-Engine")) {\n await imjoy.pm.reloadPluginRecursively({\n uri: "https://imjoy-team.github.io/jupyter-engine-manager/Jupyter-Engine-Manager.imjoy.html"\n });\n console.log("Jupyter-Engine-Manager loaded.");\n await imjoy.em.unregister("https://mybinder.org");\n }\n\n const factory = imjoy.em.getFactory("MyBinder-Engine");\n await factory.addEngine({\n name,\n spec,\n url\n });\n console.log("Binder engine added:", url);\n } catch (e) {\n console.error(e);\n alert(`Failed to connect to the engine: ${e}`);\n }\n },\n\n async loadPlugin(uri) {\n try {\n this.loading = true;\n const p = await imjoy.pm.reloadPluginRecursively({\n uri\n });\n this.loadedPlugins.push(p);\n this.showSnackbar(`Plugin ${p.name} successfully loaded.`);\n return p;\n } finally {\n this.loading = false;\n }\n },\n\n addMenuItem(config) {\n this.extraMenuItems.push(config);\n this.$forceUpdate();\n },\n\n removeMenuItem(label) {\n const item = this.extraMenuItems.filter(it => it.label === label)[0];\n const idx = this.extraMenuItems.indexOf(item);\n if (idx >= 0) this.extraMenuItems.splice(idx, 1);\n },\n\n showSnackbar(msg, duration) {\n if (this.snackBarTimer) clearTimeout(this.snackBarTimer);\n duration = duration || 3;\n this.snackBarContent = msg;\n this.$forceUpdate();\n this.snackBarTimer = setTimeout(() => {\n this.snackBarContent = null;\n this.snackBarTimer = null;\n this.$forceUpdate();\n }, duration * 1000);\n },\n\n showLoader(loading) {\n this.loading = loading;\n this.$forceUpdate();\n },\n\n addWindow(w) {\n w.api = w.api || {};\n const windowElm = document.getElementById(w.window_id);\n\n if (windowElm) {\n if (w.window_style) Object.assign(windowElm.style, w.window_style);\n w.inline = true;\n\n w.api.show = w.show = () => {\n windowElm.scrollIntoView();\n };\n\n return;\n }\n\n if (!w.dialog) {\n this.selectedRegularWindow = w;\n setTimeout(() => {\n if (w.fullscreen || w.standalone) {\n w.sizeState = "maximized";\n } else {\n w.sizeState = "normal";\n }\n\n this.$forceUpdate();\n }, 0);\n const self = this;\n\n w.api.show = w.show = () => {\n w.sizeState = "restore";\n self.selectedRegularWindow = w;\n self.$forceUpdate();\n imjoy.wm.selectWindow(w);\n w.api.emit("show");\n };\n } else {\n this.dialogWindows.push(w);\n\n if (this.selectedDialogWindow) {\n this.selectedWindowsStack.push(this.selectedDialogWindow);\n }\n\n this.selectedDialogWindow = w;\n if (w.fullscreen || w.standalone) this.fullscreen = true;else this.fullscreen = false;\n this.$modal.show("window-modal-dialog");\n this.$forceUpdate();\n\n w.api.show = w.show = () => {\n this.selectedDialogWindow = w;\n this.$modal.show("window-modal-dialog");\n imjoy.wm.selectWindow(w);\n w.api.emit("show");\n };\n\n w.api.hide = w.hide = () => {\n if (this.selectedDialogWindow === w) {\n this.$modal.hide("window-modal-dialog");\n }\n\n w.api.emit("hide");\n };\n\n setTimeout(() => {\n try {\n w.show();\n } catch (e) {\n console.error(e);\n }\n }, 500);\n }\n },\n\n showWindow(w) {\n if (w.fullscreen || w.standalone) this.fullscreen = true;else this.fullscreen = false;\n if (w) this.selectedDialogWindow = w;\n this.$modal.show("window-modal-dialog");\n },\n\n closeWindow(w) {\n let idx = this.dialogWindows.indexOf(w);\n if (idx >= 0) this.dialogWindows.splice(idx, 1);\n idx = this.allWindows.indexOf(w);\n if (idx >= 0) this.allWindows.splice(idx, 1);\n\n if (w === this.selectedDialogWindow) {\n this.selectedDialogWindow = this.selectedWindowsStack.pop();\n }\n\n if (!this.selectedDialogWindow) this.$modal.hide("window-modal-dialog");\n\n if (w === this.selectedRegularWindow) {\n if (this.regularWindows.length > 0) this.selectedRegularWindow = this.regularWindows[this.regularWindows.length - 1] || null;else this.selectedRegularWindow = null;\n }\n\n this.$forceUpdate();\n },\n\n minimizeWindow() {\n this.$modal.hide("window-modal-dialog");\n },\n\n maximizeWindow() {\n this.fullscreen = !this.fullscreen;\n }\n\n }\n });\n return app;\n}\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyBasicApp.js?' - ); - }, - './src/imjoyBasicApp.template.css': function (module, exports) { - eval( - 'module.exports = ".vm--modal {\\n max-height: 100% !important;\\n max-width: 100% !important;\\n}\\n\\n.imjoy-inline-window {\\n width: 100%;\\n height: 600px;\\n}\\n\\n.imjoy-progress-border > div {\\n background-color: #448aff;\\n height: 3px;\\n}\\n\\n.imjoy-progress-border {\\n top: 0;\\n left: 0;\\n position: absolute;\\n width: 100%;\\n height: 3px;\\n}\\n\\n.imjoy-noselect {\\n -webkit-touch-callout: none;\\n -webkit-user-select: none;\\n -khtml-user-select: none;\\n -moz-user-select: none;\\n -ms-user-select: none;\\n user-select: none;\\n}\\n\\nbody {\\n margin: 0px;\\n}\\n.imjoy-dialog-control {\\n padding: 0px;\\n line-height: 10px;\\n height: 23px;\\n width: 25px;\\n border: 0px;\\n font-size: 1rem;\\n position: absolute;\\n color: white;\\n top: 1px;\\n}\\n\\n.imjoy-dialog-control:focus {\\n outline: none;\\n}\\n\\n.imjoy-loader {\\n position: fixed;\\n top: 40%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n transform: -webkit-translate(-50%, -50%);\\n transform: -moz-translate(-50%, -50%);\\n transform: -ms-translate(-50%, -50%);\\n border: 10px solid #f3f3f3;\\n /* Light grey */\\n border-top: 10px solid #448aff;\\n /* Blue */\\n border-radius: 50%;\\n width: 40px;\\n height: 40px;\\n animation: spin 2s linear infinite;\\n}\\n\\n@keyframes spin {\\n 0% {\\n transform: rotate(0deg);\\n }\\n\\n 100% {\\n transform: rotate(360deg);\\n }\\n}\\n\\n/* The snackbar - position it at the bottom and in the middle of the screen */\\n.imjoy-snackbar {\\n font-family: Arial, Helvetica, sans-serif;\\n visibility: hidden;\\n /* Hidden by default. Visible on click */\\n min-width: 250px;\\n /* Set a default minimum width */\\n background-color: #333333c2;\\n /* Black background color */\\n color: #fff;\\n /* White text color */\\n text-align: center;\\n /* Centered text */\\n border-radius: 5px;\\n /* Rounded borders */\\n padding: 16px;\\n /* Padding */\\n position: fixed;\\n /* Sit on top of the screen */\\n z-index: 9999;\\n /* Add a z-index if needed */\\n left: 50%;\\n /* Center the snackbar */\\n transform: translate(-50%, 0);\\n bottom: 20px;\\n /* 20px from the bottom */\\n}\\n\\n.imjoy-window-title-bar {\\n cursor: move;\\n background-color: #448aff;\\n color: white;\\n text-align: center;\\n height: 24px;\\n}\\n\\n.imjoy-window-title {\\n text-align: center;\\n font-family: Arial, Helvetica, sans-serif;\\n font-size: 16px;\\n line-height: 23px;\\n margin: 0px;\\n}\\n\\n/* Show the snackbar when clicking on a button (class added with JavaScript) */\\n.imjoy-snackbar.show-snackbar {\\n visibility: visible;\\n /* Show the snackbar */\\n /* Add animation: Take 0.5 seconds to fade in and out the snackbar.\\n However, delay the fade out process for 2.5 seconds */\\n -webkit-animation: imjoy-fadein 0.5s;\\n animation: imjoy-fadein 0.5s;\\n}\\n\\n/* Animations to fade the snackbar in and out */\\n@-webkit-keyframes imjoy-fadein {\\n from {\\n bottom: 0;\\n opacity: 0;\\n }\\n\\n to {\\n bottom: 30px;\\n opacity: 1;\\n }\\n}\\n\\n@keyframes imjoy-fadein {\\n from {\\n bottom: 0;\\n opacity: 0;\\n }\\n\\n to {\\n bottom: 30px;\\n opacity: 1;\\n }\\n}\\n\\n.imjoy-dropdown-btn {\\n padding: 4px;\\n font-size: 16px;\\n border: none;\\n cursor: pointer;\\n}\\n\\n.imjoy-dropdown {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.imjoy-dropdown-content {\\n display: none;\\n position: absolute;\\n right: 0;\\n background-color: #f9f9f9;\\n min-width: 200px;\\n box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);\\n z-index: 1;\\n}\\n\\n.imjoy-dropdown-content a {\\n font-family: Arial, Helvetica, sans-serif;\\n color: black;\\n padding: 6px 10px;\\n text-decoration: none;\\n display: block;\\n}\\n\\n.imjoy-dropdown-content a:hover {\\n background-color: #f1f1f1;\\n}\\n\\n.imjoy-dropdown:hover .imjoy-dropdown-content {\\n display: block;\\n}\\n\\n.imjoy-window-container {\\n width: 100%;\\n height: 100%;\\n}\\n\\n.imjoy-windows {\\n position: relative;\\n min-height: 100px;\\n height: calc(100% - 30px);\\n}\\n\\n.block-pointer-events {\\n pointer-events: none;\\n}\\n"\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyBasicApp.template.css?' - ); - }, - './src/imjoyBasicApp.template.html': function (module, exports) { - eval( - 'module.exports = "
\\n
\\n
\\n
\\n\\n {{snackBarContent}}\\n\\n\\n \\n {{ selectedDialogWindow.name}}\\n \\n x\\n \\n \\n -\\n \\n \\n {{fullscreen?\'=\': \'+\'}}\\n \\n \\n \\n\\n"\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyBasicApp.template.html?' - ); - }, - './src/imjoyBasicAppMenu.template.html': function ( - module, - exports - ) { - eval( - 'module.exports = "
\\n \\n \\n \\n {{item.label}}\\n 0 && loadedPlugins.length>0\\"\\n />\\n 🧩 {{p.name}}\\n 0 && loadedPlugins.length>0\\"\\n />\\n ℹ️ About ImJoy\\n 0 && loadedPlugins.length>0\\"\\n />\\n 🔳 {{w.name}}\\n ❌ Close Window\\n
\\n\\n"\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyBasicAppMenu.template.html?' - ); - }, - './src/imjoyBasicAppWindows.template.html': function ( - module, - exports - ) { - eval( - 'module.exports = "\\n\\n\\n \\n\\n"\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyBasicAppWindows.template.html?' - ); - }, - './src/imjoyLoader.js': function ( - module, - __webpack_exports__, - __webpack_require__ - ) { - 'use strict'; - eval( - '__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadImJoyCore", function() { return loadImJoyCore; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "latest_rpc_version", function() { return latest_rpc_version; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadImJoyRPC", function() { return loadImJoyRPC; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadImJoyRPCSocketIO", function() { return loadImJoyRPCSocketIO; });\n/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../package.json */ "./package.json");\nvar _package_json__WEBPACK_IMPORTED_MODULE_0___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../package.json */ "./package.json", 1);\n/* harmony import */ var _imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./imjoyBasicApp.js */ "./src/imjoyBasicApp.js");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "loadImJoyBasicApp", function() { return _imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["loadImJoyBasicApp"]; });\n\n\n\n/**\n * Get the URL parameters\n * source: https://css-tricks.com/snippets/javascript/get-url-variables/\n * @param {String} url The URL\n * @return {Object} The URL parameters\n */\n\nvar _getParams = function (url) {\n var params = {};\n var parser = document.createElement("a");\n parser.href = url;\n var query = parser.search.substring(1);\n var vars = query.split("&");\n\n for (var i = 0; i < vars.length; i++) {\n var pair = vars[i].split("=");\n params[pair[0]] = decodeURIComponent(pair[1]);\n }\n\n return params;\n}; // Load the imjoy core script\n// it support the following options:\n// 1) version, you can specify a specific version of the core,\n// for example `version: "0.11.13"` or `version: "latest"`\n// 2) debug, by default, the minified version will be used,\n// if debug==true, the full version will be served\n// 3) base_url, the url for loading the core library\n\n\nfunction loadImJoyCore(config) {\n config = config || {}; // eslint-disable-next-line no-async-promise-executor\n\n return new Promise(async (resolve, reject) => {\n try {\n var baseUrl = config.base_url;\n\n if (!baseUrl) {\n const version = config.version || "latest";\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-core@${version}/dist/`;\n }\n\n delete window.imjoyCore;\n\n if (config.debug) {\n await Object(_imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["injectScript"])(baseUrl + "imjoy-core.js");\n } else {\n await Object(_imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["injectScript"])(baseUrl + "imjoy-core.min.js");\n }\n\n if (window.imjoyCore) {\n const imjoyCore = window.imjoyCore;\n delete window.imjoyCore;\n resolve(imjoyCore);\n } else if (typeof define === "function" && // eslint-disable-next-line no-undef\n __webpack_require__(/*! !webpack amd options */ "./node_modules/webpack/buildin/amd-options.js")) eval("require")(["imjoyCore"], resolve);else reject("Failed to import imjoy-core.");\n } catch (e) {\n reject(e);\n }\n });\n}\nconst _rpc_registry = {}; // get version number from package.json\n\nconst latest_rpc_version = _package_json__WEBPACK_IMPORTED_MODULE_0__["dependencies"]["imjoy-rpc"].replace(/[^\\d.-]/g, "");\nconst _rpc_api_versions = {\n "0.2.0": {\n from: "0.1.10",\n to: "0.1.17",\n skips: []\n },\n "0.2.1": {\n from: "0.1.18",\n to: "0.2.5",\n skips: []\n },\n "0.2.2": {\n from: "0.2.6",\n to: "0.2.6",\n skips: []\n },\n "0.2.3": {\n from: "0.2.7",\n to: latest_rpc_version,\n skips: ["0.2.9", "0.2.15", "0.2.16", "0.2.18", "0.2.23", "0.2.24", "0.2.25"]\n }\n}; // specify an api version and this function will return the actual imjoy-rpc version\n// if you set latestOnly to true, then it returns always the latest for the api version\n// otherwise, it will try to find a compatible version in the cached version.\n\nfunction findRPCVersionByAPIVersion(apiVersion, latestOnly) {\n if (!apiVersion || !apiVersion.includes(".")) return;\n let cached = Object.keys(_rpc_registry);\n\n if (_rpc_api_versions[apiVersion]) {\n if (cached.length <= 0 || latestOnly) {\n return _rpc_api_versions[apiVersion].to;\n } // see if we can find a compatible version in the cache\n // sort the cached version\n\n\n cached = (f => f(f(cached, 1).sort(), -1))((cached, v) => cached.map(a => a.replace(/\\d+/g, n => +n + v * 100000)));\n\n for (let c of cached.reverse()) {\n if (_rpc_registry[c].API_VERSION === apiVersion) return c;\n }\n\n return _rpc_api_versions[apiVersion].to;\n } else {\n return null;\n }\n} // Load the script for a plugin to communicate with imjoy-rpc\n// This should only be called when the window is inside the iframe\n// it support the following options:\n// 1) version, you can specify a specific version of the imjoy-rpc,\n// for example `version: "0.11.13"` or `version: "latest"`\n// 2) api_version, specify the api version of the imjoy-rpc\n// 3) debug, by default, the minified version will be used,\n// if debug==true, the full version will be served\n// 4) base_url, the url for loading the rpc library\n\n\nfunction loadImJoyRPC(config) {\n config = config || {};\n return new Promise((resolve, reject) => {\n var baseUrl = config.base_url;\n let version = config.version;\n\n if (!baseUrl) {\n if (config.version) {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc@${config.version}/dist/`;\n } else {\n if (config.api_version) {\n // find the latest version for this api_version\n version = findRPCVersionByAPIVersion(config.api_version, true);\n\n if (version) {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc@${version}/dist/`;\n } else {\n reject(Error(`Cannot find a version of imjoy-rpc that supports api v${config.api_version}`));\n return;\n }\n } else {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc@latest/dist/`;\n version = "latest";\n console.info(`Using imjoy-rpc library from ${baseUrl}.`);\n }\n }\n }\n\n if (version && _rpc_registry[version]) {\n console.info(`Using cached imjoy-rpc library v${version}.`);\n resolve(_rpc_registry[version]);\n return;\n }\n\n let rpc_url = baseUrl + "imjoy-rpc.min.js";\n\n if (config.debug) {\n rpc_url = baseUrl + "imjoy-rpc.js";\n }\n\n function checkAndCacheLib(imjoyRPC) {\n if (version && version !== "latest" && version !== imjoyRPC.VERSION) {\n throw new Error(`imjoy-rpc version mismatch ${version} != ${imjoyRPC.VERSION}`);\n }\n\n if (config.api_version && config.api_version !== imjoyRPC.API_VERSION) {\n throw new Error(`imjoy-rpc api version mismatch ${config.api_version} != ${imjoyRPC.API_VERSION}`);\n }\n\n _rpc_registry[imjoyRPC.VERSION] = imjoyRPC;\n }\n\n delete window.imjoyRPC;\n Object(_imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["injectScript"])(rpc_url).then(() => {\n if (window.imjoyRPC) {\n const imjoyRPC = window.imjoyRPC;\n delete window.imjoyRPC;\n\n try {\n checkAndCacheLib(imjoyRPC);\n resolve(imjoyRPC);\n } catch (e) {\n reject(e);\n }\n } else if (typeof define === "function" && // eslint-disable-next-line no-undef\n __webpack_require__(/*! !webpack amd options */ "./node_modules/webpack/buildin/amd-options.js")) eval("require")(["imjoyRPC"], imjoyRPC => {\n try {\n checkAndCacheLib(imjoyRPC);\n resolve(imjoyRPC);\n } catch (e) {\n reject(e);\n }\n });else {\n reject("Failed to import imjoy-rpc.");\n return;\n }\n }).catch(reject);\n });\n}\nfunction loadImJoyRPCSocketIO(config) {\n config = config || {};\n return new Promise((resolve, reject) => {\n var baseUrl = config.base_url;\n let version = config.version;\n\n if (!baseUrl) {\n if (config.version) {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc-socketio@${config.version}/dist/`;\n } else {\n if (config.api_version) {\n // find the latest version for this api_version\n version = findRPCVersionByAPIVersion(config.api_version, true);\n\n if (version) {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc-socketio@${version}/dist/`;\n } else {\n reject(Error(`Cannot find a version of imjoy-rpc-socketio that supports api v${config.api_version}`));\n return;\n }\n } else {\n baseUrl = `https://cdn.jsdelivr.net/npm/imjoy-rpc-socketio@latest/dist/`;\n version = "latest";\n console.info(`Using imjoy-rpc-socketio library from ${baseUrl}.`);\n }\n }\n }\n\n let rpc_url = baseUrl + "imjoy-rpc-socketio.min.js";\n\n if (config.debug) {\n rpc_url = baseUrl + "imjoy-rpc-socketio.js";\n }\n\n delete window.imjoyRPCSocketIO;\n Object(_imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["injectScript"])(rpc_url).then(() => {\n if (window.imjoyRPCSocketIO) {\n const imjoyRPCSocketIO = window.imjoyRPCSocketIO;\n delete window.imjoyRPCSocketIO;\n resolve(imjoyRPCSocketIO);\n } else if (typeof define === "function" && // eslint-disable-next-line no-undef\n __webpack_require__(/*! !webpack amd options */ "./node_modules/webpack/buildin/amd-options.js")) eval("require")(["imjoyRPCSocketIO"], resolve);else {\n reject("Failed to import imjoy-rpc-socketio.");\n }\n }).catch(reject);\n });\n}\n\nasync function loadImJoyRPCByQueryString() {\n const urlParams = _getParams(window.location);\n\n return await loadImJoyRPC(urlParams);\n}\n\n\nwindow.loadImJoyRPCByQueryString = loadImJoyRPCByQueryString;\nwindow.loadImJoyRPC = loadImJoyRPC;\nwindow.loadImJoyRPCSocketIO = loadImJoyRPCSocketIO;\nwindow.loadImJoyCore = loadImJoyCore;\nwindow.loadImJoyBasicApp = _imjoyBasicApp_js__WEBPACK_IMPORTED_MODULE_1__["loadImJoyBasicApp"];\n\n//# sourceURL=webpack://%5Bname%5D/./src/imjoyLoader.js?' - ); - } - }); - }), - (module.exports = factory()); - }, - 967: module => { - var factory; - window, - (factory = function () { - return (function (e) { - var n = {}; - function t(r) { - if (n[r]) return n[r].exports; - var i = (n[r] = { i: r, l: !1, exports: {} }); - return ( - e[r].call(i.exports, i, i.exports, t), (i.l = !0), i.exports - ); - } - return ( - (t.m = e), - (t.c = n), - (t.d = function (e, n, r) { - t.o(e, n) || - Object.defineProperty(e, n, { enumerable: !0, get: r }); - }), - (t.r = function (e) { - 'undefined' != typeof Symbol && - Symbol.toStringTag && - Object.defineProperty(e, Symbol.toStringTag, { - value: 'Module' - }), - Object.defineProperty(e, '__esModule', { value: !0 }); - }), - (t.t = function (e, n) { - if ((1 & n && (e = t(e)), 8 & n)) return e; - if (4 & n && 'object' == typeof e && e && e.__esModule) - return e; - var r = Object.create(null); - if ( - (t.r(r), - Object.defineProperty(r, 'default', { - enumerable: !0, - value: e - }), - 2 & n && 'string' != typeof e) - ) - for (var i in e) - t.d( - r, - i, - function (n) { - return e[n]; - }.bind(null, i) - ); - return r; - }), - (t.n = function (e) { - var n = - e && e.__esModule - ? function () { - return e.default; - } - : function () { - return e; - }; - return t.d(n, 'a', n), n; - }), - (t.o = function (e, n) { - return Object.prototype.hasOwnProperty.call(e, n); - }), - (t.p = ''), - t((t.s = './src/main.js')) - ); - })({ - './node_modules/worker-loader/dist/workers/InlineWorker.js': - function (e, n, t) { - 'use strict'; - var r = window.URL || window.webkitURL; - e.exports = function (e, n) { - try { - try { - var t; - try { - (t = new (window.BlobBuilder || - window.WebKitBlobBuilder || - window.MozBlobBuilder || - window.MSBlobBuilder)()).append(e), - (t = t.getBlob()); - } catch (n) { - t = new Blob([e]); - } - return new Worker(r.createObjectURL(t)); - } catch (n) { - return new Worker( - 'data:application/javascript,' + encodeURIComponent(e) - ); - } - } catch (e) { - if (!n) throw Error('Inline worker is not supported'); - return new Worker(n); - } - }; - }, - './package.json': function (e) { - e.exports = JSON.parse( - '{"name":"imjoy-rpc","version":"0.3.35","description":"Remote procedure calls for ImJoy.","module":"index.js","scripts":{"build":"rm -rf dist && npm run build-umd","build-umd":"webpack --config webpack.config.js --mode development && NODE_ENV=production webpack --config webpack.config.js --mode production --devtool source-map ","watch":"NODE_ENV=production webpack --watch --progress --config webpack.config.js --mode production --devtool source-map","publish-npm":"npm install && npm run build && npm publish","serve":"webpack-dev-server","stats":"webpack --profile --json > stats.json","stats-prod":"webpack --profile --json --mode production > stats-prod.json","analyze":"webpack-bundle-analyzer -p 9999 stats.json","analyze-prod":"webpack-bundle-analyzer -p 9999 stats-prod.json","clean":"rimraf dist/*","deploy":"npm run build && node deploy-site.js","format":"prettier --write \\"{src,tests}/**/**\\"","check-format":"prettier --check \\"{src,tests}/**/**\\"","test":"karma start --single-run --browsers ChromeHeadless,FirefoxHeadless karma.conf.js","test-watch":"karma start --auto-watch --browsers Chrome,FirefoxHeadless karma.conf.js --debug"},"repository":{"type":"git","url":"git+https://github.com/imjoy-team/imjoy-rpc.git"},"keywords":["imjoy","rpc"],"author":"imjoy-team ","license":"MIT","bugs":{"url":"https://github.com/imjoy-team/imjoy-rpc/issues"},"homepage":"https://github.com/imjoy-team/imjoy-rpc","dependencies":{"socket.io-client":"^4.0.1"},"devDependencies":{"@babel/core":"^7.0.0-beta.39","@babel/plugin-syntax-dynamic-import":"^7.0.0-beta.39","@babel/polyfill":"^7.0.0-beta.39","@babel/preset-env":"^7.0.0-beta.39","@types/requirejs":"^2.1.28","babel-core":"^6.26.0","babel-eslint":"^10.1.0","babel-loader":"^8.1.0","babel-runtime":"^6.26.0","chai":"^4.2.0","clean-webpack-plugin":"^0.1.19","copy-webpack-plugin":"^5.0.5","eslint":"^6.8.0","eslint-config-prettier":"^4.2.0","eslint-loader":"^4.0.2","file-loader":"^0.11.2","fs-extra":"^0.30.0","gh-pages":"^2.0.1","html-loader":"^0.5.5","html-webpack-plugin":"^3.2.0","json-loader":"^0.5.4","karma":"^6.3.2","karma-chrome-launcher":"^3.1.0","karma-firefox-launcher":"^1.3.0","karma-mocha":"^1.3.0","karma-spec-reporter":"0.0.32","karma-webpack":"^4.0.2","lerna":"^3.8.0","lodash.debounce":"^4.0.8","mocha":"^7.1.2","postcss":"^6.0.2","prettier":"^1.6.1","rimraf":"^2.6.2","schema-utils":"^0.4.3","style-loader":"^0.18.1","url-loader":"^0.5.9","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.3.2","webpack-cli":"^3.1.2","webpack-dev-server":"^3.1.1","webpack-merge":"^4.1.1","workbox-webpack-plugin":"^4.3.1","worker-loader":"^2.0.0","write-file-webpack-plugin":"^4.5.1"},"eslintConfig":{"globals":{"document":true,"window":true}}}' - ); - }, - './src/main.js': function (e, n, t) { - 'use strict'; - t.r(n), - t.d(n, 'waitForInitialization', function () { - return d; - }), - t.d(n, 'setupRPC', function () { - return _; - }); - var r = t('./src/plugin.webworker.js'), - i = t.n(r), - o = t('./src/pluginIframe.js'), - a = t('./src/utils.js'); - t.d(n, 'loadRequirements', function () { - return a.loadRequirements; - }); - var s = t('./src/rpc.js'); - t.d(n, 'RPC', function () { - return s.RPC; - }), - t.d(n, 'API_VERSION', function () { - return s.API_VERSION; - }); - var c = t('./package.json'); - function l() { - try { - return window.self !== window.top; - } catch (e) { - return !0; - } - } - function d(e) { - if (!l()) - throw new Error( - 'waitForInitialization (imjoy-rpc) should only run inside an iframe.' - ); - (e = e || {}).enable_service_worker && - (Object(a.setupServiceWorker)( - e.base_url, - e.target_origin, - e.cache_requirements - ), - (e.enable_service_worker = !1)), - e.cache_requirements && delete e.cache_requirements; - const n = e.target_origin || '*'; - if ( - e.credential_required && - 'function' != typeof e.verify_credential - ) - throw new Error( - 'Please also provide the `verify_credential` function with `credential_required`.' - ); - if (e.credential_required && '*' === n) - throw new Error( - '`target_origin` was set to `*` with `credential_required=true`, there is a security risk that you may leak the credential to website from other origin. Please specify the `target_origin` explicitly.' - ); - const t = Object(a.randId)(), - r = i => { - if ('message' === i.type && ('*' === n || i.origin === n)) { - if ('initialize' !== i.data.type) - throw new Error(`unrecognized message: ${i.data}`); - { - window.removeEventListener('message', r), - i.data.peer_id !== t && - console.warn( - `${ - i.data.config && i.data.config.name - }: connection peer id mismatch ${ - i.data.peer_id - } !== ${t}` - ); - const o = i.data.config; - '*' !== n && (o.target_origin = n), - e.credential_required - ? e.verify_credential(o.credential).then(e => { - if (!e || !e.auth || e.error) - throw new Error( - 'Failed to verify the credentail:' + - (e && e.error) - ); - (o.auth = e.auth), - _(o).then(() => { - console.log( - 'ImJoy RPC loaded successfully!' - ); - }); - }) - : _(o).then(() => { - console.log('ImJoy RPC loaded successfully!'); - }); - } - } - }; - window.addEventListener('message', r), - parent.postMessage( - { type: 'imjoyRPCReady', config: e, peer_id: t }, - '*' - ); - } - function _(e) { - return ( - ((e = e || {}).name = e.name || Object(a.randId)()), - (e = Object(a.normalizeConfig)(e)).enable_service_worker && - Object(a.setupServiceWorker)( - e.base_url, - e.target_origin, - e.cache_requirements - ), - e.cache_requirements && delete e.cache_requirements, - new Promise((n, t) => { - const r = t => { - const i = t.detail; - e.expose_api_globally && (globalThis.api = i), - n(i), - globalThis.removeEventListener( - 'imjoy_remote_api_ready', - r - ); - }; - if (l()) { - if ('web-worker' === e.type) - try { - !(function (e) { - if (!e.allow_execution) - throw new Error( - 'web-worker plugin can only work with allow_execution=true' - ); - let n = null; - e.broadcastChannel && - (n = new BroadcastChannel(e.broadcastChannel)); - const t = new i.a(), - r = setTimeout(function () { - t.terminate(), - console.warn( - 'Plugin failed to start as a web-worker, running in an iframe instead.' - ), - Object(o.default)(e); - }, 2e3), - s = Object(a.randId)(); - t.addEventListener('message', function (i) { - let o; - const a = i.data; - if ('worker-ready' === a.type) - return ( - t.postMessage({ - type: 'connectRPC', - config: e - }), - void clearTimeout(r) - ); - 'initialized' === a.type - ? ((a.config = Object.assign({}, e, a.config)), - (a.origin = window.location.origin), - (a.peer_id = s)) - : 'imjoy_remote_api_ready' === a.type - ? window.dispatchEvent( - new CustomEvent( - 'imjoy_remote_api_ready', - { detail: null } - ) - ) - : 'cacheRequirements' === a.type && - 'function' == typeof cache_requirements - ? cache_requirements(a.requirements) - : 'disconnect' === a.type - ? t.terminate() - : a.__transferables__ && - ((o = a.__transferables__), - delete a.__transferables__), - n - ? n.postMessage(a) - : parent.postMessage( - a, - e.target_origin || '*', - o - ); - }), - (n || window).addEventListener( - 'message', - function (r) { - if ( - 'message' === r.type && - (n || - '*' === e.target_origin || - r.origin === e.target_origin) - ) { - let n; - const i = r.data; - i.__transferables__ && - ((n = i.__transferables__), - delete i.__transferables__), - i.peer_id === s - ? t.postMessage(i, n) - : e.debug && - console.log( - `connection peer id mismatch ${i.peer_id} !== ${s}` - ); - } - } - ); - })(e); - } catch (n) { - Object(o.default)(e); - } - else { - if ( - ![ - 'rpc-window', - 'rpc-worker', - 'iframe', - 'window' - ].includes(e.type) - ) - return ( - console.error('Unsupported plugin type: ' + e.type), - void t('Unsupported plugin type: ' + e.type) - ); - Object(o.default)(e); - } - globalThis.addEventListener('imjoy_remote_api_ready', r); - } else - t( - new Error('imjoy-rpc should only run inside an iframe.') - ); - }) - ); - } - t.d(n, 'VERSION', function () { - return c.version; - }); - }, - './src/plugin.webworker.js': function (e, n, t) { - e.exports = function () { - return t( - './node_modules/worker-loader/dist/workers/InlineWorker.js' - )( - '/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== \'undefined\' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: \'Module\' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, \'__esModule\', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === \'object\' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, \'default\', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != \'string\') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module[\'default\']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, \'a\', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = "";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = "./src/plugin.webworker.js");\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ "./src/plugin.webworker.js":\n/*!*********************************!*\\\n !*** ./src/plugin.webworker.js ***!\n \\*********************************/\n/*! no exports provided */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n"use strict";\n__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _pluginCore_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pluginCore.js */ "./src/pluginCore.js");\n/* harmony import */ var _rpc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rpc.js */ "./src/rpc.js");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils.js */ "./src/utils.js");\n/**\n * Contains the routines loaded by the plugin Worker under web-browser.\n *\n * Initializes the web environment version of the platform-dependent\n * connection object for the plugin site\n */\n\n\n\n\n// make sure this runs inside a webworker\nif (\n typeof WorkerGlobalScope === "undefined" ||\n !self ||\n !(self instanceof WorkerGlobalScope)\n) {\n throw new Error("This script can only loaded in a webworker");\n}\n\nasync function executeEsModule(content) {\n const dataUri =\n "data:text/javascript;charset=utf-8," + encodeURIComponent(content);\n await import(/* webpackIgnore: true */ dataUri);\n}\n\n/**\n * Connection object provided to the RPC constructor,\n * plugin site implementation for the web-based environment.\n * Global will be then cleared to prevent exposure into the\n * Worker, so we put this local connection object into a closure\n */\nclass Connection extends _utils_js__WEBPACK_IMPORTED_MODULE_2__["MessageEmitter"] {\n constructor(config) {\n super(config && config.debug);\n this.config = config || {};\n }\n connect() {\n self.addEventListener("message", e => {\n this._fire(e.data.type, e.data);\n });\n this.emit({\n type: "initialized",\n config: this.config\n });\n }\n disconnect() {\n this._fire("beforeDisconnect");\n self.close();\n this._fire("disconnected");\n }\n emit(data) {\n let transferables = undefined;\n if (data.__transferables__) {\n transferables = data.__transferables__;\n delete data.__transferables__;\n }\n self.postMessage(data, transferables);\n }\n async execute(code) {\n if (code.type === "requirements") {\n await Object(_utils_js__WEBPACK_IMPORTED_MODULE_2__["loadRequirementsInWebworker"])(code.requirements);\n } else if (code.type === "script") {\n try {\n if (code.attrs.type === "module") {\n await executeEsModule(code.content);\n } else {\n eval(code.content);\n }\n } catch (e) {\n console.error(e.message, e.stack);\n throw e;\n }\n } else {\n throw "unsupported code type.";\n }\n if (code.type === "requirements") {\n self.postMessage({\n type: "cacheRequirements",\n requirements: code.requirements\n });\n }\n }\n}\nconst config = {\n type: "web-worker",\n dedicated_thread: true,\n allow_execution: true,\n lang: "javascript",\n api_version: _rpc_js__WEBPACK_IMPORTED_MODULE_1__["API_VERSION"]\n};\nconst conn = new Connection(config);\nconn.on("connectRPC", data => {\n Object(_pluginCore_js__WEBPACK_IMPORTED_MODULE_0__["connectRPC"])(conn, Object.assign(data.config, config));\n});\nconn.connect();\nself.postMessage({\n type: "worker-ready"\n});\n\n\n/***/ }),\n\n/***/ "./src/pluginCore.js":\n/*!***************************!*\\\n !*** ./src/pluginCore.js ***!\n \\***************************/\n/*! exports provided: connectRPC */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n"use strict";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "connectRPC", function() { return connectRPC; });\n/* harmony import */ var _rpc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rpc.js */ "./src/rpc.js");\n/**\n * Core plugin script loaded into the plugin process/thread.\n *\n * Initializes the plugin-site API global methods.\n */\n\nfunction connectRPC(connection, config) {\n config = config || {};\n const codecs = {};\n const rpc = new _rpc_js__WEBPACK_IMPORTED_MODULE_0__["RPC"](connection, config, codecs);\n rpc.on("getInterface", function () {\n launchConnected();\n });\n rpc.on("remoteReady", function () {\n const api = rpc.getRemote() || {};\n\n api.registerCodec = function (config) {\n if (!config["name"] || !config["encoder"] && !config["decoder"]) {\n throw new Error("Invalid codec format, please make sure you provide a name, type, encoder and decoder.");\n } else {\n if (config.type) {\n for (let k of Object.keys(codecs)) {\n if (codecs[k].type === config.type || k === config.name) {\n delete codecs[k];\n console.warn("Remove duplicated codec: " + k);\n }\n }\n }\n\n codecs[config["name"]] = config;\n }\n };\n\n api.init = function (config) {\n // register a minimal plugin api\n rpc.setInterface({\n setup() {}\n\n }, config);\n };\n\n api.disposeObject = function (obj) {\n rpc.disposeObject(obj);\n };\n\n api.export = function (_interface, config) {\n rpc.setInterface(_interface, config);\n };\n\n api.onLoad = function (handler) {\n handler = checkHandler(handler);\n\n if (connected) {\n handler();\n } else {\n connectedHandlers.push(handler);\n }\n };\n\n api.dispose = function (_interface) {\n rpc.disconnect();\n };\n\n api._rpc = rpc;\n\n if (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) {\n self.api = api;\n self.postMessage({\n type: "imjoy_remote_api_ready"\n });\n self.dispatchEvent(new CustomEvent("imjoy_remote_api_ready", {\n detail: api\n }));\n } else if (typeof window) {\n window.dispatchEvent(new CustomEvent("imjoy_remote_api_ready", {\n detail: api\n }));\n }\n });\n let connected = false;\n const connectedHandlers = [];\n\n const launchConnected = function () {\n if (!connected) {\n connected = true;\n let handler;\n\n while (handler = connectedHandlers.pop()) {\n handler();\n }\n }\n };\n\n const checkHandler = function (handler) {\n const type = typeof handler;\n\n if (type !== "function") {\n const msg = "A function may only be subsribed to the event, " + type + " was provided instead";\n throw new Error(msg);\n }\n\n return handler;\n };\n\n return rpc;\n}\n\n/***/ }),\n\n/***/ "./src/rpc.js":\n/*!********************!*\\\n !*** ./src/rpc.js ***!\n \\********************/\n/*! exports provided: API_VERSION, RPC */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n"use strict";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "API_VERSION", function() { return API_VERSION; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RPC", function() { return RPC; });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.js */ "./src/utils.js");\n/**\n * Contains the RPC object used both by the application\n * site, and by each plugin\n */\n\nconst API_VERSION = "0.2.3";\nconst ArrayBufferView = Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array())).constructor;\n\nfunction _appendBuffer(buffer1, buffer2) {\n const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n tmp.set(new Uint8Array(buffer1), 0);\n tmp.set(new Uint8Array(buffer2), buffer1.byteLength);\n return tmp.buffer;\n}\n\nfunction indexObject(obj, is) {\n if (!is) throw new Error("undefined index");\n if (typeof is === "string") return indexObject(obj, is.split("."));else if (is.length === 0) return obj;else return indexObject(obj[is[0]], is.slice(1));\n}\n/**\n * RPC object represents a single site in the\n * communication protocol between the application and the plugin\n *\n * @param {Object} connection a special object allowing to send\n * and receive messages from the opposite site (basically it\n * should only provide send() and onMessage() methods)\n */\n\n\nclass RPC extends _utils_js__WEBPACK_IMPORTED_MODULE_0__["MessageEmitter"] {\n constructor(connection, config, codecs) {\n super(config && config.debug);\n this._connection = connection;\n this.config = config || {};\n this._codecs = codecs || {};\n this._object_store = {};\n this._method_weakmap = new WeakMap();\n this._object_weakmap = new WeakMap();\n this._local_api = null;\n this._remote_set = false; // make sure there is an execute function\n\n const name = this.config.name;\n\n this._connection.execute = this._connection.execute || function () {\n throw new Error(`connection.execute not implemented (in "${name}")`);\n };\n\n this._store = new ReferenceStore();\n this._method_refs = new ReferenceStore();\n\n this._method_refs.onReady(() => {\n this._fire("remoteIdle");\n });\n\n this._method_refs.onBusy(() => {\n this._fire("remoteBusy");\n });\n\n this._setupMessageHanlders();\n }\n\n init() {\n this._connection.emit({\n type: "initialized",\n config: this.config,\n peer_id: this._connection.peer_id\n });\n }\n\n setConfig(config) {\n if (config) for (const k of Object.keys(config)) {\n this.config[k] = config[k];\n }\n }\n /**\n * Set a handler to be called when received a responce from the\n * remote site reporting that the previously provided interface\n * has been successfully set as remote for that site\n *\n * @param {Function} handler\n */\n\n\n getRemoteCallStack() {\n return this._method_refs.getStack();\n }\n /**\n * @returns {Object} set of remote interface methods\n */\n\n\n getRemote() {\n return this._remote_interface;\n }\n /**\n * Sets the interface of this site making it available to the\n * remote site by sending a message with a set of methods names\n *\n * @param {Object} _interface to set\n */\n\n\n setInterface(_interface, config) {\n config = config || {};\n this.config.name = config.name || this.config.name;\n this.config.description = config.description || this.config.description;\n\n if (this.config.forwarding_functions) {\n for (let func_name of this.config.forwarding_functions) {\n const _remote = this._remote_interface;\n\n if (_remote[func_name]) {\n if (_interface.constructor === Object) {\n if (!_interface[func_name]) {\n _interface[func_name] = (...args) => {\n _remote[func_name](...args);\n };\n }\n } else if (_interface.constructor.constructor === Function) {\n if (!_interface.constructor.prototype[func_name]) {\n _interface.constructor.prototype[func_name] = (...args) => {\n _remote[func_name](...args);\n };\n }\n }\n }\n }\n }\n\n this._local_api = _interface;\n if (!this._remote_set) this._fire("interfaceAvailable");else this.send_interface();\n return new Promise(resolve => {\n this.once("interfaceSetAsRemote", resolve);\n });\n }\n /**\n * Sends the actual interface to the remote site upon it was\n * updated or by a special request of the remote site\n */\n\n\n sendInterface() {\n if (!this._local_api) {\n throw new Error("interface is not set.");\n }\n\n this._encode(this._local_api, true).then(api => {\n this._connection.emit({\n type: "setInterface",\n api: api\n });\n });\n }\n\n _disposeObject(objectId) {\n if (this._object_store[objectId]) {\n delete this._object_store[objectId];\n } else {\n throw new Error(`Object (id=${objectId}) not found.`);\n }\n }\n\n disposeObject(obj) {\n return new Promise((resolve, reject) => {\n if (this._object_weakmap.has(obj)) {\n const objectId = this._object_weakmap.get(obj);\n\n this._connection.once("disposed", data => {\n if (data.error) reject(new Error(data.error));else resolve();\n });\n\n this._connection.emit({\n type: "disposeObject",\n object_id: objectId\n });\n } else {\n throw new Error("Invalid object");\n }\n });\n }\n /**\n * Handles a message from the remote site\n */\n\n\n _setupMessageHanlders() {\n this._connection.on("init", this.init);\n\n this._connection.on("execute", data => {\n Promise.resolve(this._connection.execute(data.code)).then(() => {\n this._connection.emit({\n type: "executed"\n });\n }).catch(e => {\n console.error(e);\n\n this._connection.emit({\n type: "executed",\n error: String(e)\n });\n });\n });\n\n this._connection.on("method", async data => {\n let resolve, reject, method, method_this, args, result;\n\n try {\n if (data.promise) {\n [resolve, reject] = await this._unwrap(data.promise, false);\n }\n\n const _interface = this._object_store[data.object_id];\n method = indexObject(_interface, data.name);\n\n if (data.name.includes(".")) {\n const tmp = data.name.split(".");\n const intf_index = tmp.slice(0, tmp.length - 1).join(".");\n method_this = indexObject(_interface, intf_index);\n } else {\n method_this = _interface;\n }\n\n args = await this._unwrap(data.args, true);\n\n if (data.promise) {\n result = method.apply(method_this, args);\n\n if (result instanceof Promise || method.constructor && method.constructor.name === "AsyncFunction") {\n result.then(resolve).catch(reject);\n } else {\n resolve(result);\n }\n } else {\n method.apply(method_this, args);\n }\n } catch (err) {\n console.error(this.config.name, err);\n\n if (reject) {\n reject(err);\n }\n }\n });\n\n this._connection.on("callback", async data => {\n let resolve, reject, method, args, result;\n\n try {\n if (data.promise) {\n [resolve, reject] = await this._unwrap(data.promise, false);\n }\n\n if (data.promise) {\n method = this._store.fetch(data.id);\n args = await this._unwrap(data.args, true);\n\n if (!method) {\n throw new Error("Callback function can only called once, if you want to call a function for multiple times, please make it as a plugin api function. See https://imjoy.io/docs for more details.");\n }\n\n result = method.apply(null, args);\n\n if (result instanceof Promise || method.constructor && method.constructor.name === "AsyncFunction") {\n result.then(resolve).catch(reject);\n } else {\n resolve(result);\n }\n } else {\n method = this._store.fetch(data.id);\n args = await this._unwrap(data.args, true);\n\n if (!method) {\n throw new Error("Please notice that callback function can only called once, if you want to call a function for multiple times, please make it as a plugin api function. See https://imjoy.io/docs for more details.");\n }\n\n method.apply(null, args);\n }\n } catch (err) {\n console.error(this.config.name, err);\n\n if (reject) {\n reject(err);\n }\n }\n });\n\n this._connection.on("disposeObject", data => {\n try {\n this._disposeObject(data.object_id);\n\n this._connection.emit({\n type: "disposed"\n });\n } catch (e) {\n console.error(e);\n\n this._connection.emit({\n type: "disposed",\n error: String(e)\n });\n }\n });\n\n this._connection.on("setInterface", data => {\n this._setRemoteInterface(data.api);\n });\n\n this._connection.on("getInterface", () => {\n this._fire("getInterface");\n\n if (this._local_api) {\n this.sendInterface();\n } else {\n this.once("interfaceAvailable", () => {\n this.sendInterface();\n });\n }\n });\n\n this._connection.on("interfaceSetAsRemote", () => {\n this._remote_set = true;\n\n this._fire("interfaceSetAsRemote");\n });\n\n this._connection.on("disconnect", () => {\n this._fire("beforeDisconnect");\n\n this._connection.disconnect();\n\n this._fire("disconnected");\n });\n }\n /**\n * Sends a requests to the remote site asking it to provide its\n * current interface\n */\n\n\n requestRemote() {\n this._connection.emit({\n type: "getInterface"\n });\n }\n\n _ndarray(typedArray, shape, dtype) {\n const _dtype = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["typedArrayToDtype"])(typedArray);\n\n if (dtype && dtype !== _dtype) {\n throw "dtype doesn\'t match the type of the array: " + _dtype + " != " + dtype;\n }\n\n shape = shape || [typedArray.length];\n return {\n _rtype: "ndarray",\n _rvalue: typedArray.buffer,\n _rshape: shape,\n _rdtype: _dtype\n };\n }\n /**\n * Sets the new remote interface provided by the other site\n *\n * @param {Array} names list of function names\n */\n\n\n _setRemoteInterface(api) {\n this._decode(api).then(intf => {\n // update existing interface instead of recreating it\n // this will preserve the object reference\n if (this._remote_interface) {\n // clear the interface\n for (let k in this._remote_interface) delete this._remote_interface[k]; // then assign the new interfaces\n\n\n Object.assign(this._remote_interface, intf);\n } else this._remote_interface = intf;\n\n this._fire("remoteReady");\n\n this._reportRemoteSet();\n });\n }\n /**\n * Generates the wrapped function corresponding to a single remote\n * method. When the generated function is called, it will send the\n * corresponding message to the remote site asking it to execute\n * the particular method of its interface\n *\n * @param {String} name of the remote method\n *\n * @returns {Function} wrapped remote method\n */\n\n\n _genRemoteMethod(targetId, name, objectId) {\n const me = this;\n\n const remoteMethod = function () {\n return new Promise(async (resolve, reject) => {\n let id = null;\n\n try {\n id = me._method_refs.put(objectId ? objectId + "/" + name : name);\n\n const wrapped_resolve = function () {\n if (id !== null) me._method_refs.fetch(id);\n return resolve.apply(this, arguments);\n };\n\n const wrapped_reject = function () {\n if (id !== null) me._method_refs.fetch(id);\n return reject.apply(this, arguments);\n };\n\n const encodedPromise = await me._wrap([wrapped_resolve, wrapped_reject]); // store the key id for removing them from the reference store together\n\n wrapped_resolve.__promise_pair = encodedPromise[1]._rvalue;\n wrapped_reject.__promise_pair = encodedPromise[0]._rvalue;\n let args = Array.prototype.slice.call(arguments);\n const argLength = args.length; // if the last argument is an object, mark it as kwargs\n\n const withKwargs = argLength > 0 && typeof args[argLength - 1] === "object" && args[argLength - 1] !== null && args[argLength - 1]._rkwargs;\n if (withKwargs) delete args[argLength - 1]._rkwargs;\n\n if (name === "register" || name === "registerService" || name === "register_service" || name === "export" || name === "on") {\n args = await me._wrap(args, true);\n } else {\n args = await me._wrap(args);\n }\n\n const transferables = args.__transferables__;\n if (transferables) delete args.__transferables__;\n\n me._connection.emit({\n type: "method",\n target_id: targetId,\n name: name,\n object_id: objectId,\n args: args,\n promise: encodedPromise,\n with_kwargs: withKwargs\n }, transferables);\n } catch (e) {\n if (id) me._method_refs.fetch(id);\n reject(`Failed to exectue remote method (interface: ${objectId || me.id}, method: ${name}), error: ${e}`);\n }\n });\n };\n\n remoteMethod.__remote_method = true;\n return remoteMethod;\n }\n /**\n * Sends a responce reporting that interface just provided by the\n * remote site was successfully set by this site as remote\n */\n\n\n _reportRemoteSet() {\n this._connection.emit({\n type: "interfaceSetAsRemote"\n });\n }\n /**\n * Prepares the provided set of remote method arguments for\n * sending to the remote site, replaces all the callbacks with\n * identifiers\n *\n * @param {Array} args to wrap\n *\n * @returns {Array} wrapped arguments\n */\n\n\n async _encode(aObject, asInterface, objectId) {\n const aType = typeof aObject;\n\n if (aType === "number" || aType === "string" || aType === "boolean" || aObject === null || aObject === undefined || aObject instanceof ArrayBuffer) {\n return aObject;\n }\n\n let bObject;\n\n if (typeof aObject === "function") {\n if (asInterface) {\n if (!objectId) throw new Error("objectId is not specified.");\n bObject = {\n _rtype: "interface",\n _rtarget_id: this._connection.peer_id,\n _rintf: objectId,\n _rvalue: asInterface\n };\n\n this._method_weakmap.set(aObject, bObject);\n } else if (this._method_weakmap.has(aObject)) {\n bObject = this._method_weakmap.get(aObject);\n } else {\n const cid = this._store.put(aObject);\n\n bObject = {\n _rtype: "callback",\n _rtarget_id: this._connection.peer_id,\n _rname: aObject.constructor && aObject.constructor.name || cid,\n _rvalue: cid\n };\n }\n\n return bObject;\n } // skip if already encoded\n\n\n if (aObject.constructor instanceof Object && aObject._rtype) {\n // make sure the interface functions are encoded\n if (aObject._rintf) {\n const temp = aObject._rtype;\n delete aObject._rtype;\n bObject = await this._encode(aObject, asInterface, objectId);\n bObject._rtype = temp;\n } else {\n bObject = aObject;\n }\n\n return bObject;\n }\n\n const transferables = [];\n const _transfer = aObject._transfer;\n const isarray = Array.isArray(aObject);\n\n for (let tp of Object.keys(this._codecs)) {\n const codec = this._codecs[tp];\n\n if (codec.encoder && aObject instanceof codec.type) {\n // TODO: what if multiple encoders found\n let encodedObj = await Promise.resolve(codec.encoder(aObject));\n if (encodedObj && !encodedObj._rtype) encodedObj._rtype = codec.name; // encode the functions in the interface object\n\n if (encodedObj && encodedObj._rintf) {\n const temp = encodedObj._rtype;\n delete encodedObj._rtype;\n encodedObj = await this._encode(encodedObj, asInterface, objectId);\n encodedObj._rtype = temp;\n }\n\n bObject = encodedObj;\n return bObject;\n }\n }\n\n if (\n /*global tf*/\n typeof tf !== "undefined" && tf.Tensor && aObject instanceof tf.Tensor) {\n const v_buffer = aObject.dataSync();\n\n if (aObject._transfer || _transfer) {\n transferables.push(v_buffer.buffer);\n delete aObject._transfer;\n }\n\n bObject = {\n _rtype: "ndarray",\n _rvalue: v_buffer.buffer,\n _rshape: aObject.shape,\n _rdtype: aObject.dtype\n };\n } else if (\n /*global nj*/\n typeof nj !== "undefined" && nj.NdArray && aObject instanceof nj.NdArray) {\n const dtype = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["typedArrayToDtype"])(aObject.selection.data);\n\n if (aObject._transfer || _transfer) {\n transferables.push(aObject.selection.data.buffer);\n delete aObject._transfer;\n }\n\n bObject = {\n _rtype: "ndarray",\n _rvalue: aObject.selection.data.buffer,\n _rshape: aObject.shape,\n _rdtype: dtype\n };\n } else if (aObject instanceof Error) {\n console.error(aObject);\n bObject = {\n _rtype: "error",\n _rvalue: aObject.toString()\n };\n } else if (typeof File !== "undefined" && aObject instanceof File) {\n bObject = {\n _rtype: "file",\n _rvalue: aObject,\n _rpath: aObject._path || aObject.webkitRelativePath\n };\n } // send objects supported by structure clone algorithm\n // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n else if (aObject !== Object(aObject) || aObject instanceof Boolean || aObject instanceof String || aObject instanceof Date || aObject instanceof RegExp || aObject instanceof ImageData || typeof FileList !== "undefined" && aObject instanceof FileList || typeof FileSystemDirectoryHandle !== "undefined" && aObject instanceof FileSystemDirectoryHandle || typeof FileSystemFileHandle !== "undefined" && aObject instanceof FileSystemFileHandle || typeof FileSystemHandle !== "undefined" && aObject instanceof FileSystemHandle || typeof FileSystemWritableFileStream !== "undefined" && aObject instanceof FileSystemWritableFileStream) {\n bObject = aObject; // TODO: avoid object such as DynamicPlugin instance.\n } else if (typeof File !== "undefined" && aObject instanceof File) {\n bObject = {\n _rtype: "file",\n _rname: aObject.name,\n _rmime: aObject.type,\n _rvalue: aObject,\n _rpath: aObject._path || aObject.webkitRelativePath\n };\n } else if (aObject instanceof Blob) {\n bObject = {\n _rtype: "blob",\n _rvalue: aObject\n };\n } else if (aObject instanceof ArrayBufferView) {\n if (aObject._transfer || _transfer) {\n transferables.push(aObject.buffer);\n delete aObject._transfer;\n }\n\n const dtype = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["typedArrayToDtype"])(aObject);\n bObject = {\n _rtype: "typedarray",\n _rvalue: aObject.buffer,\n _rdtype: dtype\n };\n } else if (aObject instanceof DataView) {\n if (aObject._transfer || _transfer) {\n transferables.push(aObject.buffer);\n delete aObject._transfer;\n }\n\n bObject = {\n _rtype: "memoryview",\n _rvalue: aObject.buffer\n };\n } else if (aObject instanceof Set) {\n bObject = {\n _rtype: "set",\n _rvalue: await this._encode(Array.from(aObject), asInterface)\n };\n } else if (aObject instanceof Map) {\n bObject = {\n _rtype: "orderedmap",\n _rvalue: await this._encode(Array.from(aObject), asInterface)\n };\n } else if (aObject.constructor instanceof Object || Array.isArray(aObject)) {\n bObject = isarray ? [] : {};\n let keys; // an object/array\n\n if (aObject.constructor === Object || Array.isArray(aObject)) {\n keys = Object.keys(aObject);\n } // a class\n else if (aObject.constructor === Function) {\n throw new Error("Please instantiate the class before exportting it.");\n } // instance of a class\n else if (aObject.constructor.constructor === Function) {\n keys = Object.getOwnPropertyNames(Object.getPrototypeOf(aObject)).concat(Object.keys(aObject)); // TODO: use a proxy object to represent the actual object\n // always encode class instance as interface\n\n asInterface = true;\n } else {\n throw Error("Unsupported interface type");\n }\n\n let hasFunction = false; // encode interfaces\n\n if (aObject._rintf || asInterface) {\n if (!objectId) {\n objectId = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["randId"])();\n this._object_store[objectId] = aObject;\n }\n\n for (let k of keys) {\n if (k === "constructor") continue;\n\n if (k.startsWith("_")) {\n continue;\n }\n\n bObject[k] = await this._encode(aObject[k], typeof asInterface === "string" ? asInterface + "." + k : k, objectId);\n\n if (typeof aObject[k] === "function") {\n hasFunction = true;\n }\n } // object id for dispose the object remotely\n\n\n if (hasFunction) bObject._rintf = objectId; // remove interface when closed\n\n if (aObject.on && typeof aObject.on === "function") {\n aObject.on("close", () => {\n delete this._object_store[objectId];\n });\n }\n } else {\n for (let k of keys) {\n if (["hasOwnProperty", "constructor"].includes(k)) continue;\n bObject[k] = await this._encode(aObject[k]);\n }\n } // for example, browserFS object\n\n } else if (typeof aObject === "object") {\n const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(aObject)).concat(Object.keys(aObject));\n const objectId = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["randId"])();\n\n for (let k of keys) {\n if (["hasOwnProperty", "constructor"].includes(k)) continue; // encode as interface\n\n bObject[k] = await this._encode(aObject[k], k, bObject);\n } // object id, used for dispose the object\n\n\n bObject._rintf = objectId;\n } else {\n throw "imjoy-rpc: Unsupported data type:" + aObject;\n }\n\n if (transferables.length > 0) {\n bObject.__transferables__ = transferables;\n }\n\n if (!bObject) {\n throw new Error("Failed to encode object");\n }\n\n return bObject;\n }\n\n async _decode(aObject, withPromise) {\n if (!aObject) {\n return aObject;\n }\n\n let bObject;\n\n if (aObject["_rtype"]) {\n if (this._codecs[aObject._rtype] && this._codecs[aObject._rtype].decoder) {\n if (aObject._rintf) {\n const temp = aObject._rtype;\n delete aObject._rtype;\n aObject = await this._decode(aObject, withPromise);\n aObject._rtype = temp;\n }\n\n bObject = await Promise.resolve(this._codecs[aObject._rtype].decoder(aObject));\n } else if (aObject._rtype === "callback") {\n bObject = this._genRemoteCallback(aObject._rtarget_id, aObject._rvalue, withPromise);\n } else if (aObject._rtype === "interface") {\n bObject = this._genRemoteMethod(aObject._rtarget_id, aObject._rvalue, aObject._rintf);\n } else if (aObject._rtype === "ndarray") {\n /*global nj tf*/\n //create build array/tensor if used in the plugin\n if (typeof nj !== "undefined" && nj.array) {\n if (Array.isArray(aObject._rvalue)) {\n aObject._rvalue = aObject._rvalue.reduce(_appendBuffer);\n }\n\n bObject = nj.array(new Uint8(aObject._rvalue), aObject._rdtype).reshape(aObject._rshape);\n } else if (typeof tf !== "undefined" && tf.Tensor) {\n if (Array.isArray(aObject._rvalue)) {\n aObject._rvalue = aObject._rvalue.reduce(_appendBuffer);\n }\n\n const arraytype = _utils_js__WEBPACK_IMPORTED_MODULE_0__["dtypeToTypedArray"][aObject._rdtype];\n bObject = tf.tensor(new arraytype(aObject._rvalue), aObject._rshape, aObject._rdtype);\n } else {\n //keep it as regular if transfered to the main app\n bObject = aObject;\n }\n } else if (aObject._rtype === "error") {\n bObject = new Error(aObject._rvalue);\n } else if (aObject._rtype === "file") {\n if (aObject._rvalue instanceof File) {\n bObject = aObject._rvalue; //patch _path\n\n bObject._path = aObject._rpath;\n } else {\n bObject = new File([aObject._rvalue], aObject._rname, {\n type: aObject._rmime\n });\n bObject._path = aObject._rpath;\n }\n } else if (aObject._rtype === "typedarray") {\n const arraytype = _utils_js__WEBPACK_IMPORTED_MODULE_0__["dtypeToTypedArray"][aObject._rdtype];\n if (!arraytype) throw new Error("unsupported dtype: " + aObject._rdtype);\n bObject = new arraytype(aObject._rvalue);\n } else if (aObject._rtype === "memoryview") {\n bObject = new DataView(aObject._rvalue);\n } else if (aObject._rtype === "blob") {\n if (aObject._rvalue instanceof Blob) {\n bObject = aObject._rvalue;\n } else {\n bObject = new Blob([aObject._rvalue], {\n type: aObject._rmime\n });\n }\n } else if (aObject._rtype === "orderedmap") {\n bObject = new Map((await this._decode(aObject._rvalue, withPromise)));\n } else if (aObject._rtype === "set") {\n bObject = new Set((await this._decode(aObject._rvalue, withPromise)));\n } else {\n // make sure all the interface functions are decoded\n if (aObject._rintf) {\n const temp = aObject._rtype;\n delete aObject._rtype;\n bObject = await this._decode(aObject, withPromise);\n bObject._rtype = temp;\n } else bObject = aObject;\n }\n } else if (aObject.constructor === Object || Array.isArray(aObject)) {\n const isarray = Array.isArray(aObject);\n bObject = isarray ? [] : {};\n\n for (let k of Object.keys(aObject)) {\n if (isarray || aObject.hasOwnProperty(k)) {\n const v = aObject[k];\n bObject[k] = await this._decode(v, withPromise);\n }\n }\n } else {\n bObject = aObject;\n }\n\n if (bObject === undefined) {\n throw new Error("Failed to decode object");\n } // store the object id for dispose\n\n\n if (aObject._rintf) {\n this._object_weakmap.set(bObject, aObject._rintf);\n }\n\n return bObject;\n }\n\n async _wrap(args, asInterface) {\n return await this._encode(args, asInterface);\n }\n /**\n * Unwraps the set of arguments delivered from the remote site,\n * replaces all callback identifiers with a function which will\n * initiate sending that callback identifier back to other site\n *\n * @param {Object} args to unwrap\n *\n * @param {Boolean} withPromise is true means this the callback should contain a promise\n *\n * @returns {Array} unwrapped args\n */\n\n\n async _unwrap(args, withPromise) {\n return await this._decode(args, withPromise);\n }\n /**\n * Generates the wrapped function corresponding to a single remote\n * callback. When the generated function is called, it will send\n * the corresponding message to the remote site asking it to\n * execute the particular callback previously saved during a call\n * by the remote site a method from the interface of this site\n *\n * @param {Number} id of the remote callback to execute\n * @param {Number} argNum argument index of the callback\n * @param {Boolean} withPromise is true means this the callback should contain a promise\n *\n * @returns {Function} wrapped remote callback\n */\n\n\n _genRemoteCallback(targetId, cid, withPromise) {\n const me = this;\n let remoteCallback;\n\n if (withPromise) {\n remoteCallback = function () {\n return new Promise(async (resolve, reject) => {\n const args = await me._wrap(Array.prototype.slice.call(arguments));\n const argLength = args.length; // if the last argument is an object, mark it as kwargs\n\n const withKwargs = argLength > 0 && typeof args[argLength - 1] === "object" && args[argLength - 1] !== null && args[argLength - 1]._rkwargs;\n if (withKwargs) delete args[argLength - 1]._rkwargs;\n const transferables = args.__transferables__;\n if (transferables) delete args.__transferables__;\n const encodedPromise = await me._wrap([resolve, reject]); // store the key id for removing them from the reference store together\n\n resolve.__promise_pair = encodedPromise[1]._rvalue;\n reject.__promise_pair = encodedPromise[0]._rvalue;\n\n try {\n me._connection.emit({\n type: "callback",\n target_id: targetId,\n id: cid,\n args: args,\n promise: encodedPromise,\n with_kwargs: withKwargs\n }, transferables);\n } catch (e) {\n reject(`Failed to exectue remote callback ( id: ${cid}).`);\n }\n });\n };\n\n return remoteCallback;\n } else {\n remoteCallback = async function () {\n const args = await me._wrap(Array.prototype.slice.call(arguments));\n const argLength = args.length; // if the last argument is an object, mark it as kwargs\n\n const withKwargs = argLength > 0 && typeof args[argLength - 1] === "object" && args[argLength - 1] !== null && args[argLength - 1]._rkwargs;\n if (withKwargs) delete args[argLength - 1]._rkwargs;\n const transferables = args.__transferables__;\n if (transferables) delete args.__transferables__;\n return me._connection.emit({\n type: "callback",\n target_id: targetId,\n id: cid,\n args: args,\n with_kwargs: withKwargs\n }, transferables);\n };\n\n return remoteCallback;\n }\n }\n\n reset() {\n this._event_handlers = {};\n this._once_handlers = {};\n this._remote_interface = null;\n this._object_store = {};\n this._method_weakmap = new WeakMap();\n this._object_weakmap = new WeakMap();\n this._local_api = null;\n this._store = new ReferenceStore();\n this._method_refs = new ReferenceStore();\n }\n /**\n * Sends the notification message and breaks the connection\n */\n\n\n disconnect() {\n this._connection.emit({\n type: "disconnect"\n });\n\n this.reset();\n setTimeout(() => {\n this._connection.disconnect();\n }, 2000);\n }\n\n}\n/**\n * ReferenceStore is a special object which stores other objects\n * and provides the references (number) instead. This reference\n * may then be sent over a json-based communication channel (IPC\n * to another Node.js process or a message to the Worker). Other\n * site may then provide the reference in the responce message\n * implying the given object should be activated.\n *\n * Primary usage for the ReferenceStore is a storage for the\n * callbacks, which therefore makes it possible to initiate a\n * callback execution by the opposite site (which normally cannot\n * directly execute functions over the communication channel).\n *\n * Each stored object can only be fetched once and is not\n * available for the second time. Each stored object must be\n * fetched, since otherwise it will remain stored forever and\n * consume memory.\n *\n * Stored object indeces are simply the numbers, which are however\n * released along with the objects, and are later reused again (in\n * order to postpone the overflow, which should not likely happen,\n * but anyway).\n */\n\nclass ReferenceStore {\n constructor() {\n this._store = {}; // stored object\n\n this._indices = [0]; // smallest available indices\n\n this._readyHandler = function () {};\n\n this._busyHandler = function () {};\n\n this._readyHandler();\n }\n /**\n * call handler when the store is empty\n *\n * @param {FUNCTION} id of a handler\n */\n\n\n onReady(readyHandler) {\n this._readyHandler = readyHandler || function () {};\n }\n /**\n * call handler when the store is not empty\n *\n * @param {FUNCTION} id of a handler\n */\n\n\n onBusy(busyHandler) {\n this._busyHandler = busyHandler || function () {};\n }\n /**\n * get the length of the store\n *\n */\n\n\n getStack() {\n return Object.keys(this._store).length;\n }\n /**\n * @function _genId() generates the new reference id\n *\n * @returns {Number} smallest available id and reserves it\n */\n\n\n _genId() {\n let id;\n\n if (this._indices.length === 1) {\n id = this._indices[0]++;\n } else {\n id = this._indices.shift();\n }\n\n return id;\n }\n /**\n * Releases the given reference id so that it will be available by\n * another object stored\n *\n * @param {Number} id to release\n */\n\n\n _releaseId(id) {\n for (let i = 0; i < this._indices.length; i++) {\n if (id < this._indices[i]) {\n this._indices.splice(i, 0, id);\n\n break;\n }\n } // cleaning-up the sequence tail\n\n\n for (let i = this._indices.length - 1; i >= 0; i--) {\n if (this._indices[i] - 1 === this._indices[i - 1]) {\n this._indices.pop();\n } else {\n break;\n }\n }\n }\n /**\n * Stores the given object and returns the refernce id instead\n *\n * @param {Object} obj to store\n *\n * @returns {Number} reference id of the stored object\n */\n\n\n put(obj) {\n if (this._busyHandler && Object.keys(this._store).length === 0) {\n this._busyHandler();\n }\n\n const id = this._genId();\n\n this._store[id] = obj;\n return id;\n }\n /**\n * Retrieves previously stored object and releases its reference\n *\n * @param {Number} id of an object to retrieve\n */\n\n\n fetch(id) {\n const obj = this._store[id];\n\n if (obj && !obj.__remote_method) {\n delete this._store[id];\n\n this._releaseId(id);\n\n if (this._readyHandler && Object.keys(this._store).length === 0) {\n this._readyHandler();\n }\n }\n\n if (obj && obj.__promise_pair) {\n this.fetch(obj.__promise_pair);\n }\n\n return obj;\n }\n\n}\n\n/***/ }),\n\n/***/ "./src/utils.js":\n/*!**********************!*\\\n !*** ./src/utils.js ***!\n \\**********************/\n/*! exports provided: randId, dtypeToTypedArray, loadRequirementsInWindow, loadRequirementsInWebworker, loadRequirements, normalizeConfig, typedArrayToDtypeMapping, typedArrayToDtype, cacheRequirements, setupServiceWorker, urlJoin, MessageEmitter */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n"use strict";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randId", function() { return randId; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dtypeToTypedArray", function() { return dtypeToTypedArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadRequirementsInWindow", function() { return loadRequirementsInWindow; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadRequirementsInWebworker", function() { return loadRequirementsInWebworker; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadRequirements", function() { return loadRequirements; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalizeConfig", function() { return normalizeConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "typedArrayToDtypeMapping", function() { return typedArrayToDtypeMapping; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "typedArrayToDtype", function() { return typedArrayToDtype; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cacheRequirements", function() { return cacheRequirements; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setupServiceWorker", function() { return setupServiceWorker; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "urlJoin", function() { return urlJoin; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MessageEmitter", function() { return MessageEmitter; });\nfunction randId() {\n return Math.random().toString(36).substr(2, 10) + new Date().getTime();\n}\nconst dtypeToTypedArray = {\n int8: Int8Array,\n int16: Int16Array,\n int32: Int32Array,\n uint8: Uint8Array,\n uint16: Uint16Array,\n uint32: Uint32Array,\n float32: Float32Array,\n float64: Float64Array,\n array: Array\n};\nasync function loadRequirementsInWindow(requirements) {\n function _importScript(url) {\n //url is URL of external file, implementationCode is the code\n //to be called from the file, location is the location to\n //insert the