@bitcobblers/wod-wiki-lang 0.44.2159 → 0.45.2166
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/dist/{browserRuntimeNow-_zhhbzoE.d.cts → browserRuntimeNow-CnGciOM0.d.cts} +15 -11
- package/dist/{browserRuntimeNow-_zhhbzoE.d.ts → browserRuntimeNow-CnGciOM0.d.ts} +15 -11
- package/dist/index.cjs +350 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -32
- package/dist/index.d.ts +110 -32
- package/dist/index.mjs +342 -31
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -2,8 +2,9 @@ import { wallClockNow, formatDurationSmart } from './chunk-PFQDVQQO.mjs';
|
|
|
2
2
|
export { createBrowserRuntimeNow, frozenNow, getRuntimeNowMs, wallClockNow } from './chunk-PFQDVQQO.mjs';
|
|
3
3
|
import { MetricType, MetricContainer, BlockKey, REFERENCE_METADATA_KEY, ParsedCodeStatement, TAG_REFERENCE_METADATA_KEY, getReferenceMetadata, OutputStatement, valueKindOf, normalizeFieldPath, getTagReference } from '@bitcobblers/wod-wiki-core';
|
|
4
4
|
import { LRParser } from '@lezer/lr';
|
|
5
|
-
import { LRLanguage, LanguageSupport } from '@codemirror/language';
|
|
5
|
+
import { LRLanguage, LanguageSupport, syntaxTree } from '@codemirror/language';
|
|
6
6
|
import { NodeProp } from '@lezer/common';
|
|
7
|
+
import { snippetCompletion, autocompletion } from '@codemirror/autocomplete';
|
|
7
8
|
import { v7 } from 'uuid';
|
|
8
9
|
|
|
9
10
|
// src/registry/Registry.ts
|
|
@@ -648,6 +649,40 @@ function residualMeta(effortMeta, rest) {
|
|
|
648
649
|
raw: rest
|
|
649
650
|
};
|
|
650
651
|
}
|
|
652
|
+
var TRAILING_WORD = /^([\s\S]*?)([a-zA-Z]+)$/;
|
|
653
|
+
function splitTrailingWord(text) {
|
|
654
|
+
const m = TRAILING_WORD.exec(text.trimEnd());
|
|
655
|
+
if (!m) return null;
|
|
656
|
+
return { rest: m[1].trim(), token: m[2] };
|
|
657
|
+
}
|
|
658
|
+
function trailingResidualMeta(effortMeta, rest) {
|
|
659
|
+
if (!effortMeta) return effortMeta;
|
|
660
|
+
return {
|
|
661
|
+
line: effortMeta.line,
|
|
662
|
+
startOffset: effortMeta.startOffset,
|
|
663
|
+
endOffset: effortMeta.startOffset !== void 0 ? effortMeta.startOffset + rest.length : effortMeta.endOffset,
|
|
664
|
+
columnStart: effortMeta.columnStart,
|
|
665
|
+
columnEnd: effortMeta.columnStart !== void 0 ? effortMeta.columnStart + rest.length : effortMeta.columnEnd,
|
|
666
|
+
length: rest.length,
|
|
667
|
+
raw: rest
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function trailingTokenMeta(effortMeta, token) {
|
|
671
|
+
if (!effortMeta) return effortMeta;
|
|
672
|
+
const tokenStart = Math.max(
|
|
673
|
+
0,
|
|
674
|
+
(effortMeta.raw?.trimEnd().length ?? (effortMeta.endOffset ?? 0) - (effortMeta.startOffset ?? 0)) - token.length
|
|
675
|
+
);
|
|
676
|
+
return {
|
|
677
|
+
line: effortMeta.line,
|
|
678
|
+
startOffset: effortMeta.startOffset !== void 0 ? effortMeta.startOffset + tokenStart : void 0,
|
|
679
|
+
endOffset: effortMeta.startOffset !== void 0 ? effortMeta.startOffset + tokenStart + token.length : effortMeta.endOffset,
|
|
680
|
+
columnStart: effortMeta.columnStart !== void 0 ? effortMeta.columnStart + tokenStart : void 0,
|
|
681
|
+
columnEnd: effortMeta.columnStart !== void 0 ? effortMeta.columnStart + tokenStart + token.length : effortMeta.columnEnd,
|
|
682
|
+
length: token.length,
|
|
683
|
+
raw: token
|
|
684
|
+
};
|
|
685
|
+
}
|
|
651
686
|
function spanMeta(firstMeta, lastMeta) {
|
|
652
687
|
if (!firstMeta || !lastMeta) return firstMeta ?? lastMeta;
|
|
653
688
|
const startOffset = firstMeta.startOffset;
|
|
@@ -784,6 +819,22 @@ function fusePairs(pairs, units) {
|
|
|
784
819
|
}
|
|
785
820
|
}
|
|
786
821
|
}
|
|
822
|
+
if (!next) {
|
|
823
|
+
const text = effortText(cur.metric);
|
|
824
|
+
const split = text !== null ? splitTrailingWord(text) : null;
|
|
825
|
+
const unit = split ? units.get(split.token) : void 0;
|
|
826
|
+
if (split && split.rest && unit && unit.canonical === "bw") {
|
|
827
|
+
out.push({
|
|
828
|
+
metric: new EffortMetric(split.rest),
|
|
829
|
+
meta: trailingResidualMeta(cur.meta, split.rest)
|
|
830
|
+
});
|
|
831
|
+
out.push({
|
|
832
|
+
metric: metricForDimension(void 0, split.token, unit.dimension),
|
|
833
|
+
meta: trailingTokenMeta(cur.meta, split.token)
|
|
834
|
+
});
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
787
838
|
out.push(cur);
|
|
788
839
|
}
|
|
789
840
|
return out;
|
|
@@ -915,6 +966,13 @@ var WodDialect = class {
|
|
|
915
966
|
return { metrics: hintsToContainer(hints) };
|
|
916
967
|
}
|
|
917
968
|
};
|
|
969
|
+
var CARDIO_ACTIVITY_KEYWORDS = [
|
|
970
|
+
{ keywords: ["RUN", "JOG", "SPRINT"], hints: ["workout.run", "behavior.aerobic"] },
|
|
971
|
+
{ keywords: ["ROW", "ROWING"], hints: ["workout.row", "behavior.aerobic"] },
|
|
972
|
+
{ keywords: ["BIKE", "CYCLE", "CYCLING"], hints: ["workout.bike", "behavior.aerobic"] },
|
|
973
|
+
{ keywords: ["SWIM", "SWIMMING"], hints: ["workout.swim", "behavior.aerobic"] },
|
|
974
|
+
{ keywords: ["WALK", "WALKING"], hints: ["workout.walk"] }
|
|
975
|
+
];
|
|
918
976
|
var CardioDialect = class {
|
|
919
977
|
id = "cardio";
|
|
920
978
|
name = "Cardio Dialect";
|
|
@@ -929,29 +987,10 @@ var CardioDialect = class {
|
|
|
929
987
|
analyze(statement) {
|
|
930
988
|
const hints = [];
|
|
931
989
|
const metrics = MetricContainer.from(statement.metrics);
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
}
|
|
937
|
-
if (this.hasKeyword(metrics, "ROW") || this.hasKeyword(metrics, "ROWING")) {
|
|
938
|
-
hints.push("domain.cardio");
|
|
939
|
-
hints.push("workout.row");
|
|
940
|
-
hints.push("behavior.aerobic");
|
|
941
|
-
}
|
|
942
|
-
if (this.hasKeyword(metrics, "BIKE") || this.hasKeyword(metrics, "CYCLE") || this.hasKeyword(metrics, "CYCLING")) {
|
|
943
|
-
hints.push("domain.cardio");
|
|
944
|
-
hints.push("workout.bike");
|
|
945
|
-
hints.push("behavior.aerobic");
|
|
946
|
-
}
|
|
947
|
-
if (this.hasKeyword(metrics, "SWIM") || this.hasKeyword(metrics, "SWIMMING")) {
|
|
948
|
-
hints.push("domain.cardio");
|
|
949
|
-
hints.push("workout.swim");
|
|
950
|
-
hints.push("behavior.aerobic");
|
|
951
|
-
}
|
|
952
|
-
if (this.hasKeyword(metrics, "WALK") || this.hasKeyword(metrics, "WALKING")) {
|
|
953
|
-
hints.push("domain.cardio");
|
|
954
|
-
hints.push("workout.walk");
|
|
990
|
+
for (const activity of CARDIO_ACTIVITY_KEYWORDS) {
|
|
991
|
+
if (activity.keywords.some((keyword2) => this.hasKeyword(metrics, keyword2))) {
|
|
992
|
+
hints.push("domain.cardio", ...activity.hints);
|
|
993
|
+
}
|
|
955
994
|
}
|
|
956
995
|
if (hints.length === 0 && this.hasDistance(metrics)) {
|
|
957
996
|
hints.push("domain.cardio");
|
|
@@ -2503,7 +2542,7 @@ var WhiteboardScript = class {
|
|
|
2503
2542
|
|
|
2504
2543
|
// src/effort-registry/types.ts
|
|
2505
2544
|
var EFFORT_REGISTRY_ORIGINS = ["bundled", "user"];
|
|
2506
|
-
var
|
|
2545
|
+
var SEED_PRECEDENCE_RANK = {
|
|
2507
2546
|
core: 0,
|
|
2508
2547
|
community: 1,
|
|
2509
2548
|
imported: 2,
|
|
@@ -2519,14 +2558,14 @@ function resolveSourceTier(sourceIdOrMetaKey, explicitTier) {
|
|
|
2519
2558
|
return "imported";
|
|
2520
2559
|
}
|
|
2521
2560
|
function resolveSourceRank(sourceIdOrMetaKey, explicitTier) {
|
|
2522
|
-
return
|
|
2561
|
+
return SEED_PRECEDENCE_RANK[resolveSourceTier(sourceIdOrMetaKey, explicitTier)];
|
|
2523
2562
|
}
|
|
2524
2563
|
function resolveEntityTier(entity) {
|
|
2525
2564
|
if (entity.registrySource === "user") return "user";
|
|
2526
2565
|
return resolveSourceTier(entity.sourceId);
|
|
2527
2566
|
}
|
|
2528
2567
|
function resolveEntityRank(entity) {
|
|
2529
|
-
return
|
|
2568
|
+
return SEED_PRECEDENCE_RANK[resolveEntityTier(entity)];
|
|
2530
2569
|
}
|
|
2531
2570
|
function dedupeEntitiesByPrecedence(entities) {
|
|
2532
2571
|
const bySlug = /* @__PURE__ */ new Map();
|
|
@@ -3643,6 +3682,273 @@ tagHighlighter([
|
|
|
3643
3682
|
{ tag: tags.invalid, class: "tok-invalid" },
|
|
3644
3683
|
{ tag: tags.punctuation, class: "tok-punctuation" }
|
|
3645
3684
|
]);
|
|
3685
|
+
var whiteboardScriptSnippets = [
|
|
3686
|
+
{
|
|
3687
|
+
name: "circuit",
|
|
3688
|
+
label: "Circuit",
|
|
3689
|
+
detail: "Rounds over indented movements",
|
|
3690
|
+
template: "(${1:3})\n ${2:10 Air Squats}\n ${3:10 Push Ups}\n ${4:10 Ring Rows}\n${0}"
|
|
3691
|
+
},
|
|
3692
|
+
{
|
|
3693
|
+
name: "5x5",
|
|
3694
|
+
label: "5x5",
|
|
3695
|
+
detail: "Inline strength sets",
|
|
3696
|
+
template: "${1:5}x${2:5} ${3:Back Squat} @${4:100kg}\n${0}"
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
name: "emom",
|
|
3700
|
+
label: "EMOM",
|
|
3701
|
+
detail: "Every minute on the minute",
|
|
3702
|
+
template: "(${1:10}) ${2::60 EMOM}\n + ${3:5 Burpees}\n + ${4:10 Kettlebell Swings 24kg}\n${0}"
|
|
3703
|
+
},
|
|
3704
|
+
{
|
|
3705
|
+
name: "amrap",
|
|
3706
|
+
label: "AMRAP",
|
|
3707
|
+
detail: "As many rounds as possible",
|
|
3708
|
+
template: "${1:10:00 AMRAP}\n ${2:5 Pull Ups}\n ${3:10 Push Ups}\n ${4:15 Air Squats}\n${0}"
|
|
3709
|
+
},
|
|
3710
|
+
{
|
|
3711
|
+
name: "tabata",
|
|
3712
|
+
label: "Tabata",
|
|
3713
|
+
detail: "Work/rest intervals",
|
|
3714
|
+
template: "(${1:8}) ${2::20 Work}\n * ${3::10 Rest}\n ${4:KB Snatch 16kg}\n${0}"
|
|
3715
|
+
},
|
|
3716
|
+
{
|
|
3717
|
+
name: "ladder",
|
|
3718
|
+
label: "Ladder",
|
|
3719
|
+
detail: "Rep ladder (21-15-9)",
|
|
3720
|
+
template: "(${1:21-15-9})\n ${2:Thrusters 95lb}\n ${3:Pull-ups}\n${0}"
|
|
3721
|
+
},
|
|
3722
|
+
{
|
|
3723
|
+
name: "choice",
|
|
3724
|
+
label: "Choice",
|
|
3725
|
+
detail: "Athlete choice between alternatives",
|
|
3726
|
+
template: "${1:10 Power Cleans 135/95 lb}\n${0}"
|
|
3727
|
+
},
|
|
3728
|
+
{
|
|
3729
|
+
name: "superset",
|
|
3730
|
+
label: "Superset",
|
|
3731
|
+
detail: "Compound set via + lap markers",
|
|
3732
|
+
template: "+ ${1:5 Pull Ups}\n+ ${2:10 Push Ups}\n${0}"
|
|
3733
|
+
},
|
|
3734
|
+
{
|
|
3735
|
+
name: "collectible",
|
|
3736
|
+
label: "Collectible",
|
|
3737
|
+
detail: "Measure time instead of prescribing it (:?)",
|
|
3738
|
+
template: "${1::? 400m Run}\n${0}"
|
|
3739
|
+
}
|
|
3740
|
+
];
|
|
3741
|
+
function applyTemplateDefaults(template) {
|
|
3742
|
+
return template.replace(/\$\{\d+:([^}]*)\}/g, "$1").replace(/\$\{\d+\}/g, "").replace(/\$\d+/g, "");
|
|
3743
|
+
}
|
|
3744
|
+
function snippetCompletions() {
|
|
3745
|
+
return whiteboardScriptSnippets.map(
|
|
3746
|
+
(snippet) => snippetCompletion(snippet.template, {
|
|
3747
|
+
label: snippet.label,
|
|
3748
|
+
detail: snippet.detail,
|
|
3749
|
+
type: "text",
|
|
3750
|
+
boost: 10
|
|
3751
|
+
})
|
|
3752
|
+
);
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
// src/parser/completion.ts
|
|
3756
|
+
var COMPLETION_PROPERTY_KEYS = ["effort", "equipment", ...Object.keys(PROPERTY_KEY_TO_METRIC_TYPE)];
|
|
3757
|
+
var STRUCTURE_KEYWORD_LABELS = ["amrap", "emom", "tabata", "for time", "rest"];
|
|
3758
|
+
var STRUCTURE_KEYWORD_DISPLAY = {
|
|
3759
|
+
"for time": "FOR TIME",
|
|
3760
|
+
rest: "Rest"
|
|
3761
|
+
};
|
|
3762
|
+
function unitCompletions(units, dimension) {
|
|
3763
|
+
return units.toArray().filter((def) => !dimension || def.dimension === dimension).flatMap((def) => [
|
|
3764
|
+
{ label: def.canonical, detail: def.dimension, type: "unit", boost: 1 },
|
|
3765
|
+
...def.aliases.map((alias) => ({ label: alias, detail: def.dimension, type: "unit" }))
|
|
3766
|
+
]);
|
|
3767
|
+
}
|
|
3768
|
+
function titleCase(word) {
|
|
3769
|
+
return word.toLowerCase().replace(/(^|[\s])([a-z])/g, (_, lead, ch) => lead + ch.toUpperCase());
|
|
3770
|
+
}
|
|
3771
|
+
function unique(words) {
|
|
3772
|
+
return [...new Set(words)];
|
|
3773
|
+
}
|
|
3774
|
+
var SPORT_VOCABULARY = {
|
|
3775
|
+
cardio: () => unique(CARDIO_ACTIVITY_KEYWORDS.flatMap((activity) => activity.keywords)).map((word) => ({
|
|
3776
|
+
label: titleCase(word),
|
|
3777
|
+
detail: "cardio",
|
|
3778
|
+
type: "text"
|
|
3779
|
+
})),
|
|
3780
|
+
yoga: () => unique([
|
|
3781
|
+
...YogaDialect.POSE_KEYWORDS,
|
|
3782
|
+
...YogaDialect.FLOW_KEYWORDS,
|
|
3783
|
+
...YogaDialect.BREATHING_KEYWORDS,
|
|
3784
|
+
...YogaDialect.MEDITATION_KEYWORDS
|
|
3785
|
+
]).filter((word) => /^[A-Z ]+$/.test(word)).map((word) => ({ label: titleCase(word), detail: "yoga", type: "text" })),
|
|
3786
|
+
habits: () => unique([...HabitsDialect.HABIT_KEYWORDS, ...HabitsDialect.STREAK_KEYWORDS]).map((word) => ({
|
|
3787
|
+
label: titleCase(word),
|
|
3788
|
+
detail: "habits",
|
|
3789
|
+
type: "text"
|
|
3790
|
+
})),
|
|
3791
|
+
climb: () => [
|
|
3792
|
+
...unique(Object.values(SEND_ALIASES)).map((send) => ({ label: send, detail: "send", type: "text" })),
|
|
3793
|
+
...unique(Object.values(DISCIPLINE_KEYWORDS)).map((discipline) => ({ label: discipline, detail: "discipline", type: "text" }))
|
|
3794
|
+
]
|
|
3795
|
+
};
|
|
3796
|
+
function structureKeywords() {
|
|
3797
|
+
return STRUCTURE_KEYWORD_LABELS.filter((word) => STRUCTURAL_EFFORT_WORDS.has(word)).map((word) => ({
|
|
3798
|
+
label: STRUCTURE_KEYWORD_DISPLAY[word] ?? word.toUpperCase(),
|
|
3799
|
+
detail: "structure",
|
|
3800
|
+
type: "keyword",
|
|
3801
|
+
boost: 5,
|
|
3802
|
+
apply: STRUCTURE_KEYWORD_DISPLAY[word] ?? word.toUpperCase()
|
|
3803
|
+
}));
|
|
3804
|
+
}
|
|
3805
|
+
function toCompletions(values, detail, quoteValues = false) {
|
|
3806
|
+
return values.map((value) => ({
|
|
3807
|
+
label: value.label ?? value.value,
|
|
3808
|
+
// `Property` values only lex as String | Number | Identifier, and
|
|
3809
|
+
// Identifier is `[a-zA-Z][a-zA-Z0-9]*` — quote slugs it cannot represent
|
|
3810
|
+
// (hyphens, spaces, leading digits) so they insert parse-valid text;
|
|
3811
|
+
// `parsePropertyValue` unwraps the quotes when the property is consumed.
|
|
3812
|
+
apply: quoteValues && !/^[A-Za-z][A-Za-z0-9]*$/.test(value.value) ? JSON.stringify(value.value) : value.value,
|
|
3813
|
+
detail: value.detail ?? detail,
|
|
3814
|
+
type: "text",
|
|
3815
|
+
info: value.info
|
|
3816
|
+
}));
|
|
3817
|
+
}
|
|
3818
|
+
function dialectWords(sport) {
|
|
3819
|
+
if (!sport) return [];
|
|
3820
|
+
const vocabulary = SPORT_VOCABULARY[SPORT_ALIASES[sport] ?? sport];
|
|
3821
|
+
return vocabulary ? vocabulary() : [];
|
|
3822
|
+
}
|
|
3823
|
+
function ancestor(node, name2) {
|
|
3824
|
+
for (let current = node; current; current = current.parent) {
|
|
3825
|
+
if (current.name === name2) return current;
|
|
3826
|
+
}
|
|
3827
|
+
return null;
|
|
3828
|
+
}
|
|
3829
|
+
function currentStatement(context) {
|
|
3830
|
+
const tree = syntaxTree(context.state);
|
|
3831
|
+
const line = context.state.doc.lineAt(context.pos);
|
|
3832
|
+
if (context.pos === line.from) return null;
|
|
3833
|
+
const resolved = tree.resolveInner(context.pos, -1);
|
|
3834
|
+
const statement = ancestor(resolved, "Block") ?? ancestor(resolved, "Property");
|
|
3835
|
+
if (statement) return statement;
|
|
3836
|
+
const beforeCursor = tree.resolveInner(context.pos - 1, -1);
|
|
3837
|
+
return ancestor(beforeCursor, "Block") ?? ancestor(beforeCursor, "Property");
|
|
3838
|
+
}
|
|
3839
|
+
function suppliedPropertyKeys(context) {
|
|
3840
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3841
|
+
for (const property of syntaxTree(context.state).topNode.getChildren("Property")) {
|
|
3842
|
+
const identifier = property.firstChild;
|
|
3843
|
+
if (identifier?.name === "Identifier") {
|
|
3844
|
+
keys.add(context.state.doc.sliceString(identifier.from, identifier.to).toLowerCase());
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
return keys;
|
|
3848
|
+
}
|
|
3849
|
+
function isUnitFragment(context, fragment, units) {
|
|
3850
|
+
return fragment.firstChild?.name === "Effort" && units.has(context.state.doc.sliceString(fragment.from, fragment.to));
|
|
3851
|
+
}
|
|
3852
|
+
function trailingEffortRun(context, statement, units) {
|
|
3853
|
+
const nodes = statement?.name === "Block" ? statement.getChildren("Fragment") : [];
|
|
3854
|
+
let end = nodes.length;
|
|
3855
|
+
while (end > 0 && nodes[end - 1].from >= context.pos) end--;
|
|
3856
|
+
let start = end;
|
|
3857
|
+
while (start > 0 && nodes[start - 1].firstChild?.name === "Effort") start--;
|
|
3858
|
+
const run = nodes.slice(start, end);
|
|
3859
|
+
let firstEffort = 0;
|
|
3860
|
+
while (firstEffort < run.length - 1 && isUnitFragment(context, run[firstEffort], units)) firstEffort++;
|
|
3861
|
+
return run.slice(firstEffort);
|
|
3862
|
+
}
|
|
3863
|
+
function inNode(context, names) {
|
|
3864
|
+
for (let node = syntaxTree(context.state).resolveInner(context.pos, -1); node; node = node.parent) {
|
|
3865
|
+
if (names.has(node.name)) return true;
|
|
3866
|
+
}
|
|
3867
|
+
return false;
|
|
3868
|
+
}
|
|
3869
|
+
var SUPPRESSED_NODES = /* @__PURE__ */ new Set(["Text", "textComment", "Heading", "heading", "MetricObject"]);
|
|
3870
|
+
function whiteboardScriptCompletionSource(options = {}) {
|
|
3871
|
+
const sportWords = dialectWords(options.sport);
|
|
3872
|
+
const keywords = structureKeywords();
|
|
3873
|
+
const snippets = snippetCompletions();
|
|
3874
|
+
const units = options.units ?? UnitRegistry.standard();
|
|
3875
|
+
const allUnitOptions = unitCompletions(units);
|
|
3876
|
+
const massUnitOptions = unitCompletions(units, "mass");
|
|
3877
|
+
return async (context) => {
|
|
3878
|
+
if (inNode(context, SUPPRESSED_NODES)) return null;
|
|
3879
|
+
const pos = context.pos;
|
|
3880
|
+
const line = context.state.doc.lineAt(pos);
|
|
3881
|
+
const before = line.text.slice(0, pos - line.from);
|
|
3882
|
+
const word = /([A-Za-z0-9-]*)$/.exec(before)[1];
|
|
3883
|
+
const beforeWord = before.slice(0, before.length - word.length);
|
|
3884
|
+
if (beforeWord.endsWith("#") && options.tags) {
|
|
3885
|
+
return { from: pos - word.length, options: toCompletions(await options.tags(), "tag") };
|
|
3886
|
+
}
|
|
3887
|
+
const statement = currentStatement(context);
|
|
3888
|
+
if (statement?.name === "Property") {
|
|
3889
|
+
const keyNode = statement.firstChild;
|
|
3890
|
+
if (keyNode?.name !== "Identifier") return null;
|
|
3891
|
+
const key = context.state.doc.sliceString(keyNode.from, keyNode.to).toLowerCase();
|
|
3892
|
+
const value = keyNode.nextSibling;
|
|
3893
|
+
if (value && !value.type.isError && pos > value.to) return null;
|
|
3894
|
+
const source = key === "effort" ? options.efforts : key === "equipment" ? options.equipment : key === "sound" ? options.sounds : void 0;
|
|
3895
|
+
if (source) return { from: value && !value.type.isError ? value.from : pos, options: toCompletions(await source(), key, true) };
|
|
3896
|
+
return null;
|
|
3897
|
+
}
|
|
3898
|
+
const efforts = options.efforts ? toCompletions(await options.efforts(), "effort") : [];
|
|
3899
|
+
const effortOptions = [...keywords, ...efforts, ...sportWords];
|
|
3900
|
+
if (/^[ \t]*[A-Za-z][A-Za-z0-9]*$/.test(before)) {
|
|
3901
|
+
const supplied = suppliedPropertyKeys(context);
|
|
3902
|
+
return {
|
|
3903
|
+
from: pos - before.trimStart().length,
|
|
3904
|
+
options: [...COMPLETION_PROPERTY_KEYS.filter((key) => !supplied.has(key)).map((key) => ({ label: key, detail: "property", type: "property", boost: 5 })), ...snippets, ...keywords, ...efforts, ...sportWords],
|
|
3905
|
+
validFor: /^[A-Za-z]*$/
|
|
3906
|
+
};
|
|
3907
|
+
}
|
|
3908
|
+
const nodes = statement?.name === "Block" ? statement.getChildren("Fragment") : [];
|
|
3909
|
+
let end = nodes.length;
|
|
3910
|
+
while (end > 0 && nodes[end - 1].from >= pos) end--;
|
|
3911
|
+
const last = nodes[end - 1];
|
|
3912
|
+
const completingWord = last?.firstChild?.name === "Effort" && last.to === pos;
|
|
3913
|
+
const quantityFragment = completingWord ? nodes[end - 2] : last;
|
|
3914
|
+
const quantity = quantityFragment?.firstChild?.name === "Quantity" ? quantityFragment.firstChild : null;
|
|
3915
|
+
const incompleteAction = statement?.name === "Block" && statement.getChildren("Fragment").some(
|
|
3916
|
+
(fragment) => fragment.firstChild?.name === "Action" && fragment.from < (quantity?.from ?? pos) && !context.state.doc.sliceString(fragment.from, fragment.to).includes(":")
|
|
3917
|
+
);
|
|
3918
|
+
if (quantity && !incompleteAction) {
|
|
3919
|
+
return {
|
|
3920
|
+
from: completingWord ? last.from : pos,
|
|
3921
|
+
options: [...quantity.getChild("AtSign") ? massUnitOptions : allUnitOptions, ...effortOptions],
|
|
3922
|
+
validFor: /^[A-Za-z]*$/
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
if (before.trim() === "") {
|
|
3926
|
+
return { from: pos, options: [...snippets, ...keywords, ...efforts, ...sportWords] };
|
|
3927
|
+
}
|
|
3928
|
+
if (word.length === 0 && /[ \t]$/.test(before)) {
|
|
3929
|
+
const effortRun = trailingEffortRun(context, statement, units);
|
|
3930
|
+
const last2 = effortRun[effortRun.length - 1];
|
|
3931
|
+
if (last2 && !isUnitFragment(context, last2, units)) return null;
|
|
3932
|
+
return { from: pos, options: effortOptions };
|
|
3933
|
+
}
|
|
3934
|
+
if (word.length > 0 && /^[A-Za-z][A-Za-z0-9'-]*$/.test(word)) {
|
|
3935
|
+
const effortRun = trailingEffortRun(context, statement, units);
|
|
3936
|
+
const first = effortRun[0];
|
|
3937
|
+
const last2 = effortRun[effortRun.length - 1];
|
|
3938
|
+
if (!first || !last2 || last2.to < pos) return null;
|
|
3939
|
+
const typed = context.state.doc.sliceString(first.from, pos).toLowerCase();
|
|
3940
|
+
const compatible = effortOptions.filter((option) => {
|
|
3941
|
+
const inserted = typeof option.apply === "string" ? option.apply : option.label;
|
|
3942
|
+
return inserted.toLowerCase().startsWith(typed);
|
|
3943
|
+
});
|
|
3944
|
+
return { from: first.from, options: compatible, validFor: /^[A-Za-z ]*$/ };
|
|
3945
|
+
}
|
|
3946
|
+
return null;
|
|
3947
|
+
};
|
|
3948
|
+
}
|
|
3949
|
+
function whiteboardScriptCompletion(options = {}) {
|
|
3950
|
+
return autocompletion({ override: [whiteboardScriptCompletionSource(options)] });
|
|
3951
|
+
}
|
|
3646
3952
|
|
|
3647
3953
|
// src/parser/whiteboard-script-language.ts
|
|
3648
3954
|
var whiteboardScriptLanguage = LRLanguage.define({
|
|
@@ -3678,8 +3984,8 @@ var whiteboardScriptLanguage = LRLanguage.define({
|
|
|
3678
3984
|
closeBrackets: { brackets: ["(", "[", "'", '"'] }
|
|
3679
3985
|
}
|
|
3680
3986
|
});
|
|
3681
|
-
function whiteboardScript() {
|
|
3682
|
-
return new LanguageSupport(whiteboardScriptLanguage);
|
|
3987
|
+
function whiteboardScript(options) {
|
|
3988
|
+
return new LanguageSupport(whiteboardScriptLanguage, whiteboardScriptCompletion(options ?? {}));
|
|
3683
3989
|
}
|
|
3684
3990
|
|
|
3685
3991
|
// src/effort-registry/disciplines.ts
|
|
@@ -12713,7 +13019,12 @@ var IntervalLogicStrategy = class {
|
|
|
12713
13019
|
const hasEmomAction = statements.some((s) => s.metrics.some(
|
|
12714
13020
|
(f) => (f.type === MetricType.Action || f.type === MetricType.Effort) && typeof f.value === "string" && f.value.toLowerCase() === "emom"
|
|
12715
13021
|
));
|
|
12716
|
-
|
|
13022
|
+
const isAmrapIdentified = statements.some(
|
|
13023
|
+
(s) => hasHint(s, CONSUMED_HINTS.LABEL_AMRAP) || s.metrics.some((f) => f.type === MetricType.Rounds && typeof f.value === "string" && f.value.toLowerCase() === "amrap")
|
|
13024
|
+
);
|
|
13025
|
+
const isTabataIdentified = statements.some((s) => hasHint(s, CONSUMED_HINTS.LABEL_TABATA) || s.metrics.some((f) => f.type === MetricType.Effort && typeof f.value === "string" && f.value.toLowerCase() === "tabata"));
|
|
13026
|
+
const hasIntervalCount = hasEmomAction || statements.some((s) => s.metrics.some((f) => f.type === MetricType.Rounds));
|
|
13027
|
+
return hasTimer && (isInterval || hasEmomAction) && !isAmrapIdentified && (!isTabataIdentified || hasIntervalCount);
|
|
12717
13028
|
}
|
|
12718
13029
|
apply(builder, statements, runtime) {
|
|
12719
13030
|
const firstStatementWithTimer = statements.find((s) => s.metrics.some(
|
|
@@ -15134,6 +15445,6 @@ function compareStatement(expectations, actual, mode) {
|
|
|
15134
15445
|
return diffs;
|
|
15135
15446
|
}
|
|
15136
15447
|
|
|
15137
|
-
export { ABSENT, AGGREGATE_BUILTINS, AUTHORITATIVE_CASTS, AbortSessionAction, AmrapLogicStrategy, AnalyticsEngine, AnalyticsTransformer, BUILTIN_CALCS, BUNDLED_EFFORT_COUNT, BehaviorContext, BlockBuilder, BlockContext, ButtonBehavior,
|
|
15448
|
+
export { ABSENT, AGGREGATE_BUILTINS, AUTHORITATIVE_CASTS, AbortSessionAction, AmrapLogicStrategy, AnalyticsEngine, AnalyticsTransformer, BUILTIN_CALCS, BUNDLED_EFFORT_COUNT, BehaviorContext, BlockBuilder, BlockContext, ButtonBehavior, COMPLETION_PROPERTY_KEYS, CONSUMED_HINTS, CONSUMED_HINT_KEYS, CONTEXT_ATOMS, CalcEngine, CalcEvalError, CalcParseError, CalcRegistrationError, CalcUnitError, CalculateBlockProcessor, CalculationRegistry, CardioDialect, ChildSelectionBehavior, ChildrenStrategy, ChoiceGroupMetric, ClearChildrenAction, ClimbDialect, ClimbMetricType, CompileAndPushBlockAction, CompletionTimestampBehavior, CompositeEffortRegistry, CountdownTimerBehavior, CountupTimerBehavior, CrossFitDialect, DAY, DEFAULT_RESOLVER_OPTIONS, DEFAULT_RUNTIME_OPTIONS, DEFAULT_SOUND_PROFILE, DEFAULT_UNRESOLVED_EFFORT_MET, DIM_COUNT, DIM_ENERGY, DIM_LENGTH, DIM_MASS, DIM_TIME, DIM_ZERO, DISCIPLINE_FACTORS, DialectStack, EFFORT_DATA_METRIC_TYPE, EFFORT_DISCIPLINES, EFFORT_REGISTRY_ORIGINS, EffortBlock, EffortFallbackStrategy, EffortResolver, EmitEventAction, EmitSystemOutputAction, ErrorAction, EventBus, ExecutionContext, ExitBehavior, FixtureSyntaxError, GenericGroupStrategy, GenericLoopStrategy, GenericTimerStrategy, HabitsDialect, INTENSITY_TIERS, InMemoryEffortRegistry, IntervalLogicStrategy, JitCompiler, LabelingBehavior, LocalEventProvider, LocalRuntimeSubscription, LookupRegistry, MAX_TAG_CONTRIBUTION_DEPTH, MdTimerRuntime, MemoryLocation, MemoryTypeEnum, MetricPromotionBehavior, NAMED_COMPOUNDS, NextAction, NextEvent, NextEventHandler, OutputEmitter, PRODUCTION_STRATEGIES, PROPERTY_KEY_TO_METRIC_TYPE, PopBlockAction, PushBlockAction, PushRestBlockAction, REFERENCE_PAIR_KEYS, REST_EXCLUSION, RPE_LABELS, RUNTIME_LOG_SUBJECT_WIDTH, RegisterEventHandlerAction, Registry, ReportOutputBehavior, ReportOutputStrategy, RestBlock, RoundsMetric, RuntimeAdapter, RuntimeBlock, RuntimeBuilder, RuntimeClock, RuntimeFactory, RuntimeLogger, RuntimeMemory, RuntimeObservers, RuntimeStack, SEED_PRECEDENCE_RANK, SOUND_PLAY_EVENT, SOUND_PROFILE_METRIC, STANDARD_UNITS, STORE_CALCS, STREAM_ATOMS, STRUCTURAL_EFFORT_WORDS, ScriptRuntime, SessionRootBlock, SessionRootStrategy, SnapshotClock, SoundProfileBehavior, SoundStrategy, SpanTrackingBehavior, StandardAnalyticsProfile, StartSessionAction, StartWorkoutAction, SubscriptionManager, TAG_MARKER_PREFIX, ThrowError, ThrowErrorAction, TimeSpan, TwoPassEffortResolutionProcess, TypedMemoryReference, UNITS, UnitRegistry, UnitSet, UnitsDialect, UnregisterEventHandlerAction, UpdateNextPreviewAction, VISIBILITY_ICONS, VISIBILITY_LABELS, WaitingToStartBlock, WaitingToStartInjectorBehavior, WhiteboardScript, WodDialect, YogaDialect, addAliasToEffort, addDim, applyTemplateDefaults, buildStaticLookups, buildTooltip, bundledEfforts, calculateElapsed, canonicalizeType, checkCalcLine, classifyStatements, closeCurrentSpan, collapseUnresolvedChoices, commonFixtureSet, compareStatement, compileLineForm, composeDivUnit, composeMulUnit, compoundName, computeColumnLabel, computeLabel, computeWorkloadRollups, convertScalar, createAnalyticsEngineForBlock, createCalcEngine, createCalcStack, createCompiler, createDialectStack, createDisciplinesTable, createEffortTable, createLineLocator, createPolicy as createMetricPresentationPolicy, createMockClock, createParser, createProfileTable, createReferenceIndex, createRpeLabelsTable, dailySessionLoads, dayBucket, dedupeEntitiesByPrecedence, dialectRegistry, dialectStack, diffStatement, dimEquals, disciplineFactorFor, documentToEffort, documentToEquipment, effortToDocument, equipmentToDocument, evaluate, evaluateCalculateDefinitions, extractEffortData, extractMetrics, extractStatementRefs, extractStatements, extractStatementsRaw, extractSyntaxFacts, filterTagsByVisibility, findBestFuzzyMatch, findTagContributionCycles, findUnresolvedChoices, fixtureBackSquat, fixtureBurpee, fixturePlank, fixtureRowing, fixtureRunning, fixtureUserCustom, fixtureUserOverride, formatDim, formatDuration, formatRuntimeLogLine, formatRuntimeLogRule, formatRuntimeTimestamp, formatSoundTrigger, metricsToLabel as fragmentsToLabel, fullFixtureSet, fuseUnits, fuseUnitsInMetrics, getAnalyticsFromLogs, getAnalyticsFromRuntime, getHints, getMetricVisibility, getUnit, hasHint, hintMetric, hintsToContainer, inferDim, isCastSubscription, isChoiceResolved, isDimensionless, isEffortDiscipline, isFragmentTag, isTimeLikeMetric, isWithinThreshold, levenshteinDistance, metricPresentation, mutateTimerSpans, normalizeForFuzzy, num, openSpan, outputNodeId, outputNodeIds, padRuntimeLogEvent, padRuntimeLogSubject, parseCalcLine, parseCalculateBlock, parseEffortFile, parseEquipmentFile, parseExpression, parseMetricLine, parseScript, parseSoundTrigger, printCalculation, readNestedSection, readTimer, realtimeProcessorRegistry, renderMetric, resolveDominantOrigin, resolveEntityRank, resolveEntityTier, resolveProfileRules, resolveSoundProfile, resolveSourceRank, resolveSourceTier, resolveTagContributions, slugifyRefLabel, snippetCompletions, startSpan, str, strategyRegistry, subDim, summaryProcessorRegistry, tagContributionMetrics, tagMarkerSlug, tagMarkerSlugs, tagMarkerType, toStoredOutputStatement, truthy, validateOutputUnit, parser as whiteboardParser, whiteboardScript, whiteboardScriptCompletion, whiteboardScriptCompletionSource, whiteboardScriptLanguage, whiteboardScriptSnippets, writeChoiceSelection };
|
|
15138
15449
|
//# sourceMappingURL=index.mjs.map
|
|
15139
15450
|
//# sourceMappingURL=index.mjs.map
|