pxt-core 12.2.26 → 12.2.28

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.
Files changed (49) hide show
  1. package/built/pxt.js +323 -12
  2. package/built/pxtblocks/fields/field_animation.d.ts +4 -2
  3. package/built/pxtlib.js +21 -2
  4. package/built/pxtsim.d.ts +11 -0
  5. package/built/pxtsim.js +302 -10
  6. package/built/target.js +1 -1
  7. package/built/targetlight.js +1 -1
  8. package/built/tests/blocksrunner.js +83 -8
  9. package/built/tests/blockssetup.js +83 -8
  10. package/built/web/blockly.css +1 -1
  11. package/built/web/main.js +2 -2
  12. package/built/web/pxtapp.js +1 -1
  13. package/built/web/pxtasseteditor.js +2 -2
  14. package/built/web/pxtembed.js +1 -1
  15. package/built/web/pxtlib.js +1 -1
  16. package/built/web/pxtsim.js +1 -1
  17. package/built/web/pxtworker.js +1 -1
  18. package/built/web/rtlblockly.css +1 -1
  19. package/built/web/rtlsemantic.css +1 -1
  20. package/built/web/runnerembed.js +2 -2
  21. package/built/web/semantic.css +1 -1
  22. package/built/web/skillmap/js/{main.d1d7cd5b.js → main.5472c093.js} +2 -2
  23. package/built/web/teachertool/css/main.a4357c60.css +1 -0
  24. package/localtypings/pxteditor.d.ts +1 -0
  25. package/package.json +1 -1
  26. package/react-common/components/share/ShareInfo.tsx +1 -1
  27. package/theme/blockly-core.less +2 -2
  28. package/theme/debugger.less +8 -1
  29. package/theme/fieldeditors.less +4 -0
  30. package/webapp/public/blockly/media/1x1.gif +0 -0
  31. package/webapp/public/blockly/media/click.mp3 +0 -0
  32. package/webapp/public/blockly/media/click.ogg +0 -0
  33. package/webapp/public/blockly/media/click.wav +0 -0
  34. package/webapp/public/blockly/media/delete.mp3 +0 -0
  35. package/webapp/public/blockly/media/delete.ogg +0 -0
  36. package/webapp/public/blockly/media/delete.wav +0 -0
  37. package/webapp/public/blockly/media/disconnect.mp3 +0 -0
  38. package/webapp/public/blockly/media/disconnect.ogg +0 -0
  39. package/webapp/public/blockly/media/disconnect.wav +0 -0
  40. package/webapp/public/blockly/media/handclosed.cur +0 -0
  41. package/webapp/public/blockly/media/handdelete.cur +0 -0
  42. package/webapp/public/blockly/media/handopen.cur +0 -0
  43. package/webapp/public/blockly/media/pilcrow.png +0 -0
  44. package/webapp/public/blockly/media/quote0.png +0 -0
  45. package/webapp/public/blockly/media/quote1.png +0 -0
  46. package/webapp/public/blockly/media/sprites.png +0 -0
  47. package/webapp/public/skillmap.html +1 -1
  48. package/webapp/public/teachertool.html +1 -1
  49. package/built/web/teachertool/css/main.a240bbae.css +0 -1
package/built/pxt.js CHANGED
@@ -119272,6 +119272,25 @@ var pxt;
119272
119272
  }
119273
119273
  if (entry.tilemapTile) {
119274
119274
  tags.push("tile");
119275
+ let category = undefined;
119276
+ if (entry.displayName && entry.displayName.indexOf("--") !== -1) {
119277
+ const rawCategory = entry.displayName.split("--")[1].trim();
119278
+ const categoryParts = rawCategory.split(/[\s\-]+/g).map((part, index) => {
119279
+ if (index === 0) {
119280
+ return part;
119281
+ }
119282
+ else {
119283
+ return part.charAt(0).toUpperCase() + part.slice(1);
119284
+ }
119285
+ });
119286
+ category = categoryParts.join("");
119287
+ }
119288
+ if (!category && !/^transparency(?:4|8|16|32)$/.test(varName)) {
119289
+ category = namespaceName;
119290
+ }
119291
+ if (category) {
119292
+ tags.push("category-" + category);
119293
+ }
119275
119294
  }
119276
119295
  }
119277
119296
  if (mimeType === pxt.IMAGE_MIME_TYPE) {
@@ -119857,11 +119876,11 @@ var pxt;
119857
119876
  return snapshot.assets[type];
119858
119877
  }
