pxt-core 8.4.1 → 8.4.3
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/built/backendutils.js +1 -0
- package/built/cli.js +83 -75
- package/built/pxt.js +1274 -179
- package/built/pxtblockly.js +323 -40
- package/built/pxtblocks.d.ts +30 -7
- package/built/pxtblocks.js +324 -41
- package/built/pxteditor.d.ts +2 -0
- package/built/pxtlib.d.ts +91 -5
- package/built/pxtlib.js +1183 -101
- package/built/pxtsim.js +8 -3
- package/built/server.js +4 -0
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/multiplayer/css/main.2dd69ed8.css +4 -0
- package/built/web/multiplayer/js/main.f3b8f930.js +2 -0
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtsim.js +1 -1
- package/built/web/pxtworker.js +2 -2
- package/built/web/react-common-authcode.css +4 -6993
- package/built/web/react-common-multiplayer.css +13 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-authcode.css +13 -0
- package/built/web/rtlreact-common-multiplayer.css +13 -0
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/js/main.a6cf40e1.chunk.js +1 -0
- package/common-docs/identity/sign-in.md +17 -3
- package/common-docs/static/music-editor/apple.png +0 -0
- package/common-docs/static/music-editor/burger.png +0 -0
- package/common-docs/static/music-editor/cake.png +0 -0
- package/common-docs/static/music-editor/car.png +0 -0
- package/common-docs/static/music-editor/cat.png +0 -0
- package/common-docs/static/music-editor/cherry.png +0 -0
- package/common-docs/static/music-editor/clam.png +0 -0
- package/common-docs/static/music-editor/computer.png +0 -0
- package/common-docs/static/music-editor/crab.png +0 -0
- package/common-docs/static/music-editor/dog.png +0 -0
- package/common-docs/static/music-editor/duck.png +0 -0
- package/common-docs/static/music-editor/egg.png +0 -0
- package/common-docs/static/music-editor/explosion.png +0 -0
- package/common-docs/static/music-editor/fish.png +0 -0
- package/common-docs/static/music-editor/ice-cream.png +0 -0
- package/common-docs/static/music-editor/lemon.png +0 -0
- package/common-docs/static/music-editor/metronomeWorker.js +35 -0
- package/common-docs/static/music-editor/snake.png +0 -0
- package/common-docs/static/music-editor/star.png +0 -0
- package/common-docs/static/music-editor/strawberry.png +0 -0
- package/common-docs/static/music-editor/taco.png +0 -0
- package/common-docs/static/music-editor/treble-clef.svg +1 -0
- package/localtypings/projectheader.d.ts +1 -0
- package/package.json +4 -2
- package/react-common/components/controls/Input.tsx +7 -3
- package/react-common/components/share/Share.tsx +6 -2
- package/react-common/components/share/ShareInfo.tsx +12 -3
- package/react-common/styles/controls/Button.less +9 -0
- package/react-common/styles/react-common-authcode-core.less +1 -1
- package/react-common/styles/react-common-authcode.less +1 -1
- package/react-common/styles/react-common-multiplayer-core.less +10 -0
- package/react-common/styles/react-common-multiplayer.less +12 -0
- package/theme/highcontrast.less +14 -0
- package/theme/music-editor/EditControls.less +22 -0
- package/theme/music-editor/MusicEditor.less +25 -0
- package/theme/music-editor/Note.less +16 -0
- package/theme/music-editor/NoteGroup.less +7 -0
- package/theme/music-editor/PlaybackControls.less +55 -0
- package/theme/music-editor/ScrollableWorkspace.less +3 -0
- package/theme/music-editor/Staff.less +31 -0
- package/theme/music-editor/Track.less +0 -0
- package/theme/music-editor/TrackSelector.less +48 -0
- package/theme/music-editor/Workspace.less +3 -0
- package/theme/pxt.less +1 -0
- package/theme/tutorial-sidebar.less +19 -3
- package/theme/tutorial.less +2 -2
- package/webapp/public/multiplayer.html +1 -1
- package/webapp/public/skillmap.html +1 -1
- package/built/web/skillmap/js/main.6fa0eaff.chunk.js +0 -1
package/built/pxt.js
CHANGED
|
@@ -97902,6 +97902,9 @@ var pxt;
|
|
|
97902
97902
|
this.setUserProfileAsync(this.state$.profile);
|
|
97903
97903
|
this.setUserPreferencesAsync(this.state$.preferences);
|
|
97904
97904
|
}
|
|
97905
|
+
async authTokenAsync() {
|
|
97906
|
+
return await pxt.storage.shared.getAsync(AUTH_CONTAINER, CSRF_TOKEN_KEY);
|
|
97907
|
+
}
|
|
97905
97908
|
/**
|
|
97906
97909
|
* Starts the process of authenticating the user against the given identity
|
|
97907
97910
|
* provider. Upon success the backend will write an http-only session cookie
|
|
@@ -98386,6 +98389,11 @@ var pxt;
|
|
|
98386
98389
|
return (_d = (_b = (_a = user === null || user === void 0 ? void 0 : user.idp) === null || _a === void 0 ? void 0 : _a.displayName) !== null && _b !== void 0 ? _b : (_c = user === null || user === void 0 ? void 0 : user.idp) === null || _c === void 0 ? void 0 : _c.username) !== null && _d !== void 0 ? _d : EMPTY_USERNAME;
|
|
98387
98390
|
}
|
|
98388
98391
|
auth.userName = userName;
|
|
98392
|
+
function firstName(user) {
|
|
98393
|
+
const userName = pxt.auth.userName(user);
|
|
98394
|
+
return (userName === null || userName === void 0 ? void 0 : userName.split(" ").shift()) || userName;
|
|
98395
|
+
}
|
|
98396
|
+
auth.firstName = firstName;
|
|
98389
98397
|
function userInitials(user) {
|
|
98390
98398
|
const username = pxt.auth.userName(user);
|
|
98391
98399
|
return ts.pxtc.Util.initials(username);
|
|
@@ -105222,6 +105230,7 @@ var pxt;
|
|
|
105222
105230
|
.then(resp => handleResponseAsync(resp));
|
|
105223
105231
|
}
|
|
105224
105232
|
function handleResponseAsync(resp) {
|
|
105233
|
+
var _a, _b, _c;
|
|
105225
105234
|
const code = resp.statusCode;
|
|
105226
105235
|
const errorData = pxt.Util.jsonTryParse(resp.text) || {};
|
|
105227
105236
|
pxt.debug(`upload result: ${code}`);
|
|
@@ -105229,16 +105238,22 @@ var pxt;
|
|
|
105229
105238
|
pxt.log(`create new translation file: ${filename}`);
|
|
105230
105239
|
return uploadAsync("add-file", {});
|
|
105231
105240
|
}
|
|
105232
|
-
else if (code == 404 && errorData.error
|
|
105241
|
+
else if (code == 404 && ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.code) == 17) {
|
|
105233
105242
|
return createDirectoryAsync(branch, prj, key, filename.replace(/\/[^\/]+$/, ""), incr)
|
|
105234
105243
|
.then(() => startAsync());
|
|
105235
105244
|
}
|
|
105236
|
-
else if (!errorData.success && errorData.error
|
|
105245
|
+
else if (!errorData.success && ((_b = errorData.error) === null || _b === void 0 ? void 0 : _b.code) == 53) {
|
|
105237
105246
|
// file is being updated
|
|
105238
105247
|
pxt.log(`${filename} being updated, waiting 5s and retry...`);
|
|
105239
105248
|
return pxt.U.delay(5000) // wait 5s and try again
|
|
105240
105249
|
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
105241
105250
|
}
|
|
105251
|
+
else if (code == 429 && ((_c = errorData.error) === null || _c === void 0 ? void 0 : _c.code) == 55) {
|
|
105252
|
+
// Too many concurrent requests
|
|
105253
|
+
pxt.log(`Maximum concurrent requests reached, waiting 10s and retry...`);
|
|
105254
|
+
return pxt.U.delay(10 * 1000) // wait 10s and try again
|
|
105255
|
+
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
105256
|
+
}
|
|
105242
105257
|
else if (code == 200 || errorData.success) {
|
|
105243
105258
|
// something crowdin reports 500 with success=true
|
|
105244
105259
|
return Promise.resolve();
|
|
@@ -106421,6 +106436,7 @@ var pxt;
|
|
|
106421
106436
|
const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
|
|
106422
106437
|
if (startTime) {
|
|
106423
106438
|
url.hash = `t=${startTime}`;
|
|
106439
|
+
url.searchParams.append("startTime", startTime);
|
|
106424
106440
|
}
|
|
106425
106441
|
if (endTime) {
|
|
106426
106442
|
url.searchParams.append("endTime", endTime);
|
|
@@ -110312,6 +110328,8 @@ var pxt;
|
|
|
110312
110328
|
sprite_1.IMAGE_PREFIX = "image";
|
|
110313
110329
|
sprite_1.ANIMATION_NAMESPACE = "myAnimations";
|
|
110314
110330
|
sprite_1.ANIMATION_PREFIX = "anim";
|
|
110331
|
+
sprite_1.SONG_NAMESPACE = "mySongs";
|
|
110332
|
+
sprite_1.SONG_PREFIX = "song";
|
|
110315
110333
|
/**
|
|
110316
110334
|
* 16-color sprite
|
|
110317
110335
|
*/
|
|
@@ -111367,6 +111385,1044 @@ var pxt;
|
|
|
111367
111385
|
})(shared = storage.shared || (storage.shared = {}));
|
|
111368
111386
|
})(storage = pxt.storage || (pxt.storage = {}));
|
|
111369
111387
|
})(pxt || (pxt = {}));
|
|
111388
|
+
var pxt;
|
|
111389
|
+
(function (pxt) {
|
|
111390
|
+
var assets;
|
|
111391
|
+
(function (assets) {
|
|
111392
|
+
var music;
|
|
111393
|
+
(function (music) {
|
|
111394
|
+
const BUFFER_SIZE = 12;
|
|
111395
|
+
function renderInstrument(instrument, noteFrequency, gateLength, volume) {
|
|
111396
|
+
var _a, _b, _c, _d, _e;
|
|
111397
|
+
const totalDuration = gateLength + instrument.ampEnvelope.release;
|
|
111398
|
+
const ampLFOInterval = ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;
|
|
111399
|
+
const pitchLFOInterval = ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;
|
|
111400
|
+
let timePoints = [0];
|
|
111401
|
+
let nextAETime = instrument.ampEnvelope.attack;
|
|
111402
|
+
let nextPETime = ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.amplitude) ? instrument.pitchEnvelope.attack : totalDuration;
|
|
111403
|
+
let nextPLTime = ((_d = instrument.pitchLFO) === null || _d === void 0 ? void 0 : _d.amplitude) ? pitchLFOInterval : totalDuration;
|
|
111404
|
+
let nextALTime = ((_e = instrument.ampLFO) === null || _e === void 0 ? void 0 : _e.amplitude) ? ampLFOInterval : totalDuration;
|
|
111405
|
+
let time = 0;
|
|
111406
|
+
while (time < totalDuration) {
|
|
111407
|
+
if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {
|
|
111408
|
+
time = nextAETime;
|
|
111409
|
+
timePoints.push(nextAETime);
|
|
111410
|
+
if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
|
|
111411
|
+
nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
|
|
111412
|
+
}
|
|
111413
|
+
else if (time < gateLength) {
|
|
111414
|
+
nextAETime = gateLength;
|
|
111415
|
+
}
|
|
111416
|
+
else {
|
|
111417
|
+
nextAETime = totalDuration;
|
|
111418
|
+
}
|
|
111419
|
+
}
|
|
111420
|
+
else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {
|
|
111421
|
+
time = nextPETime;
|
|
111422
|
+
timePoints.push(nextPETime);
|
|
111423
|
+
if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
|
|
111424
|
+
nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
|
|
111425
|
+
}
|
|
111426
|
+
else if (time < gateLength) {
|
|
111427
|
+
nextPETime = gateLength;
|
|
111428
|
+
}
|
|
111429
|
+
else if (time < gateLength + instrument.pitchEnvelope.release) {
|
|
111430
|
+
nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
|
|
111431
|
+
}
|
|
111432
|
+
else {
|
|
111433
|
+
nextPETime = totalDuration;
|
|
111434
|
+
}
|
|
111435
|
+
}
|
|
111436
|
+
else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {
|
|
111437
|
+
time = nextPLTime;
|
|
111438
|
+
timePoints.push(nextPLTime);
|
|
111439
|
+
nextPLTime += pitchLFOInterval;
|
|
111440
|
+
}
|
|
111441
|
+
else if (nextALTime < totalDuration) {
|
|
111442
|
+
time = nextALTime;
|
|
111443
|
+
timePoints.push(nextALTime);
|
|
111444
|
+
nextALTime += ampLFOInterval;
|
|
111445
|
+
}
|
|
111446
|
+
if (time >= totalDuration) {
|
|
111447
|
+
break;
|
|
111448
|
+
}
|
|
111449
|
+
if (nextAETime <= time) {
|
|
111450
|
+
if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
|
|
111451
|
+
nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
|
|
111452
|
+
}
|
|
111453
|
+
else if (time < gateLength) {
|
|
111454
|
+
nextAETime = gateLength;
|
|
111455
|
+
}
|
|
111456
|
+
else {
|
|
111457
|
+
nextAETime = totalDuration;
|
|
111458
|
+
}
|
|
111459
|
+
}
|
|
111460
|
+
if (nextPETime <= time) {
|
|
111461
|
+
if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
|
|
111462
|
+
nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
|
|
111463
|
+
}
|
|
111464
|
+
else if (time < gateLength) {
|
|
111465
|
+
nextPETime = gateLength;
|
|
111466
|
+
}
|
|
111467
|
+
else if (time < gateLength + instrument.pitchEnvelope.release) {
|
|
111468
|
+
nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
|
|
111469
|
+
}
|
|
111470
|
+
else {
|
|
111471
|
+
nextPETime = totalDuration;
|
|
111472
|
+
}
|
|
111473
|
+
}
|
|
111474
|
+
while (nextALTime <= time) {
|
|
111475
|
+
nextALTime += ampLFOInterval;
|
|
111476
|
+
}
|
|
111477
|
+
while (nextPLTime <= time) {
|
|
111478
|
+
nextPLTime += pitchLFOInterval;
|
|
111479
|
+
}
|
|
111480
|
+
}
|
|
111481
|
+
let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;
|
|
111482
|
+
let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;
|
|
111483
|
+
let prevTime = 0;
|
|
111484
|
+
let nextAmp;
|
|
111485
|
+
let nextPitch;
|
|
111486
|
+
const out = new Uint8Array(BUFFER_SIZE * (timePoints.length + 1));
|
|
111487
|
+
for (let i = 1; i < timePoints.length; i++) {
|
|
111488
|
+
if (timePoints[i] - prevTime < 5) {
|
|
111489
|
+
prevTime = timePoints[i];
|
|
111490
|
+
continue;
|
|
111491
|
+
}
|
|
111492
|
+
nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;
|
|
111493
|
+
nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0;
|
|
111494
|
+
addNote(out, (i - 1) * 12, (timePoints[i] - prevTime) | 0, prevAmp, nextAmp, instrument.waveform, prevPitch, nextPitch);
|
|
111495
|
+
prevAmp = nextAmp;
|
|
111496
|
+
prevPitch = nextPitch;
|
|
111497
|
+
prevTime = timePoints[i];
|
|
111498
|
+
}
|
|
111499
|
+
addNote(out, timePoints.length * 12, 10, prevAmp, 0, instrument.waveform, prevPitch, prevPitch);
|
|
111500
|
+
return out;
|
|
111501
|
+
}
|
|
111502
|
+
music.renderInstrument = renderInstrument;
|
|
111503
|
+
function renderDrumInstrument(sound, volume) {
|
|
111504
|
+
let prevAmp = sound.startVolume;
|
|
111505
|
+
let prevFreq = sound.startFrequency;
|
|
111506
|
+
const scaleVolume = (value) => (value / 1024) * volume;
|
|
111507
|
+
let out = new Uint8Array((sound.steps.length + 1) * BUFFER_SIZE);
|
|
111508
|
+
for (let i = 0; i < sound.steps.length; i++) {
|
|
111509
|
+
addNote(out, i * BUFFER_SIZE, sound.steps[i].duration, scaleVolume(prevAmp), scaleVolume(sound.steps[i].volume), sound.steps[i].waveform, prevFreq, sound.steps[i].frequency);
|
|
111510
|
+
prevAmp = sound.steps[i].volume;
|
|
111511
|
+
prevFreq = sound.steps[i].frequency;
|
|
111512
|
+
}
|
|
111513
|
+
addNote(out, sound.steps.length * BUFFER_SIZE, 10, scaleVolume(prevAmp), 0, sound.steps[sound.steps.length - 1].waveform, prevFreq, prevFreq);
|
|
111514
|
+
return out;
|
|
111515
|
+
}
|
|
111516
|
+
music.renderDrumInstrument = renderDrumInstrument;
|
|
111517
|
+
function instrumentPitchAtTime(instrument, noteFrequency, gateLength, time) {
|
|
111518
|
+
var _a, _b;
|
|
111519
|
+
let mod = 0;
|
|
111520
|
+
if ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.amplitude) {
|
|
111521
|
+
mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength);
|
|
111522
|
+
}
|
|
111523
|
+
if ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) {
|
|
111524
|
+
mod += lfoValueAtTime(instrument.pitchLFO, time);
|
|
111525
|
+
}
|
|
111526
|
+
return Math.max(noteFrequency + mod, 0);
|
|
111527
|
+
}
|
|
111528
|
+
function instrumentVolumeAtTime(instrument, gateLength, time, maxVolume) {
|
|
111529
|
+
var _a;
|
|
111530
|
+
let mod = 0;
|
|
111531
|
+
if (instrument.ampEnvelope.amplitude) {
|
|
111532
|
+
mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength);
|
|
111533
|
+
}
|
|
111534
|
+
if ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) {
|
|
111535
|
+
mod += lfoValueAtTime(instrument.ampLFO, time);
|
|
111536
|
+
}
|
|
111537
|
+
return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;
|
|
111538
|
+
}
|
|
111539
|
+
function envelopeValueAtTime(envelope, time, gateLength) {
|
|
111540
|
+
const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;
|
|
111541
|
+
if (time > gateLength) {
|
|
111542
|
+
if (time - gateLength > envelope.release)
|
|
111543
|
+
return 0;
|
|
111544
|
+
else if (time < envelope.attack) {
|
|
111545
|
+
const height = (envelope.amplitude / envelope.attack) * gateLength;
|
|
111546
|
+
return height - ((height / envelope.release) * (time - gateLength));
|
|
111547
|
+
}
|
|
111548
|
+
else if (time < envelope.attack + envelope.decay) {
|
|
111549
|
+
const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);
|
|
111550
|
+
return height2 - ((height2 / envelope.release) * (time - gateLength));
|
|
111551
|
+
}
|
|
111552
|
+
else {
|
|
111553
|
+
return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength);
|
|
111554
|
+
}
|
|
111555
|
+
}
|
|
111556
|
+
else if (time < envelope.attack) {
|
|
111557
|
+
return (envelope.amplitude / envelope.attack) * time;
|
|
111558
|
+
}
|
|
111559
|
+
else if (time < envelope.attack + envelope.decay) {
|
|
111560
|
+
return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack);
|
|
111561
|
+
}
|
|
111562
|
+
else {
|
|
111563
|
+
return adjustedSustain;
|
|
111564
|
+
}
|
|
111565
|
+
}
|
|
111566
|
+
function lfoValueAtTime(lfo, time) {
|
|
111567
|
+
return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude;
|
|
111568
|
+
}
|
|
111569
|
+
function set16BitNumber(buf, offset, value) {
|
|
111570
|
+
const temp = new Uint8Array(2);
|
|
111571
|
+
new Uint16Array(temp.buffer)[0] = value | 0;
|
|
111572
|
+
buf[offset] = temp[0];
|
|
111573
|
+
buf[offset + 1] = temp[1];
|
|
111574
|
+
}
|
|
111575
|
+
function get16BitNumber(buf, offset) {
|
|
111576
|
+
const temp = new Uint8Array(2);
|
|
111577
|
+
temp[0] = buf[offset];
|
|
111578
|
+
temp[1] = buf[offset + 1];
|
|
111579
|
+
return new Uint16Array(temp.buffer)[0];
|
|
111580
|
+
}
|
|
111581
|
+
function addNote(sndInstr, sndInstrPtr, ms, beg, end, soundWave, hz, endHz) {
|
|
111582
|
+
if (ms > 0) {
|
|
111583
|
+
sndInstr[sndInstrPtr] = soundWave;
|
|
111584
|
+
sndInstr[sndInstrPtr + 1] = 0;
|
|
111585
|
+
set16BitNumber(sndInstr, sndInstrPtr + 2, hz);
|
|
111586
|
+
set16BitNumber(sndInstr, sndInstrPtr + 4, ms);
|
|
111587
|
+
set16BitNumber(sndInstr, sndInstrPtr + 6, (beg * 255) >> 6);
|
|
111588
|
+
set16BitNumber(sndInstr, sndInstrPtr + 8, (end * 255) >> 6);
|
|
111589
|
+
set16BitNumber(sndInstr, sndInstrPtr + 10, endHz);
|
|
111590
|
+
sndInstrPtr += BUFFER_SIZE;
|
|
111591
|
+
}
|
|
111592
|
+
sndInstr[sndInstrPtr] = 0;
|
|
111593
|
+
return sndInstrPtr;
|
|
111594
|
+
}
|
|
111595
|
+
function encodeSongToHex(song) {
|
|
111596
|
+
const encoded = encodeSong(song);
|
|
111597
|
+
return pxt.U.toHex(encoded);
|
|
111598
|
+
}
|
|
111599
|
+
music.encodeSongToHex = encodeSongToHex;
|
|
111600
|
+
function decodeSongFromHex(hex) {
|
|
111601
|
+
const bytes = pxt.U.fromHex(hex);
|
|
111602
|
+
return decodeSong(bytes);
|
|
111603
|
+
}
|
|
111604
|
+
music.decodeSongFromHex = decodeSongFromHex;
|
|
111605
|
+
/**
|
|
111606
|
+
* Byte encoding format for songs
|
|
111607
|
+
* FIXME: should this all be word aligned?
|
|
111608
|
+
*
|
|
111609
|
+
* song(7 + length of all tracks bytes)
|
|
111610
|
+
* 0 version
|
|
111611
|
+
* 1 beats per minute
|
|
111612
|
+
* 3 beats per measure
|
|
111613
|
+
* 4 ticks per beat
|
|
111614
|
+
* 5 measures
|
|
111615
|
+
* 6 number of tracks
|
|
111616
|
+
* ...tracks
|
|
111617
|
+
*
|
|
111618
|
+
* track(6 + instrument length + note length bytes)
|
|
111619
|
+
* 0 id
|
|
111620
|
+
* 1 flags
|
|
111621
|
+
* 2 instruments byte length
|
|
111622
|
+
* 4...instrument
|
|
111623
|
+
* notes byte length
|
|
111624
|
+
* ...note events
|
|
111625
|
+
*
|
|
111626
|
+
* instrument(27 bytes)
|
|
111627
|
+
* 0 waveform
|
|
111628
|
+
* 1 amp attack
|
|
111629
|
+
* 3 amp decay
|
|
111630
|
+
* 5 amp sustain
|
|
111631
|
+
* 7 amp release
|
|
111632
|
+
* 9 amp amp
|
|
111633
|
+
* 11 pitch attack
|
|
111634
|
+
* 13 pitch decay
|
|
111635
|
+
* 15 pitch sustain
|
|
111636
|
+
* 17 pitch release
|
|
111637
|
+
* 19 pitch amp
|
|
111638
|
+
* 21 amp lfo freq
|
|
111639
|
+
* 22 amp lfo amp
|
|
111640
|
+
* 24 pitch lfo freq
|
|
111641
|
+
* 25 pitch lfo amp
|
|
111642
|
+
*
|
|
111643
|
+
* drum(5 + 7 * steps bytes)
|
|
111644
|
+
* 0 steps
|
|
111645
|
+
* 1 start freq
|
|
111646
|
+
* 3 start amp
|
|
111647
|
+
* 5...steps
|
|
111648
|
+
*
|
|
111649
|
+
* drum step(7 bytes)
|
|
111650
|
+
* 0 waveform
|
|
111651
|
+
* 1 freq
|
|
111652
|
+
* 3 volume
|
|
111653
|
+
* 5 duration
|
|
111654
|
+
*
|
|
111655
|
+
* note event(5 + 1 * polyphony bytes)
|
|
111656
|
+
* 0 start tick
|
|
111657
|
+
* 2 end tick
|
|
111658
|
+
* 4 polyphony
|
|
111659
|
+
* 5...notes(1 byte each)
|
|
111660
|
+
*
|
|
111661
|
+
*/
|
|
111662
|
+
function encodeSong(song) {
|
|
111663
|
+
const encodedTracks = song.tracks
|
|
111664
|
+
.filter((track) => track.notes.length > 0)
|
|
111665
|
+
.map(encodeTrack);
|
|
111666
|
+
const trackLength = encodedTracks.reduce((d, c) => c.length + d, 0);
|
|
111667
|
+
const out = new Uint8Array(7 + trackLength);
|
|
111668
|
+
out[0] = 0; // encoding version
|
|
111669
|
+
set16BitNumber(out, 1, song.beatsPerMinute);
|
|
111670
|
+
out[3] = song.beatsPerMeasure;
|
|
111671
|
+
out[4] = song.ticksPerBeat;
|
|
111672
|
+
out[5] = song.measures;
|
|
111673
|
+
out[6] = encodedTracks.length;
|
|
111674
|
+
let current = 7;
|
|
111675
|
+
for (const track of encodedTracks) {
|
|
111676
|
+
out.set(track, current);
|
|
111677
|
+
current += track.length;
|
|
111678
|
+
}
|
|
111679
|
+
return out;
|
|
111680
|
+
}
|
|
111681
|
+
function decodeSong(buf) {
|
|
111682
|
+
const res = {
|
|
111683
|
+
beatsPerMinute: get16BitNumber(buf, 1),
|
|
111684
|
+
beatsPerMeasure: buf[3],
|
|
111685
|
+
ticksPerBeat: buf[4],
|
|
111686
|
+
measures: buf[5],
|
|
111687
|
+
tracks: []
|
|
111688
|
+
};
|
|
111689
|
+
let current = 7;
|
|
111690
|
+
while (current < buf.length) {
|
|
111691
|
+
const [track, pointer] = decodeTrack(buf, current);
|
|
111692
|
+
current = pointer;
|
|
111693
|
+
res.tracks.push(track);
|
|
111694
|
+
}
|
|
111695
|
+
return res;
|
|
111696
|
+
}
|
|
111697
|
+
function encodeInstrument(instrument) {
|
|
111698
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
111699
|
+
const out = new Uint8Array(28);
|
|
111700
|
+
out[0] = instrument.waveform;
|
|
111701
|
+
set16BitNumber(out, 1, instrument.ampEnvelope.attack);
|
|
111702
|
+
set16BitNumber(out, 3, instrument.ampEnvelope.decay);
|
|
111703
|
+
set16BitNumber(out, 5, instrument.ampEnvelope.sustain);
|
|
111704
|
+
set16BitNumber(out, 7, instrument.ampEnvelope.release);
|
|
111705
|
+
set16BitNumber(out, 9, instrument.ampEnvelope.amplitude);
|
|
111706
|
+
set16BitNumber(out, 11, ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.attack) || 0);
|
|
111707
|
+
set16BitNumber(out, 13, ((_b = instrument.pitchEnvelope) === null || _b === void 0 ? void 0 : _b.decay) || 0);
|
|
111708
|
+
set16BitNumber(out, 15, ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.sustain) || 0);
|
|
111709
|
+
set16BitNumber(out, 17, ((_d = instrument.pitchEnvelope) === null || _d === void 0 ? void 0 : _d.release) || 0);
|
|
111710
|
+
set16BitNumber(out, 19, ((_e = instrument.pitchEnvelope) === null || _e === void 0 ? void 0 : _e.amplitude) || 0);
|
|
111711
|
+
out[21] = ((_f = instrument.ampLFO) === null || _f === void 0 ? void 0 : _f.frequency) || 0;
|
|
111712
|
+
set16BitNumber(out, 22, ((_g = instrument.ampLFO) === null || _g === void 0 ? void 0 : _g.amplitude) || 0);
|
|
111713
|
+
out[24] = ((_h = instrument.pitchLFO) === null || _h === void 0 ? void 0 : _h.frequency) || 0;
|
|
111714
|
+
set16BitNumber(out, 25, ((_j = instrument.pitchLFO) === null || _j === void 0 ? void 0 : _j.amplitude) || 0);
|
|
111715
|
+
return out;
|
|
111716
|
+
}
|
|
111717
|
+
function decodeInstrument(buf, offset) {
|
|
111718
|
+
return {
|
|
111719
|
+
waveform: buf[offset],
|
|
111720
|
+
ampEnvelope: {
|
|
111721
|
+
attack: get16BitNumber(buf, offset + 1),
|
|
111722
|
+
decay: get16BitNumber(buf, offset + 3),
|
|
111723
|
+
sustain: get16BitNumber(buf, offset + 5),
|
|
111724
|
+
release: get16BitNumber(buf, offset + 7),
|
|
111725
|
+
amplitude: get16BitNumber(buf, offset + 9),
|
|
111726
|
+
},
|
|
111727
|
+
pitchEnvelope: {
|
|
111728
|
+
attack: get16BitNumber(buf, offset + 11),
|
|
111729
|
+
decay: get16BitNumber(buf, offset + 13),
|
|
111730
|
+
sustain: get16BitNumber(buf, offset + 15),
|
|
111731
|
+
release: get16BitNumber(buf, offset + 17),
|
|
111732
|
+
amplitude: get16BitNumber(buf, offset + 19),
|
|
111733
|
+
},
|
|
111734
|
+
ampLFO: {
|
|
111735
|
+
frequency: buf[offset + 21],
|
|
111736
|
+
amplitude: get16BitNumber(buf, 22)
|
|
111737
|
+
},
|
|
111738
|
+
pitchLFO: {
|
|
111739
|
+
frequency: buf[offset + 24],
|
|
111740
|
+
amplitude: get16BitNumber(buf, 25)
|
|
111741
|
+
}
|
|
111742
|
+
};
|
|
111743
|
+
}
|
|
111744
|
+
function decodeTrack(buf, offset) {
|
|
111745
|
+
if (buf[offset + 1]) {
|
|
111746
|
+
return decodeDrumTrack(buf, offset);
|
|
111747
|
+
}
|
|
111748
|
+
return decodeMelodicTrack(buf, offset);
|
|
111749
|
+
}
|
|
111750
|
+
function encodeDrumInstrument(drum) {
|
|
111751
|
+
const out = new Uint8Array(5 + 7 * drum.steps.length);
|
|
111752
|
+
out[0] = drum.steps.length;
|
|
111753
|
+
set16BitNumber(out, 1, drum.startFrequency);
|
|
111754
|
+
set16BitNumber(out, 3, drum.startVolume);
|
|
111755
|
+
for (let i = 0; i < drum.steps.length; i++) {
|
|
111756
|
+
const start = 5 + i * 7;
|
|
111757
|
+
out[start] = drum.steps[i].waveform;
|
|
111758
|
+
set16BitNumber(out, start + 1, drum.steps[i].frequency);
|
|
111759
|
+
set16BitNumber(out, start + 3, drum.steps[i].volume);
|
|
111760
|
+
set16BitNumber(out, start + 5, drum.steps[i].duration);
|
|
111761
|
+
}
|
|
111762
|
+
return out;
|
|
111763
|
+
}
|
|
111764
|
+
function decodeDrumInstrument(buf, offset) {
|
|
111765
|
+
const res = {
|
|
111766
|
+
startFrequency: get16BitNumber(buf, offset + 1),
|
|
111767
|
+
startVolume: get16BitNumber(buf, offset + 3),
|
|
111768
|
+
steps: []
|
|
111769
|
+
};
|
|
111770
|
+
for (let i = 0; i < buf[offset]; i++) {
|
|
111771
|
+
const start = offset + 5 + i * 7;
|
|
111772
|
+
res.steps.push({
|
|
111773
|
+
waveform: buf[start],
|
|
111774
|
+
frequency: get16BitNumber(buf, start + 1),
|
|
111775
|
+
volume: get16BitNumber(buf, start + 3),
|
|
111776
|
+
duration: get16BitNumber(buf, start + 5)
|
|
111777
|
+
});
|
|
111778
|
+
}
|
|
111779
|
+
return res;
|
|
111780
|
+
}
|
|
111781
|
+
function encodeNoteEvent(event) {
|
|
111782
|
+
const out = new Uint8Array(5 + event.notes.length);
|
|
111783
|
+
set16BitNumber(out, 0, event.startTick);
|
|
111784
|
+
set16BitNumber(out, 2, event.endTick);
|
|
111785
|
+
out[4] = event.notes.length;
|
|
111786
|
+
for (let i = 0; i < event.notes.length; i++) {
|
|
111787
|
+
out[5 + i] = event.notes[i];
|
|
111788
|
+
}
|
|
111789
|
+
return out;
|
|
111790
|
+
}
|
|
111791
|
+
function decodeNoteEvent(buf, offset) {
|
|
111792
|
+
const res = {
|
|
111793
|
+
startTick: get16BitNumber(buf, offset),
|
|
111794
|
+
endTick: get16BitNumber(buf, offset + 2),
|
|
111795
|
+
notes: []
|
|
111796
|
+
};
|
|
111797
|
+
for (let i = 0; i < buf[offset + 4]; i++) {
|
|
111798
|
+
res.notes.push(buf[offset + 5 + i]);
|
|
111799
|
+
}
|
|
111800
|
+
return res;
|
|
111801
|
+
}
|
|
111802
|
+
function encodeTrack(track) {
|
|
111803
|
+
if (track.drums)
|
|
111804
|
+
return encodeDrumTrack(track);
|
|
111805
|
+
return encodeMelodicTrack(track);
|
|
111806
|
+
}
|
|
111807
|
+
function encodeMelodicTrack(track) {
|
|
111808
|
+
const encodedInstrument = encodeInstrument(track.instrument);
|
|
111809
|
+
const encodedNotes = track.notes.map(encodeNoteEvent);
|
|
111810
|
+
const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
|
|
111811
|
+
const out = new Uint8Array(6 + encodedInstrument.length + noteLength);
|
|
111812
|
+
out[0] = track.id;
|
|
111813
|
+
out[1] = 0;
|
|
111814
|
+
set16BitNumber(out, 2, encodedInstrument.length);
|
|
111815
|
+
let current = 4;
|
|
111816
|
+
out.set(encodedInstrument, current);
|
|
111817
|
+
current += encodedInstrument.length;
|
|
111818
|
+
set16BitNumber(out, current, noteLength);
|
|
111819
|
+
current += 2;
|
|
111820
|
+
for (const note of encodedNotes) {
|
|
111821
|
+
out.set(note, current);
|
|
111822
|
+
current += note.length;
|
|
111823
|
+
}
|
|
111824
|
+
return out;
|
|
111825
|
+
}
|
|
111826
|
+
function decodeMelodicTrack(buf, offset) {
|
|
111827
|
+
const res = {
|
|
111828
|
+
id: buf[offset],
|
|
111829
|
+
instrument: decodeInstrument(buf, offset + 4),
|
|
111830
|
+
notes: []
|
|
111831
|
+
};
|
|
111832
|
+
const noteStart = offset + 4 + get16BitNumber(buf, offset + 2);
|
|
111833
|
+
const noteLength = get16BitNumber(buf, noteStart);
|
|
111834
|
+
let currentOffset = noteStart + 2;
|
|
111835
|
+
while (currentOffset < noteStart + 2 + noteLength) {
|
|
111836
|
+
res.notes.push(decodeNoteEvent(buf, currentOffset));
|
|
111837
|
+
currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
|
|
111838
|
+
}
|
|
111839
|
+
return [res, currentOffset];
|
|
111840
|
+
}
|
|
111841
|
+
function encodeDrumTrack(track) {
|
|
111842
|
+
const encodedDrums = track.drums.map(encodeDrumInstrument);
|
|
111843
|
+
const drumLength = encodedDrums.reduce((d, c) => c.length + d, 0);
|
|
111844
|
+
const encodedNotes = track.notes.map(encodeNoteEvent);
|
|
111845
|
+
const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
|
|
111846
|
+
const out = new Uint8Array(6 + drumLength + noteLength);
|
|
111847
|
+
out[0] = track.id;
|
|
111848
|
+
out[1] = 1;
|
|
111849
|
+
set16BitNumber(out, 2, drumLength);
|
|
111850
|
+
let current = 4;
|
|
111851
|
+
for (const drum of encodedDrums) {
|
|
111852
|
+
out.set(drum, current);
|
|
111853
|
+
current += drum.length;
|
|
111854
|
+
}
|
|
111855
|
+
set16BitNumber(out, current, noteLength);
|
|
111856
|
+
current += 2;
|
|
111857
|
+
for (const note of encodedNotes) {
|
|
111858
|
+
out.set(note, current);
|
|
111859
|
+
current += note.length;
|
|
111860
|
+
}
|
|
111861
|
+
return out;
|
|
111862
|
+
}
|
|
111863
|
+
function decodeDrumTrack(buf, offset) {
|
|
111864
|
+
const res = {
|
|
111865
|
+
id: buf[offset],
|
|
111866
|
+
instrument: { ampEnvelope: { attack: 0, decay: 0, sustain: 0, release: 0, amplitude: 0 }, waveform: 0 },
|
|
111867
|
+
notes: [],
|
|
111868
|
+
drums: []
|
|
111869
|
+
};
|
|
111870
|
+
const drumByteLength = get16BitNumber(buf, offset + 2);
|
|
111871
|
+
let currentOffset = offset + 4;
|
|
111872
|
+
while (currentOffset < offset + 4 + drumByteLength) {
|
|
111873
|
+
res.drums.push(decodeDrumInstrument(buf, currentOffset));
|
|
111874
|
+
currentOffset += 5 + 7 * res.drums[res.drums.length - 1].steps.length;
|
|
111875
|
+
}
|
|
111876
|
+
const noteLength = get16BitNumber(buf, currentOffset);
|
|
111877
|
+
currentOffset += 2;
|
|
111878
|
+
while (currentOffset < offset + 4 + drumByteLength + noteLength) {
|
|
111879
|
+
res.notes.push(decodeNoteEvent(buf, currentOffset));
|
|
111880
|
+
currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
|
|
111881
|
+
}
|
|
111882
|
+
return [res, currentOffset];
|
|
111883
|
+
}
|
|
111884
|
+
function cloneSong(song) {
|
|
111885
|
+
return Object.assign(Object.assign({}, song), { tracks: song.tracks.map(track => (Object.assign(Object.assign({}, track), { instrument: track.instrument && Object.assign(Object.assign({}, track.instrument), { ampEnvelope: Object.assign({}, track.instrument.ampEnvelope), pitchEnvelope: track.instrument.pitchEnvelope && Object.assign({}, track.instrument.pitchEnvelope), ampLFO: track.instrument.ampLFO && Object.assign({}, track.instrument.ampLFO), pitchLFO: track.instrument.pitchLFO && Object.assign({}, track.instrument.pitchLFO) }), drums: track.drums && track.drums.map(drum => (Object.assign(Object.assign({}, drum), { steps: drum.steps.map(step => (Object.assign({}, step))) }))), notes: track.notes.map(noteEvent => (Object.assign(Object.assign({}, noteEvent), { notes: noteEvent.notes.slice() }))) }))) });
|
|
111886
|
+
}
|
|
111887
|
+
music.cloneSong = cloneSong;
|
|
111888
|
+
function songEquals(a, b) {
|
|
111889
|
+
return naiveEqualCheck(a, b);
|
|
111890
|
+
}
|
|
111891
|
+
music.songEquals = songEquals;
|
|
111892
|
+
function naiveEqualCheck(a, b) {
|
|
111893
|
+
if (typeof a !== typeof b)
|
|
111894
|
+
return false;
|
|
111895
|
+
else if (typeof a !== "object")
|
|
111896
|
+
return a === b;
|
|
111897
|
+
else if (Array.isArray(a)) {
|
|
111898
|
+
if (a.length !== b.length)
|
|
111899
|
+
return false;
|
|
111900
|
+
for (let i = 0; i < a.length; i++) {
|
|
111901
|
+
if (!naiveEqualCheck(a[i], b[i]))
|
|
111902
|
+
return false;
|
|
111903
|
+
}
|
|
111904
|
+
return true;
|
|
111905
|
+
}
|
|
111906
|
+
const aKeys = Object.keys(a);
|
|
111907
|
+
const bKeys = Object.keys(b);
|
|
111908
|
+
if (aKeys.length !== bKeys.length)
|
|
111909
|
+
return false;
|
|
111910
|
+
for (const key of aKeys) {
|
|
111911
|
+
if (bKeys.indexOf(key) === -1)
|
|
111912
|
+
return false;
|
|
111913
|
+
if (!naiveEqualCheck(a[key], b[key]))
|
|
111914
|
+
return false;
|
|
111915
|
+
}
|
|
111916
|
+
return true;
|
|
111917
|
+
}
|
|
111918
|
+
function inflateSong(song) {
|
|
111919
|
+
const base = getEmptySong(1);
|
|
111920
|
+
song.tracks = base.tracks.map((track, index) => {
|
|
111921
|
+
const existing = song.tracks.find(t => t.id === index);
|
|
111922
|
+
if (existing)
|
|
111923
|
+
track.notes = existing.notes;
|
|
111924
|
+
return track;
|
|
111925
|
+
});
|
|
111926
|
+
}
|
|
111927
|
+
music.inflateSong = inflateSong;
|
|
111928
|
+
function getEmptySong(measures) {
|
|
111929
|
+
return {
|
|
111930
|
+
ticksPerBeat: 8,
|
|
111931
|
+
beatsPerMeasure: 4,
|
|
111932
|
+
beatsPerMinute: 120,
|
|
111933
|
+
measures,
|
|
111934
|
+
tracks: [
|
|
111935
|
+
{
|
|
111936
|
+
id: 0,
|
|
111937
|
+
name: lf("Duck"),
|
|
111938
|
+
notes: [],
|
|
111939
|
+
iconURI: "/static/music-editor/duck.png",
|
|
111940
|
+
instrument: {
|
|
111941
|
+
waveform: 15,
|
|
111942
|
+
octave: 4,
|
|
111943
|
+
ampEnvelope: {
|
|
111944
|
+
attack: 5,
|
|
111945
|
+
decay: 530,
|
|
111946
|
+
sustain: 705,
|
|
111947
|
+
release: 450,
|
|
111948
|
+
amplitude: 1024
|
|
111949
|
+
},
|
|
111950
|
+
pitchEnvelope: {
|
|
111951
|
+
attack: 5,
|
|
111952
|
+
decay: 40,
|
|
111953
|
+
sustain: 0,
|
|
111954
|
+
release: 100,
|
|
111955
|
+
amplitude: 40
|
|
111956
|
+
},
|
|
111957
|
+
ampLFO: {
|
|
111958
|
+
frequency: 3,
|
|
111959
|
+
amplitude: 20
|
|
111960
|
+
},
|
|
111961
|
+
pitchLFO: {
|
|
111962
|
+
frequency: 6,
|
|
111963
|
+
amplitude: 2
|
|
111964
|
+
}
|
|
111965
|
+
}
|
|
111966
|
+
},
|
|
111967
|
+
{
|
|
111968
|
+
id: 1,
|
|
111969
|
+
name: lf("Cat"),
|
|
111970
|
+
notes: [],
|
|
111971
|
+
iconURI: "/static/music-editor/cat.png",
|
|
111972
|
+
instrument: {
|
|
111973
|
+
waveform: 12,
|
|
111974
|
+
octave: 5,
|
|
111975
|
+
ampEnvelope: {
|
|
111976
|
+
attack: 150,
|
|
111977
|
+
decay: 100,
|
|
111978
|
+
sustain: 365,
|
|
111979
|
+
release: 400,
|
|
111980
|
+
amplitude: 1024
|
|
111981
|
+
},
|
|
111982
|
+
pitchEnvelope: {
|
|
111983
|
+
attack: 120,
|
|
111984
|
+
decay: 300,
|
|
111985
|
+
sustain: 0,
|
|
111986
|
+
release: 100,
|
|
111987
|
+
amplitude: 50
|
|
111988
|
+
},
|
|
111989
|
+
pitchLFO: {
|
|
111990
|
+
frequency: 10,
|
|
111991
|
+
amplitude: 6
|
|
111992
|
+
}
|
|
111993
|
+
}
|
|
111994
|
+
},
|
|
111995
|
+
{
|
|
111996
|
+
id: 2,
|
|
111997
|
+
name: lf("Dog"),
|
|
111998
|
+
notes: [],
|
|
111999
|
+
iconURI: "/static/music-editor/dog.png",
|
|
112000
|
+
instrument: {
|
|
112001
|
+
waveform: 1,
|
|
112002
|
+
octave: 4,
|
|
112003
|
+
ampEnvelope: {
|
|
112004
|
+
attack: 10,
|
|
112005
|
+
decay: 100,
|
|
112006
|
+
sustain: 500,
|
|
112007
|
+
release: 100,
|
|
112008
|
+
amplitude: 1024
|
|
112009
|
+
},
|
|
112010
|
+
pitchLFO: {
|
|
112011
|
+
frequency: 5,
|
|
112012
|
+
amplitude: 0
|
|
112013
|
+
}
|
|
112014
|
+
}
|
|
112015
|
+
},
|
|
112016
|
+
{
|
|
112017
|
+
id: 3,
|
|
112018
|
+
name: lf("Fish"),
|
|
112019
|
+
notes: [],
|
|
112020
|
+
iconURI: "/static/music-editor/fish.png",
|
|
112021
|
+
instrument: {
|
|
112022
|
+
waveform: 1,
|
|
112023
|
+
octave: 3,
|
|
112024
|
+
ampEnvelope: {
|
|
112025
|
+
attack: 220,
|
|
112026
|
+
decay: 105,
|
|
112027
|
+
sustain: 1024,
|
|
112028
|
+
release: 350,
|
|
112029
|
+
amplitude: 1024
|
|
112030
|
+
},
|
|
112031
|
+
ampLFO: {
|
|
112032
|
+
frequency: 5,
|
|
112033
|
+
amplitude: 100
|
|
112034
|
+
},
|
|
112035
|
+
pitchLFO: {
|
|
112036
|
+
frequency: 1,
|
|
112037
|
+
amplitude: 4
|
|
112038
|
+
}
|
|
112039
|
+
}
|
|
112040
|
+
},
|
|
112041
|
+
{
|
|
112042
|
+
id: 4,
|
|
112043
|
+
name: lf("Car"),
|
|
112044
|
+
notes: [],
|
|
112045
|
+
iconURI: "/static/music-editor/car.png",
|
|
112046
|
+
instrument: {
|
|
112047
|
+
waveform: 16,
|
|
112048
|
+
octave: 4,
|
|
112049
|
+
ampEnvelope: {
|
|
112050
|
+
attack: 5,
|
|
112051
|
+
decay: 100,
|
|
112052
|
+
sustain: 1024,
|
|
112053
|
+
release: 30,
|
|
112054
|
+
amplitude: 1024
|
|
112055
|
+
},
|
|
112056
|
+
pitchLFO: {
|
|
112057
|
+
frequency: 10,
|
|
112058
|
+
amplitude: 4
|
|
112059
|
+
}
|
|
112060
|
+
}
|
|
112061
|
+
},
|
|
112062
|
+
{
|
|
112063
|
+
id: 5,
|
|
112064
|
+
name: lf("Computer"),
|
|
112065
|
+
notes: [],
|
|
112066
|
+
iconURI: "/static/music-editor/computer.png",
|
|
112067
|
+
instrument: {
|
|
112068
|
+
waveform: 15,
|
|
112069
|
+
octave: 1,
|
|
112070
|
+
ampEnvelope: {
|
|
112071
|
+
attack: 10,
|
|
112072
|
+
decay: 100,
|
|
112073
|
+
sustain: 500,
|
|
112074
|
+
release: 10,
|
|
112075
|
+
amplitude: 1024
|
|
112076
|
+
}
|
|
112077
|
+
}
|
|
112078
|
+
},
|
|
112079
|
+
{
|
|
112080
|
+
id: 6,
|
|
112081
|
+
name: lf("Burger"),
|
|
112082
|
+
notes: [],
|
|
112083
|
+
iconURI: "/static/music-editor/burger.png",
|
|
112084
|
+
instrument: {
|
|
112085
|
+
waveform: 1,
|
|
112086
|
+
octave: 1,
|
|
112087
|
+
ampEnvelope: {
|
|
112088
|
+
attack: 10,
|
|
112089
|
+
decay: 100,
|
|
112090
|
+
sustain: 500,
|
|
112091
|
+
release: 100,
|
|
112092
|
+
amplitude: 1024
|
|
112093
|
+
}
|
|
112094
|
+
}
|
|
112095
|
+
},
|
|
112096
|
+
{
|
|
112097
|
+
id: 7,
|
|
112098
|
+
name: lf("Cherry"),
|
|
112099
|
+
notes: [],
|
|
112100
|
+
iconURI: "/static/music-editor/cherry.png",
|
|
112101
|
+
instrument: {
|
|
112102
|
+
waveform: 2,
|
|
112103
|
+
octave: 3,
|
|
112104
|
+
ampEnvelope: {
|
|
112105
|
+
attack: 10,
|
|
112106
|
+
decay: 100,
|
|
112107
|
+
sustain: 500,
|
|
112108
|
+
release: 100,
|
|
112109
|
+
amplitude: 1024
|
|
112110
|
+
}
|
|
112111
|
+
}
|
|
112112
|
+
},
|
|
112113
|
+
{
|
|
112114
|
+
id: 8,
|
|
112115
|
+
name: lf("Lemon"),
|
|
112116
|
+
notes: [],
|
|
112117
|
+
iconURI: "/static/music-editor/lemon.png",
|
|
112118
|
+
instrument: {
|
|
112119
|
+
waveform: 15,
|
|
112120
|
+
octave: 2,
|
|
112121
|
+
ampEnvelope: {
|
|
112122
|
+
attack: 10,
|
|
112123
|
+
decay: 100,
|
|
112124
|
+
sustain: 500,
|
|
112125
|
+
release: 10,
|
|
112126
|
+
amplitude: 1024
|
|
112127
|
+
}
|
|
112128
|
+
}
|
|
112129
|
+
},
|
|
112130
|
+
{
|
|
112131
|
+
id: 9,
|
|
112132
|
+
name: lf("Explosion"),
|
|
112133
|
+
notes: [],
|
|
112134
|
+
iconURI: "/static/music-editor/explosion.png",
|
|
112135
|
+
instrument: {
|
|
112136
|
+
waveform: 11,
|
|
112137
|
+
octave: 4,
|
|
112138
|
+
ampEnvelope: {
|
|
112139
|
+
attack: 10,
|
|
112140
|
+
decay: 100,
|
|
112141
|
+
sustain: 500,
|
|
112142
|
+
release: 100,
|
|
112143
|
+
amplitude: 1024
|
|
112144
|
+
}
|
|
112145
|
+
},
|
|
112146
|
+
drums: [
|
|
112147
|
+
{
|
|
112148
|
+
startFrequency: 100,
|
|
112149
|
+
startVolume: 1024,
|
|
112150
|
+
steps: [
|
|
112151
|
+
{
|
|
112152
|
+
waveform: 3,
|
|
112153
|
+
frequency: 120,
|
|
112154
|
+
duration: 10,
|
|
112155
|
+
volume: 1024
|
|
112156
|
+
},
|
|
112157
|
+
{
|
|
112158
|
+
waveform: 3,
|
|
112159
|
+
frequency: 1,
|
|
112160
|
+
duration: 100,
|
|
112161
|
+
volume: 0
|
|
112162
|
+
}
|
|
112163
|
+
]
|
|
112164
|
+
},
|
|
112165
|
+
{
|
|
112166
|
+
startFrequency: 1,
|
|
112167
|
+
startVolume: 1024,
|
|
112168
|
+
steps: [
|
|
112169
|
+
{
|
|
112170
|
+
waveform: 5,
|
|
112171
|
+
frequency: 1,
|
|
112172
|
+
duration: 20,
|
|
112173
|
+
volume: 0
|
|
112174
|
+
}
|
|
112175
|
+
]
|
|
112176
|
+
},
|
|
112177
|
+
{
|
|
112178
|
+
startFrequency: 1,
|
|
112179
|
+
startVolume: 1024,
|
|
112180
|
+
steps: [
|
|
112181
|
+
{
|
|
112182
|
+
waveform: 5,
|
|
112183
|
+
frequency: 1,
|
|
112184
|
+
duration: 20,
|
|
112185
|
+
volume: 480
|
|
112186
|
+
},
|
|
112187
|
+
{
|
|
112188
|
+
waveform: 5,
|
|
112189
|
+
frequency: 1,
|
|
112190
|
+
duration: 20,
|
|
112191
|
+
volume: 260
|
|
112192
|
+
},
|
|
112193
|
+
{
|
|
112194
|
+
waveform: 5,
|
|
112195
|
+
frequency: 1,
|
|
112196
|
+
duration: 20,
|
|
112197
|
+
volume: 200
|
|
112198
|
+
},
|
|
112199
|
+
{
|
|
112200
|
+
waveform: 5,
|
|
112201
|
+
frequency: 1,
|
|
112202
|
+
duration: 200,
|
|
112203
|
+
volume: 0
|
|
112204
|
+
},
|
|
112205
|
+
]
|
|
112206
|
+
},
|
|
112207
|
+
{
|
|
112208
|
+
startFrequency: 175,
|
|
112209
|
+
startVolume: 1024,
|
|
112210
|
+
steps: [
|
|
112211
|
+
{
|
|
112212
|
+
waveform: 1,
|
|
112213
|
+
frequency: 200,
|
|
112214
|
+
duration: 10,
|
|
112215
|
+
volume: 1024
|
|
112216
|
+
},
|
|
112217
|
+
{
|
|
112218
|
+
waveform: 1,
|
|
112219
|
+
frequency: 150,
|
|
112220
|
+
duration: 20,
|
|
112221
|
+
volume: 1024
|
|
112222
|
+
},
|
|
112223
|
+
{
|
|
112224
|
+
waveform: 5,
|
|
112225
|
+
frequency: 1,
|
|
112226
|
+
duration: 20,
|
|
112227
|
+
volume: 100
|
|
112228
|
+
},
|
|
112229
|
+
{
|
|
112230
|
+
waveform: 5,
|
|
112231
|
+
frequency: 1,
|
|
112232
|
+
duration: 300,
|
|
112233
|
+
volume: 0
|
|
112234
|
+
},
|
|
112235
|
+
]
|
|
112236
|
+
},
|
|
112237
|
+
{
|
|
112238
|
+
startFrequency: 100,
|
|
112239
|
+
startVolume: 1024,
|
|
112240
|
+
steps: [
|
|
112241
|
+
{
|
|
112242
|
+
waveform: 3,
|
|
112243
|
+
frequency: 120,
|
|
112244
|
+
duration: 10,
|
|
112245
|
+
volume: 1024
|
|
112246
|
+
},
|
|
112247
|
+
{
|
|
112248
|
+
waveform: 1,
|
|
112249
|
+
frequency: 120,
|
|
112250
|
+
duration: 100,
|
|
112251
|
+
volume: 0
|
|
112252
|
+
}
|
|
112253
|
+
]
|
|
112254
|
+
},
|
|
112255
|
+
{
|
|
112256
|
+
startFrequency: 1,
|
|
112257
|
+
startVolume: 1024,
|
|
112258
|
+
steps: [
|
|
112259
|
+
{
|
|
112260
|
+
waveform: 5,
|
|
112261
|
+
frequency: 1,
|
|
112262
|
+
duration: 20,
|
|
112263
|
+
volume: 0
|
|
112264
|
+
}
|
|
112265
|
+
]
|
|
112266
|
+
},
|
|
112267
|
+
{
|
|
112268
|
+
startFrequency: 1,
|
|
112269
|
+
startVolume: 1024,
|
|
112270
|
+
steps: [
|
|
112271
|
+
{
|
|
112272
|
+
waveform: 5,
|
|
112273
|
+
frequency: 1,
|
|
112274
|
+
duration: 20,
|
|
112275
|
+
volume: 480
|
|
112276
|
+
},
|
|
112277
|
+
{
|
|
112278
|
+
waveform: 5,
|
|
112279
|
+
frequency: 1,
|
|
112280
|
+
duration: 20,
|
|
112281
|
+
volume: 260
|
|
112282
|
+
},
|
|
112283
|
+
{
|
|
112284
|
+
waveform: 5,
|
|
112285
|
+
frequency: 1,
|
|
112286
|
+
duration: 20,
|
|
112287
|
+
volume: 200
|
|
112288
|
+
},
|
|
112289
|
+
{
|
|
112290
|
+
waveform: 5,
|
|
112291
|
+
frequency: 1,
|
|
112292
|
+
duration: 200,
|
|
112293
|
+
volume: 0
|
|
112294
|
+
},
|
|
112295
|
+
]
|
|
112296
|
+
},
|
|
112297
|
+
{
|
|
112298
|
+
startFrequency: 175,
|
|
112299
|
+
startVolume: 1024,
|
|
112300
|
+
steps: [
|
|
112301
|
+
{
|
|
112302
|
+
waveform: 1,
|
|
112303
|
+
frequency: 200,
|
|
112304
|
+
duration: 10,
|
|
112305
|
+
volume: 1024
|
|
112306
|
+
},
|
|
112307
|
+
{
|
|
112308
|
+
waveform: 1,
|
|
112309
|
+
frequency: 150,
|
|
112310
|
+
duration: 20,
|
|
112311
|
+
volume: 1024
|
|
112312
|
+
},
|
|
112313
|
+
{
|
|
112314
|
+
waveform: 5,
|
|
112315
|
+
frequency: 1,
|
|
112316
|
+
duration: 20,
|
|
112317
|
+
volume: 100
|
|
112318
|
+
},
|
|
112319
|
+
{
|
|
112320
|
+
waveform: 5,
|
|
112321
|
+
frequency: 1,
|
|
112322
|
+
duration: 300,
|
|
112323
|
+
volume: 0
|
|
112324
|
+
},
|
|
112325
|
+
]
|
|
112326
|
+
},
|
|
112327
|
+
{
|
|
112328
|
+
startFrequency: 100,
|
|
112329
|
+
startVolume: 1024,
|
|
112330
|
+
steps: [
|
|
112331
|
+
{
|
|
112332
|
+
waveform: 3,
|
|
112333
|
+
frequency: 120,
|
|
112334
|
+
duration: 10,
|
|
112335
|
+
volume: 1024
|
|
112336
|
+
},
|
|
112337
|
+
{
|
|
112338
|
+
waveform: 1,
|
|
112339
|
+
frequency: 120,
|
|
112340
|
+
duration: 100,
|
|
112341
|
+
volume: 0
|
|
112342
|
+
}
|
|
112343
|
+
]
|
|
112344
|
+
},
|
|
112345
|
+
{
|
|
112346
|
+
startFrequency: 1,
|
|
112347
|
+
startVolume: 1024,
|
|
112348
|
+
steps: [
|
|
112349
|
+
{
|
|
112350
|
+
waveform: 5,
|
|
112351
|
+
frequency: 1,
|
|
112352
|
+
duration: 20,
|
|
112353
|
+
volume: 0
|
|
112354
|
+
}
|
|
112355
|
+
]
|
|
112356
|
+
},
|
|
112357
|
+
{
|
|
112358
|
+
startFrequency: 1,
|
|
112359
|
+
startVolume: 1024,
|
|
112360
|
+
steps: [
|
|
112361
|
+
{
|
|
112362
|
+
waveform: 5,
|
|
112363
|
+
frequency: 1,
|
|
112364
|
+
duration: 20,
|
|
112365
|
+
volume: 480
|
|
112366
|
+
},
|
|
112367
|
+
{
|
|
112368
|
+
waveform: 5,
|
|
112369
|
+
frequency: 1,
|
|
112370
|
+
duration: 20,
|
|
112371
|
+
volume: 260
|
|
112372
|
+
},
|
|
112373
|
+
{
|
|
112374
|
+
waveform: 5,
|
|
112375
|
+
frequency: 1,
|
|
112376
|
+
duration: 20,
|
|
112377
|
+
volume: 200
|
|
112378
|
+
},
|
|
112379
|
+
{
|
|
112380
|
+
waveform: 5,
|
|
112381
|
+
frequency: 1,
|
|
112382
|
+
duration: 200,
|
|
112383
|
+
volume: 0
|
|
112384
|
+
},
|
|
112385
|
+
]
|
|
112386
|
+
},
|
|
112387
|
+
{
|
|
112388
|
+
startFrequency: 175,
|
|
112389
|
+
startVolume: 1024,
|
|
112390
|
+
steps: [
|
|
112391
|
+
{
|
|
112392
|
+
waveform: 1,
|
|
112393
|
+
frequency: 200,
|
|
112394
|
+
duration: 10,
|
|
112395
|
+
volume: 1024
|
|
112396
|
+
},
|
|
112397
|
+
{
|
|
112398
|
+
waveform: 1,
|
|
112399
|
+
frequency: 150,
|
|
112400
|
+
duration: 20,
|
|
112401
|
+
volume: 1024
|
|
112402
|
+
},
|
|
112403
|
+
{
|
|
112404
|
+
waveform: 5,
|
|
112405
|
+
frequency: 1,
|
|
112406
|
+
duration: 20,
|
|
112407
|
+
volume: 100
|
|
112408
|
+
},
|
|
112409
|
+
{
|
|
112410
|
+
waveform: 5,
|
|
112411
|
+
frequency: 1,
|
|
112412
|
+
duration: 300,
|
|
112413
|
+
volume: 0
|
|
112414
|
+
},
|
|
112415
|
+
]
|
|
112416
|
+
}
|
|
112417
|
+
]
|
|
112418
|
+
}
|
|
112419
|
+
]
|
|
112420
|
+
};
|
|
112421
|
+
}
|
|
112422
|
+
music.getEmptySong = getEmptySong;
|
|
112423
|
+
})(music = assets.music || (assets.music = {}));
|
|
112424
|
+
})(assets = pxt.assets || (pxt.assets = {}));
|
|
112425
|
+
})(pxt || (pxt = {}));
|
|
111370
112426
|
/// <reference path="../localtypings/pxtpackage.d.ts"/>
|
|
111371
112427
|
/// <reference path="../localtypings/pxtparts.d.ts"/>
|
|
111372
112428
|
/// <reference path="../localtypings/pxtarget.d.ts"/>
|
|
@@ -115431,6 +116487,7 @@ var pxt;
|
|
|
115431
116487
|
pxt.IMAGE_MIME_TYPE = "image/x-mkcd-f4";
|
|
115432
116488
|
pxt.TILEMAP_MIME_TYPE = "application/mkcd-tilemap";
|
|
115433
116489
|
pxt.ANIMATION_MIME_TYPE = "application/mkcd-animation";
|
|
116490
|
+
pxt.SONG_MIME_TYPE = "application/mkcd-song";
|
|
115434
116491
|
class AssetCollection {
|
|
115435
116492
|
constructor() {
|
|
115436
116493
|
this.assets = [];
|
|
@@ -115617,21 +116674,24 @@ var pxt;
|
|
|
115617
116674
|
tilemaps: new AssetCollection(),
|
|
115618
116675
|
tiles: new AssetCollection(),
|
|
115619
116676
|
animations: new AssetCollection(),
|
|
115620
|
-
images: new AssetCollection()
|
|
116677
|
+
images: new AssetCollection(),
|
|
116678
|
+
songs: new AssetCollection(),
|
|
115621
116679
|
};
|
|
115622
116680
|
this.state = {
|
|
115623
116681
|
revision: this.nextID++,
|
|
115624
116682
|
tilemaps: new AssetCollection(),
|
|
115625
116683
|
tiles: new AssetCollection(),
|
|
115626
116684
|
animations: new AssetCollection(),
|
|
115627
|
-
images: new AssetCollection()
|
|
116685
|
+
images: new AssetCollection(),
|
|
116686
|
+
songs: new AssetCollection(),
|
|
115628
116687
|
};
|
|
115629
116688
|
this.gallery = {
|
|
115630
116689
|
revision: 0,
|
|
115631
116690
|
tilemaps: new AssetCollection(),
|
|
115632
116691
|
tiles: new AssetCollection(),
|
|
115633
116692
|
animations: new AssetCollection(),
|
|
115634
|
-
images: new AssetCollection()
|
|
116693
|
+
images: new AssetCollection(),
|
|
116694
|
+
songs: new AssetCollection(),
|
|
115635
116695
|
};
|
|
115636
116696
|
this.undoStack = [];
|
|
115637
116697
|
this.redoStack = [];
|
|
@@ -115733,6 +116793,19 @@ var pxt;
|
|
|
115733
116793
|
};
|
|
115734
116794
|
return this.state.images.add(newImage);
|
|
115735
116795
|
}
|
|
116796
|
+
createNewSong(data, displayName) {
|
|
116797
|
+
this.onChange();
|
|
116798
|
+
const newSong = {
|
|
116799
|
+
internalID: this.getNewInternalId(),
|
|
116800
|
+
id: this.generateNewID("song" /* AssetType.Song */),
|
|
116801
|
+
type: "song" /* AssetType.Song */,
|
|
116802
|
+
song: pxt.assets.music.cloneSong(data),
|
|
116803
|
+
meta: {
|
|
116804
|
+
displayName
|
|
116805
|
+
},
|
|
116806
|
+
};
|
|
116807
|
+
return this.state.songs.add(newSong);
|
|
116808
|
+
}
|
|
115736
116809
|
updateTile(tile) {
|
|
115737
116810
|
this.onChange();
|
|
115738
116811
|
const existing = this.resolveProjectTileByInternalID(tile.internalID);
|
|
@@ -115769,6 +116842,7 @@ var pxt;
|
|
|
115769
116842
|
const blob = {};
|
|
115770
116843
|
this.state.images.serializeToJRes(blob);
|
|
115771
116844
|
this.state.animations.serializeToJRes(blob);
|
|
116845
|
+
this.state.songs.serializeToJRes(blob);
|
|
115772
116846
|
blob["*"] = {
|
|
115773
116847
|
"mimeType": "image/x-mkcd-f4",
|
|
115774
116848
|
"dataEncoding": "base64",
|
|
@@ -115850,6 +116924,7 @@ var pxt;
|
|
|
115850
116924
|
tilemaps: this.state.tilemaps.clone(),
|
|
115851
116925
|
animations: this.state.animations.clone(),
|
|
115852
116926
|
tiles: this.state.tiles.clone(),
|
|
116927
|
+
songs: this.state.songs.clone(),
|
|
115853
116928
|
};
|
|
115854
116929
|
}
|
|
115855
116930
|
undo() {
|
|
@@ -115862,6 +116937,7 @@ var pxt;
|
|
|
115862
116937
|
this.state.images.applyDiff(undo.images, true);
|
|
115863
116938
|
this.state.tilemaps.applyDiff(undo.tilemaps, true);
|
|
115864
116939
|
this.state.animations.applyDiff(undo.animations, true);
|
|
116940
|
+
this.state.songs.applyDiff(undo.songs, true);
|
|
115865
116941
|
this.state.revision = undo.beforeRevision;
|
|
115866
116942
|
this.redoStack.push(undo);
|
|
115867
116943
|
this.committedState = this.cloneState();
|
|
@@ -115875,6 +116951,7 @@ var pxt;
|
|
|
115875
116951
|
this.state.images.applyDiff(redo.images);
|
|
115876
116952
|
this.state.tilemaps.applyDiff(redo.tilemaps);
|
|
115877
116953
|
this.state.animations.applyDiff(redo.animations);
|
|
116954
|
+
this.state.songs.applyDiff(redo.songs);
|
|
115878
116955
|
this.state.revision = redo.afterRevision;
|
|
115879
116956
|
this.undoStack.push(redo);
|
|
115880
116957
|
this.committedState = this.cloneState();
|
|
@@ -115891,7 +116968,8 @@ var pxt;
|
|
|
115891
116968
|
tiles: this.state.tiles.diff(this.committedState.tiles),
|
|
115892
116969
|
images: this.state.images.diff(this.committedState.images),
|
|
115893
116970
|
tilemaps: this.state.tilemaps.diff(this.committedState.tilemaps),
|
|
115894
|
-
animations: this.state.animations.diff(this.committedState.animations)
|
|
116971
|
+
animations: this.state.animations.diff(this.committedState.animations),
|
|
116972
|
+
songs: this.state.songs.diff(this.committedState.songs)
|
|
115895
116973
|
});
|
|
115896
116974
|
this.committedState = this.cloneState();
|
|
115897
116975
|
this.cleanupTemporaryAssets();
|
|
@@ -115921,16 +116999,8 @@ var pxt;
|
|
|
115921
116999
|
}
|
|
115922
117000
|
isNameTaken(assetType, name) {
|
|
115923
117001
|
const isTaken = (id) => {
|
|
115924
|
-
|
|
115925
|
-
|
|
115926
|
-
return this.state.images.isIDTaken(id) || this.gallery.images.isIDTaken(id);
|
|
115927
|
-
case "tile" /* AssetType.Tile */:
|
|
115928
|
-
return this.state.tiles.isIDTaken(id) || this.gallery.tiles.isIDTaken(id);
|
|
115929
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
115930
|
-
return this.state.tilemaps.isIDTaken(id) || this.gallery.tilemaps.isIDTaken(id);
|
|
115931
|
-
case "animation" /* AssetType.Animation */:
|
|
115932
|
-
return this.state.animations.isIDTaken(id) || this.gallery.animations.isIDTaken(id);
|
|
115933
|
-
}
|
|
117002
|
+
return getAssetCollection(this.state, assetType).isIDTaken(id) ||
|
|
117003
|
+
getAssetCollection(this.gallery, assetType).isIDTaken(id);
|
|
115934
117004
|
};
|
|
115935
117005
|
const shortId = getShortIDCore(assetType, name);
|
|
115936
117006
|
const checkShortId = shortId && shortId !== name;
|
|
@@ -115956,6 +117026,10 @@ var pxt;
|
|
|
115956
117026
|
* assets.animation`shortId`
|
|
115957
117027
|
* assets.animation`displayName`
|
|
115958
117028
|
*
|
|
117029
|
+
* SONGS:
|
|
117030
|
+
* assets.song`shortId`
|
|
117031
|
+
* assets.song`displayName`
|
|
117032
|
+
*
|
|
115959
117033
|
* TILEMAPS:
|
|
115960
117034
|
* tilemap`shortId`
|
|
115961
117035
|
*
|
|
@@ -115994,6 +117068,11 @@ var pxt;
|
|
|
115994
117068
|
if (displayName)
|
|
115995
117069
|
assetTsRefs += `|assets.animation\`${displayName}\``;
|
|
115996
117070
|
break;
|
|
117071
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117072
|
+
assetTsRefs = `assets.song\`${shortId}\``;
|
|
117073
|
+
if (displayName)
|
|
117074
|
+
assetTsRefs += `|assets.song\`${displayName}\``;
|
|
117075
|
+
break;
|
|
115997
117076
|
default:
|
|
115998
117077
|
assetTsRefs = `assets.image\`${shortId}\``;
|
|
115999
117078
|
if (displayName)
|
|
@@ -116016,6 +117095,11 @@ var pxt;
|
|
|
116016
117095
|
if (displayName)
|
|
116017
117096
|
assetPyRefs += `|assets.animation\("""${displayName}"""\)`;
|
|
116018
117097
|
break;
|
|
117098
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117099
|
+
assetPyRefs = `assets.song\("""${shortId}"""\)`;
|
|
117100
|
+
if (displayName)
|
|
117101
|
+
assetPyRefs += `|assets.song\("""${displayName}"""\)`;
|
|
117102
|
+
break;
|
|
116019
117103
|
default:
|
|
116020
117104
|
assetPyRefs = `assets.image\("""${shortId}"""\)`;
|
|
116021
117105
|
if (displayName)
|
|
@@ -116041,65 +117125,29 @@ var pxt;
|
|
|
116041
117125
|
return false;
|
|
116042
117126
|
}
|
|
116043
117127
|
lookupAsset(assetType, name) {
|
|
116044
|
-
|
|
116045
|
-
|
|
116046
|
-
return this.state.images.getByID(name) || this.gallery.images.getByID(name);
|
|
116047
|
-
case "tile" /* AssetType.Tile */:
|
|
116048
|
-
return this.state.tiles.getByID(name) || this.gallery.tiles.getByID(name);
|
|
116049
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116050
|
-
return this.state.tilemaps.getByID(name) || this.gallery.tilemaps.getByID(name);
|
|
116051
|
-
case "animation" /* AssetType.Animation */:
|
|
116052
|
-
return this.state.animations.getByID(name) || this.gallery.animations.getByID(name);
|
|
116053
|
-
}
|
|
117128
|
+
return getAssetCollection(this.state, assetType).getByID(name) ||
|
|
117129
|
+
getAssetCollection(this.gallery, assetType).getByID(name);
|
|
116054
117130
|
}
|
|
116055
117131
|
lookupAssetByName(assetType, name) {
|
|
116056
|
-
|
|
116057
|
-
case "image" /* AssetType.Image */:
|
|
116058
|
-
return this.state.images.getByDisplayName(name);
|
|
116059
|
-
case "tile" /* AssetType.Tile */:
|
|
116060
|
-
return this.state.tiles.getByDisplayName(name);
|
|
116061
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116062
|
-
return this.state.tilemaps.getByDisplayName(name);
|
|
116063
|
-
case "animation" /* AssetType.Animation */:
|
|
116064
|
-
return this.state.animations.getByDisplayName(name);
|
|
116065
|
-
}
|
|
117132
|
+
return getAssetCollection(this.state, assetType).getByDisplayName(name);
|
|
116066
117133
|
}
|
|
116067
117134
|
getAssets(type) {
|
|
116068
|
-
|
|
116069
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot();
|
|
116070
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot();
|
|
116071
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot();
|
|
116072
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot();
|
|
116073
|
-
}
|
|
117135
|
+
return getAssetCollection(this.state, type).getSnapshot();
|
|
116074
117136
|
}
|
|
116075
117137
|
getGalleryAssets(type) {
|
|
116076
|
-
|
|
116077
|
-
case "image" /* AssetType.Image */: return this.gallery.images.getSnapshot();
|
|
116078
|
-
case "tile" /* AssetType.Tile */: return this.gallery.tiles.getSnapshot();
|
|
116079
|
-
case "tilemap" /* AssetType.Tilemap */: return this.gallery.tilemaps.getSnapshot();
|
|
116080
|
-
case "animation" /* AssetType.Animation */: return this.gallery.animations.getSnapshot();
|
|
116081
|
-
}
|
|
117138
|
+
return getAssetCollection(this.gallery, type).getSnapshot();
|
|
116082
117139
|
}
|
|
116083
117140
|
lookupBlockAsset(type, blockID) {
|
|
116084
117141
|
let filter = (a) => { var _a, _b; return ((_b = (_a = a.meta) === null || _a === void 0 ? void 0 : _a.blockIDs) === null || _b === void 0 ? void 0 : _b.indexOf(blockID)) !== -1; };
|
|
116085
|
-
|
|
116086
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot(filter)[0];
|
|
116087
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot(filter)[0];
|
|
116088
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot(filter)[0];
|
|
116089
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot(filter)[0];
|
|
116090
|
-
}
|
|
117142
|
+
return getAssetCollection(this.state, type).getSnapshot(filter)[0];
|
|
116091
117143
|
}
|
|
116092
117144
|
updateAsset(asset) {
|
|
116093
117145
|
this.onChange();
|
|
116094
117146
|
switch (asset.type) {
|
|
116095
|
-
case "image" /* AssetType.Image */:
|
|
116096
|
-
return this.state.images.update(asset.id, asset);
|
|
116097
117147
|
case "tile" /* AssetType.Tile */:
|
|
116098
117148
|
return this.updateTile(asset);
|
|
116099
|
-
|
|
116100
|
-
return this.state.
|
|
116101
|
-
case "animation" /* AssetType.Animation */:
|
|
116102
|
-
return this.state.animations.update(asset.id, asset);
|
|
117149
|
+
default:
|
|
117150
|
+
return getAssetCollection(this.state, asset.type).update(asset.id, asset);
|
|
116103
117151
|
}
|
|
116104
117152
|
}
|
|
116105
117153
|
duplicateAsset(asset, displayName) {
|
|
@@ -116121,53 +117169,22 @@ var pxt;
|
|
|
116121
117169
|
break;
|
|
116122
117170
|
case "animation" /* AssetType.Animation */:
|
|
116123
117171
|
newAsset = this.createNewAnimationFromData(clone.frames, clone.interval, name);
|
|
117172
|
+
break;
|
|
117173
|
+
case "song" /* AssetType.Song */:
|
|
117174
|
+
newAsset = this.createNewSong(asset.song, name);
|
|
117175
|
+
break;
|
|
116124
117176
|
}
|
|
116125
117177
|
return newAsset;
|
|
116126
117178
|
}
|
|
116127
117179
|
removeAsset(asset) {
|
|
116128
117180
|
this.onChange();
|
|
116129
|
-
|
|
116130
|
-
case "image" /* AssetType.Image */:
|
|
116131
|
-
return this.state.images.removeByID(asset.id);
|
|
116132
|
-
case "tile" /* AssetType.Tile */:
|
|
116133
|
-
return this.state.tiles.removeByID(asset.id);
|
|
116134
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116135
|
-
return this.state.tilemaps.removeByID(asset.id);
|
|
116136
|
-
case "animation" /* AssetType.Animation */:
|
|
116137
|
-
return this.state.animations.removeByID(asset.id);
|
|
116138
|
-
}
|
|
117181
|
+
getAssetCollection(this.state, asset.type).removeByID(asset.id);
|
|
116139
117182
|
}
|
|
116140
117183
|
addChangeListener(asset, listener) {
|
|
116141
|
-
|
|
116142
|
-
case "image" /* AssetType.Image */:
|
|
116143
|
-
this.state.images.addListener(asset.internalID, listener);
|
|
116144
|
-
break;
|
|
116145
|
-
case "tile" /* AssetType.Tile */:
|
|
116146
|
-
this.state.tiles.addListener(asset.internalID, listener);
|
|
116147
|
-
break;
|
|
116148
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116149
|
-
this.state.tilemaps.addListener(asset.internalID, listener);
|
|
116150
|
-
break;
|
|
116151
|
-
case "animation" /* AssetType.Animation */:
|
|
116152
|
-
this.state.animations.addListener(asset.internalID, listener);
|
|
116153
|
-
break;
|
|
116154
|
-
}
|
|
117184
|
+
getAssetCollection(this.state, asset.type).addListener(asset.internalID, listener);
|
|
116155
117185
|
}
|
|
116156
117186
|
removeChangeListener(type, listener) {
|
|
116157
|
-
|
|
116158
|
-
case "image" /* AssetType.Image */:
|
|
116159
|
-
this.state.images.removeListener(listener);
|
|
116160
|
-
break;
|
|
116161
|
-
case "tile" /* AssetType.Tile */:
|
|
116162
|
-
this.state.tiles.removeListener(listener);
|
|
116163
|
-
break;
|
|
116164
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116165
|
-
this.state.tilemaps.removeListener(listener);
|
|
116166
|
-
break;
|
|
116167
|
-
case "animation" /* AssetType.Animation */:
|
|
116168
|
-
this.state.animations.removeListener(listener);
|
|
116169
|
-
break;
|
|
116170
|
-
}
|
|
117187
|
+
getAssetCollection(this.state, type).removeListener(listener);
|
|
116171
117188
|
}
|
|
116172
117189
|
loadPackage(pack) {
|
|
116173
117190
|
const allPackages = pack.sortedDeps();
|
|
@@ -116192,7 +117209,7 @@ var pxt;
|
|
|
116192
117209
|
this.gallery.images.add(image);
|
|
116193
117210
|
}
|
|
116194
117211
|
}
|
|
116195
|
-
else {
|
|
117212
|
+
else if (image.type === "animation" /* AssetType.Animation */) {
|
|
116196
117213
|
if (isProject) {
|
|
116197
117214
|
this.state.animations.add(image);
|
|
116198
117215
|
}
|
|
@@ -116200,6 +117217,14 @@ var pxt;
|
|
|
116200
117217
|
this.gallery.animations.add(image);
|
|
116201
117218
|
}
|
|
116202
117219
|
}
|
|
117220
|
+
else {
|
|
117221
|
+
if (isProject) {
|
|
117222
|
+
this.state.songs.add(image);
|
|
117223
|
+
}
|
|
117224
|
+
else {
|
|
117225
|
+
this.gallery.songs.add(image);
|
|
117226
|
+
}
|
|
117227
|
+
}
|
|
116203
117228
|
}
|
|
116204
117229
|
}
|
|
116205
117230
|
for (const tm of getTilemaps(pack.parseJRes())) {
|
|
@@ -116276,6 +117301,9 @@ var pxt;
|
|
|
116276
117301
|
this.state.animations.add(animation);
|
|
116277
117302
|
}
|
|
116278
117303
|
}
|
|
117304
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
117305
|
+
this.state.songs.add(this.generateSong(entry));
|
|
117306
|
+
}
|
|
116279
117307
|
}
|
|
116280
117308
|
for (const animation of toInflate) {
|
|
116281
117309
|
this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
|
|
@@ -116286,6 +117314,7 @@ var pxt;
|
|
|
116286
117314
|
cleanupCollection(this.state.tiles);
|
|
116287
117315
|
cleanupCollection(this.state.tilemaps);
|
|
116288
117316
|
cleanupCollection(this.state.animations);
|
|
117317
|
+
cleanupCollection(this.state.songs);
|
|
116289
117318
|
function cleanupCollection(collection) {
|
|
116290
117319
|
const inactiveAssets = collection.getSnapshot(asset => { var _a; return !asset.meta.displayName && ((_a = asset.meta.blockIDs) === null || _a === void 0 ? void 0 : _a.some(id => activeBlockIDs.indexOf(id) === -1)); });
|
|
116291
117320
|
const toRemove = [];
|
|
@@ -116315,6 +117344,17 @@ var pxt;
|
|
|
116315
117344
|
bitmap: pxt.sprite.getBitmapFromJResURL(`data:${pxt.IMAGE_MIME_TYPE};base64,${entry.data}`).data()
|
|
116316
117345
|
};
|
|
116317
117346
|
}
|
|
117347
|
+
generateSong(entry) {
|
|
117348
|
+
return {
|
|
117349
|
+
internalID: this.getNewInternalId(),
|
|
117350
|
+
type: "song" /* AssetType.Song */,
|
|
117351
|
+
id: entry.id,
|
|
117352
|
+
meta: {
|
|
117353
|
+
displayName: entry.displayName
|
|
117354
|
+
},
|
|
117355
|
+
song: pxt.assets.music.decodeSongFromHex(entry.data)
|
|
117356
|
+
};
|
|
117357
|
+
}
|
|
116318
117358
|
generateAnimation(entry) {
|
|
116319
117359
|
if (entry.dataEncoding === "json") {
|
|
116320
117360
|
let data;
|
|
@@ -116368,6 +117408,8 @@ var pxt;
|
|
|
116368
117408
|
return this.generateNewIDInternal("tile" /* AssetType.Tile */, pxt.sprite.TILE_PREFIX, pxt.sprite.TILE_NAMESPACE);
|
|
116369
117409
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116370
117410
|
return this.generateNewIDInternal("tilemap" /* AssetType.Tilemap */, lf("level"));
|
|
117411
|
+
case "song" /* AssetType.Song */:
|
|
117412
|
+
return this.generateNewIDInternal("song" /* AssetType.Song */, pxt.sprite.SONG_PREFIX, pxt.sprite.SONG_NAMESPACE);
|
|
116371
117413
|
}
|
|
116372
117414
|
}
|
|
116373
117415
|
generateNewIDInternal(type, varPrefix, namespaceString) {
|
|
@@ -116405,6 +117447,9 @@ var pxt;
|
|
|
116405
117447
|
assets.push(animation);
|
|
116406
117448
|
}
|
|
116407
117449
|
}
|
|
117450
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
117451
|
+
assets.push(this.generateSong(entry));
|
|
117452
|
+
}
|
|
116408
117453
|
}
|
|
116409
117454
|
for (const animation of toInflate) {
|
|
116410
117455
|
assets.push(this.inflateAnimation(animation, assets));
|
|
@@ -116465,6 +117510,7 @@ var pxt;
|
|
|
116465
117510
|
let out = "";
|
|
116466
117511
|
const imageEntries = [];
|
|
116467
117512
|
const animationEntries = [];
|
|
117513
|
+
const songEntries = [];
|
|
116468
117514
|
for (const key of entries) {
|
|
116469
117515
|
if (key === "*")
|
|
116470
117516
|
continue;
|
|
@@ -116491,10 +117537,17 @@ var pxt;
|
|
|
116491
117537
|
expression: `[${animation.frames.map(f => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(f), "typescript")).join(", ")}]`
|
|
116492
117538
|
});
|
|
116493
117539
|
}
|
|
117540
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
117541
|
+
songEntries.push({
|
|
117542
|
+
keys: [getShortIDCore("song" /* AssetType.Song */, key, true), entry.displayName],
|
|
117543
|
+
expression: `hex\`${entry.data}\``
|
|
117544
|
+
});
|
|
117545
|
+
}
|
|
116494
117546
|
}
|
|
116495
117547
|
const warning = lf("Auto-generated code. Do not edit.");
|
|
116496
117548
|
out += emitFactoryHelper("image", imageEntries);
|
|
116497
117549
|
out += emitFactoryHelper("animation", animationEntries);
|
|
117550
|
+
out += emitFactoryHelper("song", songEntries);
|
|
116498
117551
|
return `// ${warning}\nnamespace ${pxt.sprite.IMAGES_NAMESPACE} {\n${out}\n}\n// ${warning}\n`;
|
|
116499
117552
|
}
|
|
116500
117553
|
pxt.emitProjectImages = emitProjectImages;
|
|
@@ -116538,6 +117591,8 @@ var pxt;
|
|
|
116538
117591
|
return Object.assign(Object.assign({}, asset), { frames: asset.frames.map(frame => cloneBitmap(frame)) });
|
|
116539
117592
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116540
117593
|
return Object.assign(Object.assign({}, asset), { data: asset.data.cloneData() });
|
|
117594
|
+
case "song" /* AssetType.Song */:
|
|
117595
|
+
return Object.assign(Object.assign({}, asset), { song: pxt.assets.music.cloneSong(asset.song) });
|
|
116541
117596
|
}
|
|
116542
117597
|
}
|
|
116543
117598
|
pxt.cloneAsset = cloneAsset;
|
|
@@ -116571,6 +117626,13 @@ var pxt;
|
|
|
116571
117626
|
case "animation" /* AssetType.Animation */:
|
|
116572
117627
|
allJRes[id] = serializeAnimation(asset);
|
|
116573
117628
|
break;
|
|
117629
|
+
case "song" /* AssetType.Song */:
|
|
117630
|
+
allJRes[id] = {
|
|
117631
|
+
data: pxt.assets.music.encodeSongToHex(asset.song),
|
|
117632
|
+
mimeType: pxt.SONG_MIME_TYPE,
|
|
117633
|
+
displayName: asset.meta.displayName
|
|
117634
|
+
};
|
|
117635
|
+
break;
|
|
116574
117636
|
}
|
|
116575
117637
|
}
|
|
116576
117638
|
function assetEquals(a, b) {
|
|
@@ -116590,6 +117652,8 @@ var pxt;
|
|
|
116590
117652
|
return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
|
|
116591
117653
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116592
117654
|
return a.data.equals(b.data);
|
|
117655
|
+
case "song" /* AssetType.Song */:
|
|
117656
|
+
return pxt.assets.music.songEquals(a.song, b.song);
|
|
116593
117657
|
}
|
|
116594
117658
|
}
|
|
116595
117659
|
pxt.assetEquals = assetEquals;
|
|
@@ -116629,11 +117693,13 @@ var pxt;
|
|
|
116629
117693
|
return `assets.animation${leftTick}${shortId}${rightTick}`;
|
|
116630
117694
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116631
117695
|
return `tilemap${leftTick}${shortId}${rightTick}`;
|
|
117696
|
+
case "song" /* AssetType.Song */:
|
|
117697
|
+
return `assets.song${leftTick}${shortId}${rightTick}`;
|
|
116632
117698
|
}
|
|
116633
117699
|
}
|
|
116634
117700
|
pxt.getTSReferenceForAsset = getTSReferenceForAsset;
|
|
116635
117701
|
function parseAssetTSReference(ts) {
|
|
116636
|
-
const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
|
|
117702
|
+
const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap|song))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
|
|
116637
117703
|
if (match) {
|
|
116638
117704
|
const type = match[1] || match[2];
|
|
116639
117705
|
const name = match[3].trim();
|
|
@@ -116657,6 +117723,8 @@ var pxt;
|
|
|
116657
117723
|
return project.lookupAssetByName("tilemap" /* AssetType.Tilemap */, name) || project.lookupAsset("tilemap" /* AssetType.Tilemap */, name);
|
|
116658
117724
|
case "animation":
|
|
116659
117725
|
return project.lookupAssetByName("animation" /* AssetType.Animation */, name);
|
|
117726
|
+
case "song":
|
|
117727
|
+
return project.lookupAssetByName("song" /* AssetType.Song */, name);
|
|
116660
117728
|
}
|
|
116661
117729
|
}
|
|
116662
117730
|
return undefined;
|
|
@@ -116672,6 +117740,8 @@ var pxt;
|
|
|
116672
117740
|
return lf("level");
|
|
116673
117741
|
case "animation" /* pxt.AssetType.Animation */:
|
|
116674
117742
|
return lf("myAnim");
|
|
117743
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117744
|
+
return lf("mySong");
|
|
116675
117745
|
default:
|
|
116676
117746
|
return lf("asset");
|
|
116677
117747
|
}
|
|
@@ -116696,6 +117766,9 @@ var pxt;
|
|
|
116696
117766
|
case "animation" /* AssetType.Animation */:
|
|
116697
117767
|
prefix = pxt.sprite.ANIMATION_NAMESPACE + ".";
|
|
116698
117768
|
break;
|
|
117769
|
+
case "song" /* AssetType.Song */:
|
|
117770
|
+
prefix = pxt.sprite.SONG_NAMESPACE + ".";
|
|
117771
|
+
break;
|
|
116699
117772
|
}
|
|
116700
117773
|
if (prefix) {
|
|
116701
117774
|
if (id.startsWith(prefix)) {
|
|
@@ -116780,6 +117853,15 @@ var pxt;
|
|
|
116780
117853
|
function read16Bit(buf, offset) {
|
|
116781
117854
|
return buf[offset] | (buf[offset + 1] << 8);
|
|
116782
117855
|
}
|
|
117856
|
+
function getAssetCollection(snapshot, type) {
|
|
117857
|
+
switch (type) {
|
|
117858
|
+
case "animation" /* AssetType.Animation */: return snapshot.animations;
|
|
117859
|
+
case "image" /* AssetType.Image */: return snapshot.images;
|
|
117860
|
+
case "tile" /* AssetType.Tile */: return snapshot.tiles;
|
|
117861
|
+
case "tilemap" /* AssetType.Tilemap */: return snapshot.tilemaps;
|
|
117862
|
+
case "song" /* AssetType.Song */: return snapshot.songs;
|
|
117863
|
+
}
|
|
117864
|
+
}
|
|
116783
117865
|
})(pxt || (pxt = {}));
|
|
116784
117866
|
var pxt;
|
|
116785
117867
|
(function (pxt) {
|
|
@@ -120724,7 +121806,7 @@ var pxt;
|
|
|
120724
121806
|
return undefined;
|
|
120725
121807
|
if (scriptid[0] == "_" && scriptid.length == 13)
|
|
120726
121808
|
return scriptid;
|
|
120727
|
-
if (scriptid.length == 23 && /^[0-9\-]+$/.test(scriptid))
|
|
121809
|
+
if (scriptid.length == 23 && /^[0-9\-]+$/.test(scriptid) || scriptid.length == 24 && /^S[0-9\-]+$/.test(scriptid))
|
|
120728
121810
|
return scriptid;
|
|
120729
121811
|
return undefined;
|
|
120730
121812
|
}
|
|
@@ -154609,7 +155691,7 @@ var pxsim;
|
|
|
154609
155691
|
channel.gain.gain.value = 0;
|
|
154610
155692
|
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
154611
155693
|
channel.gain.connect(destination);
|
|
154612
|
-
if (channels.length >
|
|
155694
|
+
if (channels.length > 20)
|
|
154613
155695
|
channels[0].remove();
|
|
154614
155696
|
channels.push(channel);
|
|
154615
155697
|
const checkCancel = () => {
|
|
@@ -154679,7 +155761,7 @@ var pxsim;
|
|
|
154679
155761
|
let resolved = false;
|
|
154680
155762
|
let ctx = context();
|
|
154681
155763
|
let channel = new Channel();
|
|
154682
|
-
if (channels.length >
|
|
155764
|
+
if (channels.length > 20)
|
|
154683
155765
|
channels[0].remove();
|
|
154684
155766
|
channels.push(channel);
|
|
154685
155767
|
channel.gain = ctx.createGain();
|
|
@@ -154713,6 +155795,10 @@ var pxsim;
|
|
|
154713
155795
|
const endVolume = readUint16(instructions, i + 8);
|
|
154714
155796
|
const endFrequency = readUint16(instructions, i + 10);
|
|
154715
155797
|
totalDuration += duration;
|
|
155798
|
+
if (wave === 0) {
|
|
155799
|
+
currentTime += duration;
|
|
155800
|
+
continue;
|
|
155801
|
+
}
|
|
154716
155802
|
const isSquareWave = 11 <= wave && wave <= 15;
|
|
154717
155803
|
if (!oscillators[wave]) {
|
|
154718
155804
|
oscillators[wave] = getGenerator(wave, startFrequency);
|
|
@@ -154755,7 +155841,8 @@ var pxsim;
|
|
|
154755
155841
|
return;
|
|
154756
155842
|
}
|
|
154757
155843
|
const { frequency, volume } = findFrequencyAndVolumeAtTime((time - startTime) * 1000, instructions);
|
|
154758
|
-
onPull
|
|
155844
|
+
if (onPull)
|
|
155845
|
+
onPull(frequency, volume / 1024);
|
|
154759
155846
|
requestAnimationFrame(handleAnimationFrame);
|
|
154760
155847
|
};
|
|
154761
155848
|
requestAnimationFrame(handleAnimationFrame);
|
|
@@ -158167,7 +159254,8 @@ function pxtFileList(pref) {
|
|
|
158167
159254
|
.concat(nodeutil.allFiles(pref + "built/web/fonts", { maxDepth: 1 }))
|
|
158168
159255
|
.concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
|
|
158169
159256
|
.concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
|
|
158170
|
-
.concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }))
|
|
159257
|
+
.concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }))
|
|
159258
|
+
.concat(nodeutil.allFiles(pref + "built/web/multiplayer", { maxDepth: 4 }));
|
|
158171
159259
|
}
|
|
158172
159260
|
function semverCmp(a, b) {
|
|
158173
159261
|
let parse = (s) => {
|
|
@@ -158248,7 +159336,8 @@ function ciAsync() {
|
|
|
158248
159336
|
.then(() => buildWebStringsAsync())
|
|
158249
159337
|
.then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
|
|
158250
159338
|
.then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
|
|
158251
|
-
.then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"))
|
|
159339
|
+
.then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"))
|
|
159340
|
+
.then(() => crowdin.execCrowdinAsync("upload", "built/multiplayer-strings.json"));
|
|
158252
159341
|
if (uploadApiStrings)
|
|
158253
159342
|
p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
|
|
158254
159343
|
if (uploadDocs || uploadApiStrings)
|
|
@@ -158767,6 +159856,7 @@ function uploadCoreAsync(opts) {
|
|
|
158767
159856
|
"asseteditorUrl": opts.localDir + "asseteditor.html",
|
|
158768
159857
|
"skillmapUrl": opts.localDir + "skillmap.html",
|
|
158769
159858
|
"authcodeUrl": opts.localDir + "authcode.html",
|
|
159859
|
+
"multiplayerUrl": opts.localDir + "multiplayer.html",
|
|
158770
159860
|
"isStatic": true,
|
|
158771
159861
|
};
|
|
158772
159862
|
const targetImagePaths = targetImages.map(k => `${opts.localDir}${path.join('./docs', logos[k])}`);
|
|
@@ -158813,14 +159903,16 @@ function uploadCoreAsync(opts) {
|
|
|
158813
159903
|
"multi.html",
|
|
158814
159904
|
"asseteditor.html",
|
|
158815
159905
|
"skillmap.html",
|
|
158816
|
-
"authcode.html"
|
|
159906
|
+
"authcode.html",
|
|
159907
|
+
"multiplayer.html",
|
|
158817
159908
|
];
|
|
158818
159909
|
// expandHtml is manually called on these files before upload
|
|
158819
159910
|
// runs <!-- @include --> substitutions, fills in locale, etc
|
|
158820
159911
|
let expandFiles = [
|
|
158821
159912
|
"index.html",
|
|
158822
159913
|
"skillmap.html",
|
|
158823
|
-
"authcode.html"
|
|
159914
|
+
"authcode.html",
|
|
159915
|
+
"multiplayer.html",
|
|
158824
159916
|
];
|
|
158825
159917
|
nodeutil.mkdirP("built/uploadrepl");
|
|
158826
159918
|
function encodeURLs(urls) {
|
|
@@ -159614,33 +160706,29 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159614
160706
|
]
|
|
159615
160707
|
});
|
|
159616
160708
|
}
|
|
159617
|
-
|
|
159618
|
-
|
|
159619
|
-
|
|
159620
|
-
|
|
159621
|
-
|
|
159622
|
-
|
|
159623
|
-
|
|
159624
|
-
|
|
159625
|
-
|
|
159626
|
-
|
|
159627
|
-
|
|
159628
|
-
|
|
159629
|
-
|
|
159630
|
-
"
|
|
159631
|
-
|
|
159632
|
-
|
|
159633
|
-
|
|
159634
|
-
|
|
159635
|
-
|
|
159636
|
-
|
|
159637
|
-
|
|
159638
|
-
|
|
159639
|
-
|
|
159640
|
-
let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
|
|
159641
|
-
skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
159642
|
-
skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
159643
|
-
await writeFileAsync(`built/web/react-common-skillmap.css`, skillmapCss, "utf8");
|
|
160709
|
+
async function generateReactCommonCss(app) {
|
|
160710
|
+
const appFile = isPxtCore ? `react-common/styles/react-common-${app}-core.less` :
|
|
160711
|
+
`node_modules/pxt-core/react-common/styles/react-common-${app}.less`;
|
|
160712
|
+
await nodeutil.spawnAsync({
|
|
160713
|
+
cmd: "node",
|
|
160714
|
+
args: [
|
|
160715
|
+
lessCPath,
|
|
160716
|
+
appFile,
|
|
160717
|
+
`built/web/react-common-${app}.css`,
|
|
160718
|
+
"--include-path=" + lessIncludePaths
|
|
160719
|
+
]
|
|
160720
|
+
});
|
|
160721
|
+
let appCss = await readFileAsync(`built/web/react-common-${app}.css`, "utf8");
|
|
160722
|
+
appCss = await linkFontAsync("fa-solid-900", appCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
160723
|
+
appCss = await linkFontAsync("fa-regular-400", appCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
160724
|
+
await writeFileAsync(`built/web/react-common-${app}.css`, appCss, "utf8");
|
|
160725
|
+
}
|
|
160726
|
+
// Generate react-common css for skillmap, authcode, and multiplayer
|
|
160727
|
+
await Promise.all([
|
|
160728
|
+
generateReactCommonCss("skillmap"),
|
|
160729
|
+
generateReactCommonCss("authcode"),
|
|
160730
|
+
generateReactCommonCss("multiplayer")
|
|
160731
|
+
]);
|
|
159644
160732
|
// Run postcss with autoprefixer and rtlcss
|
|
159645
160733
|
pxt.debug("running postcss");
|
|
159646
160734
|
const postcss = require('postcss');
|
|
@@ -159660,7 +160748,7 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159660
160748
|
autoprefixer: { browsers: browserList, add: true }
|
|
159661
160749
|
});
|
|
159662
160750
|
const rtlcss = require("rtlcss");
|
|
159663
|
-
const files = ["semantic.css", "blockly.css", "react-common-skillmap.css"];
|
|
160751
|
+
const files = ["semantic.css", "blockly.css", "react-common-skillmap.css", "react-common-authcode.css", "react-common-multiplayer.css"];
|
|
159664
160752
|
for (const cssFile of files) {
|
|
159665
160753
|
const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
|
|
159666
160754
|
const processed = await postcss([cssnano])
|
|
@@ -159671,9 +160759,13 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159671
160759
|
await writeFileAsync(`built/web/rtl${cssFile}`, processedRtl.css, "utf8");
|
|
159672
160760
|
}
|
|
159673
160761
|
if (!isPxtCore) {
|
|
159674
|
-
// This is just to support the local skillmap serve for development
|
|
160762
|
+
// This is just to support the local skillmap/cra-app serve for development
|
|
159675
160763
|
nodeutil.cp("built/web/react-common-skillmap.css", "node_modules/pxt-core/skillmap/public/blb");
|
|
160764
|
+
nodeutil.cp("built/web/react-common-authcode.css", "node_modules/pxt-core/authcode/public/blb");
|
|
160765
|
+
nodeutil.cp("built/web/react-common-multiplayer.css", "node_modules/pxt-core/multiplayer/public/blb");
|
|
159676
160766
|
nodeutil.cp("built/web/semantic.css", "node_modules/pxt-core/skillmap/public/blb");
|
|
160767
|
+
nodeutil.cp("built/web/semantic.css", "node_modules/pxt-core/authcode/public/blb");
|
|
160768
|
+
nodeutil.cp("built/web/semantic.css", "node_modules/pxt-core/multiplayer/public/blb");
|
|
159677
160769
|
}
|
|
159678
160770
|
}
|
|
159679
160771
|
async function linkFontAsync(font, semCss, sourceDir = "node_modules/semantic-ui-less/themes/default/assets/fonts/", refDir = "fonts\\/") {
|
|
@@ -159692,47 +160784,13 @@ function buildWebStringsAsync() {
|
|
|
159692
160784
|
nodeutil.writeFileSync("built/webstrings.json", nodeutil.stringify(webstringsJson()));
|
|
159693
160785
|
return Promise.resolve();
|
|
159694
160786
|
}
|
|
159695
|
-
function
|
|
160787
|
+
function buildReactAppAsync(app, parsed, opts) {
|
|
160788
|
+
opts = opts || {
|
|
160789
|
+
copyAssets: true
|
|
160790
|
+
};
|
|
159696
160791
|
// local serve
|
|
159697
|
-
const
|
|
159698
|
-
const reactScriptsConfigRoot = `${skillmapRoot}/node_modules/react-scripts/config`;
|
|
160792
|
+
const appRoot = `node_modules/pxt-core/${app}`;
|
|
159699
160793
|
const docsPath = parsed.flags["docs"];
|
|
159700
|
-
return rimrafAsync(`${skillmapRoot}/public/blb`, {})
|
|
159701
|
-
.then(() => rimrafAsync(`${skillmapRoot}/build/assets`, {}))
|
|
159702
|
-
.then(() => rimrafAsync(`${skillmapRoot}/public/docs`, {}))
|
|
159703
|
-
.then(() => rimrafAsync(`${skillmapRoot}/public/static`, {}))
|
|
159704
|
-
.then(() => {
|
|
159705
|
-
// read pxtarget.json, save into 'pxtTargetBundle' global variable
|
|
159706
|
-
let cfg = readLocalPxTarget();
|
|
159707
|
-
nodeutil.writeFileSync(`${skillmapRoot}/public/blb/target.js`, "// eslint-disable-next-line \n" + targetJsPrefix + JSON.stringify(cfg));
|
|
159708
|
-
nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
|
|
159709
|
-
nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
|
|
159710
|
-
nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
|
|
159711
|
-
nodeutil.cp("node_modules/pxt-core/built/web/react-common-skillmap.css", `${skillmapRoot}/public/blb`);
|
|
159712
|
-
// copy 'assets' over from docs/static
|
|
159713
|
-
nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
|
|
159714
|
-
// copy default react-scripts webpack config into a webpack.config.base file if necessary
|
|
159715
|
-
if (!fs.existsSync(`${reactScriptsConfigRoot}/webpack.config.base.js`)) {
|
|
159716
|
-
nodeutil.cp(`${reactScriptsConfigRoot}/webpack.config.js`, reactScriptsConfigRoot, "webpack.config.base.js");
|
|
159717
|
-
}
|
|
159718
|
-
// wrap the config in our webpack.config.override for build customization
|
|
159719
|
-
nodeutil.cp(`${skillmapRoot}/webpack.config.override.js`, reactScriptsConfigRoot, "webpack.config.js");
|
|
159720
|
-
if (docsPath) {
|
|
159721
|
-
// copy docs over from specified path
|
|
159722
|
-
nodeutil.cpR(`docs/${docsPath}`, `${skillmapRoot}/public/docs/${docsPath}`);
|
|
159723
|
-
nodeutil.cpR(`docs/static/${docsPath}`, `${skillmapRoot}/public/static/${docsPath}`);
|
|
159724
|
-
}
|
|
159725
|
-
return nodeutil.spawnAsync({
|
|
159726
|
-
cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
|
|
159727
|
-
args: ["run-script", "start"],
|
|
159728
|
-
cwd: skillmapRoot,
|
|
159729
|
-
shell: true
|
|
159730
|
-
});
|
|
159731
|
-
});
|
|
159732
|
-
}
|
|
159733
|
-
function buildAuthcodeAsync(parsed) {
|
|
159734
|
-
// local serve
|
|
159735
|
-
const appRoot = "node_modules/pxt-core/authcode";
|
|
159736
160794
|
return rimrafAsync(`${appRoot}/public/blb`, {})
|
|
159737
160795
|
.then(() => rimrafAsync(`${appRoot}/build/assets`, {}))
|
|
159738
160796
|
.then(() => rimrafAsync(`${appRoot}/public/docs`, {}))
|
|
@@ -159744,9 +160802,16 @@ function buildAuthcodeAsync(parsed) {
|
|
|
159744
160802
|
nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${appRoot}/public/blb`);
|
|
159745
160803
|
nodeutil.cp("built/web/semantic.css", `${appRoot}/public/blb`);
|
|
159746
160804
|
nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${appRoot}/public/blb`);
|
|
159747
|
-
nodeutil.cp(
|
|
159748
|
-
|
|
159749
|
-
|
|
160805
|
+
nodeutil.cp(`node_modules/pxt-core/built/web/react-common-${app}.css`, `${appRoot}/public/blb`);
|
|
160806
|
+
if (opts.copyAssets) {
|
|
160807
|
+
// copy 'assets' over from docs/static
|
|
160808
|
+
nodeutil.cpR(`docs/static/${app}/assets`, `${appRoot}/public/assets`);
|
|
160809
|
+
}
|
|
160810
|
+
if (docsPath) {
|
|
160811
|
+
// copy docs over from specified path
|
|
160812
|
+
nodeutil.cpR(`docs/${docsPath}`, `${appRoot}/public/docs/${docsPath}`);
|
|
160813
|
+
nodeutil.cpR(`docs/static/${docsPath}`, `${appRoot}/public/static/${docsPath}`);
|
|
160814
|
+
}
|
|
159750
160815
|
return nodeutil.spawnAsync({
|
|
159751
160816
|
cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
|
|
159752
160817
|
args: ["run-script", "start"],
|
|
@@ -159755,6 +160820,15 @@ function buildAuthcodeAsync(parsed) {
|
|
|
159755
160820
|
});
|
|
159756
160821
|
});
|
|
159757
160822
|
}
|
|
160823
|
+
function buildSkillMapAsync(parsed) {
|
|
160824
|
+
return buildReactAppAsync("skillmap", parsed);
|
|
160825
|
+
}
|
|
160826
|
+
function buildAuthcodeAsync(parsed) {
|
|
160827
|
+
return buildReactAppAsync("authcode", parsed, { copyAssets: false });
|
|
160828
|
+
}
|
|
160829
|
+
function buildMultiplayerAsync(parsed) {
|
|
160830
|
+
return buildReactAppAsync("multiplayer", parsed, { copyAssets: false });
|
|
160831
|
+
}
|
|
159758
160832
|
function updateDefaultProjects(cfg) {
|
|
159759
160833
|
let defaultProjects = [
|
|
159760
160834
|
pxt.BLOCKS_PROJECT_NAME,
|
|
@@ -164146,9 +165220,30 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
164146
165220
|
flags: {
|
|
164147
165221
|
serve: {
|
|
164148
165222
|
description: "Serve the authcode app locally after building (npm start)"
|
|
165223
|
+
},
|
|
165224
|
+
docs: {
|
|
165225
|
+
description: "Path to local docs folder to copy into authcode",
|
|
165226
|
+
type: "string",
|
|
165227
|
+
argument: "docs"
|
|
164149
165228
|
}
|
|
164150
165229
|
}
|
|
164151
165230
|
}, buildAuthcodeAsync);
|
|
165231
|
+
p.defineCommand({
|
|
165232
|
+
name: "buildmultiplayer",
|
|
165233
|
+
aliases: ["multiplayer", "mp"],
|
|
165234
|
+
advanced: true,
|
|
165235
|
+
help: "Serves the multiplayer webapp",
|
|
165236
|
+
flags: {
|
|
165237
|
+
serve: {
|
|
165238
|
+
description: "Serve the multiplayer app locally after building (npm start)"
|
|
165239
|
+
},
|
|
165240
|
+
docs: {
|
|
165241
|
+
description: "Path to local docs folder to copy into multiplayer",
|
|
165242
|
+
type: "string",
|
|
165243
|
+
argument: "docs"
|
|
165244
|
+
}
|
|
165245
|
+
}
|
|
165246
|
+
}, buildMultiplayerAsync);
|
|
164152
165247
|
advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
|
|
164153
165248
|
advancedCommand("crowdin", "upload, download, clean, stats files to/from crowdin", pc => crowdin.execCrowdinAsync.apply(undefined, pc.args), "<cmd> <path> [output]");
|
|
164154
165249
|
advancedCommand("hidlist", "list HID devices", hid.listAsync);
|