pxt-core 7.4.26 → 7.5.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.
Files changed (40) hide show
  1. package/built/cli.js +57 -5
  2. package/built/pxt.js +194 -11
  3. package/built/pxtblockly.js +83 -32
  4. package/built/pxtblocks.d.ts +1 -0
  5. package/built/pxtblocks.js +83 -32
  6. package/built/pxtcompiler.js +42 -4
  7. package/built/pxtlib.d.ts +2 -0
  8. package/built/pxtlib.js +22 -0
  9. package/built/pxtpy.js +73 -2
  10. package/built/server.js +4 -0
  11. package/built/target.js +1 -1
  12. package/built/web/main.js +1 -1
  13. package/built/web/pxtapp.js +1 -1
  14. package/built/web/pxtasseteditor.js +1 -1
  15. package/built/web/pxtblockly.js +2 -2
  16. package/built/web/pxtblocks.js +1 -1
  17. package/built/web/pxtcompiler.js +1 -1
  18. package/built/web/pxtembed.js +2 -2
  19. package/built/web/pxtlib.js +1 -1
  20. package/built/web/pxtpy.js +1 -1
  21. package/built/web/pxtworker.js +1 -1
  22. package/built/web/react-common-authcode.css +6008 -0
  23. package/built/web/react-common-skillmap.css +1 -1
  24. package/built/web/rtlreact-common-skillmap.css +1 -1
  25. package/built/web/rtlsemantic.css +1 -1
  26. package/built/web/semantic.css +1 -1
  27. package/common-docs/faq.md +1 -1
  28. package/common-docs/translate.md +2 -2
  29. package/package.json +2 -2
  30. package/react-common/components/controls/EditorToggle.tsx +109 -0
  31. package/react-common/styles/controls/Button.less +4 -0
  32. package/react-common/styles/controls/EditorToggle.less +233 -0
  33. package/react-common/styles/profile/profile.less +2 -2
  34. package/react-common/styles/react-common-authcode-core.less +10 -0
  35. package/react-common/styles/react-common-authcode.less +12 -0
  36. package/react-common/styles/react-common-variables.less +24 -0
  37. package/react-common/styles/react-common.less +1 -0
  38. package/theme/common.less +5 -0
  39. package/theme/image-editor/imageEditor.less +7 -116
  40. package/webapp/public/authcode.html +1 -0
package/built/cli.js CHANGED
@@ -342,7 +342,8 @@ function pxtFileList(pref) {
342
342
  .concat(onlyExts(nodeutil.allFiles(pref + "built/web", 1), [".js", ".css"]))
343
343
  .concat(nodeutil.allFiles(pref + "built/web/fonts", 1))
344
344
  .concat(nodeutil.allFiles(pref + "built/web/vs", 4))
345
- .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4));
345
+ .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4))
346
+ .concat(nodeutil.allFiles(pref + "built/web/authcode", 4));
346
347
  }