119859
119878
  function patchTemporaryAsset(oldValue, newValue, project) {
119860
- if (!oldValue || assetEquals(oldValue, newValue))
119879
+ if (!oldValue || assetEquals(oldValue, newValue) || newValue.id !== oldValue.id)
119861
119880
  return newValue;
119862
119881
  newValue = cloneAsset(newValue, true);
119863
119882
  const wasTemporary = oldValue.internalID === -1;
119864
- const isTemporary = newValue.internalID === -1;
119883
+ const isTemporary = newValue.internalID === -1 && newValue.meta.displayName === undefined;
119865
119884
  // if we went from being temporary to no longer being temporary,
119866
119885
  // make sure we replace the junk id with a new value
119867
119886
  if (wasTemporary && !isTemporary) {
@@ -158794,6 +158813,10 @@ var pxsim;
158794
158813
  return;
158795
158814
  this.vca.disconnect();
158796
158815
  this.vca = undefined;
158816
+ const index = AudioSource.activeSources.indexOf(this);
158817
+ if (index !== -1) {
158818
+ AudioSource.activeSources.splice(index, 1);
158819
+ }
158797
158820
  }
158798
158821
  isDisposed() {
158799
158822
  return !this.vca;
@@ -159070,20 +159093,13 @@ var pxsim;
159070
159093
  }
159071
159094
  async function playInstructionsAsync(instructions, isCancelled, onPull) {
159072
159095
  AudioContextManager.soundEventCallback === null || AudioContextManager.soundEventCallback === void 0 ? void 0 : AudioContextManager.soundEventCallback("playinstructions", instructions);
159073
- await AudioContextManager.AudioWorkletSource.initializeWorklet(context());
159074
- let channel;
159096
+ const channel = new AudioContextManager.PlayInstructionsSource(context(), destination);
159075
159097
  let finished = false;
159076
159098
  if (onPull) {
159077
- channel = new AudioContextManager.AudioWorkletSource(context(), destination);
159078
- initOscilloscope(onPull, channel.analyser, () => finished || (isCancelled === null || isCancelled === void 0 ? void 0 : isCancelled()));
159079
- }
159080
- else {
159081
- channel = AudioContextManager.AudioWorkletSource.getAvailableSource();
159082
- if (!channel) {
159083
- channel = new AudioContextManager.AudioWorkletSource(context(), destination);
159084
- }
159099
+ initOscilloscope(onPull, channel.analyser, () => finished || (isCancelled === null || isCancelled === void 0 ? void 0 : isCancelled()) || channel.isDisposed());
159085
159100
  }
159086
159101
  await channel.playInstructionsAsync(instructions, isCancelled);
159102
+ channel.dispose();
159087
159103
  finished = true;
159088
159104
  }
159089
159105
  AudioContextManager.playInstructionsAsync = playInstructionsAsync;
@@ -159253,6 +159269,8 @@ var pxsim;
159253
159269
  this.distortion.disconnect();
159254
159270
  this.audioElement.pause();
159255
159271
  this.audioElement = undefined;
159272
+ this.source = undefined;
159273
+ this.distortion = undefined;
159256
159274
  }
159257
159275
  }
159258
159276
  AudioContextManager.AudioElementSource = AudioElementSource;
@@ -159325,6 +159343,7 @@ var pxsim;
159325
159343
  super.dispose();
159326
159344
  this.oscillator.stop();
159327
159345
  this.oscillator.disconnect();
159346
+ this.oscillator = undefined;
159328
159347
  AudioToneSource.instance = undefined;
159329
159348
  }
159330
159349
  }
@@ -159612,6 +159631,298 @@ var pxsim;
159612
159631
  })(music = codal.music || (codal.music = {}));
159613
159632
  })(codal = pxsim.codal || (pxsim.codal = {}));
159614
159633
  })(pxsim || (pxsim = {}));
