pxt-core 9.3.15 → 9.3.16

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 (38) hide show
  1. package/built/pxt.js +4 -0
  2. package/built/pxtblockly.js +9 -144
  3. package/built/pxtblocks.d.ts +1 -75
  4. package/built/pxtblocks.js +9 -144
  5. package/built/pxtlib.js +4 -0
  6. package/built/target.js +1 -1
  7. package/built/web/ai.2.min.js +2 -2
  8. package/built/web/kiosk/js/{main.7adb39f2.js → main.b063ad50.js} +2 -2
  9. package/built/web/main.js +1 -1
  10. package/built/web/multiplayer/js/{main.75ca8c58.js → main.a1b27286.js} +2 -2
  11. package/built/web/pxtapp.js +1 -1
  12. package/built/web/pxtasseteditor.js +1 -1
  13. package/built/web/pxtblockly.js +2 -2
  14. package/built/web/pxtblocks.js +1 -1
  15. package/built/web/pxtembed.js +2 -2
  16. package/built/web/pxtlib.js +1 -1
  17. package/built/web/pxtworker.js +1 -1
  18. package/built/web/rtlsemantic.css +1 -1
  19. package/built/web/runnerembed.js +1 -1
  20. package/built/web/semantic.css +1 -1
  21. package/built/web/skillmap/js/{main.236bd49e.js → main.2ff12e87.js} +2 -2
  22. package/built/web/teachertool/css/main.4df9c5c6.css +1 -0
  23. package/built/web/teachertool/js/main.6089b626.js +2 -0
  24. package/common-docs/teachertool/catalog-shared.json +58 -0
  25. package/common-docs/teachertool/test/catalog-shared.json +40 -0
  26. package/common-docs/teachertool/test/validator-plans-shared.json +17 -0
  27. package/common-docs/teachertool/validator-plans-shared.json +155 -0
  28. package/localtypings/pxteditor.d.ts +2 -0
  29. package/localtypings/validatorPlan.d.ts +49 -0
  30. package/package.json +1 -1
  31. package/react-common/components/controls/Button.tsx +4 -1
  32. package/theme/themepacks.less +9 -0
  33. package/webapp/public/kiosk.html +1 -1
  34. package/webapp/public/multiplayer.html +1 -1
  35. package/webapp/public/skillmap.html +1 -1
  36. package/webapp/public/teachertool.html +1 -1
  37. package/built/web/teachertool/css/main.e9386f28.css +0 -1
  38. package/built/web/teachertool/js/main.8aa6604c.js +0 -2
package/built/pxt.js CHANGED
@@ -111066,6 +111066,8 @@ var pxt;
111066
111066
  return proj.getTransparency(16);
111067
111067
  case "myTiles.transparency8":
111068
111068
  return proj.getTransparency(8);
111069
+ case "myTiles.transparency4":
111070
+ return proj.getTransparency(4);
111069
111071
  case "myTiles.transparency32":
111070
111072
  return proj.getTransparency(32);
111071
111073
  default:
@@ -111324,6 +111326,7 @@ var pxt;
111324
111326
  sprite_1.bitmapEquals = bitmapEquals;
111325
111327
  function tileWidthToTileScale(tileWidth) {
111326
111328
  switch (tileWidth) {
111329
+ case 4: return `TileScale.Four`;
111327
111330
  case 8: return `TileScale.Eight`;
111328
111331
  case 16: return `TileScale.Sixteen`;
111329
111332
  case 32: return `TileScale.ThirtyTwo`;
@@ -111334,6 +111337,7 @@ var pxt;
111334
111337
  function tileScaleToTileWidth(tileScale) {
111335
111338
  tileScale = tileScale.replace(/\s/g, "");
111336
111339
  switch (tileScale) {
111340
+ case `TileScale.Four`: return 4;
111337
111341
  case `TileScale.Eight`: return 8;
111338
111342
  case `TileScale.Sixteen`: return 16;
111339
111343
  case `TileScale.ThirtyTwo`: return 32;
@@ -11521,149 +11521,6 @@ var pxt;
11521
11521
  blocks.initMathRoundBlock = initMathRoundBlock;
11522
11522
  })(blocks = pxt.blocks || (pxt.blocks = {}));
11523
11523
  })(pxt || (pxt = {}));
