scratch-vm 4.8.6 → 4.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file. See
4
4
  [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.8.7](https://github.com/scratchfoundation/scratch-vm/compare/v4.8.6...v4.8.7) (2024-09-29)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **deps:** update dependency scratch-render-fonts to v1.0.106 ([32cd4d2](https://github.com/scratchfoundation/scratch-vm/commit/32cd4d219fe287af947d9d04e76f37765c90257e))
12
+
6
13
  ## [4.8.6](https://github.com/scratchfoundation/scratch-vm/compare/v4.8.5...v4.8.6) (2024-09-28)
7
14
 
8
15
 
@@ -571,6 +571,8 @@ module.exports = require("minilog");
571
571
  /******/
572
572
  /************************************************************************/
573
573
  var __webpack_exports__ = {};
574
+ // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
575
+ (() => {
574
576
  /*!***************************************************!*\
575
577
  !*** ./src/extension-support/extension-worker.js ***!
576
578
  \***************************************************/
@@ -623,6 +625,8 @@ const extensionWorker = new ExtensionWorker();
623
625
  global.Scratch.extensions = {
624
626
  register: extensionWorker.register.bind(extensionWorker)
625
627
  };
628
+ })();
629
+
626
630
  /******/ return __webpack_exports__;
627
631
  /******/ })()
628
632
  ;