159634
+ var pxsim;
159635
+ (function (pxsim) {
159636
+ var AudioContextManager;
159637
+ (function (AudioContextManager) {
159638
+ const waveForms = [null, "triangle", "sawtooth", "sine"];
159639
+ let noiseBuffer;
159640
+ let rectNoiseBuffer;
159641
+ let cycleNoiseBuffer = [];
159642
+ let squareBuffer = [];
159643
+ function getNoiseBuffer(context) {
159644
+ if (!noiseBuffer) {
159645
+ const bufferSize = 100000;
159646
+ noiseBuffer = context.createBuffer(1, bufferSize, context.sampleRate);
159647
+ const output = noiseBuffer.getChannelData(0);
159648
+ let x = 0xf01ba80;
159649
+ for (let i = 0; i < bufferSize; i++) {
159650
+ x ^= x << 13;
159651
+ x ^= x >> 17;
159652
+ x ^= x << 5;
159653
+ output[i] = ((x & 1023) / 512.0) - 1.0;
159654
+ }
159655
+ }
159656
+ return noiseBuffer;
159657
+ }
159658
+ function getRectNoiseBuffer(context) {
159659
+ // Create a square wave filtered by a pseudorandom bit sequence.
159660
+ // This uses four samples per cycle to create square-ish waves.
159661
+ // The Web Audio API's frequency scaling may be using linear
159662
+ // interpolation which would turn a two-sample wave into a triangle.
159663
+ if (!rectNoiseBuffer) {
159664
+ const bufferSize = 131072; // must be a multiple of 4
159665
+ rectNoiseBuffer = context.createBuffer(1, bufferSize, context.sampleRate);
159666
+ const output = rectNoiseBuffer.getChannelData(0);
159667
+ let x = 0xf01ba80;
159668
+ for (let i = 0; i < bufferSize; i += 4) {
159669
+ // see https://en.wikipedia.org/wiki/Xorshift
159670
+ x ^= x << 13;
159671
+ x ^= x >> 17;
159672
+ x ^= x << 5;
159673
+ if (x & 0x8000) {
159674
+ output[i] = 1.0;
159675
+ output[i + 1] = 1.0;
159676
+ output[i + 2] = -1.0;
159677
+ output[i + 3] = -1.0;
159678
+ }
159679
+ else {
159680
+ output[i] = 0.0;
159681
+ output[i + 1] = 0.0;
159682
+ output[i + 2] = 0.0;
159683
+ output[i + 3] = 0.0;
159684
+ }
159685
+ }
159686
+ }
159687
+ return rectNoiseBuffer;
159688
+ }
159689
+ function getCycleNoiseBuffer(context, bits) {
159690
+ if (!cycleNoiseBuffer[bits]) {
159691
+ // Buffer size needs to be a multiple of 4x the largest cycle length,
159692
+ // 4*64 in this case.
159693
+ const bufferSize = 1024;
159694
+ const buf = context.createBuffer(1, bufferSize, context.sampleRate);
159695
+ const output = buf.getChannelData(0);
159696
+ // See pxt-common-packages's libs/mixer/melody.cpp for details.
159697
+ // "bits" must be in the range 4..6.
159698
+ const cycle_bits = [0x2df0eb47, 0xc8165a93];
159699
+ const mask_456 = [0xf, 0x1f, 0x3f];
159700
+ for (let i = 0; i < bufferSize; i += 4) {
159701
+ let cycle = i / 4;
159702
+ let is_on;
159703
+ let cycle_mask = mask_456[bits - 4];
159704
+ cycle &= cycle_mask;
159705
+ is_on = (cycle_bits[cycle >> 5] & (1 << (cycle & 0x1f))) != 0;
159706
+ if (is_on) {
159707
+ output[i] = 1.0;
159708
+ output[i + 1] = 1.0;
159709
+ output[i + 2] = -1.0;
159710
+ output[i + 3] = -1.0;
159711
+ }
159712
+ else {
159713
+ output[i] = 0.0;
159714
+ output[i + 1] = 0.0;
159715
+ output[i + 2] = 0.0;
159716
+ output[i + 3] = 0.0;
159717
+ }
159718
+ }
159719
+ cycleNoiseBuffer[bits] = buf;
159720
+ }
159721
+ return cycleNoiseBuffer[bits];
159722
+ }
159723
+ function getSquareBuffer(context, param) {
159724
+ if (!squareBuffer[param]) {
159725
+ const bufferSize = 1024;
159726
+ const buf = context.createBuffer(1, bufferSize, context.sampleRate);
159727
+ const output = buf.getChannelData(0);
159728
+ for (let i = 0; i < bufferSize; i++) {
159729
+ output[i] = i < (param / 100 * bufferSize) ? 1 : -1;
159730
+ }
159731
+ squareBuffer[param] = buf;
159732
+ }
159733
+ return squareBuffer[param];
159734
+ }
159735
+ /*
159736
+ #define SW_TRIANGLE 1
159737
+ #define SW_SAWTOOTH 2
159738
+ #define SW_SINE 3
159739
+ #define SW_TUNEDNOISE 4
159740
+ #define SW_NOISE 5
159741
+ #define SW_SQUARE_10 11
159742
+ #define SW_SQUARE_50 15
159743
+ #define SW_SQUARE_CYCLE_16 16
159744
+ #define SW_SQUARE_CYCLE_32 17
159745
+ #define SW_SQUARE_CYCLE_64 18
159746
+ */
159747
+ /*
159748
+ struct SoundInstruction {
159749
+ uint8_t soundWave;
159750
+ uint8_t flags;
159751
+ uint16_t frequency;
159752
+ uint16_t duration;
159753
+ uint16_t startVolume;
159754
+ uint16_t endVolume;
159755
+ };
159756
+ */
159757
+ function getGenerator(context, waveFormIdx, hz) {
159758
+ let form = waveForms[waveFormIdx];
159759
+ if (form) {
159760
+ let src = context.createOscillator();
159761
+ src.type = form;
159762
+ src.frequency.value = hz;
159763
+ return src;
159764
+ }
159765
+ let buffer;
159766
+ if (waveFormIdx == 4)
159767
+ buffer = getRectNoiseBuffer(context);
159768
+ else if (waveFormIdx == 5)
159769
+ buffer = getNoiseBuffer(context);
159770
+ else if (11 <= waveFormIdx && waveFormIdx <= 15)
159771
+ buffer = getSquareBuffer(context, (waveFormIdx - 10) * 10);
159772
+ else if (16 <= waveFormIdx && waveFormIdx <= 18)
159773
+ buffer = getCycleNoiseBuffer(context, (waveFormIdx - 16) + 4);
159774
+ else
159775
+ return null;
159776
+ let node = context.createBufferSource();
159777
+ node.buffer = buffer;
159778
+ node.loop = true;
159779
+ const isFilteredNoise = waveFormIdx == 4 || (16 <= waveFormIdx && waveFormIdx <= 18);
159780
+ if (isFilteredNoise)
159781
+ node.playbackRate.value = hz / (context.sampleRate / 4);
159782
+ else if (waveFormIdx != 5)
159783
+ node.playbackRate.value = hz / (context.sampleRate / 1024);
159784
+ return node;
159785
+ }
159786
+ class PlayInstructionsSource extends AudioContextManager.AudioSource {
159787
+ constructor(context, destination) {
159788
+ super(context, destination);
159789
+ this.context = context;
159790
+ this.destination = destination;
159791
+ this.analyser = context.createAnalyser();
159792
+ this.analyser.fftSize = 2048;
159793
+ this.analyser.connect(this.vca);
159794
+ this.gain = context.createGain();
159795
+ this.gain.connect(this.analyser);
159796
+ }
159797
+ playInstructionsAsync(instructions, isCancelled, onPull) {
159798
+ return new Promise(async (resolve) => {
159799
+ AudioContextManager.soundEventCallback === null || AudioContextManager.soundEventCallback === void 0 ? void 0 : AudioContextManager.soundEventCallback("playinstructions", instructions);
159800
+ let resolved = false;
159801
+ const oscillators = {};
159802
+ const gains = {};
159803
+ let startTime = this.context.currentTime;
159804
+ let currentTime = startTime;
159805
+ let currentWave = 0;
159806
+ let totalDuration = 0;
159807
+ /** Square waves are perceved as much louder than other sounds, so scale it down a bit to make it less jarring **/
159808
+ const scaleVol = (n, isSqWave) => (n / 1024) / 4 * (isSqWave ? .5 : 1);
159809
+ const disconnectNodes = () => {
159810
+ if (resolved)
159811
+ return;
159812
+ resolved = true;
159813
+ for (const wave of Object.keys(oscillators)) {
159814
+ oscillators[wave].stop();
159815
+ oscillators[wave].disconnect();
159816
+ gains[wave].disconnect();
159817
+ }
159818
+ resolve();
159819
+ };
159820
+ for (let i = 0; i < instructions.length; i += 12) {
159821
+ const wave = instructions[i];
159822
+ const startFrequency = readUint16(instructions, i + 2);
159823
+ const duration = readUint16(instructions, i + 4) / 1000;
159824
+ const startVolume = readUint16(instructions, i + 6);
159825
+ const endVolume = readUint16(instructions, i + 8);
159826
+ const endFrequency = readUint16(instructions, i + 10);
159827
+ totalDuration += duration;
159828
+ if (wave === 0) {
159829
+ currentTime += duration;
159830
+ continue;
159831
+ }
159832
+ const isSquareWave = 11 <= wave && wave <= 15;
159833
+ if (!oscillators[wave]) {
159834
+ oscillators[wave] = getGenerator(this.context, wave, startFrequency);
159835
+ gains[wave] = this.context.createGain();
159836
+ gains[wave].gain.value = 0;
159837
+ gains[wave].connect(this.gain);
159838
+ oscillators[wave].connect(gains[wave]);
159839
+ oscillators[wave].start();
159840
+ }
159841
+ if (currentWave && wave !== currentWave) {
159842
+ gains[currentWave].gain.setTargetAtTime(0, currentTime, 0.015);
159843
+ }
159844
+ const osc = oscillators[wave];
159845
+ const gain = gains[wave];
159846
+ if (osc instanceof OscillatorNode) {
159847
+ osc.frequency.setValueAtTime(startFrequency, currentTime);
159848
+ osc.frequency.linearRampToValueAtTime(endFrequency, currentTime + duration);
159849
+ }
159850
+ else {
159851
+ const isFilteredNoise = wave == 4 || (16 <= wave && wave <= 18);
159852
+ if (isFilteredNoise)
159853
+ osc.playbackRate.linearRampToValueAtTime(endFrequency / (this.context.sampleRate / 4), currentTime + duration);
159854
+ else if (wave != 5)
159855
+ osc.playbackRate.linearRampToValueAtTime(endFrequency / (this.context.sampleRate / 1024), currentTime + duration);
159856
+ }
159857
+ gain.gain.setValueAtTime(scaleVol(startVolume, isSquareWave), currentTime);
159858
+ gain.gain.linearRampToValueAtTime(scaleVol(endVolume, isSquareWave), currentTime + duration);
159859
+ currentWave = wave;
159860
+ currentTime += duration;
159861
+ }
159862
+ this.gain.gain.setTargetAtTime(0, currentTime, 0.015);
159863
+ if (isCancelled || onPull) {
159864
+ const handleAnimationFrame = () => {
159865
+ const time = this.context.currentTime;
159866
+ if (time > startTime + totalDuration) {
159867
+ return;
159868
+ }
159869
+ if ((isCancelled && isCancelled()) || this.isDisposed()) {
159870
+ disconnectNodes();
159871
+ return;
159872
+ }
159873
+ const { frequency, volume } = findFrequencyAndVolumeAtTime((time - startTime) * 1000, instructions);
159874
+ if (onPull)
159875
+ onPull(frequency, volume / 1024);
159876
+ requestAnimationFrame(handleAnimationFrame);
159877
+ };
159878
+ requestAnimationFrame(handleAnimationFrame);
159879
+ }
159880
+ await pxsim.U.delay(totalDuration * 1000);
159881
+ disconnectNodes();
159882
+ });
159883
+ }
159884
+ dispose() {
159885
+ if (this.isDisposed())
159886
+ return;
159887
+ super.dispose();
159888
+ this.analyser.disconnect();
159889
+ this.gain.disconnect();
159890
+ this.analyser = undefined;
159891
+ this.gain = undefined;
159892
+ }
159893
+ }
159894
+ AudioContextManager.PlayInstructionsSource = PlayInstructionsSource;
159895
+ function readUint16(buf, offset) {
159896
+ const temp = new Uint8Array(2);
159897
+ temp[0] = buf[offset];
159898
+ temp[1] = buf[offset + 1];
159899
+ return new Uint16Array(temp.buffer)[0];
159900
+ }
159901
+ function findFrequencyAndVolumeAtTime(millis, instructions) {
159902
+ let currentTime = 0;
159903
+ for (let i = 0; i < instructions.length; i += 12) {
159904
+ const startFrequency = readUint16(instructions, i + 2);
159905
+ const duration = readUint16(instructions, i + 4);
159906
+ const startVolume = readUint16(instructions, i + 6);
159907
+ const endVolume = readUint16(instructions, i + 8);
159908
+ const endFrequency = readUint16(instructions, i + 10);
159909
+ if (currentTime + duration < millis) {
159910
+ currentTime += duration;
159911
+ continue;
159912
+ }
159913
+ const offset = (millis - currentTime) / duration;
159914
+ return {
159915
+ frequency: startFrequency + (endFrequency - startFrequency) * offset,
159916
+ volume: startVolume + (endVolume - startVolume) * offset,
159917
+ };
159918
+ }
159919
+ return {
159920
+ frequency: -1,
159921
+ volume: -1
159922
+ };
159923
+ }
159924
+ })(AudioContextManager = pxsim.AudioContextManager || (pxsim.AudioContextManager = {}));
159925
+ })(pxsim || (pxsim = {}));
159615
159926
  /// <reference path="../../localtypings/pxtmusic.d.ts" />
