pxt-core 9.2.9 → 9.2.10
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 +75 -296
- 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 +19 -251
- 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 +1 -0
- package/package.json +5 -1
package/built/pxt.js
CHANGED
|
@@ -105304,251 +105304,11 @@ var pxt;
|
|
|
105304
105304
|
(function (crowdin) {
|
|
105305
105305
|
crowdin.KEY_VARIABLE = "CROWDIN_KEY";
|
|
105306
105306
|
crowdin.testMode = false;
|
|
105307
|
-
crowdin.TEST_KEY = "!!!testmode!!!";
|
|
105308
105307
|
function setTestMode() {
|
|
105309
105308
|
pxt.crowdin.testMode = true;
|
|
105310
105309
|
pxt.log(`CROWDIN TEST MODE - files will NOT be uploaded`);
|
|
105311
105310
|
}
|
|
105312
105311
|
crowdin.setTestMode = setTestMode;
|
|
105313
|
-
function multipartPostAsync(key, uri, data = {}, filename = null, filecontents = null) {
|
|
105314
|
-
if (crowdin.testMode || key == crowdin.TEST_KEY) {
|
|
105315
|
-
const resp = {
|
|
105316
|
-
success: true
|
|
105317
|
-
};
|
|
105318
|
-
return Promise.resolve({ statusCode: 200, headers: {}, text: JSON.stringify(resp), json: resp });
|
|
105319
|
-
}
|
|
105320
|
-
return pxt.Util.multipartPostAsync(uri, data, filename, filecontents);
|
|
105321
|
-
}
|
|
105322
|
-
function apiUri(branch, prj, key, cmd, args) {
|
|
105323
|
-
pxt.Util.assert(!!prj && !!key && !!cmd);
|
|
105324
|
-
const apiRoot = "https://api.crowdin.com/api/project/" + prj + "/";
|
|
105325
|
-
args = args || {};
|
|
105326
|
-
if (crowdin.testMode)
|
|
105327
|
-
delete args["key"]; // ensure no key is passed in test mode
|
|
105328
|
-
else
|
|
105329
|
-
args["key"] = key;
|
|
105330
|
-
if (branch)
|
|
105331
|
-
args["branch"] = branch;
|
|
105332
|
-
return apiRoot + cmd + "?" + Object.keys(args).map(k => `${k}=${encodeURIComponent(args[k])}`).join("&");
|
|
105333
|
-
}
|
|
105334
|
-
function downloadTranslationsAsync(branch, prj, key, filename, options = {}) {
|
|
105335
|
-
const q = { json: "true" };
|
|
105336
|
-
const infoUri = apiUri(branch, prj, key, "info", q);
|
|
105337
|
-
const r = {};
|
|
105338
|
-
filename = normalizeFileName(filename);
|
|
105339
|
-
return pxt.Util.httpGetTextAsync(infoUri).then(respText => {
|
|
105340
|
-
const info = JSON.parse(respText);
|
|
105341
|
-
if (!info)
|
|
105342
|
-
throw new Error("info failed");
|
|
105343
|
-
let todo = info.languages.filter(l => l.code != "en");
|
|
105344
|
-
if (pxt.appTarget && pxt.appTarget.appTheme && pxt.appTarget.appTheme.availableLocales)
|
|
105345
|
-
todo = todo.filter(l => pxt.appTarget.appTheme.availableLocales.indexOf(l.code) > -1);
|
|
105346
|
-
pxt.log('languages: ' + todo.map(l => l.code).join(', '));
|
|
105347
|
-
const nextFile = () => {
|
|
105348
|
-
const item = todo.pop();
|
|
105349
|
-
if (!item)
|
|
105350
|
-
return Promise.resolve();
|
|
105351
|
-
const exportFileUri = apiUri(branch, prj, key, "export-file", {
|
|
105352
|
-
file: filename,
|
|
105353
|
-
language: item.code,
|
|
105354
|
-
export_translated_only: options.translatedOnly ? "1" : "0",
|
|
105355
|
-
export_approved_only: options.validatedOnly ? "1" : "0"
|
|
105356
|
-
});
|
|
105357
|
-
pxt.log(`downloading ${item.name} - ${item.code} (${todo.length} more)`);
|
|
105358
|
-
return pxt.Util.httpGetTextAsync(exportFileUri).then((transationsText) => {
|
|
105359
|
-
try {
|
|
105360
|
-
const translations = JSON.parse(transationsText);
|
|
105361
|
-
if (translations)
|
|
105362
|
-
r[item.code] = translations;
|
|
105363
|
-
}
|
|
105364
|
-
catch (e) {
|
|
105365
|
-
pxt.log(exportFileUri + ' ' + e);
|
|
105366
|
-
}
|
|
105367
|
-
return nextFile();
|
|
105368
|
-
}).then(() => pxt.Util.delay(1000)); // throttling otherwise crowdin fails
|
|
105369
|
-
};
|
|
105370
|
-
return nextFile();
|
|
105371
|
-
}).then(() => r);
|
|
105372
|
-
}
|
|
105373
|
-
crowdin.downloadTranslationsAsync = downloadTranslationsAsync;
|
|
105374
|
-
function mkIncr(filename) {
|
|
105375
|
-
let cnt = 0;
|
|
105376
|
-
return function incr() {
|
|
105377
|
-
if (cnt++ > 10) {
|
|
105378
|
-
throw new Error("Too many API calls for " + filename);
|
|
105379
|
-
}
|
|
105380
|
-
};
|
|
105381
|
-
}
|
|
105382
|
-
function createDirectoryAsync(branch, prj, key, name, incr) {
|
|
105383
|
-
name = normalizeFileName(name);
|
|
105384
|
-
pxt.debug(`create directory ${branch || ""}/${name}`);
|
|
105385
|
-
if (!incr)
|
|
105386
|
-
incr = mkIncr(name);
|
|
105387
|
-
return multipartPostAsync(key, apiUri(branch, prj, key, "add-directory"), { json: "true", name: name })
|
|
105388
|
-
.then(resp => {
|
|
105389
|
-
pxt.debug(`crowdin resp: ${resp.statusCode}`);
|
|
105390
|
-
// 400 returned by folder already exists
|
|
105391
|
-
if (resp.statusCode == 200 || resp.statusCode == 400)
|
|
105392
|
-
return Promise.resolve();
|
|
105393
|
-
if (resp.statusCode == 500 && resp.text) {
|
|
105394
|
-
const json = JSON.parse(resp.text);
|
|
105395
|
-
if (json.error.code === 50) {
|
|
105396
|
-
pxt.log('directory already exists');
|
|
105397
|
-
return Promise.resolve();
|
|
105398
|
-
}
|
|
105399
|
-
}
|
|
105400
|
-
const data = resp.json || JSON.parse(resp.text) || { error: {} };
|
|
105401
|
-
if (resp.statusCode == 404 && data.error.code == 17) {
|
|
105402
|
-
pxt.log(`parent directory missing for ${name}`);
|
|
105403
|
-
const par = name.replace(/\/[^\/]+$/, "");
|
|
105404
|
-
if (par != name) {
|
|
105405
|
-
return createDirectoryAsync(branch, prj, key, par, incr)
|
|
105406
|
-
.then(() => createDirectoryAsync(branch, prj, key, name, incr)); // retry
|
|
105407
|
-
}
|
|
105408
|
-
}
|
|
105409
|
-
throw new Error(`cannot create directory ${branch || ""}/${name}: ${resp.statusCode} ${JSON.stringify(data)}`);
|
|
105410
|
-
});
|
|
105411
|
-
}
|
|
105412
|
-
crowdin.createDirectoryAsync = createDirectoryAsync;
|
|
105413
|
-
function normalizeFileName(filename) {
|
|
105414
|
-
return filename.replace(/\\/g, '/');
|
|
105415
|
-
}
|
|
105416
|
-
function uploadTranslationAsync(branch, prj, key, filename, data) {
|
|
105417
|
-
pxt.Util.assert(!!prj);
|
|
105418
|
-
pxt.Util.assert(!!key);
|
|
105419
|
-
filename = normalizeFileName(filename);
|
|
105420
|
-
const incr = mkIncr(filename);
|
|
105421
|
-
function startAsync() {
|
|
105422
|
-
return uploadAsync("update-file", { update_option: "update_as_unapproved" });
|
|
105423
|
-
}
|
|
105424
|
-
function uploadAsync(op, opts) {
|
|
105425
|
-
opts["type"] = "auto";
|
|
105426
|
-
opts["json"] = "";
|
|
105427
|
-
opts["escape_quotes"] = "0";
|
|
105428
|
-
incr();
|
|
105429
|
-
return multipartPostAsync(key, apiUri(branch, prj, key, op), opts, filename, data)
|
|
105430
|
-
.then(resp => handleResponseAsync(resp));
|
|
105431
|
-
}
|
|
105432
|
-
function handleResponseAsync(resp) {
|
|
105433
|
-
var _a, _b, _c;
|
|
105434
|
-
const code = resp.statusCode;
|
|
105435
|
-
const errorData = pxt.Util.jsonTryParse(resp.text) || {};
|
|
105436
|
-
pxt.debug(`upload result: ${code}`);
|
|
105437
|
-
if (code == 404 && errorData.error && errorData.error.code == 8) {
|
|
105438
|
-
pxt.log(`create new translation file: ${filename}`);
|
|
105439
|
-
return uploadAsync("add-file", {});
|
|
105440
|
-
}
|
|
105441
|
-
else if (code == 404 && ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.code) == 17) {
|
|
105442
|
-
return createDirectoryAsync(branch, prj, key, filename.replace(/\/[^\/]+$/, ""), incr)
|
|
105443
|
-
.then(() => startAsync());
|
|
105444
|
-
}
|
|
105445
|
-
else if (!errorData.success && ((_b = errorData.error) === null || _b === void 0 ? void 0 : _b.code) == 53) {
|
|
105446
|
-
// file is being updated
|
|
105447
|
-
pxt.log(`${filename} being updated, waiting 5s and retry...`);
|
|
105448
|
-
return pxt.U.delay(5000) // wait 5s and try again
|
|
105449
|
-
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
105450
|
-
}
|
|
105451
|
-
else if (code == 429 && ((_c = errorData.error) === null || _c === void 0 ? void 0 : _c.code) == 55) {
|
|
105452
|
-
// Too many concurrent requests
|
|
105453
|
-
pxt.log(`Maximum concurrent requests reached, waiting 10s and retry...`);
|
|
105454
|
-
return pxt.U.delay(10 * 1000) // wait 10s and try again
|
|
105455
|
-
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
105456
|
-
}
|
|
105457
|
-
else if (code == 200 || errorData.success) {
|
|
105458
|
-
// something crowdin reports 500 with success=true
|
|
105459
|
-
return Promise.resolve();
|
|
105460
|
-
}
|
|
105461
|
-
else {
|
|
105462
|
-
throw new Error(`Error, upload translation: ${filename}, ${code}, ${resp.text}`);
|
|
105463
|
-
}
|
|
105464
|
-
}
|
|
105465
|
-
return startAsync();
|
|
105466
|
-
}
|
|
105467
|
-
crowdin.uploadTranslationAsync = uploadTranslationAsync;
|
|
105468
|
-
function flatten(allFiles, node, parentDir, branch) {
|
|
105469
|
-
const n = node.name;
|
|
105470
|
-
const d = parentDir ? parentDir + "/" + n : n;
|
|
105471
|
-
node.fullName = d;
|
|
105472
|
-
node.branch = branch || "";
|
|
105473
|
-
switch (node.node_type) {
|
|
105474
|
-
case "file":
|
|
105475
|
-
allFiles.push(node);
|
|
105476
|
-
break;
|
|
105477
|
-
case "directory":
|
|
105478
|
-
(node.files || []).forEach(f => flatten(allFiles, f, d, branch));
|
|
105479
|
-
break;
|
|
105480
|
-
case "branch":
|
|
105481
|
-
(node.files || []).forEach(f => flatten(allFiles, f, parentDir, node.name));
|
|
105482
|
-
break;
|
|
105483
|
-
}
|
|
105484
|
-
}
|
|
105485
|
-
function filterAndFlattenFiles(files, crowdinPath) {
|
|
105486
|
-
const pxtCrowdinBranch = pxt.appTarget.versions.pxtCrowdinBranch || "";
|
|
105487
|
-
const targetCrowdinBranch = pxt.appTarget.versions.targetCrowdinBranch || "";
|
|
105488
|
-
let allFiles = [];
|
|
105489
|
-
// flatten the files
|
|
105490
|
-
files.forEach(f => flatten(allFiles, f, ""));
|
|
105491
|
-
// top level files are for PXT, subolder are targets
|
|
105492
|
-
allFiles = allFiles.filter(f => {
|
|
105493
|
-
if (f.fullName.indexOf('/') < 0)
|
|
105494
|
-
return f.branch == pxtCrowdinBranch; // pxt file
|
|
105495
|
-
else
|
|
105496
|
-
return f.branch == targetCrowdinBranch;
|
|
105497
|
-
});
|
|
105498
|
-
// folder filter
|
|
105499
|
-
if (crowdinPath) {
|
|
105500
|
-
// filter out crowdin folder
|
|
105501
|
-
allFiles = allFiles.filter(f => f.fullName.indexOf(crowdinPath) == 0);
|
|
105502
|
-
}
|
|
105503
|
-
// filter out non-target files
|
|
105504
|
-
if (pxt.appTarget.id != "core") {
|
|
105505
|
-
const id = pxt.appTarget.id + '/';
|
|
105506
|
-
allFiles = allFiles.filter(f => {
|
|
105507
|
-
return f.fullName.indexOf('/') < 0 // top level file
|
|
105508
|
-
|| f.fullName.substr(0, id.length) == id // from the target folder
|
|
105509
|
-
|| f.fullName.indexOf('common-docs') >= 0; // common docs
|
|
105510
|
-
});
|
|
105511
|
-
}
|
|
105512
|
-
return allFiles;
|
|
105513
|
-
}
|
|
105514
|
-
function projectInfoAsync(prj, key) {
|
|
105515
|
-
const q = { json: "true" };
|
|
105516
|
-
const infoUri = apiUri("", prj, key, "info", q);
|
|
105517
|
-
return pxt.Util.httpGetTextAsync(infoUri).then(respText => {
|
|
105518
|
-
const info = JSON.parse(respText);
|
|
105519
|
-
return info;
|
|
105520
|
-
});
|
|
105521
|
-
}
|
|
105522
|
-
crowdin.projectInfoAsync = projectInfoAsync;
|
|
105523
|
-
/**
|
|
105524
|
-
* Scans files in crowdin and report files that are not on disk anymore
|
|
105525
|
-
*/
|
|
105526
|
-
function listFilesAsync(prj, key, crowdinPath) {
|
|
105527
|
-
pxt.log(`crowdin: listing files under ${crowdinPath}`);
|
|
105528
|
-
return projectInfoAsync(prj, key)
|
|
105529
|
-
.then(info => {
|
|
105530
|
-
if (!info)
|
|
105531
|
-
throw new Error("info failed");
|
|
105532
|
-
let allFiles = filterAndFlattenFiles(info.files, crowdinPath);
|
|
105533
|
-
pxt.debug(`crowdin: found ${allFiles.length} under ${crowdinPath}`);
|
|
105534
|
-
return allFiles.map(f => {
|
|
105535
|
-
return {
|
|
105536
|
-
fullName: f.fullName,
|
|
105537
|
-
branch: f.branch || ""
|
|
105538
|
-
};
|
|
105539
|
-
});
|
|
105540
|
-
});
|
|
105541
|
-
}
|
|
105542
|
-
crowdin.listFilesAsync = listFilesAsync;
|
|
105543
|
-
function languageStatsAsync(prj, key, lang) {
|
|
105544
|
-
const uri = apiUri("", prj, key, "language-status", { language: lang, json: "true" });
|
|
105545
|
-
return pxt.Util.httpGetJsonAsync(uri)
|
|
105546
|
-
.then(info => {
|
|
105547
|
-
const allFiles = filterAndFlattenFiles(info.files);
|
|
105548
|
-
return allFiles;
|
|
105549
|
-
});
|
|
105550
|
-
}
|
|
105551
|
-
crowdin.languageStatsAsync = languageStatsAsync;
|
|
105552
105312
|
function inContextLoadAsync(text) {
|
|
105553
105313
|
const node = document.createElement("input");
|
|
105554
105314
|
node.type = "text";
|
|
@@ -111039,11 +110799,12 @@ var pxt;
|
|
|
111039
110799
|
return result;
|
|
111040
110800
|
}
|
|
111041
110801
|
sprite_1.resizeTilemap = resizeTilemap;
|
|
111042
|
-
function imageLiteralToBitmap(text) {
|
|
110802
|
+
function imageLiteralToBitmap(text, templateLiteral = "img") {
|
|
111043
110803
|
// Strip the tagged template string business and the whitespace. We don't have to exhaustively
|
|
111044
110804
|
// replace encoded characters because the compiler will catch any disallowed characters and throw
|
|
111045
110805
|
// an error before the decompilation happens. 96 is backtick and 9 is tab
|
|
111046
110806
|
text = text.replace(/[ `]|(?:`)|(?:	)|(?:img)/g, "").trim();
|
|
110807
|
+
text = text.replaceAll(templateLiteral, "");
|
|
111047
110808
|
text = text.replace(/^["`\(\)]*/, '').replace(/["`\(\)]*$/, '');
|
|
111048
110809
|
text = text.replace(/ /g, "\n");
|
|
111049
110810
|
const rows = text.split("\n");
|
|
@@ -111205,14 +110966,14 @@ var pxt;
|
|
|
111205
110966
|
pxt.sprite.trimTilemapTileset(result);
|
|
111206
110967
|
}
|
|
111207
110968
|
sprite_1.updateTilemapReferencesFromResult = updateTilemapReferencesFromResult;
|
|
111208
|
-
function imageLiteralPrologue(fileType) {
|
|
110969
|
+
function imageLiteralPrologue(fileType, templateLiteral = "img") {
|
|
111209
110970
|
let res = '';
|
|
111210
110971
|
switch (fileType) {
|
|
111211
110972
|
case "python":
|
|
111212
|
-
res =
|
|
110973
|
+
res = `${templateLiteral}("""`;
|
|
111213
110974
|
break;
|
|
111214
110975
|
default:
|
|
111215
|
-
res =
|
|
110976
|
+
res = `${templateLiteral}\``;
|
|
111216
110977
|
break;
|
|
111217
110978
|
}
|
|
111218
110979
|
return res;
|
|
@@ -111243,10 +111004,10 @@ var pxt;
|
|
|
111243
111004
|
return res;
|
|
111244
111005
|
}
|
|
111245
111006
|
sprite_1.imageLiteralFromDimensions = imageLiteralFromDimensions;
|
|
111246
|
-
function bitmapToImageLiteral(bitmap, fileType) {
|
|
111007
|
+
function bitmapToImageLiteral(bitmap, fileType, templateLiteral = "img") {
|
|
111247
111008
|
if (!bitmap || bitmap.height === 0 || bitmap.width === 0)
|
|
111248
111009
|
return "";
|
|
111249
|
-
let res = imageLiteralPrologue(fileType);
|
|
111010
|
+
let res = imageLiteralPrologue(fileType, templateLiteral);
|
|
111250
111011
|
if (bitmap) {
|
|
111251
111012
|
const paddingBetweenPixels = (bitmap.width * bitmap.height > 300) ? "" : " ";
|
|
111252
111013
|
for (let r = 0; r < bitmap.height; r++) {
|
|
@@ -113747,11 +113508,7 @@ var pxt;
|
|
|
113747
113508
|
};
|
|
113748
113509
|
await loadDepsRecursive(null, this);
|
|
113749
113510
|
// get paletter config loading deps, so the more higher level packages take precedence
|
|
113750
|
-
|
|
113751
|
-
pxt.appTarget.runtime.palette = pxt.U.clone(this.config.palette);
|
|
113752
|
-
if (this.config.paletteNames)
|
|
113753
|
-
pxt.appTarget.runtime.paletteNames = this.config.paletteNames;
|
|
113754
|
-
}
|
|
113511
|
+
this.patchAppTargetPalette();
|
|
113755
113512
|
// get screen size loading deps, so the more higher level packages take precedence
|
|
113756
113513
|
if (this.config.screenSize && pxt.appTarget.runtime)
|
|
113757
113514
|
pxt.appTarget.runtime.screenSize = pxt.U.clone(this.config.screenSize);
|
|
@@ -113897,6 +113654,13 @@ var pxt;
|
|
|
113897
113654
|
}
|
|
113898
113655
|
return r;
|
|
113899
113656
|
}
|
|
113657
|
+
patchAppTargetPalette() {
|
|
113658
|
+
if (this.config.palette && pxt.appTarget.runtime) {
|
|
113659
|
+
pxt.appTarget.runtime.palette = pxt.U.clone(this.config.palette);
|
|
113660
|
+
if (this.config.paletteNames)
|
|
113661
|
+
pxt.appTarget.runtime.paletteNames = this.config.paletteNames;
|
|
113662
|
+
}
|
|
113663
|
+
}
|
|
113900
113664
|
}
|
|
113901
113665
|
Package.depWarnings = {};
|
|
113902
113666
|
pxt.Package = Package;
|
|
@@ -114158,6 +113922,10 @@ var pxt;
|
|
|
114158
113922
|
opts.jres = this.getJRes();
|
|
114159
113923
|
const functionOpts = pxt.appTarget.runtime && pxt.appTarget.runtime.functionsOptions;
|
|
114160
113924
|
opts.allowedArgumentTypes = functionOpts && functionOpts.extraFunctionEditorTypes && functionOpts.extraFunctionEditorTypes.map(info => info.typeName).concat("number", "boolean", "string");
|
|
113925
|
+
for (const dep of this.sortedDeps()) {
|
|
113926
|
+
dep.patchAppTargetPalette();
|
|
113927
|
+
}
|
|
113928
|
+
this.patchAppTargetPalette();
|
|
114161
113929
|
return opts;
|
|
114162
113930
|
}
|
|
114163
113931
|
prepareConfigToBePublished() {
|
|
@@ -160874,7 +160642,7 @@ function checkIfTaggedCommitAsync() {
|
|
|
160874
160642
|
});
|
|
160875
160643
|
}
|
|
160876
160644
|
let readJson = nodeutil.readJson;
|
|
160877
|
-
function ciAsync() {
|
|
160645
|
+
async function ciAsync() {
|
|
160878
160646
|
forceCloudBuild = true;
|
|
160879
160647
|
const buildInfo = ciBuildInfo();
|
|
160880
160648
|
pxt.log(`ci build using ${buildInfo.ci}`);
|
|
@@ -160920,55 +160688,54 @@ function ciAsync() {
|
|
|
160920
160688
|
let pkg = readJson("package.json");
|
|
160921
160689
|
if (pkg["name"] == "pxt-core") {
|
|
160922
160690
|
pxt.log("pxt-core build");
|
|
160923
|
-
|
|
160924
|
-
|
|
160925
|
-
|
|
160926
|
-
|
|
160927
|
-
if (
|
|
160928
|
-
|
|
160929
|
-
|
|
160930
|
-
|
|
160931
|
-
|
|
160932
|
-
|
|
160933
|
-
|
|
160934
|
-
|
|
160935
|
-
|
|
160936
|
-
|
|
160937
|
-
p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
|
|
160938
|
-
if (uploadDocs || uploadApiStrings)
|
|
160939
|
-
p = p.then(() => crowdin.internalUploadTargetTranslationsAsync(uploadApiStrings, uploadDocs));
|
|
160691
|
+
const isTaggedCommit = await checkIfTaggedCommitAsync();
|
|
160692
|
+
pxt.log(`is tagged commit: ${isTaggedCommit}`);
|
|
160693
|
+
await npmPublishAsync();
|
|
160694
|
+
if (branch === "master" && isTaggedCommit) {
|
|
160695
|
+
if (uploadDocs) {
|
|
160696
|
+
await buildWebStringsAsync();
|
|
160697
|
+
await crowdin.uploadBuiltStringsAsync("built/webstrings.json");
|
|
160698
|
+
await crowdin.uploadBuiltStringsAsync(`built/skillmap-strings.json`);
|
|
160699
|
+
await crowdin.uploadBuiltStringsAsync(`built/authcode-strings.json`);
|
|
160700
|
+
await crowdin.uploadBuiltStringsAsync(`built/multiplayer-strings.json`);
|
|
160701
|
+
await crowdin.uploadBuiltStringsAsync(`built/kiosk-strings.json`);
|
|
160702
|
+
}
|
|
160703
|
+
if (uploadApiStrings) {
|
|
160704
|
+
await crowdin.uploadBuiltStringsAsync("built/strings.json");
|
|
160940
160705
|
}
|
|
160941
|
-
|
|
160942
|
-
|
|
160706
|
+
if (uploadDocs || uploadApiStrings) {
|
|
160707
|
+
await crowdin.internalUploadTargetTranslationsAsync(uploadApiStrings, uploadDocs);
|
|
160708
|
+
pxt.log("translations uploaded");
|
|
160709
|
+
}
|
|
160710
|
+
else {
|
|
160711
|
+
pxt.log("skipping translations upload");
|
|
160712
|
+
}
|
|
160713
|
+
}
|
|
160943
160714
|
}
|
|
160944
160715
|
else {
|
|
160945
160716
|
pxt.log("target build");
|
|
160946
|
-
|
|
160947
|
-
|
|
160948
|
-
|
|
160949
|
-
|
|
160950
|
-
|
|
160951
|
-
|
|
160952
|
-
|
|
160953
|
-
|
|
160954
|
-
|
|
160955
|
-
}
|
|
160717
|
+
await internalBuildTargetAsync();
|
|
160718
|
+
await internalCheckDocsAsync(true);
|
|
160719
|
+
await blockTestsAsync();
|
|
160720
|
+
await npmPublishAsync();
|
|
160721
|
+
if (!process.env["PXT_ACCESS_TOKEN"]) {
|
|
160722
|
+
// pull request, don't try to upload target
|
|
160723
|
+
pxt.log('no token, skipping upload');
|
|
160724
|
+
}
|
|
160725
|
+
else {
|
|
160956
160726
|
const trg = readLocalPxTarget();
|
|
160957
160727
|
const label = `${trg.id}/${tag || latest}`;
|
|
160958
160728
|
pxt.log(`uploading target with label ${label}...`);
|
|
160959
|
-
|
|
160960
|
-
}
|
|
160961
|
-
|
|
160962
|
-
|
|
160963
|
-
|
|
160964
|
-
|
|
160965
|
-
|
|
160966
|
-
|
|
160967
|
-
|
|
160968
|
-
|
|
160969
|
-
return Promise.resolve();
|
|
160970
|
-
}
|
|
160971
|
-
});
|
|
160729
|
+
await uploadTargetAsync(label);
|
|
160730
|
+
}
|
|
160731
|
+
pxt.log("target uploaded");
|
|
160732
|
+
if (uploadDocs || uploadApiStrings) {
|
|
160733
|
+
await crowdin.internalUploadTargetTranslationsAsync(uploadApiStrings, uploadDocs);
|
|
160734
|
+
pxt.log("translations uploaded");
|
|
160735
|
+
}
|
|
160736
|
+
else {
|
|
160737
|
+
pxt.log("skipping translations upload");
|
|
160738
|
+
}
|
|
160972
160739
|
}
|
|
160973
160740
|
}
|
|
160974
160741
|
function lintJSONInDirectory(dir) {
|
|
@@ -166839,7 +166606,7 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
166839
166606
|
advanced: true,
|
|
166840
166607
|
}, pc => uploadTargetRefsAsync(pc.args[0]));
|
|
166841
166608
|
advancedCommand("uploadtt", "upload tagged release", uploadTaggedTargetAsync, "");
|
|
166842
|
-
advancedCommand("downloadtrgtranslations", "download translations from bundled projects", crowdin.downloadTargetTranslationsAsync, "
|
|
166609
|
+
advancedCommand("downloadtrgtranslations", "download translations from bundled projects", crowdin.downloadTargetTranslationsAsync, "[package]");
|
|
166843
166610
|
p.defineCommand({
|
|
166844
166611
|
name: "checkdocs",
|
|
166845
166612
|
onlineHelp: true,
|
|
@@ -166917,7 +166684,19 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
166917
166684
|
}
|
|
166918
166685
|
}, buildAuthcodeAsync);
|
|
166919
166686
|
advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
|
|
166920
|
-
|
|
166687
|
+
p.defineCommand({
|
|
166688
|
+
name: "crowdin",
|
|
166689
|
+
advanced: true,
|
|
166690
|
+
argString: "<cmd> <path> [output]",
|
|
166691
|
+
help: "upload, download, clean, stats files to/from crowdin",
|
|
166692
|
+
flags: {
|
|
166693
|
+
test: { description: "test run, do not upload files to crowdin" }
|
|
166694
|
+
}
|
|
166695
|
+
}, pc => {
|
|
166696
|
+
if (pc.flags.test)
|
|
166697
|
+
pxt.crowdin.setTestMode();
|
|
166698
|
+
return crowdin.execCrowdinAsync.apply(undefined, pc.args);
|
|
166699
|
+
});
|
|
166921
166700
|
advancedCommand("hidlist", "list HID devices", hid.listAsync);
|
|
166922
166701
|
advancedCommand("hidserial", "run HID serial forwarding", hid.serialAsync, undefined, true);
|
|
166923
166702
|
advancedCommand("hiddmesg", "fetch DMESG buffer over HID and print it", hid.dmesgAsync, undefined, true);
|
package/built/pxtblockly.js
CHANGED
|
@@ -12159,7 +12159,7 @@ var pxtblockly;
|
|
|
12159
12159
|
const existing = pxt.lookupProjectAssetByTSReference(text, project);
|
|
12160
12160
|
if (existing)
|
|
12161
12161
|
return existing;
|
|
12162
|
-
const frames = parseImageArrayString(text);
|
|
12162
|
+
const frames = parseImageArrayString(text, this.params.taggedTemplate);
|
|
12163
12163
|
if (frames && frames.length) {
|
|
12164
12164
|
const id = this.sourceBlock_.id;
|
|
12165
12165
|
const newAnimation = {
|
|
@@ -12195,7 +12195,7 @@ var pxtblockly;
|
|
|
12195
12195
|
if (!this.asset)
|
|
12196
12196
|
return "[]";
|
|
12197
12197
|
if (this.isTemporaryAsset()) {
|
|
12198
|
-
return "[" + this.asset.frames.map(frame => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(frame), "typescript" /* pxt.editor.FileType.TypeScript
|
|
12198
|
+
return "[" + this.asset.frames.map(frame => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(frame), "typescript" /* pxt.editor.FileType.TypeScript */, this.params.taggedTemplate)).join(",") + "]";
|
|
12199
12199
|
}
|
|
12200
12200
|
return pxt.getTSReferenceForAsset(this.asset);
|
|
12201
12201
|
}
|
|
@@ -12274,6 +12274,7 @@ var pxtblockly;
|
|
|
12274
12274
|
}
|
|
12275
12275
|
parsed.initWidth = withDefault(opts.initWidth, parsed.initWidth);
|
|
12276
12276
|
parsed.initHeight = withDefault(opts.initHeight, parsed.initHeight);
|
|
12277
|
+
parsed.taggedTemplate = opts.taggedTemplate;
|
|
12277
12278
|
return parsed;
|
|
12278
12279
|
function withDefault(raw, def) {
|
|
12279
12280
|
const res = parseInt(raw);
|
|
@@ -12283,11 +12284,11 @@ var pxtblockly;
|
|
|
12283
12284
|
return res;
|
|
12284
12285
|
}
|
|
12285
12286
|
}
|
|
12286
|
-
function parseImageArrayString(str) {
|
|
12287
|
+
function parseImageArrayString(str, templateLiteral) {
|
|
12287
12288
|
if (str.indexOf("[") === -1)
|
|
12288
12289
|
return null;
|
|
12289
12290
|
str = str.replace(/[\[\]]/mg, "");
|
|
12290
|
-
return str.split(",").map(s => pxt.sprite.imageLiteralToBitmap(s).data()).filter(b => b.height && b.width);
|
|
12291
|
+
return str.split(",").map(s => pxt.sprite.imageLiteralToBitmap(s, templateLiteral).data()).filter(b => b.height && b.width);
|
|
12291
12292
|
}
|
|
12292
12293
|
function isNumberType(type) {
|
|
12293
12294
|
return type === "math_number" || type === "math_integer" || type === "math_whole_number";
|
|
@@ -16326,7 +16327,7 @@ var pxtblockly;
|
|
|
16326
16327
|
if (this.getBlockData()) {
|
|
16327
16328
|
return project.lookupAsset("image" /* pxt.AssetType.Image */, this.getBlockData());
|
|
16328
16329
|
}
|
|
16329
|
-
const bmp = text ? pxt.sprite.imageLiteralToBitmap(text) : new pxt.sprite.Bitmap(this.params.initWidth, this.params.initHeight);
|
|
16330
|
+
const bmp = text ? pxt.sprite.imageLiteralToBitmap(text, this.params.taggedTemplate) : new pxt.sprite.Bitmap(this.params.initWidth, this.params.initHeight);
|
|
16330
16331
|
if (!bmp) {
|
|
16331
16332
|
this.isGreyBlock = true;
|
|
16332
16333
|
this.valueText = text;
|
|
@@ -16347,7 +16348,7 @@ var pxtblockly;
|
|
|
16347
16348
|
if (this.asset && !this.isTemporaryAsset()) {
|
|
16348
16349
|
return pxt.getTSReferenceForAsset(this.asset);
|
|
16349
16350
|
}
|
|
16350
|
-
return pxt.sprite.bitmapToImageLiteral(this.asset && pxt.sprite.Bitmap.fromData(this.asset.bitmap), "typescript" /* pxt.editor.FileType.TypeScript
|
|
16351
|
+
return pxt.sprite.bitmapToImageLiteral(this.asset && pxt.sprite.Bitmap.fromData(this.asset.bitmap), "typescript" /* pxt.editor.FileType.TypeScript */, this.params.taggedTemplate);
|
|
16351
16352
|
}
|
|
16352
16353
|
parseFieldOptions(opts) {
|
|
16353
16354
|
return parseFieldOptions(opts);
|
|
@@ -16402,6 +16403,7 @@ var pxtblockly;
|
|
|
16402
16403
|
parsed.initColor = withDefault(opts.initColor, parsed.initColor);
|
|
16403
16404
|
parsed.initWidth = withDefault(opts.initWidth, parsed.initWidth);
|
|
16404
16405
|
parsed.initHeight = withDefault(opts.initHeight, parsed.initHeight);
|
|
16406
|
+
parsed.taggedTemplate = opts.taggedTemplate;
|
|
16405
16407
|
return parsed;
|
|
16406
16408
|
function withDefault(raw, def) {
|
|
16407
16409
|
const res = parseInt(raw);
|
package/built/pxtblocks.d.ts
CHANGED
|
@@ -498,6 +498,7 @@ declare namespace pxtblockly {
|
|
|
498
498
|
disableResize: string;
|
|
499
499
|
filter?: string;
|
|
500
500
|
lightMode: boolean;
|
|
501
|
+
taggedTemplate?: string;
|
|
501
502
|
}
|
|
502
503
|
interface ParsedFieldAnimationOptions {
|
|
503
504
|
initWidth: number;
|
|
@@ -505,6 +506,7 @@ declare namespace pxtblockly {
|
|
|
505
506
|
disableResize: boolean;
|
|
506
507
|
filter?: string;
|
|
507
508
|
lightMode: boolean;
|
|
509
|
+
taggedTemplate?: string;
|
|
508
510
|
}
|
|
509
511
|
class FieldAnimationEditor extends FieldAssetEditor<FieldAnimationOptions, ParsedFieldAnimationOptions> {
|
|
510
512
|
protected frames: string[];
|
|
@@ -1293,6 +1295,7 @@ declare namespace pxtblockly {
|
|
|
1293
1295
|
disableResize: string;
|
|
1294
1296
|
filter?: string;
|
|
1295
1297
|
lightMode: boolean;
|
|
1298
|
+
taggedTemplate?: string;
|
|
1296
1299
|
}
|
|
1297
1300
|
interface ParsedSpriteEditorOptions {
|
|
1298
1301
|
initColor: number;
|
|
@@ -1301,6 +1304,7 @@ declare namespace pxtblockly {
|
|
|
1301
1304
|
disableResize: boolean;
|
|
1302
1305
|
filter?: string;
|
|
1303
1306
|
lightMode: boolean;
|
|
1307
|
+
taggedTemplate?: string;
|
|
1304
1308
|
}
|
|
1305
1309
|
export class FieldSpriteEditor extends FieldAssetEditor<FieldSpriteEditorOptions, ParsedSpriteEditorOptions> {
|
|
1306
1310
|
protected getAssetType(): pxt.AssetType;
|
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);
|