11524
- var pxt;
11525
- (function (pxt) {
11526
- var blocks;
11527
- (function (blocks) {
11528
- const maxConcurrentChecks = 4;
11529
- async function runValidatorPlanAsync(usedBlocks, plan) {
11530
- // Each plan can have multiple checks it needs to run.
11531
- // Run all of them in parallel, and then check if the number of successes is greater than the specified threshold.
11532
- // TBD if it's faster to run in parallel without short-circuiting once the threshold is reached, or if it's faster to run sequentially and short-circuit.
11533
- const startTime = Date.now();
11534
- const checkRuns = pxt.Util.promisePoolAsync(maxConcurrentChecks, plan.checks, async (check) => {
11535
- switch (check.validator) {
11536
- case "blocksExist":
11537
- return runBlocksExistValidation(usedBlocks, check);
11538
- case "blockCommentsExist":
11539
- return runValidateBlockCommentsExist(usedBlocks, check);
11540
- case "specificBlockCommentsExist":
11541
- return runValidateSpecificBlockCommentsExist(usedBlocks, check);
11542
- case "blocksInSetExist":
11543
- return runBlocksInSetExistValidation(usedBlocks, check);
11544
- default:
11545
- pxt.debug(`Unrecognized validator: ${check.validator}`);
11546
- return false;
11547
- }
11548
- });
11549
- const results = await checkRuns;
11550
- const successCount = results.filter((r) => r).length;
11551
- const passed = successCount >= plan.threshold;
11552
- pxt.tickEvent("validation.evaluation_complete", {
11553
- plan: plan.name,
11554
- durationMs: Date.now() - startTime,
11555
- passed: `${passed}`,
11556
- });
11557
- return passed;
11558
- }
11559
- blocks.runValidatorPlanAsync = runValidatorPlanAsync;
11560
- function runBlocksExistValidation(usedBlocks, inputs) {
11561
- const blockResults = blocks.validateBlocksExist({ usedBlocks, requiredBlockCounts: inputs.blockCounts });
11562
- const success = blockResults.disabledBlocks.length === 0 &&
11563
- blockResults.missingBlocks.length === 0 &&
11564
- blockResults.insufficientBlocks.length === 0;
11565
- return success;
11566
- }
11567
- function runValidateBlockCommentsExist(usedBlocks, inputs) {
11568
- const blockResults = blocks.validateBlockCommentsExist({ usedBlocks, numRequired: inputs.count });
11569
- return blockResults.passed;
11570
- }
11571
- function runValidateSpecificBlockCommentsExist(usedBlocks, inputs) {
11572
- const blockResults = blocks.validateSpecificBlockCommentsExist({ usedBlocks, blockType: inputs.blockType });
11573
- return blockResults.passed;
11574
- }
11575
- function runBlocksInSetExistValidation(usedBlocks, inputs) {
11576
- const blockResults = blocks.validateBlocksInSetExist({ usedBlocks, blockIdsToCheck: inputs.blocks, count: inputs.count });
11577
- return blockResults.passed;
11578
- }
11579
- })(blocks = pxt.blocks || (pxt.blocks = {}));
11580
- })(pxt || (pxt = {}));
11581
- var pxt;
11582
- (function (pxt) {
11583
- var blocks;
11584
- (function (blocks) {
11585
- function validateBlocksExist({ usedBlocks, requiredBlockCounts }) {
11586
- let missingBlocks = [];
11587
- let disabledBlocks = [];
11588
- let insufficientBlocks = [];
11589
- const userBlocksEnabledByType = usedBlocks === null || usedBlocks === void 0 ? void 0 : usedBlocks.reduce((acc, block) => {
11590
- acc[block.type] = (acc[block.type] || 0) + (block.isEnabled() ? 1 : 0);
11591
- return acc;
11592
- }, {});
11593
- for (const [requiredBlockId, requiredCount] of Object.entries(requiredBlockCounts || {})) {
11594
- const countForBlock = userBlocksEnabledByType[requiredBlockId];
11595
- if (countForBlock === undefined) {
11596
- // user did not use a specific block
11597
- missingBlocks.push(requiredBlockId);
11598
- }
11599
- else if (!countForBlock) {
11600
- // all instances of block are disabled
11601
- disabledBlocks.push(requiredBlockId);
11602
- }
11603
- else if (countForBlock < requiredCount) {
11604
- // instances of block exists, but not enough.
11605
- insufficientBlocks.push(requiredBlockId);
11606
- }
11607
- }
11608
- return {
11609
- missingBlocks,
11610
- disabledBlocks,
11611
- insufficientBlocks,
11612
- };
11613
- }
11614
- blocks.validateBlocksExist = validateBlocksExist;
11615
- })(blocks = pxt.blocks || (pxt.blocks = {}));
11616
- })(pxt || (pxt = {}));
11617
- var pxt;
11618
- (function (pxt) {
11619
- var blocks;
11620
- (function (blocks) {
11621
- // validates that a combination of blocks in the set satisfies the required count
11622
- // returns the blocks that make the validator pass
11623
- function validateBlocksInSetExist({ usedBlocks, blockIdsToCheck, count, requireUnique }) {
11624
- const successfulBlocks = [];
11625
- const enabledBlocks = usedBlocks.filter((block) => block.isEnabled());
11626
- for (const block of blockIdsToCheck) {
11627
- const blockInstances = enabledBlocks.filter((b) => b.type === block);
11628
- if (requireUnique && blockInstances.length >= 1) {
11629
- successfulBlocks.push(blockInstances[0]);
11630
- }
11631
- else {
11632
- successfulBlocks.push(...blockInstances);
11633
- }
11634
- }
11635
- return { successfulBlocks, passed: successfulBlocks.length >= count };
11636
- }
11637
- blocks.validateBlocksInSetExist = validateBlocksInSetExist;
11638
- })(blocks = pxt.blocks || (pxt.blocks = {}));
11639
- })(pxt || (pxt = {}));
11640
- var pxt;
11641
- (function (pxt) {
11642
- var blocks;
11643
- (function (blocks) {
11644
- // validates that one or more blocks comments are in the project
11645
- // returns the blocks that have comments for teacher tool scenario
11646
- function validateBlockCommentsExist({ usedBlocks, numRequired }) {
11647
- const commentedBlocks = usedBlocks.filter((block) => !!block.getCommentText());
11648
- return { commentedBlocks, passed: commentedBlocks.length >= numRequired };
11649
- }
11650
- blocks.validateBlockCommentsExist = validateBlockCommentsExist;
11651
- })(blocks = pxt.blocks || (pxt.blocks = {}));
11652
- })(pxt || (pxt = {}));
11653
- var pxt;
11654
- (function (pxt) {
11655
- var blocks;
11656
- (function (blocks) {
11657
- // validates that all of a specific block type have comments
11658
- // returns the blocks that do not have comments for a tutorial validation scenario
11659
- function validateSpecificBlockCommentsExist({ usedBlocks, blockType }) {
11660
- const allSpecifcBlocks = usedBlocks.filter((block) => block.type === blockType);
11661
- const uncommentedBlocks = allSpecifcBlocks.filter((block) => !block.getCommentText());
11662
- return { uncommentedBlocks, passed: uncommentedBlocks.length === 0 };
11663
- }
11664
- blocks.validateSpecificBlockCommentsExist = validateSpecificBlockCommentsExist;
11665
- })(blocks = pxt.blocks || (pxt.blocks = {}));
11666
- })(pxt || (pxt = {}));
11667
11524
  var pxtblockly;
