xml-tokenizer 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/dist/cjs/selector/TokenSelector.js +1 -1
- package/dist/cjs/selector/select.js +1 -1
- package/dist/cjs/xml-to-simplified-object.js +1 -1
- package/dist/esm/selector/TokenSelector.js +1 -1
- package/dist/esm/selector/select.js +1 -1
- package/dist/esm/xml-to-simplified-object.js +1 -1
- package/dist/types/selector/TokenSelector.d.ts +2 -3
- package/dist/types/selector/TokenSelector.d.ts.map +1 -1
- package/dist/types/selector/select.d.ts +2 -3
- package/dist/types/selector/select.d.ts.map +1 -1
- package/dist/types/selector/types.d.ts +7 -0
- package/dist/types/selector/types.d.ts.map +1 -1
- package/dist/types/xml-to-simplified-object.d.ts +2 -3
- package/dist/types/xml-to-simplified-object.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ The implementation is based on the [roxmltree](https://github.com/RazrFalcon/rox
|
|
|
35
35
|
|
|
36
36
|
Create a typesafe, straightforward, and lightweight [XML](https://de.wikipedia.org/wiki/Extensible_Markup_Language) parser. Many existing parsers either lack TypeScript support, aren't actively maintained, or exceed 20kB gzipped.
|
|
37
37
|
|
|
38
|
-
My goal was to develop an efficient & flexible alternative by porting [roxmltree](https://github.com/RazrFalcon/roxmltree) to TypeScript or integrating it via WASM. While it functions well and is quite
|
|
38
|
+
My goal was to develop an efficient & flexible alternative by porting [roxmltree](https://github.com/RazrFalcon/roxmltree) to TypeScript or integrating it via WASM. While it functions well and is quite versatile due to its streaming approach, it's not as fast as I hoped.
|
|
39
39
|
|
|
40
40
|
### ⚖️ Alternatives
|
|
41
41
|
|
|
@@ -46,13 +46,16 @@ My goal was to develop an efficient & flexible alternative by porting [roxmltree
|
|
|
46
46
|
## 📖 Usage
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import { xmlToObject,
|
|
49
|
+
import { xmlToObject, xmlToSimplifiedObject, tokenize, select } from 'xml-tokenizer';
|
|
50
50
|
|
|
51
|
-
// Parse XML to Javascript object (uses `
|
|
51
|
+
// Parse XML to Javascript object without information lost (uses `tokenize` under the hood)
|
|
52
52
|
const xmlObject = xmlToObject("<p>Hello World</p>");
|
|
53
53
|
|
|
54
|
+
// Or, parse XML to easy to queryable Javascript object
|
|
55
|
+
const simplifiedXmlObject = xmlToSimplifiedObject("<p>Hello World</p>");
|
|
56
|
+
|
|
54
57
|
// Or, parse XML to a stream of tokens
|
|
55
|
-
|
|
58
|
+
tokenize("<p>Hello World</p>", false, (token) => {
|
|
56
59
|
switch (token.type) {
|
|
57
60
|
case 'ElementStart':
|
|
58
61
|
console.log('Start of element:', token);
|
|
@@ -65,6 +68,16 @@ parseString("<p>Hello World</p>", false, (token) => {
|
|
|
65
68
|
console.log('Token:', token);
|
|
66
69
|
}
|
|
67
70
|
});
|
|
71
|
+
|
|
72
|
+
// Or, stream only a selection of tokens
|
|
73
|
+
select(xml, [
|
|
74
|
+
[
|
|
75
|
+
{ axis: 'child', local: 'bookstore' },
|
|
76
|
+
{ axis: 'child', local: 'book', attributes: [{ local: 'category', value: 'COOKING' }] }
|
|
77
|
+
]
|
|
78
|
+
], (selectedToken) => {
|
|
79
|
+
// Handle selected token
|
|
80
|
+
});
|
|
68
81
|
```
|
|
69
82
|
|
|
70
83
|
### Token Types
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=require("./TokenSelectState.js"),l=require("./TokenSelectStateMachine.js"),u=Object.defineProperty,S=(r,t,
|
|
1
|
+
"use strict";var a=require("./TokenSelectState.js"),l=require("./TokenSelectStateMachine.js"),u=Object.defineProperty,S=(r,t,e)=>t in r?u(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,s=(r,t,e)=>S(r,typeof t!="symbol"?t+"":t,e);class p{constructor(t){s(this,"_currentDepth",0),s(this,"_tspStateMachines"),s(this,"_isRecording",!1),this._tspStateMachines=t.map(e=>new l.TokenSelectStateMachine(e))}pipeToken(t,e){let n=!1,i=!1;switch(t.type){case"ElementStart":n=this.handleElementStart(t);break;case"Attribute":n=this.handleAttribute(t);break;case"Text":n=this.handleText(t);break;case"ElementEnd":{i=this.handleElementEnd(t);break}}n&&!this._isRecording&&(this._isRecording=!0,e({type:"SelectionStart"}));for(const c of this._tspStateMachines){c.record(t);const h=c.takeRecordedTokens();h!=null&&h.forEach(o=>{e(o)})}this._isRecording&&e(t),i&&(e({type:"SelectionEnd"}),this._isRecording=!1)}handleElementStart(t){this._currentDepth+=1;let e=!1;for(const n of this._tspStateMachines){if(n.resetCurrentStateCache(),n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.ETokenMatchCriteria.Name)||n.transitionIfNameMatch(t.local,t.prefix,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleAttribute(t){let e=!1;for(const n of this._tspStateMachines){if(n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.ETokenMatchCriteria.Attributes)||n.transitionIfAttributesMatch(t.local,t.prefix,t.value,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleText(t){let e=!1;for(const n of this._tspStateMachines){if(n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.ETokenMatchCriteria.Text)||n.transitionIfTextMatch(t.text,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleElementEnd(t){if(t.end.type==="Close"||t.end.type==="Empty"){this._currentDepth-=1;let e=!1;for(const n of this._tspStateMachines){const i=n.getCurrentState();i!=null&&(i.enteredDepth!=null&&this._currentDepth<i.enteredDepth&&n.transitionBack(this._currentDepth),e=e||n.isFinalState())}return!e}return!1}}exports.TokenSelector=p;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var i=require("../tokenizer/tokenize.js"),k=require("./TokenSelector.js");function
|
|
1
|
+
"use strict";var i=require("../tokenizer/tokenize.js"),k=require("./TokenSelector.js");function l(e,t,n){const o=new k.TokenSelector(t);i.tokenize(e,!1,r=>{o.pipeToken(r,c=>{n(c)})})}exports.select=l;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=require("./get-q-name.js"),o=require("./tokenizer/tokenize.js");function s(i,l=!1){const e={},t=[e];return o.tokenize(i,l,r=>{a(r,t)}),e}function a(i,l){switch(i.type){case"ElementStart":{const e=c.getQName(i.local,i.prefix),t=`_${e}`,r={},n=l[l.length-1];n!=null&&(n.content!=null?(r.tag=e,n.content.push(r)):n.text!=null?(r.tag=e,n.content=[n.text,r],delete n.text):n[t]==null?n[t]=[r]:Array.isArray(n[t])?n[t].push(r):n[t]=[n[t],r]),l.push(r);break}case"ElementEnd":{(i.end.type==="Close"||i.end.type==="Empty")&&l.pop();break}case"Attribute":{const e=l[l.length-1];if(e!=null){const t=c.getQName(i.local,i.prefix);e.attributes!=null?e.attributes[t]=i.value:e.attributes={[t]:i.value}}break}case"Text":case"Cdata":{const e=l[l.length-1];if(e!=null){const t=i.text.trim();t.length>0&&(e.content!=null?e.content.push(t):e.text!=null?(e.content=[e.text,t],delete e.text):e.text=t)}break}}}exports.processTokenForSimplifiedObject=a,exports.xmlToSimplifiedObject=s;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ETokenMatchCriteria as a}from"./TokenSelectState.js";import{TokenSelectStateMachine as l}from"./TokenSelectStateMachine.js";var u=Object.defineProperty,p=(r,t,
|
|
1
|
+
import{ETokenMatchCriteria as a}from"./TokenSelectState.js";import{TokenSelectStateMachine as l}from"./TokenSelectStateMachine.js";var u=Object.defineProperty,p=(r,t,e)=>t in r?u(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,s=(r,t,e)=>p(r,typeof t!="symbol"?t+"":t,e);class f{constructor(t){s(this,"_currentDepth",0),s(this,"_tspStateMachines"),s(this,"_isRecording",!1),this._tspStateMachines=t.map(e=>new l(e))}pipeToken(t,e){let n=!1,i=!1;switch(t.type){case"ElementStart":n=this.handleElementStart(t);break;case"Attribute":n=this.handleAttribute(t);break;case"Text":n=this.handleText(t);break;case"ElementEnd":{i=this.handleElementEnd(t);break}}n&&!this._isRecording&&(this._isRecording=!0,e({type:"SelectionStart"}));for(const c of this._tspStateMachines){c.record(t);const h=c.takeRecordedTokens();h!=null&&h.forEach(o=>{e(o)})}this._isRecording&&e(t),i&&(e({type:"SelectionEnd"}),this._isRecording=!1)}handleElementStart(t){this._currentDepth+=1;let e=!1;for(const n of this._tspStateMachines){if(n.resetCurrentStateCache(),n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.Name)||n.transitionIfNameMatch(t.local,t.prefix,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleAttribute(t){let e=!1;for(const n of this._tspStateMachines){if(n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.Attributes)||n.transitionIfAttributesMatch(t.local,t.prefix,t.value,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleText(t){let e=!1;for(const n of this._tspStateMachines){if(n.isFinalState())continue;const i=n.getNextState();i==null||!(i.matchCriteria&a.Text)||n.transitionIfTextMatch(t.text,this._currentDepth)&&n.isFinalState()&&(e=!0)}return e}handleElementEnd(t){if(t.end.type==="Close"||t.end.type==="Empty"){this._currentDepth-=1;let e=!1;for(const n of this._tspStateMachines){const i=n.getCurrentState();i!=null&&(i.enteredDepth!=null&&this._currentDepth<i.enteredDepth&&n.transitionBack(this._currentDepth),e=e||n.isFinalState())}return!e}return!1}}export{f as TokenSelector};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{tokenize as p}from"../tokenizer/tokenize.js";import{TokenSelector as c}from"./TokenSelector.js";function m(e,o,
|
|
1
|
+
import{tokenize as p}from"../tokenizer/tokenize.js";import{TokenSelector as c}from"./TokenSelector.js";function m(e,o,t){const n=new c(o);p(e,!1,r=>{n.pipeToken(r,i=>{t(i)})})}export{m as select};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getQName as
|
|
1
|
+
import{getQName as c}from"./get-q-name.js";import{tokenize as i}from"./tokenizer/tokenize.js";function s(o,l=!1){const t={},e=[t];return i(o,l,r=>{a(r,e)}),t}function a(o,l){switch(o.type){case"ElementStart":{const t=c(o.local,o.prefix),e=`_${t}`,r={},n=l[l.length-1];n!=null&&(n.content!=null?(r.tag=t,n.content.push(r)):n.text!=null?(r.tag=t,n.content=[n.text,r],delete n.text):n[e]==null?n[e]=[r]:Array.isArray(n[e])?n[e].push(r):n[e]=[n[e],r]),l.push(r);break}case"ElementEnd":{(o.end.type==="Close"||o.end.type==="Empty")&&l.pop();break}case"Attribute":{const t=l[l.length-1];if(t!=null){const e=c(o.local,o.prefix);t.attributes!=null?t.attributes[e]=o.value:t.attributes={[e]:o.value}}break}case"Text":case"Cdata":{const t=l[l.length-1];if(t!=null){const e=o.text.trim();e.length>0&&(t.content!=null?t.content.push(e):t.text!=null?(t.content=[t.text,e],delete t.text):t.text=e)}break}}}export{a as processTokenForSimplifiedObject,s as xmlToSimplifiedObject};
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { type TXmlToken } from '../tokenizer';
|
|
2
|
-
import { type TTokenSelectPath } from './types';
|
|
2
|
+
import { type TSelectedXmlToken, type TTokenSelectPath } from './types';
|
|
3
3
|
export declare class TokenSelector {
|
|
4
4
|
private _currentDepth;
|
|
5
5
|
private _tspStateMachines;
|
|
6
6
|
private _isRecording;
|
|
7
7
|
constructor(tokenSelectPaths: TTokenSelectPath[]);
|
|
8
|
-
pipeToken(token: TXmlToken, recorder: (token:
|
|
8
|
+
pipeToken(token: TXmlToken, recorder: (token: TSelectedXmlToken) => void): void;
|
|
9
9
|
private handleElementStart;
|
|
10
10
|
private handleAttribute;
|
|
11
11
|
private handleText;
|
|
12
12
|
private handleElementEnd;
|
|
13
|
-
private record;
|
|
14
13
|
}
|
|
15
14
|
//# sourceMappingURL=TokenSelector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenSelector.d.ts","sourceRoot":"","sources":["../../../src/selector/TokenSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,SAAS,EACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"TokenSelector.d.ts","sourceRoot":"","sources":["../../../src/selector/TokenSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,SAAS,EACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAExE,qBAAa,aAAa;IACzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,YAAY,CAAS;gBAEjB,gBAAgB,EAAE,gBAAgB,EAAE;IAMzC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI;IA6CtF,OAAO,CAAC,kBAAkB;IA6B1B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,gBAAgB;CAuBxB"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
3
|
-
export declare function select(xml: string, tokenSelectPaths: TTokenSelectPath[], callback: TTokenCallback): void;
|
|
1
|
+
import { type TSelectedTokenCallback, type TTokenSelectPath } from './types';
|
|
2
|
+
export declare function select(xml: string, tokenSelectPaths: TTokenSelectPath[], callback: TSelectedTokenCallback): void;
|
|
4
3
|
//# sourceMappingURL=select.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/selector/select.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/selector/select.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE7E,wBAAgB,MAAM,CACrB,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,gBAAgB,EAAE,EACpC,QAAQ,EAAE,sBAAsB,GAC9B,IAAI,CAON"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { type TXmlToken } from '../tokenizer';
|
|
2
|
+
export type TSelectedXmlToken = TXmlToken | {
|
|
3
|
+
type: 'SelectionStart';
|
|
4
|
+
} | {
|
|
5
|
+
type: 'SelectionEnd';
|
|
6
|
+
};
|
|
7
|
+
export type TSelectedTokenCallback = (token: TSelectedXmlToken) => void;
|
|
1
8
|
/**
|
|
2
9
|
* A limited segment of an XPath expression in an object-oriented manner.
|
|
3
10
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/selector/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,MAAM,WAAW,uBAAuB;IACvC;;;;;OAKG;IACH,IAAI,EAAE,OAAO,GAAG,oBAAoB,CAAC;IAErC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAElE;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,MAAM,CAAC;KACd,KAAK,OAAO,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/selector/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAElG,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAExE;;;;;;;;;;;;;;GAcG;AAGH,MAAM,WAAW,uBAAuB;IACvC;;;;;OAKG;IACH,IAAI,EAAE,OAAO,GAAG,oBAAoB,CAAC;IAErC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAElE;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,MAAM,CAAC;KACd,KAAK,OAAO,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAC"}
|
|
@@ -6,8 +6,7 @@ export interface TSimplifiedXmlNode {
|
|
|
6
6
|
attributes?: Record<string, string>;
|
|
7
7
|
text?: string;
|
|
8
8
|
content?: (string | TSimplifiedXmlNode)[];
|
|
9
|
-
[key: TSimplifiedXmlNodeTagName]: TSimplifiedXmlNode
|
|
9
|
+
[key: TSimplifiedXmlNodeTagName]: TSimplifiedXmlNode[];
|
|
10
10
|
}
|
|
11
|
-
type TSimplifiedXmlNodeTagName = `_${string}`;
|
|
12
|
-
export {};
|
|
11
|
+
export type TSimplifiedXmlNodeTagName = `_${string}`;
|
|
13
12
|
//# sourceMappingURL=xml-to-simplified-object.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xml-to-simplified-object.d.ts","sourceRoot":"","sources":["../../src/xml-to-simplified-object.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAEvD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,kBAAkB,CAS7F;AAED,wBAAgB,+BAA+B,CAC9C,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,kBAAkB,EAAE,GACzB,IAAI,CAsEN;AAED,MAAM,WAAW,kBAAkB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC;IAE1C,CAAC,GAAG,EAAE,yBAAyB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"xml-to-simplified-object.d.ts","sourceRoot":"","sources":["../../src/xml-to-simplified-object.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAEvD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,kBAAkB,CAS7F;AAED,wBAAgB,+BAA+B,CAC9C,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,kBAAkB,EAAE,GACzB,IAAI,CAsEN;AAED,MAAM,WAAW,kBAAkB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC;IAE1C,CAAC,GAAG,EAAE,yBAAyB,GAAG,kBAAkB,EAAE,CAAC;CACvD;AAED,MAAM,MAAM,yBAAyB,GAAG,IAAI,MAAM,EAAE,CAAC"}
|