sb-edit-custom 0.15.0

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,628 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
+ return new (P || (P = Promise))(function (resolve, reject) {
39
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
42
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
43
+ });
44
+ };
45
+ var __generator = (this && this.__generator) || function (thisArg, body) {
46
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
47
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
48
+ function verb(n) { return function (v) { return step([n, v]); }; }
49
+ function step(op) {
50
+ if (f) throw new TypeError("Generator is already executing.");
51
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
52
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
53
+ if (y = 0, t) op = [op[0] & 2, t.value];
54
+ switch (op[0]) {
55
+ case 0: case 1: t = op; break;
56
+ case 4: _.label++; return { value: op[1], done: false };
57
+ case 5: _.label++; y = op[1]; op = [0]; continue;
58
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
59
+ default:
60
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
61
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
62
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
63
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
64
+ if (t[2]) _.ops.pop();
65
+ _.trys.pop(); continue;
66
+ }
67
+ op = body.call(thisArg, _);
68
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
69
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
70
+ }
71
+ };
72
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
73
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
74
+ if (ar || !(i in from)) {
75
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
76
+ ar[i] = from[i];
77
+ }
78
+ }
79
+ return to.concat(ar || Array.prototype.slice.call(from));
80
+ };
81
+ var __importDefault = (this && this.__importDefault) || function (mod) {
82
+ return (mod && mod.__esModule) ? mod : { "default": mod };
83
+ };
84
+ Object.defineProperty(exports, "__esModule", { value: true });
85
+ exports.fromSb3JSON = void 0;
86
+ var JSZip = __importStar(require("jszip"));
87
+ var sb3 = __importStar(require("./interfaces"));
88
+ var OpCode_1 = require("../../OpCode");
89
+ var Block_1 = require("../../Block");
90
+ var Costume_1 = __importDefault(require("../../Costume"));
91
+ var Project_1 = __importDefault(require("../../Project"));
92
+ var Sound_1 = __importDefault(require("../../Sound"));
93
+ var Target_1 = require("../../Target");
94
+ var Data_1 = require("../../Data");
95
+ var Script_1 = __importDefault(require("../../Script"));
96
+ function extractCostumes(target, getAsset) {
97
+ var _this = this;
98
+ return Promise.all(target.costumes.map(function (costumeData) { return __awaiter(_this, void 0, void 0, function () {
99
+ var _a;
100
+ var _b;
101
+ return __generator(this, function (_c) {
102
+ switch (_c.label) {
103
+ case 0:
104
+ console.log("Target: ".concat(target.name));
105
+ console.log("".concat(costumeData.assetId, ".").concat(costumeData.dataFormat));
106
+ _a = Costume_1.default.bind;
107
+ _b = {
108
+ name: costumeData.name
109
+ };
110
+ return [4 /*yield*/, getAsset({
111
+ type: "costume",
112
+ name: costumeData.name,
113
+ md5: costumeData.assetId,
114
+ ext: costumeData.dataFormat,
115
+ spriteName: target.name
116
+ })];
117
+ case 1: return [2 /*return*/, new (_a.apply(Costume_1.default, [void 0, (_b.asset = _c.sent(),
118
+ _b.md5 = costumeData.assetId,
119
+ _b.ext = costumeData.dataFormat === 'svg' ? 'png' : costumeData.dataFormat,
120
+ _b.wasSvg = costumeData.dataFormat === 'svg',
121
+ // It's possible that the rotation center of the costume is null.
122
+ // Because computing a rotation center ourselves would be messy and
123
+ // easily incompatible with Scratch, pass such complexity onto the
124
+ // Scratch implementation running a project exported from sb-edit.
125
+ _b.bitmapResolution = costumeData.bitmapResolution || 2,
126
+ _b.centerX = costumeData.rotationCenterX,
127
+ _b.centerY = costumeData.rotationCenterY,
128
+ _b)]))()];
129
+ }
130
+ });
131
+ }); }));
132
+ }
133
+ function extractSounds(target, getAsset) {
134
+ return __awaiter(this, void 0, void 0, function () {
135
+ var _this = this;
136
+ return __generator(this, function (_a) {
137
+ return [2 /*return*/, Promise.all(target.sounds.map(function (soundData) { return __awaiter(_this, void 0, void 0, function () {
138
+ var _a;
139
+ var _b;
140
+ return __generator(this, function (_c) {
141
+ switch (_c.label) {
142
+ case 0:
143
+ _a = Sound_1.default.bind;
144
+ _b = {
145
+ name: soundData.name
146
+ };
147
+ return [4 /*yield*/, getAsset({
148
+ type: "sound",
149
+ name: soundData.name,
150
+ md5: soundData.assetId,
151
+ ext: soundData.dataFormat,
152
+ spriteName: target.name
153
+ })];
154
+ case 1: return [2 /*return*/, new (_a.apply(Sound_1.default, [void 0, (_b.asset = _c.sent(),
155
+ _b.md5 = soundData.assetId,
156
+ _b.ext = soundData.dataFormat,
157
+ _b.sampleCount = soundData.sampleCount,
158
+ _b.sampleRate = soundData.rate,
159
+ _b)]))()];
160
+ }
161
+ });
162
+ }); }))];
163
+ });
164
+ });
165
+ }
166
+ function getBlockScript(blocks) {
167
+ function getBlockInputs(block, blockId) {
168
+ return __assign(__assign({}, translateInputs(block.inputs)), translateFields(block.fields, block.opcode));
169
+ function translateInputs(inputs) {
170
+ var result = {};
171
+ // TODO: do we really need to create a new object every time?
172
+ var addInput = function (name, value) {
173
+ var _a;
174
+ result = __assign(__assign({}, result), (_a = {}, _a[name] = value, _a));
175
+ };
176
+ var _loop_1 = function (inputName, input) {
177
+ var value = input[1];
178
+ if (typeof value === "string") {
179
+ var block_1 = blocks[value];
180
+ var inputScript = blockWithNext(value, blockId);
181
+ if (inputScript.length === 1 && blocks[value].shadow) {
182
+ // Procedure prototype (the "example" of what a custom procedure looks like,
183
+ // inside the "define" block) - this is considered a shadow block but requires
184
+ // special care compared to normal shadow blocks, so handle it separately.
185
+ if (block_1.opcode === OpCode_1.OpCode.procedures_prototype) {
186
+ var mutation = block_1.mutation;
187
+ // Split proccode (such as "letter %n of %s") into ["letter", "%n", "of", "%s"]
188
+ var parts = mutation.proccode.split(/((^|[^\\])%[nsb])/);
189
+ parts = parts.map(function (str) { return str.trim(); });
190
+ parts = parts.filter(function (str) { return str !== ""; });
191
+ var argNames_1 = JSON.parse(mutation.argumentnames);
192
+ var argDefaults_1 = JSON.parse(mutation.argumentdefaults);
193
+ var args = parts.map(function (part) {
194
+ var optionalToNumber = function (value) {
195
+ if (typeof value !== "string") {
196
+ return value;
197
+ }
198
+ var asNum = Number(value);
199
+ if (!isNaN(asNum)) {
200
+ return asNum;
201
+ }
202
+ return value;
203
+ };
204
+ switch (part) {
205
+ case "%s":
206
+ case "%n":
207
+ return {
208
+ type: "numberOrString",
209
+ // TODO: remove non-null assertions
210
+ name: argNames_1.shift(),
211
+ defaultValue: optionalToNumber(argDefaults_1.shift())
212
+ };
213
+ case "%b":
214
+ return {
215
+ type: "boolean",
216
+ // TODO: remove non-null assertions
217
+ name: argNames_1.shift(),
218
+ defaultValue: argDefaults_1.shift() === "true"
219
+ };
220
+ default:
221
+ return {
222
+ type: "label",
223
+ name: part
224
+ };
225
+ }
226
+ });
227
+ addInput("PROCCODE", { type: "string", value: mutation.proccode });
228
+ addInput("ARGUMENTS", { type: "customBlockArguments", value: args });
229
+ addInput("WARP", { type: "boolean", value: mutation.warp === "true" });
230
+ }
231
+ else {
232
+ // Input contains a shadow block. Conceptually, shadow blocks are weird.
233
+ // We basically just want to copy the important information from the
234
+ // shadow block down into the block containing the shadow. There are some
235
+ // special cases so compute the inputs and fields up-front, then decide
236
+ // how to apply them.
237
+ var shadowInputs = translateInputs(blocks[value].inputs);
238
+ var shadowFields = translateFields(blocks[value].fields, blocks[value].opcode);
239
+ if (blocks[value].opcode === "pen_menu_colorParam") {
240
+ result = __assign(__assign({}, result), { COLOR_PARAM: shadowFields.colorParam });
241
+ }
242
+ else {
243
+ // For most shadow blocks, just copy the shadow block's fields and inputs
244
+ // into its parent using the exact same names.
245
+ result = __assign(__assign(__assign({}, result), shadowInputs), shadowFields);
246
+ }
247
+ }
248
+ }
249
+ else {
250
+ var isBlocks = void 0;
251
+ if (Block_1.BlockBase.isKnownBlock(block_1.opcode)) {
252
+ var defaultInput = Block_1.BlockBase.getDefaultInput(block_1.opcode, inputName);
253
+ if (defaultInput && defaultInput.type === "blocks") {
254
+ isBlocks = true;
255
+ }
256
+ }
257
+ isBlocks = isBlocks || inputScript.length > 1;
258
+ if (isBlocks) {
259
+ addInput(inputName, { type: "blocks", value: inputScript });
260
+ }
261
+ else {
262
+ addInput(inputName, { type: "block", value: inputScript[0] });
263
+ }
264
+ }
265
+ }
266
+ else if (value === null) {
267
+ return "continue";
268
+ }
269
+ else {
270
+ var BIS = sb3.BlockInputStatus;
271
+ switch (value[0]) {
272
+ case BIS.MATH_NUM_PRIMITIVE:
273
+ case BIS.POSITIVE_NUM_PRIMITIVE:
274
+ case BIS.WHOLE_NUM_PRIMITIVE:
275
+ case BIS.INTEGER_NUM_PRIMITIVE: {
276
+ var storedValue = value[1];
277
+ var asNum = Number(storedValue);
278
+ if (!isNaN(asNum)) {
279
+ storedValue = asNum;
280
+ }
281
+ addInput(inputName, { type: "number", value: storedValue });
282
+ break;
283
+ }
284
+ case BIS.ANGLE_NUM_PRIMITIVE:
285
+ addInput(inputName, { type: "angle", value: Number(value[1]) });
286
+ break;
287
+ case BIS.COLOR_PICKER_PRIMITIVE:
288
+ addInput(inputName, {
289
+ type: "color",
290
+ value: {
291
+ r: parseInt(value[1].slice(1, 3), 16),
292
+ g: parseInt(value[1].slice(3, 5), 16),
293
+ b: parseInt(value[1].slice(5, 7), 16)
294
+ }
295
+ });
296
+ break;
297
+ case BIS.TEXT_PRIMITIVE:
298
+ addInput(inputName, { type: "string", value: value[1] });
299
+ break;
300
+ case BIS.BROADCAST_PRIMITIVE:
301
+ addInput(inputName, { type: "broadcast", value: value[1] });
302
+ break;
303
+ case BIS.VAR_PRIMITIVE:
304
+ // This is a variable input. Convert it to a variable block.
305
+ addInput(inputName, {
306
+ type: "block",
307
+ value: new Block_1.BlockBase({
308
+ opcode: OpCode_1.OpCode.data_variable,
309
+ inputs: { VARIABLE: { type: "variable", value: { id: value[2], name: value[1] } } },
310
+ parent: blockId
311
+ })
312
+ });
313
+ break;
314
+ case BIS.LIST_PRIMITIVE:
315
+ // This is a list input. Convert it to a list contents block.
316
+ addInput(inputName, {
317
+ type: "block",
318
+ value: new Block_1.BlockBase({
319
+ opcode: OpCode_1.OpCode.data_listcontents,
320
+ inputs: { LIST: { type: "list", value: { id: value[2], name: value[1] } } },
321
+ parent: blockId
322
+ })
323
+ });
324
+ break;
325
+ }
326
+ }
327
+ };
328
+ for (var _i = 0, _a = Object.entries(inputs); _i < _a.length; _i++) {
329
+ var _b = _a[_i], inputName = _b[0], input = _b[1];
330
+ _loop_1(inputName, input);
331
+ }
332
+ if (block.opcode === OpCode_1.OpCode.procedures_call) {
333
+ var mutation = block.mutation;
334
+ result = {
335
+ PROCCODE: { type: "string", value: mutation.proccode },
336
+ INPUTS: {
337
+ type: "customBlockInputValues",
338
+ value: JSON.parse(mutation.argumentids).map(function (argumentid) {
339
+ var value = result[argumentid];
340
+ if (value === undefined) {
341
+ // TODO: Find a way to determine type of missing input value
342
+ // (Caused by things like boolean procedure_call inputs that
343
+ // were never filled at any time.)
344
+ return { type: "boolean", value: false };
345
+ }
346
+ // Auto-coerce number inputs into numbers
347
+ // TODO: this may lose data!
348
+ if (typeof value.value === "string") {
349
+ var asNum = Number(value.value);
350
+ if (!isNaN(asNum)) {
351
+ value.value = asNum;
352
+ }
353
+ }
354
+ return value;
355
+ })
356
+ }
357
+ };
358
+ }
359
+ return result;
360
+ }
361
+ function translateFields(fields, opcode) {
362
+ var fieldTypes = sb3.fieldTypeMap[opcode];
363
+ if (!fieldTypes)
364
+ return {};
365
+ var result = {};
366
+ for (var _i = 0, _a = Object.entries(fields); _i < _a.length; _i++) {
367
+ var _b = _a[_i], fieldName = _b[0], values = _b[1];
368
+ var type = fieldTypes[fieldName];
369
+ // TODO: remove this type assertion and actually validate fields
370
+ if (fieldName === "VARIABLE" || fieldName === "LIST") {
371
+ result[fieldName] = { type: type, value: { id: values[1], name: values[0] } };
372
+ }
373
+ else {
374
+ result[fieldName] = { type: type, value: values[0] };
375
+ }
376
+ }
377
+ return result;
378
+ }
379
+ }
380
+ function blockWithNext(blockId, parentId) {
381
+ var _a;
382
+ var sb3Block = blocks[blockId];
383
+ var block = new Block_1.BlockBase({
384
+ opcode: sb3Block.opcode,
385
+ inputs: getBlockInputs(sb3Block, blockId),
386
+ id: blockId,
387
+ parent: parentId,
388
+ next: (_a = sb3Block.next) !== null && _a !== void 0 ? _a : undefined
389
+ });
390
+ var next = [];
391
+ if (typeof sb3Block.next === "string") {
392
+ next = blockWithNext(sb3Block.next, blockId);
393
+ }
394
+ return __spreadArray([block], next, true);
395
+ }
396
+ return blockWithNext;
397
+ }
398
+ function fromSb3JSON(json, options) {
399
+ return __awaiter(this, void 0, void 0, function () {
400
+ function getVariables(target) {
401
+ return Object.entries(target.variables).map(function (_a) {
402
+ var _b;
403
+ var id = _a[0], _c = _a[1], name = _c[0], value = _c[1], _d = _c[2], cloud = _d === void 0 ? false : _d;
404
+ var monitor = (_b = json.monitors) === null || _b === void 0 ? void 0 : _b.find(function (monitor) { return monitor.id === id; });
405
+ if (!monitor) {
406
+ // Sometimes .sb3 files are missing monitors. Fill in with reasonable defaults.
407
+ monitor = {
408
+ id: id,
409
+ mode: "default",
410
+ opcode: "data_variable",
411
+ params: { VARIABLE: name },
412
+ spriteName: target.name,
413
+ value: value,
414
+ width: null,
415
+ height: null,
416
+ x: 0,
417
+ y: 0,
418
+ visible: false,
419
+ sliderMin: 0,
420
+ sliderMax: 100,
421
+ isDiscrete: true
422
+ };
423
+ }
424
+ return new Data_1.Variable({
425
+ name: name,
426
+ id: id,
427
+ value: value,
428
+ cloud: cloud,
429
+ visible: monitor.visible,
430
+ mode: monitor.mode,
431
+ x: monitor.x,
432
+ y: monitor.y,
433
+ sliderMin: monitor.sliderMin,
434
+ sliderMax: monitor.sliderMax,
435
+ isDiscrete: monitor.isDiscrete
436
+ });
437
+ });
438
+ }
439
+ function getLists(target) {
440
+ return Object.entries(target.lists).map(function (_a) {
441
+ var _b;
442
+ var id = _a[0], _c = _a[1], name = _c[0], value = _c[1];
443
+ var monitor = (_b = json.monitors) === null || _b === void 0 ? void 0 : _b.find(function (monitor) { return monitor.id === id; });
444
+ if (!monitor) {
445
+ // Sometimes .sb3 files are missing monitors. Fill in with reasonable defaults.
446
+ monitor = {
447
+ id: id,
448
+ mode: "list",
449
+ opcode: "data_listcontents",
450
+ params: { LIST: name },
451
+ spriteName: target.name,
452
+ value: value,
453
+ width: null,
454
+ height: null,
455
+ x: 0,
456
+ y: 0,
457
+ visible: false
458
+ };
459
+ }
460
+ return new Data_1.List({
461
+ name: name,
462
+ id: id,
463
+ value: value,
464
+ visible: monitor.visible,
465
+ x: monitor.x,
466
+ y: monitor.y,
467
+ // set width and height to undefined if they're 0, null, or undefined
468
+ width: monitor.width || undefined,
469
+ height: monitor.height || undefined
470
+ });
471
+ });
472
+ }
473
+ function getTargetOptions(target) {
474
+ return __awaiter(this, void 0, void 0, function () {
475
+ var _a, costumes, sounds, getScript;
476
+ return __generator(this, function (_b) {
477
+ switch (_b.label) {
478
+ case 0: return [4 /*yield*/, Promise.all([
479
+ extractCostumes(target, options.getAsset),
480
+ extractSounds(target, options.getAsset)
481
+ ])];
482
+ case 1:
483
+ _a = _b.sent(), costumes = _a[0], sounds = _a[1];
484
+ getScript = getBlockScript(target.blocks);
485
+ return [2 /*return*/, {
486
+ name: target.name,
487
+ isStage: target.isStage,
488
+ costumes: costumes,
489
+ costumeNumber: target.currentCostume,
490
+ sounds: sounds,
491
+ scripts: Object.entries(target.blocks)
492
+ .filter(function (_a) {
493
+ var block = _a[1];
494
+ return block.topLevel && !block.shadow;
495
+ })
496
+ .map(function (_a) {
497
+ var id = _a[0], block = _a[1];
498
+ return new Script_1.default({
499
+ blocks: getScript(id),
500
+ x: block.x,
501
+ y: block.y
502
+ });
503
+ }),
504
+ variables: getVariables(target),
505
+ lists: getLists(target),
506
+ volume: target.volume,
507
+ layerOrder: target.layerOrder
508
+ }];
509
+ }
510
+ });
511
+ });
512
+ }
513
+ var stage, project, _a, _b, _i, _c, target, relevantBlocks, usedVariableIds, _d, relevantBlocks_1, block, id, _e, _f, varList, i, variable;
514
+ var _g;
515
+ var _this = this;
516
+ return __generator(this, function (_h) {
517
+ switch (_h.label) {
518
+ case 0:
519
+ stage = json.targets.find(function (target) { return target.isStage; });
520
+ _a = Project_1.default.bind;
521
+ _g = {};
522
+ _b = Target_1.Stage.bind;
523
+ return [4 /*yield*/, getTargetOptions(stage)];
524
+ case 1:
525
+ _g.stage = new (_b.apply(Target_1.Stage, [void 0, _h.sent()]))();
526
+ return [4 /*yield*/, Promise.all(json.targets
527
+ .filter(function (target) { return !target.isStage; })
528
+ .map(function (spriteData) { return __awaiter(_this, void 0, void 0, function () {
529
+ var _a, _b;
530
+ return __generator(this, function (_c) {
531
+ switch (_c.label) {
532
+ case 0:
533
+ _a = Target_1.Sprite.bind;
534
+ _b = [{}];
535
+ return [4 /*yield*/, getTargetOptions(spriteData)];
536
+ case 1: return [2 /*return*/, new (_a.apply(Target_1.Sprite, [void 0, __assign.apply(void 0, [__assign.apply(void 0, _b.concat([(_c.sent())])), { x: spriteData.x, y: spriteData.y, size: spriteData.size, direction: spriteData.direction, rotationStyle: {
537
+ "all around": "normal",
538
+ "left-right": "leftRight",
539
+ "don't rotate": "none"
540
+ }[spriteData.rotationStyle], isDraggable: spriteData.draggable, visible: spriteData.visible }])]))()];
541
+ }
542
+ });
543
+ }); }))];
544
+ case 2:
545
+ project = new (_a.apply(Project_1.default, [void 0, (_g.sprites = _h.sent(),
546
+ _g.tempo = stage.tempo,
547
+ _g.videoOn = stage.videoState === "on",
548
+ _g.videoAlpha = stage.videoTransparency,
549
+ _g)]))();
550
+ // Run an extra pass on variables (and lists). Only those which are actually
551
+ // referenced in blocks or monitors should be kept.
552
+ for (_i = 0, _c = __spreadArray([project.stage], project.sprites, true); _i < _c.length; _i++) {
553
+ target = _c[_i];
554
+ relevantBlocks = void 0;
555
+ if (target === project.stage) {
556
+ relevantBlocks = target.blocks.concat(project.sprites.flatMap(function (sprite) { return sprite.blocks; }));
557
+ }
558
+ else {
559
+ relevantBlocks = target.blocks;
560
+ }
561
+ usedVariableIds = new Set();
562
+ for (_d = 0, relevantBlocks_1 = relevantBlocks; _d < relevantBlocks_1.length; _d++) {
563
+ block = relevantBlocks_1[_d];
564
+ id = null;
565
+ if (block.inputs.VARIABLE) {
566
+ id = block.inputs.VARIABLE.value.id;
567
+ }
568
+ else if (block.inputs.LIST) {
569
+ id = block.inputs.LIST.value.id;
570
+ }
571
+ else {
572
+ continue;
573
+ }
574
+ usedVariableIds.add(id);
575
+ }
576
+ for (_e = 0, _f = [target.variables, target.lists]; _e < _f.length; _e++) {
577
+ varList = _f[_e];
578
+ for (i = 0, variable = void 0; (variable = varList[i]); i++) {
579
+ if (variable.visible) {
580
+ continue;
581
+ }
582
+ if (usedVariableIds.has(variable.id)) {
583
+ continue;
584
+ }
585
+ varList.splice(i, 1);
586
+ i--;
587
+ }
588
+ }
589
+ }
590
+ return [2 /*return*/, project];
591
+ }
592
+ });
593
+ });
594
+ }
595
+ exports.fromSb3JSON = fromSb3JSON;
596
+ function fromSb3(fileData) {
597
+ return __awaiter(this, void 0, void 0, function () {
598
+ var inZip, projectFile, json, getAsset;
599
+ var _this = this;
600
+ return __generator(this, function (_a) {
601
+ switch (_a.label) {
602
+ case 0: return [4 /*yield*/, JSZip.loadAsync(fileData)];
603
+ case 1:
604
+ inZip = _a.sent();
605
+ projectFile = inZip.file("project.json");
606
+ if (!projectFile) {
607
+ throw new Error("Missing project.json");
608
+ }
609
+ return [4 /*yield*/, projectFile.async("text")];
610
+ case 2:
611
+ json = _a.sent();
612
+ getAsset = function (_a) {
613
+ var md5 = _a.md5, ext = _a.ext;
614
+ return __awaiter(_this, void 0, void 0, function () {
615
+ var _b;
616
+ return __generator(this, function (_c) {
617
+ // TODO: figure out how to handle missing assets
618
+ return [2 /*return*/, (_b = inZip.file("".concat(md5, ".").concat(ext))) === null || _b === void 0 ? void 0 : _b.async("arraybuffer")];
619
+ });
620
+ });
621
+ };
622
+ return [2 /*return*/, fromSb3JSON(JSON.parse(json), { getAsset: getAsset })];
623
+ }
624
+ });
625
+ });
626
+ }
627
+ exports.default = fromSb3;
628
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbVNiMy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9pby9zYjMvZnJvbVNiMy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQStCO0FBQy9CLGdEQUFvQztBQUVwQyx1Q0FBc0M7QUFFdEMscUNBQStDO0FBRS9DLDBEQUFvQztBQUNwQywwREFBb0M7QUFDcEMsc0RBQWdDO0FBQ2hDLHVDQUE0RDtBQUM1RCxtQ0FBNEM7QUFDNUMsd0RBQWtDO0FBZ0JsQyxTQUFTLGVBQWUsQ0FBQyxNQUFrQixFQUFFLFFBQWtCO0lBQS9ELGlCQWdDQztJQS9CQyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQ2hCLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUNqQixVQUFPLFdBQXdCOzs7Ozs7b0JBQzdCLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQVcsTUFBTSxDQUFDLElBQUksQ0FBRSxDQUFDLENBQUM7b0JBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBRyxXQUFXLENBQUMsT0FBTyxjQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUUsQ0FBQyxDQUFDO3lCQUVyRCxpQkFBTzs7d0JBQ2hCLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSTs7b0JBQ2YscUJBQU0sUUFBUSxDQUFDOzRCQUNwQixJQUFJLEVBQUUsU0FBUzs0QkFDZixJQUFJLEVBQUUsV0FBVyxDQUFDLElBQUk7NEJBQ3RCLEdBQUcsRUFBRSxXQUFXLENBQUMsT0FBTzs0QkFDeEIsR0FBRyxFQUFFLFdBQVcsQ0FBQyxVQUFVOzRCQUMzQixVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUk7eUJBQ3hCLENBQUMsRUFBQTt3QkFSSixzQkFBTyxjQUFJLGlCQUFPLFlBRWhCLFFBQUssR0FBRSxTQU1MOzRCQUVGLE1BQUcsR0FB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