11668
11525
  (function (pxtblockly) {
11669
11526
  class FieldBase extends Blockly.Field {
@@ -16652,6 +16509,9 @@ var pxtblockly;
16652
16509
  if (opts.tileWidth) {
16653
16510
  if (typeof opts.tileWidth === "number") {
16654
16511
  switch (opts.tileWidth) {
16512
+ case 4:
16513
+ parsed.tileWidth = 4;
16514
+ break;
16655
16515
  case 8:
16656
16516
  parsed.tileWidth = 8;
16657
16517
  break;
@@ -16666,6 +16526,10 @@ var pxtblockly;
16666
16526
  else {
16667
16527
  const tw = opts.tileWidth.trim().toLowerCase();
16668
16528
  switch (tw) {
16529
+ case "4":
16530
+ case "four":
16531
+ parsed.tileWidth = 4;
16532
+ break;
16669
16533
  case "8":
16670
16534
  case "eight":
16671
16535
  parsed.tileWidth = 8;
@@ -16729,7 +16593,7 @@ var pxtblockly;
16729
16593
  FieldTileset.cachedRevision = project.revision();
16730
16594
  FieldTileset.cachedWorkspaceId = workspace.id;
16731
16595
  const references = pxtblockly.getAllReferencedTiles(workspace);
16732
- const supportedTileWidths = [16, 8, 32];
16596
+ const supportedTileWidths = [16, 4, 8, 32];
16733
16597
  for (const width of supportedTileWidths) {
16734
16598
  const projectTiles = project.getProjectTiles(width, width === 16);
16735
16599
  if (!projectTiles)
@@ -16893,6 +16757,7 @@ var pxtblockly;
16893
16757
  switch (id) {
16894
16758
  case "myTiles.transparency16":
16895
16759
  return 1;
16760
+ case "myTiles.transparency4":
16896
16761
  case "myTiles.transparency8":
16897
16762
  case "myTiles.transparency32":
16898
16763
  return 2;
@@ -392,80 +392,6 @@ declare namespace pxt.blocks {
392
392
  declare namespace pxt.blocks {
393
393
  function initMathRoundBlock(): void;
394
394
  }
395
- declare namespace pxt.blocks {
396
- interface EvaluationResult {
397
- result: boolean;
398
- }
399
- }
400
- declare namespace pxt.blocks {
401
- function runValidatorPlanAsync(usedBlocks: Blockly.Block[], plan: ValidatorPlan): Promise<boolean>;
402
- }
403
- declare namespace pxt.blocks {
404
- function validateBlocksExist({ usedBlocks, requiredBlockCounts }: {
405
- usedBlocks: Blockly.Block[];
406
- requiredBlockCounts: pxt.Map<number>;
407
- }): {
408
- missingBlocks: string[];
409
- disabledBlocks: string[];
410
- insufficientBlocks: string[];
411
- };
412
- }
413
- declare namespace pxt.blocks {
414
- function validateBlocksInSetExist({ usedBlocks, blockIdsToCheck, count, requireUnique }: {
415
- usedBlocks: Blockly.Block[];
416
- blockIdsToCheck: string[];
417
- count: number;
418
- requireUnique?: boolean;
419
- }): {
420
- successfulBlocks: Blockly.Block[];
421
- passed: boolean;
422
- };
423
- }
424
- declare namespace pxt.blocks {
425
- function validateBlockCommentsExist({ usedBlocks, numRequired }: {
426
- usedBlocks: Blockly.Block[];
427
- numRequired: number;
428
- }): {
429
- commentedBlocks: Blockly.Block[];
430
- passed: boolean;
431
- };
432
- }
433
- declare namespace pxt.blocks {
434
- function validateSpecificBlockCommentsExist({ usedBlocks, blockType }: {
435
- usedBlocks: Blockly.Block[];
436
- blockType: string;
437
- }): {
438
- uncommentedBlocks: Blockly.Block[];
439
- passed: boolean;
440
- };
441
- }
442
- declare namespace pxt.blocks {
443
- interface ValidatorPlan {
444
- name: string;
445
- threshold: number;
446
- checks: ValidatorCheckBase[];
447
- }
448
- interface ValidatorCheckBase {
449
- validator: string;
450
- }
451
- interface BlocksExistValidatorCheck extends ValidatorCheckBase {
452
- validator: "blocksExist";
453
- blockCounts: pxt.Map<number>;
454
- }
455
- interface BlockCommentsExistValidatorCheck extends ValidatorCheckBase {
456
- validator: "blockCommentsExist";
457
- count: number;
458
- }
459
- interface SpecificBlockCommentsExistValidatorCheck extends ValidatorCheckBase {
460
- validator: "specificBlockCommentsExist";
461
- blockType: string;
462
- }
463
- interface BlocksInSetExistValidatorCheck extends ValidatorCheckBase {
464
- validator: "blocksInSetExist";
465
- blocks: string[];
466
- count: number;
467
- }
468
- }
469
395
  declare namespace pxtblockly {
470
396
  abstract class FieldBase<U> extends Blockly.Field implements Blockly.FieldCustom {
471
397
  isFieldCustom_: true;
@@ -1404,7 +1330,7 @@ declare namespace pxtblockly {
1404
1330
  initWidth: number;
1405
1331
  initHeight: number;
1406
1332
  disableResize: boolean;
1407
- tileWidth: 8 | 16 | 32;
1333
+ tileWidth: 4 | 8 | 16 | 32;
1408
1334
  filter?: string;
1409
1335
  lightMode: boolean;
1410
1336
  }
@@ -7959,149 +7959,6 @@ var pxt;
7959
7959
  blocks.initMathRoundBlock = initMathRoundBlock;
7960
7960
  })(blocks = pxt.blocks || (pxt.blocks = {}));
7961
7961
  })(pxt || (pxt = {}));
7962
- var pxt;
7963
- (function (pxt) {
7964
- var blocks;
7965
- (function (blocks) {
7966
- const maxConcurrentChecks = 4;
7967
- async function runValidatorPlanAsync(usedBlocks, plan) {
7968
- // Each plan can have multiple checks it needs to run.
7969
- // Run all of them in parallel, and then check if the number of successes is greater than the specified threshold.
7970
- // TBD if it's faster to run in parallel without short-circuiting once the threshold is reached, or if it's faster to run sequentially and short-circuit.
7971
- const startTime = Date.now();
7972
- const checkRuns = pxt.Util.promisePoolAsync(maxConcurrentChecks, plan.checks, async (check) => {
7973
- switch (check.validator) {
7974
- case "blocksExist":
7975
- return runBlocksExistValidation(usedBlocks, check);
7976
- case "blockCommentsExist":
7977
- return runValidateBlockCommentsExist(usedBlocks, check);
7978
- case "specificBlockCommentsExist":
7979
- return runValidateSpecificBlockCommentsExist(usedBlocks, check);
7980
- case "blocksInSetExist":
7981
- return runBlocksInSetExistValidation(usedBlocks, check);
7982
- default:
7983
- pxt.debug(`Unrecognized validator: ${check.validator}`);
7984
- return false;
7985
- }
7986
- });
7987
- const results = await checkRuns;
7988
- const successCount = results.filter((r) => r).length;
7989
- const passed = successCount >= plan.threshold;
7990
- pxt.tickEvent("validation.evaluation_complete", {
7991
- plan: plan.name,
7992
- durationMs: Date.now() - startTime,
7993
- passed: `${passed}`,
7994
- });
7995
- return passed;
7996
- }
7997
- blocks.runValidatorPlanAsync = runValidatorPlanAsync;
7998
- function runBlocksExistValidation(usedBlocks, inputs) {
7999
- const blockResults = blocks.validateBlocksExist({ usedBlocks, requiredBlockCounts: inputs.blockCounts });
8000
- const success = blockResults.disabledBlocks.length === 0 &&
8001
- blockResults.missingBlocks.length === 0 &&
8002
- blockResults.insufficientBlocks.length === 0;
8003
- return success;
8004
- }
8005
- function runValidateBlockCommentsExist(usedBlocks, inputs) {
8006
- const blockResults = blocks.validateBlockCommentsExist({ usedBlocks, numRequired: inputs.count });
8007
- return blockResults.passed;
8008
- }
8009
- function runValidateSpecificBlockCommentsExist(usedBlocks, inputs) {
8010
- const blockResults = blocks.validateSpecificBlockCommentsExist({ usedBlocks, blockType: inputs.blockType });
8011
- return blockResults.passed;
8012
- }
8013
- function runBlocksInSetExistValidation(usedBlocks, inputs) {
8014
- const blockResults = blocks.validateBlocksInSetExist({ usedBlocks, blockIdsToCheck: inputs.blocks, count: inputs.count });
8015
- return blockResults.passed;
8016
- }
8017
- })(blocks = pxt.blocks || (pxt.blocks = {}));
8018
- })(pxt || (pxt = {}));
8019
- var pxt;
8020
- (function (pxt) {
8021
- var blocks;
8022
- (function (blocks) {
8023
- function validateBlocksExist({ usedBlocks, requiredBlockCounts }) {
8024
- let missingBlocks = [];
8025
- let disabledBlocks = [];
8026
- let insufficientBlocks = [];
8027
- const userBlocksEnabledByType = usedBlocks === null || usedBlocks === void 0 ? void 0 : usedBlocks.reduce((acc, block) => {
8028
- acc[block.type] = (acc[block.type] || 0) + (block.isEnabled() ? 1 : 0);
8029
- return acc;
8030
- }, {});
8031
- for (const [requiredBlockId, requiredCount] of Object.entries(requiredBlockCounts || {})) {
8032
- const countForBlock = userBlocksEnabledByType[requiredBlockId];
8033
- if (countForBlock === undefined) {
8034
- // user did not use a specific block
8035
- missingBlocks.push(requiredBlockId);
8036
- }
8037
- else if (!countForBlock) {
8038
- // all instances of block are disabled
8039
- disabledBlocks.push(requiredBlockId);
8040
- }
8041
- else if (countForBlock < requiredCount) {
8042
- // instances of block exists, but not enough.
8043
- insufficientBlocks.push(requiredBlockId);
8044
- }
8045
- }
8046
- return {
8047
- missingBlocks,
8048
- disabledBlocks,
8049
- insufficientBlocks,
8050
- };
8051
- }
8052
- blocks.validateBlocksExist = validateBlocksExist;
8053
- })(blocks = pxt.blocks || (pxt.blocks = {}));
8054
- })(pxt || (pxt = {}));
8055
- var pxt;
8056
- (function (pxt) {
8057
- var blocks;
8058
- (function (blocks) {
8059
- // validates that a combination of blocks in the set satisfies the required count
8060
- // returns the blocks that make the validator pass
8061
- function validateBlocksInSetExist({ usedBlocks, blockIdsToCheck, count, requireUnique }) {
8062
- const successfulBlocks = [];
8063
- const enabledBlocks = usedBlocks.filter((block) => block.isEnabled());
8064
- for (const block of blockIdsToCheck) {
8065
- const blockInstances = enabledBlocks.filter((b) => b.type === block);
8066
- if (requireUnique && blockInstances.length >= 1) {
8067
- successfulBlocks.push(blockInstances[0]);
8068
- }
8069
- else {
8070
- successfulBlocks.push(...blockInstances);
8071
- }
8072
- }
8073
- return { successfulBlocks, passed: successfulBlocks.length >= count };
8074
- }
8075
- blocks.validateBlocksInSetExist = validateBlocksInSetExist;
8076
- })(blocks = pxt.blocks || (pxt.blocks = {}));
8077
- })(pxt || (pxt = {}));
8078
- var pxt;
8079
- (function (pxt) {
8080
- var blocks;
8081
- (function (blocks) {
8082
- // validates that one or more blocks comments are in the project
8083
- // returns the blocks that have comments for teacher tool scenario
8084
- function validateBlockCommentsExist({ usedBlocks, numRequired }) {
8085
- const commentedBlocks = usedBlocks.filter((block) => !!block.getCommentText());
8086
- return { commentedBlocks, passed: commentedBlocks.length >= numRequired };
8087
- }
8088
- blocks.validateBlockCommentsExist = validateBlockCommentsExist;
8089
- })(blocks = pxt.blocks || (pxt.blocks = {}));
8090
- })(pxt || (pxt = {}));
8091
- var pxt;
8092
- (function (pxt) {
8093
- var blocks;
8094
- (function (blocks) {
8095
- // validates that all of a specific block type have comments
8096
- // returns the blocks that do not have comments for a tutorial validation scenario
8097
- function validateSpecificBlockCommentsExist({ usedBlocks, blockType }) {
8098
- const allSpecifcBlocks = usedBlocks.filter((block) => block.type === blockType);
8099
- const uncommentedBlocks = allSpecifcBlocks.filter((block) => !block.getCommentText());
8100
- return { uncommentedBlocks, passed: uncommentedBlocks.length === 0 };
8101
- }
8102
- blocks.validateSpecificBlockCommentsExist = validateSpecificBlockCommentsExist;
8103
- })(blocks = pxt.blocks || (pxt.blocks = {}));
8104
- })(pxt || (pxt = {}));
8105
7962
  var pxtblockly;
8106
7963
  (function (pxtblockly) {
8107
7964
  class FieldBase extends Blockly.Field {
@@ -13090,6 +12947,9 @@ var pxtblockly;
13090
12947
  if (opts.tileWidth) {
13091
12948
  if (typeof opts.tileWidth === "number") {
13092
12949
  switch (opts.tileWidth) {
12950
+ case 4:
12951
+ parsed.tileWidth = 4;
12952
+ break;
13093
12953
  case 8:
13094
12954
  parsed.tileWidth = 8;
13095
12955
  break;
@@ -13104,6 +12964,10 @@ var pxtblockly;
13104
12964
  else {
13105
12965
  const tw = opts.tileWidth.trim().toLowerCase();
13106
12966
  switch (tw) {
12967
+ case "4":
12968
+ case "four":
12969
+ parsed.tileWidth = 4;
12970
+ break;
13107
12971
  case "8":
13108
12972
  case "eight":
13109
12973
  parsed.tileWidth = 8;
@@ -13167,7 +13031,7 @@ var pxtblockly;
13167
13031
  FieldTileset.cachedRevision = project.revision();
13168
13032
  FieldTileset.cachedWorkspaceId = workspace.id;
13169
13033
  const references = pxtblockly.getAllReferencedTiles(workspace);
13170
- const supportedTileWidths = [16, 8, 32];
13034
+ const supportedTileWidths = [16, 4, 8, 32];
13171
13035
  for (const width of supportedTileWidths) {
13172
13036
  const projectTiles = project.getProjectTiles(width, width === 16);
13173
13037
  if (!projectTiles)
@@ -13331,6 +13195,7 @@ var pxtblockly;
13331
13195
  switch (id) {
13332
13196
  case "myTiles.transparency16":
13333
13197
  return 1;
13198
+ case "myTiles.transparency4":
13334
13199
  case "myTiles.transparency8":
13335
13200
  case "myTiles.transparency32":
13336
13201
  return 2;
package/built/pxtlib.js CHANGED
@@ -13380,6 +13380,8 @@ var pxt;
13380
13380
  return proj.getTransparency(16);
13381
13381
  case "myTiles.transparency8":
13382
13382
  return proj.getTransparency(8);
13383
+ case "myTiles.transparency4":
13384
+ return proj.getTransparency(4);
13383
13385
  case "myTiles.transparency32":
13384
13386
  return proj.getTransparency(32);
13385
13387
  default:
@@ -13638,6 +13640,7 @@ var pxt;
13638
13640
  sprite_1.bitmapEquals = bitmapEquals;
13639
13641
  function tileWidthToTileScale(tileWidth) {
13640
13642
  switch (tileWidth) {
13643
+ case 4: return `TileScale.Four`;
13641
13644
  case 8: return `TileScale.Eight`;
13642
13645
  case 16: return `TileScale.Sixteen`;
13643
13646
  case 32: return `TileScale.ThirtyTwo`;
@@ -13648,6 +13651,7 @@ var pxt;
13648
13651
  function tileScaleToTileWidth(tileScale) {
13649
13652
  tileScale = tileScale.replace(/\s/g, "");
13650
13653
  switch (tileScale) {
13654
+ case `TileScale.Four`: return 4;
13651
13655
  case `TileScale.Eight`: return 8;
13652
13656
  case `TileScale.Sixteen`: return 16;
13653
13657
  case `TileScale.ThirtyTwo`: return 32;