347
348
  function semverCmp(a, b) {
348
349
  let parse = (s) => {
@@ -422,7 +423,8 @@ function ciAsync() {
422
423
  p = p
423
424
  .then(() => buildWebStringsAsync())
424
425
  .then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
425
- .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"));
426
+ .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
427
+ .then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"));
426
428
  if (uploadApiStrings)
427
429
  p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
428
430
  if (uploadDocs || uploadApiStrings)
@@ -940,6 +942,7 @@ function uploadCoreAsync(opts) {
940
942
  "multiUrl": opts.localDir + "multi.html",
941
943
  "asseteditorUrl": opts.localDir + "asseteditor.html",
942
944
  "skillmapUrl": opts.localDir + "skillmap.html",
945
+ "authcodeUrl": opts.localDir + "authcode.html",
943
946
  "isStatic": true,
944
947
  };
945
948
  const targetImagePaths = targetImages.map(k => `${opts.localDir}${path.join('./docs', logos[k])}`);
@@ -985,13 +988,15 @@ function uploadCoreAsync(opts) {
985
988
  "workerConfig.js",
986
989
  "multi.html",
987
990
  "asseteditor.html",
988
- "skillmap.html"
991
+ "skillmap.html",
992
+ "authcode.html"
989
993
  ];
990
994
  // expandHtml is manually called on these files before upload
991
995
  // runs <!-- @include --> substitutions, fills in locale, etc
992
996
  let expandFiles = [
993
997
  "index.html",
994
- "skillmap.html"
998
+ "skillmap.html",
999
+ "authcode.html"
995
1000
  ];
996
1001
  nodeutil.mkdirP("built/uploadrepl");
997
1002
  function encodeURLs(urls) {
@@ -1785,7 +1790,7 @@ async function buildSemanticUIAsync(parsed) {
1785
1790
  ]
1786
1791
  });
1787
1792
  }
1788
- // Generate react-common css for skillmap
1793
+ // Generate react-common css for skillmap and authcode
1789
1794
  const skillmapFile = isPxtCore ? "react-common/styles/react-common-skillmap-core.less" :
1790
1795
  "node_modules/pxt-core/react-common/styles/react-common-skillmap.less";
1791
1796
  await nodeutil.spawnAsync({
@@ -1797,6 +1802,17 @@ async function buildSemanticUIAsync(parsed) {
1797
1802
  "--include-path=" + lessIncludePaths
1798
1803
  ]
1799
1804
  });
1805
+ const authcodeFile = isPxtCore ? "react-common/styles/react-common-authcode-core.less" :
1806
+ "node_modules/pxt-core/react-common/styles/react-common-authcode.less";
1807
+ await nodeutil.spawnAsync({
1808
+ cmd: "node",
1809
+ args: [
1810
+ lessCPath,
1811
+ authcodeFile,
1812
+ "built/web/react-common-authcode.css",
1813
+ "--include-path=" + lessIncludePaths
1814
+ ]
1815
+ });
1800
1816
  let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
1801
1817
  skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
1802
1818
  skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
@@ -1890,6 +1906,31 @@ function buildSkillMapAsync(parsed) {
1890
1906
  });
1891
1907
  });
1892
1908
  }
1909
+ function buildAuthcodeAsync(parsed) {
1910
+ // local serve
1911
+ const appRoot = "node_modules/pxt-core/authcode";
1912
+ return rimrafAsync(`${appRoot}/public/blb`, {})
1913
+ .then(() => rimrafAsync(`${appRoot}/build/assets`, {}))
1914
+ .then(() => rimrafAsync(`${appRoot}/public/docs`, {}))
1915
+ .then(() => rimrafAsync(`${appRoot}/public/static`, {}))
1916
+ .then(() => {
1917
+ // read pxtarget.json, save into 'pxtTargetBundle' global variable
1918
+ let cfg = readLocalPxTarget();
1919
+ nodeutil.writeFileSync(`${appRoot}/public/blb/target.js`, "// eslint-disable-next-line \n" + targetJsPrefix + JSON.stringify(cfg));
1920
+ nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${appRoot}/public/blb`);
1921
+ nodeutil.cp("built/web/semantic.css", `${appRoot}/public/blb`);
1922
+ nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${appRoot}/public/blb`);
1923
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common-authcode.css", `${appRoot}/public/blb`);
1924
+ // copy 'assets' over from docs/static
1925
+ nodeutil.cpR("docs/static/authcode/assets", `${appRoot}/public/assets`);
1926
+ return nodeutil.spawnAsync({
1927
+ cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
1928
+ args: ["run-script", "start"],
1929
+ cwd: appRoot,
1930
+ shell: true
1931
+ });
1932
+ });
1933
+ }
1893
1934
  function updateDefaultProjects(cfg) {
1894
1935
  let defaultProjects = [
1895
1936
  pxt.BLOCKS_PROJECT_NAME,
@@ -6252,6 +6293,17 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
6252
6293
  }
6253
6294
  }
6254
6295
  }, buildSkillMapAsync);