159616
159927
  var pxsim;
159617
159928
  (function (pxsim) {
@@ -32,10 +32,12 @@ export declare class FieldAnimationEditor extends FieldAssetEditor<FieldAnimatio
32
32
  protected onEditorClose(newValue: pxt.Animation): void;
33
33
  protected getValueText(): string;
34
34
  protected redrawPreview(): void;
35
- protected onMouseEnter: () => void;
36
- protected onMouseLeave: () => void;
35
+ protected onMouseEnter: (e: MouseEvent) => void;
36
+ protected onDocumentMouseMove: (e: MouseEvent) => void;
37
+ protected cancelAnimation: () => void;
37
38
  protected getParentIntervalBlock(): Blockly.Block;
38
39
  protected setParentInterval(interval: number): void;
39
40
  protected getParentInterval(): number;
40
41
  protected parseFieldOptions(opts: FieldAnimationOptions): ParsedFieldAnimationOptions;
42
+ onDispose(): void;
41
43
  }
package/built/pxtlib.js CHANGED
@@ -21551,6 +21551,25 @@ var pxt;
21551
21551
  }
21552
21552
  if (entry.tilemapTile) {
21553
21553
  tags.push("tile");
21554
+ let category = undefined;
21555
+ if (entry.displayName && entry.displayName.indexOf("--") !== -1) {
21556
+ const rawCategory = entry.displayName.split("--")[1].trim();
21557
+ const categoryParts = rawCategory.split(/[\s\-]+/g).map((part, index) => {
21558
+ if (index === 0) {
21559
+ return part;
21560
+ }
21561
+ else {
21562
+ return part.charAt(0).toUpperCase() + part.slice(1);
21563
+ }
21564
+ });
21565
+ category = categoryParts.join("");
21566
+ }
21567
+ if (!category && !/^transparency(?:4|8|16|32)$/.test(varName)) {
21568
+ category = namespaceName;
21569
+ }
21570
+ if (category) {
21571
+ tags.push("category-" + category);
21572
+ }
21554
21573
  }