@@ -1 +1 @@
1
- {"version":3,"file":"extension-worker.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAHA;AAAA;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC1OA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC7GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AChBA;AACA;AAEA;;;;;;;;;;;ACHA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACvBA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://VirtualMachine/webpack/universalModuleDefinition","webpack://VirtualMachine/./src/dispatch/shared-dispatch.js","webpack://VirtualMachine/./src/dispatch/worker-dispatch.js","webpack://VirtualMachine/./src/extension-support/argument-type.js","webpack://VirtualMachine/./src/extension-support/block-type.js","webpack://VirtualMachine/./src/extension-support/target-type.js","webpack://VirtualMachine/./src/util/log.js","webpack://VirtualMachine/external commonjs \"minilog\"","webpack://VirtualMachine/webpack/bootstrap","webpack://VirtualMachine/./src/extension-support/extension-worker.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VirtualMachine\"] = factory();\n\telse\n\t\troot[\"VirtualMachine\"] = factory();\n})(global, () => {\nreturn ","const log = require('../util/log');\n\n/**\n * @typedef {object} DispatchCallMessage - a message to the dispatch system representing a service method call\n * @property {*} responseId - send a response message with this response ID. See {@link DispatchResponseMessage}\n * @property {string} service - the name of the service to be called\n * @property {string} method - the name of the method to be called\n * @property {Array|undefined} args - the arguments to be passed to the method\n */\n\n/**\n * @typedef {object} DispatchResponseMessage - a message to the dispatch system representing the results of a call\n * @property {*} responseId - a copy of the response ID from the call which generated this response\n * @property {*|undefined} error - if this is truthy, then it contains results from a failed call (such as an exception)\n * @property {*|undefined} result - if error is not truthy, then this contains the return value of the call (if any)\n */\n\n/**\n * @typedef {DispatchCallMessage|DispatchResponseMessage} DispatchMessage\n * Any message to the dispatch system.\n */\n\n/**\n * The SharedDispatch class is responsible for dispatch features shared by\n * {@link CentralDispatch} and {@link WorkerDispatch}.\n */\nclass SharedDispatch {\n constructor () {\n /**\n * List of callback registrations for promises waiting for a response from a call to a service on another\n * worker. A callback registration is an array of [resolve,reject] Promise functions.\n * Calls to local services don't enter this list.\n * @type {Array.<Function[]>}\n */\n this.callbacks = [];\n\n /**\n * The next response ID to be used.\n * @type {int}\n */\n this.nextResponseId = 0;\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.call('vm', 'setData', 'cat', 42);\n * // this finds the worker for the 'vm' service, then on that worker calls:\n * vm.setData('cat', 42);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n call (service, method, ...args) {\n return this.transferCall(service, method, null, ...args);\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.transferCall('vm', 'setData', [myArrayBuffer], 'cat', myArrayBuffer);\n * // this finds the worker for the 'vm' service, transfers `myArrayBuffer` to it, then on that worker calls:\n * vm.setData('cat', myArrayBuffer);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n transferCall (service, method, transfer, ...args) {\n try {\n const {provider, isRemote} = this._getServiceProvider(service);\n if (provider) {\n if (isRemote) {\n return this._remoteTransferCall(provider, service, method, transfer, ...args);\n }\n\n // TODO: verify correct `this` after switching from apply to spread\n // eslint-disable-next-line prefer-spread\n const result = provider[method].apply(provider, args);\n return Promise.resolve(result);\n }\n return Promise.reject(new Error(`Service not found: ${service}`));\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n /**\n * Check if a particular service lives on another worker.\n * @param {string} service - the service to check.\n * @returns {boolean} - true if the service is remote (calls must cross a Worker boundary), false otherwise.\n * @private\n */\n _isRemoteService (service) {\n return this._getServiceProvider(service).isRemote;\n }\n\n /**\n * Like {@link call}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteCall (provider, service, method, ...args) {\n return this._remoteTransferCall(provider, service, method, null, ...args);\n }\n\n /**\n * Like {@link transferCall}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteTransferCall (provider, service, method, transfer, ...args) {\n return new Promise((resolve, reject) => {\n const responseId = this._storeCallbacks(resolve, reject);\n\n /** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */\n if ((args.length > 0) && (typeof args[args.length - 1].yield === 'function')) {\n args.pop();\n }\n\n if (transfer) {\n provider.postMessage({service, method, responseId, args}, transfer);\n } else {\n provider.postMessage({service, method, responseId, args});\n }\n });\n }\n\n /**\n * Store callback functions pending a response message.\n * @param {Function} resolve - function to call if the service method returns.\n * @param {Function} reject - function to call if the service method throws.\n * @returns {*} - a unique response ID for this set of callbacks. See {@link _deliverResponse}.\n * @protected\n */\n _storeCallbacks (resolve, reject) {\n const responseId = this.nextResponseId++;\n this.callbacks[responseId] = [resolve, reject];\n return responseId;\n }\n\n /**\n * Deliver call response from a worker. This should only be called as the result of a message from a worker.\n * @param {int} responseId - the response ID of the callback set to call.\n * @param {DispatchResponseMessage} message - the message containing the response value(s).\n * @protected\n */\n _deliverResponse (responseId, message) {\n try {\n const [resolve, reject] = this.callbacks[responseId];\n delete this.callbacks[responseId];\n if (message.error) {\n reject(message.error);\n } else {\n resolve(message.result);\n }\n } catch (e) {\n log.error(`Dispatch callback failed: ${JSON.stringify(e)}`);\n }\n }\n\n /**\n * Handle a message event received from a connected worker.\n * @param {Worker} worker - the worker which sent the message, or the global object if running in a worker.\n * @param {MessageEvent} event - the message event to be handled.\n * @protected\n */\n _onMessage (worker, event) {\n /** @type {DispatchMessage} */\n const message = event.data;\n message.args = message.args || [];\n let promise;\n if (message.service) {\n if (message.service === 'dispatch') {\n promise = this._onDispatchMessage(worker, message);\n } else {\n promise = this.call(message.service, message.method, ...message.args);\n }\n } else if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch caught malformed message from a worker: ${JSON.stringify(event)}`);\n } else {\n this._deliverResponse(message.responseId, message);\n }\n if (promise) {\n if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch message missing required response ID: ${JSON.stringify(event)}`);\n } else {\n promise.then(\n result => worker.postMessage({responseId: message.responseId, result}),\n error => worker.postMessage({responseId: message.responseId, error})\n );\n }\n }\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @abstract\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n throw new Error(`Could not get provider for ${service}: _getServiceProvider not implemented`);\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @abstract\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @private\n */\n _onDispatchMessage (worker, message) {\n throw new Error(`Unimplemented dispatch message handler cannot handle ${message.method} method`);\n }\n}\n\nmodule.exports = SharedDispatch;\n","const SharedDispatch = require('./shared-dispatch');\n\nconst log = require('../util/log');\n\n/**\n * This class provides a Worker with the means to participate in the message dispatch system managed by CentralDispatch.\n * From any context in the messaging system, the dispatcher's \"call\" method can call any method on any \"service\"\n * provided in any participating context. The dispatch system will forward function arguments and return values across\n * worker boundaries as needed.\n * @see {CentralDispatch}\n */\nclass WorkerDispatch extends SharedDispatch {\n constructor () {\n super();\n\n /**\n * This promise will be resolved when we have successfully connected to central dispatch.\n * @type {Promise}\n * @see {waitForConnection}\n * @private\n */\n this._connectionPromise = new Promise(resolve => {\n this._onConnect = resolve;\n });\n\n /**\n * Map of service name to local service provider.\n * If a service is not listed here, it is assumed to be provided by another context (another Worker or the main\n * thread).\n * @see {setService}\n * @type {object}\n */\n this.services = {};\n\n this._onMessage = this._onMessage.bind(this, self);\n if (typeof self !== 'undefined') {\n self.onmessage = this._onMessage;\n }\n }\n\n /**\n * @returns {Promise} a promise which will resolve upon connection to central dispatch. If you need to make a call\n * immediately on \"startup\" you can attach a 'then' to this promise.\n * @example\n * dispatch.waitForConnection.then(() => {\n * dispatch.call('myService', 'hello');\n * })\n */\n get waitForConnection () {\n return this._connectionPromise;\n }\n\n /**\n * Set a local object as the global provider of the specified service.\n * WARNING: Any method on the provider can be called from any worker within the dispatch system.\n * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'.\n * @param {object} provider - a local object which provides this service.\n * @returns {Promise} - a promise which will resolve once the service is registered.\n */\n setService (service, provider) {\n if (Object.prototype.hasOwnProperty.call(this.services, service)) {\n log.warn(`Worker dispatch replacing existing service provider for ${service}`);\n }\n this.services[service] = provider;\n return this.waitForConnection.then(() => this._remoteCall(self, 'dispatch', 'setService', service));\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @override\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n // if we don't have a local service by this name, contact central dispatch by calling `postMessage` on self\n const provider = this.services[service];\n return {\n provider: provider || self,\n isRemote: !provider\n };\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @override\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @protected\n */\n _onDispatchMessage (worker, message) {\n let promise;\n switch (message.method) {\n case 'handshake':\n promise = this._onConnect();\n break;\n case 'terminate':\n // Don't close until next tick, after sending confirmation back\n setTimeout(() => self.close(), 0);\n promise = Promise.resolve();\n break;\n default:\n log.error(`Worker dispatch received message for unknown method: ${message.method}`);\n }\n return promise;\n }\n}\n\nmodule.exports = new WorkerDispatch();\n","/**\n * Block argument types\n * @enum {string}\n */\nconst ArgumentType = {\n /**\n * Numeric value with angle picker\n */\n ANGLE: 'angle',\n\n /**\n * Boolean value with hexagonal placeholder\n */\n BOOLEAN: 'Boolean',\n\n /**\n * Numeric value with color picker\n */\n COLOR: 'color',\n\n /**\n * Numeric value with text field\n */\n NUMBER: 'number',\n\n /**\n * String value with text field\n */\n STRING: 'string',\n\n /**\n * String value with matrix field\n */\n MATRIX: 'matrix',\n\n /**\n * MIDI note number with note picker (piano) field\n */\n NOTE: 'note',\n\n /**\n * Inline image on block (as part of the label)\n */\n IMAGE: 'image'\n};\n\nmodule.exports = ArgumentType;\n","/**\n * Types of block\n * @enum {string}\n */\nconst BlockType = {\n /**\n * Boolean reporter with hexagonal shape\n */\n BOOLEAN: 'Boolean',\n\n /**\n * A button (not an actual block) for some special action, like making a variable\n */\n BUTTON: 'button',\n\n /**\n * Command block\n */\n COMMAND: 'command',\n\n /**\n * Specialized command block which may or may not run a child branch\n * The thread continues with the next block whether or not a child branch ran.\n */\n CONDITIONAL: 'conditional',\n\n /**\n * Specialized hat block with no implementation function\n * This stack only runs if the corresponding event is emitted by other code.\n */\n EVENT: 'event',\n\n /**\n * Hat block which conditionally starts a block stack\n */\n HAT: 'hat',\n\n /**\n * Specialized command block which may or may not run a child branch\n * If a child branch runs, the thread evaluates the loop block again.\n */\n LOOP: 'loop',\n\n /**\n * General reporter with numeric or string value\n */\n REPORTER: 'reporter'\n};\n\nmodule.exports = BlockType;\n","/**\n * Default types of Target supported by the VM\n * @enum {string}\n */\nconst TargetType = {\n /**\n * Rendered target which can move, change costumes, etc.\n */\n SPRITE: 'sprite',\n\n /**\n * Rendered target which cannot move but can change backdrops\n */\n STAGE: 'stage'\n};\n\nmodule.exports = TargetType;\n","const minilog = require('minilog');\nminilog.enable();\n\nmodule.exports = minilog('vm');\n","module.exports = require(\"minilog\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/* eslint-env worker */\n\nconst ArgumentType = require('../extension-support/argument-type');\nconst BlockType = require('../extension-support/block-type');\nconst dispatch = require('../dispatch/worker-dispatch');\nconst TargetType = require('../extension-support/target-type');\n\nclass ExtensionWorker {\n constructor () {\n this.nextExtensionId = 0;\n\n this.initialRegistrations = [];\n\n dispatch.waitForConnection.then(() => {\n dispatch.call('extensions', 'allocateWorker').then(x => {\n const [id, extension] = x;\n this.workerId = id;\n\n try {\n importScripts(extension);\n\n const initialRegistrations = this.initialRegistrations;\n this.initialRegistrations = null;\n\n Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));\n } catch (e) {\n dispatch.call('extensions', 'onWorkerInit', id, e);\n }\n });\n });\n\n this.extensions = [];\n }\n\n register (extensionObject) {\n const extensionId = this.nextExtensionId++;\n this.extensions.push(extensionObject);\n const serviceName = `extension.${this.workerId}.${extensionId}`;\n const promise = dispatch.setService(serviceName, extensionObject)\n .then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));\n if (this.initialRegistrations) {\n this.initialRegistrations.push(promise);\n }\n return promise;\n }\n}\n\nglobal.Scratch = global.Scratch || {};\nglobal.Scratch.ArgumentType = ArgumentType;\nglobal.Scratch.BlockType = BlockType;\nglobal.Scratch.TargetType = TargetType;\n\n/**\n * Expose only specific parts of the worker to extensions.\n */\nconst extensionWorker = new ExtensionWorker();\nglobal.Scratch.extensions = {\n register: extensionWorker.register.bind(extensionWorker)\n};\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"extension-worker.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAHA;AAAA;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC1OA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC7GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AChBA;AACA;AAEA;;;;;;;;;;;ACHA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACvBA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://VirtualMachine/webpack/universalModuleDefinition","webpack://VirtualMachine/./src/dispatch/shared-dispatch.js","webpack://VirtualMachine/./src/dispatch/worker-dispatch.js","webpack://VirtualMachine/./src/extension-support/argument-type.js","webpack://VirtualMachine/./src/extension-support/block-type.js","webpack://VirtualMachine/./src/extension-support/target-type.js","webpack://VirtualMachine/./src/util/log.js","webpack://VirtualMachine/external commonjs \"minilog\"","webpack://VirtualMachine/webpack/bootstrap","webpack://VirtualMachine/./src/extension-support/extension-worker.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VirtualMachine\"] = factory();\n\telse\n\t\troot[\"VirtualMachine\"] = factory();\n})(global, () => {\nreturn ","const log = require('../util/log');\n\n/**\n * @typedef {object} DispatchCallMessage - a message to the dispatch system representing a service method call\n * @property {*} responseId - send a response message with this response ID. See {@link DispatchResponseMessage}\n * @property {string} service - the name of the service to be called\n * @property {string} method - the name of the method to be called\n * @property {Array|undefined} args - the arguments to be passed to the method\n */\n\n/**\n * @typedef {object} DispatchResponseMessage - a message to the dispatch system representing the results of a call\n * @property {*} responseId - a copy of the response ID from the call which generated this response\n * @property {*|undefined} error - if this is truthy, then it contains results from a failed call (such as an exception)\n * @property {*|undefined} result - if error is not truthy, then this contains the return value of the call (if any)\n */\n\n/**\n * @typedef {DispatchCallMessage|DispatchResponseMessage} DispatchMessage\n * Any message to the dispatch system.\n */\n\n/**\n * The SharedDispatch class is responsible for dispatch features shared by\n * {@link CentralDispatch} and {@link WorkerDispatch}.\n */\nclass SharedDispatch {\n constructor () {\n /**\n * List of callback registrations for promises waiting for a response from a call to a service on another\n * worker. A callback registration is an array of [resolve,reject] Promise functions.\n * Calls to local services don't enter this list.\n * @type {Array.<Function[]>}\n */\n this.callbacks = [];\n\n /**\n * The next response ID to be used.\n * @type {int}\n */\n this.nextResponseId = 0;\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.call('vm', 'setData', 'cat', 42);\n * // this finds the worker for the 'vm' service, then on that worker calls:\n * vm.setData('cat', 42);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n call (service, method, ...args) {\n return this.transferCall(service, method, null, ...args);\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.transferCall('vm', 'setData', [myArrayBuffer], 'cat', myArrayBuffer);\n * // this finds the worker for the 'vm' service, transfers `myArrayBuffer` to it, then on that worker calls:\n * vm.setData('cat', myArrayBuffer);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n transferCall (service, method, transfer, ...args) {\n try {\n const {provider, isRemote} = this._getServiceProvider(service);\n if (provider) {\n if (isRemote) {\n return this._remoteTransferCall(provider, service, method, transfer, ...args);\n }\n\n // TODO: verify correct `this` after switching from apply to spread\n // eslint-disable-next-line prefer-spread\n const result = provider[method].apply(provider, args);\n return Promise.resolve(result);\n }\n return Promise.reject(new Error(`Service not found: ${service}`));\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n /**\n * Check if a particular service lives on another worker.\n * @param {string} service - the service to check.\n * @returns {boolean} - true if the service is remote (calls must cross a Worker boundary), false otherwise.\n * @private\n */\n _isRemoteService (service) {\n return this._getServiceProvider(service).isRemote;\n }\n\n /**\n * Like {@link call}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteCall (provider, service, method, ...args) {\n return this._remoteTransferCall(provider, service, method, null, ...args);\n }\n\n /**\n * Like {@link transferCall}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteTransferCall (provider, service, method, transfer, ...args) {\n return new Promise((resolve, reject) => {\n const responseId = this._storeCallbacks(resolve, reject);\n\n /** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */\n if ((args.length > 0) && (typeof args[args.length - 1].yield === 'function')) {\n args.pop();\n }\n\n if (transfer) {\n provider.postMessage({service, method, responseId, args}, transfer);\n } else {\n provider.postMessage({service, method, responseId, args});\n }\n });\n }\n\n /**\n * Store callback functions pending a response message.\n * @param {Function} resolve - function to call if the service method returns.\n * @param {Function} reject - function to call if the service method throws.\n * @returns {*} - a unique response ID for this set of callbacks. See {@link _deliverResponse}.\n * @protected\n */\n _storeCallbacks (resolve, reject) {\n const responseId = this.nextResponseId++;\n this.callbacks[responseId] = [resolve, reject];\n return responseId;\n }\n\n /**\n * Deliver call response from a worker. This should only be called as the result of a message from a worker.\n * @param {int} responseId - the response ID of the callback set to call.\n * @param {DispatchResponseMessage} message - the message containing the response value(s).\n * @protected\n */\n _deliverResponse (responseId, message) {\n try {\n const [resolve, reject] = this.callbacks[responseId];\n delete this.callbacks[responseId];\n if (message.error) {\n reject(message.error);\n } else {\n resolve(message.result);\n }\n } catch (e) {\n log.error(`Dispatch callback failed: ${JSON.stringify(e)}`);\n }\n }\n\n /**\n * Handle a message event received from a connected worker.\n * @param {Worker} worker - the worker which sent the message, or the global object if running in a worker.\n * @param {MessageEvent} event - the message event to be handled.\n * @protected\n */\n _onMessage (worker, event) {\n /** @type {DispatchMessage} */\n const message = event.data;\n message.args = message.args || [];\n let promise;\n if (message.service) {\n if (message.service === 'dispatch') {\n promise = this._onDispatchMessage(worker, message);\n } else {\n promise = this.call(message.service, message.method, ...message.args);\n }\n } else if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch caught malformed message from a worker: ${JSON.stringify(event)}`);\n } else {\n this._deliverResponse(message.responseId, message);\n }\n if (promise) {\n if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch message missing required response ID: ${JSON.stringify(event)}`);\n } else {\n promise.then(\n result => worker.postMessage({responseId: message.responseId, result}),\n error => worker.postMessage({responseId: message.responseId, error})\n );\n }\n }\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @abstract\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n throw new Error(`Could not get provider for ${service}: _getServiceProvider not implemented`);\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @abstract\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @private\n */\n _onDispatchMessage (worker, message) {\n throw new Error(`Unimplemented dispatch message handler cannot handle ${message.method} method`);\n }\n}\n\nmodule.exports = SharedDispatch;\n","const SharedDispatch = require('./shared-dispatch');\n\nconst log = require('../util/log');\n\n/**\n * This class provides a Worker with the means to participate in the message dispatch system managed by CentralDispatch.\n * From any context in the messaging system, the dispatcher's \"call\" method can call any method on any \"service\"\n * provided in any participating context. The dispatch system will forward function arguments and return values across\n * worker boundaries as needed.\n * @see {CentralDispatch}\n */\nclass WorkerDispatch extends SharedDispatch {\n constructor () {\n super();\n\n /**\n * This promise will be resolved when we have successfully connected to central dispatch.\n * @type {Promise}\n * @see {waitForConnection}\n * @private\n */\n this._connectionPromise = new Promise(resolve => {\n this._onConnect = resolve;\n });\n\n /**\n * Map of service name to local service provider.\n * If a service is not listed here, it is assumed to be provided by another context (another Worker or the main\n * thread).\n * @see {setService}\n * @type {object}\n */\n this.services = {};\n\n this._onMessage = this._onMessage.bind(this, self);\n if (typeof self !== 'undefined') {\n self.onmessage = this._onMessage;\n }\n }\n\n /**\n * @returns {Promise} a promise which will resolve upon connection to central dispatch. If you need to make a call\n * immediately on \"startup\" you can attach a 'then' to this promise.\n * @example\n * dispatch.waitForConnection.then(() => {\n * dispatch.call('myService', 'hello');\n * })\n */\n get waitForConnection () {\n return this._connectionPromise;\n }\n\n /**\n * Set a local object as the global provider of the specified service.\n * WARNING: Any method on the provider can be called from any worker within the dispatch system.\n * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'.\n * @param {object} provider - a local object which provides this service.\n * @returns {Promise} - a promise which will resolve once the service is registered.\n */\n setService (service, provider) {\n if (Object.prototype.hasOwnProperty.call(this.services, service)) {\n log.warn(`Worker dispatch replacing existing service provider for ${service}`);\n }\n this.services[service] = provider;\n return this.waitForConnection.then(() => this._remoteCall(self, 'dispatch', 'setService', service));\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @override\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n // if we don't have a local service by this name, contact central dispatch by calling `postMessage` on self\n const provider = this.services[service];\n return {\n provider: provider || self,\n isRemote: !provider\n };\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @override\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @protected\n */\n _onDispatchMessage (worker, message) {\n let promise;\n switch (message.method) {\n case 'handshake':\n promise = this._onConnect();\n break;\n case 'terminate':\n // Don't close until next tick, after sending confirmation back\n setTimeout(() => self.close(), 0);\n promise = Promise.resolve();\n break;\n default:\n log.error(`Worker dispatch received message for unknown method: ${message.method}`);\n }\n return promise;\n }\n}\n\nmodule.exports = new WorkerDispatch();\n","/**\n * Block argument types\n * @enum {string}\n */\nconst ArgumentType = {\n /**\n * Numeric value with angle picker\n */\n ANGLE: 'angle',\n\n /**\n * Boolean value with hexagonal placeholder\n */\n BOOLEAN: 'Boolean',\n\n /**\n * Numeric value with color picker\n */\n COLOR: 'color',\n\n /**\n * Numeric value with text field\n */\n NUMBER: 'number',\n\n /**\n * String value with text field\n */\n STRING: 'string',\n\n /**\n * String value with matrix field\n */\n MATRIX: 'matrix',\n\n /**\n * MIDI note number with note picker (piano) field\n */\n NOTE: 'note',\n\n /**\n * Inline image on block (as part of the label)\n */\n IMAGE: 'image'\n};\n\nmodule.exports = ArgumentType;\n","/**\n * Types of block\n * @enum {string}\n */\nconst BlockType = {\n /**\n * Boolean reporter with hexagonal shape\n */\n BOOLEAN: 'Boolean',\n\n /**\n * A button (not an actual block) for some special action, like making a variable\n */\n BUTTON: 'button',\n\n /**\n * Command block\n */\n COMMAND: 'command',\n\n /**\n * Specialized command block which may or may not run a child branch\n * The thread continues with the next block whether or not a child branch ran.\n */\n CONDITIONAL: 'conditional',\n\n /**\n * Specialized hat block with no implementation function\n * This stack only runs if the corresponding event is emitted by other code.\n */\n EVENT: 'event',\n\n /**\n * Hat block which conditionally starts a block stack\n */\n HAT: 'hat',\n\n /**\n * Specialized command block which may or may not run a child branch\n * If a child branch runs, the thread evaluates the loop block again.\n */\n LOOP: 'loop',\n\n /**\n * General reporter with numeric or string value\n */\n REPORTER: 'reporter'\n};\n\nmodule.exports = BlockType;\n","/**\n * Default types of Target supported by the VM\n * @enum {string}\n */\nconst TargetType = {\n /**\n * Rendered target which can move, change costumes, etc.\n */\n SPRITE: 'sprite',\n\n /**\n * Rendered target which cannot move but can change backdrops\n */\n STAGE: 'stage'\n};\n\nmodule.exports = TargetType;\n","const minilog = require('minilog');\nminilog.enable();\n\nmodule.exports = minilog('vm');\n","module.exports = require(\"minilog\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/* eslint-env worker */\n\nconst ArgumentType = require('../extension-support/argument-type');\nconst BlockType = require('../extension-support/block-type');\nconst dispatch = require('../dispatch/worker-dispatch');\nconst TargetType = require('../extension-support/target-type');\n\nclass ExtensionWorker {\n constructor () {\n this.nextExtensionId = 0;\n\n this.initialRegistrations = [];\n\n dispatch.waitForConnection.then(() => {\n dispatch.call('extensions', 'allocateWorker').then(x => {\n const [id, extension] = x;\n this.workerId = id;\n\n try {\n importScripts(extension);\n\n const initialRegistrations = this.initialRegistrations;\n this.initialRegistrations = null;\n\n Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));\n } catch (e) {\n dispatch.call('extensions', 'onWorkerInit', id, e);\n }\n });\n });\n\n this.extensions = [];\n }\n\n register (extensionObject) {\n const extensionId = this.nextExtensionId++;\n this.extensions.push(extensionObject);\n const serviceName = `extension.${this.workerId}.${extensionId}`;\n const promise = dispatch.setService(serviceName, extensionObject)\n .then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));\n if (this.initialRegistrations) {\n this.initialRegistrations.push(promise);\n }\n return promise;\n }\n}\n\nglobal.Scratch = global.Scratch || {};\nglobal.Scratch.ArgumentType = ArgumentType;\nglobal.Scratch.BlockType = BlockType;\nglobal.Scratch.TargetType = TargetType;\n\n/**\n * Expose only specific parts of the worker to extensions.\n */\nconst extensionWorker = new ExtensionWorker();\nglobal.Scratch.extensions = {\n register: extensionWorker.register.bind(extensionWorker)\n};\n"],"names":[],"sourceRoot":""}
@@ -32707,7 +32707,7 @@ module.exports = require("uuid");
32707
32707
  /***/ ((module) => {
32708
32708
 
32709
32709
  "use strict";
32710
- module.exports = /*#__PURE__*/JSON.parse('{"name":"scratch-vm","version":"4.8.5","description":"Virtual Machine for Scratch 3.0","author":"Massachusetts Institute of Technology","license":"BSD-3-Clause","homepage":"https://github.com/scratchfoundation/scratch-vm#readme","repository":{"type":"git","url":"https://github.com/scratchfoundation/scratch-vm.git","sha":"cc7ea7014be0df46b52b4e31d593ea64b79cdeb6"},"main":"./dist/node/scratch-vm.js","browser":"./dist/web/scratch-vm.js","exports":{"webpack":"./src/index.js","browser":"./dist/web/scratch-vm.js","node":"./dist/node/scratch-vm.js","default":"./src/index.js"},"scripts":{"build":"npm run docs && webpack --progress","coverage":"tap ./test/{unit,integration}/*.js --coverage --coverage-report=lcov","docs":"jsdoc -c .jsdoc.json","i18n:src":"mkdirp translations/core && format-message extract --out-file translations/core/en.json src/extensions/**/index.js","i18n:push":"tx-push-src scratch-editor extensions translations/core/en.json","lint":"eslint . && format-message lint src/**/*.js","prepare":"husky install","prepublish":"in-publish && npm run build || not-in-publish","start":"webpack serve","tap":"tap ./test/{unit,integration}/*.js","tap:unit":"tap ./test/unit/*.js","tap:integration":"tap ./test/integration/*.js","test":"npm run lint && npm run tap","watch":"webpack --progress --watch","version":"json -f package.json -I -e \\"this.repository.sha = \'$(git log -n1 --pretty=format:%H)\'\\""},"config":{"commitizen":{"path":"cz-conventional-changelog"}},"browserslist":["Chrome >= 63","Edge >= 15","Firefox >= 57","Safari >= 11"],"tap":{"branches":60,"functions":70,"lines":70,"statements":70},"dependencies":{"@vernier/godirect":"^1.5.0","arraybuffer-loader":"^1.0.6","atob":"^2.1.2","btoa":"^1.2.1","canvas-toBlob":"^1.0.0","decode-html":"^2.0.0","diff-match-patch":"^1.0.4","format-message":"^6.2.1","htmlparser2":"^3.10.0","immutable":"^3.8.1","jszip":"^3.1.5","minilog":"^3.1.0","scratch-audio":"^1.0.6","scratch-parser":"^5.1.1","scratch-render":"^1.0.232","scratch-sb1-converter":"^1.0.0","scratch-storage":"^2.3.5","scratch-svg-renderer":"2.5.2","scratch-translate-extension-languages":"^1.0.0","text-encoding":"^0.7.0","uuid":"^8.3.2","web-worker":"^1.3.0"},"devDependencies":{"@babel/core":"7.25.2","@babel/eslint-parser":"7.25.1","@babel/preset-env":"7.25.4","@commitlint/cli":"17.8.1","@commitlint/config-conventional":"17.8.1","adm-zip":"0.4.11","babel-loader":"9.2.1","callsite":"1.0.0","copy-webpack-plugin":"4.6.0","docdash":"1.2.0","eslint":"8.57.1","eslint-config-scratch":"9.0.9","expose-loader":"1.0.3","file-loader":"6.2.0","format-message-cli":"6.2.4","husky":"8.0.3","in-publish":"2.0.1","js-md5":"0.7.3","jsdoc":"3.6.11","json":"^9.0.4","pngjs":"3.4.0","scratch-blocks":"1.1.206","scratch-l10n":"3.18.324","scratch-render-fonts":"1.0.105","scratch-semantic-release-config":"1.0.16","scratch-webpack-configuration":"1.6.0","script-loader":"0.7.2","semantic-release":"19.0.5","stats.js":"0.17.0","tap":"16.3.10","webpack":"5.94.0","webpack-cli":"4.10.0","webpack-dev-server":"3.11.3"}}');
32710
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"scratch-vm","version":"4.8.6","description":"Virtual Machine for Scratch 3.0","author":"Massachusetts Institute of Technology","license":"BSD-3-Clause","homepage":"https://github.com/scratchfoundation/scratch-vm#readme","repository":{"type":"git","url":"https://github.com/scratchfoundation/scratch-vm.git","sha":"6f31da7edfefb97bd96d173277372093e8ab3903"},"main":"./dist/node/scratch-vm.js","browser":"./dist/web/scratch-vm.js","exports":{"webpack":"./src/index.js","browser":"./dist/web/scratch-vm.js","node":"./dist/node/scratch-vm.js","default":"./src/index.js"},"scripts":{"build":"npm run docs && webpack --progress","coverage":"tap ./test/{unit,integration}/*.js --coverage --coverage-report=lcov","docs":"jsdoc -c .jsdoc.json","i18n:src":"mkdirp translations/core && format-message extract --out-file translations/core/en.json src/extensions/**/index.js","i18n:push":"tx-push-src scratch-editor extensions translations/core/en.json","lint":"eslint . && format-message lint src/**/*.js","prepare":"husky install","prepublish":"in-publish && npm run build || not-in-publish","start":"webpack serve","tap":"tap ./test/{unit,integration}/*.js","tap:unit":"tap ./test/unit/*.js","tap:integration":"tap ./test/integration/*.js","test":"npm run lint && npm run tap","watch":"webpack --progress --watch","version":"json -f package.json -I -e \\"this.repository.sha = \'$(git log -n1 --pretty=format:%H)\'\\""},"config":{"commitizen":{"path":"cz-conventional-changelog"}},"browserslist":["Chrome >= 63","Edge >= 15","Firefox >= 57","Safari >= 11"],"tap":{"branches":60,"functions":70,"lines":70,"statements":70},"dependencies":{"@vernier/godirect":"^1.5.0","arraybuffer-loader":"^1.0.6","atob":"^2.1.2","btoa":"^1.2.1","canvas-toBlob":"^1.0.0","decode-html":"^2.0.0","diff-match-patch":"^1.0.4","format-message":"^6.2.1","htmlparser2":"^3.10.0","immutable":"^3.8.1","jszip":"^3.1.5","minilog":"^3.1.0","scratch-audio":"^1.0.6","scratch-parser":"^5.1.1","scratch-render":"^1.0.232","scratch-sb1-converter":"^1.0.0","scratch-storage":"^2.3.5","scratch-svg-renderer":"2.5.2","scratch-translate-extension-languages":"^1.0.0","text-encoding":"^0.7.0","uuid":"^8.3.2","web-worker":"^1.3.0"},"devDependencies":{"@babel/core":"7.25.2","@babel/eslint-parser":"7.25.1","@babel/preset-env":"7.25.4","@commitlint/cli":"17.8.1","@commitlint/config-conventional":"17.8.1","adm-zip":"0.4.11","babel-loader":"9.2.1","callsite":"1.0.0","copy-webpack-plugin":"4.6.0","docdash":"1.2.0","eslint":"8.57.1","eslint-config-scratch":"9.0.9","expose-loader":"1.0.3","file-loader":"6.2.0","format-message-cli":"6.2.4","husky":"8.0.3","in-publish":"2.0.1","js-md5":"0.7.3","jsdoc":"3.6.11","json":"^9.0.4","pngjs":"3.4.0","scratch-blocks":"1.1.206","scratch-l10n":"3.18.324","scratch-render-fonts":"1.0.106","scratch-semantic-release-config":"1.0.16","scratch-webpack-configuration":"1.6.0","script-loader":"0.7.2","semantic-release":"19.0.5","stats.js":"0.17.0","tap":"16.3.10","webpack":"5.95.0","webpack-cli":"4.10.0","webpack-dev-server":"3.11.3"}}');
32711
32711
 
32712
32712
  /***/ })
32713
32713
 
@@ -1156,6 +1156,8 @@ module.exports = logger;
1156
1156
  /******/
1157
1157
  /************************************************************************/
1158
1158
  var __webpack_exports__ = {};
1159
+ // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
1160
+ (() => {
1159
1161
  /*!***************************************************!*\
1160
1162
  !*** ./src/extension-support/extension-worker.js ***!
1161
1163
  \***************************************************/
@@ -1208,6 +1210,8 @@ const extensionWorker = new ExtensionWorker();
1208
1210
  __webpack_require__.g.Scratch.extensions = {
1209
1211
  register: extensionWorker.register.bind(extensionWorker)
1210
1212
  };
1213
+ })();
1214
+
1211
1215
  /******/ return __webpack_exports__;
1212
1216
  /******/ })()
