pxt-core 8.2.4 → 8.2.7

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 (64) hide show
  1. package/built/backendutils.js +19 -1
  2. package/built/cli.js +1 -0
  3. package/built/pxt-common.json +1 -1
  4. package/built/pxt.js +191 -33
  5. package/built/pxtblockly.js +17 -4
  6. package/built/pxtblocks.d.ts +1 -0
  7. package/built/pxtblocks.js +17 -4
  8. package/built/pxtcompiler.d.ts +1 -0
  9. package/built/pxtcompiler.js +34 -8
  10. package/built/pxteditor.d.ts +1 -0
  11. package/built/pxteditor.js +5 -0
  12. package/built/pxtlib.d.ts +14 -0
  13. package/built/pxtlib.js +117 -9
  14. package/built/pxtpy.d.ts +1 -0
  15. package/built/pxtpy.js +39 -16
  16. package/built/target.js +1 -1
  17. package/built/web/blockly.css +1 -1
  18. package/built/web/main.js +1 -1
  19. package/built/web/pxtapp.js +1 -1
  20. package/built/web/pxtasseteditor.js +1 -1
  21. package/built/web/pxtblockly.js +1 -1
  22. package/built/web/pxtblocks.js +1 -1
  23. package/built/web/pxtcompiler.js +1 -1
  24. package/built/web/pxteditor.js +1 -1
  25. package/built/web/pxtembed.js +2 -2
  26. package/built/web/pxtlib.js +1 -1
  27. package/built/web/pxtpy.js +1 -1
  28. package/built/web/pxtworker.js +1 -1
  29. package/built/web/react-common-authcode.css +98 -0
  30. package/built/web/react-common-skillmap.css +1 -1
  31. package/built/web/rtlblockly.css +1 -1
  32. package/built/web/rtlreact-common-skillmap.css +1 -1
  33. package/built/web/rtlsemantic.css +1 -1
  34. package/built/web/semantic.css +1 -1
  35. package/built/web/skillmap/css/main.3684f34d.chunk.css +1 -0
  36. package/built/web/skillmap/js/2.26325281.chunk.js +2 -0
  37. package/built/web/skillmap/js/main.b87a119c.chunk.js +1 -0
  38. package/localtypings/react.d.ts +5 -0
  39. package/package.json +1 -1
  40. package/react-common/components/controls/Checkbox.tsx +1 -1
  41. package/react-common/components/palette/ColorPickerField.tsx +65 -0
  42. package/react-common/components/palette/PaletteEditor.tsx +66 -0
  43. package/react-common/components/palette/PalettePicker.tsx +52 -0
  44. package/react-common/components/palette/PaletteSwatch.tsx +27 -0
  45. package/react-common/components/palette/Palettes.ts +289 -0
  46. package/react-common/components/profile/SignInModal.tsx +100 -0
  47. package/react-common/components/profile/UserPane.tsx +17 -9
  48. package/react-common/styles/palette/ColorPickerField.less +21 -0
  49. package/react-common/styles/palette/PalettePicker.less +10 -0
  50. package/react-common/styles/palette/PaletteSwatch.less +27 -0
  51. package/react-common/styles/palette/palette.less +3 -0
  52. package/react-common/styles/profile/profile.less +64 -1
  53. package/react-common/styles/react-common.less +1 -0
  54. package/theme/asset-editor.less +5 -0
  55. package/theme/blockly-core.less +1 -1
  56. package/theme/common.less +13 -2
  57. package/theme/greenscreen.less +4 -1
  58. package/theme/home.less +0 -5
  59. package/theme/image-editor/bottomBar.less +1 -1
  60. package/theme/tutorial-sidebar.less +43 -2
  61. package/webapp/public/skillmap.html +2 -2
  62. package/built/web/skillmap/css/main.c5811548.chunk.css +0 -1
  63. package/built/web/skillmap/js/2.26b9a6f6.chunk.js +0 -2
  64. package/built/web/skillmap/js/main.98eed582.chunk.js +0 -1
package/built/pxt.js CHANGED
@@ -101796,7 +101796,7 @@ var pxt;
101796
101796
  MATH_ADDITION_SYMBOL: pxt.Util.lf("{id:op}+"),
101797
101797
  MATH_SUBTRACTION_SYMBOL: pxt.Util.lf("{id:op}-"),
101798
101798
  MATH_MULTIPLICATION_SYMBOL: pxt.Util.lf("{id:op}×"),
101799
- MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}÷"),
101799
+ MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}/"),
101800
101800
  MATH_POWER_SYMBOL: pxt.Util.lf("{id:op}**")
101801
101801
  }
101802
101802
  },
@@ -101806,7 +101806,7 @@ var pxt;
101806
101806
  url: '/blocks/math',
101807
101807
  category: 'math',
101808
101808
  block: {
101809
- MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1 ÷ %2")
101809
+ MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1 / %2")
101810
101810
  }
101811
101811
  },
