@sendbird/actionbook-core 0.10.0 → 0.10.2
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/index.d.ts +10 -1
- package/dist/index.js +27 -11
- package/dist/index.js.map +1 -1
- package/dist/ui/index.d.ts +7 -1
- package/dist/ui/index.js +474 -110
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.js
CHANGED
|
@@ -2020,7 +2020,7 @@ function resourceTagToMarkdown() {
|
|
|
2020
2020
|
}
|
|
2021
2021
|
|
|
2022
2022
|
// src/markdown/plugins/jumpPoint.ts
|
|
2023
|
-
var JUMP_POINT_RE = /\^([
|
|
2023
|
+
var JUMP_POINT_RE = /\^([\p{L}\p{N}_-]+)\^/gu;
|
|
2024
2024
|
function splitTextWithJumpPoints(text2) {
|
|
2025
2025
|
const results = [];
|
|
2026
2026
|
let lastIndex = 0;
|
|
@@ -2677,7 +2677,7 @@ function useEditorView(config) {
|
|
|
2677
2677
|
const view = new EditorView(container, {
|
|
2678
2678
|
state,
|
|
2679
2679
|
nodeViews,
|
|
2680
|
-
editable: () => configRef.current.editable
|
|
2680
|
+
editable: () => configRef.current.editable === true,
|
|
2681
2681
|
dispatchTransaction(tr) {
|
|
2682
2682
|
const newState = view.state.apply(tr);
|
|
2683
2683
|
view.updateState(newState);
|
|
@@ -2733,13 +2733,87 @@ function useEditorView(config) {
|
|
|
2733
2733
|
// src/ui/plugin/inputRulesPlugin.ts
|
|
2734
2734
|
import { InputRule, textblockTypeInputRule, wrappingInputRule } from "prosemirror-inputrules";
|
|
2735
2735
|
import { TextSelection } from "prosemirror-state";
|
|
2736
|
+
|
|
2737
|
+
// src/ui/plugin/slashCommandPlugin.ts
|
|
2738
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
2739
|
+
var slashCommandKey = new PluginKey("slashCommand");
|
|
2740
|
+
var TRIGGER_RE = /(?:^|\s)(\/[^\s]*)$/;
|
|
2741
|
+
function deriveState(state, dismissedFrom) {
|
|
2742
|
+
const inactive = { active: false, range: null, query: "", parentType: "" };
|
|
2743
|
+
const { selection } = state;
|
|
2744
|
+
if (!selection.empty) return inactive;
|
|
2745
|
+
const { $from } = selection;
|
|
2746
|
+
const parentType = $from.parent.type.name;
|
|
2747
|
+
for (let d = $from.depth; d > 0; d--) {
|
|
2748
|
+
if ($from.node(d).type.name === "noteBlock") return inactive;
|
|
2749
|
+
}
|
|
2750
|
+
const textBefore = $from.parent.textBetween(0, $from.parentOffset, "\n", "\0");
|
|
2751
|
+
const match = TRIGGER_RE.exec(textBefore);
|
|
2752
|
+
if (!match) return inactive;
|
|
2753
|
+
const slashText = match[1];
|
|
2754
|
+
const slashStartInParent = textBefore.lastIndexOf(slashText);
|
|
2755
|
+
const from = $from.start() + slashStartInParent;
|
|
2756
|
+
const to = $from.pos;
|
|
2757
|
+
if (dismissedFrom === from) return inactive;
|
|
2758
|
+
return {
|
|
2759
|
+
active: true,
|
|
2760
|
+
range: { from, to },
|
|
2761
|
+
query: slashText.slice(1),
|
|
2762
|
+
parentType
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
function createSlashCommandPlugin() {
|
|
2766
|
+
const plugin = new Plugin({
|
|
2767
|
+
key: slashCommandKey,
|
|
2768
|
+
state: {
|
|
2769
|
+
init(_, state) {
|
|
2770
|
+
const derived = deriveState(state, null);
|
|
2771
|
+
return { ...derived, _dismissedFrom: null };
|
|
2772
|
+
},
|
|
2773
|
+
apply(tr, prev, _old, newState) {
|
|
2774
|
+
const meta = tr.getMeta(slashCommandKey);
|
|
2775
|
+
let dismissedFrom = prev._dismissedFrom;
|
|
2776
|
+
if (meta?.dismiss !== void 0) {
|
|
2777
|
+
dismissedFrom = meta.dismiss;
|
|
2778
|
+
} else if (dismissedFrom !== null) {
|
|
2779
|
+
const derived2 = deriveState(newState, null);
|
|
2780
|
+
if (derived2.active && derived2.range && derived2.range.from !== dismissedFrom) {
|
|
2781
|
+
dismissedFrom = null;
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
const derived = deriveState(newState, dismissedFrom);
|
|
2785
|
+
return { ...derived, _dismissedFrom: dismissedFrom };
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
// Expose only the public fields via the key
|
|
2789
|
+
// (InternalState is a superset of SlashCommandState so reads work fine)
|
|
2790
|
+
});
|
|
2791
|
+
return {
|
|
2792
|
+
name: "slashCommand",
|
|
2793
|
+
plugins: () => [plugin],
|
|
2794
|
+
keymap: () => ({
|
|
2795
|
+
Escape: (state, dispatch) => {
|
|
2796
|
+
const s = slashCommandKey.getState(state);
|
|
2797
|
+
if (!s?.active || !s.range) return false;
|
|
2798
|
+
if (dispatch) {
|
|
2799
|
+
const tr = state.tr;
|
|
2800
|
+
tr.setMeta(slashCommandKey, { dismiss: s.range.from });
|
|
2801
|
+
dispatch(tr);
|
|
2802
|
+
}
|
|
2803
|
+
return true;
|
|
2804
|
+
}
|
|
2805
|
+
})
|
|
2806
|
+
};
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
// src/ui/plugin/inputRulesPlugin.ts
|
|
2736
2810
|
var HEADING_RE = /^(#{1,6})\s$/;
|
|
2737
2811
|
var BLOCKQUOTE_RE = /^\s*>\s$/;
|
|
2738
2812
|
var CODE_BLOCK_RE = /^```([a-zA-Z0-9]*)$/;
|
|
2739
2813
|
var HR_RE = /^([-*_])\1{2,}$/;
|
|
2740
2814
|
var BULLET_LIST_RE = /^\s*([-*])\s$/;
|
|
2741
2815
|
var ORDERED_LIST_RE = /^(\d+)\.\s$/;
|
|
2742
|
-
var JUMP_POINT_RE2 = /\^([
|
|
2816
|
+
var JUMP_POINT_RE2 = /\^([\p{L}\p{N}_-]+)\^$/u;
|
|
2743
2817
|
var BOLD_STAR_RE = /(?:^|[^*])\*\*([^*]+)\*\*$/;
|
|
2744
2818
|
var BOLD_UNDER_RE = /(?:^|[^_])__([^_]+)__$/;
|
|
2745
2819
|
var ITALIC_STAR_RE = /(?:^|[^*])\*([^*]+)\*$/;
|
|
@@ -2806,6 +2880,8 @@ function handleListInputRule(state, start, end, listType, attrs) {
|
|
|
2806
2880
|
}
|
|
2807
2881
|
function markInputRule(pattern, markType, markerLen) {
|
|
2808
2882
|
return new InputRule(pattern, (state, match, start, end) => {
|
|
2883
|
+
const slashState = slashCommandKey.getState(state);
|
|
2884
|
+
if (slashState?.active) return null;
|
|
2809
2885
|
const textContent2 = match[1];
|
|
2810
2886
|
const fullMatch = match[0];
|
|
2811
2887
|
const markedLength = markerLen * 2 + textContent2.length;
|
|
@@ -3298,9 +3374,20 @@ var enterCommand = chainCommands(
|
|
|
3298
3374
|
);
|
|
3299
3375
|
var shiftEnterCommand = (state, dispatch) => {
|
|
3300
3376
|
if (dispatch) {
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
);
|
|
3377
|
+
const { from, to, $from } = state.selection;
|
|
3378
|
+
const tr = state.tr;
|
|
3379
|
+
if (from !== to) tr.delete(from, to);
|
|
3380
|
+
const insertPos = tr.mapping.map(from);
|
|
3381
|
+
const marks = $from.marks();
|
|
3382
|
+
tr.insert(insertPos, hardBreak.create());
|
|
3383
|
+
const afterBr = insertPos + 1;
|
|
3384
|
+
tr.insertText("\u200B", afterBr);
|
|
3385
|
+
const cursorPos = afterBr + 1;
|
|
3386
|
+
if (cursorPos <= tr.doc.content.size) {
|
|
3387
|
+
tr.setSelection(TextSelection2.create(tr.doc, cursorPos));
|
|
3388
|
+
}
|
|
3389
|
+
if (marks.length > 0) tr.setStoredMarks(marks);
|
|
3390
|
+
dispatch(tr.scrollIntoView());
|
|
3304
3391
|
}
|
|
3305
3392
|
return true;
|
|
3306
3393
|
};
|
|
@@ -3327,7 +3414,7 @@ function createKeymapPlugin() {
|
|
|
3327
3414
|
|
|
3328
3415
|
// src/ui/plugin/markdownClipboard.ts
|
|
3329
3416
|
import { DOMParser as ProseMirrorDOMParser, Fragment, Slice } from "prosemirror-model";
|
|
3330
|
-
import { Plugin, PluginKey } from "prosemirror-state";
|
|
3417
|
+
import { Plugin as Plugin2, PluginKey as PluginKey2 } from "prosemirror-state";
|
|
3331
3418
|
|
|
3332
3419
|
// src/ast/traverse.ts
|
|
3333
3420
|
var MAX_DEPTH3 = 128;
|
|
@@ -5062,6 +5149,320 @@ function analyzeJinjaBlocks(doc2) {
|
|
|
5062
5149
|
});
|
|
5063
5150
|
}
|
|
5064
5151
|
|
|
5152
|
+
// src/jinja/evaluator.ts
|
|
5153
|
+
var KEYWORDS2 = {
|
|
5154
|
+
and: "AND",
|
|
5155
|
+
or: "OR",
|
|
5156
|
+
not: "NOT",
|
|
5157
|
+
in: "IN",
|
|
5158
|
+
is: "IS",
|
|
5159
|
+
True: "BOOL",
|
|
5160
|
+
False: "BOOL",
|
|
5161
|
+
true: "BOOL",
|
|
5162
|
+
false: "BOOL",
|
|
5163
|
+
None: "NONE",
|
|
5164
|
+
null: "NONE"
|
|
5165
|
+
};
|
|
5166
|
+
function tokenize(input) {
|
|
5167
|
+
const tokens = [];
|
|
5168
|
+
let i = 0;
|
|
5169
|
+
while (i < input.length) {
|
|
5170
|
+
if (/\s/.test(input[i])) {
|
|
5171
|
+
i++;
|
|
5172
|
+
continue;
|
|
5173
|
+
}
|
|
5174
|
+
if (input[i] === '"' || input[i] === "'") {
|
|
5175
|
+
const quote = input[i];
|
|
5176
|
+
let str = "";
|
|
5177
|
+
i++;
|
|
5178
|
+
while (i < input.length && input[i] !== quote) {
|
|
5179
|
+
if (input[i] === "\\" && i + 1 < input.length) {
|
|
5180
|
+
str += input[i + 1];
|
|
5181
|
+
i += 2;
|
|
5182
|
+
} else {
|
|
5183
|
+
str += input[i];
|
|
5184
|
+
i++;
|
|
5185
|
+
}
|
|
5186
|
+
}
|
|
5187
|
+
if (i >= input.length) return { tokens: [], error: "Unterminated string literal" };
|
|
5188
|
+
i++;
|
|
5189
|
+
tokens.push({ type: "STRING", value: str });
|
|
5190
|
+
continue;
|
|
5191
|
+
}
|
|
5192
|
+
if (/[0-9]/.test(input[i]) || input[i] === "-" && i + 1 < input.length && /[0-9]/.test(input[i + 1]) && (tokens.length === 0 || ["AND", "OR", "NOT", "EQ", "NEQ", "LT", "GT", "LTE", "GTE", "LPAREN", "IN", "IS"].includes(tokens[tokens.length - 1].type))) {
|
|
5193
|
+
let num = "";
|
|
5194
|
+
if (input[i] === "-") {
|
|
5195
|
+
num = "-";
|
|
5196
|
+
i++;
|
|
5197
|
+
}
|
|
5198
|
+
while (i < input.length && /[0-9]/.test(input[i])) {
|
|
5199
|
+
num += input[i];
|
|
5200
|
+
i++;
|
|
5201
|
+
}
|
|
5202
|
+
if (i < input.length && input[i] === ".") {
|
|
5203
|
+
num += ".";
|
|
5204
|
+
i++;
|
|
5205
|
+
while (i < input.length && /[0-9]/.test(input[i])) {
|
|
5206
|
+
num += input[i];
|
|
5207
|
+
i++;
|
|
5208
|
+
}
|
|
5209
|
+
}
|
|
5210
|
+
tokens.push({ type: "NUMBER", value: num });
|
|
5211
|
+
continue;
|
|
5212
|
+
}
|
|
5213
|
+
if (/[a-zA-Z_]/.test(input[i])) {
|
|
5214
|
+
let ident = "";
|
|
5215
|
+
while (i < input.length && /[a-zA-Z0-9_.]/.test(input[i])) {
|
|
5216
|
+
ident += input[i];
|
|
5217
|
+
i++;
|
|
5218
|
+
}
|
|
5219
|
+
const kwType = KEYWORDS2[ident];
|
|
5220
|
+
if (kwType) {
|
|
5221
|
+
tokens.push({ type: kwType, value: ident });
|
|
5222
|
+
} else {
|
|
5223
|
+
tokens.push({ type: "IDENT", value: ident });
|
|
5224
|
+
}
|
|
5225
|
+
continue;
|
|
5226
|
+
}
|
|
5227
|
+
if (i + 1 < input.length) {
|
|
5228
|
+
const two = input[i] + input[i + 1];
|
|
5229
|
+
if (two === "==") {
|
|
5230
|
+
tokens.push({ type: "EQ", value: "==" });
|
|
5231
|
+
i += 2;
|
|
5232
|
+
continue;
|
|
5233
|
+
}
|
|
5234
|
+
if (two === "!=") {
|
|
5235
|
+
tokens.push({ type: "NEQ", value: "!=" });
|
|
5236
|
+
i += 2;
|
|
5237
|
+
continue;
|
|
5238
|
+
}
|
|
5239
|
+
if (two === "<=") {
|
|
5240
|
+
tokens.push({ type: "LTE", value: "<=" });
|
|
5241
|
+
i += 2;
|
|
5242
|
+
continue;
|
|
5243
|
+
}
|
|
5244
|
+
if (two === ">=") {
|
|
5245
|
+
tokens.push({ type: "GTE", value: ">=" });
|
|
5246
|
+
i += 2;
|
|
5247
|
+
continue;
|
|
5248
|
+
}
|
|
5249
|
+
}
|
|
5250
|
+
if (input[i] === "<") {
|
|
5251
|
+
tokens.push({ type: "LT", value: "<" });
|
|
5252
|
+
i++;
|
|
5253
|
+
continue;
|
|
5254
|
+
}
|
|
5255
|
+
if (input[i] === ">") {
|
|
5256
|
+
tokens.push({ type: "GT", value: ">" });
|
|
5257
|
+
i++;
|
|
5258
|
+
continue;
|
|
5259
|
+
}
|
|
5260
|
+
if (input[i] === "(") {
|
|
5261
|
+
tokens.push({ type: "LPAREN", value: "(" });
|
|
5262
|
+
i++;
|
|
5263
|
+
continue;
|
|
5264
|
+
}
|
|
5265
|
+
if (input[i] === ")") {
|
|
5266
|
+
tokens.push({ type: "RPAREN", value: ")" });
|
|
5267
|
+
i++;
|
|
5268
|
+
continue;
|
|
5269
|
+
}
|
|
5270
|
+
return { tokens: [], error: `Unexpected character: ${input[i]}` };
|
|
5271
|
+
}
|
|
5272
|
+
tokens.push({ type: "EOF", value: "" });
|
|
5273
|
+
return { tokens };
|
|
5274
|
+
}
|
|
5275
|
+
var Parser = class {
|
|
5276
|
+
pos = 0;
|
|
5277
|
+
tokens;
|
|
5278
|
+
variables;
|
|
5279
|
+
constructor(tokens, variables) {
|
|
5280
|
+
this.tokens = tokens;
|
|
5281
|
+
this.variables = variables;
|
|
5282
|
+
}
|
|
5283
|
+
peek() {
|
|
5284
|
+
return this.tokens[this.pos] ?? { type: "EOF", value: "" };
|
|
5285
|
+
}
|
|
5286
|
+
advance() {
|
|
5287
|
+
const t = this.tokens[this.pos];
|
|
5288
|
+
this.pos++;
|
|
5289
|
+
return t;
|
|
5290
|
+
}
|
|
5291
|
+
expect(type) {
|
|
5292
|
+
const t = this.peek();
|
|
5293
|
+
if (t.type !== type) {
|
|
5294
|
+
throw new Error(`Expected ${type}, got ${t.type}`);
|
|
5295
|
+
}
|
|
5296
|
+
return this.advance();
|
|
5297
|
+
}
|
|
5298
|
+
// Grammar (precedence low→high):
|
|
5299
|
+
// expr → or_expr
|
|
5300
|
+
// or_expr → and_expr ('or' and_expr)*
|
|
5301
|
+
// and_expr → not_expr ('and' not_expr)*
|
|
5302
|
+
// not_expr → 'not' not_expr | cmp_expr
|
|
5303
|
+
// cmp_expr → primary (('=='|'!='|'<'|'>'|'<='|'>='|'in'|'is'|'is not') primary)?
|
|
5304
|
+
// primary → STRING | NUMBER | BOOL | NONE | IDENT | '(' expr ')'
|
|
5305
|
+
evaluate() {
|
|
5306
|
+
const result = this.orExpr();
|
|
5307
|
+
if (this.peek().type !== "EOF") {
|
|
5308
|
+
throw new Error(`Unexpected token: ${this.peek().value}`);
|
|
5309
|
+
}
|
|
5310
|
+
return result;
|
|
5311
|
+
}
|
|
5312
|
+
orExpr() {
|
|
5313
|
+
let left = this.andExpr();
|
|
5314
|
+
while (this.peek().type === "OR") {
|
|
5315
|
+
this.advance();
|
|
5316
|
+
const right = this.andExpr();
|
|
5317
|
+
left = isTruthy(left) || isTruthy(right);
|
|
5318
|
+
}
|
|
5319
|
+
return left;
|
|
5320
|
+
}
|
|
5321
|
+
andExpr() {
|
|
5322
|
+
let left = this.notExpr();
|
|
5323
|
+
while (this.peek().type === "AND") {
|
|
5324
|
+
this.advance();
|
|
5325
|
+
const right = this.notExpr();
|
|
5326
|
+
left = isTruthy(left) && isTruthy(right);
|
|
5327
|
+
}
|
|
5328
|
+
return left;
|
|
5329
|
+
}
|
|
5330
|
+
notExpr() {
|
|
5331
|
+
if (this.peek().type === "NOT") {
|
|
5332
|
+
this.advance();
|
|
5333
|
+
const val = this.notExpr();
|
|
5334
|
+
return !isTruthy(val);
|
|
5335
|
+
}
|
|
5336
|
+
return this.cmpExpr();
|
|
5337
|
+
}
|
|
5338
|
+
cmpExpr() {
|
|
5339
|
+
const left = this.primary();
|
|
5340
|
+
const op = this.peek().type;
|
|
5341
|
+
switch (op) {
|
|
5342
|
+
case "EQ":
|
|
5343
|
+
this.advance();
|
|
5344
|
+
return looseEqual(left, this.primary());
|
|
5345
|
+
case "NEQ":
|
|
5346
|
+
this.advance();
|
|
5347
|
+
return !looseEqual(left, this.primary());
|
|
5348
|
+
case "LT":
|
|
5349
|
+
this.advance();
|
|
5350
|
+
return toNumber(left) < toNumber(this.primary());
|
|
5351
|
+
case "GT":
|
|
5352
|
+
this.advance();
|
|
5353
|
+
return toNumber(left) > toNumber(this.primary());
|
|
5354
|
+
case "LTE":
|
|
5355
|
+
this.advance();
|
|
5356
|
+
return toNumber(left) <= toNumber(this.primary());
|
|
5357
|
+
case "GTE":
|
|
5358
|
+
this.advance();
|
|
5359
|
+
return toNumber(left) >= toNumber(this.primary());
|
|
5360
|
+
case "IN": {
|
|
5361
|
+
this.advance();
|
|
5362
|
+
const collection = this.primary();
|
|
5363
|
+
if (Array.isArray(collection)) {
|
|
5364
|
+
return collection.some((item) => looseEqual(item, left));
|
|
5365
|
+
}
|
|
5366
|
+
if (typeof collection === "string" && typeof left === "string") {
|
|
5367
|
+
return collection.includes(left);
|
|
5368
|
+
}
|
|
5369
|
+
return false;
|
|
5370
|
+
}
|
|
5371
|
+
case "IS": {
|
|
5372
|
+
this.advance();
|
|
5373
|
+
if (this.peek().type === "NOT") {
|
|
5374
|
+
this.advance();
|
|
5375
|
+
return !looseEqual(left, this.primary());
|
|
5376
|
+
}
|
|
5377
|
+
return looseEqual(left, this.primary());
|
|
5378
|
+
}
|
|
5379
|
+
default:
|
|
5380
|
+
return left;
|
|
5381
|
+
}
|
|
5382
|
+
}
|
|
5383
|
+
primary() {
|
|
5384
|
+
const t = this.peek();
|
|
5385
|
+
switch (t.type) {
|
|
5386
|
+
case "STRING":
|
|
5387
|
+
this.advance();
|
|
5388
|
+
return t.value;
|
|
5389
|
+
case "NUMBER":
|
|
5390
|
+
this.advance();
|
|
5391
|
+
return parseFloat(t.value);
|
|
5392
|
+
case "BOOL":
|
|
5393
|
+
this.advance();
|
|
5394
|
+
return t.value === "True" || t.value === "true";
|
|
5395
|
+
case "NONE":
|
|
5396
|
+
this.advance();
|
|
5397
|
+
return null;
|
|
5398
|
+
case "IDENT": {
|
|
5399
|
+
this.advance();
|
|
5400
|
+
return this.resolveVariable(t.value);
|
|
5401
|
+
}
|
|
5402
|
+
case "LPAREN": {
|
|
5403
|
+
this.advance();
|
|
5404
|
+
const val = this.orExpr();
|
|
5405
|
+
this.expect("RPAREN");
|
|
5406
|
+
return val;
|
|
5407
|
+
}
|
|
5408
|
+
default:
|
|
5409
|
+
throw new Error(`Unexpected token in primary: ${t.type} "${t.value}"`);
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
resolveVariable(name) {
|
|
5413
|
+
const entry = this.variables.get(name);
|
|
5414
|
+
if (entry === void 0) {
|
|
5415
|
+
return null;
|
|
5416
|
+
}
|
|
5417
|
+
switch (entry.type) {
|
|
5418
|
+
case "string":
|
|
5419
|
+
return String(entry.value);
|
|
5420
|
+
case "number":
|
|
5421
|
+
return Number(entry.value);
|
|
5422
|
+
case "boolean":
|
|
5423
|
+
return entry.value === true || entry.value === "true";
|
|
5424
|
+
default:
|
|
5425
|
+
return String(entry.value);
|
|
5426
|
+
}
|
|
5427
|
+
}
|
|
5428
|
+
};
|
|
5429
|
+
function isTruthy(v) {
|
|
5430
|
+
if (v === null || v === void 0) return false;
|
|
5431
|
+
if (typeof v === "boolean") return v;
|
|
5432
|
+
if (typeof v === "number") return v !== 0;
|
|
5433
|
+
if (typeof v === "string") return v.length > 0;
|
|
5434
|
+
if (Array.isArray(v)) return v.length > 0;
|
|
5435
|
+
return true;
|
|
5436
|
+
}
|
|
5437
|
+
function looseEqual(a, b) {
|
|
5438
|
+
if (a === b) return true;
|
|
5439
|
+
if (a === null || b === null) return a === b;
|
|
5440
|
+
if (typeof a === "number" && typeof b === "string") return a === parseFloat(b);
|
|
5441
|
+
if (typeof a === "string" && typeof b === "number") return parseFloat(a) === b;
|
|
5442
|
+
return false;
|
|
5443
|
+
}
|
|
5444
|
+
function toNumber(v) {
|
|
5445
|
+
if (typeof v === "number") return v;
|
|
5446
|
+
if (typeof v === "string") return parseFloat(v) || 0;
|
|
5447
|
+
if (typeof v === "boolean") return v ? 1 : 0;
|
|
5448
|
+
return 0;
|
|
5449
|
+
}
|
|
5450
|
+
function validateCondition(condition) {
|
|
5451
|
+
const trimmed = condition.trim();
|
|
5452
|
+
if (trimmed === "") return { valid: true };
|
|
5453
|
+
const { tokens, error: tokenError } = tokenize(trimmed);
|
|
5454
|
+
if (tokenError) return { valid: false, error: tokenError };
|
|
5455
|
+
if (tokens.length === 0) return { valid: false, error: "Empty expression" };
|
|
5456
|
+
try {
|
|
5457
|
+
const parser = new Parser(tokens, /* @__PURE__ */ new Map());
|
|
5458
|
+
parser.evaluate();
|
|
5459
|
+
return { valid: true };
|
|
5460
|
+
} catch (e) {
|
|
5461
|
+
const msg = e instanceof Error ? e.message : "Invalid expression";
|
|
5462
|
+
return { valid: false, error: msg };
|
|
5463
|
+
}
|
|
5464
|
+
}
|
|
5465
|
+
|
|
5065
5466
|
// src/tree/documentTree.ts
|
|
5066
5467
|
var MAX_DEPTH6 = 128;
|
|
5067
5468
|
var END_ACTION_RESOURCE_IDS = /* @__PURE__ */ new Set([
|
|
@@ -5210,7 +5611,7 @@ function buildDocumentTree(doc2) {
|
|
|
5210
5611
|
}
|
|
5211
5612
|
|
|
5212
5613
|
// src/ui/plugin/markdownClipboard.ts
|
|
5213
|
-
var key = new
|
|
5614
|
+
var key = new PluginKey2("markdownClipboard");
|
|
5214
5615
|
var MAX_PASTE_LIST_DEPTH = 3;
|
|
5215
5616
|
var MAX_FLATTEN_DEPTH = 128;
|
|
5216
5617
|
function flattenDeepLists(node, listDepth = 0, _recurseDepth = 0) {
|
|
@@ -5273,7 +5674,7 @@ function textToSlice(text2, view) {
|
|
|
5273
5674
|
view.state.doc.descendants((node) => {
|
|
5274
5675
|
if (node.type.name === "jumpPoint") existingIds.add(node.attrs.id);
|
|
5275
5676
|
});
|
|
5276
|
-
const deduped = text2.replace(/\^([
|
|
5677
|
+
const deduped = text2.replace(/\^([\p{L}\p{N}_-]+)\^/gmu, (match, id) => {
|
|
5277
5678
|
if (existingIds.has(id)) return id;
|
|
5278
5679
|
existingIds.add(id);
|
|
5279
5680
|
return match;
|
|
@@ -5290,7 +5691,7 @@ function textToSlice(text2, view) {
|
|
|
5290
5691
|
}
|
|
5291
5692
|
var URL_RE = /^https?:\/\/[^\s]+$/i;
|
|
5292
5693
|
function createPlugin() {
|
|
5293
|
-
return new
|
|
5694
|
+
return new Plugin2({
|
|
5294
5695
|
key,
|
|
5295
5696
|
props: {
|
|
5296
5697
|
handlePaste(view, event) {
|
|
@@ -5356,9 +5757,9 @@ function createMarkdownClipboardPlugin() {
|
|
|
5356
5757
|
}
|
|
5357
5758
|
|
|
5358
5759
|
// src/ui/plugin/jumpPointPlugin.ts
|
|
5359
|
-
import { Plugin as
|
|
5760
|
+
import { Plugin as Plugin3, PluginKey as PluginKey3, TextSelection as TextSelection3 } from "prosemirror-state";
|
|
5360
5761
|
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
5361
|
-
var adjacentKey = new
|
|
5762
|
+
var adjacentKey = new PluginKey3("jumpPointAdjacent");
|
|
5362
5763
|
var JUMP_POINT_ADJACENT_SPEC = { jumpPointAdjacent: true };
|
|
5363
5764
|
function buildDecorations(state) {
|
|
5364
5765
|
const { selection } = state;
|
|
@@ -5374,10 +5775,10 @@ function buildDecorations(state) {
|
|
|
5374
5775
|
});
|
|
5375
5776
|
return DecorationSet.create(state.doc, decorations);
|
|
5376
5777
|
}
|
|
5377
|
-
var jumpPointEditKey = new
|
|
5378
|
-
var JUMP_POINT_FULL_RE = /^\^([
|
|
5778
|
+
var jumpPointEditKey = new PluginKey3("jumpPointEdit");
|
|
5779
|
+
var JUMP_POINT_FULL_RE = /^\^([\p{L}\p{N}_-]+)\^$/u;
|
|
5379
5780
|
function createJumpPointEditPlugin() {
|
|
5380
|
-
return new
|
|
5781
|
+
return new Plugin3({
|
|
5381
5782
|
key: jumpPointEditKey,
|
|
5382
5783
|
state: {
|
|
5383
5784
|
init: () => ({ rawRange: null }),
|
|
@@ -5479,7 +5880,7 @@ function createJumpPointAdjacentPlugin() {
|
|
|
5479
5880
|
}),
|
|
5480
5881
|
plugins: () => [
|
|
5481
5882
|
createJumpPointEditPlugin(),
|
|
5482
|
-
new
|
|
5883
|
+
new Plugin3({
|
|
5483
5884
|
key: adjacentKey,
|
|
5484
5885
|
state: {
|
|
5485
5886
|
init(_, state) {
|
|
@@ -5645,9 +6046,9 @@ function createJumpPointNodeViewPlugin() {
|
|
|
5645
6046
|
}
|
|
5646
6047
|
|
|
5647
6048
|
// src/ui/plugin/jumpPointValidationPlugin.ts
|
|
5648
|
-
import { Plugin as
|
|
6049
|
+
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
|
|
5649
6050
|
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "prosemirror-view";
|
|
5650
|
-
var pluginKey = new
|
|
6051
|
+
var pluginKey = new PluginKey4("jumpPointValidation");
|
|
5651
6052
|
function collectJumpPointIds(state) {
|
|
5652
6053
|
const ids = /* @__PURE__ */ new Set();
|
|
5653
6054
|
state.doc.descendants((node) => {
|
|
@@ -5697,7 +6098,7 @@ function createJumpPointValidationPlugin() {
|
|
|
5697
6098
|
return {
|
|
5698
6099
|
name: "jumpPointValidation",
|
|
5699
6100
|
plugins: () => [
|
|
5700
|
-
new
|
|
6101
|
+
new Plugin4({
|
|
5701
6102
|
key: pluginKey,
|
|
5702
6103
|
state: {
|
|
5703
6104
|
init(_, state) {
|
|
@@ -5813,9 +6214,9 @@ function createInlineToolTagNodeViewPlugin() {
|
|
|
5813
6214
|
}
|
|
5814
6215
|
|
|
5815
6216
|
// src/ui/plugin/jinjaDecoration.ts
|
|
5816
|
-
import { Plugin as
|
|
6217
|
+
import { Plugin as Plugin5, PluginKey as PluginKey5 } from "prosemirror-state";
|
|
5817
6218
|
import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "prosemirror-view";
|
|
5818
|
-
var jinjaPluginKey = new
|
|
6219
|
+
var jinjaPluginKey = new PluginKey5("jinjaDecoration");
|
|
5819
6220
|
var JINJA_TAG_RE = /\{%\s*(if|elif|else|endif)\s*([^%]*?)\s*%\}/g;
|
|
5820
6221
|
function getBlockPositions(doc2) {
|
|
5821
6222
|
const blocks = [];
|
|
@@ -5906,7 +6307,7 @@ function createJinjaDecorationPlugin() {
|
|
|
5906
6307
|
return {
|
|
5907
6308
|
name: "jinjaDecoration",
|
|
5908
6309
|
plugins: () => [
|
|
5909
|
-
new
|
|
6310
|
+
new Plugin5({
|
|
5910
6311
|
key: jinjaPluginKey,
|
|
5911
6312
|
state: {
|
|
5912
6313
|
init(_, state) {
|
|
@@ -5930,7 +6331,7 @@ function createJinjaDecorationPlugin() {
|
|
|
5930
6331
|
// src/ui/plugin/jinjaIfBlockPlugin.tsx
|
|
5931
6332
|
import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
5932
6333
|
import { createRoot as createRoot2 } from "react-dom/client";
|
|
5933
|
-
import { Plugin as
|
|
6334
|
+
import { Plugin as Plugin6, TextSelection as TextSelection4 } from "prosemirror-state";
|
|
5934
6335
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
5935
6336
|
var PLACEHOLDER_TEXT = "Describe what AI agent should do when this condition is met";
|
|
5936
6337
|
var CONDITION_PLACEHOLDER = "Write a condition in natural language";
|
|
@@ -6029,6 +6430,18 @@ var JINJA_STYLES = `
|
|
|
6029
6430
|
letter-spacing: -0.3px;
|
|
6030
6431
|
}
|
|
6031
6432
|
|
|
6433
|
+
.jinja-branch-condition-invalid {
|
|
6434
|
+
text-decoration: wavy underline #D9352C;
|
|
6435
|
+
text-underline-offset: 3px;
|
|
6436
|
+
}
|
|
6437
|
+
|
|
6438
|
+
.jinja-condition-error-icon {
|
|
6439
|
+
color: #D9352C;
|
|
6440
|
+
margin-left: 4px;
|
|
6441
|
+
font-size: 12px;
|
|
6442
|
+
flex-shrink: 0;
|
|
6443
|
+
}
|
|
6444
|
+
|
|
6032
6445
|
.jinja-token-variable {
|
|
6033
6446
|
color: #4141B2;
|
|
6034
6447
|
}
|
|
@@ -6477,11 +6890,14 @@ function ConditionDisplay({
|
|
|
6477
6890
|
}
|
|
6478
6891
|
);
|
|
6479
6892
|
}
|
|
6893
|
+
const validation = condition.length > 0 ? validateCondition(condition) : null;
|
|
6894
|
+
const isInvalid = validation != null && !validation.valid;
|
|
6480
6895
|
return /* @__PURE__ */ jsx6(
|
|
6481
6896
|
"button",
|
|
6482
6897
|
{
|
|
6483
6898
|
type: "button",
|
|
6484
|
-
className: "jinja-branch-condition"
|
|
6899
|
+
className: `jinja-branch-condition${isInvalid ? " jinja-branch-condition-invalid" : ""}`,
|
|
6900
|
+
title: isInvalid ? validation.error : void 0,
|
|
6485
6901
|
onMouseDown: (event) => event.preventDefault(),
|
|
6486
6902
|
onClick: () => {
|
|
6487
6903
|
if (editable) {
|
|
@@ -6489,7 +6905,10 @@ function ConditionDisplay({
|
|
|
6489
6905
|
setIsEditing(true);
|
|
6490
6906
|
}
|
|
6491
6907
|
},
|
|
6492
|
-
children: condition.length > 0 ?
|
|
6908
|
+
children: condition.length > 0 ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
6909
|
+
renderCondition(condition),
|
|
6910
|
+
isInvalid && /* @__PURE__ */ jsx6("span", { className: "jinja-condition-error-icon", children: "\u26A0" })
|
|
6911
|
+
] }) : /* @__PURE__ */ jsx6("span", { className: "jinja-condition-placeholder", children: CONDITION_PLACEHOLDER })
|
|
6493
6912
|
}
|
|
6494
6913
|
);
|
|
6495
6914
|
}
|
|
@@ -6766,7 +7185,7 @@ var JinjaIfBranchView = class {
|
|
|
6766
7185
|
{
|
|
6767
7186
|
branchType,
|
|
6768
7187
|
condition,
|
|
6769
|
-
editable: this.view.editable,
|
|
7188
|
+
editable: this.view.editable && this.view.dom.getAttribute("contenteditable") !== "false",
|
|
6770
7189
|
isLastBranch: showAddButton,
|
|
6771
7190
|
hasElseBranch: context && nodePos != null ? getElseBranch(this.view, nodePos) : false,
|
|
6772
7191
|
onConditionChange: (value) => {
|
|
@@ -6824,7 +7243,7 @@ var JinjaIfBranchView = class {
|
|
|
6824
7243
|
};
|
|
6825
7244
|
function createEditableWatcherPlugin() {
|
|
6826
7245
|
let lastEditable = null;
|
|
6827
|
-
return new
|
|
7246
|
+
return new Plugin6({
|
|
6828
7247
|
view(editorView) {
|
|
6829
7248
|
lastEditable = editorView.editable;
|
|
6830
7249
|
return {
|
|
@@ -6855,10 +7274,10 @@ function createJinjaIfBlockPlugin() {
|
|
|
6855
7274
|
|
|
6856
7275
|
// src/ui/plugin/linkPlugin.ts
|
|
6857
7276
|
import { InputRule as InputRule2, inputRules as inputRules2 } from "prosemirror-inputrules";
|
|
6858
|
-
import { Plugin as
|
|
7277
|
+
import { Plugin as Plugin7, PluginKey as PluginKey6, TextSelection as TextSelection5 } from "prosemirror-state";
|
|
6859
7278
|
var LINK_INPUT_RE = /\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
|
|
6860
7279
|
var LINK_FULL_RE = /^\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
|
|
6861
|
-
var linkEditKey = new
|
|
7280
|
+
var linkEditKey = new PluginKey6("linkEdit");
|
|
6862
7281
|
function getMarkRange($pos, type) {
|
|
6863
7282
|
const { parentOffset } = $pos;
|
|
6864
7283
|
let child = $pos.parent.childAfter(parentOffset);
|
|
@@ -6906,7 +7325,7 @@ function explodeLinkToRaw(state) {
|
|
|
6906
7325
|
return tr;
|
|
6907
7326
|
}
|
|
6908
7327
|
function createLinkEditPlugin() {
|
|
6909
|
-
return new
|
|
7328
|
+
return new Plugin7({
|
|
6910
7329
|
key: linkEditKey,
|
|
6911
7330
|
state: {
|
|
6912
7331
|
init: () => ({ rawRange: null }),
|
|
@@ -6976,8 +7395,8 @@ function createLinkInputRule() {
|
|
|
6976
7395
|
);
|
|
6977
7396
|
}
|
|
6978
7397
|
function createLinkClickPlugin() {
|
|
6979
|
-
return new
|
|
6980
|
-
key: new
|
|
7398
|
+
return new Plugin7({
|
|
7399
|
+
key: new PluginKey6("linkClick"),
|
|
6981
7400
|
props: {
|
|
6982
7401
|
handleDOMEvents: {
|
|
6983
7402
|
click: (_view, event) => {
|
|
@@ -7029,8 +7448,8 @@ function createLinkPlugin() {
|
|
|
7029
7448
|
}
|
|
7030
7449
|
|
|
7031
7450
|
// src/ui/plugin/dragHandlePlugin.ts
|
|
7032
|
-
import { Plugin as
|
|
7033
|
-
var PLUGIN_KEY = new
|
|
7451
|
+
import { Plugin as Plugin8, PluginKey as PluginKey7 } from "prosemirror-state";
|
|
7452
|
+
var PLUGIN_KEY = new PluginKey7("dragHandle");
|
|
7034
7453
|
var GRIP_SVG = `<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
7035
7454
|
<circle cx="4" cy="2.5" r="1.2"/><circle cx="8" cy="2.5" r="1.2"/>
|
|
7036
7455
|
<circle cx="4" cy="6" r="1.2"/><circle cx="8" cy="6" r="1.2"/>
|
|
@@ -7837,7 +8256,7 @@ function createDragHandlePlugin() {
|
|
|
7837
8256
|
plugins: () => {
|
|
7838
8257
|
let controller = null;
|
|
7839
8258
|
return [
|
|
7840
|
-
new
|
|
8259
|
+
new Plugin8({
|
|
7841
8260
|
key: PLUGIN_KEY,
|
|
7842
8261
|
view(editorView) {
|
|
7843
8262
|
controller = new DragHandleController(editorView);
|
|
@@ -7960,10 +8379,10 @@ function createTodoNodeViewPlugin() {
|
|
|
7960
8379
|
}
|
|
7961
8380
|
|
|
7962
8381
|
// src/ui/plugin/placeholderPlugin.ts
|
|
7963
|
-
import { Plugin as
|
|
8382
|
+
import { Plugin as Plugin9, PluginKey as PluginKey8 } from "prosemirror-state";
|
|
7964
8383
|
import { Decoration as Decoration4, DecorationSet as DecorationSet4 } from "prosemirror-view";
|
|
7965
8384
|
var PLACEHOLDER_TEXT2 = "Type to start writing, or press / to insert an action.";
|
|
7966
|
-
var pluginKey2 = new
|
|
8385
|
+
var pluginKey2 = new PluginKey8("placeholder");
|
|
7967
8386
|
function buildDecorations4(state) {
|
|
7968
8387
|
const { doc: doc2, selection } = state;
|
|
7969
8388
|
if (!selection.empty) return DecorationSet4.empty;
|
|
@@ -7989,7 +8408,7 @@ function createPlaceholderPlugin() {
|
|
|
7989
8408
|
return {
|
|
7990
8409
|
name: "placeholder",
|
|
7991
8410
|
plugins: () => [
|
|
7992
|
-
new
|
|
8411
|
+
new Plugin9({
|
|
7993
8412
|
key: pluginKey2,
|
|
7994
8413
|
state: {
|
|
7995
8414
|
init(_, state) {
|
|
@@ -8012,78 +8431,6 @@ function createPlaceholderPlugin() {
|
|
|
8012
8431
|
};
|
|
8013
8432
|
}
|
|
8014
8433
|
|
|
8015
|
-
// src/ui/plugin/slashCommandPlugin.ts
|
|
8016
|
-
import { Plugin as Plugin9, PluginKey as PluginKey8 } from "prosemirror-state";
|
|
8017
|
-
var slashCommandKey = new PluginKey8("slashCommand");
|
|
8018
|
-
var TRIGGER_RE = /(?:^|\s)(\/[^\s]*)$/;
|
|
8019
|
-
function deriveState(state, dismissedFrom) {
|
|
8020
|
-
const inactive = { active: false, range: null, query: "", parentType: "" };
|
|
8021
|
-
const { selection } = state;
|
|
8022
|
-
if (!selection.empty) return inactive;
|
|
8023
|
-
const { $from } = selection;
|
|
8024
|
-
const parentType = $from.parent.type.name;
|
|
8025
|
-
for (let d = $from.depth; d > 0; d--) {
|
|
8026
|
-
if ($from.node(d).type.name === "noteBlock") return inactive;
|
|
8027
|
-
}
|
|
8028
|
-
const textBefore = $from.parent.textBetween(0, $from.parentOffset, "\n", "\0");
|
|
8029
|
-
const match = TRIGGER_RE.exec(textBefore);
|
|
8030
|
-
if (!match) return inactive;
|
|
8031
|
-
const slashText = match[1];
|
|
8032
|
-
const slashStartInParent = textBefore.lastIndexOf(slashText);
|
|
8033
|
-
const from = $from.start() + slashStartInParent;
|
|
8034
|
-
const to = $from.pos;
|
|
8035
|
-
if (dismissedFrom === from) return inactive;
|
|
8036
|
-
return {
|
|
8037
|
-
active: true,
|
|
8038
|
-
range: { from, to },
|
|
8039
|
-
query: slashText.slice(1),
|
|
8040
|
-
parentType
|
|
8041
|
-
};
|
|
8042
|
-
}
|
|
8043
|
-
function createSlashCommandPlugin() {
|
|
8044
|
-
const plugin = new Plugin9({
|
|
8045
|
-
key: slashCommandKey,
|
|
8046
|
-
state: {
|
|
8047
|
-
init(_, state) {
|
|
8048
|
-
const derived = deriveState(state, null);
|
|
8049
|
-
return { ...derived, _dismissedFrom: null };
|
|
8050
|
-
},
|
|
8051
|
-
apply(tr, prev, _old, newState) {
|
|
8052
|
-
const meta = tr.getMeta(slashCommandKey);
|
|
8053
|
-
let dismissedFrom = prev._dismissedFrom;
|
|
8054
|
-
if (meta?.dismiss !== void 0) {
|
|
8055
|
-
dismissedFrom = meta.dismiss;
|
|
8056
|
-
} else if (dismissedFrom !== null) {
|
|
8057
|
-
const derived2 = deriveState(newState, null);
|
|
8058
|
-
if (derived2.active && derived2.range && derived2.range.from !== dismissedFrom) {
|
|
8059
|
-
dismissedFrom = null;
|
|
8060
|
-
}
|
|
8061
|
-
}
|
|
8062
|
-
const derived = deriveState(newState, dismissedFrom);
|
|
8063
|
-
return { ...derived, _dismissedFrom: dismissedFrom };
|
|
8064
|
-
}
|
|
8065
|
-
}
|
|
8066
|
-
// Expose only the public fields via the key
|
|
8067
|
-
// (InternalState is a superset of SlashCommandState so reads work fine)
|
|
8068
|
-
});
|
|
8069
|
-
return {
|
|
8070
|
-
name: "slashCommand",
|
|
8071
|
-
plugins: () => [plugin],
|
|
8072
|
-
keymap: () => ({
|
|
8073
|
-
Escape: (state, dispatch) => {
|
|
8074
|
-
const s = slashCommandKey.getState(state);
|
|
8075
|
-
if (!s?.active || !s.range) return false;
|
|
8076
|
-
if (dispatch) {
|
|
8077
|
-
const tr = state.tr;
|
|
8078
|
-
tr.setMeta(slashCommandKey, { dismiss: s.range.from });
|
|
8079
|
-
dispatch(tr);
|
|
8080
|
-
}
|
|
8081
|
-
return true;
|
|
8082
|
-
}
|
|
8083
|
-
})
|
|
8084
|
-
};
|
|
8085
|
-
}
|
|
8086
|
-
|
|
8087
8434
|
// src/ui/components/SlashCommandMenu.tsx
|
|
8088
8435
|
import React4, { useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState4 } from "react";
|
|
8089
8436
|
import { createPortal } from "react-dom";
|
|
@@ -9956,6 +10303,22 @@ function createInlineSuggestPlugin(provider, endpoint, options) {
|
|
|
9956
10303
|
]
|
|
9957
10304
|
};
|
|
9958
10305
|
}
|
|
10306
|
+
|
|
10307
|
+
// src/ui/bridge/jinjaValidation.ts
|
|
10308
|
+
function hasInvalidJinjaConditions(state) {
|
|
10309
|
+
let found = false;
|
|
10310
|
+
state.doc.descendants((node) => {
|
|
10311
|
+
if (found) return false;
|
|
10312
|
+
if (node.type.name === "jinjaIfBranch") {
|
|
10313
|
+
const condition = String(node.attrs.condition ?? "");
|
|
10314
|
+
if (condition && !validateCondition(condition).valid) {
|
|
10315
|
+
found = true;
|
|
10316
|
+
}
|
|
10317
|
+
return false;
|
|
10318
|
+
}
|
|
10319
|
+
});
|
|
10320
|
+
return found;
|
|
10321
|
+
}
|
|
9959
10322
|
export {
|
|
9960
10323
|
ActionbookRenderer,
|
|
9961
10324
|
DocumentTreeView,
|
|
@@ -9989,6 +10352,7 @@ export {
|
|
|
9989
10352
|
createTodoNodeViewPlugin,
|
|
9990
10353
|
hasBrokenAnchorRefs,
|
|
9991
10354
|
hasDuplicateJumpPoints,
|
|
10355
|
+
hasInvalidJinjaConditions,
|
|
9992
10356
|
inlineSuggestKey,
|
|
9993
10357
|
slashCommandKey,
|
|
9994
10358
|
toProseMirrorJSON,
|