pxt-core 8.4.2 → 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 +1264 -176
- package/built/pxtblockly.js +323 -40
- package/built/pxtblocks.d.ts +30 -7
- package/built/pxtblocks.js +324 -41
- package/built/pxtlib.d.ts +91 -5
- package/built/pxtlib.js +1173 -98
- 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/package.json +4 -2
- package/react-common/components/controls/Input.tsx +7 -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 +6 -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 +3 -0
- package/webapp/public/multiplayer.html +1 -0
- package/webapp/public/skillmap.html +1 -1
- package/built/web/skillmap/js/main.6eec9e0f.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);
|
|
@@ -106428,6 +106436,7 @@ var pxt;
|
|
|
106428
106436
|
const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
|
|
106429
106437
|
if (startTime) {
|
|
106430
106438
|
url.hash = `t=${startTime}`;
|
|
106439
|
+
url.searchParams.append("startTime", startTime);
|
|
106431
106440
|
}
|
|
106432
106441
|
if (endTime) {
|
|
106433
106442
|
url.searchParams.append("endTime", endTime);
|
|
@@ -110319,6 +110328,8 @@ var pxt;
|
|
|
110319
110328
|
sprite_1.IMAGE_PREFIX = "image";
|
|
110320
110329
|
sprite_1.ANIMATION_NAMESPACE = "myAnimations";
|
|
110321
110330
|
sprite_1.ANIMATION_PREFIX = "anim";
|
|
110331
|
+
sprite_1.SONG_NAMESPACE = "mySongs";
|
|
110332
|
+
sprite_1.SONG_PREFIX = "song";
|
|
110322
110333
|
/**
|
|
110323
110334
|
* 16-color sprite
|
|
110324
110335
|
*/
|
|
@@ -111374,6 +111385,1044 @@ var pxt;
|
|
|
111374
111385
|
})(shared = storage.shared || (storage.shared = {}));
|
|
111375
111386
|
})(storage = pxt.storage || (pxt.storage = {}));
|
|
111376
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 = {}));
|
|
111377
112426
|
/// <reference path="../localtypings/pxtpackage.d.ts"/>
|
|
111378
112427
|
/// <reference path="../localtypings/pxtparts.d.ts"/>
|
|
111379
112428
|
/// <reference path="../localtypings/pxtarget.d.ts"/>
|
|
@@ -115438,6 +116487,7 @@ var pxt;
|
|
|
115438
116487
|
pxt.IMAGE_MIME_TYPE = "image/x-mkcd-f4";
|
|
115439
116488
|
pxt.TILEMAP_MIME_TYPE = "application/mkcd-tilemap";
|
|
115440
116489
|
pxt.ANIMATION_MIME_TYPE = "application/mkcd-animation";
|
|
116490
|
+
pxt.SONG_MIME_TYPE = "application/mkcd-song";
|
|
115441
116491
|
class AssetCollection {
|
|
115442
116492
|
constructor() {
|
|
115443
116493
|
this.assets = [];
|
|
@@ -115624,21 +116674,24 @@ var pxt;
|
|
|
115624
116674
|
tilemaps: new AssetCollection(),
|
|
115625
116675
|
tiles: new AssetCollection(),
|
|
115626
116676
|
animations: new AssetCollection(),
|
|
115627
|
-
images: new AssetCollection()
|
|
116677
|
+
images: new AssetCollection(),
|
|
116678
|
+
songs: new AssetCollection(),
|
|
115628
116679
|
};
|
|
115629
116680
|
this.state = {
|
|
115630
116681
|
revision: this.nextID++,
|
|
115631
116682
|
tilemaps: new AssetCollection(),
|
|
115632
116683
|
tiles: new AssetCollection(),
|
|
115633
116684
|
animations: new AssetCollection(),
|
|
115634
|
-
images: new AssetCollection()
|
|
116685
|
+
images: new AssetCollection(),
|
|
116686
|
+
songs: new AssetCollection(),
|
|
115635
116687
|
};
|
|
115636
116688
|
this.gallery = {
|
|
115637
116689
|
revision: 0,
|
|
115638
116690
|
tilemaps: new AssetCollection(),
|
|
115639
116691
|
tiles: new AssetCollection(),
|
|
115640
116692
|
animations: new AssetCollection(),
|
|
115641
|
-
images: new AssetCollection()
|
|
116693
|
+
images: new AssetCollection(),
|
|
116694
|
+
songs: new AssetCollection(),
|
|
115642
116695
|
};
|
|
115643
116696
|
this.undoStack = [];
|
|
115644
116697
|
this.redoStack = [];
|
|
@@ -115740,6 +116793,19 @@ var pxt;
|
|
|
115740
116793
|
};
|
|
115741
116794
|
return this.state.images.add(newImage);
|
|
115742
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
|
+
}
|
|
115743
116809
|
updateTile(tile) {
|
|
115744
116810
|
this.onChange();
|
|
115745
116811
|
const existing = this.resolveProjectTileByInternalID(tile.internalID);
|
|
@@ -115776,6 +116842,7 @@ var pxt;
|
|
|
115776
116842
|
const blob = {};
|
|
115777
116843
|
this.state.images.serializeToJRes(blob);
|
|
115778
116844
|
this.state.animations.serializeToJRes(blob);
|
|
116845
|
+
this.state.songs.serializeToJRes(blob);
|
|
115779
116846
|
blob["*"] = {
|
|
115780
116847
|
"mimeType": "image/x-mkcd-f4",
|
|
115781
116848
|
"dataEncoding": "base64",
|
|
@@ -115857,6 +116924,7 @@ var pxt;
|
|
|
115857
116924
|
tilemaps: this.state.tilemaps.clone(),
|
|
115858
116925
|
animations: this.state.animations.clone(),
|
|
115859
116926
|
tiles: this.state.tiles.clone(),
|
|
116927
|
+
songs: this.state.songs.clone(),
|
|
115860
116928
|
};
|
|
115861
116929
|
}
|
|
115862
116930
|
undo() {
|
|
@@ -115869,6 +116937,7 @@ var pxt;
|
|
|
115869
116937
|
this.state.images.applyDiff(undo.images, true);
|
|
115870
116938
|
this.state.tilemaps.applyDiff(undo.tilemaps, true);
|
|
115871
116939
|
this.state.animations.applyDiff(undo.animations, true);
|
|
116940
|
+
this.state.songs.applyDiff(undo.songs, true);
|
|
115872
116941
|
this.state.revision = undo.beforeRevision;
|
|
115873
116942
|
this.redoStack.push(undo);
|
|
115874
116943
|
this.committedState = this.cloneState();
|
|
@@ -115882,6 +116951,7 @@ var pxt;
|
|
|
115882
116951
|
this.state.images.applyDiff(redo.images);
|
|
115883
116952
|
this.state.tilemaps.applyDiff(redo.tilemaps);
|
|
115884
116953
|
this.state.animations.applyDiff(redo.animations);
|
|
116954
|
+
this.state.songs.applyDiff(redo.songs);
|
|
115885
116955
|
this.state.revision = redo.afterRevision;
|
|
115886
116956
|
this.undoStack.push(redo);
|
|
115887
116957
|
this.committedState = this.cloneState();
|
|
@@ -115898,7 +116968,8 @@ var pxt;
|
|
|
115898
116968
|
tiles: this.state.tiles.diff(this.committedState.tiles),
|
|
115899
116969
|
images: this.state.images.diff(this.committedState.images),
|
|
115900
116970
|
tilemaps: this.state.tilemaps.diff(this.committedState.tilemaps),
|
|
115901
|
-
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)
|
|
115902
116973
|
});
|
|
115903
116974
|
this.committedState = this.cloneState();
|
|
115904
116975
|
this.cleanupTemporaryAssets();
|
|
@@ -115928,16 +116999,8 @@ var pxt;
|
|
|
115928
116999
|
}
|
|
115929
117000
|
isNameTaken(assetType, name) {
|
|
115930
117001
|
const isTaken = (id) => {
|
|
115931
|
-
|
|
115932
|
-
|
|
115933
|
-
return this.state.images.isIDTaken(id) || this.gallery.images.isIDTaken(id);
|
|
115934
|
-
case "tile" /* AssetType.Tile */:
|
|
115935
|
-
return this.state.tiles.isIDTaken(id) || this.gallery.tiles.isIDTaken(id);
|
|
115936
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
115937
|
-
return this.state.tilemaps.isIDTaken(id) || this.gallery.tilemaps.isIDTaken(id);
|
|
115938
|
-
case "animation" /* AssetType.Animation */:
|
|
115939
|
-
return this.state.animations.isIDTaken(id) || this.gallery.animations.isIDTaken(id);
|
|
115940
|
-
}
|
|
117002
|
+
return getAssetCollection(this.state, assetType).isIDTaken(id) ||
|
|
117003
|
+
getAssetCollection(this.gallery, assetType).isIDTaken(id);
|
|
115941
117004
|
};
|
|
115942
117005
|
const shortId = getShortIDCore(assetType, name);
|
|
115943
117006
|
const checkShortId = shortId && shortId !== name;
|
|
@@ -115963,6 +117026,10 @@ var pxt;
|
|
|
115963
117026
|
* assets.animation`shortId`
|
|
115964
117027
|
* assets.animation`displayName`
|
|
115965
117028
|
*
|
|
117029
|
+
* SONGS:
|
|
117030
|
+
* assets.song`shortId`
|
|
117031
|
+
* assets.song`displayName`
|
|
117032
|
+
*
|
|
115966
117033
|
* TILEMAPS:
|
|
115967
117034
|
* tilemap`shortId`
|
|
115968
117035
|
*
|
|
@@ -116001,6 +117068,11 @@ var pxt;
|
|
|
116001
117068
|
if (displayName)
|
|
116002
117069
|
assetTsRefs += `|assets.animation\`${displayName}\``;
|
|
116003
117070
|
break;
|
|
117071
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117072
|
+
assetTsRefs = `assets.song\`${shortId}\``;
|
|
117073
|
+
if (displayName)
|
|
117074
|
+
assetTsRefs += `|assets.song\`${displayName}\``;
|
|
117075
|
+
break;
|
|
116004
117076
|
default:
|
|
116005
117077
|
assetTsRefs = `assets.image\`${shortId}\``;
|
|
116006
117078
|
if (displayName)
|
|
@@ -116023,6 +117095,11 @@ var pxt;
|
|
|
116023
117095
|
if (displayName)
|
|
116024
117096
|
assetPyRefs += `|assets.animation\("""${displayName}"""\)`;
|
|
116025
117097
|
break;
|
|
117098
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117099
|
+
assetPyRefs = `assets.song\("""${shortId}"""\)`;
|
|
117100
|
+
if (displayName)
|
|
117101
|
+
assetPyRefs += `|assets.song\("""${displayName}"""\)`;
|
|
117102
|
+
break;
|
|
116026
117103
|
default:
|
|
116027
117104
|
assetPyRefs = `assets.image\("""${shortId}"""\)`;
|
|
116028
117105
|
if (displayName)
|
|
@@ -116048,65 +117125,29 @@ var pxt;
|
|
|
116048
117125
|
return false;
|
|
116049
117126
|
}
|
|
116050
117127
|
lookupAsset(assetType, name) {
|
|
116051
|
-
|
|
116052
|
-
|
|
116053
|
-
return this.state.images.getByID(name) || this.gallery.images.getByID(name);
|
|
116054
|
-
case "tile" /* AssetType.Tile */:
|
|
116055
|
-
return this.state.tiles.getByID(name) || this.gallery.tiles.getByID(name);
|
|
116056
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116057
|
-
return this.state.tilemaps.getByID(name) || this.gallery.tilemaps.getByID(name);
|
|
116058
|
-
case "animation" /* AssetType.Animation */:
|
|
116059
|
-
return this.state.animations.getByID(name) || this.gallery.animations.getByID(name);
|
|
116060
|
-
}
|
|
117128
|
+
return getAssetCollection(this.state, assetType).getByID(name) ||
|
|
117129
|
+
getAssetCollection(this.gallery, assetType).getByID(name);
|
|
116061
117130
|
}
|
|
116062
117131
|
lookupAssetByName(assetType, name) {
|
|
116063
|
-
|
|
116064
|
-
case "image" /* AssetType.Image */:
|
|
116065
|
-
return this.state.images.getByDisplayName(name);
|
|
116066
|
-
case "tile" /* AssetType.Tile */:
|
|
116067
|
-
return this.state.tiles.getByDisplayName(name);
|
|
116068
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116069
|
-
return this.state.tilemaps.getByDisplayName(name);
|
|
116070
|
-
case "animation" /* AssetType.Animation */:
|
|
116071
|
-
return this.state.animations.getByDisplayName(name);
|
|
116072
|
-
}
|
|
117132
|
+
return getAssetCollection(this.state, assetType).getByDisplayName(name);
|
|
116073
117133
|
}
|
|
116074
117134
|
getAssets(type) {
|
|
116075
|
-
|
|
116076
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot();
|
|
116077
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot();
|
|
116078
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot();
|
|
116079
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot();
|
|
116080
|
-
}
|
|
117135
|
+
return getAssetCollection(this.state, type).getSnapshot();
|
|
116081
117136
|
}
|
|
116082
117137
|
getGalleryAssets(type) {
|
|
116083
|
-
|
|
116084
|
-
case "image" /* AssetType.Image */: return this.gallery.images.getSnapshot();
|
|
116085
|
-
case "tile" /* AssetType.Tile */: return this.gallery.tiles.getSnapshot();
|
|
116086
|
-
case "tilemap" /* AssetType.Tilemap */: return this.gallery.tilemaps.getSnapshot();
|
|
116087
|
-
case "animation" /* AssetType.Animation */: return this.gallery.animations.getSnapshot();
|
|
116088
|
-
}
|
|
117138
|
+
return getAssetCollection(this.gallery, type).getSnapshot();
|
|
116089
117139
|
}
|
|
116090
117140
|
lookupBlockAsset(type, blockID) {
|
|
116091
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; };
|
|
116092
|
-
|
|
116093
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot(filter)[0];
|
|
116094
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot(filter)[0];
|
|
116095
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot(filter)[0];
|
|
116096
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot(filter)[0];
|
|
116097
|
-
}
|
|
117142
|
+
return getAssetCollection(this.state, type).getSnapshot(filter)[0];
|
|
116098
117143
|
}
|
|
116099
117144
|
updateAsset(asset) {
|
|
116100
117145
|
this.onChange();
|
|
116101
117146
|
switch (asset.type) {
|
|
116102
|
-
case "image" /* AssetType.Image */:
|
|
116103
|
-
return this.state.images.update(asset.id, asset);
|
|
116104
117147
|
case "tile" /* AssetType.Tile */:
|
|
116105
117148
|
return this.updateTile(asset);
|
|
116106
|
-
|
|
116107
|
-
return this.state.
|
|
116108
|
-
case "animation" /* AssetType.Animation */:
|
|
116109
|
-
return this.state.animations.update(asset.id, asset);
|
|
117149
|
+
default:
|
|
117150
|
+
return getAssetCollection(this.state, asset.type).update(asset.id, asset);
|
|
116110
117151
|
}
|
|
116111
117152
|
}
|
|
116112
117153
|
duplicateAsset(asset, displayName) {
|
|
@@ -116128,53 +117169,22 @@ var pxt;
|
|
|
116128
117169
|
break;
|
|
116129
117170
|
case "animation" /* AssetType.Animation */:
|
|
116130
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;
|
|
116131
117176
|
}
|
|
116132
117177
|
return newAsset;
|
|
116133
117178
|
}
|
|
116134
117179
|
removeAsset(asset) {
|
|
116135
117180
|
this.onChange();
|
|
116136
|
-
|
|
116137
|
-
case "image" /* AssetType.Image */:
|
|
116138
|
-
return this.state.images.removeByID(asset.id);
|
|
116139
|
-
case "tile" /* AssetType.Tile */:
|
|
116140
|
-
return this.state.tiles.removeByID(asset.id);
|
|
116141
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116142
|
-
return this.state.tilemaps.removeByID(asset.id);
|
|
116143
|
-
case "animation" /* AssetType.Animation */:
|
|
116144
|
-
return this.state.animations.removeByID(asset.id);
|
|
116145
|
-
}
|
|
117181
|
+
getAssetCollection(this.state, asset.type).removeByID(asset.id);
|
|
116146
117182
|
}
|
|
116147
117183
|
addChangeListener(asset, listener) {
|
|
116148
|
-
|
|
116149
|
-
case "image" /* AssetType.Image */:
|
|
116150
|
-
this.state.images.addListener(asset.internalID, listener);
|
|
116151
|
-
break;
|
|
116152
|
-
case "tile" /* AssetType.Tile */:
|
|
116153
|
-
this.state.tiles.addListener(asset.internalID, listener);
|
|
116154
|
-
break;
|
|
116155
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116156
|
-
this.state.tilemaps.addListener(asset.internalID, listener);
|
|
116157
|
-
break;
|
|
116158
|
-
case "animation" /* AssetType.Animation */:
|
|
116159
|
-
this.state.animations.addListener(asset.internalID, listener);
|
|
116160
|
-
break;
|
|
116161
|
-
}
|
|
117184
|
+
getAssetCollection(this.state, asset.type).addListener(asset.internalID, listener);
|
|
116162
117185
|
}
|
|
116163
117186
|
removeChangeListener(type, listener) {
|
|
116164
|
-
|
|
116165
|
-
case "image" /* AssetType.Image */:
|
|
116166
|
-
this.state.images.removeListener(listener);
|
|
116167
|
-
break;
|
|
116168
|
-
case "tile" /* AssetType.Tile */:
|
|
116169
|
-
this.state.tiles.removeListener(listener);
|
|
116170
|
-
break;
|
|
116171
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
116172
|
-
this.state.tilemaps.removeListener(listener);
|
|
116173
|
-
break;
|
|
116174
|
-
case "animation" /* AssetType.Animation */:
|
|
116175
|
-
this.state.animations.removeListener(listener);
|
|
116176
|
-
break;
|
|
116177
|
-
}
|
|
117187
|
+
getAssetCollection(this.state, type).removeListener(listener);
|
|
116178
117188
|
}
|
|
116179
117189
|
loadPackage(pack) {
|
|
116180
117190
|
const allPackages = pack.sortedDeps();
|
|
@@ -116199,7 +117209,7 @@ var pxt;
|
|
|
116199
117209
|
this.gallery.images.add(image);
|
|
116200
117210
|
}
|
|
116201
117211
|
}
|
|
116202
|
-
else {
|
|
117212
|
+
else if (image.type === "animation" /* AssetType.Animation */) {
|
|
116203
117213
|
if (isProject) {
|
|
116204
117214
|
this.state.animations.add(image);
|
|
116205
117215
|
}
|
|
@@ -116207,6 +117217,14 @@ var pxt;
|
|
|
116207
117217
|
this.gallery.animations.add(image);
|
|
116208
117218
|
}
|
|
116209
117219
|
}
|
|
117220
|
+
else {
|
|
117221
|
+
if (isProject) {
|
|
117222
|
+
this.state.songs.add(image);
|
|
117223
|
+
}
|
|
117224
|
+
else {
|
|
117225
|
+
this.gallery.songs.add(image);
|
|
117226
|
+
}
|
|
117227
|
+
}
|
|
116210
117228
|
}
|
|
116211
117229
|
}
|
|
116212
117230
|
for (const tm of getTilemaps(pack.parseJRes())) {
|
|
@@ -116283,6 +117301,9 @@ var pxt;
|
|
|
116283
117301
|
this.state.animations.add(animation);
|
|
116284
117302
|
}
|
|
116285
117303
|
}
|
|
117304
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
117305
|
+
this.state.songs.add(this.generateSong(entry));
|
|
117306
|
+
}
|
|
116286
117307
|
}
|
|
116287
117308
|
for (const animation of toInflate) {
|
|
116288
117309
|
this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
|
|
@@ -116293,6 +117314,7 @@ var pxt;
|
|
|
116293
117314
|
cleanupCollection(this.state.tiles);
|
|
116294
117315
|
cleanupCollection(this.state.tilemaps);
|
|
116295
117316
|
cleanupCollection(this.state.animations);
|
|
117317
|
+
cleanupCollection(this.state.songs);
|
|
116296
117318
|
function cleanupCollection(collection) {
|
|
116297
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)); });
|
|
116298
117320
|
const toRemove = [];
|
|
@@ -116322,6 +117344,17 @@ var pxt;
|
|
|
116322
117344
|
bitmap: pxt.sprite.getBitmapFromJResURL(`data:${pxt.IMAGE_MIME_TYPE};base64,${entry.data}`).data()
|
|
116323
117345
|
};
|
|
116324
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
|
+
}
|
|
116325
117358
|
generateAnimation(entry) {
|
|
116326
117359
|
if (entry.dataEncoding === "json") {
|
|
116327
117360
|
let data;
|
|
@@ -116375,6 +117408,8 @@ var pxt;
|
|
|
116375
117408
|
return this.generateNewIDInternal("tile" /* AssetType.Tile */, pxt.sprite.TILE_PREFIX, pxt.sprite.TILE_NAMESPACE);
|
|
116376
117409
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116377
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);
|
|
116378
117413
|
}
|
|
116379
117414
|
}
|
|
116380
117415
|
generateNewIDInternal(type, varPrefix, namespaceString) {
|
|
@@ -116412,6 +117447,9 @@ var pxt;
|
|
|
116412
117447
|
assets.push(animation);
|
|
116413
117448
|
}
|
|
116414
117449
|
}
|
|
117450
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
117451
|
+
assets.push(this.generateSong(entry));
|
|
117452
|
+
}
|
|
116415
117453
|
}
|
|
116416
117454
|
for (const animation of toInflate) {
|
|
116417
117455
|
assets.push(this.inflateAnimation(animation, assets));
|
|
@@ -116472,6 +117510,7 @@ var pxt;
|
|
|
116472
117510
|
let out = "";
|
|
116473
117511
|
const imageEntries = [];
|
|
116474
117512
|
const animationEntries = [];
|
|
117513
|
+
const songEntries = [];
|
|
116475
117514
|
for (const key of entries) {
|
|
116476
117515
|
if (key === "*")
|
|
116477
117516
|
continue;
|
|
@@ -116498,10 +117537,17 @@ var pxt;
|
|
|
116498
117537
|
expression: `[${animation.frames.map(f => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(f), "typescript")).join(", ")}]`
|
|
116499
117538
|
});
|
|
116500
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
|
+
}
|
|
116501
117546
|
}
|
|
116502
117547
|
const warning = lf("Auto-generated code. Do not edit.");
|
|
116503
117548
|
out += emitFactoryHelper("image", imageEntries);
|
|
116504
117549
|
out += emitFactoryHelper("animation", animationEntries);
|
|
117550
|
+
out += emitFactoryHelper("song", songEntries);
|
|
116505
117551
|
return `// ${warning}\nnamespace ${pxt.sprite.IMAGES_NAMESPACE} {\n${out}\n}\n// ${warning}\n`;
|
|
116506
117552
|
}
|
|
116507
117553
|
pxt.emitProjectImages = emitProjectImages;
|
|
@@ -116545,6 +117591,8 @@ var pxt;
|
|
|
116545
117591
|
return Object.assign(Object.assign({}, asset), { frames: asset.frames.map(frame => cloneBitmap(frame)) });
|
|
116546
117592
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116547
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) });
|
|
116548
117596
|
}
|
|
116549
117597
|
}
|
|
116550
117598
|
pxt.cloneAsset = cloneAsset;
|
|
@@ -116578,6 +117626,13 @@ var pxt;
|
|
|
116578
117626
|
case "animation" /* AssetType.Animation */:
|
|
116579
117627
|
allJRes[id] = serializeAnimation(asset);
|
|
116580
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;
|
|
116581
117636
|
}
|
|
116582
117637
|
}
|
|
116583
117638
|
function assetEquals(a, b) {
|
|
@@ -116597,6 +117652,8 @@ var pxt;
|
|
|
116597
117652
|
return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
|
|
116598
117653
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116599
117654
|
return a.data.equals(b.data);
|
|
117655
|
+
case "song" /* AssetType.Song */:
|
|
117656
|
+
return pxt.assets.music.songEquals(a.song, b.song);
|
|
116600
117657
|
}
|
|
116601
117658
|
}
|
|
116602
117659
|
pxt.assetEquals = assetEquals;
|
|
@@ -116636,11 +117693,13 @@ var pxt;
|
|
|
116636
117693
|
return `assets.animation${leftTick}${shortId}${rightTick}`;
|
|
116637
117694
|
case "tilemap" /* AssetType.Tilemap */:
|
|
116638
117695
|
return `tilemap${leftTick}${shortId}${rightTick}`;
|
|
117696
|
+
case "song" /* AssetType.Song */:
|
|
117697
|
+
return `assets.song${leftTick}${shortId}${rightTick}`;
|
|
116639
117698
|
}
|
|
116640
117699
|
}
|
|
116641
117700
|
pxt.getTSReferenceForAsset = getTSReferenceForAsset;
|
|
116642
117701
|
function parseAssetTSReference(ts) {
|
|
116643
|
-
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);
|
|
116644
117703
|
if (match) {
|
|
116645
117704
|
const type = match[1] || match[2];
|
|
116646
117705
|
const name = match[3].trim();
|
|
@@ -116664,6 +117723,8 @@ var pxt;
|
|
|
116664
117723
|
return project.lookupAssetByName("tilemap" /* AssetType.Tilemap */, name) || project.lookupAsset("tilemap" /* AssetType.Tilemap */, name);
|
|
116665
117724
|
case "animation":
|
|
116666
117725
|
return project.lookupAssetByName("animation" /* AssetType.Animation */, name);
|
|
117726
|
+
case "song":
|
|
117727
|
+
return project.lookupAssetByName("song" /* AssetType.Song */, name);
|
|
116667
117728
|
}
|
|
116668
117729
|
}
|
|
116669
117730
|
return undefined;
|
|
@@ -116679,6 +117740,8 @@ var pxt;
|
|
|
116679
117740
|
return lf("level");
|
|
116680
117741
|
case "animation" /* pxt.AssetType.Animation */:
|
|
116681
117742
|
return lf("myAnim");
|
|
117743
|
+
case "song" /* pxt.AssetType.Song */:
|
|
117744
|
+
return lf("mySong");
|
|
116682
117745
|
default:
|
|
116683
117746
|
return lf("asset");
|
|
116684
117747
|
}
|
|
@@ -116703,6 +117766,9 @@ var pxt;
|
|
|
116703
117766
|
case "animation" /* AssetType.Animation */:
|
|
116704
117767
|
prefix = pxt.sprite.ANIMATION_NAMESPACE + ".";
|
|
116705
117768
|
break;
|
|
117769
|
+
case "song" /* AssetType.Song */:
|
|
117770
|
+
prefix = pxt.sprite.SONG_NAMESPACE + ".";
|
|
117771
|
+
break;
|
|
116706
117772
|
}
|
|
116707
117773
|
if (prefix) {
|
|
116708
117774
|
if (id.startsWith(prefix)) {
|
|
@@ -116787,6 +117853,15 @@ var pxt;
|
|
|
116787
117853
|
function read16Bit(buf, offset) {
|
|
116788
117854
|
return buf[offset] | (buf[offset + 1] << 8);
|
|
116789
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
|
+
}
|
|
116790
117865
|
})(pxt || (pxt = {}));
|
|
116791
117866
|
var pxt;
|
|
116792
117867
|
(function (pxt) {
|
|
@@ -154616,7 +155691,7 @@ var pxsim;
|
|
|
154616
155691
|
channel.gain.gain.value = 0;
|
|
154617
155692
|
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
154618
155693
|
channel.gain.connect(destination);
|
|
154619
|
-
if (channels.length >
|
|
155694
|
+
if (channels.length > 20)
|
|
154620
155695
|
channels[0].remove();
|
|
154621
155696
|
channels.push(channel);
|
|
154622
155697
|
const checkCancel = () => {
|
|
@@ -154686,7 +155761,7 @@ var pxsim;
|
|
|
154686
155761
|
let resolved = false;
|
|
154687
155762
|
let ctx = context();
|
|
154688
155763
|
let channel = new Channel();
|
|
154689
|
-
if (channels.length >
|
|
155764
|
+
if (channels.length > 20)
|
|
154690
155765
|
channels[0].remove();
|
|
154691
155766
|
channels.push(channel);
|
|
154692
155767
|
channel.gain = ctx.createGain();
|
|
@@ -154720,6 +155795,10 @@ var pxsim;
|
|
|
154720
155795
|
const endVolume = readUint16(instructions, i + 8);
|
|
154721
155796
|
const endFrequency = readUint16(instructions, i + 10);
|
|
154722
155797
|
totalDuration += duration;
|
|
155798
|
+
if (wave === 0) {
|
|
155799
|
+
currentTime += duration;
|
|
155800
|
+
continue;
|
|
155801
|
+
}
|
|
154723
155802
|
const isSquareWave = 11 <= wave && wave <= 15;
|
|
154724
155803
|
if (!oscillators[wave]) {
|
|
154725
155804
|
oscillators[wave] = getGenerator(wave, startFrequency);
|
|
@@ -154762,7 +155841,8 @@ var pxsim;
|
|
|
154762
155841
|
return;
|
|
154763
155842
|
}
|
|
154764
155843
|
const { frequency, volume } = findFrequencyAndVolumeAtTime((time - startTime) * 1000, instructions);
|
|
154765
|
-
onPull
|
|
155844
|
+
if (onPull)
|
|
155845
|
+
onPull(frequency, volume / 1024);
|
|
154766
155846
|
requestAnimationFrame(handleAnimationFrame);
|
|
154767
155847
|
};
|
|
154768
155848
|
requestAnimationFrame(handleAnimationFrame);
|
|
@@ -158174,7 +159254,8 @@ function pxtFileList(pref) {
|
|
|
158174
159254
|
.concat(nodeutil.allFiles(pref + "built/web/fonts", { maxDepth: 1 }))
|
|
158175
159255
|
.concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
|
|
158176
159256
|
.concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
|
|
158177
|
-
.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 }));
|
|
158178
159259
|
}
|
|
158179
159260
|
function semverCmp(a, b) {
|
|
158180
159261
|
let parse = (s) => {
|
|
@@ -158255,7 +159336,8 @@ function ciAsync() {
|
|
|
158255
159336
|
.then(() => buildWebStringsAsync())
|
|
158256
159337
|
.then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
|
|
158257
159338
|
.then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
|
|
158258
|
-
.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"));
|
|
158259
159341
|
if (uploadApiStrings)
|
|
158260
159342
|
p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
|
|
158261
159343
|
if (uploadDocs || uploadApiStrings)
|
|
@@ -158774,6 +159856,7 @@ function uploadCoreAsync(opts) {
|
|
|
158774
159856
|
"asseteditorUrl": opts.localDir + "asseteditor.html",
|
|
158775
159857
|
"skillmapUrl": opts.localDir + "skillmap.html",
|
|
158776
159858
|
"authcodeUrl": opts.localDir + "authcode.html",
|
|
159859
|
+
"multiplayerUrl": opts.localDir + "multiplayer.html",
|
|
158777
159860
|
"isStatic": true,
|
|
158778
159861
|
};
|
|
158779
159862
|
const targetImagePaths = targetImages.map(k => `${opts.localDir}${path.join('./docs', logos[k])}`);
|
|
@@ -158820,14 +159903,16 @@ function uploadCoreAsync(opts) {
|
|
|
158820
159903
|
"multi.html",
|
|
158821
159904
|
"asseteditor.html",
|
|
158822
159905
|
"skillmap.html",
|
|
158823
|
-
"authcode.html"
|
|
159906
|
+
"authcode.html",
|
|
159907
|
+
"multiplayer.html",
|
|
158824
159908
|
];
|
|
158825
159909
|
// expandHtml is manually called on these files before upload
|
|
158826
159910
|
// runs <!-- @include --> substitutions, fills in locale, etc
|
|
158827
159911
|
let expandFiles = [
|
|
158828
159912
|
"index.html",
|
|
158829
159913
|
"skillmap.html",
|
|
158830
|
-
"authcode.html"
|
|
159914
|
+
"authcode.html",
|
|
159915
|
+
"multiplayer.html",
|
|
158831
159916
|
];
|
|
158832
159917
|
nodeutil.mkdirP("built/uploadrepl");
|
|
158833
159918
|
function encodeURLs(urls) {
|
|
@@ -159621,33 +160706,29 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159621
160706
|
]
|
|
159622
160707
|
});
|
|
159623
160708
|
}
|
|
159624
|
-
|
|
159625
|
-
|
|
159626
|
-
|
|
159627
|
-
|
|
159628
|
-
|
|
159629
|
-
|
|
159630
|
-
|
|
159631
|
-
|
|
159632
|
-
|
|
159633
|
-
|
|
159634
|
-
|
|
159635
|
-
|
|
159636
|
-
|
|
159637
|
-
"
|
|
159638
|
-
|
|
159639
|
-
|
|
159640
|
-
|
|
159641
|
-
|
|
159642
|
-
|
|
159643
|
-
|
|
159644
|
-
|
|
159645
|
-
|
|
159646
|
-
|
|
159647
|
-
let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
|
|
159648
|
-
skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
159649
|
-
skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
|
|
159650
|
-
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
|
+
]);
|
|
159651
160732
|
// Run postcss with autoprefixer and rtlcss
|
|
159652
160733
|
pxt.debug("running postcss");
|
|
159653
160734
|
const postcss = require('postcss');
|
|
@@ -159667,7 +160748,7 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159667
160748
|
autoprefixer: { browsers: browserList, add: true }
|
|
159668
160749
|
});
|
|
159669
160750
|
const rtlcss = require("rtlcss");
|
|
159670
|
-
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"];
|
|
159671
160752
|
for (const cssFile of files) {
|
|
159672
160753
|
const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
|
|
159673
160754
|
const processed = await postcss([cssnano])
|
|
@@ -159678,9 +160759,13 @@ async function buildSemanticUIAsync(parsed) {
|
|
|
159678
160759
|
await writeFileAsync(`built/web/rtl${cssFile}`, processedRtl.css, "utf8");
|
|
159679
160760
|
}
|
|
159680
160761
|
if (!isPxtCore) {
|
|
159681
|
-
// 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
|
|
159682
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");
|
|
159683
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");
|
|
159684
160769
|
}
|
|
159685
160770
|
}
|
|
159686
160771
|
async function linkFontAsync(font, semCss, sourceDir = "node_modules/semantic-ui-less/themes/default/assets/fonts/", refDir = "fonts\\/") {
|
|
@@ -159699,47 +160784,13 @@ function buildWebStringsAsync() {
|
|
|
159699
160784
|
nodeutil.writeFileSync("built/webstrings.json", nodeutil.stringify(webstringsJson()));
|
|
159700
160785
|
return Promise.resolve();
|
|
159701
160786
|
}
|
|
159702
|
-
function
|
|
160787
|
+
function buildReactAppAsync(app, parsed, opts) {
|
|
160788
|
+
opts = opts || {
|
|
160789
|
+
copyAssets: true
|
|
160790
|
+
};
|
|
159703
160791
|
// local serve
|
|
159704
|
-
const
|
|
159705
|
-
const reactScriptsConfigRoot = `${skillmapRoot}/node_modules/react-scripts/config`;
|
|
160792
|
+
const appRoot = `node_modules/pxt-core/${app}`;
|
|
159706
160793
|
const docsPath = parsed.flags["docs"];
|
|
159707
|
-
return rimrafAsync(`${skillmapRoot}/public/blb`, {})
|
|
159708
|
-
.then(() => rimrafAsync(`${skillmapRoot}/build/assets`, {}))
|
|
159709
|
-
.then(() => rimrafAsync(`${skillmapRoot}/public/docs`, {}))
|
|
159710
|
-
.then(() => rimrafAsync(`${skillmapRoot}/public/static`, {}))
|
|
159711
|
-
.then(() => {
|
|
159712
|
-
// read pxtarget.json, save into 'pxtTargetBundle' global variable
|
|
159713
|
-
let cfg = readLocalPxTarget();
|
|
159714
|
-
nodeutil.writeFileSync(`${skillmapRoot}/public/blb/target.js`, "// eslint-disable-next-line \n" + targetJsPrefix + JSON.stringify(cfg));
|
|
159715
|
-
nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
|
|
159716
|
-
nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
|
|
159717
|
-
nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
|
|
159718
|
-
nodeutil.cp("node_modules/pxt-core/built/web/react-common-skillmap.css", `${skillmapRoot}/public/blb`);
|
|
159719
|
-
// copy 'assets' over from docs/static
|
|
159720
|
-
nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
|
|
159721
|
-
// copy default react-scripts webpack config into a webpack.config.base file if necessary
|
|
159722
|
-
if (!fs.existsSync(`${reactScriptsConfigRoot}/webpack.config.base.js`)) {
|
|
159723
|
-
nodeutil.cp(`${reactScriptsConfigRoot}/webpack.config.js`, reactScriptsConfigRoot, "webpack.config.base.js");
|
|
159724
|
-
}
|
|
159725
|
-
// wrap the config in our webpack.config.override for build customization
|
|
159726
|
-
nodeutil.cp(`${skillmapRoot}/webpack.config.override.js`, reactScriptsConfigRoot, "webpack.config.js");
|
|
159727
|
-
if (docsPath) {
|
|
159728
|
-
// copy docs over from specified path
|
|
159729
|
-
nodeutil.cpR(`docs/${docsPath}`, `${skillmapRoot}/public/docs/${docsPath}`);
|
|
159730
|
-
nodeutil.cpR(`docs/static/${docsPath}`, `${skillmapRoot}/public/static/${docsPath}`);
|
|
159731
|
-
}
|
|
159732
|
-
return nodeutil.spawnAsync({
|
|
159733
|
-
cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
|
|
159734
|
-
args: ["run-script", "start"],
|
|
159735
|
-
cwd: skillmapRoot,
|
|
159736
|
-
shell: true
|
|
159737
|
-
});
|
|
159738
|
-
});
|
|
159739
|
-
}
|
|
159740
|
-
function buildAuthcodeAsync(parsed) {
|
|
159741
|
-
// local serve
|
|
159742
|
-
const appRoot = "node_modules/pxt-core/authcode";
|
|
159743
160794
|
return rimrafAsync(`${appRoot}/public/blb`, {})
|
|
159744
160795
|
.then(() => rimrafAsync(`${appRoot}/build/assets`, {}))
|
|
159745
160796
|
.then(() => rimrafAsync(`${appRoot}/public/docs`, {}))
|
|
@@ -159751,9 +160802,16 @@ function buildAuthcodeAsync(parsed) {
|
|
|
159751
160802
|
nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${appRoot}/public/blb`);
|
|
159752
160803
|
nodeutil.cp("built/web/semantic.css", `${appRoot}/public/blb`);
|
|
159753
160804
|
nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${appRoot}/public/blb`);
|
|
159754
|
-
nodeutil.cp(
|
|
159755
|
-
|
|
159756
|
-
|
|
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
|
+
}
|
|
159757
160815
|
return nodeutil.spawnAsync({
|
|
159758
160816
|
cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
|
|
159759
160817
|
args: ["run-script", "start"],
|
|
@@ -159762,6 +160820,15 @@ function buildAuthcodeAsync(parsed) {
|
|
|
159762
160820
|
});
|
|
159763
160821
|
});
|
|
159764
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
|
+
}
|
|
159765
160832
|
function updateDefaultProjects(cfg) {
|
|
159766
160833
|
let defaultProjects = [
|
|
159767
160834
|
pxt.BLOCKS_PROJECT_NAME,
|
|
@@ -164153,9 +165220,30 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
164153
165220
|
flags: {
|
|
164154
165221
|
serve: {
|
|
164155
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"
|
|
164156
165228
|
}
|
|
164157
165229
|
}
|
|
164158
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);
|
|
164159
165247
|
advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
|
|
164160
165248
|
advancedCommand("crowdin", "upload, download, clean, stats files to/from crowdin", pc => crowdin.execCrowdinAsync.apply(undefined, pc.args), "<cmd> <path> [output]");
|
|
164161
165249
|
advancedCommand("hidlist", "list HID devices", hid.listAsync);
|