101812
101812
  'math_js_op': {
@@ -101835,7 +101835,7 @@ var pxt;
101835
101835
  "acos": pxt.Util.lf("{id:op}acos"),
101836
101836
  "tan": pxt.Util.lf("{id:op}tan"),
101837
101837
  "atan2": pxt.Util.lf("{id:op}atan2"),
101838
- "idiv": pxt.Util.lf("{id:op}integer ÷"),
101838
+ "idiv": pxt.Util.lf("{id:op}integer /"),
101839
101839
  "imul": pxt.Util.lf("{id:op}integer ×"),
101840
101840
  }
101841
101841
  },
@@ -106399,6 +106399,7 @@ var pxt;
106399
106399
  docs.prepTemplate = prepTemplate;
106400
106400
  function setupRenderer(renderer) {
106401
106401
  renderer.image = function (href, title, text) {
106402
+ var _a, _b;
106402
106403
  const endpointName = "makecodeprodmediaeastus-usea";
106403
106404
  if (href.startsWith("youtube:")) {
106404
106405
  let out = '<div class="tutorial-video-embed"><iframe class="yt-embed" src="https://www.youtube.com/embed/' + href.split(":").pop()
@@ -106406,7 +106407,24 @@ var pxt;
106406
106407
  return out;
106407
106408
  }
106408
106409
  else if (href.startsWith("azuremedia:")) {
106409
- let out = `<div class="tutorial-video-embed"><video class="ams-embed" controls src="https://${endpointName}.streaming.media.azure.net/` + href.split(":").pop() + '/manifest(format=mpd-time-cmaf)" /></div>';
106410
+ let videoID = href.split(":")[1];
106411
+ const flagsSplit = videoID.split("?");
106412
+ let startTime;
106413
+ let endTime;
106414
+ if (flagsSplit[1]) {
106415
+ videoID = flagsSplit[0];
106416
+ const passedParameters = flagsSplit[1];
106417
+ startTime = (_a = /start(?:time)?=(\d+)/i.exec(passedParameters)) === null || _a === void 0 ? void 0 : _a[1];
106418
+ endTime = (_b = /end(?:time)?=(\d+)/i.exec(passedParameters)) === null || _b === void 0 ? void 0 : _b[1];
106419
+ }
106420
+ const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
106421
+ if (startTime) {
106422
+ url.hash = `t=${startTime}`;
106423
+ }
106424
+ if (endTime) {
106425
+ url.searchParams.append("endTime", endTime);
106426
+ }
106427
+ let out = `<div class="tutorial-video-embed"><video class="ams-embed" controls src="${url.toString()}" /></div>`;
106410
106428
  return out;
106411
106429
  }
106412
106430
  else {
@@ -111961,7 +111979,7 @@ var pxt;
111961
111979
  // and pulls from master
111962
111980
  const modtag = (modid === null || modid === void 0 ? void 0 : modid.tag) || ((_a = mod.config) === null || _a === void 0 ? void 0 : _a.version);
111963
111981
  const vertag = verid.tag;
111964
- // if there is no tag on the current dependency,
111982
+ // if there is no tag on the current dependency,
111965
111983
  // assume same as existing module version if any
111966
111984
  if (modtag && !vertag) {
111967
111985
  pxt.debug(`unversioned ${ver}, using ${modtag}`);
@@ -112420,6 +112438,8 @@ var pxt;
112420
112438
  opts.otherMultiVariants.push(etarget);
112421
112439
  }
112422
112440
  else {
112441
+ etarget.target.isNative = opts.target.isNative;
112442
+ opts.target = etarget.target;
112423
112443
  ext = einfo;
112424
112444
  opts.otherMultiVariants = [];
112425
112445
  }
@@ -113375,7 +113395,12 @@ var ts;
113375
113395
  const left = param.substr(0, dotIdx);
113376
113396
  let right = param.substr(dotIdx + 1);
113377
113397
  right = pxtc.U.snakify(right).toUpperCase();
113378
- return `${left}.${right}`;
113398
+ if (left) {
113399
+ return `${left}.${right}`;
113400
+ }
113401
+ else {
113402
+ return right;
113403
+ }
113379
113404
  }
113380
113405
  return param;
113381
113406
  }
@@ -119289,6 +119314,18 @@ var ts;
119289
119314
  }
119290
119315
  }
119291
119316
  assembler.Line = Line;
119317
+ const MAX_OBJ_USERS = 5;
119318
+ class AsmObject {
119319
+ constructor(id, description) {
119320
+ this.id = id;
119321
+ this.description = description;
119322
+ this.sizeAdj = 0;
119323
+ this.users = [];
119324
+ }
119325
+ get size() {
119326
+ return (this.endLocation - this.startLocation) - this.sizeAdj;
119327
+ }
119328
+ }
119292
119329
  // File is the center of the action: parsing a file into a sequence of Lines
119293
119330
  // and also emitting the binary (buf)
