pxt-core 9.2.9 → 9.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/built/cli.js +56 -45
- package/built/crowdin.d.ts +2 -1
- package/built/crowdin.js +218 -213
- package/built/crowdinApi.d.ts +10 -0
- package/built/crowdinApi.js +374 -0
- package/built/pxt.js +97 -298
- package/built/pxtblockly.js +8 -6
- package/built/pxtblocks.d.ts +4 -0
- package/built/pxtblocks.js +8 -6
- package/built/pxtlib.d.ts +3 -37
- package/built/pxtlib.js +41 -253
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/localtypings/pxtarget.d.ts +3 -0
- package/package.json +5 -1
package/built/pxtblocks.js
CHANGED
|
@@ -8597,7 +8597,7 @@ var pxtblockly;
|
|
|
8597
8597
|
const existing = pxt.lookupProjectAssetByTSReference(text, project);
|
|
8598
8598
|
if (existing)
|
|
8599
8599
|
return existing;
|
|
8600
|
-
const frames = parseImageArrayString(text);
|
|
8600
|
+
const frames = parseImageArrayString(text, this.params.taggedTemplate);
|
|
8601
8601
|
if (frames && frames.length) {
|
|
8602
8602
|
const id = this.sourceBlock_.id;
|
|
8603
8603
|
const newAnimation = {
|
|
@@ -8633,7 +8633,7 @@ var pxtblockly;
|
|
|
8633
8633
|
if (!this.asset)
|
|
8634
8634
|
return "[]";
|
|
8635
8635
|
if (this.isTemporaryAsset()) {
|
|
8636
|
-
return "[" + this.asset.frames.map(frame => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(frame), "typescript" /* pxt.editor.FileType.TypeScript
|
|
8636
|
+
return "[" + this.asset.frames.map(frame => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(frame), "typescript" /* pxt.editor.FileType.TypeScript */, this.params.taggedTemplate)).join(",") + "]";
|
|
8637
8637
|
}
|
|
8638
8638
|
return pxt.getTSReferenceForAsset(this.asset);
|
|
8639
8639
|
}
|
|
@@ -8712,6 +8712,7 @@ var pxtblockly;
|
|
|
8712
8712
|
}
|
|
8713
8713
|
parsed.initWidth = withDefault(opts.initWidth, parsed.initWidth);
|
|
8714
8714
|
parsed.initHeight = withDefault(opts.initHeight, parsed.initHeight);
|
|
8715
|
+
parsed.taggedTemplate = opts.taggedTemplate;
|
|
8715
8716
|
return parsed;
|
|
8716
8717
|
function withDefault(raw, def) {
|
|
8717
8718
|
const res = parseInt(raw);
|
|
@@ -8721,11 +8722,11 @@ var pxtblockly;
|
|
|
8721
8722
|
return res;
|
|
8722
8723
|
}
|
|
8723
8724
|
}
|
|
8724
|
-
function parseImageArrayString(str) {
|
|
8725
|
+
function parseImageArrayString(str, templateLiteral) {
|
|
8725
8726
|
if (str.indexOf("[") === -1)
|
|
8726
8727
|
return null;
|
|
8727
8728
|
str = str.replace(/[\[\]]/mg, "");
|
|
8728
|
-
return str.split(",").map(s => pxt.sprite.imageLiteralToBitmap(s).data()).filter(b => b.height && b.width);
|
|
8729
|
+
return str.split(",").map(s => pxt.sprite.imageLiteralToBitmap(s, templateLiteral).data()).filter(b => b.height && b.width);
|
|
8729
8730
|
}
|
|
8730
8731
|
function isNumberType(type) {
|
|
8731
8732
|
return type === "math_number" || type === "math_integer" || type === "math_whole_number";
|
|
@@ -12764,7 +12765,7 @@ var pxtblockly;
|
|
|
12764
12765
|
if (this.getBlockData()) {
|
|
12765
12766
|
return project.lookupAsset("image" /* pxt.AssetType.Image */, this.getBlockData());
|
|
12766
12767
|
}
|
|
12767
|
-
const bmp = text ? pxt.sprite.imageLiteralToBitmap(text) : new pxt.sprite.Bitmap(this.params.initWidth, this.params.initHeight);
|
|
12768
|
+
const bmp = text ? pxt.sprite.imageLiteralToBitmap(text, this.params.taggedTemplate) : new pxt.sprite.Bitmap(this.params.initWidth, this.params.initHeight);
|
|
12768
12769
|
if (!bmp) {
|
|
12769
12770
|
this.isGreyBlock = true;
|
|
12770
12771
|
this.valueText = text;
|
|
@@ -12785,7 +12786,7 @@ var pxtblockly;
|
|
|
12785
12786
|
if (this.asset && !this.isTemporaryAsset()) {
|
|
12786
12787
|
return pxt.getTSReferenceForAsset(this.asset);
|
|
12787
12788
|
}
|
|
12788
|
-
return pxt.sprite.bitmapToImageLiteral(this.asset && pxt.sprite.Bitmap.fromData(this.asset.bitmap), "typescript" /* pxt.editor.FileType.TypeScript
|
|
12789
|
+
return pxt.sprite.bitmapToImageLiteral(this.asset && pxt.sprite.Bitmap.fromData(this.asset.bitmap), "typescript" /* pxt.editor.FileType.TypeScript */, this.params.taggedTemplate);
|
|
12789
12790
|
}
|
|
12790
12791
|
parseFieldOptions(opts) {
|
|
12791
12792
|
return parseFieldOptions(opts);
|
|
@@ -12840,6 +12841,7 @@ var pxtblockly;
|
|
|
12840
12841
|
parsed.initColor = withDefault(opts.initColor, parsed.initColor);
|
|
12841
12842
|
parsed.initWidth = withDefault(opts.initWidth, parsed.initWidth);
|
|
12842
12843
|
parsed.initHeight = withDefault(opts.initHeight, parsed.initHeight);
|
|
12844
|
+
parsed.taggedTemplate = opts.taggedTemplate;
|
|
12843
12845
|
return parsed;
|
|
12844
12846
|
function withDefault(raw, def) {
|
|
12845
12847
|
const res = parseInt(raw);
|
package/built/pxtlib.d.ts
CHANGED
|
@@ -996,42 +996,7 @@ declare namespace pxt.hexloader {
|
|
|
996
996
|
declare namespace pxt.crowdin {
|
|
997
997
|
const KEY_VARIABLE = "CROWDIN_KEY";
|
|
998
998
|
let testMode: boolean;
|
|
999
|
-
const TEST_KEY = "!!!testmode!!!";
|
|
1000
999
|
function setTestMode(): void;
|
|
1001
|
-
interface CrowdinFileInfo {
|
|
1002
|
-
name: string;
|
|
1003
|
-
fullName?: string;
|
|
1004
|
-
id: number;
|
|
1005
|
-
node_type: "file" | "directory" | "branch";
|
|
1006
|
-
phrases?: number;
|
|
1007
|
-
translated?: number;
|
|
1008
|
-
approved?: number;
|
|
1009
|
-
branch?: string;
|
|
1010
|
-
files?: CrowdinFileInfo[];
|
|
1011
|
-
}
|
|
1012
|
-
interface CrowdinProjectInfo {
|
|
1013
|
-
languages: {
|
|
1014
|
-
name: string;
|
|
1015
|
-
code: string;
|
|
1016
|
-
}[];
|
|
1017
|
-
files: CrowdinFileInfo[];
|
|
1018
|
-
}
|
|
1019
|
-
interface DownloadOptions {
|
|
1020
|
-
translatedOnly?: boolean;
|
|
1021
|
-
validatedOnly?: boolean;
|
|
1022
|
-
}
|
|
1023
|
-
function downloadTranslationsAsync(branch: string, prj: string, key: string, filename: string, options?: DownloadOptions): Promise<Map<Map<string>>>;
|
|
1024
|
-
function createDirectoryAsync(branch: string, prj: string, key: string, name: string, incr?: () => void): Promise<void>;
|
|
1025
|
-
function uploadTranslationAsync(branch: string, prj: string, key: string, filename: string, data: string): Promise<void>;
|
|
1026
|
-
function projectInfoAsync(prj: string, key: string): Promise<CrowdinProjectInfo>;
|
|
1027
|
-
/**
|
|
1028
|
-
* Scans files in crowdin and report files that are not on disk anymore
|
|
1029
|
-
*/
|
|
1030
|
-
function listFilesAsync(prj: string, key: string, crowdinPath: string): Promise<{
|
|
1031
|
-
fullName: string;
|
|
1032
|
-
branch: string;
|
|
1033
|
-
}[]>;
|
|
1034
|
-
function languageStatsAsync(prj: string, key: string, lang: string): Promise<CrowdinFileInfo[]>;
|
|
1035
1000
|
function inContextLoadAsync(text: string): Promise<string>;
|
|
1036
1001
|
}
|
|
1037
1002
|
declare namespace pxt.diff {
|
|
@@ -1759,12 +1724,12 @@ declare namespace pxt.sprite {
|
|
|
1759
1724
|
function formatByte(value: number, bytes: number): string;
|
|
1760
1725
|
function resizeBitmap(img: Bitmap, width: number, height: number): Bitmap;
|
|
1761
1726
|
function resizeTilemap(img: Tilemap, width: number, height: number): Tilemap;
|
|
1762
|
-
function imageLiteralToBitmap(text: string): Bitmap;
|
|
1727
|
+
function imageLiteralToBitmap(text: string, templateLiteral?: string): Bitmap;
|
|
1763
1728
|
function encodeAnimationString(frames: BitmapData[], interval: number): string;
|
|
1764
1729
|
function addMissingTilemapTilesAndReferences(project: TilemapProject, asset: ProjectTilemap): void;
|
|
1765
1730
|
function updateTilemapReferencesFromResult(project: TilemapProject, assetResult: ProjectTilemap): void;
|
|
1766
1731
|
function imageLiteralFromDimensions(width: number, height: number, color: number, fileType: "typescript" | "python"): string;
|
|
1767
|
-
function bitmapToImageLiteral(bitmap: Bitmap, fileType: "typescript" | "python"): string;
|
|
1732
|
+
function bitmapToImageLiteral(bitmap: Bitmap, fileType: "typescript" | "python", templateLiteral?: string): string;
|
|
1768
1733
|
function bitmapEquals(a: pxt.sprite.BitmapData, b: pxt.sprite.BitmapData): boolean;
|
|
1769
1734
|
function tileWidthToTileScale(tileWidth: number): string;
|
|
1770
1735
|
function tileScaleToTileWidth(tileScale: string): number;
|
|
@@ -1919,6 +1884,7 @@ declare namespace pxt {
|
|
|
1919
1884
|
*/
|
|
1920
1885
|
packageLocalizationStringsAsync(lang: string): Promise<Map<string>>;
|
|
1921
1886
|
bundledStringsForFile(lang: string, filename: string): Map<string>;
|
|
1887
|
+
patchAppTargetPalette(): void;
|
|
1922
1888
|
}
|
|
1923
1889
|
class MainPackage extends Package {
|
|
1924
1890
|
_host: Host;
|
package/built/pxtlib.js
CHANGED
|
@@ -7618,251 +7618,11 @@ var pxt;
|
|
|
7618
7618
|
(function (crowdin) {
|
|
7619
7619
|
crowdin.KEY_VARIABLE = "CROWDIN_KEY";
|
|
7620
7620
|
crowdin.testMode = false;
|
|
7621
|
-
crowdin.TEST_KEY = "!!!testmode!!!";
|
|
7622
7621
|
function setTestMode() {
|
|
7623
7622
|
pxt.crowdin.testMode = true;
|
|
7624
7623
|
pxt.log(`CROWDIN TEST MODE - files will NOT be uploaded`);
|
|
7625
7624
|
}
|
|
7626
7625
|
crowdin.setTestMode = setTestMode;
|
|
7627
|
-
function multipartPostAsync(key, uri, data = {}, filename = null, filecontents = null) {
|
|
7628
|
-
if (crowdin.testMode || key == crowdin.TEST_KEY) {
|
|
7629
|
-
const resp = {
|
|
7630
|
-
success: true
|
|
7631
|
-
};
|
|
7632
|
-
return Promise.resolve({ statusCode: 200, headers: {}, text: JSON.stringify(resp), json: resp });
|
|
7633
|
-
}
|
|
7634
|
-
return pxt.Util.multipartPostAsync(uri, data, filename, filecontents);
|
|
7635
|
-
}
|
|
7636
|
-
function apiUri(branch, prj, key, cmd, args) {
|
|
7637
|
-
pxt.Util.assert(!!prj && !!key && !!cmd);
|
|
7638
|
-
const apiRoot = "https://api.crowdin.com/api/project/" + prj + "/";
|
|
7639
|
-
args = args || {};
|
|
7640
|
-
if (crowdin.testMode)
|
|
7641
|
-
delete args["key"]; // ensure no key is passed in test mode
|
|
7642
|
-
else
|
|
7643
|
-
args["key"] = key;
|
|
7644
|
-
if (branch)
|
|
7645
|
-
args["branch"] = branch;
|
|
7646
|
-
return apiRoot + cmd + "?" + Object.keys(args).map(k => `${k}=${encodeURIComponent(args[k])}`).join("&");
|
|
7647
|
-
}
|
|
7648
|
-
function downloadTranslationsAsync(branch, prj, key, filename, options = {}) {
|
|
7649
|
-
const q = { json: "true" };
|
|
7650
|
-
const infoUri = apiUri(branch, prj, key, "info", q);
|
|
7651
|
-
const r = {};
|
|
7652
|
-
filename = normalizeFileName(filename);
|
|
7653
|
-
return pxt.Util.httpGetTextAsync(infoUri).then(respText => {
|
|
7654
|
-
const info = JSON.parse(respText);
|
|
7655
|
-
if (!info)
|
|
7656
|
-
throw new Error("info failed");
|
|
7657
|
-
let todo = info.languages.filter(l => l.code != "en");
|
|
7658
|
-
if (pxt.appTarget && pxt.appTarget.appTheme && pxt.appTarget.appTheme.availableLocales)
|
|
7659
|
-
todo = todo.filter(l => pxt.appTarget.appTheme.availableLocales.indexOf(l.code) > -1);
|
|
7660
|
-
pxt.log('languages: ' + todo.map(l => l.code).join(', '));
|
|
7661
|
-
const nextFile = () => {
|
|
7662
|
-
const item = todo.pop();
|
|
7663
|
-
if (!item)
|
|
7664
|
-
return Promise.resolve();
|
|
7665
|
-
const exportFileUri = apiUri(branch, prj, key, "export-file", {
|
|
7666
|
-
file: filename,
|
|
7667
|
-
language: item.code,
|
|
7668
|
-
export_translated_only: options.translatedOnly ? "1" : "0",
|
|
7669
|
-
export_approved_only: options.validatedOnly ? "1" : "0"
|
|
7670
|
-
});
|
|
7671
|
-
pxt.log(`downloading ${item.name} - ${item.code} (${todo.length} more)`);
|
|
7672
|
-
return pxt.Util.httpGetTextAsync(exportFileUri).then((transationsText) => {
|
|
7673
|
-
try {
|
|
7674
|
-
const translations = JSON.parse(transationsText);
|
|
7675
|
-
if (translations)
|
|
7676
|
-
r[item.code] = translations;
|
|
7677
|
-
}
|
|
7678
|
-
catch (e) {
|
|
7679
|
-
pxt.log(exportFileUri + ' ' + e);
|
|
7680
|
-
}
|
|
7681
|
-
return nextFile();
|
|
7682
|
-
}).then(() => pxt.Util.delay(1000)); // throttling otherwise crowdin fails
|
|
7683
|
-
};
|
|
7684
|
-
return nextFile();
|
|
7685
|
-
}).then(() => r);
|
|
7686
|
-
}
|
|
7687
|
-
crowdin.downloadTranslationsAsync = downloadTranslationsAsync;
|
|
7688
|
-
function mkIncr(filename) {
|
|
7689
|
-
let cnt = 0;
|
|
7690
|
-
return function incr() {
|
|
7691
|
-
if (cnt++ > 10) {
|
|
7692
|
-
throw new Error("Too many API calls for " + filename);
|
|
7693
|
-
}
|
|
7694
|
-
};
|
|
7695
|
-
}
|
|
7696
|
-
function createDirectoryAsync(branch, prj, key, name, incr) {
|
|
7697
|
-
name = normalizeFileName(name);
|
|
7698
|
-
pxt.debug(`create directory ${branch || ""}/${name}`);
|
|
7699
|
-
if (!incr)
|
|
7700
|
-
incr = mkIncr(name);
|
|
7701
|
-
return multipartPostAsync(key, apiUri(branch, prj, key, "add-directory"), { json: "true", name: name })
|
|
7702
|
-
.then(resp => {
|
|
7703
|
-
pxt.debug(`crowdin resp: ${resp.statusCode}`);
|
|
7704
|
-
// 400 returned by folder already exists
|
|
7705
|
-
if (resp.statusCode == 200 || resp.statusCode == 400)
|
|
7706
|
-
return Promise.resolve();
|
|
7707
|
-
if (resp.statusCode == 500 && resp.text) {
|
|
7708
|
-
const json = JSON.parse(resp.text);
|
|
7709
|
-
if (json.error.code === 50) {
|
|
7710
|
-
pxt.log('directory already exists');
|
|
7711
|
-
return Promise.resolve();
|
|
7712
|
-
}
|
|
7713
|
-
}
|
|
7714
|
-
const data = resp.json || JSON.parse(resp.text) || { error: {} };
|
|
7715
|
-
if (resp.statusCode == 404 && data.error.code == 17) {
|
|
7716
|
-
pxt.log(`parent directory missing for ${name}`);
|
|
7717
|
-
const par = name.replace(/\/[^\/]+$/, "");
|
|
7718
|
-
if (par != name) {
|
|
7719
|
-
return createDirectoryAsync(branch, prj, key, par, incr)
|
|
7720
|
-
.then(() => createDirectoryAsync(branch, prj, key, name, incr)); // retry
|
|
7721
|
-
}
|
|
7722
|
-
}
|
|
7723
|
-
throw new Error(`cannot create directory ${branch || ""}/${name}: ${resp.statusCode} ${JSON.stringify(data)}`);
|
|
7724
|
-
});
|
|
7725
|
-
}
|
|
7726
|
-
crowdin.createDirectoryAsync = createDirectoryAsync;
|
|
7727
|
-
function normalizeFileName(filename) {
|
|
7728
|
-
return filename.replace(/\\/g, '/');
|
|
7729
|
-
}
|
|
7730
|
-
function uploadTranslationAsync(branch, prj, key, filename, data) {
|
|
7731
|
-
pxt.Util.assert(!!prj);
|
|
7732
|
-
pxt.Util.assert(!!key);
|
|
7733
|
-
filename = normalizeFileName(filename);
|
|
7734
|
-
const incr = mkIncr(filename);
|
|
7735
|
-
function startAsync() {
|
|
7736
|
-
return uploadAsync("update-file", { update_option: "update_as_unapproved" });
|
|
7737
|
-
}
|
|
7738
|
-
function uploadAsync(op, opts) {
|
|
7739
|
-
opts["type"] = "auto";
|
|
7740
|
-
opts["json"] = "";
|
|
7741
|
-
opts["escape_quotes"] = "0";
|
|
7742
|
-
incr();
|
|
7743
|
-
return multipartPostAsync(key, apiUri(branch, prj, key, op), opts, filename, data)
|
|
7744
|
-
.then(resp => handleResponseAsync(resp));
|
|
7745
|
-
}
|
|
7746
|
-
function handleResponseAsync(resp) {
|
|
7747
|
-
var _a, _b, _c;
|
|
7748
|
-
const code = resp.statusCode;
|
|
7749
|
-
const errorData = pxt.Util.jsonTryParse(resp.text) || {};
|
|
7750
|
-
pxt.debug(`upload result: ${code}`);
|
|
7751
|
-
if (code == 404 && errorData.error && errorData.error.code == 8) {
|
|
7752
|
-
pxt.log(`create new translation file: ${filename}`);
|
|
7753
|
-
return uploadAsync("add-file", {});
|
|
7754
|
-
}
|
|
7755
|
-
else if (code == 404 && ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.code) == 17) {
|
|
7756
|
-
return createDirectoryAsync(branch, prj, key, filename.replace(/\/[^\/]+$/, ""), incr)
|
|
7757
|
-
.then(() => startAsync());
|
|
7758
|
-
}
|
|
7759
|
-
else if (!errorData.success && ((_b = errorData.error) === null || _b === void 0 ? void 0 : _b.code) == 53) {
|
|
7760
|
-
// file is being updated
|
|
7761
|
-
pxt.log(`${filename} being updated, waiting 5s and retry...`);
|
|
7762
|
-
return pxt.U.delay(5000) // wait 5s and try again
|
|
7763
|
-
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
7764
|
-
}
|
|
7765
|
-
else if (code == 429 && ((_c = errorData.error) === null || _c === void 0 ? void 0 : _c.code) == 55) {
|
|
7766
|
-
// Too many concurrent requests
|
|
7767
|
-
pxt.log(`Maximum concurrent requests reached, waiting 10s and retry...`);
|
|
7768
|
-
return pxt.U.delay(10 * 1000) // wait 10s and try again
|
|
7769
|
-
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
7770
|
-
}
|
|
7771
|
-
else if (code == 200 || errorData.success) {
|
|
7772
|
-
// something crowdin reports 500 with success=true
|
|
7773
|
-
return Promise.resolve();
|
|
7774
|
-
}
|
|
7775
|
-
else {
|
|
7776
|
-
throw new Error(`Error, upload translation: ${filename}, ${code}, ${resp.text}`);
|
|
7777
|
-
}
|
|
7778
|
-
}
|
|
7779
|
-
return startAsync();
|
|
7780
|
-
}
|
|
7781
|
-
crowdin.uploadTranslationAsync = uploadTranslationAsync;
|
|
7782
|
-
function flatten(allFiles, node, parentDir, branch) {
|
|
7783
|
-
const n = node.name;
|
|
7784
|
-
const d = parentDir ? parentDir + "/" + n : n;
|
|
7785
|
-
node.fullName = d;
|
|
7786
|
-
node.branch = branch || "";
|
|
7787
|
-
switch (node.node_type) {
|
|
7788
|
-
case "file":
|
|
7789
|
-
allFiles.push(node);
|
|
7790
|
-
break;
|
|
7791
|
-
case "directory":
|
|
7792
|
-
(node.files || []).forEach(f => flatten(allFiles, f, d, branch));
|
|
7793
|
-
break;
|
|
7794
|
-
case "branch":
|
|
7795
|
-
(node.files || []).forEach(f => flatten(allFiles, f, parentDir, node.name));
|
|
7796
|
-
break;
|
|
7797
|
-
}
|
|
7798
|
-
}
|
|
7799
|
-
function filterAndFlattenFiles(files, crowdinPath) {
|
|
7800
|
-
const pxtCrowdinBranch = pxt.appTarget.versions.pxtCrowdinBranch || "";
|
|
7801
|
-
const targetCrowdinBranch = pxt.appTarget.versions.targetCrowdinBranch || "";
|
|
7802
|
-
let allFiles = [];
|
|
7803
|
-
// flatten the files
|
|
7804
|
-
files.forEach(f => flatten(allFiles, f, ""));
|
|
7805
|
-
// top level files are for PXT, subolder are targets
|
|
7806
|
-
allFiles = allFiles.filter(f => {
|
|
7807
|
-
if (f.fullName.indexOf('/') < 0)
|
|
7808
|
-
return f.branch == pxtCrowdinBranch; // pxt file
|
|
7809
|
-
else
|
|
7810
|
-
return f.branch == targetCrowdinBranch;
|
|
7811
|
-
});
|
|
7812
|
-
// folder filter
|
|
7813
|
-
if (crowdinPath) {
|
|
7814
|
-
// filter out crowdin folder
|
|
7815
|
-
allFiles = allFiles.filter(f => f.fullName.indexOf(crowdinPath) == 0);
|
|
7816
|
-
}
|
|
7817
|
-
// filter out non-target files
|
|
7818
|
-
if (pxt.appTarget.id != "core") {
|
|
7819
|
-
const id = pxt.appTarget.id + '/';
|
|
7820
|
-
allFiles = allFiles.filter(f => {
|
|
7821
|
-
return f.fullName.indexOf('/') < 0 // top level file
|
|
7822
|
-
|| f.fullName.substr(0, id.length) == id // from the target folder
|
|
7823
|
-
|| f.fullName.indexOf('common-docs') >= 0; // common docs
|
|
7824
|
-
});
|
|
7825
|
-
}
|
|
7826
|
-
return allFiles;
|
|
7827
|
-
}
|
|
7828
|
-
function projectInfoAsync(prj, key) {
|
|
7829
|
-
const q = { json: "true" };
|
|
7830
|
-
const infoUri = apiUri("", prj, key, "info", q);
|
|
7831
|
-
return pxt.Util.httpGetTextAsync(infoUri).then(respText => {
|
|
7832
|
-
const info = JSON.parse(respText);
|
|
7833
|
-
return info;
|
|
7834
|
-
});
|
|
7835
|
-
}
|
|
7836
|
-
crowdin.projectInfoAsync = projectInfoAsync;
|
|
7837
|
-
/**
|
|
7838
|
-
* Scans files in crowdin and report files that are not on disk anymore
|
|
7839
|
-
*/
|
|
7840
|
-
function listFilesAsync(prj, key, crowdinPath) {
|
|
7841
|
-
pxt.log(`crowdin: listing files under ${crowdinPath}`);
|
|
7842
|
-
return projectInfoAsync(prj, key)
|
|
7843
|
-
.then(info => {
|
|
7844
|
-
if (!info)
|
|
7845
|
-
throw new Error("info failed");
|
|
7846
|
-
let allFiles = filterAndFlattenFiles(info.files, crowdinPath);
|
|
7847
|
-
pxt.debug(`crowdin: found ${allFiles.length} under ${crowdinPath}`);
|
|
7848
|
-
return allFiles.map(f => {
|
|
7849
|
-
return {
|
|
7850
|
-
fullName: f.fullName,
|
|
7851
|
-
branch: f.branch || ""
|
|
7852
|
-
};
|
|
7853
|
-
});
|
|
7854
|
-
});
|
|
7855
|
-
}
|
|
7856
|
-
crowdin.listFilesAsync = listFilesAsync;
|
|
7857
|
-
function languageStatsAsync(prj, key, lang) {
|
|
7858
|
-
const uri = apiUri("", prj, key, "language-status", { language: lang, json: "true" });
|
|
7859
|
-
return pxt.Util.httpGetJsonAsync(uri)
|
|
7860
|
-
.then(info => {
|
|
7861
|
-
const allFiles = filterAndFlattenFiles(info.files);
|
|
7862
|
-
return allFiles;
|
|
7863
|
-
});
|
|
7864
|
-
}
|
|
7865
|
-
crowdin.languageStatsAsync = languageStatsAsync;
|
|
7866
7626
|
function inContextLoadAsync(text) {
|
|
7867
7627
|
const node = document.createElement("input");
|
|
7868
7628
|
node.type = "text";
|
|
@@ -13353,11 +13113,12 @@ var pxt;
|
|
|
13353
13113
|
return result;
|
|
13354
13114
|
}
|
|
13355
13115
|
sprite_1.resizeTilemap = resizeTilemap;
|
|
13356
|
-
function imageLiteralToBitmap(text) {
|
|
13116
|
+
function imageLiteralToBitmap(text, templateLiteral = "img") {
|
|
13357
13117
|
// Strip the tagged template string business and the whitespace. We don't have to exhaustively
|
|
13358
13118
|
// replace encoded characters because the compiler will catch any disallowed characters and throw
|
|
13359
13119
|
// an error before the decompilation happens. 96 is backtick and 9 is tab
|
|
13360
13120
|
text = text.replace(/[ `]|(?:`)|(?:	)|(?:img)/g, "").trim();
|
|
13121
|
+
text = text.replaceAll(templateLiteral, "");
|
|
13361
13122
|
text = text.replace(/^["`\(\)]*/, '').replace(/["`\(\)]*$/, '');
|
|
13362
13123
|
text = text.replace(/ /g, "\n");
|
|
13363
13124
|
const rows = text.split("\n");
|
|
@@ -13519,14 +13280,14 @@ var pxt;
|
|
|
13519
13280
|
pxt.sprite.trimTilemapTileset(result);
|
|
13520
13281
|
}
|
|
13521
13282
|
sprite_1.updateTilemapReferencesFromResult = updateTilemapReferencesFromResult;
|
|
13522
|
-
function imageLiteralPrologue(fileType) {
|
|
13283
|
+
function imageLiteralPrologue(fileType, templateLiteral = "img") {
|
|
13523
13284
|
let res = '';
|
|
13524
13285
|
switch (fileType) {
|
|
13525
13286
|
case "python":
|
|
13526
|
-
res =
|
|
13287
|
+
res = `${templateLiteral}("""`;
|
|
13527
13288
|
break;
|
|
13528
13289
|
default:
|
|
13529
|
-
res =
|
|
13290
|
+
res = `${templateLiteral}\``;
|
|
13530
13291
|
break;
|
|
13531
13292
|
}
|
|
13532
13293
|
return res;
|
|
@@ -13557,10 +13318,10 @@ var pxt;
|
|
|
13557
13318
|
return res;
|
|
13558
13319
|
}
|
|
13559
13320
|
sprite_1.imageLiteralFromDimensions = imageLiteralFromDimensions;
|
|
13560
|
-
function bitmapToImageLiteral(bitmap, fileType) {
|
|
13321
|
+
function bitmapToImageLiteral(bitmap, fileType, templateLiteral = "img") {
|
|
13561
13322
|
if (!bitmap || bitmap.height === 0 || bitmap.width === 0)
|
|
13562
13323
|
return "";
|
|
13563
|
-
let res = imageLiteralPrologue(fileType);
|
|
13324
|
+
let res = imageLiteralPrologue(fileType, templateLiteral);
|
|
13564
13325
|
if (bitmap) {
|
|
13565
13326
|
const paddingBetweenPixels = (bitmap.width * bitmap.height > 300) ? "" : " ";
|
|
13566
13327
|
for (let r = 0; r < bitmap.height; r++) {
|
|
@@ -16061,11 +15822,7 @@ var pxt;
|
|
|
16061
15822
|
};
|
|
16062
15823
|
await loadDepsRecursive(null, this);
|
|
16063
15824
|
// get paletter config loading deps, so the more higher level packages take precedence
|
|
16064
|
-
|
|
16065
|
-
pxt.appTarget.runtime.palette = pxt.U.clone(this.config.palette);
|
|
16066
|
-
if (this.config.paletteNames)
|
|
16067
|
-
pxt.appTarget.runtime.paletteNames = this.config.paletteNames;
|
|
16068
|
-
}
|
|
15825
|
+
this.patchAppTargetPalette();
|
|
16069
15826
|
// get screen size loading deps, so the more higher level packages take precedence
|
|
16070
15827
|
if (this.config.screenSize && pxt.appTarget.runtime)
|
|
16071
15828
|
pxt.appTarget.runtime.screenSize = pxt.U.clone(this.config.screenSize);
|
|
@@ -16211,6 +15968,13 @@ var pxt;
|
|
|
16211
15968
|
}
|
|
16212
15969
|
return r;
|
|
16213
15970
|
}
|
|
15971
|
+
patchAppTargetPalette() {
|
|
15972
|
+
if (this.config.palette && pxt.appTarget.runtime) {
|
|
15973
|
+
pxt.appTarget.runtime.palette = pxt.U.clone(this.config.palette);
|
|
15974
|
+
if (this.config.paletteNames)
|
|
15975
|
+
pxt.appTarget.runtime.paletteNames = this.config.paletteNames;
|
|
15976
|
+
}
|
|
15977
|
+
}
|
|
16214
15978
|
}
|
|
16215
15979
|
Package.depWarnings = {};
|
|
16216
15980
|
pxt.Package = Package;
|
|
@@ -16472,6 +16236,10 @@ var pxt;
|
|
|
16472
16236
|
opts.jres = this.getJRes();
|
|
16473
16237
|
const functionOpts = pxt.appTarget.runtime && pxt.appTarget.runtime.functionsOptions;
|
|
16474
16238
|
opts.allowedArgumentTypes = functionOpts && functionOpts.extraFunctionEditorTypes && functionOpts.extraFunctionEditorTypes.map(info => info.typeName).concat("number", "boolean", "string");
|
|
16239
|
+
for (const dep of this.sortedDeps()) {
|
|
16240
|
+
dep.patchAppTargetPalette();
|
|
16241
|
+
}
|
|
16242
|
+
this.patchAppTargetPalette();
|
|
16475
16243
|
return opts;
|
|
16476
16244
|
}
|
|
16477
16245
|
prepareConfigToBePublished() {
|
|
@@ -21246,7 +21014,7 @@ var pxt;
|
|
|
21246
21014
|
if (!steps)
|
|
21247
21015
|
return undefined; // error parsing steps
|
|
21248
21016
|
// collect code and infer editor
|
|
21249
|
-
const { code, templateCode, editor, language, jres, assetJson, customTs, simThemeJson } = computeBodyMetadata(body);
|
|
21017
|
+
const { code, templateCode, templateLanguage, editor, language, jres, assetJson, customTs, simThemeJson } = computeBodyMetadata(body);
|
|
21250
21018
|
// noDiffs legacy
|
|
21251
21019
|
if (metadata.diffs === true // enabled in tutorial
|
|
21252
21020
|
|| (metadata.diffs !== false && metadata.noDiffs !== true // not disabled
|
|
@@ -21272,6 +21040,7 @@ var pxt;
|
|
|
21272
21040
|
activities,
|
|
21273
21041
|
code,
|
|
21274
21042
|
templateCode,
|
|
21043
|
+
templateLanguage,
|
|
21275
21044
|
metadata,
|
|
21276
21045
|
language,
|
|
21277
21046
|
jres,
|
|
@@ -21284,7 +21053,7 @@ var pxt;
|
|
|
21284
21053
|
}
|
|
21285
21054
|
tutorial_1.parseTutorial = parseTutorial;
|
|
21286
21055
|
function getMetadataRegex() {
|
|
21287
|
-
return /``` *(sim|block|blocks|filterblocks|spy|ghost|typescript|ts|js|javascript|template|python|jres|assetjson|customts|simtheme)\s*\n([\s\S]*?)\n```/gmi;
|
|
21056
|
+
return /``` *(sim|block|blocks|filterblocks|spy|ghost|typescript|ts|js|javascript|template|python|jres|assetjson|customts|simtheme|python-template|ts-template|typescript-template|js-template|javascript-template)\s*\n([\s\S]*?)\n```/gmi;
|
|
21288
21057
|
}
|
|
21289
21058
|
tutorial_1.getMetadataRegex = getMetadataRegex;
|
|
21290
21059
|
function computeBodyMetadata(body) {
|
|
@@ -21294,6 +21063,7 @@ var pxt;
|
|
|
21294
21063
|
let jres;
|
|
21295
21064
|
let code = [];
|
|
21296
21065
|
let templateCode;
|
|
21066
|
+
let templateLanguage;
|
|
21297
21067
|
let language;
|
|
21298
21068
|
let idx = 0;
|
|
21299
21069
|
let assetJson;
|
|
@@ -21329,6 +21099,22 @@ var pxt;
|
|
|
21329
21099
|
case "template":
|
|
21330
21100
|
templateCode = m2;
|
|
21331
21101
|
break;
|
|
21102
|
+
case "python-template":
|
|
21103
|
+
if (!checkTutorialEditor(pxt.PYTHON_PROJECT_NAME))
|
|
21104
|
+
return undefined;
|
|
21105
|
+
templateCode = m2;
|
|
21106
|
+
templateLanguage = "python";
|
|
21107
|
+
language = "python";
|
|
21108
|
+
break;
|
|
21109
|
+
case "ts-template":
|
|
21110
|
+
case "typescript-template":
|
|
21111
|
+
case "js-template":
|
|
21112
|
+
case "javascript-template":
|
|
21113
|
+
if (!checkTutorialEditor(pxt.JAVASCRIPT_PROJECT_NAME))
|
|
21114
|
+
return undefined;
|
|
21115
|
+
templateCode = m2;
|
|
21116
|
+
templateLanguage = "typescript";
|
|
21117
|
+
break;
|
|
21332
21118
|
case "jres":
|
|
21333
21119
|
jres = m2;
|
|
21334
21120
|
break;
|
|
@@ -21352,6 +21138,7 @@ var pxt;
|
|
|
21352
21138
|
return {
|
|
21353
21139
|
code,
|
|
21354
21140
|
templateCode,
|
|
21141
|
+
templateLanguage,
|
|
21355
21142
|
editor,
|
|
21356
21143
|
language,
|
|
21357
21144
|
jres,
|
|
@@ -21634,6 +21421,7 @@ ${code}
|
|
|
21634
21421
|
tutorialCode: tutorialInfo.code,
|
|
21635
21422
|
tutorialRecipe: !!recipe,
|
|
21636
21423
|
templateCode: tutorialInfo.templateCode,
|
|
21424
|
+
templateLanguage: tutorialInfo.templateLanguage,
|
|
21637
21425
|
autoexpandStep: ((_a = tutorialInfo.metadata) === null || _a === void 0 ? void 0 : _a.autoexpandOff) ? false : true,
|
|
21638
21426
|
metadata: tutorialInfo.metadata,
|
|
21639
21427
|
language: tutorialInfo.language,
|