6296
+ p.defineCommand({
6297
+ name: "buildauthcode",
6298
+ aliases: ["authcode"],
6299
+ advanced: true,
6300
+ help: "Serves the authcode webapp",
6301
+ flags: {
6302
+ serve: {
6303
+ description: "Serve the authcode app locally after building (npm start)"
6304
+ }
6305
+ }
6306
+ }, buildAuthcodeAsync);
6255
6307
  advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
6256
6308
  advancedCommand("crowdin", "upload, download, clean, stats files to/from crowdin", pc => crowdin.execCrowdinAsync.apply(undefined, pc.args), "<cmd> <path> [output]");
6257
6309
  advancedCommand("hidlist", "list HID devices", hid.listAsync);
package/built/pxt.js CHANGED
@@ -101595,6 +101595,25 @@ var pxt;
101595
101595
  });
101596
101596
  }
101597
101597
  blocks.hasHandler = hasHandler;
101598
+ function getHelpUrl(fn) {
101599
+ if (fn.attributes.help) {
101600
+ const helpUrl = fn.attributes.help.replace(/^\//, '');
101601
+ if (/^github:/.test(helpUrl)) {
101602
+ return helpUrl;
101603
+ }
101604
+ else if (helpUrl !== "none") {
101605
+ return "/reference/" + helpUrl;
101606
+ }
101607
+ }
101608
+ else if (fn.pkg && !pxt.appTarget.bundledpkgs[fn.pkg]) { // added package
101609
+ let anchor = fn.qName.toLowerCase().split('.');
101610
+ if (anchor[0] == fn.pkg)
101611
+ anchor.shift();
101612
+ return `/pkg/${fn.pkg}#${encodeURIComponent(anchor.join('-'))}`;
101613
+ }
101614
+ return undefined;
101615
+ }
101616
+ blocks.getHelpUrl = getHelpUrl;
101598
101617
  /**
101599
101618
  * Returns which Blockly block type to use for an argument reporter based
101600
101619
  * on the specified TypeScript type.
@@ -101606,6 +101625,9 @@ var pxt;
101606
101625
  if (varType === "boolean" || varType === "number" || varType === "string") {
101607
101626
  reporterType = `argument_reporter_${varType}`;
101608
101627
  }
101628
+ if (/^(?:Array<(?:.+)>)|(?:(?:.+)\[\])$/.test(varType)) {
101629
+ reporterType = "argument_reporter_array";
101630
+ }
101609
101631
  return reporterType;
101610
101632
  }
101611
101633
  blocks.reporterTypeForArgType = reporterTypeForArgType;
@@ -125490,6 +125512,8 @@ ${output}</xml>`;
125490
125512
  return getTaggedTemplateExpression(n);
125491
125513
  case SK.CallExpression:
125492
125514
  return getStatementBlock(n, undefined, undefined, true);
125515
+ case SK.AsExpression:
125516
+ return getOutputBlock(n.expression);
125493
125517
  default:
125494
125518
  error(n, pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]));
125495
125519
  break;
@@ -126370,11 +126394,14 @@ ${output}</xml>`;
126370
126394
  r.mutationChildren = [];
126371
126395
  n.parameters.forEach(p => {
126372
126396
  const paramName = p.name.getText();
126397
+ let type = normalizeType(p.type.getText());
126398
+ if (pxt.U.endsWith(type, "[]"))
126399
+ type = "Array";
126373
126400
  r.mutationChildren.push({
126374
126401
  nodeName: "arg",
126375
126402
  attributes: {
126376
126403
  name: paramName,
126377
- type: p.type.getText(),
126404
+ type,
126378
126405
  id: env.functionParamIds[name][paramName]
126379
126406
  }
126380
126407
  });
@@ -126450,11 +126477,14 @@ ${output}</xml>`;
126450
126477
  env.declaredFunctions[name].parameters.forEach((p, i) => {
126451
126478
  const paramName = p.name.getText();
126452
126479
  const argId = env.functionParamIds[name][paramName];
126480
+ let type = normalizeType(p.type.getText());
126481
+ if (pxt.U.endsWith(type, "[]"))
126482
+ type = "Array";
126453
126483
  r.mutationChildren.push({
126454
126484
  nodeName: "arg",
126455
126485
  attributes: {
126456
126486
  name: paramName,
126457
- type: p.type.getText(),
126487
+ type: type,
126458
126488
  id: argId
126459
126489
  }
126460
126490
  });
@@ -127322,7 +127352,8 @@ ${output}</xml>`;
127322
127352
  if (!type) {
127323
127353
  return pxtc.Util.lf("Function parameters must declare a type");
127324
127354
  }
127325
- if (env.opts.allowedArgumentTypes.indexOf(normalizeType(type)) === -1) {
127355
+ const normalized = normalizeType(type);
127356
+ if (env.opts.allowedArgumentTypes.indexOf(normalized) === -1 && !pxtc.U.endsWith(normalized, "[]")) {
127326
127357
  return pxtc.Util.lf("Only types that can be added in blocks can be used for function arguments");
127327
127358
  }
127328
127359
  }
@@ -127597,6 +127628,8 @@ ${output}</xml>`;
127597
127628
  return checkStatement(n, env, true, undefined);
127598
127629
  case SK.TaggedTemplateExpression:
127599
127630
  return checkTaggedTemplateExpression(n, env);
127631
+ case SK.AsExpression:
127632
+ return checkAsExpression(n);
127600
127633
  }
127601
127634
  return pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]);
127602
127635
  function checkStringLiteral(n) {
@@ -127693,6 +127726,31 @@ ${output}</xml>`;
127693
127726
  // The compiler will have already caught any invalid tags or templates
127694
127727
  return undefined;
127695
127728
  }
127729
+ function checkAsExpression(n) {
127730
+ // The only time we allow casts to decompile is in the very special case where someone has
127731
+ // written a program comparing two string, boolean, or numeric literals in blocks and
127732
+ // converted to text. e.g. 3 == 5 or true != false
127733
+ if (n.type.getText().trim() === "any" && (ts.isStringOrNumericLiteral(n.expression) ||
127734
+ n.expression.kind === SK.TrueKeyword || n.expression.kind === SK.FalseKeyword)) {
127735
+ const [parent] = getParent(n);
127736
+ if (parent.kind === SK.BinaryExpression) {
127737
+ switch (parent.operatorToken.kind) {
127738
+ case SK.EqualsEqualsToken:
127739
+ case SK.EqualsEqualsEqualsToken:
127740
+ case SK.ExclamationEqualsToken:
127741
+ case SK.ExclamationEqualsEqualsToken:
127742
+ case SK.LessThanToken:
127743
+ case SK.LessThanEqualsToken:
127744
+ case SK.GreaterThanToken:
127745
+ case SK.GreaterThanEqualsToken:
127746
+ return undefined;
127747
+ default:
127748
+ break;
127749
+ }
127750
+ }
127751
+ }
127752
+ return pxtc.Util.lf("Casting not supported in blocks");
127753
+ }
127696
127754
  function getParent(node) {
127697
127755
  if (!node.parent) {
127698
127756
  return [undefined, node];
@@ -133485,8 +133543,10 @@ ${lbl}: .short 0xffff
133485
133543
  return needsNumberConversions() ? pxtc.ir.rtcall("pxt::toInt", [e]) : e;
133486
133544
  };
133487
133545
  // c = a[i]
133488
- if (iterVar)
133546
+ if (iterVar) {
133489
133547
  proc.emitExpr(iterVar.storeByRef(pxtc.ir.rtcall(indexer, [collectionVar.loadCore(), toInt(intVarIter.loadCore())])));
133548
+ emitBrk(node.initializer);
133549
+ }
133490
133550
  flushHoistedFunctionDefinitions();
133491
133551
  emit(node.statement);
133492
133552
  proc.emitLblDirect(l.cont);
@@ -140954,6 +141014,14 @@ var pxt;
140954
141014
  FloorDiv: 1,
140955
141015
  Mult: 1, // this can be also used on strings and arrays, but let's ignore that for now
140956
141016
  };
141017
+ const arithmeticCompareOps = {
141018
+ Eq: 1,
141019
+ NotEq: 1,
141020
+ Lt: 1,
141021
+ LtE: 1,
141022
+ Gt: 1,
141023
+ GtE: 1
141024
+ };
140957
141025
  const opMapping = {
140958
141026
  Add: "+",
140959
141027
  Sub: "-",
@@ -141825,9 +141893,24 @@ var pxt;
141825
141893
  let idx = B.mkInfix(expr(n.comparators[0]), ".", B.H.mkCall("indexOf", [expr(n.left)]));
141826
141894
  return B.mkInfix(idx, n.ops[0] == "In" ? ">=" : "<", B.mkText("0"));
141827
141895
  }
141828
- let r = binop(expr(n.left), n.ops[0], expr(n.comparators[0]));
141896
+ let left = expr(n.left);
141897
+ let right = expr(n.comparators[0]);
141898
+ // Special handling for comparisons of literal types, e.g. 0 === 5
141899
+ const castIfLiteralComparison = (op, leftExpr, rightExpr) => {
141900
+ if (arithmeticCompareOps[op]) {
141901
+ if (isNumStringOrBool(leftExpr) && isNumStringOrBool(rightExpr) && B.flattenNode([left]) !== B.flattenNode([right])) {
141902
+ left = B.H.mkParenthesizedExpression(B.mkGroup([left, B.mkText(" as any")]));
141903
+ right = B.H.mkParenthesizedExpression(B.mkGroup([right, B.mkText(" as any")]));
141904
+ }
141905
+ }
141906
+ };
141907
+ castIfLiteralComparison(n.ops[0], n.left, n.comparators[0]);
141908
+ let r = binop(left, n.ops[0], right);
141829
141909
  for (let i = 1; i < n.ops.length; ++i) {
141830
- r = binop(r, "And", binop(expr(n.comparators[i - 1]), n.ops[i], expr(n.comparators[i])));
141910
+ left = expr(n.comparators[i - 1]);
141911
+ right = expr(n.comparators[i]);
141912
+ castIfLiteralComparison(n.ops[i], n.comparators[i - 1], n.comparators[i]);
141913
+ r = binop(r, "And", binop(left, n.ops[i], right));
141831
141914
  }
141832
141915
  return r;
141833
141916
  },
@@ -142615,6 +142698,16 @@ var pxt;
142615
142698
  const t = canonicalize(typeOf(expr));
142616
142699
  return t && t.primType === "@array";
142617
142700
  }
142701
+ function isNumStringOrBool(expr) {
142702
+ switch (expr.kind) {
142703
+ case "Num":
142704
+ case "Str":
142705
+ return true;
142706
+ case "NameConstant":
142707
+ return expr.value !== null;
142708
+ }
142709
+ return false;
142710
+ }
142618
142711
  function buildOverride(override, args, recv) {
142619
142712
  const result = [];
142620
142713
  for (const part of override.parts) {
@@ -145986,6 +146079,42 @@ var pxt;
145986
146079
  }
145987
146080
  return fn(s);
145988
146081
  }
146082
+ function getParent(node) {
146083
+ if (!node.parent) {
146084
+ return undefined;
146085
+ }
146086
+ else if (node.parent.kind === ts.SyntaxKind.ParenthesizedExpression) {
146087
+ return getParent(node.parent);
146088
+ }
146089
+ else {
146090
+ return node.parent;
146091
+ }
146092
+ }
146093
+ function isDecompilableAsExpression(n) {
146094
+ // The only time we allow casts to decompile is in the very special case where someone has
146095
+ // written a program comparing two string, boolean, or numeric literals in blocks and
146096
+ // converted to text. e.g. 3 == 5 or true != false
146097
+ if (n.type.getText().trim() === "any" && (ts.isNumericLiteral(n.expression) || ts.isStringLiteral(n.expression) ||
146098
+ n.expression.kind === ts.SyntaxKind.TrueKeyword || n.expression.kind === ts.SyntaxKind.FalseKeyword)) {
146099
+ const parent = getParent(n);
146100
+ if ((parent === null || parent === void 0 ? void 0 : parent.kind) === ts.SyntaxKind.BinaryExpression) {
146101
+ switch (parent.operatorToken.kind) {
146102
+ case ts.SyntaxKind.EqualsEqualsToken:
146103
+ case ts.SyntaxKind.EqualsEqualsEqualsToken:
146104
+ case ts.SyntaxKind.ExclamationEqualsToken:
146105
+ case ts.SyntaxKind.ExclamationEqualsEqualsToken:
146106
+ case ts.SyntaxKind.LessThanToken:
146107
+ case ts.SyntaxKind.LessThanEqualsToken:
146108
+ case ts.SyntaxKind.GreaterThanToken:
146109
+ case ts.SyntaxKind.GreaterThanEqualsToken:
146110
+ return true;
146111
+ default:
146112
+ break;
146113
+ }
146114
+ }
146115
+ }
146116
+ return false;
146117
+ }
145989
146118
  function isConstExp(s) {
145990
146119
  let isConst = (s) => {
145991
146120
  switch (s.kind) {
@@ -146068,6 +146197,8 @@ var pxt;
146068
146197
  return asExpRes(s.getText());
146069
146198
  if (ts.isConditionalExpression(s))
146070
146199
  return emitCondExp(s);
146200
+ if (ts.isAsExpression(s) && isDecompilableAsExpression(s))
146201
+ return emitExp(s.expression);
146071
146202
  // TODO handle more expressions
146072
146203
  pxt.tickEvent("depython.todo.expression", { kind: s.kind });
146073
146204
  // return asExpRes(s.getText(), ["# unknown expression: " + s.kind]) // uncomment for easier locating
@@ -156292,7 +156423,8 @@ function pxtFileList(pref) {
156292
156423
  .concat(onlyExts(nodeutil.allFiles(pref + "built/web", 1), [".js", ".css"]))
156293
156424
  .concat(nodeutil.allFiles(pref + "built/web/fonts", 1))
156294
156425
  .concat(nodeutil.allFiles(pref + "built/web/vs", 4))
156295
- .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4));
156426
+ .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4))
156427
+ .concat(nodeutil.allFiles(pref + "built/web/authcode", 4));
156296
156428
  }
156297
156429
  function semverCmp(a, b) {
156298
156430
  let parse = (s) => {
@@ -156372,7 +156504,8 @@ function ciAsync() {
156372
156504
  p = p
156373
156505
  .then(() => buildWebStringsAsync())
156374
156506
  .then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
156375
- .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"));
156507
+ .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
156508
+ .then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"));
156376
156509
  if (uploadApiStrings)
156377
156510
  p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
156378
156511
  if (uploadDocs || uploadApiStrings)
@@ -156890,6 +157023,7 @@ function uploadCoreAsync(opts) {
156890
157023
  "multiUrl": opts.localDir + "multi.html",
156891
157024
  "asseteditorUrl": opts.localDir + "asseteditor.html",
156892
157025
  "skillmapUrl": opts.localDir + "skillmap.html",
157026
+ "authcodeUrl": opts.localDir + "authcode.html",
156893
157027
  "isStatic": true,
156894
157028
  };
156895
157029
  const targetImagePaths = targetImages.map(k => `${opts.localDir}${path.join('./docs', logos[k])}`);
@@ -156935,13 +157069,15 @@ function uploadCoreAsync(opts) {
156935
157069
  "workerConfig.js",
156936
157070
  "multi.html",
156937
157071
  "asseteditor.html",
156938
- "skillmap.html"
157072
+ "skillmap.html",
157073
+ "authcode.html"
156939
157074
  ];
156940
157075
  // expandHtml is manually called on these files before upload
156941
157076
  // runs <!-- @include --> substitutions, fills in locale, etc
156942
157077
  let expandFiles = [
156943
157078
  "index.html",
156944
- "skillmap.html"
157079
+ "skillmap.html",
157080
+ "authcode.html"
156945
157081
  ];
156946
157082
  nodeutil.mkdirP("built/uploadrepl");
156947
157083
  function encodeURLs(urls) {
@@ -157735,7 +157871,7 @@ async function buildSemanticUIAsync(parsed) {
157735
157871
  ]
157736
157872
  });
157737
157873
  }
157738
- // Generate react-common css for skillmap
157874
+ // Generate react-common css for skillmap and authcode
157739
157875
  const skillmapFile = isPxtCore ? "react-common/styles/react-common-skillmap-core.less" :
157740
157876
  "node_modules/pxt-core/react-common/styles/react-common-skillmap.less";
157741
157877
  await nodeutil.spawnAsync({
@@ -157747,6 +157883,17 @@ async function buildSemanticUIAsync(parsed) {
157747
157883
  "--include-path=" + lessIncludePaths
157748
157884
  ]
157749
157885
  });
157886
+ const authcodeFile = isPxtCore ? "react-common/styles/react-common-authcode-core.less" :
157887
+ "node_modules/pxt-core/react-common/styles/react-common-authcode.less";
157888
+ await nodeutil.spawnAsync({
157889
+ cmd: "node",
157890
+ args: [
157891
+ lessCPath,
157892
+ authcodeFile,
157893
+ "built/web/react-common-authcode.css",
157894
+ "--include-path=" + lessIncludePaths
157895
+ ]
157896
+ });
157750
157897
  let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
157751
157898
  skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
157752
157899
  skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
@@ -157840,6 +157987,31 @@ function buildSkillMapAsync(parsed) {
157840
157987
  });
157841
157988
  });
157842
157989
  }
157990
+ function buildAuthcodeAsync(parsed) {
157991
+ // local serve
157992
+ const appRoot = "node_modules/pxt-core/authcode";
157993
+ return rimrafAsync(`${appRoot}/public/blb`, {})
157994
+ .then(() => rimrafAsync(`${appRoot}/build/assets`, {}))
157995
+ .then(() => rimrafAsync(`${appRoot}/public/docs`, {}))
157996
+ .then(() => rimrafAsync(`${appRoot}/public/static`, {}))
157997
+ .then(() => {
157998
+ // read pxtarget.json, save into 'pxtTargetBundle' global variable
157999
+ let cfg = readLocalPxTarget();
158000
+ nodeutil.writeFileSync(`${appRoot}/public/blb/target.js`, "// eslint-disable-next-line \n" + targetJsPrefix + JSON.stringify(cfg));
158001
+ nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${appRoot}/public/blb`);
158002
+ nodeutil.cp("built/web/semantic.css", `${appRoot}/public/blb`);
158003
+ nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${appRoot}/public/blb`);
158004
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common-authcode.css", `${appRoot}/public/blb`);
158005
+ // copy 'assets' over from docs/static
158006
+ nodeutil.cpR("docs/static/authcode/assets", `${appRoot}/public/assets`);
158007
+ return nodeutil.spawnAsync({
158008
+ cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
158009
+ args: ["run-script", "start"],
158010
+ cwd: appRoot,
158011
+ shell: true
158012
+ });
158013
+ });
158014
+ }
157843
158015
  function updateDefaultProjects(cfg) {
157844
158016
  let defaultProjects = [
157845
158017
  pxt.BLOCKS_PROJECT_NAME,
@@ -162202,6 +162374,17 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
162202
162374
  }
162203
162375
  }
162204
162376
  }, buildSkillMapAsync);
162377
+ p.defineCommand({
162378
+ name: "buildauthcode",
162379
+ aliases: ["authcode"],
162380
+ advanced: true,
162381
+ help: "Serves the authcode webapp",
162382
+ flags: {
162383
+ serve: {
162384
+ description: "Serve the authcode app locally after building (npm start)"
162385
+ }
162386
+ }
162387
+ }, buildAuthcodeAsync);
162205
162388
  advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
162206
162389
  advancedCommand("crowdin", "upload, download, clean, stats files to/from crowdin", pc => crowdin.execCrowdinAsync.apply(undefined, pc.args), "<cmd> <path> [output]");
162207
162390
  advancedCommand("hidlist", "list HID devices", hid.listAsync);