scratch-vm 4.5.378 → 4.5.379

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.
@@ -0,0 +1,1215 @@
1
+ (function webpackUniversalModuleDefinition(root, factory) {
2
+ if(typeof exports === 'object' && typeof module === 'object')
3
+ module.exports = factory();
4
+ else if(typeof define === 'function' && define.amd)
5
+ define([], factory);
6
+ else if(typeof exports === 'object')
7
+ exports["VirtualMachine"] = factory();
8
+ else
9
+ root["VirtualMachine"] = factory();
10
+ })(self, () => {
11
+ return /******/ (() => { // webpackBootstrap
12
+ /******/ var __webpack_modules__ = ({
13
+
14
+ /***/ "./src/dispatch/shared-dispatch.js":
15
+ /*!*****************************************!*\
16
+ !*** ./src/dispatch/shared-dispatch.js ***!
17
+ \*****************************************/
18
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
19
+
20
+ const log = __webpack_require__(/*! ../util/log */ "./src/util/log.js");
21
+
22
+ /**
23
+ * @typedef {object} DispatchCallMessage - a message to the dispatch system representing a service method call
24
+ * @property {*} responseId - send a response message with this response ID. See {@link DispatchResponseMessage}
25
+ * @property {string} service - the name of the service to be called
26
+ * @property {string} method - the name of the method to be called
27
+ * @property {Array|undefined} args - the arguments to be passed to the method
28
+ */
29
+
30
+ /**
31
+ * @typedef {object} DispatchResponseMessage - a message to the dispatch system representing the results of a call
32
+ * @property {*} responseId - a copy of the response ID from the call which generated this response
33
+ * @property {*|undefined} error - if this is truthy, then it contains results from a failed call (such as an exception)
34
+ * @property {*|undefined} result - if error is not truthy, then this contains the return value of the call (if any)
35
+ */
36
+
37
+ /**
38
+ * @typedef {DispatchCallMessage|DispatchResponseMessage} DispatchMessage
39
+ * Any message to the dispatch system.
40
+ */
41
+
42
+ /**
43
+ * The SharedDispatch class is responsible for dispatch features shared by
44
+ * {@link CentralDispatch} and {@link WorkerDispatch}.
45
+ */
46
+ class SharedDispatch {
47
+ constructor() {
48
+ /**
49
+ * List of callback registrations for promises waiting for a response from a call to a service on another
50
+ * worker. A callback registration is an array of [resolve,reject] Promise functions.
51
+ * Calls to local services don't enter this list.
52
+ * @type {Array.<Function[]>}
53
+ */
54
+ this.callbacks = [];
55
+
56
+ /**
57
+ * The next response ID to be used.
58
+ * @type {int}
59
+ */
60
+ this.nextResponseId = 0;
61
+ }
62
+
63
+ /**
64
+ * Call a particular method on a particular service, regardless of whether that service is provided locally or on
65
+ * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone
66
+ * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be
67
+ * transferred to the worker, and they should not be used after this call.
68
+ * @example
69
+ * dispatcher.call('vm', 'setData', 'cat', 42);
70
+ * // this finds the worker for the 'vm' service, then on that worker calls:
71
+ * vm.setData('cat', 42);
72
+ * @param {string} service - the name of the service.
73
+ * @param {string} method - the name of the method.
74
+ * @param {*} [args] - the arguments to be copied to the method, if any.
75
+ * @returns {Promise} - a promise for the return value of the service method.
76
+ */
77
+ call(service, method) {
78
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
79
+ args[_key - 2] = arguments[_key];
80
+ }
81
+ return this.transferCall(service, method, null, ...args);
82
+ }
83
+
84
+ /**
85
+ * Call a particular method on a particular service, regardless of whether that service is provided locally or on
86
+ * a worker. If the service is provided by a worker, the `args` will be copied using the Structured Clone
87
+ * algorithm, except for any items which are also in the `transfer` list. Ownership of those items will be
88
+ * transferred to the worker, and they should not be used after this call.
89
+ * @example
90
+ * dispatcher.transferCall('vm', 'setData', [myArrayBuffer], 'cat', myArrayBuffer);
91
+ * // this finds the worker for the 'vm' service, transfers `myArrayBuffer` to it, then on that worker calls:
92
+ * vm.setData('cat', myArrayBuffer);
93
+ * @param {string} service - the name of the service.
94
+ * @param {string} method - the name of the method.
95
+ * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.
96
+ * @param {*} [args] - the arguments to be copied to the method, if any.
97
+ * @returns {Promise} - a promise for the return value of the service method.
98
+ */
99
+ transferCall(service, method, transfer) {
100
+ try {
101
+ const {
102
+ provider,
103
+ isRemote
104
+ } = this._getServiceProvider(service);
105
+ if (provider) {
106
+ for (var _len2 = arguments.length, args = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
107
+ args[_key2 - 3] = arguments[_key2];
108
+ }
109
+ if (isRemote) {
110
+ return this._remoteTransferCall(provider, service, method, transfer, ...args);
111
+ }
112
+
113
+ // TODO: verify correct `this` after switching from apply to spread
114
+ // eslint-disable-next-line prefer-spread
115
+ const result = provider[method].apply(provider, args);
116
+ return Promise.resolve(result);
117
+ }
118
+ return Promise.reject(new Error("Service not found: ".concat(service)));
119
+ } catch (e) {
120
+ return Promise.reject(e);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Check if a particular service lives on another worker.
126
+ * @param {string} service - the service to check.
127
+ * @returns {boolean} - true if the service is remote (calls must cross a Worker boundary), false otherwise.
128
+ * @private
129
+ */
130
+ _isRemoteService(service) {
131
+ return this._getServiceProvider(service).isRemote;
132
+ }
133
+
134
+ /**
135
+ * Like {@link call}, but force the call to be posted through a particular communication channel.
136
+ * @param {object} provider - send the call through this object's `postMessage` function.
137
+ * @param {string} service - the name of the service.
138
+ * @param {string} method - the name of the method.
139
+ * @param {*} [args] - the arguments to be copied to the method, if any.
140
+ * @returns {Promise} - a promise for the return value of the service method.
141
+ */
142
+ _remoteCall(provider, service, method) {
143
+ for (var _len3 = arguments.length, args = new Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {
144
+ args[_key3 - 3] = arguments[_key3];
145
+ }
146
+ return this._remoteTransferCall(provider, service, method, null, ...args);
147
+ }
148
+
149
+ /**
150
+ * Like {@link transferCall}, but force the call to be posted through a particular communication channel.
151
+ * @param {object} provider - send the call through this object's `postMessage` function.
152
+ * @param {string} service - the name of the service.
153
+ * @param {string} method - the name of the method.
154
+ * @param {Array} [transfer] - objects to be transferred instead of copied. Must be present in `args` to be useful.
155
+ * @param {*} [args] - the arguments to be copied to the method, if any.
156
+ * @returns {Promise} - a promise for the return value of the service method.
157
+ */
158
+ _remoteTransferCall(provider, service, method, transfer) {
159
+ for (var _len4 = arguments.length, args = new Array(_len4 > 4 ? _len4 - 4 : 0), _key4 = 4; _key4 < _len4; _key4++) {
160
+ args[_key4 - 4] = arguments[_key4];
161
+ }
162
+ return new Promise((resolve, reject) => {
163
+ const responseId = this._storeCallbacks(resolve, reject);
164
+
165
+ /** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */
166
+ if (args.length > 0 && typeof args[args.length - 1].yield === 'function') {
167
+ args.pop();
168
+ }
169
+ if (transfer) {
170
+ provider.postMessage({
171
+ service,
172
+ method,
173
+ responseId,
174
+ args
175
+ }, transfer);
176
+ } else {
177
+ provider.postMessage({
178
+ service,
179
+ method,
180
+ responseId,
181
+ args
182
+ });
183
+ }
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Store callback functions pending a response message.
189
+ * @param {Function} resolve - function to call if the service method returns.
190
+ * @param {Function} reject - function to call if the service method throws.
191
+ * @returns {*} - a unique response ID for this set of callbacks. See {@link _deliverResponse}.
192
+ * @protected
193
+ */
194
+ _storeCallbacks(resolve, reject) {
195
+ const responseId = this.nextResponseId++;
196
+ this.callbacks[responseId] = [resolve, reject];
197
+ return responseId;
198
+ }
199
+
200
+ /**
201
+ * Deliver call response from a worker. This should only be called as the result of a message from a worker.
202
+ * @param {int} responseId - the response ID of the callback set to call.
203
+ * @param {DispatchResponseMessage} message - the message containing the response value(s).
204
+ * @protected
205
+ */
206
+ _deliverResponse(responseId, message) {
207
+ try {
208
+ const [resolve, reject] = this.callbacks[responseId];
209
+ delete this.callbacks[responseId];
210
+ if (message.error) {
211
+ reject(message.error);
212
+ } else {
213
+ resolve(message.result);
214
+ }
215
+ } catch (e) {
216
+ log.error("Dispatch callback failed: ".concat(JSON.stringify(e)));
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Handle a message event received from a connected worker.
222
+ * @param {Worker} worker - the worker which sent the message, or the global object if running in a worker.
223
+ * @param {MessageEvent} event - the message event to be handled.
224
+ * @protected
225
+ */
226
+ _onMessage(worker, event) {
227
+ /** @type {DispatchMessage} */
228
+ const message = event.data;
229
+ message.args = message.args || [];
230
+ let promise;
231
+ if (message.service) {
232
+ if (message.service === 'dispatch') {
233
+ promise = this._onDispatchMessage(worker, message);
234
+ } else {
235
+ promise = this.call(message.service, message.method, ...message.args);
236
+ }
237
+ } else if (typeof message.responseId === 'undefined') {
238
+ log.error("Dispatch caught malformed message from a worker: ".concat(JSON.stringify(event)));
239
+ } else {
240
+ this._deliverResponse(message.responseId, message);
241
+ }
242
+ if (promise) {
243
+ if (typeof message.responseId === 'undefined') {
244
+ log.error("Dispatch message missing required response ID: ".concat(JSON.stringify(event)));
245
+ } else {
246
+ promise.then(result => worker.postMessage({
247
+ responseId: message.responseId,
248
+ result
249
+ }), error => worker.postMessage({
250
+ responseId: message.responseId,
251
+ error
252
+ }));
253
+ }
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Fetch the service provider object for a particular service name.
259
+ * @abstract
260
+ * @param {string} service - the name of the service to look up
261
+ * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found
262
+ * @protected
263
+ */
264
+ _getServiceProvider(service) {
265
+ throw new Error("Could not get provider for ".concat(service, ": _getServiceProvider not implemented"));
266
+ }
267
+
268
+ /**
269
+ * Handle a call message sent to the dispatch service itself
270
+ * @abstract
271
+ * @param {Worker} worker - the worker which sent the message.
272
+ * @param {DispatchCallMessage} message - the message to be handled.
273
+ * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate
274
+ * @private
275
+ */
276
+ _onDispatchMessage(worker, message) {
277
+ throw new Error("Unimplemented dispatch message handler cannot handle ".concat(message.method, " method"));
278
+ }
279
+ }
280
+ module.exports = SharedDispatch;
281
+
282
+ /***/ }),
283
+
284
+ /***/ "./src/dispatch/worker-dispatch.js":
285
+ /*!*****************************************!*\
286
+ !*** ./src/dispatch/worker-dispatch.js ***!
287
+ \*****************************************/
288
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
289
+
290
+ const SharedDispatch = __webpack_require__(/*! ./shared-dispatch */ "./src/dispatch/shared-dispatch.js");
291
+ const log = __webpack_require__(/*! ../util/log */ "./src/util/log.js");
292
+
293
+ /**
294
+ * This class provides a Worker with the means to participate in the message dispatch system managed by CentralDispatch.
295
+ * From any context in the messaging system, the dispatcher's "call" method can call any method on any "service"
296
+ * provided in any participating context. The dispatch system will forward function arguments and return values across
297
+ * worker boundaries as needed.
298
+ * @see {CentralDispatch}
299
+ */
300
+ class WorkerDispatch extends SharedDispatch {
301
+ constructor() {
302
+ super();
303
+
304
+ /**
305
+ * This promise will be resolved when we have successfully connected to central dispatch.
306
+ * @type {Promise}
307
+ * @see {waitForConnection}
308
+ * @private
309
+ */
310
+ this._connectionPromise = new Promise(resolve => {
311
+ this._onConnect = resolve;
312
+ });
313
+
314
+ /**
315
+ * Map of service name to local service provider.
316
+ * If a service is not listed here, it is assumed to be provided by another context (another Worker or the main
317
+ * thread).
318
+ * @see {setService}
319
+ * @type {object}
320
+ */
321
+ this.services = {};
322
+ this._onMessage = this._onMessage.bind(this, self);
323
+ if (typeof self !== 'undefined') {
324
+ self.onmessage = this._onMessage;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * @returns {Promise} a promise which will resolve upon connection to central dispatch. If you need to make a call
330
+ * immediately on "startup" you can attach a 'then' to this promise.
331
+ * @example
332
+ * dispatch.waitForConnection.then(() => {
333
+ * dispatch.call('myService', 'hello');
334
+ * })
335
+ */
336
+ get waitForConnection() {
337
+ return this._connectionPromise;
338
+ }
339
+
340
+ /**
341
+ * Set a local object as the global provider of the specified service.
342
+ * WARNING: Any method on the provider can be called from any worker within the dispatch system.
343
+ * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'.
344
+ * @param {object} provider - a local object which provides this service.
345
+ * @returns {Promise} - a promise which will resolve once the service is registered.
346
+ */
347
+ setService(service, provider) {
348
+ if (Object.prototype.hasOwnProperty.call(this.services, service)) {
349
+ log.warn("Worker dispatch replacing existing service provider for ".concat(service));
350
+ }
351
+ this.services[service] = provider;
352
+ return this.waitForConnection.then(() => this._remoteCall(self, 'dispatch', 'setService', service));
353
+ }
354
+
355
+ /**
356
+ * Fetch the service provider object for a particular service name.
357
+ * @override
358
+ * @param {string} service - the name of the service to look up
359
+ * @returns {{provider:(object|Worker), isRemote:boolean}} - the means to contact the service, if found
360
+ * @protected
361
+ */
362
+ _getServiceProvider(service) {
363
+ // if we don't have a local service by this name, contact central dispatch by calling `postMessage` on self
364
+ const provider = this.services[service];
365
+ return {
366
+ provider: provider || self,
367
+ isRemote: !provider
368
+ };
369
+ }
370
+
371
+ /**
372
+ * Handle a call message sent to the dispatch service itself
373
+ * @override
374
+ * @param {Worker} worker - the worker which sent the message.
375
+ * @param {DispatchCallMessage} message - the message to be handled.
376
+ * @returns {Promise|undefined} - a promise for the results of this operation, if appropriate
377
+ * @protected
378
+ */
379
+ _onDispatchMessage(worker, message) {
380
+ let promise;
381
+ switch (message.method) {
382
+ case 'handshake':
383
+ promise = this._onConnect();
384
+ break;
385
+ case 'terminate':
386
+ // Don't close until next tick, after sending confirmation back
387
+ setTimeout(() => self.close(), 0);
388
+ promise = Promise.resolve();
389
+ break;
390
+ default:
391
+ log.error("Worker dispatch received message for unknown method: ".concat(message.method));
392
+ }
393
+ return promise;
394
+ }
395
+ }
396
+ module.exports = new WorkerDispatch();
397
+
398
+ /***/ }),
399
+
400
+ /***/ "./src/extension-support/argument-type.js":
401
+ /*!************************************************!*\
402
+ !*** ./src/extension-support/argument-type.js ***!
403
+ \************************************************/
404
+ /***/ ((module) => {
405
+
406
+ /**
407
+ * Block argument types
408
+ * @enum {string}
409
+ */
410
+ const ArgumentType = {
411
+ /**
412
+ * Numeric value with angle picker
413
+ */
414
+ ANGLE: 'angle',
415
+ /**
416
+ * Boolean value with hexagonal placeholder
417
+ */
418
+ BOOLEAN: 'Boolean',
419
+ /**
420
+ * Numeric value with color picker
421
+ */
422
+ COLOR: 'color',
423
+ /**
424
+ * Numeric value with text field
425
+ */
426
+ NUMBER: 'number',
427
+ /**
428
+ * String value with text field
429
+ */
430
+ STRING: 'string',
431
+ /**
432
+ * String value with matrix field
433
+ */
434
+ MATRIX: 'matrix',
435
+ /**
436
+ * MIDI note number with note picker (piano) field
437
+ */
438
+ NOTE: 'note',
439
+ /**
440
+ * Inline image on block (as part of the label)
441
+ */
442
+ IMAGE: 'image'
443
+ };
444
+ module.exports = ArgumentType;
445
+
446
+ /***/ }),
447
+
448
+ /***/ "./src/extension-support/block-type.js":
449
+ /*!*********************************************!*\
450
+ !*** ./src/extension-support/block-type.js ***!
451
+ \*********************************************/
452
+ /***/ ((module) => {
453
+
454
+ /**
455
+ * Types of block
456
+ * @enum {string}
457
+ */
458
+ const BlockType = {
459
+ /**
460
+ * Boolean reporter with hexagonal shape
461
+ */
462
+ BOOLEAN: 'Boolean',
463
+ /**
464
+ * A button (not an actual block) for some special action, like making a variable
465
+ */
466
+ BUTTON: 'button',
467
+ /**
468
+ * Command block
469
+ */
470
+ COMMAND: 'command',
471
+ /**
472
+ * Specialized command block which may or may not run a child branch
473
+ * The thread continues with the next block whether or not a child branch ran.
474
+ */
475
+ CONDITIONAL: 'conditional',
476
+ /**
477
+ * Specialized hat block with no implementation function
478
+ * This stack only runs if the corresponding event is emitted by other code.
479
+ */
480
+ EVENT: 'event',
481
+ /**
482
+ * Hat block which conditionally starts a block stack
483
+ */
484
+ HAT: 'hat',
485
+ /**
486
+ * Specialized command block which may or may not run a child branch
487
+ * If a child branch runs, the thread evaluates the loop block again.
488
+ */
489
+ LOOP: 'loop',
490
+ /**
491
+ * General reporter with numeric or string value
492
+ */
493
+ REPORTER: 'reporter'
494
+ };
495
+ module.exports = BlockType;
496
+
497
+ /***/ }),
498
+
499
+ /***/ "./src/extension-support/target-type.js":
500
+ /*!**********************************************!*\
501
+ !*** ./src/extension-support/target-type.js ***!
502
+ \**********************************************/
503
+ /***/ ((module) => {
504
+
505
+ /**
506
+ * Default types of Target supported by the VM
507
+ * @enum {string}
508
+ */
509
+ const TargetType = {
510
+ /**
511
+ * Rendered target which can move, change costumes, etc.
512
+ */
513
+ SPRITE: 'sprite',
514
+ /**
515
+ * Rendered target which cannot move but can change backdrops
516
+ */
517
+ STAGE: 'stage'
518
+ };
519
+ module.exports = TargetType;
520
+
521
+ /***/ }),
522
+
523
+ /***/ "./src/util/log.js":
524
+ /*!*************************!*\
525
+ !*** ./src/util/log.js ***!
526
+ \*************************/
527
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
528
+
529
+ const minilog = __webpack_require__(/*! minilog */ "./node_modules/minilog/lib/web/index.js");
530
+ minilog.enable();
531
+ module.exports = minilog('vm');
532
+
533
+ /***/ }),
534
+
535
+ /***/ "./node_modules/microee/index.js":
536
+ /*!***************************************!*\
537
+ !*** ./node_modules/microee/index.js ***!
538
+ \***************************************/
539
+ /***/ ((module) => {
540
+
541
+ function M() { this._events = {}; }
542
+ M.prototype = {
543
+ on: function(ev, cb) {
544
+ this._events || (this._events = {});
545
+ var e = this._events;
546
+ (e[ev] || (e[ev] = [])).push(cb);
547
+ return this;
548
+ },
549
+ removeListener: function(ev, cb) {
550
+ var e = this._events[ev] || [], i;
551
+ for(i = e.length-1; i >= 0 && e[i]; i--){
552
+ if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); }
553
+ }
554
+ },
555
+ removeAllListeners: function(ev) {
556
+ if(!ev) { this._events = {}; }
557
+ else { this._events[ev] && (this._events[ev] = []); }
558
+ },
559
+ listeners: function(ev) {
560
+ return (this._events ? this._events[ev] || [] : []);
561
+ },
562
+ emit: function(ev) {
563
+ this._events || (this._events = {});
564
+ var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || [];
565
+ for(i = e.length-1; i >= 0 && e[i]; i--){
566
+ e[i].apply(this, args);
567
+ }
568
+ return this;
569
+ },
570
+ when: function(ev, cb) {
571
+ return this.once(ev, cb, true);
572
+ },
573
+ once: function(ev, cb, when) {
574
+ if(!cb) return this;
575
+ function c() {
576
+ if(!when) this.removeListener(ev, c);
577
+ if(cb.apply(this, arguments) && when) this.removeListener(ev, c);
578
+ }
579
+ c.cb = cb;
580
+ this.on(ev, c);
581
+ return this;
582
+ }
583
+ };
584
+ M.mixin = function(dest) {
585
+ var o = M.prototype, k;
586
+ for (k in o) {
587
+ o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
588
+ }
589
+ };
590
+ module.exports = M;
591
+
592
+
593
+ /***/ }),
594
+
595
+ /***/ "./node_modules/minilog/lib/common/filter.js":
596
+ /*!***************************************************!*\
597
+ !*** ./node_modules/minilog/lib/common/filter.js ***!
598
+ \***************************************************/
599
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
600
+
601
+ // default filter
602
+ var Transform = __webpack_require__(/*! ./transform.js */ "./node_modules/minilog/lib/common/transform.js");
603
+
604
+ var levelMap = { debug: 1, info: 2, warn: 3, error: 4 };
605
+
606
+ function Filter() {
607
+ this.enabled = true;
608
+ this.defaultResult = true;
609
+ this.clear();
610
+ }
611
+
612
+ Transform.mixin(Filter);
613
+
614
+ // allow all matching, with level >= given level
615
+ Filter.prototype.allow = function(name, level) {
616
+ this._white.push({ n: name, l: levelMap[level] });
617
+ return this;
618
+ };
619
+
620
+ // deny all matching, with level <= given level
621
+ Filter.prototype.deny = function(name, level) {
622
+ this._black.push({ n: name, l: levelMap[level] });
623
+ return this;
624
+ };
625
+
626
+ Filter.prototype.clear = function() {
627
+ this._white = [];
628
+ this._black = [];
629
+ return this;
630
+ };
631
+
632
+ function test(rule, name) {
633
+ // use .test for RegExps
634
+ return (rule.n.test ? rule.n.test(name) : rule.n == name);
635
+ };
636
+
637
+ Filter.prototype.test = function(name, level) {
638
+ var i, len = Math.max(this._white.length, this._black.length);
639
+ for(i = 0; i < len; i++) {
640
+ if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) {
641
+ return true;
642
+ }
643
+ if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) {
644
+ return false;
645
+ }
646
+ }
647
+ return this.defaultResult;
648
+ };
649
+
650
+ Filter.prototype.write = function(name, level, args) {
651
+ if(!this.enabled || this.test(name, level)) {
652
+ return this.emit('item', name, level, args);
653
+ }
654
+ };
655
+
656
+ module.exports = Filter;
657
+
658
+
659
+ /***/ }),
660
+
661
+ /***/ "./node_modules/minilog/lib/common/minilog.js":
662
+ /*!****************************************************!*\
663
+ !*** ./node_modules/minilog/lib/common/minilog.js ***!
664
+ \****************************************************/
665
+ /***/ ((module, exports, __webpack_require__) => {
666
+
667
+ var Transform = __webpack_require__(/*! ./transform.js */ "./node_modules/minilog/lib/common/transform.js"),
668
+ Filter = __webpack_require__(/*! ./filter.js */ "./node_modules/minilog/lib/common/filter.js");
669
+
670
+ var log = new Transform(),
671
+ slice = Array.prototype.slice;
672
+
673
+ exports = module.exports = function create(name) {
674
+ var o = function() { log.write(name, undefined, slice.call(arguments)); return o; };
675
+ o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; };
676
+ o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; };
677
+ o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; };
678
+ o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; };
679
+ o.log = o.debug; // for interface compliance with Node and browser consoles
680
+ o.suggest = exports.suggest;
681
+ o.format = log.format;
682
+ return o;
683
+ };
684
+
685
+ // filled in separately
686
+ exports.defaultBackend = exports.defaultFormatter = null;
687
+
688
+ exports.pipe = function(dest) {
689
+ return log.pipe(dest);
690
+ };
691
+
692
+ exports.end = exports.unpipe = exports.disable = function(from) {
693
+ return log.unpipe(from);
694
+ };
695
+
696
+ exports.Transform = Transform;
697
+ exports.Filter = Filter;
698
+ // this is the default filter that's applied when .enable() is called normally
699
+ // you can bypass it completely and set up your own pipes
700
+ exports.suggest = new Filter();
701
+
702
+ exports.enable = function() {
703
+ if(exports.defaultFormatter) {
704
+ return log.pipe(exports.suggest) // filter
705
+ .pipe(exports.defaultFormatter) // formatter
706
+ .pipe(exports.defaultBackend); // backend
707
+ }
708
+ return log.pipe(exports.suggest) // filter
709
+ .pipe(exports.defaultBackend); // formatter
710
+ };
711
+
712
+
713
+
714
+ /***/ }),
715
+
716
+ /***/ "./node_modules/minilog/lib/common/transform.js":
717
+ /*!******************************************************!*\
718
+ !*** ./node_modules/minilog/lib/common/transform.js ***!
719
+ \******************************************************/
720
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
721
+
722
+ var microee = __webpack_require__(/*! microee */ "./node_modules/microee/index.js");
723
+
724
+ // Implements a subset of Node's stream.Transform - in a cross-platform manner.
725
+ function Transform() {}
726
+
727
+ microee.mixin(Transform);
728
+
729
+ // The write() signature is different from Node's
730
+ // --> makes it much easier to work with objects in logs.
731
+ // One of the lessons from v1 was that it's better to target
732
+ // a good browser rather than the lowest common denominator
733
+ // internally.
734
+ // If you want to use external streams, pipe() to ./stringify.js first.
735
+ Transform.prototype.write = function(name, level, args) {
736
+ this.emit('item', name, level, args);
737
+ };
738
+
739
+ Transform.prototype.end = function() {
740
+ this.emit('end');
741
+ this.removeAllListeners();
742
+ };
743
+
744
+ Transform.prototype.pipe = function(dest) {
745
+ var s = this;
746
+ // prevent double piping
747
+ s.emit('unpipe', dest);
748
+ // tell the dest that it's being piped to
749
+ dest.emit('pipe', s);
750
+
751
+ function onItem() {
752
+ dest.write.apply(dest, Array.prototype.slice.call(arguments));
753
+ }
754
+ function onEnd() { !dest._isStdio && dest.end(); }
755
+
756
+ s.on('item', onItem);
757
+ s.on('end', onEnd);
758
+
759
+ s.when('unpipe', function(from) {
760
+ var match = (from === dest) || typeof from == 'undefined';
761
+ if(match) {
762
+ s.removeListener('item', onItem);
763
+ s.removeListener('end', onEnd);
764
+ dest.emit('unpipe');
765
+ }
766
+ return match;
767
+ });
768
+
769
+ return dest;
770
+ };
771
+
772
+ Transform.prototype.unpipe = function(from) {
773
+ this.emit('unpipe', from);
774
+ return this;
775
+ };
776
+
777
+ Transform.prototype.format = function(dest) {
778
+ throw new Error([
779
+ 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:',
780
+ 'var Minilog = require(\'minilog\');',
781
+ 'Minilog',
782
+ ' .pipe(Minilog.backends.console.formatClean)',
783
+ ' .pipe(Minilog.backends.console);'].join('\n'));
784
+ };
785
+
786
+ Transform.mixin = function(dest) {
787
+ var o = Transform.prototype, k;
788
+ for (k in o) {
789
+ o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
790
+ }
791
+ };
792
+
793
+ module.exports = Transform;
794
+
795
+
796
+ /***/ }),
797
+
798
+ /***/ "./node_modules/minilog/lib/web/array.js":
799
+ /*!***********************************************!*\
800
+ !*** ./node_modules/minilog/lib/web/array.js ***!
801
+ \***********************************************/
802
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
803
+
804
+ var Transform = __webpack_require__(/*! ../common/transform.js */ "./node_modules/minilog/lib/common/transform.js"),
805
+ cache = [ ];
806
+
807
+ var logger = new Transform();
808
+
809
+ logger.write = function(name, level, args) {
810
+ cache.push([ name, level, args ]);
811
+ };
812
+
813
+ // utility functions
814
+ logger.get = function() { return cache; };
815
+ logger.empty = function() { cache = []; };
816
+
817
+ module.exports = logger;
818
+
819
+
820
+ /***/ }),
821
+
822
+ /***/ "./node_modules/minilog/lib/web/console.js":
823
+ /*!*************************************************!*\
824
+ !*** ./node_modules/minilog/lib/web/console.js ***!
825
+ \*************************************************/
826
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
827
+
828
+ var Transform = __webpack_require__(/*! ../common/transform.js */ "./node_modules/minilog/lib/common/transform.js");
829
+
830
+ var newlines = /\n+$/,
831
+ logger = new Transform();
832
+
833
+ logger.write = function(name, level, args) {
834
+ var i = args.length-1;
835
+ if (typeof console === 'undefined' || !console.log) {
836
+ return;
837
+ }
838
+ if(console.log.apply) {
839
+ return console.log.apply(console, [name, level].concat(args));
840
+ } else if(JSON && JSON.stringify) {
841
+ // console.log.apply is undefined in IE8 and IE9
842
+ // for IE8/9: make console.log at least a bit less awful
843
+ if(args[i] && typeof args[i] == 'string') {
844
+ args[i] = args[i].replace(newlines, '');
845
+ }
846
+ try {
847
+ for(i = 0; i < args.length; i++) {
848
+ args[i] = JSON.stringify(args[i]);
849
+ }
850
+ } catch(e) {}
851
+ console.log(args.join(' '));
852
+ }
853
+ };
854
+
855
+ logger.formatters = ['color', 'minilog'];
856
+ logger.color = __webpack_require__(/*! ./formatters/color.js */ "./node_modules/minilog/lib/web/formatters/color.js");
857
+ logger.minilog = __webpack_require__(/*! ./formatters/minilog.js */ "./node_modules/minilog/lib/web/formatters/minilog.js");
858
+
859
+ module.exports = logger;
860
+
861
+
862
+ /***/ }),
863
+
864
+ /***/ "./node_modules/minilog/lib/web/formatters/color.js":
865
+ /*!**********************************************************!*\
866
+ !*** ./node_modules/minilog/lib/web/formatters/color.js ***!
867
+ \**********************************************************/
868
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
869
+
870
+ var Transform = __webpack_require__(/*! ../../common/transform.js */ "./node_modules/minilog/lib/common/transform.js"),
871
+ color = __webpack_require__(/*! ./util.js */ "./node_modules/minilog/lib/web/formatters/util.js");
872
+
873
+ var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
874
+ logger = new Transform();
875
+
876
+ logger.write = function(name, level, args) {
877
+ var fn = console.log;
878
+ if(console[level] && console[level].apply) {
879
+ fn = console[level];
880
+ fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args));
881
+ }
882
+ };
883
+
884
+ // NOP, because piping the formatted logs can only cause trouble.
885
+ logger.pipe = function() { };
886
+
887
+ module.exports = logger;
888
+
889
+
890
+ /***/ }),
891
+
892
+ /***/ "./node_modules/minilog/lib/web/formatters/minilog.js":
893
+ /*!************************************************************!*\
894
+ !*** ./node_modules/minilog/lib/web/formatters/minilog.js ***!
895
+ \************************************************************/
896
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
897
+
898
+ var Transform = __webpack_require__(/*! ../../common/transform.js */ "./node_modules/minilog/lib/common/transform.js"),
899
+ color = __webpack_require__(/*! ./util.js */ "./node_modules/minilog/lib/web/formatters/util.js"),
900
+ colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
901
+ logger = new Transform();
902
+
903
+ logger.write = function(name, level, args) {
904
+ var fn = console.log;
905
+ if(level != 'debug' && console[level]) {
906
+ fn = console[level];
907
+ }
908
+
909
+ var subset = [], i = 0;
910
+ if(level != 'info') {
911
+ for(; i < args.length; i++) {
912
+ if(typeof args[i] != 'string') break;
913
+ }
914
+ fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i)));
915
+ } else {
916
+ fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args));
917
+ }
918
+ };
919
+
920
+ // NOP, because piping the formatted logs can only cause trouble.
921
+ logger.pipe = function() { };
922
+
923
+ module.exports = logger;
924
+
925
+
926
+ /***/ }),
927
+
928
+ /***/ "./node_modules/minilog/lib/web/formatters/util.js":
929
+ /*!*********************************************************!*\
930
+ !*** ./node_modules/minilog/lib/web/formatters/util.js ***!
931
+ \*********************************************************/
932
+ /***/ ((module) => {
933
+
934
+ var hex = {
935
+ black: '#000',
936
+ red: '#c23621',
937
+ green: '#25bc26',
938
+ yellow: '#bbbb00',
939
+ blue: '#492ee1',
940
+ magenta: '#d338d3',
941
+ cyan: '#33bbc8',
942
+ gray: '#808080',
943
+ purple: '#708'
944
+ };
945
+ function color(fg, isInverse) {
946
+ if(isInverse) {
947
+ return 'color: #fff; background: '+hex[fg]+';';
948
+ } else {
949
+ return 'color: '+hex[fg]+';';
950
+ }
951
+ }
952
+
953
+ module.exports = color;
954
+
955
+
956
+ /***/ }),
957
+
958
+ /***/ "./node_modules/minilog/lib/web/index.js":
959
+ /*!***********************************************!*\
960
+ !*** ./node_modules/minilog/lib/web/index.js ***!
961
+ \***********************************************/
962
+ /***/ ((module, exports, __webpack_require__) => {
963
+
964
+ var Minilog = __webpack_require__(/*! ../common/minilog.js */ "./node_modules/minilog/lib/common/minilog.js");
965
+
966
+ var oldEnable = Minilog.enable,
967
+ oldDisable = Minilog.disable,
968
+ isChrome = (typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent)),
969
+ console = __webpack_require__(/*! ./console.js */ "./node_modules/minilog/lib/web/console.js");
970
+
971
+ // Use a more capable logging backend if on Chrome
972
+ Minilog.defaultBackend = (isChrome ? console.minilog : console);
973
+
974
+ // apply enable inputs from localStorage and from the URL
975
+ if(typeof window != 'undefined') {
976
+ try {
977
+ Minilog.enable(JSON.parse(window.localStorage['minilogSettings']));
978
+ } catch(e) {}
979
+ if(window.location && window.location.search) {
980
+ var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search);
981
+ match && Minilog.enable(decodeURIComponent(match[1]));
982
+ }
983
+ }
984
+
985
+ // Make enable also add to localStorage
986
+ Minilog.enable = function() {
987
+ oldEnable.call(Minilog, true);
988
+ try { window.localStorage['minilogSettings'] = JSON.stringify(true); } catch(e) {}
989
+ return this;
990
+ };
991
+
992
+ Minilog.disable = function() {
993
+ oldDisable.call(Minilog);
994
+ try { delete window.localStorage.minilogSettings; } catch(e) {}
995
+ return this;
996
+ };
997
+
998
+ exports = module.exports = Minilog;
999
+
1000
+ exports.backends = {
1001
+ array: __webpack_require__(/*! ./array.js */ "./node_modules/minilog/lib/web/array.js"),
1002
+ browser: Minilog.defaultBackend,
1003
+ localStorage: __webpack_require__(/*! ./localstorage.js */ "./node_modules/minilog/lib/web/localstorage.js"),
1004
+ jQuery: __webpack_require__(/*! ./jquery_simple.js */ "./node_modules/minilog/lib/web/jquery_simple.js")
1005
+ };
1006
+
1007
+
1008
+ /***/ }),
1009
+
1010
+ /***/ "./node_modules/minilog/lib/web/jquery_simple.js":
1011
+ /*!*******************************************************!*\
1012
+ !*** ./node_modules/minilog/lib/web/jquery_simple.js ***!
1013
+ \*******************************************************/
1014
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1015
+
1016
+ var Transform = __webpack_require__(/*! ../common/transform.js */ "./node_modules/minilog/lib/common/transform.js");
1017
+
1018
+ var cid = new Date().valueOf().toString(36);
1019
+
1020
+ function AjaxLogger(options) {
1021
+ this.url = options.url || '';
1022
+ this.cache = [];
1023
+ this.timer = null;
1024
+ this.interval = options.interval || 30*1000;
1025
+ this.enabled = true;
1026
+ this.jQuery = window.jQuery;
1027
+ this.extras = {};
1028
+ }
1029
+
1030
+ Transform.mixin(AjaxLogger);
1031
+
1032
+ AjaxLogger.prototype.write = function(name, level, args) {
1033
+ if(!this.timer) { this.init(); }
1034
+ this.cache.push([name, level].concat(args));
1035
+ };
1036
+
1037
+ AjaxLogger.prototype.init = function() {
1038
+ if(!this.enabled || !this.jQuery) return;
1039
+ var self = this;
1040
+ this.timer = setTimeout(function() {
1041
+ var i, logs = [], ajaxData, url = self.url;
1042
+ if(self.cache.length == 0) return self.init();
1043
+ // Test each log line and only log the ones that are valid (e.g. don't have circular references).
1044
+ // Slight performance hit but benefit is we log all valid lines.
1045
+ for(i = 0; i < self.cache.length; i++) {
1046
+ try {
1047
+ JSON.stringify(self.cache[i]);
1048
+ logs.push(self.cache[i]);
1049
+ } catch(e) { }
1050
+ }
1051
+ if(self.jQuery.isEmptyObject(self.extras)) {
1052
+ ajaxData = JSON.stringify({ logs: logs });
1053
+ url = self.url + '?client_id=' + cid;
1054
+ } else {
1055
+ ajaxData = JSON.stringify(self.jQuery.extend({logs: logs}, self.extras));
1056
+ }
1057
+
1058
+ self.jQuery.ajax(url, {
1059
+ type: 'POST',
1060
+ cache: false,
1061
+ processData: false,
1062
+ data: ajaxData,
1063
+ contentType: 'application/json',
1064
+ timeout: 10000
1065
+ }).success(function(data, status, jqxhr) {
1066
+ if(data.interval) {
1067
+ self.interval = Math.max(1000, data.interval);
1068
+ }
1069
+ }).error(function() {
1070
+ self.interval = 30000;
1071
+ }).always(function() {
1072
+ self.init();
1073
+ });
1074
+ self.cache = [];
1075
+ }, this.interval);
1076
+ };
1077
+
1078
+ AjaxLogger.prototype.end = function() {};
1079
+
1080
+ // wait until jQuery is defined. Useful if you don't control the load order.
1081
+ AjaxLogger.jQueryWait = function(onDone) {
1082
+ if(typeof window !== 'undefined' && (window.jQuery || window.$)) {
1083
+ return onDone(window.jQuery || window.$);
1084
+ } else if (typeof window !== 'undefined') {
1085
+ setTimeout(function() { AjaxLogger.jQueryWait(onDone); }, 200);
1086
+ }
1087
+ };
1088
+
1089
+ module.exports = AjaxLogger;
1090
+
1091
+
1092
+ /***/ }),
1093
+
1094
+ /***/ "./node_modules/minilog/lib/web/localstorage.js":
1095
+ /*!******************************************************!*\
1096
+ !*** ./node_modules/minilog/lib/web/localstorage.js ***!
1097
+ \******************************************************/
1098
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1099
+
1100
+ var Transform = __webpack_require__(/*! ../common/transform.js */ "./node_modules/minilog/lib/common/transform.js"),
1101
+ cache = false;
1102
+
1103
+ var logger = new Transform();
1104
+
1105
+ logger.write = function(name, level, args) {
1106
+ if(typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return;
1107
+ try {
1108
+ if(!cache) { cache = (window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : []); }
1109
+ cache.push([ new Date().toString(), name, level, args ]);
1110
+ window.localStorage.minilog = JSON.stringify(cache);
1111
+ } catch(e) {}
1112
+ };
1113
+
1114
+ module.exports = logger;
1115
+
1116
+ /***/ })
1117
+
1118
+ /******/ });
1119
+ /************************************************************************/
1120
+ /******/ // The module cache
1121
+ /******/ var __webpack_module_cache__ = {};
1122
+ /******/
1123
+ /******/ // The require function
1124
+ /******/ function __webpack_require__(moduleId) {
1125
+ /******/ // Check if module is in cache
1126
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
1127
+ /******/ if (cachedModule !== undefined) {
1128
+ /******/ return cachedModule.exports;
1129
+ /******/ }
1130
+ /******/ // Create a new module (and put it into the cache)
1131
+ /******/ var module = __webpack_module_cache__[moduleId] = {
1132
+ /******/ // no module.id needed
1133
+ /******/ // no module.loaded needed
1134
+ /******/ exports: {}
1135
+ /******/ };
1136
+ /******/
1137
+ /******/ // Execute the module function
1138
+ /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
1139
+ /******/
1140
+ /******/ // Return the exports of the module
1141
+ /******/ return module.exports;
1142
+ /******/ }
1143
+ /******/
1144
+ /************************************************************************/
1145
+ /******/ /* webpack/runtime/global */
1146
+ /******/ (() => {
1147
+ /******/ __webpack_require__.g = (function() {
1148
+ /******/ if (typeof globalThis === 'object') return globalThis;
1149
+ /******/ try {
1150
+ /******/ return this || new Function('return this')();
1151
+ /******/ } catch (e) {
1152
+ /******/ if (typeof window === 'object') return window;
1153
+ /******/ }
1154
+ /******/ })();
1155
+ /******/ })();
1156
+ /******/
1157
+ /************************************************************************/
1158
+ var __webpack_exports__ = {};
1159
+ /*!***************************************************!*\
1160
+ !*** ./src/extension-support/extension-worker.js ***!
1161
+ \***************************************************/
1162
+ /* eslint-env worker */
1163
+
1164
+ const ArgumentType = __webpack_require__(/*! ../extension-support/argument-type */ "./src/extension-support/argument-type.js");
1165
+ const BlockType = __webpack_require__(/*! ../extension-support/block-type */ "./src/extension-support/block-type.js");
1166
+ const dispatch = __webpack_require__(/*! ../dispatch/worker-dispatch */ "./src/dispatch/worker-dispatch.js");
1167
+ const TargetType = __webpack_require__(/*! ../extension-support/target-type */ "./src/extension-support/target-type.js");
1168
+ class ExtensionWorker {
1169
+ constructor() {
1170
+ this.nextExtensionId = 0;
1171
+ this.initialRegistrations = [];
1172
+ dispatch.waitForConnection.then(() => {
1173
+ dispatch.call('extensions', 'allocateWorker').then(x => {
1174
+ const [id, extension] = x;
1175
+ this.workerId = id;
1176
+ try {
1177
+ importScripts(extension);
1178
+ const initialRegistrations = this.initialRegistrations;
1179
+ this.initialRegistrations = null;
1180
+ Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));
1181
+ } catch (e) {
1182
+ dispatch.call('extensions', 'onWorkerInit', id, e);
1183
+ }
1184
+ });
1185
+ });
1186
+ this.extensions = [];
1187
+ }
1188
+ register(extensionObject) {
1189
+ const extensionId = this.nextExtensionId++;
1190
+ this.extensions.push(extensionObject);
1191
+ const serviceName = "extension.".concat(this.workerId, ".").concat(extensionId);
1192
+ const promise = dispatch.setService(serviceName, extensionObject).then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));
1193
+ if (this.initialRegistrations) {
1194
+ this.initialRegistrations.push(promise);
1195
+ }
1196
+ return promise;
1197
+ }
1198
+ }
1199
+ __webpack_require__.g.Scratch = __webpack_require__.g.Scratch || {};
1200
+ __webpack_require__.g.Scratch.ArgumentType = ArgumentType;
1201
+ __webpack_require__.g.Scratch.BlockType = BlockType;
1202
+ __webpack_require__.g.Scratch.TargetType = TargetType;
1203
+
1204
+ /**
1205
+ * Expose only specific parts of the worker to extensions.
1206
+ */
1207
+ const extensionWorker = new ExtensionWorker();
1208
+ __webpack_require__.g.Scratch.extensions = {
1209
+ register: extensionWorker.register.bind(extensionWorker)
1210
+ };
1211
+ /******/ return __webpack_exports__;
1212
+ /******/ })()
1213
+ ;
1214
+ });
1215
+ //# sourceMappingURL=extension-worker.js.map