1213
1217
  ;
@@ -1 +1 @@
1
- {"version":3,"file":"extension-worker.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAHA;AAAA;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC1OA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC7GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AChBA;AACA;AAEA;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACPA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://VirtualMachine/webpack/universalModuleDefinition","webpack://VirtualMachine/./src/dispatch/shared-dispatch.js","webpack://VirtualMachine/./src/dispatch/worker-dispatch.js","webpack://VirtualMachine/./src/extension-support/argument-type.js","webpack://VirtualMachine/./src/extension-support/block-type.js","webpack://VirtualMachine/./src/extension-support/target-type.js","webpack://VirtualMachine/./src/util/log.js","webpack://VirtualMachine/./node_modules/microee/index.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/filter.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/minilog.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/transform.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/array.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/console.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/color.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/minilog.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/util.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/index.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/jquery_simple.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/localstorage.js","webpack://VirtualMachine/webpack/bootstrap","webpack://VirtualMachine/webpack/runtime/global","webpack://VirtualMachine/./src/extension-support/extension-worker.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VirtualMachine\"] = factory();\n\telse\n\t\troot[\"VirtualMachine\"] = factory();\n})(self, () => {\nreturn ","const log = require('../util/log');\n\n/**\n * @typedef {object} DispatchCallMessage - a message to the dispatch system representing a service method call\n * @property {*} responseId - send a response message with this response ID. See {@link DispatchResponseMessage}\n * @property {string} service - the name of the service to be called\n * @property {string} method - the name of the method to be called\n * @property {Array|undefined} args - the arguments to be passed to the method\n */\n\n/**\n * @typedef {object} DispatchResponseMessage - a message to the dispatch system representing the results of a call\n * @property {*} responseId - a copy of the response ID from the call which generated this response\n * @property {*|undefined} error - if this is truthy, then it contains results from a failed call (such as an exception)\n * @property {*|undefined} result - if error is not truthy, then this contains the return value of the call (if any)\n */\n\n/**\n * @typedef {DispatchCallMessage|DispatchResponseMessage} DispatchMessage\n * Any message to the dispatch system.\n */\n\n/**\n * The SharedDispatch class is responsible for dispatch features shared by\n * {@link CentralDispatch} and {@link WorkerDispatch}.\n */\nclass SharedDispatch {\n constructor () {\n /**\n * List of callback registrations for promises waiting for a response from a call to a service on another\n * worker. A callback registration is an array of [resolve,reject] Promise functions.\n * Calls to local services don't enter this list.\n * @type {Array.<Function[]>}\n */\n this.callbacks = [];\n\n /**\n * The next response ID to be used.\n * @type {int}\n */\n this.nextResponseId = 0;\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.call('vm', 'setData', 'cat', 42);\n * // this finds the worker for the 'vm' service, then on that worker calls:\n * vm.setData('cat', 42);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n call (service, method, ...args) {\n return this.transferCall(service, method, null, ...args);\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.transferCall('vm', 'setData', [myArrayBuffer], 'cat', myArrayBuffer);\n * // this finds the worker for the 'vm' service, transfers `myArrayBuffer` to it, then on that worker calls:\n * vm.setData('cat', myArrayBuffer);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n transferCall (service, method, transfer, ...args) {\n try {\n const {provider, isRemote} = this._getServiceProvider(service);\n if (provider) {\n if (isRemote) {\n return this._remoteTransferCall(provider, service, method, transfer, ...args);\n }\n\n // TODO: verify correct `this` after switching from apply to spread\n // eslint-disable-next-line prefer-spread\n const result = provider[method].apply(provider, args);\n return Promise.resolve(result);\n }\n return Promise.reject(new Error(`Service not found: ${service}`));\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n /**\n * Check if a particular service lives on another worker.\n * @param {string} service - the service to check.\n * @returns {boolean} - true if the service is remote (calls must cross a Worker boundary), false otherwise.\n * @private\n */\n _isRemoteService (service) {\n return this._getServiceProvider(service).isRemote;\n }\n\n /**\n * Like {@link call}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteCall (provider, service, method, ...args) {\n return this._remoteTransferCall(provider, service, method, null, ...args);\n }\n\n /**\n * Like {@link transferCall}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteTransferCall (provider, service, method, transfer, ...args) {\n return new Promise((resolve, reject) => {\n const responseId = this._storeCallbacks(resolve, reject);\n\n /** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */\n if ((args.length > 0) && (typeof args[args.length - 1].yield === 'function')) {\n args.pop();\n }\n\n if (transfer) {\n provider.postMessage({service, method, responseId, args}, transfer);\n } else {\n provider.postMessage({service, method, responseId, args});\n }\n });\n }\n\n /**\n * Store callback functions pending a response message.\n * @param {Function} resolve - function to call if the service method returns.\n * @param {Function} reject - function to call if the service method throws.\n * @returns {*} - a unique response ID for this set of callbacks. See {@link _deliverResponse}.\n * @protected\n */\n _storeCallbacks (resolve, reject) {\n const responseId = this.nextResponseId++;\n this.callbacks[responseId] = [resolve, reject];\n return responseId;\n }\n\n /**\n * Deliver call response from a worker. This should only be called as the result of a message from a worker.\n * @param {int} responseId - the response ID of the callback set to call.\n * @param {DispatchResponseMessage} message - the message containing the response value(s).\n * @protected\n */\n _deliverResponse (responseId, message) {\n try {\n const [resolve, reject] = this.callbacks[responseId];\n delete this.callbacks[responseId];\n if (message.error) {\n reject(message.error);\n } else {\n resolve(message.result);\n }\n } catch (e) {\n log.error(`Dispatch callback failed: ${JSON.stringify(e)}`);\n }\n }\n\n /**\n * Handle a message event received from a connected worker.\n * @param {Worker} worker - the worker which sent the message, or the global object if running in a worker.\n * @param {MessageEvent} event - the message event to be handled.\n * @protected\n */\n _onMessage (worker, event) {\n /** @type {DispatchMessage} */\n const message = event.data;\n message.args = message.args || [];\n let promise;\n if (message.service) {\n if (message.service === 'dispatch') {\n promise = this._onDispatchMessage(worker, message);\n } else {\n promise = this.call(message.service, message.method, ...message.args);\n }\n } else if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch caught malformed message from a worker: ${JSON.stringify(event)}`);\n } else {\n this._deliverResponse(message.responseId, message);\n }\n if (promise) {\n if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch message missing required response ID: ${JSON.stringify(event)}`);\n } else {\n promise.then(\n result => worker.postMessage({responseId: message.responseId, result}),\n error => worker.postMessage({responseId: message.responseId, error})\n );\n }\n }\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @abstract\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n throw new Error(`Could not get provider for ${service}: _getServiceProvider not implemented`);\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @abstract\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @private\n */\n _onDispatchMessage (worker, message) {\n throw new Error(`Unimplemented dispatch message handler cannot handle ${message.method} method`);\n }\n}\n\nmodule.exports = SharedDispatch;\n","const SharedDispatch = require('./shared-dispatch');\n\nconst log = require('../util/log');\n\n/**\n * This class provides a Worker with the means to participate in the message dispatch system managed by CentralDispatch.\n * From any context in the messaging system, the dispatcher's \"call\" method can call any method on any \"service\"\n * provided in any participating context. The dispatch system will forward function arguments and return values across\n * worker boundaries as needed.\n * @see {CentralDispatch}\n */\nclass WorkerDispatch extends SharedDispatch {\n constructor () {\n super();\n\n /**\n * This promise will be resolved when we have successfully connected to central dispatch.\n * @type {Promise}\n * @see {waitForConnection}\n * @private\n */\n this._connectionPromise = new Promise(resolve => {\n this._onConnect = resolve;\n });\n\n /**\n * Map of service name to local service provider.\n * If a service is not listed here, it is assumed to be provided by another context (another Worker or the main\n * thread).\n * @see {setService}\n * @type {object}\n */\n this.services = {};\n\n this._onMessage = this._onMessage.bind(this, self);\n if (typeof self !== 'undefined') {\n self.onmessage = this._onMessage;\n }\n }\n\n /**\n * @returns {Promise} a promise which will resolve upon connection to central dispatch. If you need to make a call\n * immediately on \"startup\" you can attach a 'then' to this promise.\n * @example\n * dispatch.waitForConnection.then(() => {\n * dispatch.call('myService', 'hello');\n * })\n */\n get waitForConnection () {\n return this._connectionPromise;\n }\n\n /**\n * Set a local object as the global provider of the specified service.\n * WARNING: Any method on the provider can be called from any worker within the dispatch system.\n * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'.\n * @param {object} provider - a local object which provides this service.\n * @returns {Promise} - a promise which will resolve once the service is registered.\n */\n setService (service, provider) {\n if (Object.prototype.hasOwnProperty.call(this.services, service)) {\n log.warn(`Worker dispatch replacing existing service provider for ${service}`);\n }\n this.services[service] = provider;\n return this.waitForConnection.then(() => this._remoteCall(self, 'dispatch', 'setService', service));\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @override\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n // if we don't have a local service by this name, contact central dispatch by calling `postMessage` on self\n const provider = this.services[service];\n return {\n provider: provider || self,\n isRemote: !provider\n };\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @override\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @protected\n */\n _onDispatchMessage (worker, message) {\n let promise;\n switch (message.method) {\n case 'handshake':\n promise = this._onConnect();\n break;\n case 'terminate':\n // Don't close until next tick, after sending confirmation back\n setTimeout(() => self.close(), 0);\n promise = Promise.resolve();\n break;\n default:\n log.error(`Worker dispatch received message for unknown method: ${message.method}`);\n }\n return promise;\n }\n}\n\nmodule.exports = new WorkerDispatch();\n","/**\n * Block argument types\n * @enum {string}\n */\nconst ArgumentType = {\n /**\n * Numeric value with angle picker\n */\n ANGLE: 'angle',\n\n /**\n * Boolean value with hexagonal placeholder\n */\n BOOLEAN: 'Boolean',\n\n /**\n * Numeric value with color picker\n */\n COLOR: 'color',\n\n /**\n * Numeric value with text field\n */\n NUMBER: 'number',\n\n /**\n * String value with text field\n */\n STRING: 'string',\n\n /**\n * String value with matrix field\n */\n MATRIX: 'matrix',\n\n /**\n * MIDI note number with note picker (piano) field\n */\n NOTE: 'note',\n\n /**\n * Inline image on block (as part of the label)\n */\n IMAGE: 'image'\n};\n\nmodule.exports = ArgumentType;\n","/**\n * Types of block\n * @enum {string}\n */\nconst BlockType = {\n /**\n * Boolean reporter with hexagonal shape\n */\n BOOLEAN: 'Boolean',\n\n /**\n * A button (not an actual block) for some special action, like making a variable\n */\n BUTTON: 'button',\n\n /**\n * Command block\n */\n COMMAND: 'command',\n\n /**\n * Specialized command block which may or may not run a child branch\n * The thread continues with the next block whether or not a child branch ran.\n */\n CONDITIONAL: 'conditional',\n\n /**\n * Specialized hat block with no implementation function\n * This stack only runs if the corresponding event is emitted by other code.\n */\n EVENT: 'event',\n\n /**\n * Hat block which conditionally starts a block stack\n */\n HAT: 'hat',\n\n /**\n * Specialized command block which may or may not run a child branch\n * If a child branch runs, the thread evaluates the loop block again.\n */\n LOOP: 'loop',\n\n /**\n * General reporter with numeric or string value\n */\n REPORTER: 'reporter'\n};\n\nmodule.exports = BlockType;\n","/**\n * Default types of Target supported by the VM\n * @enum {string}\n */\nconst TargetType = {\n /**\n * Rendered target which can move, change costumes, etc.\n */\n SPRITE: 'sprite',\n\n /**\n * Rendered target which cannot move but can change backdrops\n */\n STAGE: 'stage'\n};\n\nmodule.exports = TargetType;\n","const minilog = require('minilog');\nminilog.enable();\n\nmodule.exports = minilog('vm');\n","function M() { this._events = {}; }\nM.prototype = {\n on: function(ev, cb) {\n this._events || (this._events = {});\n var e = this._events;\n (e[ev] || (e[ev] = [])).push(cb);\n return this;\n },\n removeListener: function(ev, cb) {\n var e = this._events[ev] || [], i;\n for(i = e.length-1; i >= 0 && e[i]; i--){\n if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); }\n }\n },\n removeAllListeners: function(ev) {\n if(!ev) { this._events = {}; }\n else { this._events[ev] && (this._events[ev] = []); }\n },\n listeners: function(ev) {\n return (this._events ? this._events[ev] || [] : []);\n },\n emit: function(ev) {\n this._events || (this._events = {});\n var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || [];\n for(i = e.length-1; i >= 0 && e[i]; i--){\n e[i].apply(this, args);\n }\n return this;\n },\n when: function(ev, cb) {\n return this.once(ev, cb, true);\n },\n once: function(ev, cb, when) {\n if(!cb) return this;\n function c() {\n if(!when) this.removeListener(ev, c);\n if(cb.apply(this, arguments) && when) this.removeListener(ev, c);\n }\n c.cb = cb;\n this.on(ev, c);\n return this;\n }\n};\nM.mixin = function(dest) {\n var o = M.prototype, k;\n for (k in o) {\n o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);\n }\n};\nmodule.exports = M;\n","// default filter\nvar Transform = require('./transform.js');\n\nvar levelMap = { debug: 1, info: 2, warn: 3, error: 4 };\n\nfunction Filter() {\n this.enabled = true;\n this.defaultResult = true;\n this.clear();\n}\n\nTransform.mixin(Filter);\n\n// allow all matching, with level >= given level\nFilter.prototype.allow = function(name, level) {\n this._white.push({ n: name, l: levelMap[level] });\n return this;\n};\n\n// deny all matching, with level <= given level\nFilter.prototype.deny = function(name, level) {\n this._black.push({ n: name, l: levelMap[level] });\n return this;\n};\n\nFilter.prototype.clear = function() {\n this._white = [];\n this._black = [];\n return this;\n};\n\nfunction test(rule, name) {\n // use .test for RegExps\n return (rule.n.test ? rule.n.test(name) : rule.n == name);\n};\n\nFilter.prototype.test = function(name, level) {\n var i, len = Math.max(this._white.length, this._black.length);\n for(i = 0; i < len; i++) {\n if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) {\n return true;\n }\n if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) {\n return false;\n }\n }\n return this.defaultResult;\n};\n\nFilter.prototype.write = function(name, level, args) {\n if(!this.enabled || this.test(name, level)) {\n return this.emit('item', name, level, args);\n }\n};\n\nmodule.exports = Filter;\n","var Transform = require('./transform.js'),\n Filter = require('./filter.js');\n\nvar log = new Transform(),\n slice = Array.prototype.slice;\n\nexports = module.exports = function create(name) {\n var o = function() { log.write(name, undefined, slice.call(arguments)); return o; };\n o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; };\n o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; };\n o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; };\n o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; };\n o.log = o.debug; // for interface compliance with Node and browser consoles\n o.suggest = exports.suggest;\n o.format = log.format;\n return o;\n};\n\n// filled in separately\nexports.defaultBackend = exports.defaultFormatter = null;\n\nexports.pipe = function(dest) {\n return log.pipe(dest);\n};\n\nexports.end = exports.unpipe = exports.disable = function(from) {\n return log.unpipe(from);\n};\n\nexports.Transform = Transform;\nexports.Filter = Filter;\n// this is the default filter that's applied when .enable() is called normally\n// you can bypass it completely and set up your own pipes\nexports.suggest = new Filter();\n\nexports.enable = function() {\n if(exports.defaultFormatter) {\n return log.pipe(exports.suggest) // filter\n .pipe(exports.defaultFormatter) // formatter\n .pipe(exports.defaultBackend); // backend\n }\n return log.pipe(exports.suggest) // filter\n .pipe(exports.defaultBackend); // formatter\n};\n\n","var microee = require('microee');\n\n// Implements a subset of Node's stream.Transform - in a cross-platform manner.\nfunction Transform() {}\n\nmicroee.mixin(Transform);\n\n// The write() signature is different from Node's\n// --> makes it much easier to work with objects in logs.\n// One of the lessons from v1 was that it's better to target\n// a good browser rather than the lowest common denominator\n// internally.\n// If you want to use external streams, pipe() to ./stringify.js first.\nTransform.prototype.write = function(name, level, args) {\n this.emit('item', name, level, args);\n};\n\nTransform.prototype.end = function() {\n this.emit('end');\n this.removeAllListeners();\n};\n\nTransform.prototype.pipe = function(dest) {\n var s = this;\n // prevent double piping\n s.emit('unpipe', dest);\n // tell the dest that it's being piped to\n dest.emit('pipe', s);\n\n function onItem() {\n dest.write.apply(dest, Array.prototype.slice.call(arguments));\n }\n function onEnd() { !dest._isStdio && dest.end(); }\n\n s.on('item', onItem);\n s.on('end', onEnd);\n\n s.when('unpipe', function(from) {\n var match = (from === dest) || typeof from == 'undefined';\n if(match) {\n s.removeListener('item', onItem);\n s.removeListener('end', onEnd);\n dest.emit('unpipe');\n }\n return match;\n });\n\n return dest;\n};\n\nTransform.prototype.unpipe = function(from) {\n this.emit('unpipe', from);\n return this;\n};\n\nTransform.prototype.format = function(dest) {\n throw new Error([\n 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:',\n 'var Minilog = require(\\'minilog\\');',\n 'Minilog',\n ' .pipe(Minilog.backends.console.formatClean)',\n ' .pipe(Minilog.backends.console);'].join('\\n'));\n};\n\nTransform.mixin = function(dest) {\n var o = Transform.prototype, k;\n for (k in o) {\n o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);\n }\n};\n\nmodule.exports = Transform;\n","var Transform = require('../common/transform.js'),\n cache = [ ];\n\nvar logger = new Transform();\n\nlogger.write = function(name, level, args) {\n cache.push([ name, level, args ]);\n};\n\n// utility functions\nlogger.get = function() { return cache; };\nlogger.empty = function() { cache = []; };\n\nmodule.exports = logger;\n","var Transform = require('../common/transform.js');\n\nvar newlines = /\\n+$/,\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var i = args.length-1;\n if (typeof console === 'undefined' || !console.log) {\n return;\n }\n if(console.log.apply) {\n return console.log.apply(console, [name, level].concat(args));\n } else if(JSON && JSON.stringify) {\n // console.log.apply is undefined in IE8 and IE9\n // for IE8/9: make console.log at least a bit less awful\n if(args[i] && typeof args[i] == 'string') {\n args[i] = args[i].replace(newlines, '');\n }\n try {\n for(i = 0; i < args.length; i++) {\n args[i] = JSON.stringify(args[i]);\n }\n } catch(e) {}\n console.log(args.join(' '));\n }\n};\n\nlogger.formatters = ['color', 'minilog'];\nlogger.color = require('./formatters/color.js');\nlogger.minilog = require('./formatters/minilog.js');\n\nmodule.exports = logger;\n","var Transform = require('../../common/transform.js'),\n color = require('./util.js');\n\nvar colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var fn = console.log;\n if(console[level] && console[level].apply) {\n fn = console[level];\n fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args));\n }\n};\n\n// NOP, because piping the formatted logs can only cause trouble.\nlogger.pipe = function() { };\n\nmodule.exports = logger;\n","var Transform = require('../../common/transform.js'),\n color = require('./util.js'),\n colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var fn = console.log;\n if(level != 'debug' && console[level]) {\n fn = console[level];\n }\n\n var subset = [], i = 0;\n if(level != 'info') {\n for(; i < args.length; i++) {\n if(typeof args[i] != 'string') break;\n }\n fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i)));\n } else {\n fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args));\n }\n};\n\n// NOP, because piping the formatted logs can only cause trouble.\nlogger.pipe = function() { };\n\nmodule.exports = logger;\n","var hex = {\n black: '#000',\n red: '#c23621',\n green: '#25bc26',\n yellow: '#bbbb00',\n blue: '#492ee1',\n magenta: '#d338d3',\n cyan: '#33bbc8',\n gray: '#808080',\n purple: '#708'\n};\nfunction color(fg, isInverse) {\n if(isInverse) {\n return 'color: #fff; background: '+hex[fg]+';';\n } else {\n return 'color: '+hex[fg]+';';\n }\n}\n\nmodule.exports = color;\n","var Minilog = require('../common/minilog.js');\n\nvar oldEnable = Minilog.enable,\n oldDisable = Minilog.disable,\n isChrome = (typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent)),\n console = require('./console.js');\n\n// Use a more capable logging backend if on Chrome\nMinilog.defaultBackend = (isChrome ? console.minilog : console);\n\n// apply enable inputs from localStorage and from the URL\nif(typeof window != 'undefined') {\n try {\n Minilog.enable(JSON.parse(window.localStorage['minilogSettings']));\n } catch(e) {}\n if(window.location && window.location.search) {\n var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search);\n match && Minilog.enable(decodeURIComponent(match[1]));\n }\n}\n\n// Make enable also add to localStorage\nMinilog.enable = function() {\n oldEnable.call(Minilog, true);\n try { window.localStorage['minilogSettings'] = JSON.stringify(true); } catch(e) {}\n return this;\n};\n\nMinilog.disable = function() {\n oldDisable.call(Minilog);\n try { delete window.localStorage.minilogSettings; } catch(e) {}\n return this;\n};\n\nexports = module.exports = Minilog;\n\nexports.backends = {\n array: require('./array.js'),\n browser: Minilog.defaultBackend,\n localStorage: require('./localstorage.js'),\n jQuery: require('./jquery_simple.js')\n};\n","var Transform = require('../common/transform.js');\n\nvar cid = new Date().valueOf().toString(36);\n\nfunction AjaxLogger(options) {\n this.url = options.url || '';\n this.cache = [];\n this.timer = null;\n this.interval = options.interval || 30*1000;\n this.enabled = true;\n this.jQuery = window.jQuery;\n this.extras = {};\n}\n\nTransform.mixin(AjaxLogger);\n\nAjaxLogger.prototype.write = function(name, level, args) {\n if(!this.timer) { this.init(); }\n this.cache.push([name, level].concat(args));\n};\n\nAjaxLogger.prototype.init = function() {\n if(!this.enabled || !this.jQuery) return;\n var self = this;\n this.timer = setTimeout(function() {\n var i, logs = [], ajaxData, url = self.url;\n if(self.cache.length == 0) return self.init();\n // Test each log line and only log the ones that are valid (e.g. don't have circular references).\n // Slight performance hit but benefit is we log all valid lines.\n for(i = 0; i < self.cache.length; i++) {\n try {\n JSON.stringify(self.cache[i]);\n logs.push(self.cache[i]);\n } catch(e) { }\n }\n if(self.jQuery.isEmptyObject(self.extras)) {\n ajaxData = JSON.stringify({ logs: logs });\n url = self.url + '?client_id=' + cid;\n } else {\n ajaxData = JSON.stringify(self.jQuery.extend({logs: logs}, self.extras));\n }\n\n self.jQuery.ajax(url, {\n type: 'POST',\n cache: false,\n processData: false,\n data: ajaxData,\n contentType: 'application/json',\n timeout: 10000\n }).success(function(data, status, jqxhr) {\n if(data.interval) {\n self.interval = Math.max(1000, data.interval);\n }\n }).error(function() {\n self.interval = 30000;\n }).always(function() {\n self.init();\n });\n self.cache = [];\n }, this.interval);\n};\n\nAjaxLogger.prototype.end = function() {};\n\n// wait until jQuery is defined. Useful if you don't control the load order.\nAjaxLogger.jQueryWait = function(onDone) {\n if(typeof window !== 'undefined' && (window.jQuery || window.$)) {\n return onDone(window.jQuery || window.$);\n } else if (typeof window !== 'undefined') {\n setTimeout(function() { AjaxLogger.jQueryWait(onDone); }, 200);\n }\n};\n\nmodule.exports = AjaxLogger;\n","var Transform = require('../common/transform.js'),\n cache = false;\n\nvar logger = new Transform();\n\nlogger.write = function(name, level, args) {\n if(typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return;\n try {\n if(!cache) { cache = (window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : []); }\n cache.push([ new Date().toString(), name, level, args ]);\n window.localStorage.minilog = JSON.stringify(cache);\n } catch(e) {}\n};\n\nmodule.exports = logger;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","/* eslint-env worker */\n\nconst ArgumentType = require('../extension-support/argument-type');\nconst BlockType = require('../extension-support/block-type');\nconst dispatch = require('../dispatch/worker-dispatch');\nconst TargetType = require('../extension-support/target-type');\n\nclass ExtensionWorker {\n constructor () {\n this.nextExtensionId = 0;\n\n this.initialRegistrations = [];\n\n dispatch.waitForConnection.then(() => {\n dispatch.call('extensions', 'allocateWorker').then(x => {\n const [id, extension] = x;\n this.workerId = id;\n\n try {\n importScripts(extension);\n\n const initialRegistrations = this.initialRegistrations;\n this.initialRegistrations = null;\n\n Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));\n } catch (e) {\n dispatch.call('extensions', 'onWorkerInit', id, e);\n }\n });\n });\n\n this.extensions = [];\n }\n\n register (extensionObject) {\n const extensionId = this.nextExtensionId++;\n this.extensions.push(extensionObject);\n const serviceName = `extension.${this.workerId}.${extensionId}`;\n const promise = dispatch.setService(serviceName, extensionObject)\n .then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));\n if (this.initialRegistrations) {\n this.initialRegistrations.push(promise);\n }\n return promise;\n }\n}\n\nglobal.Scratch = global.Scratch || {};\nglobal.Scratch.ArgumentType = ArgumentType;\nglobal.Scratch.BlockType = BlockType;\nglobal.Scratch.TargetType = TargetType;\n\n/**\n * Expose only specific parts of the worker to extensions.\n */\nconst extensionWorker = new ExtensionWorker();\nglobal.Scratch.extensions = {\n register: extensionWorker.register.bind(extensionWorker)\n};\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"extension-worker.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAHA;AAAA;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC1OA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC7GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AChBA;AACA;AAEA;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;ACPA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://VirtualMachine/webpack/universalModuleDefinition","webpack://VirtualMachine/./src/dispatch/shared-dispatch.js","webpack://VirtualMachine/./src/dispatch/worker-dispatch.js","webpack://VirtualMachine/./src/extension-support/argument-type.js","webpack://VirtualMachine/./src/extension-support/block-type.js","webpack://VirtualMachine/./src/extension-support/target-type.js","webpack://VirtualMachine/./src/util/log.js","webpack://VirtualMachine/./node_modules/microee/index.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/filter.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/minilog.js","webpack://VirtualMachine/./node_modules/minilog/lib/common/transform.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/array.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/console.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/color.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/minilog.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/formatters/util.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/index.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/jquery_simple.js","webpack://VirtualMachine/./node_modules/minilog/lib/web/localstorage.js","webpack://VirtualMachine/webpack/bootstrap","webpack://VirtualMachine/webpack/runtime/global","webpack://VirtualMachine/./src/extension-support/extension-worker.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VirtualMachine\"] = factory();\n\telse\n\t\troot[\"VirtualMachine\"] = factory();\n})(self, () => {\nreturn ","const log = require('../util/log');\n\n/**\n * @typedef {object} DispatchCallMessage - a message to the dispatch system representing a service method call\n * @property {*} responseId - send a response message with this response ID. See {@link DispatchResponseMessage}\n * @property {string} service - the name of the service to be called\n * @property {string} method - the name of the method to be called\n * @property {Array|undefined} args - the arguments to be passed to the method\n */\n\n/**\n * @typedef {object} DispatchResponseMessage - a message to the dispatch system representing the results of a call\n * @property {*} responseId - a copy of the response ID from the call which generated this response\n * @property {*|undefined} error - if this is truthy, then it contains results from a failed call (such as an exception)\n * @property {*|undefined} result - if error is not truthy, then this contains the return value of the call (if any)\n */\n\n/**\n * @typedef {DispatchCallMessage|DispatchResponseMessage} DispatchMessage\n * Any message to the dispatch system.\n */\n\n/**\n * The SharedDispatch class is responsible for dispatch features shared by\n * {@link CentralDispatch} and {@link WorkerDispatch}.\n */\nclass SharedDispatch {\n constructor () {\n /**\n * List of callback registrations for promises waiting for a response from a call to a service on another\n * worker. A callback registration is an array of [resolve,reject] Promise functions.\n * Calls to local services don't enter this list.\n * @type {Array.<Function[]>}\n */\n this.callbacks = [];\n\n /**\n * The next response ID to be used.\n * @type {int}\n */\n this.nextResponseId = 0;\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.call('vm', 'setData', 'cat', 42);\n * // this finds the worker for the 'vm' service, then on that worker calls:\n * vm.setData('cat', 42);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n call (service, method, ...args) {\n return this.transferCall(service, method, null, ...args);\n }\n\n /**\n * Call a particular method on a particular service, regardless of whether that service is provided locally or on\n * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone\n * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be\n * transferred to the worker, and they should not be used after this call.\n * @example\n * dispatcher.transferCall('vm', 'setData', [myArrayBuffer], 'cat', myArrayBuffer);\n * // this finds the worker for the 'vm' service, transfers `myArrayBuffer` to it, then on that worker calls:\n * vm.setData('cat', myArrayBuffer);\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n transferCall (service, method, transfer, ...args) {\n try {\n const {provider, isRemote} = this._getServiceProvider(service);\n if (provider) {\n if (isRemote) {\n return this._remoteTransferCall(provider, service, method, transfer, ...args);\n }\n\n // TODO: verify correct `this` after switching from apply to spread\n // eslint-disable-next-line prefer-spread\n const result = provider[method].apply(provider, args);\n return Promise.resolve(result);\n }\n return Promise.reject(new Error(`Service not found: ${service}`));\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n /**\n * Check if a particular service lives on another worker.\n * @param {string} service - the service to check.\n * @returns {boolean} - true if the service is remote (calls must cross a Worker boundary), false otherwise.\n * @private\n */\n _isRemoteService (service) {\n return this._getServiceProvider(service).isRemote;\n }\n\n /**\n * Like {@link call}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteCall (provider, service, method, ...args) {\n return this._remoteTransferCall(provider, service, method, null, ...args);\n }\n\n /**\n * Like {@link transferCall}, but force the call to be posted through a particular communication channel.\n * @param {object} provider - send the call through this object's `postMessage` function.\n * @param {string} service - the name of the service.\n * @param {string} method - the name of the method.\n * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.\n * @param {*} [args] - the arguments to be copied to the method, if any.\n * @returns {Promise} - a promise for the return value of the service method.\n */\n _remoteTransferCall (provider, service, method, transfer, ...args) {\n return new Promise((resolve, reject) => {\n const responseId = this._storeCallbacks(resolve, reject);\n\n /** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */\n if ((args.length > 0) && (typeof args[args.length - 1].yield === 'function')) {\n args.pop();\n }\n\n if (transfer) {\n provider.postMessage({service, method, responseId, args}, transfer);\n } else {\n provider.postMessage({service, method, responseId, args});\n }\n });\n }\n\n /**\n * Store callback functions pending a response message.\n * @param {Function} resolve - function to call if the service method returns.\n * @param {Function} reject - function to call if the service method throws.\n * @returns {*} - a unique response ID for this set of callbacks. See {@link _deliverResponse}.\n * @protected\n */\n _storeCallbacks (resolve, reject) {\n const responseId = this.nextResponseId++;\n this.callbacks[responseId] = [resolve, reject];\n return responseId;\n }\n\n /**\n * Deliver call response from a worker. This should only be called as the result of a message from a worker.\n * @param {int} responseId - the response ID of the callback set to call.\n * @param {DispatchResponseMessage} message - the message containing the response value(s).\n * @protected\n */\n _deliverResponse (responseId, message) {\n try {\n const [resolve, reject] = this.callbacks[responseId];\n delete this.callbacks[responseId];\n if (message.error) {\n reject(message.error);\n } else {\n resolve(message.result);\n }\n } catch (e) {\n log.error(`Dispatch callback failed: ${JSON.stringify(e)}`);\n }\n }\n\n /**\n * Handle a message event received from a connected worker.\n * @param {Worker} worker - the worker which sent the message, or the global object if running in a worker.\n * @param {MessageEvent} event - the message event to be handled.\n * @protected\n */\n _onMessage (worker, event) {\n /** @type {DispatchMessage} */\n const message = event.data;\n message.args = message.args || [];\n let promise;\n if (message.service) {\n if (message.service === 'dispatch') {\n promise = this._onDispatchMessage(worker, message);\n } else {\n promise = this.call(message.service, message.method, ...message.args);\n }\n } else if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch caught malformed message from a worker: ${JSON.stringify(event)}`);\n } else {\n this._deliverResponse(message.responseId, message);\n }\n if (promise) {\n if (typeof message.responseId === 'undefined') {\n log.error(`Dispatch message missing required response ID: ${JSON.stringify(event)}`);\n } else {\n promise.then(\n result => worker.postMessage({responseId: message.responseId, result}),\n error => worker.postMessage({responseId: message.responseId, error})\n );\n }\n }\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @abstract\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n throw new Error(`Could not get provider for ${service}: _getServiceProvider not implemented`);\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @abstract\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @private\n */\n _onDispatchMessage (worker, message) {\n throw new Error(`Unimplemented dispatch message handler cannot handle ${message.method} method`);\n }\n}\n\nmodule.exports = SharedDispatch;\n","const SharedDispatch = require('./shared-dispatch');\n\nconst log = require('../util/log');\n\n/**\n * This class provides a Worker with the means to participate in the message dispatch system managed by CentralDispatch.\n * From any context in the messaging system, the dispatcher's \"call\" method can call any method on any \"service\"\n * provided in any participating context. The dispatch system will forward function arguments and return values across\n * worker boundaries as needed.\n * @see {CentralDispatch}\n */\nclass WorkerDispatch extends SharedDispatch {\n constructor () {\n super();\n\n /**\n * This promise will be resolved when we have successfully connected to central dispatch.\n * @type {Promise}\n * @see {waitForConnection}\n * @private\n */\n this._connectionPromise = new Promise(resolve => {\n this._onConnect = resolve;\n });\n\n /**\n * Map of service name to local service provider.\n * If a service is not listed here, it is assumed to be provided by another context (another Worker or the main\n * thread).\n * @see {setService}\n * @type {object}\n */\n this.services = {};\n\n this._onMessage = this._onMessage.bind(this, self);\n if (typeof self !== 'undefined') {\n self.onmessage = this._onMessage;\n }\n }\n\n /**\n * @returns {Promise} a promise which will resolve upon connection to central dispatch. If you need to make a call\n * immediately on \"startup\" you can attach a 'then' to this promise.\n * @example\n * dispatch.waitForConnection.then(() => {\n * dispatch.call('myService', 'hello');\n * })\n */\n get waitForConnection () {\n return this._connectionPromise;\n }\n\n /**\n * Set a local object as the global provider of the specified service.\n * WARNING: Any method on the provider can be called from any worker within the dispatch system.\n * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'.\n * @param {object} provider - a local object which provides this service.\n * @returns {Promise} - a promise which will resolve once the service is registered.\n */\n setService (service, provider) {\n if (Object.prototype.hasOwnProperty.call(this.services, service)) {\n log.warn(`Worker dispatch replacing existing service provider for ${service}`);\n }\n this.services[service] = provider;\n return this.waitForConnection.then(() => this._remoteCall(self, 'dispatch', 'setService', service));\n }\n\n /**\n * Fetch the service provider object for a particular service name.\n * @override\n * @param {string} service - the name of the service to look up\n * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found\n * @protected\n */\n _getServiceProvider (service) {\n // if we don't have a local service by this name, contact central dispatch by calling `postMessage` on self\n const provider = this.services[service];\n return {\n provider: provider || self,\n isRemote: !provider\n };\n }\n\n /**\n * Handle a call message sent to the dispatch service itself\n * @override\n * @param {Worker} worker - the worker which sent the message.\n * @param {DispatchCallMessage} message - the message to be handled.\n * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate\n * @protected\n */\n _onDispatchMessage (worker, message) {\n let promise;\n switch (message.method) {\n case 'handshake':\n promise = this._onConnect();\n break;\n case 'terminate':\n // Don't close until next tick, after sending confirmation back\n setTimeout(() => self.close(), 0);\n promise = Promise.resolve();\n break;\n default:\n log.error(`Worker dispatch received message for unknown method: ${message.method}`);\n }\n return promise;\n }\n}\n\nmodule.exports = new WorkerDispatch();\n","/**\n * Block argument types\n * @enum {string}\n */\nconst ArgumentType = {\n /**\n * Numeric value with angle picker\n */\n ANGLE: 'angle',\n\n /**\n * Boolean value with hexagonal placeholder\n */\n BOOLEAN: 'Boolean',\n\n /**\n * Numeric value with color picker\n */\n COLOR: 'color',\n\n /**\n * Numeric value with text field\n */\n NUMBER: 'number',\n\n /**\n * String value with text field\n */\n STRING: 'string',\n\n /**\n * String value with matrix field\n */\n MATRIX: 'matrix',\n\n /**\n * MIDI note number with note picker (piano) field\n */\n NOTE: 'note',\n\n /**\n * Inline image on block (as part of the label)\n */\n IMAGE: 'image'\n};\n\nmodule.exports = ArgumentType;\n","/**\n * Types of block\n * @enum {string}\n */\nconst BlockType = {\n /**\n * Boolean reporter with hexagonal shape\n */\n BOOLEAN: 'Boolean',\n\n /**\n * A button (not an actual block) for some special action, like making a variable\n */\n BUTTON: 'button',\n\n /**\n * Command block\n */\n COMMAND: 'command',\n\n /**\n * Specialized command block which may or may not run a child branch\n * The thread continues with the next block whether or not a child branch ran.\n */\n CONDITIONAL: 'conditional',\n\n /**\n * Specialized hat block with no implementation function\n * This stack only runs if the corresponding event is emitted by other code.\n */\n EVENT: 'event',\n\n /**\n * Hat block which conditionally starts a block stack\n */\n HAT: 'hat',\n\n /**\n * Specialized command block which may or may not run a child branch\n * If a child branch runs, the thread evaluates the loop block again.\n */\n LOOP: 'loop',\n\n /**\n * General reporter with numeric or string value\n */\n REPORTER: 'reporter'\n};\n\nmodule.exports = BlockType;\n","/**\n * Default types of Target supported by the VM\n * @enum {string}\n */\nconst TargetType = {\n /**\n * Rendered target which can move, change costumes, etc.\n */\n SPRITE: 'sprite',\n\n /**\n * Rendered target which cannot move but can change backdrops\n */\n STAGE: 'stage'\n};\n\nmodule.exports = TargetType;\n","const minilog = require('minilog');\nminilog.enable();\n\nmodule.exports = minilog('vm');\n","function M() { this._events = {}; }\nM.prototype = {\n on: function(ev, cb) {\n this._events || (this._events = {});\n var e = this._events;\n (e[ev] || (e[ev] = [])).push(cb);\n return this;\n },\n removeListener: function(ev, cb) {\n var e = this._events[ev] || [], i;\n for(i = e.length-1; i >= 0 && e[i]; i--){\n if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); }\n }\n },\n removeAllListeners: function(ev) {\n if(!ev) { this._events = {}; }\n else { this._events[ev] && (this._events[ev] = []); }\n },\n listeners: function(ev) {\n return (this._events ? this._events[ev] || [] : []);\n },\n emit: function(ev) {\n this._events || (this._events = {});\n var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || [];\n for(i = e.length-1; i >= 0 && e[i]; i--){\n e[i].apply(this, args);\n }\n return this;\n },\n when: function(ev, cb) {\n return this.once(ev, cb, true);\n },\n once: function(ev, cb, when) {\n if(!cb) return this;\n function c() {\n if(!when) this.removeListener(ev, c);\n if(cb.apply(this, arguments) && when) this.removeListener(ev, c);\n }\n c.cb = cb;\n this.on(ev, c);\n return this;\n }\n};\nM.mixin = function(dest) {\n var o = M.prototype, k;\n for (k in o) {\n o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);\n }\n};\nmodule.exports = M;\n","// default filter\nvar Transform = require('./transform.js');\n\nvar levelMap = { debug: 1, info: 2, warn: 3, error: 4 };\n\nfunction Filter() {\n this.enabled = true;\n this.defaultResult = true;\n this.clear();\n}\n\nTransform.mixin(Filter);\n\n// allow all matching, with level >= given level\nFilter.prototype.allow = function(name, level) {\n this._white.push({ n: name, l: levelMap[level] });\n return this;\n};\n\n// deny all matching, with level <= given level\nFilter.prototype.deny = function(name, level) {\n this._black.push({ n: name, l: levelMap[level] });\n return this;\n};\n\nFilter.prototype.clear = function() {\n this._white = [];\n this._black = [];\n return this;\n};\n\nfunction test(rule, name) {\n // use .test for RegExps\n return (rule.n.test ? rule.n.test(name) : rule.n == name);\n};\n\nFilter.prototype.test = function(name, level) {\n var i, len = Math.max(this._white.length, this._black.length);\n for(i = 0; i < len; i++) {\n if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) {\n return true;\n }\n if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) {\n return false;\n }\n }\n return this.defaultResult;\n};\n\nFilter.prototype.write = function(name, level, args) {\n if(!this.enabled || this.test(name, level)) {\n return this.emit('item', name, level, args);\n }\n};\n\nmodule.exports = Filter;\n","var Transform = require('./transform.js'),\n Filter = require('./filter.js');\n\nvar log = new Transform(),\n slice = Array.prototype.slice;\n\nexports = module.exports = function create(name) {\n var o = function() { log.write(name, undefined, slice.call(arguments)); return o; };\n o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; };\n o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; };\n o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; };\n o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; };\n o.log = o.debug; // for interface compliance with Node and browser consoles\n o.suggest = exports.suggest;\n o.format = log.format;\n return o;\n};\n\n// filled in separately\nexports.defaultBackend = exports.defaultFormatter = null;\n\nexports.pipe = function(dest) {\n return log.pipe(dest);\n};\n\nexports.end = exports.unpipe = exports.disable = function(from) {\n return log.unpipe(from);\n};\n\nexports.Transform = Transform;\nexports.Filter = Filter;\n// this is the default filter that's applied when .enable() is called normally\n// you can bypass it completely and set up your own pipes\nexports.suggest = new Filter();\n\nexports.enable = function() {\n if(exports.defaultFormatter) {\n return log.pipe(exports.suggest) // filter\n .pipe(exports.defaultFormatter) // formatter\n .pipe(exports.defaultBackend); // backend\n }\n return log.pipe(exports.suggest) // filter\n .pipe(exports.defaultBackend); // formatter\n};\n\n","var microee = require('microee');\n\n// Implements a subset of Node's stream.Transform - in a cross-platform manner.\nfunction Transform() {}\n\nmicroee.mixin(Transform);\n\n// The write() signature is different from Node's\n// --> makes it much easier to work with objects in logs.\n// One of the lessons from v1 was that it's better to target\n// a good browser rather than the lowest common denominator\n// internally.\n// If you want to use external streams, pipe() to ./stringify.js first.\nTransform.prototype.write = function(name, level, args) {\n this.emit('item', name, level, args);\n};\n\nTransform.prototype.end = function() {\n this.emit('end');\n this.removeAllListeners();\n};\n\nTransform.prototype.pipe = function(dest) {\n var s = this;\n // prevent double piping\n s.emit('unpipe', dest);\n // tell the dest that it's being piped to\n dest.emit('pipe', s);\n\n function onItem() {\n dest.write.apply(dest, Array.prototype.slice.call(arguments));\n }\n function onEnd() { !dest._isStdio && dest.end(); }\n\n s.on('item', onItem);\n s.on('end', onEnd);\n\n s.when('unpipe', function(from) {\n var match = (from === dest) || typeof from == 'undefined';\n if(match) {\n s.removeListener('item', onItem);\n s.removeListener('end', onEnd);\n dest.emit('unpipe');\n }\n return match;\n });\n\n return dest;\n};\n\nTransform.prototype.unpipe = function(from) {\n this.emit('unpipe', from);\n return this;\n};\n\nTransform.prototype.format = function(dest) {\n throw new Error([\n 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:',\n 'var Minilog = require(\\'minilog\\');',\n 'Minilog',\n ' .pipe(Minilog.backends.console.formatClean)',\n ' .pipe(Minilog.backends.console);'].join('\\n'));\n};\n\nTransform.mixin = function(dest) {\n var o = Transform.prototype, k;\n for (k in o) {\n o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);\n }\n};\n\nmodule.exports = Transform;\n","var Transform = require('../common/transform.js'),\n cache = [ ];\n\nvar logger = new Transform();\n\nlogger.write = function(name, level, args) {\n cache.push([ name, level, args ]);\n};\n\n// utility functions\nlogger.get = function() { return cache; };\nlogger.empty = function() { cache = []; };\n\nmodule.exports = logger;\n","var Transform = require('../common/transform.js');\n\nvar newlines = /\\n+$/,\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var i = args.length-1;\n if (typeof console === 'undefined' || !console.log) {\n return;\n }\n if(console.log.apply) {\n return console.log.apply(console, [name, level].concat(args));\n } else if(JSON && JSON.stringify) {\n // console.log.apply is undefined in IE8 and IE9\n // for IE8/9: make console.log at least a bit less awful\n if(args[i] && typeof args[i] == 'string') {\n args[i] = args[i].replace(newlines, '');\n }\n try {\n for(i = 0; i < args.length; i++) {\n args[i] = JSON.stringify(args[i]);\n }\n } catch(e) {}\n console.log(args.join(' '));\n }\n};\n\nlogger.formatters = ['color', 'minilog'];\nlogger.color = require('./formatters/color.js');\nlogger.minilog = require('./formatters/minilog.js');\n\nmodule.exports = logger;\n","var Transform = require('../../common/transform.js'),\n color = require('./util.js');\n\nvar colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var fn = console.log;\n if(console[level] && console[level].apply) {\n fn = console[level];\n fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args));\n }\n};\n\n// NOP, because piping the formatted logs can only cause trouble.\nlogger.pipe = function() { };\n\nmodule.exports = logger;\n","var Transform = require('../../common/transform.js'),\n color = require('./util.js'),\n colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },\n logger = new Transform();\n\nlogger.write = function(name, level, args) {\n var fn = console.log;\n if(level != 'debug' && console[level]) {\n fn = console[level];\n }\n\n var subset = [], i = 0;\n if(level != 'info') {\n for(; i < args.length; i++) {\n if(typeof args[i] != 'string') break;\n }\n fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i)));\n } else {\n fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args));\n }\n};\n\n// NOP, because piping the formatted logs can only cause trouble.\nlogger.pipe = function() { };\n\nmodule.exports = logger;\n","var hex = {\n black: '#000',\n red: '#c23621',\n green: '#25bc26',\n yellow: '#bbbb00',\n blue: '#492ee1',\n magenta: '#d338d3',\n cyan: '#33bbc8',\n gray: '#808080',\n purple: '#708'\n};\nfunction color(fg, isInverse) {\n if(isInverse) {\n return 'color: #fff; background: '+hex[fg]+';';\n } else {\n return 'color: '+hex[fg]+';';\n }\n}\n\nmodule.exports = color;\n","var Minilog = require('../common/minilog.js');\n\nvar oldEnable = Minilog.enable,\n oldDisable = Minilog.disable,\n isChrome = (typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent)),\n console = require('./console.js');\n\n// Use a more capable logging backend if on Chrome\nMinilog.defaultBackend = (isChrome ? console.minilog : console);\n\n// apply enable inputs from localStorage and from the URL\nif(typeof window != 'undefined') {\n try {\n Minilog.enable(JSON.parse(window.localStorage['minilogSettings']));\n } catch(e) {}\n if(window.location && window.location.search) {\n var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search);\n match && Minilog.enable(decodeURIComponent(match[1]));\n }\n}\n\n// Make enable also add to localStorage\nMinilog.enable = function() {\n oldEnable.call(Minilog, true);\n try { window.localStorage['minilogSettings'] = JSON.stringify(true); } catch(e) {}\n return this;\n};\n\nMinilog.disable = function() {\n oldDisable.call(Minilog);\n try { delete window.localStorage.minilogSettings; } catch(e) {}\n return this;\n};\n\nexports = module.exports = Minilog;\n\nexports.backends = {\n array: require('./array.js'),\n browser: Minilog.defaultBackend,\n localStorage: require('./localstorage.js'),\n jQuery: require('./jquery_simple.js')\n};\n","var Transform = require('../common/transform.js');\n\nvar cid = new Date().valueOf().toString(36);\n\nfunction AjaxLogger(options) {\n this.url = options.url || '';\n this.cache = [];\n this.timer = null;\n this.interval = options.interval || 30*1000;\n this.enabled = true;\n this.jQuery = window.jQuery;\n this.extras = {};\n}\n\nTransform.mixin(AjaxLogger);\n\nAjaxLogger.prototype.write = function(name, level, args) {\n if(!this.timer) { this.init(); }\n this.cache.push([name, level].concat(args));\n};\n\nAjaxLogger.prototype.init = function() {\n if(!this.enabled || !this.jQuery) return;\n var self = this;\n this.timer = setTimeout(function() {\n var i, logs = [], ajaxData, url = self.url;\n if(self.cache.length == 0) return self.init();\n // Test each log line and only log the ones that are valid (e.g. don't have circular references).\n // Slight performance hit but benefit is we log all valid lines.\n for(i = 0; i < self.cache.length; i++) {\n try {\n JSON.stringify(self.cache[i]);\n logs.push(self.cache[i]);\n } catch(e) { }\n }\n if(self.jQuery.isEmptyObject(self.extras)) {\n ajaxData = JSON.stringify({ logs: logs });\n url = self.url + '?client_id=' + cid;\n } else {\n ajaxData = JSON.stringify(self.jQuery.extend({logs: logs}, self.extras));\n }\n\n self.jQuery.ajax(url, {\n type: 'POST',\n cache: false,\n processData: false,\n data: ajaxData,\n contentType: 'application/json',\n timeout: 10000\n }).success(function(data, status, jqxhr) {\n if(data.interval) {\n self.interval = Math.max(1000, data.interval);\n }\n }).error(function() {\n self.interval = 30000;\n }).always(function() {\n self.init();\n });\n self.cache = [];\n }, this.interval);\n};\n\nAjaxLogger.prototype.end = function() {};\n\n// wait until jQuery is defined. Useful if you don't control the load order.\nAjaxLogger.jQueryWait = function(onDone) {\n if(typeof window !== 'undefined' && (window.jQuery || window.$)) {\n return onDone(window.jQuery || window.$);\n } else if (typeof window !== 'undefined') {\n setTimeout(function() { AjaxLogger.jQueryWait(onDone); }, 200);\n }\n};\n\nmodule.exports = AjaxLogger;\n","var Transform = require('../common/transform.js'),\n cache = false;\n\nvar logger = new Transform();\n\nlogger.write = function(name, level, args) {\n if(typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return;\n try {\n if(!cache) { cache = (window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : []); }\n cache.push([ new Date().toString(), name, level, args ]);\n window.localStorage.minilog = JSON.stringify(cache);\n } catch(e) {}\n};\n\nmodule.exports = logger;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","/* eslint-env worker */\n\nconst ArgumentType = require('../extension-support/argument-type');\nconst BlockType = require('../extension-support/block-type');\nconst dispatch = require('../dispatch/worker-dispatch');\nconst TargetType = require('../extension-support/target-type');\n\nclass ExtensionWorker {\n constructor () {\n this.nextExtensionId = 0;\n\n this.initialRegistrations = [];\n\n dispatch.waitForConnection.then(() => {\n dispatch.call('extensions', 'allocateWorker').then(x => {\n const [id, extension] = x;\n this.workerId = id;\n\n try {\n importScripts(extension);\n\n const initialRegistrations = this.initialRegistrations;\n this.initialRegistrations = null;\n\n Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));\n } catch (e) {\n dispatch.call('extensions', 'onWorkerInit', id, e);\n }\n });\n });\n\n this.extensions = [];\n }\n\n register (extensionObject) {\n const extensionId = this.nextExtensionId++;\n this.extensions.push(extensionObject);\n const serviceName = `extension.${this.workerId}.${extensionId}`;\n const promise = dispatch.setService(serviceName, extensionObject)\n .then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));\n if (this.initialRegistrations) {\n this.initialRegistrations.push(promise);\n }\n return promise;\n }\n}\n\nglobal.Scratch = global.Scratch || {};\nglobal.Scratch.ArgumentType = ArgumentType;\nglobal.Scratch.BlockType = BlockType;\nglobal.Scratch.TargetType = TargetType;\n\n/**\n * Expose only specific parts of the worker to extensions.\n */\nconst extensionWorker = new ExtensionWorker();\nglobal.Scratch.extensions = {\n register: extensionWorker.register.bind(extensionWorker)\n};\n"],"names":[],"sourceRoot":""}
@@ -80335,7 +80335,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"menuMap":{"cs":[{"code":"am","name":
80335
80335
  /***/ ((module) => {
80336
80336
 
80337
80337
  "use strict";
80338
- module.exports = /*#__PURE__*/JSON.parse('{"name":"scratch-vm","version":"4.8.5","description":"Virtual Machine for Scratch 3.0","author":"Massachusetts Institute of Technology","license":"BSD-3-Clause","homepage":"https://github.com/scratchfoundation/scratch-vm#readme","repository":{"type":"git","url":"https://github.com/scratchfoundation/scratch-vm.git","sha":"cc7ea7014be0df46b52b4e31d593ea64b79cdeb6"},"main":"./dist/node/scratch-vm.js","browser":"./dist/web/scratch-vm.js","exports":{"webpack":"./src/index.js","browser":"./dist/web/scratch-vm.js","node":"./dist/node/scratch-vm.js","default":"./src/index.js"},"scripts":{"build":"npm run docs && webpack --progress","coverage":"tap ./test/{unit,integration}/*.js --coverage --coverage-report=lcov","docs":"jsdoc -c .jsdoc.json","i18n:src":"mkdirp translations/core && format-message extract --out-file translations/core/en.json src/extensions/**/index.js","i18n:push":"tx-push-src scratch-editor extensions translations/core/en.json","lint":"eslint . && format-message lint src/**/*.js","prepare":"husky install","prepublish":"in-publish && npm run build || not-in-publish","start":"webpack serve","tap":"tap ./test/{unit,integration}/*.js","tap:unit":"tap ./test/unit/*.js","tap:integration":"tap ./test/integration/*.js","test":"npm run lint && npm run tap","watch":"webpack --progress --watch","version":"json -f package.json -I -e \\"this.repository.sha = \'$(git log -n1 --pretty=format:%H)\'\\""},"config":{"commitizen":{"path":"cz-conventional-changelog"}},"browserslist":["Chrome >= 63","Edge >= 15","Firefox >= 57","Safari >= 11"],"tap":{"branches":60,"functions":70,"lines":70,"statements":70},"dependencies":{"@vernier/godirect":"^1.5.0","arraybuffer-loader":"^1.0.6","atob":"^2.1.2","btoa":"^1.2.1","canvas-toBlob":"^1.0.0","decode-html":"^2.0.0","diff-match-patch":"^1.0.4","format-message":"^6.2.1","htmlparser2":"^3.10.0","immutable":"^3.8.1","jszip":"^3.1.5","minilog":"^3.1.0","scratch-audio":"^1.0.6","scratch-parser":"^5.1.1","scratch-render":"^1.0.232","scratch-sb1-converter":"^1.0.0","scratch-storage":"^2.3.5","scratch-svg-renderer":"2.5.2","scratch-translate-extension-languages":"^1.0.0","text-encoding":"^0.7.0","uuid":"^8.3.2","web-worker":"^1.3.0"},"devDependencies":{"@babel/core":"7.25.2","@babel/eslint-parser":"7.25.1","@babel/preset-env":"7.25.4","@commitlint/cli":"17.8.1","@commitlint/config-conventional":"17.8.1","adm-zip":"0.4.11","babel-loader":"9.2.1","callsite":"1.0.0","copy-webpack-plugin":"4.6.0","docdash":"1.2.0","eslint":"8.57.1","eslint-config-scratch":"9.0.9","expose-loader":"1.0.3","file-loader":"6.2.0","format-message-cli":"6.2.4","husky":"8.0.3","in-publish":"2.0.1","js-md5":"0.7.3","jsdoc":"3.6.11","json":"^9.0.4","pngjs":"3.4.0","scratch-blocks":"1.1.206","scratch-l10n":"3.18.324","scratch-render-fonts":"1.0.105","scratch-semantic-release-config":"1.0.16","scratch-webpack-configuration":"1.6.0","script-loader":"0.7.2","semantic-release":"19.0.5","stats.js":"0.17.0","tap":"16.3.10","webpack":"5.94.0","webpack-cli":"4.10.0","webpack-dev-server":"3.11.3"}}');
80338
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"scratch-vm","version":"4.8.6","description":"Virtual Machine for Scratch 3.0","author":"Massachusetts Institute of Technology","license":"BSD-3-Clause","homepage":"https://github.com/scratchfoundation/scratch-vm#readme","repository":{"type":"git","url":"https://github.com/scratchfoundation/scratch-vm.git","sha":"6f31da7edfefb97bd96d173277372093e8ab3903"},"main":"./dist/node/scratch-vm.js","browser":"./dist/web/scratch-vm.js","exports":{"webpack":"./src/index.js","browser":"./dist/web/scratch-vm.js","node":"./dist/node/scratch-vm.js","default":"./src/index.js"},"scripts":{"build":"npm run docs && webpack --progress","coverage":"tap ./test/{unit,integration}/*.js --coverage --coverage-report=lcov","docs":"jsdoc -c .jsdoc.json","i18n:src":"mkdirp translations/core && format-message extract --out-file translations/core/en.json src/extensions/**/index.js","i18n:push":"tx-push-src scratch-editor extensions translations/core/en.json","lint":"eslint . && format-message lint src/**/*.js","prepare":"husky install","prepublish":"in-publish && npm run build || not-in-publish","start":"webpack serve","tap":"tap ./test/{unit,integration}/*.js","tap:unit":"tap ./test/unit/*.js","tap:integration":"tap ./test/integration/*.js","test":"npm run lint && npm run tap","watch":"webpack --progress --watch","version":"json -f package.json -I -e \\"this.repository.sha = \'$(git log -n1 --pretty=format:%H)\'\\""},"config":{"commitizen":{"path":"cz-conventional-changelog"}},"browserslist":["Chrome >= 63","Edge >= 15","Firefox >= 57","Safari >= 11"],"tap":{"branches":60,"functions":70,"lines":70,"statements":70},"dependencies":{"@vernier/godirect":"^1.5.0","arraybuffer-loader":"^1.0.6","atob":"^2.1.2","btoa":"^1.2.1","canvas-toBlob":"^1.0.0","decode-html":"^2.0.0","diff-match-patch":"^1.0.4","format-message":"^6.2.1","htmlparser2":"^3.10.0","immutable":"^3.8.1","jszip":"^3.1.5","minilog":"^3.1.0","scratch-audio":"^1.0.6","scratch-parser":"^5.1.1","scratch-render":"^1.0.232","scratch-sb1-converter":"^1.0.0","scratch-storage":"^2.3.5","scratch-svg-renderer":"2.5.2","scratch-translate-extension-languages":"^1.0.0","text-encoding":"^0.7.0","uuid":"^8.3.2","web-worker":"^1.3.0"},"devDependencies":{"@babel/core":"7.25.2","@babel/eslint-parser":"7.25.1","@babel/preset-env":"7.25.4","@commitlint/cli":"17.8.1","@commitlint/config-conventional":"17.8.1","adm-zip":"0.4.11","babel-loader":"9.2.1","callsite":"1.0.0","copy-webpack-plugin":"4.6.0","docdash":"1.2.0","eslint":"8.57.1","eslint-config-scratch":"9.0.9","expose-loader":"1.0.3","file-loader":"6.2.0","format-message-cli":"6.2.4","husky":"8.0.3","in-publish":"2.0.1","js-md5":"0.7.3","jsdoc":"3.6.11","json":"^9.0.4","pngjs":"3.4.0","scratch-blocks":"1.1.206","scratch-l10n":"3.18.324","scratch-render-fonts":"1.0.106","scratch-semantic-release-config":"1.0.16","scratch-webpack-configuration":"1.6.0","script-loader":"0.7.2","semantic-release":"19.0.5","stats.js":"0.17.0","tap":"16.3.10","webpack":"5.95.0","webpack-cli":"4.10.0","webpack-dev-server":"3.11.3"}}');
80339
80339
 
80340
80340
  /***/ })
80341
80341
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scratch-vm",
3
- "version": "4.8.6",
3
+ "version": "4.8.7",
4
4
  "description": "Virtual Machine for Scratch 3.0",
5
5
  "author": "Massachusetts Institute of Technology",
6
6
  "license": "BSD-3-Clause",
@@ -8,7 +8,7 @@
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/scratchfoundation/scratch-vm.git",
11
- "sha": "6f31da7edfefb97bd96d173277372093e8ab3903"
11
+ "sha": "d09bf01d627f95ddd55bd3446a6e29bee850cd77"
12
12
  },
13
13
  "main": "./dist/node/scratch-vm.js",
14
14
  "browser": "./dist/web/scratch-vm.js",
@@ -100,14 +100,14 @@
100
100
  "pngjs": "3.4.0",
101
101
  "scratch-blocks": "1.1.206",
102
102
  "scratch-l10n": "3.18.324",
103
- "scratch-render-fonts": "1.0.105",
103
+ "scratch-render-fonts": "1.0.106",
104
104
  "scratch-semantic-release-config": "1.0.16",
105
105
  "scratch-webpack-configuration": "1.6.0",
106
106
  "script-loader": "0.7.2",
107
107
  "semantic-release": "19.0.5",
108
108
  "stats.js": "0.17.0",
109
109
  "tap": "16.3.10",
110
- "webpack": "5.94.0",
110
+ "webpack": "5.95.0",
111
111
  "webpack-cli": "4.10.0",
112
112
  "webpack-dev-server": "3.11.3"
113
113
  }