21555
21574
  }
21556
21575
  if (mimeType === pxt.IMAGE_MIME_TYPE) {
@@ -22136,11 +22155,11 @@ var pxt;
22136
22155
  return snapshot.assets[type];
22137
22156
  }
22138
22157
  function patchTemporaryAsset(oldValue, newValue, project) {
22139
- if (!oldValue || assetEquals(oldValue, newValue))
22158
+ if (!oldValue || assetEquals(oldValue, newValue) || newValue.id !== oldValue.id)
22140
22159
  return newValue;
22141
22160
  newValue = cloneAsset(newValue, true);
22142
22161
  const wasTemporary = oldValue.internalID === -1;
22143
- const isTemporary = newValue.internalID === -1;
22162
+ const isTemporary = newValue.internalID === -1 && newValue.meta.displayName === undefined;
22144
22163
  // if we went from being temporary to no longer being temporary,
22145
22164
  // make sure we replace the junk id with a new value
22146
22165
  if (wasTemporary && !isTemporary) {
package/built/pxtsim.d.ts CHANGED
@@ -1865,6 +1865,17 @@ declare namespace pxsim.codal.music.MusicalProgressions {
1865
1865
  */
1866
1866
  function calculateFrequencyFromProgression(root: number, progression: Progression, offset: number): number;
1867
1867
  }
1868
+ declare namespace pxsim.AudioContextManager {
1869
+ class PlayInstructionsSource extends AudioSource {
1870
+ context: AudioContext;
1871
+ destination: AudioNode;
1872
+ analyser: AnalyserNode;
1873
+ gain: GainNode;
1874
+ constructor(context: AudioContext, destination: AudioNode);
1875
+ playInstructionsAsync(instructions: Uint8Array, isCancelled?: () => boolean, onPull?: (freq: number, volume: number) => void): Promise<void>;
1876
+ dispose(): void;
1877
+ }
1878
+ }
1868
1879
  declare namespace pxsim.music {
1869
1880
  type SequencerState = "play" | "loop" | "stop";
1870
1881
  type SequencerEvent = "tick" | "play" | "stop" | "loop" | "state-change" | "looped";