119294
119331
  class File {
@@ -119313,6 +119350,11 @@ var ts;
119313
119350
  this.throwOnError = false;
119314
119351
  this.disablePeepHole = false;
119315
119352
  this.stackAtLabel = {};
119353
+ this.codeSizeStats = false;
119354
+ this.labelToObject = {};
119355
+ this.idToObject = {};
119356
+ this.objSuspendStart = 0;
119357
+ this.labelsToObjectDone = false;
119316
119358
  this.currLine = new Line(this, "<start>");
119317
119359
  this.currLine.lineNo = 0;
119318
119360
  this.ei = ei;
@@ -119332,6 +119374,15 @@ var ts;
119332
119374
  pc() {
119333
119375
  return this.location() + this.baseOffset;
119334
119376
  }
119377
+ useLabel(name) {
119378
+ if (!this.currObject || name[0] == '.' || this.objSuspendStart)
119379
+ return;
119380
+ const obj = pxtc.U.lookup(this.labelToObject, name);
119381
+ if (!obj || obj == this.currObject)
119382
+ return;
119383
+ if (obj.users.length < MAX_OBJ_USERS && obj.users.indexOf(this.currObject) < 0)
119384
+ obj.users.push(this.currObject);
119385
+ }
119335
119386
  // parsing of an "integer", well actually much more than
119336
119387
  // just that
119337
119388
  parseOneInt(s) {
@@ -119461,6 +119512,7 @@ var ts;
119461
119512
  return name;
119462
119513
  }
119463
119514
  lookupLabel(name, direct = false) {
119515
+ this.useLabel(name);
119464
119516
  let v = null;
119465
119517
  let scoped = this.scopedName(name);
119466
119518
  if (this.labels.hasOwnProperty(scoped)) {
@@ -119619,6 +119671,37 @@ var ts;
119619
119671
  };
119620
119672
  let num0;
119621
119673
  switch (words[0]) {
119674
+ case ".object":
119675
+ if (!this.codeSizeStats) {
119676
+ // do nothing
119677
+ }
119678
+ else if (words[1] == "PUSH") {
119679
+ this.objSuspendStart = this.location();
119680
+ }
119681
+ else if (words[1] == "POP") {
119682
+ if (this.objSuspendStart)
119683
+ this.currObject.sizeAdj += this.location() - this.objSuspendStart;
119684
+ this.objSuspendStart = 0;
119685
+ }
119686
+ else {
119687
+ if (this.currObject)
119688
+ this.currObject.endLocation = this.location();
119689
+ this.currObject = pxtc.U.lookup(this.idToObject, words[1]);
119690
+ if (!this.currObject) {
119691
+ const str = l.text.replace(/^[^"]*/, "");
119692
+ let parsed = words[1];
119693
+ if (words.length > 2) {
119694
+ parsed = parseString(str.trim());
119695
+ if (parsed == null)
119696
+ this.directiveError(lf("expecting string in .object"));
119697
+ }
119698
+ this.currObject = new AsmObject(words[1], parsed);
119699
+ this.idToObject[words[1]] = this.currObject;
119700
+ }
119701
+ this.currObject.sizeAdj = 0;
119702
+ this.currObject.startLocation = this.location();
119703
+ }
119704
+ break;
119622
119705
  case ".ascii":
119623
119706
  case ".asciz":
119624
119707
  case ".string":
@@ -119813,6 +119896,8 @@ var ts;
119813
119896
  }
119814
119897
  }
119815
119898
  handleOneInstruction(ln, instr) {
119899
+ if (this.codeSizeStats && ln.ldlitLabel)
119900
+ this.useLabel(ln.ldlitLabel);
119816
119901
  let op = instr.emit(ln);
119817
119902
  if (!op.error) {
119818
119903
  this.stack += op.stack;
@@ -119921,6 +120006,8 @@ var ts;
119921
120006
  if (l.words.length == 0)
119922
120007
  return;
119923
120008
  if (l.type == "label") {
120009
+ if (this.currObject && !this.labelsToObjectDone && l.words[0][0] != '.')
120010
+ this.labelToObject[l.words[0]] = this.currObject;
119924
120011
  let lblname = this.scopedName(l.words[0]);
119925
120012
  this.prevLabel = lblname;
119926
120013
  if (this.finalEmit) {
@@ -119961,6 +120048,8 @@ var ts;
119961
120048
  pxtc.oops();
119962
120049
  }
119963
120050
  });
120051
+ this.labelsToObjectDone = true;
120052
+ this.currObject = null;
119964
120053
  }
119965
120054
  getSourceMap() {
119966
120055
  const sourceMap = {};
@@ -119993,6 +120082,22 @@ var ts;
119993
120082
  }
119994
120083
  return sourceMap;
119995
120084
  }
120085
+ getCodeSizeStats() {
120086
+ if (!this.codeSizeStats)
120087
+ return "";
120088
+ const objs = pxtc.U.values(this.idToObject);
120089
+ objs.sort((a, b) => b.size - a.size);
120090
+ let r = ";\n; Code size:\n;\n";
120091
+ for (const obj of objs) {
120092
+ r += `; ${(" " + obj.size).slice(-6)} ${obj.description} [${obj.id}]\n`;
120093
+ if (obj.users.length >= MAX_OBJ_USERS)
120094
+ r += `; by many, including ${obj.users[0].description}\n`;
120095
+ else
120096
+ for (const x of obj.users)
120097
+ r += `; by ${x.description} [${x.id}]\n`;
120098
+ }
120099
+ return r;
120100
+ }
119996
120101
  getSource(clean, numStmts = 1, flashSize = 0) {
119997
120102
  let lenPrev = 0;
119998
120103
  let size = (lbl) => {
@@ -120008,8 +120113,11 @@ var ts;
120008
120113
  let lenLiterals = size("_literals_end");
120009
120114
  let lenAllCode = lenPrev;
120010
120115
  let totalSize = (lenTotal + this.baseOffset) & 0xffffff;
120011
- if (flashSize && totalSize > flashSize)
120012
- pxtc.U.userError(lf("program too big by {0} bytes!", totalSize - flashSize));
120116
+ if (flashSize && totalSize > flashSize) {
120117
+ const e = new Error(lf("program too big by {0} bytes!", totalSize - flashSize));
120118
+ e.ksErrorCode = 9283;
120119
+ throw e;
120120
+ }
120013
120121
  flashSize = flashSize || 128 * 1024;
120014
120122
  let totalInfo = lf("; total bytes: {0} ({1}% of {2}k flash with {3} free)", totalSize, (100 * totalSize / flashSize).toFixed(1), (flashSize / 1024).toFixed(1), flashSize - totalSize);
120015
120123
  let res =
@@ -120017,7 +120125,7 @@ var ts;
120017
120125
  lf("; generated code sizes (bytes): {0} (incl. {1} user, {2} helpers, {3} vtables, {4} lits); src size {5}\n", lenAllCode, lenCode, lenHelpers, lenVtables, lenLiterals, lenTotal - lenAllCode) +
120018
120126
  lf("; assembly: {0} lines; density: {1} bytes/stmt; ({2} stmts)\n", this.lines.length, Math.round(100 * lenCode / numStmts) / 100, numStmts) +
120019
120127
  totalInfo + "\n" +
120020
- this.stats + "\n\n";
120128
+ this.stats + this.getCodeSizeStats() + "\n\n";
120021
120129
  let skipOne = false;
120022
120130
  this.lines.forEach((ln, i) => {
120023
120131
  if (ln.words[0] == "_stored_program") {
@@ -121818,6 +121926,7 @@ var ts;
121818
121926
  const info = utf8AsmStringLiteral(strLit);
121819
121927
  return `
121820
121928
  .balign 4
121929
+ .object ${lbl}
121821
121930
  ${lbl}: ${this.obj_header(info.vt)}
121822
121931
  ${info.asm}
121823
121932
  `;
@@ -121828,6 +121937,7 @@ var ts;
121828
121937
  const align = /f{16}/i.test(data) ? 8 : 4;
121829
121938
  return `
121830
121939
  .balign ${align}
121940
+ .object ${lbl}
121831
121941
  ${lbl}: ${this.obj_header("pxt::buffer_vt")}
121832
121942
  ${hexLiteralAsm(data)}
121833
121943
  `;
@@ -121937,6 +122047,7 @@ ${hexLiteralAsm(data)}
121937
122047
  ;
121938
122048
  `);
121939
122049
  let baseLabel = this.proc.label();
122050
+ this.write(`.object ${baseLabel} ${JSON.stringify(this.proc.getFullName())}`);
121940
122051
  let preLabel = baseLabel + "_pre";
121941
122052
  let bkptLabel = baseLabel + "_bkpt";
121942
122053
  let locLabel = baseLabel + "_locals";
@@ -122301,9 +122412,13 @@ ${baseLabel}_nochk:
122301
122412
  this.writeFailBranch();
122302
122413
  });
122303
122414
  }
122415
+ helperObject(desc) {
122416
+ return `.object _pxt_helper_${desc.replace(/[^\w]+/g, "_")} "helper: ${desc}"`;
122417
+ }
122304
122418
  emitBindHelper() {
122305
122419
  const maxArgs = 12;
122306
122420
  this.write(`
122421
+ ${this.helperObject("bind")}
122307
122422
  .section code
122308
122423
  _pxt_bind_helper:
122309
122424
  push {r0, r2}
@@ -122778,6 +122893,7 @@ ${baseLabel}_nochk:
122778
122893
  emitFieldMethods() {
122779
122894
  for (let op of ["get", "set"]) {
122780
122895
  this.write(`
122896
+ ${this.helperObject(op)}
122781
122897
  .section code
122782
122898
  _pxt_map_${op}:
122783
122899
  `);
@@ -122819,6 +122935,7 @@ ${baseLabel}_nochk:
122819
122935
  }
122820
122936
  emitArrayMethod(op, isBuffer) {
122821
122937
  this.write(`
122938
+ ${this.helperObject(op + " " + (isBuffer ? "buffer" : "array"))}
122822
122939
  .section code
122823
122940
  _pxt_${isBuffer ? "buffer" : "array"}_${op}:
122824
122941
  `);
@@ -122903,6 +123020,7 @@ ${baseLabel}_nochk:
122903
123020
  emitLambdaTrampoline() {
122904
123021
  let r3 = pxtc.target.stackAlign ? "r3," : "";
122905
123022
  this.write(`
123023
+ ${this.helperObject("trampoline")}
122906
123024
  .section code
122907
123025
  _pxt_lambda_trampoline:
122908
123026
  push {${r3} r4, r5, r6, r7, lr}
@@ -122942,6 +123060,7 @@ ${baseLabel}_nochk:
122942
123060
  mov r11, r7
122943
123061
  pop {${r3} r4, r5, r6, r7, pc}`);
122944
123062
  this.write(`
123063
+ ${this.helperObject("exn")}
122945
123064
  .section code
122946
123065
  ; r0 - try frame
122947
123066
  ; r1 - handler PC
@@ -122970,6 +123089,7 @@ ${baseLabel}_nochk:
122970
123089
  bx r1
122971
123090
  `);
122972
123091
  this.write(`
123092
+ ${this.helperObject("stringconv")}
122973
123093
  .section code
122974
123094
  _pxt_stringConv:
122975
123095
  `);
@@ -124284,6 +124404,7 @@ _numops_fromInt:
124284
124404
  // this make sure to set the Z flag correctly
124285
124405
  r += `
124286
124406
  .section code
124407
+ .object _pxt_helper_cmp_${op}
124287
124408
  _cmp_${op}:
124288
124409
  lsls r2, r0, #31
124289
124410
  beq .boxed
@@ -128869,7 +128990,8 @@ var ts;
128869
128990
  lbl = "_ldlit_" + ++seq;
128870
128991
  values[v] = lbl;
128871
128992
  }
128872
- line.update(`ldr ${reg}, ${lbl}`);
128993
+ line.ldlitLabel = line.words[3];
128994
+ line.update(`ldr ${reg}, ${lbl} ; ${line.ldlitLabel}`);
128873
128995
  }
128874
128996
  if (line === nextGoodSpot) {
128875
128997
  nextGoodSpot = null;
@@ -128877,6 +128999,7 @@ var ts;
128877
128999
  let jmplbl = "_jmpwords_" + ++seq;
128878
129000
  if (needsJumpOver)
128879
129001
  txtLines.push("bb " + jmplbl);
129002
+ txtLines.push(`.object PUSH`);
128880
129003
  txtLines.push(".balign 4");
128881
129004
  for (let v of Object.keys(values)) {
128882
129005
  let lbl = values[v];
@@ -128884,6 +129007,7 @@ var ts;
128884
129007
  }
128885
129008
  if (needsJumpOver)
128886
129009
  txtLines.push(jmplbl + ":");
129010
+ txtLines.push(`.object POP`);
128887
129011
  for (let t of txtLines) {
128888
129012
  f.buildLine(t, outlines);
128889
129013
  let ll = outlines[outlines.length - 1];
@@ -130178,7 +130302,7 @@ var ts;
130178
130302
  function inspect(n) {
130179
130303
  console.log(stringKind(n));
130180
130304
  }
130181
- // next free error 9283
130305
+ // next free error 9284
130182
130306
  function userError(code, msg, secondary = false) {
130183
130307
  let e = new Error(msg);
130184
130308
  e.ksEmitterUserError = true;
@@ -136348,7 +136472,8 @@ var ts;
136348
136472
  asmLabels[lbl] = true;
136349
136473
  return "";
136350
136474
  });
136351
- let code = ".section code\n" +
136475
+ let code = ".object inlineasm\n" +
136476
+ ".section code\n" +
136352
136477
  "@stackmark func\n" +
136353
136478
  "@scope user" + asmIdx++ + "\n" +
136354
136479
  src + "\n" +
@@ -136881,6 +137006,7 @@ var ts;
136881
137006
  for (let data of Object.keys(bin.doubles)) {
136882
137007
  let lbl = bin.doubles[data];
136883
137008
  bin.otherLiterals.push(`
137009
+ .object ${lbl}
136884
137010
  .balign 4
136885
137011
  ${lbl}: ${snippets.obj_header("pxt::number_vt")}
136886
137012
  .hex ${data}
@@ -136973,6 +137099,7 @@ ${lbl}: ${snippets.obj_header("pxt::number_vt")}
136973
137099
  // ifaceInfo.mult = 0
136974
137100
  let ptrSz = pxtc.target.shortPointers ? ".short" : ".word";
136975
137101
  let s = `
137102
+ .object ${info.id}_VT
136976
137103
  .balign 4
136977
137104
  ${info.id}_VT:
136978
137105
  .short ${info.allfields.length * 4 + 4} ; size in bytes
@@ -137070,14 +137197,18 @@ ${hexfile.hexPrelude()}
137070
137197
  asmsource += hexfile.asmTotalSource; // user-supplied asm
137071
137198
  asmsource += "_code_end:\n\n";
137072
137199
  pxtc.U.iterMap(bin.codeHelpers, (code, lbl) => {
137073
- asmsource += ` .section code\n${lbl}:\n${code}\n`;
137200
+ asmsource +=
137201
+ ` .section code\n` +
137202
+ ` .object _code_helper_${lbl}\n` +
137203
+ `${lbl}:\n` +
137204
+ `${code}\n`;
137074
137205
  });
137075
137206
  asmsource += snippets.arithmetic();
137076
137207
  asmsource += "_helpers_end:\n\n";
137077
137208
  bin.usedClassInfos.forEach(info => {
137078
137209
  asmsource += vtableToAsm(info, opts, bin);
137079
137210
  });
137080
- asmsource += `\n.balign 4\n_pxt_iface_member_names:\n`;
137211
+ asmsource += `\n.balign 4\n.object _pxt_iface_member_names\n_pxt_iface_member_names:\n`;
137081
137212
  asmsource += ` .word ${bin.ifaceMembers.length}\n`;
137082
137213
  let idx = 0;
137083
137214
  for (let d of bin.ifaceMembers) {
@@ -137086,7 +137217,7 @@ ${hexfile.hexPrelude()}
137086
137217
  }
137087
137218
  asmsource += ` .word 0\n`;
137088
137219
  asmsource += "_vtables_end:\n\n";
137089
- asmsource += `\n.balign 4\n_pxt_config_data:\n`;
137220
+ asmsource += `\n.balign 4\n.object _pxt_config_data\n_pxt_config_data:\n`;
137090
137221
  const cfg = bin.res.configData || [];
137091
137222
  // asmsource += ` .word ${cfg.length}, 0 ; num. entries`
137092
137223
  for (let d of cfg) {
@@ -137095,7 +137226,7 @@ ${hexfile.hexPrelude()}
137095
137226
  asmsource += ` .word 0\n\n`;
137096
137227
  emitStrings(snippets, bin);
137097
137228
  asmsource += bin.otherLiterals.join("");
137098
- asmsource += `\n.balign 4\n.section code\n_pxt_perf_counters:\n`;
137229
+ asmsource += `\n.balign 4\n.section code\n.object _perf_counters\n_pxt_perf_counters:\n`;
137099
137230
  asmsource += ` .word ${perfCounters.length}\n`;
137100
137231
  let strs = "";
137101
137232
  for (let i = 0; i < perfCounters.length; ++i) {
@@ -137128,6 +137259,8 @@ ${hexfile.hexPrelude()}
137128
137259
  b.ei.testAssembler(); // just in case
137129
137260
  if (target.switches.noPeepHole)
137130
137261
  b.disablePeepHole = true;
137262
+ if (target.switches.size)
137263
+ b.codeSizeStats = true;
137131
137264
  b.lookupExternalLabel = hexfile.lookupFunctionAddr;
137132
137265
  b.normalizeExternalLabel = s => {
137133
137266
  let inf = hexfile.lookupFunc(s);
@@ -137188,6 +137321,7 @@ ${hexfile.hexPrelude()}
137188
137321
  }
137189
137322
  return `
137190
137323
  .balign 16
137324
+ .object _stored_program
137191
137325
  _stored_program: .hex ${res}
137192
137326
  `;
137193
137327
  }
@@ -139735,7 +139869,7 @@ var ts;
139735
139869
  }
139736
139870
  const type = checker === null || checker === void 0 ? void 0 : checker.getTypeAtLocation(param);
139737
139871
  const typeSymbol = service.getPxtSymbolFromTsSymbol(type === null || type === void 0 ? void 0 : type.symbol, apis, checker);
139738
- if ((typeSymbol === null || typeSymbol === void 0 ? void 0 : typeSymbol.attributes.fixedInstances) && python) {
139872
+ if (((typeSymbol === null || typeSymbol === void 0 ? void 0 : typeSymbol.attributes.fixedInstances) || (typeSymbol === null || typeSymbol === void 0 ? void 0 : typeSymbol.attributes.emitAsConstant)) && python) {
139739
139873
  return pxt.Util.snakify(paramDefl);
139740
139874
  }
139741
139875
  if (python) {
@@ -140763,6 +140897,13 @@ var pxt;
140763
140897
  error(a, 9503, pxt.U.lf("No module named '{0}'", name));
140764
140898
  return sym;
140765
140899
  }
140900
+ function getHelperVariableName() {
140901
+ const scope = currentScope();
140902
+ if (scope.nextHelperVariableId === undefined) {
140903
+ scope.nextHelperVariableId = 0;
140904
+ }
140905
+ return "___tempvar" + scope.nextHelperVariableId++;
140906
+ }
140766
140907
  function defvar(name, opts, modifier, scope) {
140767
140908
  if (!scope)
140768
140909
  scope = currentScope();
@@ -142069,20 +142210,7 @@ var pxt;
142069
142210
  return B.mkStmt(B.mkText(pref), B.mkInfix(expr(target), "=", expr(value)));
142070
142211
  }
142071
142212
  if (!pref && target.kind == "Tuple") {
142072
- let tup = target;
142073
- let targs = [B.mkText("let "), B.mkText("[")];
142074
- let nonNames = tup.elts.filter(e => e.kind !== "Name");
142075
- if (nonNames.length) {
142076
- error(n, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
142077
- return stmtTODO(n);
142078
- }
142079
- let tupNames = tup.elts
142080
- .map(e => e)
142081
- .map(convertName);
142082
- targs.push(B.mkCommaSep(tupNames));
142083
- targs.push(B.mkText("]"));
142084
- let res = B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
142085
- return res;
142213
+ return convertDestructuring(n, target, value);
142086
142214
  }
142087
142215
  if (target.kind === "Name") {
142088
142216
  const scopeSym = currentScope().vars[nm];
@@ -142110,12 +142238,41 @@ var pxt;
142110
142238
  if (!lExp)
142111
142239
  lExp = expr(target);
142112
142240
  return B.mkStmt(B.mkText(pref), B.mkInfix(lExp, "=", expr(value)));
142113
- function convertName(n) {
142241
+ }
142242
+ function convertDestructuring(parent, targets, value) {
142243
+ let nonNames = targets.elts.filter(e => e.kind !== "Name");
142244
+ if (nonNames.length) {
142245
+ error(parent, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
142246
+ return stmtTODO(parent);
142247
+ }
142248
+ const names = targets.elts.map(tryGetName);
142249
+ const symbols = names
142250
+ .map(nm => nm ? currentScope().vars[nm] : undefined);
142251
+ if (symbols.some(s => (s === null || s === void 0 ? void 0 : s.modifier) !== undefined)) {
142252
+ const helperVar = getHelperVariableName();
142253
+ const valueAssign = B.mkStmt(B.mkInfix(B.mkGroup([B.mkText("let "), B.mkText(helperVar)]), "=", expr(value)));
142254
+ const assignStatements = [valueAssign];
142255
+ for (let i = 0; i < symbols.length; i++) {
142256
+ const name = convertName(targets.elts[i]);
142257
+ assignStatements.push(B.mkStmt(B.mkInfix(name, "=", B.mkGroup([B.mkText(helperVar), B.mkText(`[${i}]`)]))));
142258
+ }
142259
+ return B.mkGroup(assignStatements);
142260
+ }
142261
+ else {
142262
+ let targs = [B.mkText("let "), B.mkText("[")];
142263
+ let tupNames = targets.elts
142264
+ .map(e => e)
142265
+ .map(e => convertName(e, true));
142266
+ targs.push(B.mkCommaSep(tupNames));
142267
+ targs.push(B.mkText("]"));
142268
+ return B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
142269
+ }
142270
+ function convertName(n, excludeLet = false) {
142114
142271
  // TODO resuse with Name expr
142115
142272
  markInfoNode(n, "identifierCompletion");
142116
142273
  typeOf(n);
142117
142274
  let v = lookupName(n);
142118
- return possibleDef(n, /*excludeLet*/ true);
142275
+ return possibleDef(n, excludeLet);
142119
142276
  }
142120
142277
  }
142121
142278
  function possibleDef(n, excludeLet = false) {
@@ -159681,6 +159838,7 @@ async function buildTargetCoreAsync(options = {}) {
159681
159838
  updateTOC(cfg);
159682
159839
  cfg.bundledpkgs = {};
159683
159840
  pxt.setAppTarget(cfg);
159841
+ pxt.reloadAppTargetVariant();
159684
159842
  dirsToWatch = cfg.bundleddirs.slice();
159685
159843
  if (pxt.appTarget.id != "core") {
159686
159844
  if (fs.existsSync("theme")) {
@@ -6747,6 +6747,22 @@ var pxt;
6747
6747
  }
6748
6748
  });
6749
6749
  }
6750
+ function validateAllReferencedBlocksExist(xml) {
6751
+ pxt.U.assert(!!(Blockly === null || Blockly === void 0 ? void 0 : Blockly.Blocks), "Called validateAllReferencedBlocksExist before initializing Blockly");
6752
+ const dom = Blockly.Xml.textToDom(xml);
6753
+ const blocks = dom.querySelectorAll("block");
6754
+ for (let i = 0; i < blocks.length; i++) {
6755
+ if (!Blockly.Blocks[blocks.item(i).getAttribute("type")])
6756
+ return false;
6757
+ }
6758
+ const shadows = dom.querySelectorAll("shadow");
6759
+ for (let i = 0; i < shadows.length; i++) {
6760
+ if (!Blockly.Blocks[shadows.item(i).getAttribute("type")])
6761
+ return false;
6762
+ }
6763
+ return true;
6764
+ }
6765
+ blocks_2.validateAllReferencedBlocksExist = validateAllReferencedBlocksExist;
6750
6766
  })(blocks = pxt.blocks || (pxt.blocks = {}));
6751
6767
  })(pxt || (pxt = {}));
6752
6768
  var pxt;
@@ -6768,6 +6784,7 @@ var pxt;
6768
6784
  const newDom = Blockly.Xml.workspaceToDom(newWs, true);
6769
6785
  pxt.Util.toArray(oldDom.childNodes)
6770
6786
  .filter((n) => n.nodeType == Node.ELEMENT_NODE && n.localName == "block" && n.getAttribute("disabled") == "true")
6787
+ .filter((n) => !!Blockly.Blocks[n.getAttribute("type")])
6771
6788
  .forEach(n => newDom.appendChild(newDom.ownerDocument.importNode(n, true)));
6772
6789
  const updatedXml = Blockly.Xml.domToText(newDom);
6773
6790
  return updatedXml;
@@ -11951,7 +11968,6 @@ var pxtblockly;
11951
11968
  this.fieldGroup_.appendChild(bg.el);
11952
11969
  const icon = new svg.Text("\uf008")
11953
11970
  .at(X_PADDING, 5 + (TOTAL_HEIGHT >> 1))
11954
- .fill(this.sourceBlock_.getColourSecondary())
11955
11971
  .setClass("semanticIcon");
11956
11972
  this.fieldGroup_.appendChild(icon.el);
11957
11973
  if (this.asset) {
@@ -12931,9 +12947,6 @@ var pxtblockly;
12931
12947
  }
12932
12948
  }
12933
12949
  containerSize.height += addedHeight;
12934
- if (this.sourceBlock_.RTL) {
12935
- Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, containerSize);
12936
- }
12937
12950
  // Position the menu.
12938
12951
  Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, containerSize, this.sourceBlock_.RTL);
12939
12952
  // (<any>scrollContainer).focus();
@@ -157,6 +157,7 @@ declare namespace pxt.blocks {
157
157
  */
158
158
  let extensionBlocklyPatch: (pkgTargetVersion: string, dom: Element) => void;
159
159
  function importXml(pkgTargetVersion: string, xml: string, info: pxtc.BlocksInfo, skipReport?: boolean): string;
160
+ function validateAllReferencedBlocksExist(xml: string): boolean;
160
161
  }
161
162
  declare namespace pxt.blocks.layout {
162
163
  interface FlowOptions {
@@ -3185,6 +3185,22 @@ var pxt;
3185
3185
  }
3186
3186
  });
3187
3187
  }
3188
+ function validateAllReferencedBlocksExist(xml) {
3189
+ pxt.U.assert(!!(Blockly === null || Blockly === void 0 ? void 0 : Blockly.Blocks), "Called validateAllReferencedBlocksExist before initializing Blockly");
3190
+ const dom = Blockly.Xml.textToDom(xml);
3191
+ const blocks = dom.querySelectorAll("block");
3192
+ for (let i = 0; i < blocks.length; i++) {
3193
+ if (!Blockly.Blocks[blocks.item(i).getAttribute("type")])
3194
+ return false;
3195
+ }
3196
+ const shadows = dom.querySelectorAll("shadow");
3197
+ for (let i = 0; i < shadows.length; i++) {
3198
+ if (!Blockly.Blocks[shadows.item(i).getAttribute("type")])
3199
+ return false;
3200
+ }
3201
+ return true;
3202
+ }
3203
+ blocks_2.validateAllReferencedBlocksExist = validateAllReferencedBlocksExist;
3188
3204
  })(blocks = pxt.blocks || (pxt.blocks = {}));
3189
3205
  })(pxt || (pxt = {}));
3190
3206
  var pxt;
@@ -3206,6 +3222,7 @@ var pxt;
3206
3222
  const newDom = Blockly.Xml.workspaceToDom(newWs, true);
3207
3223
  pxt.Util.toArray(oldDom.childNodes)
3208
3224
  .filter((n) => n.nodeType == Node.ELEMENT_NODE && n.localName == "block" && n.getAttribute("disabled") == "true")
3225
+ .filter((n) => !!Blockly.Blocks[n.getAttribute("type")])
3209
3226
  .forEach(n => newDom.appendChild(newDom.ownerDocument.importNode(n, true)));
3210
3227
  const updatedXml = Blockly.Xml.domToText(newDom);
3211
3228
  return updatedXml;
@@ -8389,7 +8406,6 @@ var pxtblockly;
8389
8406
  this.fieldGroup_.appendChild(bg.el);
8390
8407
  const icon = new svg.Text("\uf008")
8391
8408
  .at(X_PADDING, 5 + (TOTAL_HEIGHT >> 1))
8392
- .fill(this.sourceBlock_.getColourSecondary())
8393
8409
  .setClass("semanticIcon");
8394
8410
  this.fieldGroup_.appendChild(icon.el);
8395
8411
  if (this.asset) {
@@ -9369,9 +9385,6 @@ var pxtblockly;
9369
9385
  }
9370
9386
  }
9371
9387
  containerSize.height += addedHeight;
9372
- if (this.sourceBlock_.RTL) {
9373
- Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, containerSize);
9374
- }
9375
9388
  // Position the menu.
9376
9389
  Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, containerSize, this.sourceBlock_.RTL);
9377
9390
  // (<any>scrollContainer).focus();
@@ -121,6 +121,7 @@ declare namespace ts.pxtc {
121
121
  private emitFieldAccess;
122
122
  private writeFailBranch;
123
123
  private emitClassCall;
124
+ private helperObject;
124
125
  private emitBindHelper;
125
126
  private ifaceCallCore;
126
127
  private emitIfaceCall;