@kerebron/extension-menu 0.4.2 → 0.4.4
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/README.md +80 -0
- package/assets/custom-menu.css +26 -6
- package/assets/menu.css +2 -2
- package/esm/_dnt.polyfills.d.ts +101 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +127 -0
- package/esm/_dnt.shims.d.ts +1 -5
- package/esm/_dnt.shims.d.ts.map +1 -1
- package/esm/_dnt.shims.js +1 -5
- package/esm/editor/src/utilities/getShadowRoot.d.ts +2 -0
- package/esm/editor/src/utilities/getShadowRoot.d.ts.map +1 -0
- package/esm/editor/src/utilities/getShadowRoot.js +16 -0
- package/esm/editor/src/utilities/mod.d.ts +6 -0
- package/esm/editor/src/utilities/mod.d.ts.map +1 -0
- package/esm/editor/src/utilities/mod.js +5 -0
- package/esm/editor/src/utilities/toRawTextResult.d.ts +3 -0
- package/esm/editor/src/utilities/toRawTextResult.d.ts.map +1 -0
- package/esm/editor/src/utilities/toRawTextResult.js +21 -0
- package/esm/extension-autocomplete/src/AutocompletePlugin.d.ts +8 -0
- package/esm/extension-autocomplete/src/AutocompletePlugin.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/AutocompletePlugin.js +232 -0
- package/esm/extension-autocomplete/src/DefaultRenderer.d.ts +17 -0
- package/esm/extension-autocomplete/src/DefaultRenderer.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/DefaultRenderer.js +137 -0
- package/esm/extension-autocomplete/src/ExtensionAutocomplete.d.ts +26 -0
- package/esm/extension-autocomplete/src/ExtensionAutocomplete.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/ExtensionAutocomplete.js +30 -0
- package/esm/extension-autocomplete/src/createDefaultMatcher.d.ts +11 -0
- package/esm/extension-autocomplete/src/createDefaultMatcher.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/createDefaultMatcher.js +58 -0
- package/esm/extension-autocomplete/src/createRegexMatcher.d.ts +4 -0
- package/esm/extension-autocomplete/src/createRegexMatcher.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/createRegexMatcher.js +50 -0
- package/esm/extension-autocomplete/src/mod.d.ts +3 -0
- package/esm/extension-autocomplete/src/mod.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/mod.js +2 -0
- package/esm/extension-autocomplete/src/types.d.ts +60 -0
- package/esm/extension-autocomplete/src/types.d.ts.map +1 -0
- package/esm/extension-autocomplete/src/types.js +1 -0
- package/esm/extension-basic-editor/src/ExtensionHtml.d.ts +15 -0
- package/esm/extension-basic-editor/src/ExtensionHtml.d.ts.map +1 -0
- package/esm/extension-basic-editor/src/ExtensionHtml.js +108 -0
- package/esm/extension-lsp/src/DiagnosticPlugin.d.ts +32 -0
- package/esm/extension-lsp/src/DiagnosticPlugin.d.ts.map +1 -0
- package/esm/extension-lsp/src/DiagnosticPlugin.js +131 -0
- package/esm/extension-lsp/src/ExtensionLsp.d.ts +25 -0
- package/esm/extension-lsp/src/ExtensionLsp.d.ts.map +1 -0
- package/esm/extension-lsp/src/ExtensionLsp.js +126 -0
- package/esm/extension-lsp/src/LSPClient.d.ts +56 -0
- package/esm/extension-lsp/src/LSPClient.d.ts.map +1 -0
- package/esm/extension-lsp/src/LSPClient.js +449 -0
- package/esm/extension-lsp/src/LspStatus.d.ts +34 -0
- package/esm/extension-lsp/src/LspStatus.d.ts.map +1 -0
- package/esm/extension-lsp/src/LspStatus.js +127 -0
- package/esm/extension-lsp/src/computeIncrementalChanges.d.ts +8 -0
- package/esm/extension-lsp/src/computeIncrementalChanges.d.ts.map +1 -0
- package/esm/extension-lsp/src/computeIncrementalChanges.js +82 -0
- package/esm/extension-lsp/src/createLspAutocomplete.d.ts +23 -0
- package/esm/extension-lsp/src/createLspAutocomplete.d.ts.map +1 -0
- package/esm/extension-lsp/src/createLspAutocomplete.js +68 -0
- package/esm/extension-lsp/src/workspace.d.ts +62 -0
- package/esm/extension-lsp/src/workspace.d.ts.map +1 -0
- package/esm/extension-lsp/src/workspace.js +168 -0
- package/esm/extension-markdown/src/DocumentMarkdownInlineTokenizer.d.ts +36 -0
- package/esm/extension-markdown/src/DocumentMarkdownInlineTokenizer.d.ts.map +1 -0
- package/esm/extension-markdown/src/DocumentMarkdownInlineTokenizer.js +240 -0
- package/esm/extension-markdown/src/DocumentMarkdownTokenizer.d.ts +26 -0
- package/esm/extension-markdown/src/DocumentMarkdownTokenizer.d.ts.map +1 -0
- package/esm/extension-markdown/src/DocumentMarkdownTokenizer.js +115 -0
- package/esm/extension-markdown/src/ExtensionMarkdown.d.ts +22 -0
- package/esm/extension-markdown/src/ExtensionMarkdown.d.ts.map +1 -0
- package/esm/extension-markdown/src/ExtensionMarkdown.js +48 -0
- package/esm/extension-markdown/src/MarkdownParser.d.ts +61 -0
- package/esm/extension-markdown/src/MarkdownParser.d.ts.map +1 -0
- package/esm/extension-markdown/src/MarkdownParser.js +249 -0
- package/esm/extension-markdown/src/MarkdownSerializer.d.ts +42 -0
- package/esm/extension-markdown/src/MarkdownSerializer.d.ts.map +1 -0
- package/esm/extension-markdown/src/MarkdownSerializer.js +325 -0
- package/esm/extension-markdown/src/PositionMapper.d.ts +15 -0
- package/esm/extension-markdown/src/PositionMapper.d.ts.map +1 -0
- package/esm/extension-markdown/src/PositionMapper.js +100 -0
- package/esm/extension-markdown/src/TokenSource.d.ts +11 -0
- package/esm/extension-markdown/src/TokenSource.d.ts.map +1 -0
- package/esm/extension-markdown/src/TokenSource.js +39 -0
- package/esm/extension-markdown/src/mdToPmConverter.d.ts +5 -0
- package/esm/extension-markdown/src/mdToPmConverter.d.ts.map +1 -0
- package/esm/extension-markdown/src/mdToPmConverter.js +111 -0
- package/esm/extension-markdown/src/pmToMdConverter.d.ts +16 -0
- package/esm/extension-markdown/src/pmToMdConverter.d.ts.map +1 -0
- package/esm/extension-markdown/src/pmToMdConverter.js +433 -0
- package/esm/extension-markdown/src/token_handlers/basic_token_handlers.d.ts +4 -0
- package/esm/extension-markdown/src/token_handlers/basic_token_handlers.d.ts.map +1 -0
- package/esm/extension-markdown/src/token_handlers/basic_token_handlers.js +151 -0
- package/esm/extension-markdown/src/token_handlers/footnote_token_handlers.d.ts +3 -0
- package/esm/extension-markdown/src/token_handlers/footnote_token_handlers.d.ts.map +1 -0
- package/esm/extension-markdown/src/token_handlers/footnote_token_handlers.js +34 -0
- package/esm/extension-markdown/src/token_handlers/inline_token_handlers.d.ts +6 -0
- package/esm/extension-markdown/src/token_handlers/inline_token_handlers.d.ts.map +1 -0
- package/esm/extension-markdown/src/token_handlers/inline_token_handlers.js +380 -0
- package/esm/extension-markdown/src/token_handlers/lists_token_handlers.d.ts +3 -0
- package/esm/extension-markdown/src/token_handlers/lists_token_handlers.d.ts.map +1 -0
- package/esm/extension-markdown/src/token_handlers/lists_token_handlers.js +323 -0
- package/esm/extension-markdown/src/token_handlers/table_token_handlers.d.ts +9 -0
- package/esm/extension-markdown/src/token_handlers/table_token_handlers.d.ts.map +1 -0
- package/esm/extension-markdown/src/token_handlers/table_token_handlers.js +308 -0
- package/esm/extension-markdown/src/treeSitterTokenizer.d.ts +5 -0
- package/esm/extension-markdown/src/treeSitterTokenizer.d.ts.map +1 -0
- package/esm/extension-markdown/src/treeSitterTokenizer.js +769 -0
- package/esm/extension-markdown/src/types.d.ts +28 -0
- package/esm/extension-markdown/src/types.d.ts.map +1 -0
- package/esm/extension-markdown/src/types.js +131 -0
- package/esm/extension-markdown/src/utils.d.ts +8 -0
- package/esm/extension-markdown/src/utils.d.ts.map +1 -0
- package/esm/extension-markdown/src/utils.js +86 -0
- package/esm/extension-menu/src/CustomMenuPlugin.d.ts +7 -3
- package/esm/extension-menu/src/CustomMenuPlugin.d.ts.map +1 -1
- package/esm/extension-menu/src/CustomMenuPlugin.js +60 -4
- package/esm/extension-menu/src/ExtensionCustomMenu.d.ts +6 -2
- package/esm/extension-menu/src/ExtensionCustomMenu.d.ts.map +1 -1
- package/esm/extension-menu/src/ExtensionCustomMenu.js +36 -1
- package/esm/extension-menu/src/menu.d.ts +1 -1
- package/esm/extension-menu/src/mod.d.ts +1 -0
- package/esm/extension-menu/src/mod.d.ts.map +1 -1
- package/esm/extension-menu/src/mod.js +1 -0
- package/esm/extension-yjs/src/CollaborationStatus.d.ts +59 -0
- package/esm/extension-yjs/src/CollaborationStatus.d.ts.map +1 -0
- package/esm/extension-yjs/src/CollaborationStatus.js +286 -0
- package/esm/tree-sitter-shim/src/main.d.ts +15 -0
- package/esm/tree-sitter-shim/src/main.d.ts.map +1 -0
- package/esm/tree-sitter-shim/src/main.js +25 -0
- package/esm/tree-sitter-shim/src/tree_sitter/node.d.ts +6 -0
- package/esm/tree-sitter-shim/src/tree_sitter/node.d.ts.map +1 -0
- package/esm/tree-sitter-shim/src/tree_sitter/node.js +1 -0
- package/esm/tree-sitter-shim/src/tree_sitter/parser.d.ts +7 -0
- package/esm/tree-sitter-shim/src/tree_sitter/parser.d.ts.map +1 -0
- package/esm/tree-sitter-shim/src/tree_sitter/parser.js +5 -0
- package/esm/tree-sitter-shim/src/tree_sitter/tree.d.ts +6 -0
- package/esm/tree-sitter-shim/src/tree_sitter/tree.d.ts.map +1 -0
- package/esm/tree-sitter-shim/src/tree_sitter/tree.js +1 -0
- package/esm/wasm/src/mod.d.ts +12 -0
- package/esm/wasm/src/mod.d.ts.map +1 -0
- package/esm/wasm/src/mod.js +48 -0
- package/esm/wasm/wasm.d.ts +138 -0
- package/esm/wasm/wasm.d.ts.map +1 -0
- package/esm/wasm/wasm.js +120 -0
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fragment, Node, type ParseOptions, Schema } from 'prosemirror-model';
|
|
2
|
+
import { type Converter, type CoreEditor, Extension } from '../../editor/src/mod.js';
|
|
3
|
+
export type CreateNodeFromContentOptions = {
|
|
4
|
+
parseOptions?: ParseOptions;
|
|
5
|
+
errorOnInvalidContent?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function getHTMLFromFragment(fragment: Fragment, schema: Schema): string;
|
|
8
|
+
export declare function elementFromString(value: string): HTMLElement;
|
|
9
|
+
export declare function createNodeFromHTML(content: string, schema: Schema, options?: CreateNodeFromContentOptions): Node;
|
|
10
|
+
export declare function createFragmentFromHTML(content: string, schema: Schema, options?: CreateNodeFromContentOptions): Fragment;
|
|
11
|
+
export declare class ExtensionHtml extends Extension {
|
|
12
|
+
name: string;
|
|
13
|
+
getConverters(editor: CoreEditor, schema: Schema): Record<string, Converter>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ExtensionHtml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtensionHtml.d.ts","sourceRoot":"","sources":["../../../src/extension-basic-editor/src/ExtensionHtml.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,EACR,IAAI,EACJ,KAAK,YAAY,EACjB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAErF,MAAM,MAAM,4BAA4B,GAAG;IACzC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAaR;AAqBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAQ5D;AA+BD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAgBN;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,QAAQ,CAiBV;AAED,qBAAa,aAAc,SAAQ,SAAS;IAC1C,IAAI,SAAU;IAEL,aAAa,CACpB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;CAe7B"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { DOMParser, DOMSerializer, Schema, } from 'prosemirror-model';
|
|
2
|
+
import { Extension } from '../../editor/src/mod.js';
|
|
3
|
+
export function getHTMLFromFragment(fragment, schema) {
|
|
4
|
+
const document = globalThis.document;
|
|
5
|
+
const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment, { document });
|
|
6
|
+
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
7
|
+
const container = temporaryDocument.createElement('div');
|
|
8
|
+
container.appendChild(documentFragment);
|
|
9
|
+
return container.innerHTML;
|
|
10
|
+
}
|
|
11
|
+
const removeWhitespaces = (node) => {
|
|
12
|
+
const children = node.childNodes;
|
|
13
|
+
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
14
|
+
const child = children[i];
|
|
15
|
+
if (child.nodeType === 3 && child.nodeValue &&
|
|
16
|
+
/^(\n\s\s|\n)$/.test(child.nodeValue)) {
|
|
17
|
+
node.removeChild(child);
|
|
18
|
+
}
|
|
19
|
+
else if (child.nodeType === 1) {
|
|
20
|
+
removeWhitespaces(child);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return node;
|
|
24
|
+
};
|
|
25
|
+
export function elementFromString(value) {
|
|
26
|
+
// add a wrapper to preserve leading and trailing whitespace
|
|
27
|
+
const wrappedValue = `<body>${value}</body>`;
|
|
28
|
+
const html = new globalThis.DOMParser().parseFromString(wrappedValue, 'text/html').body;
|
|
29
|
+
return removeWhitespaces(html);
|
|
30
|
+
}
|
|
31
|
+
function prepareContentCheckSchema(schema) {
|
|
32
|
+
const contentCheckSchema = new Schema({
|
|
33
|
+
topNode: schema.spec.topNode,
|
|
34
|
+
marks: schema.spec.marks,
|
|
35
|
+
// Prosemirror's schemas are executed such that: the last to execute, matches last
|
|
36
|
+
// This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle
|
|
37
|
+
nodes: schema.spec.nodes.append({
|
|
38
|
+
__unknown__catch__all__node: {
|
|
39
|
+
content: 'inline*',
|
|
40
|
+
group: 'block',
|
|
41
|
+
parseDOM: [
|
|
42
|
+
{
|
|
43
|
+
tag: '*',
|
|
44
|
+
getAttrs: (e) => {
|
|
45
|
+
// Try to stringify the element for a more helpful error message
|
|
46
|
+
const invalidContent = typeof e === 'string' ? e : e.outerHTML;
|
|
47
|
+
throw new Error('Invalid HTML content', {
|
|
48
|
+
cause: new Error(`Invalid element found: ${invalidContent}`),
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
return contentCheckSchema;
|
|
57
|
+
}
|
|
58
|
+
export function createNodeFromHTML(content, schema, options) {
|
|
59
|
+
options = {
|
|
60
|
+
parseOptions: {},
|
|
61
|
+
...options,
|
|
62
|
+
};
|
|
63
|
+
if (options.errorOnInvalidContent) {
|
|
64
|
+
const contentCheckSchema = prepareContentCheckSchema(schema);
|
|
65
|
+
DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
|
|
66
|
+
}
|
|
67
|
+
const parser = DOMParser.fromSchema(schema);
|
|
68
|
+
return parser.parse(elementFromString(content), options.parseOptions);
|
|
69
|
+
}
|
|
70
|
+
export function createFragmentFromHTML(content, schema, options) {
|
|
71
|
+
options = {
|
|
72
|
+
parseOptions: {},
|
|
73
|
+
...options,
|
|
74
|
+
};
|
|
75
|
+
if (options.errorOnInvalidContent) {
|
|
76
|
+
const contentCheckSchema = prepareContentCheckSchema(schema);
|
|
77
|
+
DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
|
|
78
|
+
}
|
|
79
|
+
const parser = DOMParser.fromSchema(schema);
|
|
80
|
+
return parser.parseSlice(elementFromString(content), options.parseOptions)
|
|
81
|
+
.content;
|
|
82
|
+
}
|
|
83
|
+
export class ExtensionHtml extends Extension {
|
|
84
|
+
constructor() {
|
|
85
|
+
super(...arguments);
|
|
86
|
+
Object.defineProperty(this, "name", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: 'html'
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
getConverters(editor, schema) {
|
|
94
|
+
const config = this.config;
|
|
95
|
+
return {
|
|
96
|
+
'text/html': {
|
|
97
|
+
fromDoc: async (document) => {
|
|
98
|
+
const html = getHTMLFromFragment(document.content, editor.schema);
|
|
99
|
+
return new TextEncoder().encode(html);
|
|
100
|
+
},
|
|
101
|
+
toDoc: async (buffer) => {
|
|
102
|
+
const html = new TextDecoder().decode(buffer);
|
|
103
|
+
return createNodeFromHTML(html, editor.schema);
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Plugin } from 'prosemirror-state';
|
|
2
|
+
import { ExtensionLsp } from './ExtensionLsp.js';
|
|
3
|
+
import { PositionMapper } from '../../extension-markdown/src/PositionMapper.js';
|
|
4
|
+
interface LspRange {
|
|
5
|
+
line: number;
|
|
6
|
+
character: number;
|
|
7
|
+
}
|
|
8
|
+
interface DiagnosticsItem {
|
|
9
|
+
severity: number;
|
|
10
|
+
range: {
|
|
11
|
+
start: LspRange;
|
|
12
|
+
end: LspRange;
|
|
13
|
+
};
|
|
14
|
+
message: string;
|
|
15
|
+
source: string;
|
|
16
|
+
code: string;
|
|
17
|
+
data: any;
|
|
18
|
+
}
|
|
19
|
+
interface DiagnosticPluginState {
|
|
20
|
+
diagnostics: DiagnosticsItem[];
|
|
21
|
+
mapper?: PositionMapper;
|
|
22
|
+
}
|
|
23
|
+
interface DiagnosticConfig {
|
|
24
|
+
}
|
|
25
|
+
export declare class DiagnosticPlugin extends Plugin<DiagnosticPluginState> {
|
|
26
|
+
diagListener: ((event: Event) => void) | undefined;
|
|
27
|
+
listenerDisconnect: ((event: Event) => void) | undefined;
|
|
28
|
+
listenerChange: ((event: Event) => void) | undefined;
|
|
29
|
+
constructor(config: DiagnosticConfig, extension: ExtensionLsp);
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=DiagnosticPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-lsp/src/DiagnosticPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0B,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAEhF,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QACL,KAAK,EAAE,QAAQ,CAAC;QAChB,GAAG,EAAE,QAAQ,CAAC;KACf,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,CAAC;CACX;AAED,UAAU,qBAAqB;IAC7B,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,UAAU,gBAAgB;CACzB;AAID,qBAAa,gBAAiB,SAAQ,MAAM,CAAC,qBAAqB,CAAC;IACjE,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnD,kBAAkB,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzD,cAAc,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;gBAEzC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY;CA8J9D"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
+
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
3
|
+
const DiagnosticPluginKey = new PluginKey('lsp-diagnostic');
|
|
4
|
+
export class DiagnosticPlugin extends Plugin {
|
|
5
|
+
constructor(config, extension) {
|
|
6
|
+
super({
|
|
7
|
+
key: DiagnosticPluginKey,
|
|
8
|
+
view(view) {
|
|
9
|
+
return {
|
|
10
|
+
destroy: () => {
|
|
11
|
+
const client = extension.getClient(extension.mainLang);
|
|
12
|
+
if (this.listener && client) {
|
|
13
|
+
client.removeEventListener('textDocument/publishDiagnostics', this.listener);
|
|
14
|
+
}
|
|
15
|
+
if (this.listenerDisconnect && client) {
|
|
16
|
+
client.removeEventListener('close', this.listenerDisconnect);
|
|
17
|
+
}
|
|
18
|
+
if (this.changeListener) {
|
|
19
|
+
extension.getEditor().removeEventListener('change', this.changeListener);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
state: {
|
|
25
|
+
init() {
|
|
26
|
+
return {
|
|
27
|
+
diagnostics: [],
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
apply(tr, prev, oldState, newState) {
|
|
31
|
+
const next = { ...prev };
|
|
32
|
+
const meta = tr.getMeta(DiagnosticPluginKey);
|
|
33
|
+
if (meta?.diagnostics) {
|
|
34
|
+
next.diagnostics = meta.diagnostics;
|
|
35
|
+
}
|
|
36
|
+
if (meta?.mapper) {
|
|
37
|
+
next.mapper = meta.mapper;
|
|
38
|
+
}
|
|
39
|
+
return next;
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
props: {
|
|
43
|
+
decorations(state) {
|
|
44
|
+
const decorations = [];
|
|
45
|
+
const pluginState = this.getState(state);
|
|
46
|
+
if (pluginState) {
|
|
47
|
+
const { diagnostics, mapper } = pluginState;
|
|
48
|
+
if (mapper) {
|
|
49
|
+
for (const diag of diagnostics) {
|
|
50
|
+
const from = mapper.fromLineChar(diag.range.start.line, diag.range.start.character);
|
|
51
|
+
const end = mapper.fromLineChar(diag.range.end.line, diag.range.end.character);
|
|
52
|
+
if (from > -1 && end > -1) {
|
|
53
|
+
const decoration = Decoration.inline(from, end, { class: 'kb-lsp__error', title: diag.message });
|
|
54
|
+
decorations.push(decoration);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return DecorationSet.create(state.doc, decorations);
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(this, "diagListener", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: void 0
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(this, "listenerDisconnect", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
configurable: true,
|
|
72
|
+
writable: true,
|
|
73
|
+
value: void 0
|
|
74
|
+
});
|
|
75
|
+
Object.defineProperty(this, "listenerChange", {
|
|
76
|
+
enumerable: true,
|
|
77
|
+
configurable: true,
|
|
78
|
+
writable: true,
|
|
79
|
+
value: void 0
|
|
80
|
+
});
|
|
81
|
+
let lastDiag = 0;
|
|
82
|
+
const editor = extension.getEditor();
|
|
83
|
+
const uri = editor.config.uri;
|
|
84
|
+
if (uri) {
|
|
85
|
+
const client = extension.getClient(extension.mainLang);
|
|
86
|
+
this.diagListener = (event) => {
|
|
87
|
+
const detail = event.detail;
|
|
88
|
+
if (detail.params.uri !== uri) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
lastDiag = +Date();
|
|
93
|
+
if (client) {
|
|
94
|
+
const file = client.workspace.getFile(uri);
|
|
95
|
+
if (file) {
|
|
96
|
+
const { mapper } = file;
|
|
97
|
+
const tr = editor.view.state.tr.setMeta(DiagnosticPluginKey, {
|
|
98
|
+
diagnostics: detail.params.diagnostics,
|
|
99
|
+
mapper,
|
|
100
|
+
});
|
|
101
|
+
editor.view.dispatch(tr);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if (client) {
|
|
106
|
+
client.addEventListener('textDocument/publishDiagnostics', this.diagListener);
|
|
107
|
+
}
|
|
108
|
+
this.listenerDisconnect = (event) => {
|
|
109
|
+
const tr = editor.view.state.tr.setMeta(DiagnosticPluginKey, {
|
|
110
|
+
diagnostics: [],
|
|
111
|
+
mapper: undefined,
|
|
112
|
+
});
|
|
113
|
+
editor.view.dispatch(tr);
|
|
114
|
+
};
|
|
115
|
+
if (client) {
|
|
116
|
+
client.addEventListener('close', this.listenerDisconnect);
|
|
117
|
+
}
|
|
118
|
+
this.listenerChange = (event) => {
|
|
119
|
+
if (lastDiag === 0 && +Date() - lastDiag > 10_1000) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const tr = editor.view.state.tr.setMeta(DiagnosticPluginKey, {
|
|
123
|
+
diagnostics: [],
|
|
124
|
+
mapper: undefined,
|
|
125
|
+
});
|
|
126
|
+
editor.view.dispatch(tr);
|
|
127
|
+
};
|
|
128
|
+
// extension.getEditor().addEventListener('changed', this.listenerChange);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Plugin } from 'prosemirror-state';
|
|
2
|
+
import { Extension } from '../../editor/src/mod.js';
|
|
3
|
+
import { type ExtensionMarkdown } from '../../extension-markdown/src/ExtensionMarkdown.js';
|
|
4
|
+
import { type ExtensionAutocomplete } from '../../extension-autocomplete/src/mod.js';
|
|
5
|
+
import { LSPClient, Transport } from './LSPClient.js';
|
|
6
|
+
import { LspSource } from './workspace.js';
|
|
7
|
+
export type LspTransportGetter = (lang: string) => Transport | undefined;
|
|
8
|
+
export interface LspConfig {
|
|
9
|
+
getLspTransport: LspTransportGetter;
|
|
10
|
+
}
|
|
11
|
+
export declare class ExtensionLsp extends Extension {
|
|
12
|
+
protected config: LspConfig;
|
|
13
|
+
name: string;
|
|
14
|
+
clients: Record<string, LSPClient>;
|
|
15
|
+
uri: string | undefined;
|
|
16
|
+
extensionMarkdown: ExtensionMarkdown;
|
|
17
|
+
extensionAutocomplete: ExtensionAutocomplete;
|
|
18
|
+
mainLang: string;
|
|
19
|
+
source: LspSource;
|
|
20
|
+
constructor(config: LspConfig);
|
|
21
|
+
getProseMirrorPlugins(): Plugin[];
|
|
22
|
+
created(): void;
|
|
23
|
+
getClient(lang: string): LSPClient | undefined;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ExtensionLsp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtensionLsp.d.ts","sourceRoot":"","sources":["../../../src/extension-lsp/src/ExtensionLsp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAGrF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,kBAAkB,CAAC;CACrC;AAED,qBAAa,YAAa,SAAQ,SAAS;cASV,MAAM,EAAE,SAAS;IARhD,IAAI,SAAS;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAM;IACxC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,iBAAiB,EAAG,iBAAiB,CAAC;IACtC,qBAAqB,EAAG,qBAAqB,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAc;IAC9B,MAAM,EAAG,SAAS,CAAC;gBAEY,MAAM,EAAE,SAAS;IAIvC,qBAAqB,IAAI,MAAM,EAAE;IAWjC,OAAO;IA6DhB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;CAW/C"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Extension } from '../../editor/src/mod.js';
|
|
2
|
+
import { PositionMapper } from '../../extension-markdown/src/PositionMapper.js';
|
|
3
|
+
import { LSPClient } from './LSPClient.js';
|
|
4
|
+
import { AutocompletePlugin } from '../../extension-autocomplete/src/AutocompletePlugin.js';
|
|
5
|
+
import { DiagnosticPlugin } from './DiagnosticPlugin.js';
|
|
6
|
+
import { createLspAutocomplete } from './createLspAutocomplete.js';
|
|
7
|
+
export class ExtensionLsp extends Extension {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
super(config);
|
|
10
|
+
Object.defineProperty(this, "config", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true,
|
|
14
|
+
value: config
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(this, "name", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: 'lsp'
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(this, "clients", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: {}
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(this, "uri", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: void 0
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(this, "extensionMarkdown", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true,
|
|
38
|
+
value: void 0
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(this, "extensionAutocomplete", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true,
|
|
44
|
+
value: void 0
|
|
45
|
+
});
|
|
46
|
+
Object.defineProperty(this, "mainLang", {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
configurable: true,
|
|
49
|
+
writable: true,
|
|
50
|
+
value: 'markdown'
|
|
51
|
+
});
|
|
52
|
+
Object.defineProperty(this, "source", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
configurable: true,
|
|
55
|
+
writable: true,
|
|
56
|
+
value: void 0
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
getProseMirrorPlugins() {
|
|
60
|
+
const plugins = [];
|
|
61
|
+
const { autocompleteConfig } = createLspAutocomplete(this);
|
|
62
|
+
plugins.push(new AutocompletePlugin(autocompleteConfig, this.editor));
|
|
63
|
+
plugins.push(new DiagnosticPlugin({}, this));
|
|
64
|
+
return plugins;
|
|
65
|
+
}
|
|
66
|
+
created() {
|
|
67
|
+
this.mainLang = this.editor.config.languageID || 'markdown';
|
|
68
|
+
this.source = {
|
|
69
|
+
ui: this.editor.ui,
|
|
70
|
+
getMappedContent: () => {
|
|
71
|
+
const editor = this.editor;
|
|
72
|
+
const result = this.extensionMarkdown.toMarkdown(editor.state.doc);
|
|
73
|
+
const mapper = new PositionMapper(editor, result.rawTextMap);
|
|
74
|
+
return {
|
|
75
|
+
...result,
|
|
76
|
+
mapper,
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const extensionMarkdown = this.editor
|
|
81
|
+
.getExtension('markdown');
|
|
82
|
+
if (!extensionMarkdown) {
|
|
83
|
+
throw new Error('No markdown extension');
|
|
84
|
+
}
|
|
85
|
+
this.extensionMarkdown = extensionMarkdown;
|
|
86
|
+
this.editor.addEventListener('doc:loaded', async () => {
|
|
87
|
+
const languageID = this.mainLang;
|
|
88
|
+
this.uri = this.editor.config.uri;
|
|
89
|
+
if (this.uri) {
|
|
90
|
+
const client = this.getClient(this.mainLang);
|
|
91
|
+
if (client) {
|
|
92
|
+
client.connect(this.uri, this.source);
|
|
93
|
+
await client.restart();
|
|
94
|
+
client.workspace.openFile(this.uri, languageID, this.source);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
this.editor.addEventListener('changed', () => {
|
|
99
|
+
if (this.editor.config.uri) {
|
|
100
|
+
const client = this.getClient(this.mainLang);
|
|
101
|
+
if (client) {
|
|
102
|
+
client.workspace.changedFile(this.editor.config.uri);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
this.editor.addEventListener('beforeDestroy', () => {
|
|
107
|
+
if (this.uri) {
|
|
108
|
+
const client = this.getClient(this.mainLang);
|
|
109
|
+
if (client) {
|
|
110
|
+
client.disconnect(this.uri);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
getClient(lang) {
|
|
116
|
+
if (!this.clients[lang]) {
|
|
117
|
+
const transport = this.config.getLspTransport(lang);
|
|
118
|
+
if (!transport) {
|
|
119
|
+
console.warn(`No lsp transport for ${lang}`);
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
this.clients[lang] = new LSPClient(transport, { rootUri: 'file:///' });
|
|
123
|
+
}
|
|
124
|
+
return this.clients[lang];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type * as lsp from 'vscode-languageserver-protocol';
|
|
2
|
+
import { TextDocumentSyncKind } from 'vscode-languageserver-protocol';
|
|
3
|
+
import { LspSource, Workspace, WorkspaceFile } from './workspace.js';
|
|
4
|
+
export type Transport = {
|
|
5
|
+
connect(): void;
|
|
6
|
+
disconnect(): void;
|
|
7
|
+
send(message: string): void;
|
|
8
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
9
|
+
removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
|
|
10
|
+
isConnected(): boolean;
|
|
11
|
+
isInitialized(): boolean;
|
|
12
|
+
};
|
|
13
|
+
export type LSPClientConfig = {
|
|
14
|
+
rootUri?: string;
|
|
15
|
+
workspace?: (client: LSPClient) => Workspace;
|
|
16
|
+
timeout?: number;
|
|
17
|
+
sanitizeHTML?: (html: string) => string;
|
|
18
|
+
unhandledNotification?: (client: LSPClient, method: string, params: any) => void;
|
|
19
|
+
};
|
|
20
|
+
export declare class LSPError extends Error {
|
|
21
|
+
isTimeout: boolean;
|
|
22
|
+
readonly isLSP = true;
|
|
23
|
+
static createTimeout(): LSPError;
|
|
24
|
+
}
|
|
25
|
+
export declare class LSPClient extends EventTarget {
|
|
26
|
+
private readonly transport;
|
|
27
|
+
readonly config: LSPClientConfig;
|
|
28
|
+
sources: Record<string, LspSource>;
|
|
29
|
+
workspace: Workspace;
|
|
30
|
+
private nextReqID;
|
|
31
|
+
private requests;
|
|
32
|
+
serverCapabilities: lsp.ServerCapabilities | null;
|
|
33
|
+
supportSync: TextDocumentSyncKind;
|
|
34
|
+
private readonly timeout;
|
|
35
|
+
private initializing;
|
|
36
|
+
private readonly receiveListener;
|
|
37
|
+
active: boolean;
|
|
38
|
+
constructor(transport: Transport, config?: LSPClientConfig);
|
|
39
|
+
startInitializing(): void;
|
|
40
|
+
stopInitializing(): void;
|
|
41
|
+
restart(): Promise<void>;
|
|
42
|
+
onInitialized(): void;
|
|
43
|
+
connect(uri: string, source: LspSource): void;
|
|
44
|
+
disconnect(uri: string): void;
|
|
45
|
+
didOpen(file: WorkspaceFile): Promise<boolean>;
|
|
46
|
+
didClose(uri: string): void;
|
|
47
|
+
private receiveMessage;
|
|
48
|
+
request<Params, Result>(method: string, params: Params): Promise<Result>;
|
|
49
|
+
private requestInner;
|
|
50
|
+
notification<Params>(method: string, params: Params): Promise<boolean>;
|
|
51
|
+
cancelRequest(params: any): void;
|
|
52
|
+
hasCapability(name: keyof lsp.ServerCapabilities): boolean | null;
|
|
53
|
+
sync(): void;
|
|
54
|
+
private timeoutRequest;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=LSPClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LSPClient.d.ts","sourceRoot":"","sources":["../../../src/extension-lsp/src/LSPClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAEL,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAEL,SAAS,EACT,SAAS,EACT,aAAa,EACd,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,IAAI,IAAI,CAAC;IAChB,UAAU,IAAI,IAAI,CAAC;IACnB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;IACR,mBAAmB,CACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,GAAG,IAAI,EACnD,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,GACvC,IAAI,CAAC;IACR,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC;CAC1B,CAAC;AAiEF,MAAM,MAAM,eAAe,GAAG;IAE5B,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,SAAS,CAAC;IAG7C,OAAO,CAAC,EAAE,MAAM,CAAC;IAOjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAGxC,qBAAqB,CAAC,EAAE,CACtB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,GAAG,KACR,IAAI,CAAC;CACX,CAAC;AAEF,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAS,UAAS;IAClB,QAAQ,CAAC,KAAK,QAAQ;IAEtB,MAAM,CAAC,aAAa;CAKrB;AAED,qBAAa,SAAU,SAAQ,WAAW;IAiBtC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,QAAQ,CAAC,MAAM,EAAE,eAAe;IAjBlC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAM;IAExC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAsB;IAEtC,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAQ;IAClD,WAAW,EAAE,oBAAoB,CAA6B;IAErE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,YAAY,CAA6C;IAEjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,MAAM,EAAE,OAAO,CAAS;gBAGL,SAAS,EAAE,SAAS,EAC5B,MAAM,GAAE,eAAoB;IAuCvC,iBAAiB;IAoCjB,gBAAgB;IAOV,OAAO;IASb,aAAa;IAQb,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS;IAWtC,UAAU,CAAC,GAAG,EAAE,MAAM;IAahB,OAAO,CAAC,IAAI,EAAE,aAAa;IAmBjC,QAAQ,CAAC,GAAG,EAAE,MAAM;IASpB,OAAO,CAAC,cAAc;IA+ChB,OAAO,CAAC,MAAM,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAalB,OAAO,CAAC,YAAY;IA8Cd,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB5E,aAAa,CAAC,MAAM,EAAE,GAAG;IAOzB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,kBAAkB;IAIhD,IAAI;IAIJ,OAAO,CAAC,cAAc;CAcvB"}
|