@piedata/pieui 1.1.27 → 1.1.29

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 CHANGED
@@ -88,3 +88,13 @@ Type exports:
88
88
  - `PieConfig`: Configuration object for Pie roots. Includes `apiServer` and optional `centrifugeServer`, `enableRenderingLog`, `pageProcessor`.
89
89
  - `UIConfigType`: Server-driven UI configuration with `card`, `data`, and `content` (nested `UIConfigType` or array).
90
90
  - `SetUiAjaxConfigurationType`: Setter type for updating the UI configuration or streaming UI events.
91
+
92
+ **Shadcn Registry Output**
93
+
94
+ `pieui postbuild` now also creates shadcn-compatible registry artifacts:
95
+
96
+ - `dist/registry.json`: registry source manifest.
97
+ - `dist/r/index.json`: index of installable items.
98
+ - `dist/r/<item>.json`: per-component registry item files.
99
+
100
+ Each item installs a lightweight wrapper component that re-exports the corresponding component from `@piedata/pieui/components`.
package/dist/cli.js CHANGED
@@ -4,15 +4,29 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
@@ -608,6 +622,7 @@ var require_minimatch = __commonJS((exports2, module2) => {
608
622
  pattern = pattern.split(path.sep).join("/");
609
623
  }
610
624
  this.options = options;
625
+ this.maxGlobstarRecursion = options.maxGlobstarRecursion !== undefined ? options.maxGlobstarRecursion : 200;
611
626
  this.set = [];
612
627
  this.pattern = pattern;
613
628
  this.regexp = null;
@@ -1016,52 +1031,127 @@ var require_minimatch = __commonJS((exports2, module2) => {
1016
1031
  return this.negate;
1017
1032
  };
1018
1033
  Minimatch.prototype.matchOne = function(file, pattern, partial) {
1019
- var options = this.options;
1020
- this.debug("matchOne", { this: this, file, pattern });
1021
- this.debug("matchOne", file.length, pattern.length);
1022
- for (var fi2 = 0, pi2 = 0, fl = file.length, pl = pattern.length;fi2 < fl && pi2 < pl; fi2++, pi2++) {
1023
- this.debug("matchOne loop");
1024
- var p = pattern[pi2];
1025
- var f = file[fi2];
1026
- this.debug(pattern, p, f);
1027
- if (p === false)
1034
+ if (pattern.indexOf(GLOBSTAR) !== -1) {
1035
+ return this._matchGlobstar(file, pattern, partial, 0, 0);
1036
+ }
1037
+ return this._matchOne(file, pattern, partial, 0, 0);
1038
+ };
1039
+ Minimatch.prototype._matchGlobstar = function(file, pattern, partial, fileIndex, patternIndex) {
1040
+ var i;
1041
+ var firstgs = -1;
1042
+ for (i = patternIndex;i < pattern.length; i++) {
1043
+ if (pattern[i] === GLOBSTAR) {
1044
+ firstgs = i;
1045
+ break;
1046
+ }
1047
+ }
1048
+ var lastgs = -1;
1049
+ for (i = pattern.length - 1;i >= 0; i--) {
1050
+ if (pattern[i] === GLOBSTAR) {
1051
+ lastgs = i;
1052
+ break;
1053
+ }
1054
+ }
1055
+ var head = pattern.slice(patternIndex, firstgs);
1056
+ var body = partial ? pattern.slice(firstgs + 1) : pattern.slice(firstgs + 1, lastgs);
1057
+ var tail = partial ? [] : pattern.slice(lastgs + 1);
1058
+ if (head.length) {
1059
+ var fileHead = file.slice(fileIndex, fileIndex + head.length);
1060
+ if (!this._matchOne(fileHead, head, partial, 0, 0)) {
1028
1061
  return false;
1029
- if (p === GLOBSTAR) {
1030
- this.debug("GLOBSTAR", [pattern, p, f]);
1031
- var fr = fi2;
1032
- var pr = pi2 + 1;
1033
- if (pr === pl) {
1034
- this.debug("** at the end");
1035
- for (;fi2 < fl; fi2++) {
1036
- if (file[fi2] === "." || file[fi2] === ".." || !options.dot && file[fi2].charAt(0) === ".")
1037
- return false;
1038
- }
1039
- return true;
1062
+ }
1063
+ fileIndex += head.length;
1064
+ }
1065
+ var fileTailMatch = 0;
1066
+ if (tail.length) {
1067
+ if (tail.length + fileIndex > file.length)
1068
+ return false;
1069
+ var tailStart = file.length - tail.length;
1070
+ if (this._matchOne(file, tail, partial, tailStart, 0)) {
1071
+ fileTailMatch = tail.length;
1072
+ } else {
1073
+ if (file[file.length - 1] !== "" || fileIndex + tail.length === file.length) {
1074
+ return false;
1040
1075
  }
1041
- while (fr < fl) {
1042
- var swallowee = file[fr];
1043
- this.debug(`
1044
- globstar while`, file, fr, pattern, pr, swallowee);
1045
- if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
1046
- this.debug("globstar found match!", fr, fl, swallowee);
1047
- return true;
1048
- } else {
1049
- if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") {
1050
- this.debug("dot detected!", file, fr, pattern, pr);
1051
- break;
1052
- }
1053
- this.debug("globstar swallow a segment, and continue");
1054
- fr++;
1055
- }
1076
+ tailStart--;
1077
+ if (!this._matchOne(file, tail, partial, tailStart, 0)) {
1078
+ return false;
1056
1079
  }
1057
- if (partial) {
1058
- this.debug(`
1059
- >>> no match, partial?`, file, fr, pattern, pr);
1060
- if (fr === fl)
1061
- return true;
1080
+ fileTailMatch = tail.length + 1;
1081
+ }
1082
+ }
1083
+ if (!body.length) {
1084
+ var sawSome = !!fileTailMatch;
1085
+ for (i = fileIndex;i < file.length - fileTailMatch; i++) {
1086
+ var f = String(file[i]);
1087
+ sawSome = true;
1088
+ if (f === "." || f === ".." || !this.options.dot && f.charAt(0) === ".") {
1089
+ return false;
1090
+ }
1091
+ }
1092
+ return partial || sawSome;
1093
+ }
1094
+ var bodySegments = [[[], 0]];
1095
+ var currentBody = bodySegments[0];
1096
+ var nonGsParts = 0;
1097
+ var nonGsPartsSums = [0];
1098
+ for (var bi2 = 0;bi2 < body.length; bi2++) {
1099
+ var b = body[bi2];
1100
+ if (b === GLOBSTAR) {
1101
+ nonGsPartsSums.push(nonGsParts);
1102
+ currentBody = [[], 0];
1103
+ bodySegments.push(currentBody);
1104
+ } else {
1105
+ currentBody[0].push(b);
1106
+ nonGsParts++;
1107
+ }
1108
+ }
1109
+ var idx = bodySegments.length - 1;
1110
+ var fileLength = file.length - fileTailMatch;
1111
+ for (var si2 = 0;si2 < bodySegments.length; si2++) {
1112
+ bodySegments[si2][1] = fileLength - (nonGsPartsSums[idx--] + bodySegments[si2][0].length);
1113
+ }
1114
+ return !!this._matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
1115
+ };
1116
+ Minimatch.prototype._matchGlobStarBodySections = function(file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
1117
+ var bs2 = bodySegments[bodyIndex];
1118
+ if (!bs2) {
1119
+ for (var i = fileIndex;i < file.length; i++) {
1120
+ sawTail = true;
1121
+ var f = file[i];
1122
+ if (f === "." || f === ".." || !this.options.dot && f.charAt(0) === ".") {
1123
+ return false;
1124
+ }
1125
+ }
1126
+ return sawTail;
1127
+ }
1128
+ var body = bs2[0];
1129
+ var after = bs2[1];
1130
+ while (fileIndex <= after) {
1131
+ var m = this._matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
1132
+ if (m && globStarDepth < this.maxGlobstarRecursion) {
1133
+ var sub = this._matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
1134
+ if (sub !== false) {
1135
+ return sub;
1062
1136
  }
1137
+ }
1138
+ var f = file[fileIndex];
1139
+ if (f === "." || f === ".." || !this.options.dot && f.charAt(0) === ".") {
1063
1140
  return false;
1064
1141
  }
1142
+ fileIndex++;
1143
+ }
1144
+ return partial || null;
1145
+ };
1146
+ Minimatch.prototype._matchOne = function(file, pattern, partial, fileIndex, patternIndex) {
1147
+ var fi2, pi2, fl, pl;
1148
+ for (fi2 = fileIndex, pi2 = patternIndex, fl = file.length, pl = pattern.length;fi2 < fl && pi2 < pl; fi2++, pi2++) {
1149
+ this.debug("matchOne loop");
1150
+ var p = pattern[pi2];
1151
+ var f = file[fi2];
1152
+ this.debug(pattern, p, f);
1153
+ if (p === false || p === GLOBSTAR)
1154
+ return false;
1065
1155
  var hit;
1066
1156
  if (typeof p === "string") {
1067
1157
  hit = f === p;
@@ -187133,6 +187223,10 @@ var TJS = __toESM(require_typescript_json_schema(), 1);
187133
187223
  var __dirname = "/home/runner/work/pieui/pieui/src";
187134
187224
  var MANIFEST_FILENAME = "pieui.components.json";
187135
187225
  var REGISTER_FUNCTION = "registerPieComponent";
187226
+ var SHADCN_REGISTRY_SOURCE_FILENAME = "registry.json";
187227
+ var SHADCN_REGISTRY_DIRECTORY = "r";
187228
+ var SHADCN_REGISTRY_INDEX_FILENAME = "index.json";
187229
+ var SHADCN_ITEM_SCHEMA = "https://ui.shadcn.com/schema/registry-item.json";
187136
187230
  var ts3 = TJS.ts;
187137
187231
  var parseArgs = (argv) => {
187138
187232
  const [command = ""] = argv;
@@ -187810,6 +187904,147 @@ export default ${componentName}
187810
187904
  break;
187811
187905
  }
187812
187906
  };
187907
+ var toKebabCase = (value2) => {
187908
+ return value2.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
187909
+ };
187910
+ var normalizeRepositoryUrl = (value2) => {
187911
+ return value2.replace(/^git\+/, "").replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
187912
+ };
187913
+ var readPackageMetadata = () => {
187914
+ const fallback = {
187915
+ name: "@piedata/pieui",
187916
+ homepage: "https://github.com/PieDataLabs/pieui"
187917
+ };
187918
+ const packageJsonPath = import_path.default.join(process.cwd(), "package.json");
187919
+ if (!import_fs2.default.existsSync(packageJsonPath)) {
187920
+ return fallback;
187921
+ }
187922
+ try {
187923
+ const packageJsonRaw = import_fs2.default.readFileSync(packageJsonPath, "utf8");
187924
+ const packageJson = JSON.parse(packageJsonRaw);
187925
+ const packageName = packageJson.name || fallback.name;
187926
+ const repositoryUrl = typeof packageJson.repository === "string" ? packageJson.repository : packageJson.repository?.url;
187927
+ const homepage = packageJson.homepage || (repositoryUrl ? normalizeRepositoryUrl(repositoryUrl) : fallback.homepage);
187928
+ return {
187929
+ name: packageName,
187930
+ homepage
187931
+ };
187932
+ } catch {
187933
+ return fallback;
187934
+ }
187935
+ };
187936
+ var findComponentExports = (srcDir) => {
187937
+ const componentsIndexPath = import_path.default.join(srcDir, "components", "index.ts");
187938
+ if (!import_fs2.default.existsSync(componentsIndexPath)) {
187939
+ console.log(`[pieui] Warning: ${componentsIndexPath} not found. Skipping shadcn registry generation.`);
187940
+ return [];
187941
+ }
187942
+ const sourceText = import_fs2.default.readFileSync(componentsIndexPath, "utf8");
187943
+ const sourceFile = ts3.createSourceFile(componentsIndexPath, sourceText, ts3.ScriptTarget.ES2020, true, ts3.ScriptKind.TS);
187944
+ const exports2 = [];
187945
+ for (const statement of sourceFile.statements) {
187946
+ if (!ts3.isExportDeclaration(statement) || !statement.moduleSpecifier || !ts3.isStringLiteral(statement.moduleSpecifier) || !statement.exportClause || !ts3.isNamedExports(statement.exportClause)) {
187947
+ continue;
187948
+ }
187949
+ const sourcePath = statement.moduleSpecifier.text;
187950
+ for (const element of statement.exportClause.elements) {
187951
+ if (element.propertyName && ts3.isIdentifier(element.propertyName) && element.propertyName.text === "default") {
187952
+ exports2.push({
187953
+ name: element.name.text,
187954
+ sourcePath
187955
+ });
187956
+ }
187957
+ }
187958
+ }
187959
+ return exports2;
187960
+ };
187961
+ var createShadcnWrapperContent = (componentName, packageName) => {
187962
+ return `import { ${componentName} } from '${packageName}/components'
187963
+
187964
+ export default ${componentName}
187965
+ `;
187966
+ };
187967
+ var writeShadcnRegistry = (outDir, srcDir, componentManifest) => {
187968
+ console.log("[pieui] Generating shadcn registry...");
187969
+ const exports2 = findComponentExports(srcDir).sort((a, b) => a.name.localeCompare(b.name));
187970
+ if (exports2.length === 0) {
187971
+ console.log("[pieui] Warning: No default exports found in src/components/index.ts");
187972
+ return;
187973
+ }
187974
+ const packageMetadata = readPackageMetadata();
187975
+ const manifestByCard = new Map(componentManifest.map((entry) => [entry.card, entry]));
187976
+ const usedItemNames = new Set;
187977
+ const getUniqueItemName = (initialName) => {
187978
+ if (!usedItemNames.has(initialName)) {
187979
+ usedItemNames.add(initialName);
187980
+ return initialName;
187981
+ }
187982
+ let index = 2;
187983
+ while (usedItemNames.has(`${initialName}-${index}`)) {
187984
+ index += 1;
187985
+ }
187986
+ const uniqueName = `${initialName}-${index}`;
187987
+ usedItemNames.add(uniqueName);
187988
+ return uniqueName;
187989
+ };
187990
+ const items = exports2.map((component) => {
187991
+ const itemName = getUniqueItemName(toKebabCase(component.name));
187992
+ const schemaEntry = manifestByCard.get(component.name);
187993
+ const description = schemaEntry ? `${component.name} card from PieUI` : `${component.name} component from PieUI`;
187994
+ const meta = {
187995
+ sourceExport: component.name,
187996
+ sourcePath: component.sourcePath
187997
+ };
187998
+ if (schemaEntry) {
187999
+ meta.pieCard = schemaEntry.card;
188000
+ meta.dataSchema = schemaEntry.data;
188001
+ }
188002
+ return {
188003
+ $schema: SHADCN_ITEM_SCHEMA,
188004
+ name: itemName,
188005
+ type: "registry:component",
188006
+ title: component.name,
188007
+ description,
188008
+ dependencies: [packageMetadata.name],
188009
+ files: [
188010
+ {
188011
+ path: `registry/${itemName}.tsx`,
188012
+ type: "registry:component",
188013
+ content: createShadcnWrapperContent(component.name, packageMetadata.name)
188014
+ }
188015
+ ],
188016
+ meta
188017
+ };
188018
+ });
188019
+ const registry = {
188020
+ name: packageMetadata.name,
188021
+ homepage: packageMetadata.homepage,
188022
+ items: items.map((item) => ({
188023
+ name: item.name,
188024
+ type: item.type,
188025
+ title: item.title,
188026
+ description: item.description
188027
+ }))
188028
+ };
188029
+ const resolvedOutDir = import_path.default.resolve(process.cwd(), outDir);
188030
+ const registryDir = import_path.default.join(resolvedOutDir, SHADCN_REGISTRY_DIRECTORY);
188031
+ import_fs2.default.mkdirSync(registryDir, { recursive: true });
188032
+ const sourceRegistryPath = import_path.default.join(resolvedOutDir, SHADCN_REGISTRY_SOURCE_FILENAME);
188033
+ import_fs2.default.writeFileSync(sourceRegistryPath, JSON.stringify(registry, null, 2));
188034
+ const indexPath = import_path.default.join(registryDir, SHADCN_REGISTRY_INDEX_FILENAME);
188035
+ import_fs2.default.writeFileSync(indexPath, JSON.stringify(items.map((item) => ({
188036
+ name: item.name,
188037
+ type: item.type,
188038
+ title: item.title,
188039
+ description: item.description
188040
+ })), null, 2));
188041
+ for (const item of items) {
188042
+ const itemPath = import_path.default.join(registryDir, `${item.name}.json`);
188043
+ import_fs2.default.writeFileSync(itemPath, JSON.stringify(item, null, 2));
188044
+ }
188045
+ console.log(`[pieui] Shadcn registry saved to ${sourceRegistryPath} and ${registryDir}`);
188046
+ console.log(`[pieui] Shadcn components generated: ${items.length}`);
188047
+ };
187813
188048
  var main = async () => {
187814
188049
  const { command, outDir, srcDir, append, componentName, componentType } = parseArgs(process.argv.slice(2));
187815
188050
  console.log(`[pieui] CLI started with command: "${command}"`);
@@ -187963,6 +188198,7 @@ var main = async () => {
187963
188198
  import_fs2.default.writeFileSync(manifestPath, JSON.stringify(mergedEntries, null, 2), "utf8");
187964
188199
  console.log(`[pieui] Component manifest saved to ${manifestPath}`);
187965
188200
  console.log(`[pieui] Total components: ${mergedEntries.length} (${existingEntries.length} from pieui, ${entries.length} new/updated)`);
188201
+ writeShadcnRegistry(outDir, srcDir, mergedEntries);
187966
188202
  } catch (error) {
187967
188203
  const message = error instanceof Error ? error.message : String(error);
187968
188204
  console.error(`[pieui] Failed to generate component manifest: ${message}`);
@@ -2,8 +2,11 @@ export { default as PieCard } from './PieCard';
2
2
  export { default as UI } from './UI';
3
3
  export { default as ChatCard } from './Chats/ChatCard';
4
4
  export { default as AjaxButtonCard } from './Buttons/AjaxButtonCard';
5
+ export { default as AjaxGroupCard } from './Containers/AjaxGroupCard';
5
6
  export { default as RedirectButtonCard } from './Buttons/RedirectButtonCard';
6
7
  export { default as SequenceCard } from './Containers/SequenceCard';
8
+ export { default as BoxCard } from './Containers/BoxCard';
9
+ export { default as TableCard } from './Containers/TableCard';
7
10
  export { default as UnionCard } from './Containers/UnionCard';
8
11
  export { default as HTMLEmbedCard } from './Common/HTMLEmbedCard';
9
12
  export { default as OpenAIVoiceAgentCard } from './Agents/OpenAIVoiceAgentCard';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAC5E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAC/E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACvE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAC5E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAC/E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACvE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA"}