@ggui-ai/ui-gen 0.6.2 → 0.6.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/base.ts","../../src/adapters/tool-bridge.ts","../../src/adapters/extract-code.ts","../../src/adapters/claude/client.ts","../../src/adapters/claude/raw.ts","../../src/adapters/claude/message-parser.ts","../../src/adapters/claude/tool-bridge.ts","../../src/adapters/claude/sdk.ts","../../src/adapters/openai/raw.ts","../../src/adapters/openai/sdk.ts","../../src/adapters/google/raw.ts","../../src/adapters/google/sdk.ts","../../src/adapters/openrouter/types.ts","../../src/adapters/openrouter/client.ts","../../src/adapters/openrouter/raw.ts","../../src/adapters/types.ts","../../src/adapters/index.ts","../../src/adapters/registry.ts","../../src/validation/primitives.ts","../../src/validation/allowed-imports.ts","../../src/validation/component-detailed.ts","../../src/design-system-docs.ts","../../src/boilerplate/json-schema-ts.ts","../../src/check/contract-validation.ts","../../src/check/type-checker.ts","../../src/check/react-linter.ts","../../src/tools/render-check.ts","../../src/adapters/tools.ts"],"names":["path","init_tool_bridge","raw_exports","init_raw","sdk_exports","init_sdk","result","init_client","ClaudeRawAdapter","ClaudeSdkAdapter","OpenAiRawAdapter","OpenAiSdkAdapter","GoogleRawAdapter","GoogleSdkAdapter","OpenRouterRawAdapter","SHARED_DANGEROUS_PATTERNS","ts","resolved","createRequire","z","esbuild3"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqHA,SAAS,iBAAiB,OAAA,EAAyB;AACjD,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACtC,EAAA,OAAO,cAAc,CAAA,GAAI,OAAA,CAAQ,KAAA,CAAM,UAAA,GAAa,CAAC,CAAA,GAAI,OAAA;AAC3D;AAKO,SAAS,cAAA,CACd,WACG,WAAA,EACM;AACT,EAAA,IAAI,MAAA,CAAO,QAAQ,OAAO,IAAA;AAC1B,EAAA,IAAI,MAAA,CAAO,YAAY,OAAO,IAAA;AAC9B,EAAA,OAAO,WAAA,CAAY,KAAK,CAAC,IAAA,KAAS,CAAC,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAC,CAAA;AACvD;AApIA,IAoFsB;AApFtB,IAAA,SAAA,GAAA,KAAA,CAAA;AAAA,EAAA,sBAAA,GAAA;AAoFO,IAAe,mBAAf,MAAgC;AAAA,MAKrC,YAA+B,MAAA,EAA0B;AAA1B,QAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,MAA2B;AAAA,MAA3B,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiB/B,eAAe,cAAA,EAAgC;AAC7C,QAAA,OAAO,iBAAiB,cAAc,CAAA;AAAA,MACxC;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;AChGO,SAAS,gBAAgB,MAAA,EAA+B;AAC7D,EAAA,OAAO,CAAA,CAAE,aAAa,MAAM,CAAA;AAC9B;AAUO,SAAS,qBAAqB,IAAA,EAA8C;AACjF,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAG/C,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA,KAAU,SAAY,MAAA,GAAY,WAAA,CAAY,OAAO,GAAG,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,WAAA,CAAY,OAAgBA,KAAAA,EAAyB;AAC5D,EAAA,IACE,KAAA,KAAU,IAAA,IACV,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,SAAA,EACjB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM,WAAA,CAAY,IAAA,EAAM,CAAA,EAAGA,KAAI,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,WAAA,CAAY,KAAA,EAAO,CAAA,EAAGA,KAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA;AAAA,IAClF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,iDAAA,EAAoDA,KAAI,CAAA,GAAA,EAAM,OAAO,KAAK,CAAA,CAAA;AAAA,GAC5E;AACF;AAzDA,IAAA,gBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,6BAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;ACqBO,SAAS,aAAA,GAA6B;AAC3C,EAAA,OAAO,EAAE,cAAc,EAAA,EAAI,UAAA,EAAY,QAAW,MAAA,EAAQ,MAAA,EAAW,eAAe,MAAA,EAAU;AAChG;AAMO,SAAS,iBAAA,CACd,OAAA,EACA,QAAA,EACA,IAAA,EACM;AACN,EAAA,IAAI,QAAA,KAAa,mBAAA,IAAuB,OAAO,IAAA,CAAK,SAAS,QAAA,EAAU;AACrE,IAAA,OAAA,CAAQ,aAAa,IAAA,CAAK,IAAA;AAAA,EAC5B;AACF;AAMO,SAAS,mBAAA,CACd,OAAA,EACA,QAAA,EACA,MAAA,EACM;AACN,EAAA,IAAI,QAAA,KAAa,mBAAA,IAAuB,MAAA,CAAO,OAAA,EAAS;AAExD,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,OAAO,OAAA,CAAQ,CAAC,EAAE,IAAI,CAAA;AAChD,IAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,YAAA,EAAc;AACzC,MAAA,OAAA,CAAQ,eAAe,MAAA,CAAO,YAAA;AAAA,IAChC;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAOO,SAAS,cAAA,CAAe,SAAsB,IAAA,EAAoB;AACvE,EAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,IAAU,IAAA,CAAK,QAAA,CAAS,sBAAsB,CAAA,EAAG;AAC5D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,8DAA8D,CAAA;AACvF,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,SAAS,IAAA,CAAK,KAAA;AAAA,UACpB,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,IAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,OAAA,CAAQ,SAAS,IAAI;AAAA,SAC3E;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAAe;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,OAAA,CAAQ,aAAA,IAAiB,IAAA,CAAK,QAAA,CAAS,eAAe,CAAA,EAAG;AAC5D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,gDAAgD,CAAA;AACzE,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,CAAC,CAAA,CAAE,QAAQ,kBAAA,EAAoB,EAAE,EAAE,IAAA,EAAK;AAC/D,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,IAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AACrF,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,QAAA,IAAI,OAAO,QAAA,EAAU;AACnB,UAAA,OAAA,CAAQ,aAAA,GAAgB,EAAE,QAAA,EAAU,MAAA,CAAO,UAAU,WAAA,EAAa,MAAA,CAAO,eAAe,EAAA,EAAG;AAAA,QAC7F;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAAe;AAAA,IACzB;AAAA,EACF;AACF;AAMA,eAAsB,mBAAA,CACpB,WAAA,EACA,KAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI,WAAA,CAAY,UAAU,GAAA,EAAK;AAE/B,EAAA,MAAM,YACJ,WAAA,CAAY,KAAA,CAAM,2DAA2D,CAAA,IAC7E,WAAA,CAAY,MAAM,uBAAuB,CAAA;AAC3C,EAAA,IAAI,OAAO,SAAA,GAAY,SAAA,CAAU,CAAC,CAAA,CAAE,MAAK,GAAI,EAAA;AAE7C,EAAA,IAAI,CAAC,SAAS,WAAA,CAAY,QAAA,CAAS,gBAAgB,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI;AAChG,IAAA,IAAA,GAAO,WAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,IAAA,IAAQ,EAAE,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI;AACnF,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,UAAA,GAAa,IAAA;AACrB,EAAA,MAAM,cAAc,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,mBAAmB,CAAA;AACpE,EAAA,IAAI,CAAC,WAAA,EAAa;AAElB,EAAA,MAAM,aAAA,GAAgB,MAAM,WAAA,CAAY,OAAA,CAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,iBAAiB,CAAA;AACnF,EAAA,IAAI,cAAc,OAAA,EAAS;AACzB,IAAA,OAAA,CAAQ,IAAA,CAAK,iDAAA,EAAmD,aAAA,CAAc,OAAA,CAAQ,CAAC,GAAG,IAAA,EAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,EAC/G;AACA,EAAA,mBAAA,CAAoB,OAAA,EAAS,qBAAqB,aAAa,CAAA;AACjE;AAWA,eAAsB,iBAAA,CACpB,SACA,aAAA,EACe;AACf,EAAA,IAAI,QAAQ,YAAA,EAAc;AAG1B,EAAA,IAAI,OAAO,OAAA,CAAQ,UAAA;AAGnB,EAAA,IAAI,CAAC,IAAA,IAAQ,aAAA,IAAiB,aAAA,CAAc,SAAS,GAAA,EAAK;AACxD,IAAA,MAAM,YACJ,aAAA,CAAc,KAAA,CAAM,2DAA2D,CAAA,IAC/E,aAAA,CAAc,MAAM,uBAAuB,CAAA;AAC7C,IAAA,IAAA,GAAO,SAAA,GAAY,SAAA,CAAU,CAAC,CAAA,CAAE,MAAK,GAAI,MAAA;AAEzC,IAAA,IAAI,CAAC,SAAS,aAAA,CAAc,QAAA,CAAS,gBAAgB,CAAA,IAAK,aAAA,CAAc,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI;AACpG,MAAA,IAAA,GAAO,aAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,IAAA,IAAQ,EAAE,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI;AACnF,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAc,OAAA,CAAA,SAAA,CAAU,IAAA,EAAM;AAAA,MAC3C,MAAA,EAAQ,KAAA;AAAA,MACR,MAAA,EAAQ,QAAA;AAAA,MACR,MAAA,EAAQ,KAAA;AAAA,MACR,GAAA,EAAK,WAAA;AAAA,MACL,eAAA,EAAiB,OAAA;AAAA,MACjB,MAAA,EAAQ,IAAA;AAAA,MACR,UAAA,EAAY;AAAA,KACb,CAAA;AAED,IAAA,OAAA,CAAQ,eAAe,MAAA,CAAO,IAAA;AAC9B,IAAA,OAAA,CAAQ,UAAA,GAAa,IAAA;AACrB,IAAA,OAAA,CAAQ,KAAK,wFAAmF,CAAA;AAAA,EAClG,SAAS,GAAA,EAAK;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK,uCAAuC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACtG;AACF;AAlLA,IAAA,iBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,8BAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;ACuBO,SAAS,sBACd,MAAA,EACW;AACX,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,IAAI,SAAA,CAAU;AAAA,MACnB,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAI,SAAA,CAAU;AAAA,IACnB,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS;AAAA,GACV,CAAA;AACH;AAnCA,IAAA,WAAA,GAAA,KAAA,CAAA;AAAA,EAAA,+BAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACAA,IAAA,WAAA,GAAA,EAAA;AAAA,QAAA,CAAA,WAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAsJA,SAAS,gBAAgB,GAAA,EAAqC;AAC5D,EAAA,OAAO;AAAA,IACL,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,aAAa,GAAA,CAAI,WAAA;AAAA,IACjB,YAAA,EAAc,eAAA,CAAgB,GAAA,CAAI,WAAW;AAAA,GAC/C;AACF;AA5JA,IAiBa;AAjBb,IAAA,QAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AASA,IAAA,SAAA,EAAA;AAGA,IAAA,gBAAA,EAAA;AACA,IAAA,iBAAA,EAAA;AAEA,IAAA,WAAA,EAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,kBAAA;AAAA,MAEf,MAAA,GAA2B,IAAA;AAAA,MAEnC,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,mBAAmB,CAAA;AAAA,MACxD;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,QAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAIhB,UAAA,IAAI,IAAA,CAAK,OAAO,UAAA,EAAY;AAC1B,YAAA,IAAA,CAAK,MAAA,GAAS,sBAAsB,MAAS,CAAA;AAAA,UAC/C,CAAA,MAAO;AACL,YAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI,iBAAA;AACjD,YAAA,IAAA,CAAK,MAAA,GAAS,sBAAsB,MAAM,CAAA;AAAA,UAC5C;AAAA,QACF;AAEA,QAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,eAAe,CAAA;AACvD,QAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,QAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,QAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,QAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,QAAA,MAAM,QAAA,GAAqC;AAAA,UACzC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,OAAO,UAAA;AAAW,SAC7C;AAEA,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,MAAA,CAAO,UAAU,IAAA,EAAA,EAAQ;AACjD,UAAA,SAAA,GAAY,IAAA,GAAO,CAAA;AAEnB,UAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,SAAS,MAAA,CAAO;AAAA,YACjD,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,UAAA,EAAY,KAAA;AAAA,YACZ,QAAQ,MAAA,CAAO,YAAA;AAAA,YACf,QAAA;AAAA,YACA,KAAA,EAAO;AAAA,WACR,CAAA;AAED,UAAA,gBAAA,IAAoB,SAAS,KAAA,CAAM,YAAA;AACnC,UAAA,iBAAA,IAAqB,SAAS,KAAA,CAAM,aAAA;AAEpC,UAAA,MAAM,aAAA,GAAgB,SAAS,OAAA,CAAQ,MAAA;AAAA,YACrC,CAAC,KAAA,KAA2C,KAAA,CAAM,IAAA,KAAS;AAAA,WAC7D;AAGA,UAAA,KAAA,MAAW,KAAA,IAAS,SAAS,OAAA,EAAS;AACpC,YAAA,IAAI,MAAM,IAAA,KAAS,MAAA,EAAQ,cAAA,CAAe,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,UAC/D;AAEA,UAAA,IAAI,aAAA,CAAc,MAAA,KAAW,CAAA,IAAK,QAAA,CAAS,gBAAgB,UAAA,EAAY;AACrE,YAAA;AAAA,UACF;AAEA,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,IAAA,EAAM,WAAA;AAAA,YACN,OAAA,EAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,KAAU;AACvC,cAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,gBAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,MAAM,IAAA,EAAK;AAAA,cACnD;AACA,cAAA,OAAO;AAAA,gBACL,IAAA,EAAM,UAAA;AAAA,gBACN,IAAK,KAAA,CAAiC,EAAA;AAAA,gBACtC,MAAO,KAAA,CAAiC,IAAA;AAAA,gBACxC,OAAQ,KAAA,CAAiC;AAAA,eAC3C;AAAA,YACF,CAAC;AAAA,WACF,CAAA;AAED,UAAA,MAAM,cAAgD,EAAC;AAEvD,UAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,YAAA,MAAM,OAAA,GAAU,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,SAAA,CAAU,IAAI,CAAA;AAClE,YAAA,IAAI,CAAC,OAAA,EAAS;AACZ,cAAA,WAAA,CAAY,IAAA,CAAK;AAAA,gBACf,IAAA,EAAM,aAAA;AAAA,gBACN,aAAa,SAAA,CAAU,EAAA;AAAA,gBACvB,OAAA,EAAS,CAAA,MAAA,EAAS,SAAA,CAAU,IAAI,CAAA,WAAA,CAAA;AAAA,gBAChC,QAAA,EAAU;AAAA,eACX,CAAA;AACD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,IAAA,GAAQ,SAAA,CAAU,KAAA,IAAwB,EAAC;AACjD,YAAA,iBAAA,CAAkB,OAAA,EAAS,SAAA,CAAU,IAAA,EAAM,IAAI,CAAA;AAE/C,YAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACzC,YAAA,mBAAA,CAAoB,OAAA,EAAS,SAAA,CAAU,IAAA,EAAM,MAAM,CAAA;AAEnD,YAAA,WAAA,CAAY,IAAA,CAAK;AAAA,cACf,IAAA,EAAM,aAAA;AAAA,cACN,aAAa,SAAA,CAAU,EAAA;AAAA,cACvB,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,CAAA,CAAE,IAAA,EAAK,CAAE,CAAA;AAAA,cAC5E,UAAU,MAAA,CAAO;AAAA,aAClB,CAAA;AAAA,UACH;AAEA,UAAA,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAa,CAAA;AAAA,QACtD;AAEA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,QACjF;AAEA,QAAA,OAAO;AAAA,UACL,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,UACvB,MAAA,EAAQ;AAAA,YACN,KAAA,EAAO,gBAAA;AAAA,YACP,MAAA,EAAQ,iBAAA;AAAA,YACR,OAAO,gBAAA,GAAmB;AAAA,WAC5B;AAAA,UACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,UAC/B;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AClHO,SAAS,eAAA,GAAoC;AAClD,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,EAAA;AAAA,IACd,UAAA,EAAY,MAAA;AAAA,IACZ,MAAA,EAAQ,MAAA;AAAA,IACR,aAAA,EAAe,MAAA;AAAA,IACf,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,CAAA;AAAA,IACX,WAAA,EAAa,CAAA;AAAA,IACb,YAAA,EAAc,CAAA;AAAA,IACd,mBAAA,EAAqB,CAAA;AAAA,IACrB,eAAA,EAAiB,CAAA;AAAA,IACjB,gBAAA,EAAkB,MAAA;AAAA,IAClB,eAAe;AAAC,GAClB;AACF;AAQO,SAAS,cAAA,CACd,OAAA,EACA,SAAA,EACA,UAAA,EACA,QAAA,EACM;AACN,EAAA,gBAAA,CAAiB,SAAS,SAAS,CAAA;AACnC,EAAA,UAAA,CAAW,OAAA,EAAS,SAAA,EAAW,UAAA,EAAY,QAAQ,CAAA;AACnD,EAAA,eAAA,CAAgB,SAAS,SAAS,CAAA;AAClC,EAAA,mBAAA,CAAoB,OAAA,EAAS,WAAW,UAAU,CAAA;AAClD,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AACpC,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AACpC,EAAA,oBAAA,CAAqB,SAAS,SAAS,CAAA;AACzC;AAIA,SAAS,gBAAA,CAAiB,SAAqB,SAAA,EAAmC;AAChF,EAAA,IAAI,OAAA,CAAQ,SAAS,QAAA,EAAU;AAC/B,EAAA,MAAM,SAAA,GAAY,OAAA;AAClB,EAAA,IAAI,SAAA,CAAU,YAAY,MAAA,EAAQ;AAChC,IAAA,SAAA,CAAU,eAAe,SAAA,CAAU,UAAA;AAAA,EACrC;AACF;AAEA,SAAS,UAAA,CACP,OAAA,EACA,SAAA,EACA,UAAA,EACA,QAAA,EACM;AACN,EAAA,IAAI,OAAA,CAAQ,SAAS,WAAA,EAAa;AAClC,EAAA,MAAM,YAAA,GAAe,OAAA;AACrB,EAAA,SAAA,CAAU,SAAA,EAAA;AAEV,EAAA,MAAM,aAAA,GAAgB,aAAa,OAAA,EAAS,OAAA;AAC5C,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,aAAa,CAAA,EAAG;AAChC,IAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,MAAA,IAAI,KAAA,CAAM,SAAS,UAAA,EAAY;AAC7B,QAAA,UAAA,GAAa,EAAE,IAAA,EAAM,WAAA,EAAa,MAAM,KAAA,CAAM,IAAA,IAAQ,WAAW,CAAA;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACA,EAAA,UAAA,GAAa,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA,EAAW,QAAA,EAAU,QAAA,IAAY,CAAA,EAAG,CAAA;AACnF;AAEA,SAAS,eAAA,CAAgB,SAAqB,SAAA,EAAmC;AAC/E,EAAA,IAAI,OAAA,CAAQ,SAAS,QAAA,EAAU;AAC/B,EAAA,MAAM,SAAA,GAAY,OAAA;AAElB,EAAA,IAAI,SAAA,CAAU,YAAY,SAAA,EAAW;AACnC,IAAA,MAAM,QAAQ,SAAA,CAAU,KAAA;AACxB,IAAA,SAAA,CAAU,WAAA,GAAc,MAAM,YAAA,IAAgB,CAAA;AAC9C,IAAA,SAAA,CAAU,mBAAA,GAAsB,MAAM,2BAAA,IAA+B,CAAA;AACrE,IAAA,SAAA,CAAU,eAAA,GAAkB,MAAM,uBAAA,IAA2B,CAAA;AAC7D,IAAA,SAAA,CAAU,YAAA,GAAe,MAAM,aAAA,IAAiB,CAAA;AAChD,IAAA,SAAA,CAAU,mBAAmB,SAAA,CAAU,cAAA;AAAA,EACzC;AACF;AAEA,SAAS,mBAAA,CACP,OAAA,EACA,SAAA,EACA,UAAA,EACM;AACN,EAAA,IAAI,UAAU,YAAA,EAAc;AAE5B,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AACrC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,cAAc,CAAA,EAAG;AAGtC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,+CAA+C,CAAA;AAC1E,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,eAAe,IAAA,CAAK,KAAA,CAAM,IAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA,CAAG,CAAA;AACnD,MAAA,UAAA,GAAa,EAAE,IAAA,EAAM,UAAA,EAAY,OAAO,SAAA,CAAU,YAAA,CAAa,QAAQ,CAAA;AACvE,MAAA;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,IAAA,MAAM,OAAA,GAAU,OAAA;AAChB,IAAA,MAAM,IAAA,GAAO,uBAAuB,OAAO,CAAA;AAC3C,IAAA,IAAI,IAAA,YAAgB,YAAA,GAAe,IAAA;AAAA,EACrC;AACF;AAKA,SAAS,uBAAuB,OAAA,EAA6C;AAC3E,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,EAAS,OAAA;AACjC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,GAAG,OAAO,MAAA;AAEpC,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,IAAA,IAAI,OAAO,SAAS,QAAA,IAAY,IAAA,KAAS,QAAQ,MAAA,IAAU,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,aAAA,EAAe;AAC9F,MAAA,MAAM,cAAA,GAAiB,IAAA;AACvB,MAAA,MAAM,IAAA,GAAO,4BAAA,CAA6B,cAAA,CAAe,OAAO,CAAA;AAChE,MAAA,IAAI,MAAM,OAAO,IAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,6BAA6B,OAAA,EAAsC;AAC1E,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC1B,IAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,MAAA,MAAM,QAAA,GAAW,IAAA;AACjB,MAAA,IAAI,SAAS,IAAA,KAAS,MAAA,IAAU,SAAS,IAAA,EAAM,QAAA,CAAS,cAAc,CAAA,EAAG;AACvE,QAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,QAAA,CAAS,IAAI,CAAA;AAC/C,QAAA,IAAI,MAAM,OAAO,IAAA;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAA,EAAG;AACnE,IAAA,OAAO,qBAAqB,OAAO,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,qBAAqB,IAAA,EAAkC;AAC9D,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,IAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,YAAA,SAAqB,MAAA,CAAO,YAAA;AAAA,EAC3D,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,iBAAA,CAAkB,SAAqB,SAAA,EAAmC;AACjF,EAAA,IAAI,OAAA,CAAQ,SAAS,WAAA,EAAa;AAClC,EAAA,MAAM,YAAA,GAAe,OAAA;AAErB,EAAA,MAAM,OAAA,GAAU,aAAa,OAAA,EAAS,OAAA;AACtC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG;AAE7B,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,UAAA,IAAc,KAAA,CAAM,SAAS,OAAA,EAAS;AACvD,MAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,SAAA,CAAU,aAAa,KAAA,CAAM,OAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,mBAAmB,CAAA,EAAmB;AAC7C,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,IAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AAC3E;AAMA,SAAS,aAAA,CAAc,MAAA,EAAgB,WAAA,EAAqB,SAAA,EAAuC;AACjG,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,WAAW,GAAG,OAAO,MAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,MAAA,CAAO,GAAG,WAAW,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAE,CAAC,CAAA;AACvF,EAAA,OAAO,QAAQ,CAAC,CAAA;AAClB;AAEA,SAAS,iBAAA,CAAkB,SAAqB,SAAA,EAAmC;AACjF,EAAA,IAAI,UAAU,MAAA,EAAQ;AAEtB,EAAA,MAAM,MAAM,aAAA,CAAc,IAAA,CAAK,UAAU,OAAO,CAAA,EAAG,wBAAwB,0BAA0B,CAAA;AACrG,EAAA,IAAI,CAAC,GAAA,EAAK;AAEV,EAAA,IAAI;AACF,IAAA,SAAA,CAAU,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,kBAAA,CAAmB,GAAG,CAAC,CAAA;AAAA,EACvD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,SAAS,oBAAA,CAAqB,SAAqB,SAAA,EAAmC;AACpF,EAAA,IAAI,UAAU,aAAA,EAAe;AAE7B,EAAA,MAAM,MAAM,aAAA,CAAc,IAAA,CAAK,UAAU,OAAO,CAAA,EAAG,iBAAiB,mBAAmB,CAAA;AACvF,EAAA,IAAI,CAAC,GAAA,EAAK;AAEV,EAAA,IAAI;AACF,IAAA,MAAM,WAAW,GAAA,CAAI,OAAA,CAAQ,kBAAA,EAAoB,EAAE,EAAE,IAAA,EAAK;AAC1D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,kBAAA,CAAmB,QAAQ,CAAC,CAAA;AACtD,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,SAAA,CAAU,aAAA,GAAgB;AAAA,QACxB,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,WAAA,EAAa,OAAO,WAAA,IAAe;AAAA,OACrC;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAhQA,IAAA,mBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,uCAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC0BA,eAAsB,oBACpB,KAAA,EAIC;AACD,EAAA,MAAM,EAAE,IAAA,EAAM,kBAAA,EAAmB,GAAI,MAAM,OAAO,gCAAgC,CAAA;AAElF,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,GAAA,CAAI,CAAC,GAAA,KAAQ;AAElC,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,CAAY,KAAA,IAAS,EAAC;AAExC,IAAA,OAAO,IAAA;AAAA,MACL,GAAA,CAAI,IAAA;AAAA,MACJ,GAAA,CAAI,WAAA;AAAA,MACJ,KAAA;AAAA,MACA,OAAO,IAAA,KAAqB;AAC1B,QAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AACrC,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,YAClC,IAAA,EAAM,MAAA;AAAA,YACN,MAAM,CAAA,CAAE;AAAA,WACV,CAAE,CAAA;AAAA,UACF,GAAI,MAAA,CAAO,OAAA,IAAW,EAAE,SAAS,IAAA;AAAK,SACxC;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,SAAS,kBAAA,CAAmB;AAAA,IAChC,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS,OAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,QAAQ,eAAe,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAE9E,EAAA,OAAO,EAAE,QAAQ,gBAAA,EAAiB;AACpC;AAhEA,IAiBa,eAAA;AAjBb,IAAAC,iBAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,oCAAA,GAAA;AAiBO,IAAM,eAAA,GAAkB,MAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACjB/B,IAAA,WAAA,GAAA,EAAA;AAAA,QAAA,CAAA,WAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAqIA,SAAS,SAAS,SAAA,EAA4D;AAC5E,EAAA,IAAI,WAAW,OAAO,WAAA,CAAY,EAAE,GAAG,WAAW,CAAA;AAElD,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtD,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA;AAAA,EACtC;AACA,EAAA,OAAO,YAAY,GAAG,CAAA;AACxB;AAMA,SAAS,YAAY,GAAA,EAAqD;AAGxE,EAAA,IAAI,GAAA,CAAI,kBAAA,EAAoB,QAAA,CAAS,WAAW,CAAA,EAAG;AACjD,IAAA,OAAO,GAAA,CAAI,kBAAA;AAAA,EACb;AACA,EAAA,OAAO,GAAA;AACT;AA1JA,IAgBa;AAhBb,IAAA,QAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAUA,IAAA,SAAA,EAAA;AAGA,IAAA,mBAAA,EAAA;AACA,IAAAA,iBAAAA,EAAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,oBAAA;AAAA,MAEvB,WAAA,CAAY,MAAA,GAA0B,EAAC,EAAG;AACxC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA;AAAA,MAGA,IAAY,SAAA,GAA6B;AACvC,QAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,mBAAmB,CAAA;AAAA,MACxD;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,QAAA,MAAM,MAAM,IAAA,CAAK,SAAA;AAGjB,QAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,OAAO,gCAAgC,CAAA;AAG/D,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAE5B,QAAA,MAAM,YAAY,eAAA,EAAgB;AAClC,QAAA,MAAM,aAAa,GAAA,CAAI,UAAA;AAGvB,QAAA,IAAI,aAA0D,GAAA,CAAI,UAAA;AAClE,QAAA,IAAI,eAAqC,GAAA,CAAI,YAAA;AAE7C,QAAA,IAAI,CAAC,UAAA,IAAc,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AAE1C,UAAA,MAAM,MAAA,GAAS,MAAM,mBAAA,CAAoB,MAAA,CAAO,KAAK,CAAA;AACrD,UAAA,UAAA,GAAa,EAAE,IAAA,EAAM,MAAA,CAAO,MAAA,EAAO;AACnC,UAAA,YAAA,GAAe,MAAA,CAAO,gBAAA;AAAA,QACxB;AAGA,QAAA,WAAA,MAAiB,WAAW,KAAA,CAAM;AAAA,UAChC,QAAQ,MAAA,CAAO,UAAA;AAAA,UACf,OAAA,EAAS;AAAA,YACP,KAAK,GAAA,CAAI,GAAA;AAAA,YACT,GAAA;AAAA,YACA,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,cAAc,MAAA,CAAO,YAAA;AAAA,YACrB,GAAI,UAAA,IAAc,EAAE,UAAA,EAAW;AAAA,YAC/B,GAAI,GAAA,CAAI,MAAA,IAAU,EAAE,MAAA,EAAQ,IAAI,MAAA,EAAO;AAAA,YACvC,GAAI,YAAA,IAAgB,EAAE,YAAA,EAAa;AAAA,YACnC,cAAA,EAAgB,mBAAA;AAAA,YAChB,+BAAA,EAAiC,IAAA;AAAA,YACjC,GAAI,GAAA,CAAI,OAAA,IAAW,EAAE,0BAAA,EAA4B,IAAI,OAAA,EAAQ;AAAA,YAC7D,GAAI,GAAA,CAAI,MAAA,IAAU,EAAE,MAAA,EAAQ,IAAI,MAAA;AAAO;AACzC,SACD,CAAA,EAAG;AACF,UAAA,cAAA;AAAA,YACE,OAAA;AAAA,YACA,SAAA;AAAA,YACA,UAAA;AAAA,YACA,MAAA,CAAO;AAAA,WACT;AAAA,QACF;AAEA,QAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAOtC,QAAA,MAAM,YAAA,GAAe,SAAA,CAAU,WAAA,GAAc,SAAA,CAAU,sBAAsB,SAAA,CAAU,eAAA;AACvF,QAAA,MAAM,YAAA,GAAe,eAAe,CAAA,GAChC,IAAA,CAAK,MAAO,SAAA,CAAU,eAAA,GAAkB,YAAA,GAAgB,GAAG,CAAA,GAC3D,CAAA;AACJ,QAAA,OAAA,CAAQ,GAAA;AAAA,UACN,+BAA+B,SAAA,CAAU,mBAAmB,CAAA,MAAA,EAAS,SAAA,CAAU,eAAe,CAAA,OAAA,EAAU,SAAA,CAAU,WAAW,CAAA,QAAA,EAAW,UAAU,YAAY,CAAA,OAAA,EAAU,SAAA,CAAU,SAAS,mBAAmB,YAAY,CAAA,CAAA;AAAA,SAC5N;AAEA,QAAA,IAAI,CAAC,UAAU,YAAA,EAAc;AAC3B,UAAA,MAAM,YAAA,GAAe,SAAA,CAAU,SAAA,IAAa,MAAA,CAAO,QAAA;AACnD,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,YAAA,GACI,CAAA,oBAAA,EAAuB,MAAA,CAAO,QAAQ,CAAA,uCAAA,CAAA,GACtC;AAAA,WACN;AAAA,QACF;AAEA,QAAA,OAAO;AAAA,UACL,cAAc,SAAA,CAAU,YAAA;AAAA,UACxB,YAAY,SAAA,CAAU,UAAA;AAAA,UACtB,MAAA,EAAQ;AAAA,YACN,OAAO,SAAA,CAAU,WAAA;AAAA,YACjB,QAAQ,SAAA,CAAU,YAAA;AAAA,YAClB,OACE,SAAA,CAAU,WAAA,GACV,UAAU,mBAAA,GACV,SAAA,CAAU,kBACV,SAAA,CAAU;AAAA,WACd;AAAA,UACA,gBAAA;AAAA,UACA,WAAW,SAAA,CAAU,SAAA;AAAA,UACrB,YAAY,SAAA,CAAU,gBAAA;AAAA,UACtB,QAAQ,SAAA,CAAU,MAAA;AAAA,UAClB,eAAe,SAAA,CAAU,aAAA;AAAA,UACzB,eAAe,SAAA,CAAU,aAAA;AAAA,UACzB,qBAAqB,SAAA,CAAU,mBAAA;AAAA,UAC/B,iBAAiB,SAAA,CAAU,eAAA;AAAA,UAC3B,cAAc,SAAA,CAAU;AAAA,SAC1B;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACnIA,IAAAC,YAAAA,GAAA,EAAA;AAAA,QAAA,CAAAA,YAAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAuBA,eAAe,UAAA,GAA+C;AAC5D,EAAA,OAAO,OAAO,QAAQ,CAAA;AACxB;AAmJA,SAAS,gBAAgB,GAAA,EAAuH;AAC9I,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,aAAa,GAAA,CAAI,WAAA;AAAA,IACjB,UAAA,EAAY,eAAA,CAAgB,GAAA,CAAI,WAAW,CAAA;AAAA,IAC3C,MAAA,EAAQ;AAAA,GACV;AACF;AApLA,IA2Ba;AA3Bb,IAAAC,SAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAQA,IAAA,SAAA,EAAA;AAGA,IAAA,gBAAA,EAAA;AACA,IAAA,iBAAA,EAAA;AAeO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,kBAAA;AAAA,MAEf,MAAA,GAAwB,IAAA;AAAA,MAEhC,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,gBAAgB,CAAA;AAAA,MACrD;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,QAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,UAAA,MAAM,EAAE,OAAA,EAAS,YAAA,EAAa,GAAI,MAAM,UAAA,EAAW;AACnD,UAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa;AAAA,YAC7B,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI;AAAA,WAC3C,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,eAAe,CAAA;AAC9C,QAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,QAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,QAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,QAAA,IAAI,SAAA,GAAY,CAAA;AAChB,QAAA,IAAI,aAAA,GAAgB,EAAA;AAGpB,QAAA,IAAI,QAAA,GAA+B,MAAM,IAAA,CAAK,MAAA,CAAO,UAAU,MAAA,CAAO;AAAA,UACpE,OAAO,MAAA,CAAO,KAAA;AAAA,UACd,cAAc,MAAA,CAAO,YAAA;AAAA,UACrB,KAAA,EAAO,CAAC,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,MAAA,CAAO,YAAY,CAAA;AAAA,UACpD,KAAA;AAAA,UACA,KAAA,EAAO;AAAA;AAAA,SACR,CAAA;AAGD,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,MAAA,CAAO,UAAU,IAAA,EAAA,EAAQ;AACjD,UAAA,SAAA,GAAY,IAAA,GAAO,CAAA;AAGnB,UAAA,IAAI,SAAS,KAAA,EAAO;AAClB,YAAA,gBAAA,IAAoB,QAAA,CAAS,MAAM,YAAA,IAAgB,CAAA;AACnD,YAAA,iBAAA,IAAqB,QAAA,CAAS,MAAM,aAAA,IAAiB,CAAA;AAAA,UACvD;AAGA,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,MAAA,IAAU,EAAC;AACnC,UAAA,MAAM,gBAAgB,MAAA,CAAO,MAAA;AAAA,YAC3B,CAAC,IAAA,KAAqD,IAAA,CAAK,IAAA,KAAS;AAAA,WACtE;AAGA,UAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,YAAA,IAAI,KAAK,IAAA,KAAS,SAAA,IAAa,SAAA,IAAa,IAAA,IAAQ,KAAK,OAAA,EAAS;AAChE,cAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,OAAA,EAAS;AAC/B,gBAAA,IAAI,IAAA,CAAK,IAAA,KAAS,aAAA,IAAiB,IAAA,CAAK,IAAA,EAAM;AAC5C,kBAAA,aAAA,IAAiB,KAAK,IAAA,GAAO,IAAA;AAC7B,kBAAA,cAAA,CAAe,OAAA,EAAS,KAAK,IAAI,CAAA;AAAA,gBACnC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,UAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAGhC,UAAA,MAAM,YAA8D,EAAC;AAErE,UAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,YAAA,MAAM,OAAA,GAAU,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,EAAA,CAAG,IAAI,CAAA;AAC3D,YAAA,IAAI,CAAC,OAAA,EAAS;AACZ,cAAA,SAAA,CAAU,IAAA,CAAK;AAAA,gBACb,IAAA,EAAM,sBAAA;AAAA,gBACN,SAAS,EAAA,CAAG,OAAA;AAAA,gBACZ,MAAA,EAAQ,KAAK,SAAA,CAAU,EAAE,OAAO,CAAA,MAAA,EAAS,EAAA,CAAG,IAAI,CAAA,WAAA,CAAA,EAAe;AAAA,eAChE,CAAA;AACD,cAAA;AAAA,YACF;AAEA,YAAA,IAAI,OAAmB,EAAC;AACxB,YAAA,IAAI;AAAE,cAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,SAAA,IAAa,IAAI,CAAA;AAAA,YAAiB,CAAA,CAAA,MAAQ;AAAA,YAAc;AAEnF,YAAA,iBAAA,CAAkB,OAAA,EAAS,EAAA,CAAG,IAAA,EAAM,IAAI,CAAA;AAExC,YAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACzC,YAAA,mBAAA,CAAoB,OAAA,EAAS,EAAA,CAAG,IAAA,EAAM,MAAM,CAAA;AAE5C,YAAA,SAAA,CAAU,IAAA,CAAK;AAAA,cACb,IAAA,EAAM,sBAAA;AAAA,cACN,SAAS,EAAA,CAAG,OAAA;AAAA,cACZ,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,CAAC,GAAG,IAAA,IAAQ;AAAA,aACpC,CAAA;AAAA,UACH;AAGA,UAAA,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,MAAA,CAAO;AAAA,YAC5C,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,cAAc,MAAA,CAAO,YAAA;AAAA,YACrB,KAAA,EAAO,SAAA;AAAA,YACP,KAAA;AAAA,YACA,sBAAsB,QAAA,CAAS,EAAA;AAAA,YAC/B,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,QACH;AAGA,QAAA,IAAI,CAAC,OAAA,CAAQ,YAAA,IAAgB,aAAA,EAAe;AAC1C,UAAA,cAAA,CAAe,SAAS,aAAa,CAAA;AACrC,UAAA,MAAM,mBAAA,CAAoB,aAAA,EAAe,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA;AAAA,QAChE;AAGA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,iBAAA,CAAkB,SAAS,aAAa,CAAA;AAAA,QAChD;AAEA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,QACjF;AAEA,QAAA,OAAO;AAAA,UACL,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,UACvB,MAAA,EAAQ;AAAA,YACN,KAAA,EAAO,gBAAA;AAAA,YACP,MAAA,EAAQ,iBAAA;AAAA,YACR,OAAO,gBAAA,GAAmB;AAAA,WAC5B;AAAA,UACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,UAC/B;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACvKA,IAAAC,YAAAA,GAAA,EAAA;AAAA,QAAA,CAAAA,YAAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAiBA,eAAe,gBAAA,GAAmB;AAChC,EAAA,OAAO,OAAO,gBAAgB,CAAA;AAChC;AAnBA,IAqBa;AArBb,IAAAC,SAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAKA,IAAA,SAAA,EAAA;AAGA,IAAA,iBAAA,EAAA;AAaO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,qBAAA;AAAA,MAEvB,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,gBAAgB,CAAA;AAAA,MACrD;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI,cAAA;AACjD,QAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,cAAA,GAAiB,MAAA;AAEzC,QAAA,MAAM,UAAU,aAAA,EAAc;AAG9B,QAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAK,IAAA,EAAK,GAAI,MAAM,gBAAA,EAAiB;AAEpD,QAAA,MAAM,UAAA,GAAa,OAAO,KAAA,CAAM,GAAA;AAAA,UAAI,CAAC,QACnC,IAAA,CAAK;AAAA,YACH,MAAM,GAAA,CAAI,IAAA;AAAA,YACV,aAAa,GAAA,CAAI,WAAA;AAAA,YACjB,YAAY,GAAA,CAAI,WAAA;AAAA,YAChB,OAAA,EAAS,OAAO,IAAA,KAAS;AACvB,cAAA,MAAM,SAAA,GAAa,QAAQ,EAAC;AAC5B,cAAA,iBAAA,CAAkB,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,SAAS,CAAA;AAE9C,cAAA,MAAMC,OAAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AAC1C,cAAA,mBAAA,CAAoB,OAAA,EAAS,GAAA,CAAI,IAAA,EAAMA,OAAM,CAAA;AAE7C,cAAA,OAAOA,OAAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,IAAA,IAAQ,EAAA;AAAA,YACpC;AAAA,WACD;AAAA,SACH;AAEA,QAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM;AAAA,UACtB,IAAA,EAAM,cAAA;AAAA,UACN,cAAc,MAAA,CAAO,YAAA;AAAA,UACrB,OAAO,MAAA,CAAO,KAAA;AAAA,UACd,KAAA,EAAO;AAAA,SACR,CAAA;AAED,QAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,KAAA,EAAO,OAAO,UAAA,EAAY;AAAA,UACjD,UAAU,MAAA,CAAO;AAAA,SAClB,CAAA;AAED,QAAA,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,WAAA,IAAe,EAAE,CAAA;AAGnD,QAAA,IAAI,WAAA,EAAa,cAAA,CAAe,OAAA,EAAS,WAAW,CAAA;AAGpD,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,mBAAA,CAAoB,WAAA,EAAa,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA;AAE5D,UAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,YAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,UACjF;AAAA,QACF;AACA,QAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,CAAM,KAAA;AAC3B,QAAA,MAAM,cAAc,KAAA,CAAM,WAAA;AAC1B,QAAA,MAAM,eAAe,KAAA,CAAM,YAAA;AAE3B,QAAA,OAAO;AAAA,UACL,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,UACvB,MAAA,EAAQ;AAAA,YACN,KAAA,EAAO,WAAA;AAAA,YACP,MAAA,EAAQ,YAAA;AAAA,YACR,OAAO,WAAA,GAAc;AAAA,WACvB;AAAA,UACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,UAC/B,SAAA,EAAW,MAAA,CAAO,YAAA,EAAc,MAAA,IAAU;AAAA,SAC5C;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACxGA,IAAAJ,YAAAA,GAAA,EAAA;AAAA,QAAA,CAAAA,YAAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAeA,eAAe,eAAA,GAAkB;AAC/B,EAAA,OAAO,OAAO,eAAe,CAAA;AAC/B;AAiJA,SAAS,kBAAkB,GAAA,EAA4C;AACrE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,aAAa,GAAA,CAAI,WAAA;AAAA,IACjB,UAAA,EAAY,eAAA,CAAgB,GAAA,CAAI,WAAW;AAAA,GAC7C;AACF;AAzKA,IAmBa;AAnBb,IAAAC,SAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AASA,IAAA,SAAA,EAAA;AAGA,IAAA,gBAAA,EAAA;AACA,IAAA,iBAAA,EAAA;AAMO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,kCAAA;AAAA,MAEf,MAAA,GAAiC,IAAA;AAAA,MAEzC,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,MACvE;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,QAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,UAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,eAAA,EAAgB;AAC9C,UAAA,IAAA,CAAK,MAAA,GAAS,IAAI,WAAA,CAAY;AAAA,YAC5B,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI,cAAA,IAAkB,QAAQ,GAAA,CAAI,cAAA;AAAA,YACxE,WAAA,EAAa,EAAE,OAAA,EAAS,GAAA;AAAQ;AAAA,WACjC,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,iBAAiB,CAAA;AAChD,QAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,QAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,QAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,QAAA,IAAI,SAAA,GAAY,CAAA;AAShB,QAAA,MAAM,aAAA,GAAgB,KAAK,MAAA,CAAO,aAAA;AAClC,QAAA,MAAM,gBAAA,GAAmB,aAAA,GACrB,EAAE,cAAA,EAAgB,eAAc,GAChC,MAAA;AAGJ,QAAA,IAAI,WAAA,GAAc,MAAM,IAAA,CAAK,MAAA,CAAO,aAAa,MAAA,CAAO;AAAA,UACtD,OAAO,MAAA,CAAO,KAAA;AAAA,UACd,oBAAoB,MAAA,CAAO,YAAA;AAAA,UAC3B,KAAA;AAAA,UACA,OAAO,MAAA,CAAO,UAAA;AAAA,UACd,GAAI,gBAAA,GAAmB,EAAE,iBAAA,EAAmB,gBAAA,KAAqB;AAAC,SACnE,CAAA;AAED,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,MAAA,CAAO,UAAU,IAAA,EAAA,EAAQ;AACjD,UAAA,SAAA,GAAY,IAAA,GAAO,CAAA;AAGnB,UAAA,IAAI,YAAY,KAAA,EAAO;AACrB,YAAA,gBAAA,IAAoB,WAAA,CAAY,MAAM,kBAAA,IAAsB,CAAA;AAC5D,YAAA,iBAAA,IAAqB,WAAA,CAAY,MAAM,mBAAA,IAAuB,CAAA;AAAA,UAChE;AAMA,UAAA,KAAA,MAAW,IAAA,IAAQ,YAAY,KAAA,EAAO;AACpC,YAAA,IAAI,IAAA,CAAK,SAAS,cAAA,EAAgB;AAChC,cAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,OAAA,IAAW,EAAC,EAAG;AACxC,gBAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,kBAAA,cAAA,CAAe,OAAA,EAAS,QAAQ,IAAI,CAAA;AAAA,gBACtC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,UAAA,MAAM,aAAA,GAAgB,YAAY,KAAA,CAAM,MAAA;AAAA,YACtC,CAAC,CAAA,KAA0C,CAAA,CAAE,IAAA,KAAS;AAAA,WACxD;AAEA,UAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAGhC,UAAA,MAAM,UAA6C,EAAC;AAEpD,UAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,YAAA,MAAM,OAAA,GAAU,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,EAAA,CAAG,IAAI,CAAA;AAC3D,YAAA,IAAI,CAAC,OAAA,EAAS;AACZ,cAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,gBACX,IAAA,EAAM,iBAAA;AAAA,gBACN,SAAS,EAAA,CAAG,EAAA;AAAA,gBACZ,MAAM,EAAA,CAAG,IAAA;AAAA,gBACT,MAAA,EAAQ,KAAK,SAAA,CAAU,EAAE,OAAO,CAAA,MAAA,EAAS,EAAA,CAAG,IAAI,CAAA,WAAA,CAAA,EAAe,CAAA;AAAA,gBAC/D,QAAA,EAAU;AAAA,eACX,CAAA;AACD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,EAAA,CAAG,SAAS,CAAA;AAC9C,YAAA,iBAAA,CAAkB,OAAA,EAAS,EAAA,CAAG,IAAA,EAAM,IAAI,CAAA;AAExC,YAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACzC,YAAA,mBAAA,CAAoB,OAAA,EAAS,EAAA,CAAG,IAAA,EAAM,MAAM,CAAA;AAE5C,YAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,cACX,IAAA,EAAM,iBAAA;AAAA,cACN,SAAS,EAAA,CAAG,EAAA;AAAA,cACZ,MAAM,EAAA,CAAG,IAAA;AAAA,cACT,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,CAAC,GAAG,IAAA,IAAQ;AAAA,aACpC,CAAA;AAAA,UACH;AAGA,UAAA,WAAA,GAAc,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,MAAA,CAAO;AAAA,YAClD,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,yBAAyB,WAAA,CAAY,EAAA;AAAA,YACrC,KAAA,EAAO,OAAA;AAAA,YACP,GAAI,gBAAA,GAAmB,EAAE,iBAAA,EAAmB,gBAAA,KAAqB;AAAC,WACnE,CAAA;AAAA,QACH;AAEA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,QACjF;AAEA,QAAA,OAAO;AAAA,UACL,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,UACvB,MAAA,EAAQ;AAAA,YACN,KAAA,EAAO,gBAAA;AAAA,YACP,MAAA,EAAQ,iBAAA;AAAA,YACR,OAAO,gBAAA,GAAmB;AAAA,WAC5B;AAAA,UACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,UAC/B;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC/JA,IAAAC,YAAAA,GAAA,EAAA;AAAA,QAAA,CAAAA,YAAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,UAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AA2DA,eAAsB,WACpB,MAAA,EACwB;AACxB,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,EAAA,MAAM,EAAE,cAAc,QAAA,EAAU,cAAA,EAAgB,iBAAgB,GAAI,MAAM,OAAO,aAAa,CAAA;AAE9F,EAAA,MAAM,UAAU,aAAA,EAAc;AAG9B,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,CAAC,OAAA,CAAQ,IAAI,oBAAA,EAAsB;AACtD,IAAA,OAAA,CAAQ,GAAA,CAAI,uBAAuB,MAAA,CAAO,MAAA;AAAA,EAC5C;AAGA,EAAA,MAAM,QAAA,GAAW,OAAO,KAAA,CAAM,GAAA;AAAA,IAAI,CAAC,GAAA,KACjC,IAAI,YAAA,CAAa;AAAA,MACf,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,aAAa,GAAA,CAAI,WAAA;AAAA;AAAA,MAEjB,YAAY,GAAA,CAAI,WAAA;AAAA,MAChB,OAAA,EAAS,OAAO,IAAA,KAAkB;AAChC,QAAA,MAAM,SAAA,GAAa,QAAQ,EAAC;AAC5B,QAAA,iBAAA,CAAkB,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,SAAS,CAAA;AAC9C,QAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AAC1C,QAAA,mBAAA,CAAoB,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,MAAM,CAAA;AAC7C,QAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,IAAA,IAAQ,EAAA;AAAA,MACpC;AAAA,KACD;AAAA,GACH;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAI,QAAA,CAAS;AAAA,IACzB,IAAA,EAAM,cAAA;AAAA,IACN,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,aAAa,MAAA,CAAO,YAAA;AAAA,IACpB,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,MAAM,SAAS,IAAI,cAAA,CAAe,EAAE,KAAA,EAAO,OAAA,EAAS,kBAAkB,CAAA;AACtE,EAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,cAAA,CAAe,aAAA,CAAc;AAAA,IACxD,OAAA,EAAS,gBAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,MAAM,WAAA,GAAuB;AAAA,IAC3B,IAAA,EAAM,MAAA;AAAA,IACN,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,CAAO,YAAY;AAAA,GACrC;AAEA,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,EAAA,IAAI,iBAAA,GAAoB,CAAA;AAExB,EAAA,WAAA,MAAiB,KAAA,IAAS,OAAO,QAAA,CAAS;AAAA,IACxC,MAAA,EAAQ,WAAA;AAAA,IACR,WAAW,OAAA,CAAQ,EAAA;AAAA,IACnB,UAAA,EAAY;AAAA,GACb,CAAA,EAAG;AACF,IAAA,SAAA,EAAA;AAGA,IAAA,MAAM,QAAQ,KAAA,CAAM,aAAA;AACpB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,gBAAA,IAAoB,MAAM,gBAAA,IAAoB,CAAA;AAC9C,MAAA,iBAAA,IAAqB,MAAM,oBAAA,IAAwB,CAAA;AAAA,IACrD;AAGA,IAAA,IAAI,KAAA,CAAM,SAAS,KAAA,EAAO;AACxB,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAY,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AACvE,MAAA,IAAI,IAAA,EAAM,cAAA,CAAe,OAAA,EAAS,IAAI,CAAA;AAAA,IACxC;AAEA,IAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC1B,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,EAAS,KAAA;AAC7B,MAAA,SAAA,GAAY,KAAA,EAAO,GAAA,CAAI,CAAC,CAAA,KAAY,CAAA,CAAE,QAAQ,EAAE,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,IAAK,EAAA;AAAA,IAChE;AAAA,EACF;AAGA,EAAA,IAAI,SAAA,EAAW,cAAA,CAAe,OAAA,EAAS,SAAS,CAAA;AAEhD,EAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAEA,EAAA,OAAO;AAAA,IACL,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,IACvB,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,gBAAA;AAAA,MACP,MAAA,EAAQ,iBAAA;AAAA,MACR,OAAO,gBAAA,GAAmB;AAAA,KAC5B;AAAA,IACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,IAC/B,SAAA,EAAW;AAAA,GACb;AACF;AA/JA,IAaa;AAbb,IAAAC,SAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAKA,IAAA,SAAA,EAAA;AAGA,IAAA,iBAAA,EAAA;AAKO,IAAM,gBAAA,GAAN,cAA+B,gBAAA,CAAiB;AAAA,MAC5C,QAAA,GAAyB,QAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,qBAAA;AAAA,MAEvB,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,MACvE;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,MAAA,GAAS,KAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI,cAAA,IAAkB,QAAQ,GAAA,CAAI,cAAA;AAE/E,QAAA,OAAO,UAAA,CAAW;AAAA,UAChB,cAAc,MAAA,CAAO,YAAA;AAAA,UACrB,YAAY,MAAA,CAAO,UAAA;AAAA,UACnB,OAAO,MAAA,CAAO,KAAA;AAAA,UACd,OAAO,MAAA,CAAO,KAAA;AAAA,UACd;AAAA,SACD,CAAA;AAAA,MACH;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACrCA,IA4Ha,eAAA;AA5Hb,IAAA,UAAA,GAAA,KAAA,CAAA;AAAA,EAAA,kCAAA,GAAA;AA4HO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,MACzC,WAAA,CACE,OAAA,EACgB,MAAA,EACA,IAAA,EAChB;AACA,QAAA,KAAA,CAAM,OAAO,CAAA;AAHG,QAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,QAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAGhB,QAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,MACd;AAAA,MALkB,MAAA;AAAA,MACA,IAAA;AAAA,MAMlB,IAAI,WAAA,GAAuB;AACzB,QAAA,OAAO,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,IAAA,CAAK,MAAA,KAAW,OACzC,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,IAAA,CAAK,MAAA,KAAW,GAAA;AAAA,MAC9C;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC1IA,IAmBM,gBAAA,EAEO,gBAAA;AArBb,IAAAE,YAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,mCAAA,GAAA;AAUA,IAAA,UAAA,EAAA;AASA,IAAM,gBAAA,GAAmB,8BAAA;AAElB,IAAM,mBAAN,MAAuB;AAAA,MAI5B,YAA6B,MAAA,EAAgC;AAAhC,QAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAC3B,QAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,IAAW,OAAA,CAAQ,IAAI,mBAAA,IAAuB,gBAAA;AACpE,QAAA,IAAA,CAAK,OAAA,GAAU;AAAA,UACb,eAAA,EAAiB,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,UACxC,cAAA,EAAgB,kBAAA;AAAA,UAChB,cAAA,EAAgB,MAAA,CAAO,OAAA,IAAW,OAAA,CAAQ,IAAI,mBAAA,IAAuB,iBAAA;AAAA,UACrE,SAAA,EAAW,MAAA,CAAO,QAAA,IAAY,OAAA,CAAQ,IAAI,oBAAA,IAAwB;AAAA,SACpE;AAAA,MACF;AAAA,MAR6B,MAAA;AAAA,MAHZ,OAAA;AAAA,MACA,OAAA;AAAA;AAAA;AAAA;AAAA,MAejB,MAAM,eACJ,MAAA,EACiC;AACjC,QAAA,MAAM,IAAA,GAA8B,EAAE,GAAG,MAAA,EAAQ,QAAQ,KAAA,EAAM;AAC/D,QAAA,MAAM,WAAW,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,iBAAA,CAAA,EAAqB;AAAA,UAC/D,MAAA,EAAQ,MAAA;AAAA,UACR,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,SAC1B,CAAA;AAED,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,CAAS,UAAA,IAAa,CAAE,CAAA;AACjG,UAAA,MAAM,OAAA,GAAW,SAAA,CAA+C,KAAA,EAAO,OAAA,IAAW,QAAA,CAAS,UAAA;AAC3F,UAAA,MAAM,IAAI,eAAA,CAAgB,OAAA,EAAS,QAAA,CAAS,MAAM,CAAA;AAAA,QACpD;AAEA,QAAA,OAAO,SAAS,IAAA,EAAK;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO,qBACL,MAAA,EACuC;AACvC,QAAA,MAAM,IAAA,GAA8B,EAAE,GAAG,MAAA,EAAQ,QAAQ,IAAA,EAAK;AAC9D,QAAA,MAAM,WAAW,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,iBAAA,CAAA,EAAqB;AAAA,UAC/D,MAAA,EAAQ,MAAA;AAAA,UACR,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,SAC1B,CAAA;AAED,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,CAAS,UAAA,IAAa,CAAE,CAAA;AACjG,UAAA,MAAM,OAAA,GAAW,SAAA,CAA+C,KAAA,EAAO,OAAA,IAAW,QAAA,CAAS,UAAA;AAC3F,UAAA,MAAM,IAAI,eAAA,CAAgB,OAAA,EAAS,QAAA,CAAS,MAAM,CAAA;AAAA,QACpD;AAEA,QAAA,IAAI,CAAC,SAAS,IAAA,EAAM;AAClB,UAAA,MAAM,IAAI,eAAA,CAAgB,wCAAA,EAA0C,GAAG,CAAA;AAAA,QACzE;AAEA,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,CAAK,SAAA,EAAU;AACvC,QAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,QAAA,IAAI,MAAA,GAAS,EAAA;AAEb,QAAA,IAAI;AACF,UAAA,OAAO,IAAA,EAAM;AACX,YAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,YAAA,IAAI,IAAA,EAAM;AAEV,YAAA,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAChD,YAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,YAAA,MAAA,GAAS,KAAA,CAAM,KAAI,IAAK,EAAA;AAExB,YAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,cAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,cAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AACzC,cAAA,IAAI,YAAY,cAAA,EAAgB;AAChC,cAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,QAAQ,CAAA,EAAG;AAEnC,cAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA;AAC1C,cAAA,IAAI;AACF,gBAAA,MAAM,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,cACvB,CAAA,CAAA,MAAQ;AAAA,cAER;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAA,SAAE;AACA,UAAA,MAAA,CAAO,WAAA,EAAY;AAAA,QACrB;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AChHA,IAAAL,YAAAA,GAAA,EAAA;AAAA,QAAA,CAAAA,YAAAA,EAAA;AAAA,EAAA,oBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAiLA,SAAS,iBAAiB,GAAA,EAAqC;AAC7D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,UAAA,EAAY,eAAA,CAAgB,GAAA,CAAI,WAAW;AAAA;AAC7C,GACF;AACF;AA1LA,IAsBa,oBAAA;AAtBb,IAAAC,SAAAA,GAAA,KAAA,CAAA;AAAA,EAAA,gCAAA,GAAA;AAMA,IAAA,SAAA,EAAA;AAGA,IAAA,gBAAA,EAAA;AACA,IAAA,iBAAA,EAAA;AASA,IAAAI,YAAAA,EAAAA;AAGO,IAAM,oBAAA,GAAN,cAAmC,gBAAA,CAAiB;AAAA,MAChD,QAAA,GAAyB,YAAA;AAAA,MACzB,IAAA,GAAoB,KAAA;AAAA,MACpB,WAAA,GAAc,sBAAA;AAAA,MAEf,MAAA,GAAkC,IAAA;AAAA,MAE1C,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,QAAA,KAAA,CAAM,MAAM,CAAA;AAAA,MACd;AAAA,MAEA,WAAA,GAAuB;AACrB,QAAA,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,oBAAoB,CAAA;AAAA,MACzD;AAAA,MAEA,MAAM,SAAS,MAAA,EAAgD;AAC7D,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,QAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,UAAA,IAAA,CAAK,MAAA,GAAS,IAAI,gBAAA,CAAiB;AAAA,YACjC,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,QAAQ,GAAA,CAAI;AAAA,WAC3C,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,gBAAgB,CAAA;AAC/C,QAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,QAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,QAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,QAAA,IAAI,mBAAA;AACJ,QAAA,IAAI,eAAA;AACJ,QAAA,IAAI,SAAA,GAAY,CAAA;AAChB,QAAA,IAAI,aAAA,GAAgB,EAAA;AAGpB,QAAA,MAAM,UAAU,MAAA,CAAO,KAAA;AACvB,QAAA,MAAM,mBAAmB,OAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,IAAK,OAAA,CAAQ,SAAS,QAAQ,CAAA;AAGpF,QAAA,MAAM,gBAAmC,gBAAA,GACrC;AAAA,UACE,IAAA,EAAM,QAAA;AAAA,UACN,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,MAAA,CAAO,YAAA,EAAc,aAAA,EAAe,EAAE,IAAA,EAAM,WAAA,IAAe;AAAA,YAE7F,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,OAAO,YAAA,EAAa;AAEnD,QAAA,MAAM,QAAA,GAAgC;AAAA,UACpC,aAAA;AAAA,UACA,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,OAAO,UAAA;AAAW,SAC7C;AAGA,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,MAAA,CAAO,UAAU,IAAA,EAAA,EAAQ;AACjD,UAAA,SAAA,GAAY,IAAA,GAAO,CAAA;AAEnB,UAAA,MAAM,QAAA,GAAmC,MAAM,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe;AAAA,YACxE,KAAA,EAAO,OAAA;AAAA,YACP,QAAA;AAAA,YACA,KAAA,EAAO,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,MAAA;AAAA,YAClC,WAAA,EAAa,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,MAAA;AAAA,YACzC,UAAA,EAAY;AAAA,WACb,CAAA;AAGD,UAAA,IAAI,SAAS,KAAA,EAAO;AAClB,YAAA,gBAAA,IAAoB,SAAS,KAAA,CAAM,aAAA;AACnC,YAAA,iBAAA,IAAqB,SAAS,KAAA,CAAM,iBAAA;AACpC,YAAA,IAAI,QAAA,CAAS,MAAM,2BAAA,EAA6B;AAC9C,cAAA,mBAAA,GAAA,CAAuB,mBAAA,IAAuB,CAAA,IAAK,QAAA,CAAS,KAAA,CAAM,2BAAA;AAAA,YACpE;AACA,YAAA,IAAI,QAAA,CAAS,MAAM,uBAAA,EAAyB;AAC1C,cAAA,eAAA,GAAA,CAAmB,eAAA,IAAmB,CAAA,IAAK,QAAA,CAAS,KAAA,CAAM,uBAAA;AAAA,YAC5D;AAAA,UACF;AAEA,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA;AACjC,UAAA,IAAI,CAAC,MAAA,EAAQ;AAGb,UAAA,IAAI,MAAA,CAAO,QAAQ,OAAA,EAAS;AAC1B,YAAA,aAAA,IAAiB,MAAA,CAAO,QAAQ,OAAA,GAAU,IAAA;AAC1C,YAAA,cAAA,CAAe,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AAAA,UAChD;AAEA,UAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,UAAA;AACjC,UAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG;AAG1C,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,IAAA,EAAM,WAAA;AAAA,YACN,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA;AAAA,YACxB,UAAA,EAAY;AAAA,WACb,CAAA;AAGD,UAAA,KAAA,MAAW,MAAM,SAAA,EAAW;AAC1B,YAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,EAAA,CAAG,QAAA,CAAS,IAAI,CAAA;AACpE,YAAA,IAAI,CAAC,OAAA,EAAS;AACZ,cAAA,QAAA,CAAS,IAAA,CAAK;AAAA,gBACZ,IAAA,EAAM,MAAA;AAAA,gBACN,cAAc,EAAA,CAAG,EAAA;AAAA,gBACjB,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,SAAS,EAAA,CAAG,QAAA,CAAS,IAAI,CAAA,WAAA,CAAA,EAAe;AAAA,eAC1E,CAAA;AACD,cAAA;AAAA,YACF;AAEA,YAAA,IAAI,OAAmB,EAAC;AACxB,YAAA,IAAI;AAAE,cAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,QAAA,CAAS,aAAa,IAAI,CAAA;AAAA,YAAiB,CAAA,CAAA,MAAQ;AAAA,YAAc;AAE5F,YAAA,iBAAA,CAAkB,OAAA,EAAS,EAAA,CAAG,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAEjD,YAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACzC,YAAA,mBAAA,CAAoB,OAAA,EAAS,EAAA,CAAG,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAErD,YAAA,QAAA,CAAS,IAAA,CAAK;AAAA,cACZ,IAAA,EAAM,MAAA;AAAA,cACN,cAAc,EAAA,CAAG,EAAA;AAAA,cACjB,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,CAAC,GAAG,IAAA,IAAQ;AAAA,aACrC,CAAA;AAAA,UACH;AAAA,QACF;AAGA,QAAA,IAAI,CAAC,OAAA,CAAQ,YAAA,IAAgB,aAAA,EAAe;AAC1C,UAAA,cAAA,CAAe,SAAS,aAAa,CAAA;AACrC,UAAA,MAAM,mBAAA,CAAoB,aAAA,EAAe,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA;AAAA,QAChE;AAGA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,iBAAA,CAAkB,SAAS,aAAa,CAAA;AAAA,QAChD;AAEA,QAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AACzB,UAAA,MAAM,IAAI,MAAM,mEAAmE,CAAA;AAAA,QACrF;AAEA,QAAA,OAAO;AAAA,UACL,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,eAAe,OAAA,CAAQ,aAAA;AAAA,UACvB,MAAA,EAAQ;AAAA,YACN,KAAA,EAAO,gBAAA;AAAA,YACP,MAAA,EAAQ,iBAAA;AAAA,YACR,OAAO,gBAAA,GAAmB;AAAA,WAC5B;AAAA,UACA,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,UAC/B,SAAA;AAAA,UACA,mBAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AChKO,IAAM,sBAAA,GAAuD;AAAA,EAClE,MAAA,EAAQ,kBAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,eAAA;AAAA,EACR,UAAA,EAAY;AACd;;;ACIA,SAAA,EAAA;;;ACTA,IAAM,oBAAiG,EAAC;AAExG,SAAS,gBAAA,CAAiB,UAAwB,SAAA,EAA+D;AAC/G,EAAA,iBAAA,CAAkB,QAAQ,CAAA,GAAI,SAAA;AAChC;AAGA,gBAAA,CAAiB,QAAA,EAAU;AAAA,EACzB,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,QAAA,EAAA,EAAA,WAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC,CAAA;AAAA,EACA,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,QAAA,EAAA,EAAA,WAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC;AACF,CAAC,CAAA;AAGD,gBAAA,CAAiB,QAAA,EAAU;AAAA,EACzB,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,SAAA,EAAA,EAAA,YAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC,CAAA;AAAA,EACA,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,SAAA,EAAA,EAAA,YAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC;AACF,CAAC,CAAA;AAGD,gBAAA,CAAiB,QAAA,EAAU;AAAA,EACzB,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,SAAA,EAAA,EAAA,YAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC,CAAA;AAAA,EACA,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,SAAA,EAAA,EAAA,YAAA,CAAA,CAAA;AACnC,IAAA,OAAO,IAAIA,kBAAiB,MAAM,CAAA;AAAA,EACpC;AACF,CAAC,CAAA;AAGD,gBAAA,CAAiB,YAAA,EAAc;AAAA,EAC7B,GAAA,EAAK,OAAO,MAAA,KAAW;AACrB,IAAA,MAAM,EAAE,oBAAA,EAAAC,qBAAAA,EAAqB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,SAAA,EAAA,EAAA,YAAA,CAAA,CAAA;AACvC,IAAA,OAAO,IAAIA,sBAAqB,MAAM,CAAA;AAAA,EACxC;AACF,CAAC,CAAA;AAKD,eAAsB,UAAA,CACpB,QAAA,EACA,IAAA,EACA,MAAA,GAA2B,EAAC,EACD;AAC3B,EAAA,MAAM,iBAAA,GAAoB,kBAAkB,QAAQ,CAAA;AACpD,EAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kBAAA,EAAqB,QAAQ,CAAA,aAAA,EAAgB,MAAA,CAAO,KAAK,iBAAiB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACxF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,kBAAkB,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,cAAA,EAAiB,IAAI,CAAA,gBAAA,EAAmB,QAAQ,CAAA,cAAA,EAAiB,MAAA,CAAO,IAAA,CAAK,iBAAiB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KAC5G;AAAA,EACF;AAEA,EAAA,OAAO,QAAQ,MAAM,CAAA;AACvB;AAKA,eAAsB,YAAA,CACpB,MAAA,GAA2B,EAAC,EAG5B;AACA,EAAA,MAAM,SAKD,EAAC;AAEN,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AACjE,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACrC,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,QAAwB,CAAA,GAAI,IAAmB,CAAA;AACjF,QAAA,IAAI,CAAC,OAAA,EAAS;AACd,QAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,MAAM,CAAA;AACpC,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA;AAAA,UACA,IAAA;AAAA,UACA,SAAA,EAAW,QAAQ,WAAA,EAAY;AAAA,UAC/B,aAAa,OAAA,CAAQ;AAAA,SACtB,CAAA;AAAA,MACH,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA;AAAA,UACA,IAAA;AAAA,UACA,SAAA,EAAW,KAAA;AAAA,UACX,WAAA,EAAa,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,gBAAA;AAAA,SACjC,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;;;AC5HO,IAAM,wBAAA,GAA2B,u1xIAAA;AAajC,IAAM,gBAAA,GAAmB;AAAA,EAC9B,WAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EACA,OAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;;;ACrDO,IAAM,oBAAA,GAAuB;AAAA,EAClC,OAAA;AAAA,EACA,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA;AAOO,SAAS,eAAA,CACd,WACA,cAAA,EACS;AACT,EAAA,KAAA,MAAW,QAAQ,oBAAA,EAAsB;AACvC,IAAA,IAAI,SAAA,KAAc,QAAQ,SAAA,CAAU,UAAA,CAAW,GAAG,IAAI,CAAA,CAAA,CAAG,GAAG,OAAO,IAAA;AAAA,EACrE;AACA,EAAA,OAAO,cAAA,EAAgB,GAAA,CAAI,SAAS,CAAA,IAAK,KAAA;AAC3C;AAMO,SAAS,sBAAA,GAAiC;AAC/C,EAAA,OAAO,uGAAA;AACT;ACAA,IAAM,gBAAgB,EAAA,GAAK,IAAA;AAC3B,IAAM,cAAA,GAAiB,GAAA;AAIvB,IAAM,kBAAA,GAAqBC,oBAAA;AAK3B,SAAS,aAAA,CAAc,MAAc,KAAA,EAAgC;AACnE,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,MAAM,KAAK,CAAA;AAC/C,EAAA,OAAO,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA;AAC/B;AAKA,SAAS,eAAe,IAAA,EAAuD;AAC7E,EAAA,MAAM,UAAmD,EAAC;AAC1D,EAAA,MAAM,WAAA,GAAc,sDAAA;AACpB,EAAA,IAAI,KAAA;AAEJ,EAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAChD,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,MAAA,EAAQ,MAAM,CAAC,CAAA;AAAA,MACf,IAAA,EAAM,aAAA,CAAc,IAAA,EAAM,KAAK;AAAA,KAChC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,sBAAsB,IAAA,EAAwB;AAErD,EAAA,MAAM,WAAA,GAAc,uBAAA;AACpB,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,IAAI,KAAA;AAEJ,EAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAChD,IAAA,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACnB;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AA4BO,SAAS,yBAAA,CAA0B,IAAA,EAAc,OAAA,GAA6B,EAAC,EAAqB;AACzG,EAAA,MAAM,SAA4B,EAAC;AACnC,EAAA,MAAM,WAAgC,EAAC;AACvC,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,EAAA,MAAM,YAAY,KAAA,CAAM,MAAA;AACxB,EAAA,MAAM,YAAY,IAAA,CAAK,MAAA;AAGvB,EAAA,IAAI,CAAC,QAAQ,cAAA,EAAgB;AAC3B,IAAA,IAAI,YAAY,aAAA,EAAe;AAC7B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS,4BAA4B,SAAA,GAAY,IAAA,EAAM,QAAQ,CAAC,CAAC,CAAA,WAAA,EAAc,aAAA,GAAgB,IAAI,CAAA,QAAA,CAAA;AAAA,QACnG,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,YAAY,cAAA,EAAgB;AAC9B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS,CAAA,8BAAA,EAAiC,SAAS,CAAA,SAAA,EAAY,cAAc,CAAA,WAAA,CAAA;AAAA,QAC7E,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAAA,EACF;AAMA,EAAA,MAAM,OAAA,GAAU,eAAe,IAAI,CAAA;AACnC,EAAA,IAAI,CAAC,QAAQ,oBAAA,EAAsB;AACnC,IAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,MAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA;AAI5C,MAAA,MAAM,kBACJ,GAAA,CAAI,MAAA,KAAW,qBACf,GAAA,CAAI,MAAA,CAAO,WAAW,kBAAkB,CAAA;AAC1C,MAAA,IAAI,CAAC,SAAA,IAAa,CAAC,eAAA,EAAiB;AAClC,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,QAAA;AAAA,UACN,OAAA,EAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,UACvC,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,UAAA,EAAY,CAAA,kBAAA,EAAqB,sBAAA,EAAwB,CAAA,qDAAA;AAAA,SAC1D,CAAA;AAAA,MACH;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,QAAQ,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,OAAO,CAAA,EAAG;AAE9C,MAAA,IAAI,mEAAA,CAAoE,IAAA,CAAK,IAAI,CAAA,EAAG;AAClF,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA,EAAM,eAAA;AAAA,UACN,OAAA,EAAS,2DAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACb,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,QAAQ,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,iBAAiB,CAAA,EAAG;AACxD,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,6CAAA;AAAA,QACT,UAAA,EACE;AAAA,OACH,CAAA;AAAA,IACH;AAAA,EACA;AAGA,EAAA,MAAM,cAAA,GAAiB,sBAAsB,IAAI,CAAA;AAGjD,EAAA,MAAM,qBAAA,GAAwB,QAAQ,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,MAAA,CAAO,UAAA,CAAW,iBAAiB,CAAC,CAAA;AAGxF,EAAA,MAAM,sBAAA,uBAA6B,GAAA,EAAY;AAE/C,EAAA,IAAI,qBAAA,EAAuB;AAEzB,IAAA,MAAM,gBAAA,GAAmB,yDAAA;AACzB,IAAA,IAAI,KAAA;AACJ,IAAA,OAAA,CAAQ,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACrD,MAAA,MAAM,QAAQ,KAAA,CAAM,CAAC,EAAE,KAAA,CAAM,GAAG,EAAE,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAA,GAAO,KAAA,CAAM,MAAM,EAAE,CAAC,CAAA,CAAE,MAAM,CAAA;AAC7E,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,IAAA,EAAM,sBAAA,CAAuB,GAAA,CAAI,IAAI,CAAA;AAAA,MAC3C;AAAA,IACF;AAEA,IAAA,MAAM,kBAAA,GAAqB,2DAAA;AAC3B,IAAA,OAAA,CAAQ,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACvD,MAAA,sBAAA,CAAuB,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACrC;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,aAAa,cAAA,EAAgB;AACtC,IAAA,IAAI,CAAC,gBAAA,CAAiB,QAAA,CAAS,SAA8C,CAAA,EAAG;AAE9E,MAAA,IAAI,sBAAA,CAAuB,GAAA,CAAI,SAAS,CAAA,EAAG;AACzC,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,aAAa,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IAAK,IAAA,CAAK,SAAS,SAAS,CAAA;AACrE,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,WAAA;AAAA,UACN,OAAA,EAAS,uBAAuB,SAAS,CAAA,+BAAA,CAAA;AAAA,UACzC,UAAA,EAAY,oCAAoC,gBAAA,CAAiB,KAAA,CAAM,GAAG,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,uEAAA;AAAA,SACzF,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,QAAQ,oBAAA,EAAsB;AACjC,IAAA,KAAA,MAAW,EAAE,OAAA,EAAS,IAAA,EAAM,UAAA,MAAgB,kBAAA,EAAoB;AAC9D,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAC/B,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,UAAA;AAAA,UACN,OAAA,EAAS,uBAAuB,IAAI,CAAA,eAAA,CAAA;AAAA,UACpC,IAAA,EAAM,aAAA,CAAc,IAAA,EAAM,KAAK,CAAA;AAAA,UAC/B,UAAA;AAAA,UACA,IAAA,EAAM,MAAM,CAAC;AAAA,SACd,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACpC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,WAAA;AAAA,MACN,OAAA,EAAS,sCAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,6CAAA,CAA8C,IAAA,CAAK,IAAI,CAAA,EAAG;AAC5D,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,WAAA;AAAA,MACN,OAAA,EAAS,kCAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AACpF,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,eAAA;AAAA,MACN,OAAA,EAAS,uDAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,uCAAA,CAAwC,IAAA,CAAK,IAAI,CAAA,EAAG;AACtD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EACE,wFAAA;AAAA,MACF,UAAA,EACE;AAAA,KACH,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,IAAA,CAAK,SAAS,OAAO,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AACpD,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,eAAA;AAAA,MACN,OAAA,EAAS,+CAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,IAAA,CAAK,SAAS,QAAQ,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AACrD,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,eAAA;AAAA,MACN,OAAA,EAAS,6BAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,IAAK,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,IAAK,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAC5F,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,IAAA,CAAK,IAAI,KAAK,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,IAAK,cAAc,IAAA,CAAK,IAAI,CAAA,IAAK,kBAAA,CAAmB,KAAK,IAAI,CAAA;AAC1H,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,qCAAA;AAAA,QACT,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,KAAM,CAAC,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AAC/F,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,eAAA;AAAA,MACN,OAAA,EAAS,yBAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAIA,EAAA,MAAM,iBAAA,GAAoB,mDAAA;AAC1B,EAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA,EAAG;AAChC,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,eAAA;AAAA,MACN,OAAA,EAAS,gDAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,SAAS,CAAA,IAAK,CAAC,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA,EAAG;AAChE,IAAA,IAAI,KAAK,QAAA,CAAS,UAAU,KAAK,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG;AACxD,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,sCAAA;AAAA,QACT,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,WAAA,CAAY,KAAK,4EAA4E,CAAA;AAAA,EAC/F;AAEA,EAAA,IAAI,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,QAAQ,CAAA,EAAG;AAC3C,IAAA,WAAA,CAAY,IAAA;AAAA,MACV;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,UAAU,CAAA,EAAG;AAC7C,IAAA,WAAA,CAAY,KAAK,6DAA6D,CAAA;AAAA,EAChF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB,MAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,SAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAa,OAAA,CAAQ,MAAA;AAAA,MACrB,gBAAgB,cAAA,CAAe,MAAA;AAAA,QAAO,CAAC,CAAA,KACrC,gBAAA,CAAiB,QAAA,CAAS,CAAsC;AAAA,OAClE,CAAE;AAAA;AACJ,GACF;AACF;AAoBO,SAAS,gCAAgC,MAAA,EAAkC;AAChF,EAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA,EAAG;AAChD,IAAA,OAAO,wDAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,IAAA,KAAA,CAAM,KAAK,mCAAmC,CAAA;AAC9C,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,WAAW,KAAA,CAAM,IAAA,GAAO,CAAA,OAAA,EAAU,KAAA,CAAM,IAAI,CAAA,CAAA,CAAA,GAAM,EAAA;AACxD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,IAAA,EAAO,KAAA,CAAM,IAAA,CAAK,WAAA,EAAa,CAAA,EAAA,EAAK,QAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA;AAC3E,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,KAAA,CAAM,UAAU,CAAA,CAAE,CAAA;AACzC,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,IAAI,CAAA,EAAA,CAAI,CAAA;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC9B,IAAA,KAAA,CAAM,KAAK,sCAAsC,CAAA;AACjD,IAAA,KAAA,MAAW,OAAA,IAAW,OAAO,QAAA,EAAU;AACrC,MAAA,MAAM,WAAW,OAAA,CAAQ,IAAA,GAAO,CAAA,OAAA,EAAU,OAAA,CAAQ,IAAI,CAAA,CAAA,CAAA,GAAM,EAAA;AAC5D,MAAA,KAAA,CAAM,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAI,KAAK,QAAQ,CAAA,EAAA,EAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AACjE,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,gBAAA,EAAmB,OAAA,CAAQ,UAAU,CAAA,CAAE,CAAA;AAAA,IACpD;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,CAAO,WAAA,CAAY,MAAA,GAAS,CAAA,EAAG;AACjC,IAAA,KAAA,CAAM,KAAK,4BAA4B,CAAA;AACvC,IAAA,KAAA,MAAW,UAAA,IAAc,OAAO,WAAA,EAAa;AAC3C,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,UAAU,CAAA,CAAE,CAAA;AAAA,IAC9B;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ;AAAA,UAAA,EAAe,OAAO,KAAA,CAAM,SAAS,CAAA,QAAA,EAAW,MAAA,CAAO,MAAM,cAAc,CAAA,gBAAA;AAAA,GAC7E;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;ACnbO,IAAM,0BAAA,GAA6B,CAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAAA,CAAA;;;ACEnC,SAAS,mBAAmB,MAAA,EAA4B;AAE7D,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA;AAC5C,EAAA,IAAI,cAAc,MAAA,EAAQ;AACxB,IAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,IAAI,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,CAAA,CAAA,KAAK,kBAAA,CAAmB,CAAC,CAAC,CAAC,CAAC,CAAA;AACvE,IAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,EACzD;AAGA,EAAA,IAAI,MAAA,CAAO,UAAU,MAAA,EAAW;AAC9B,IAAA,OAAO,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,CAAA,CAAA,EAAI,OAAO,KAAK,CAAA,CAAA,CAAA,GAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,EACrF;AAGA,EAAA,IAAI,MAAA,CAAO,MAAM,MAAA,EAAQ;AACvB,IAAA,OAAO,MAAA,CAAO,IAAA,CACX,GAAA,CAAI,CAAA,CAAA,KAAK,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAA,EAAI,CAAC,MAAM,MAAA,CAAO,CAAC,CAAC,CAAA,CACrD,KAAK,KAAK,CAAA;AAAA,EACf;AAEA,EAAA,IAAI,MAAA;AAEJ,EAAA,QAAQ,OAAO,IAAA;AAAM,IACnB,KAAK,QAAA;AACH,MAAA,MAAA,GAAS,QAAA;AACT,MAAA;AAAA,IACF,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AACH,MAAA,MAAA,GAAS,QAAA;AACT,MAAA;AAAA,IACF,KAAK,SAAA;AACH,MAAA,MAAA,GAAS,SAAA;AACT,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,OAAO,MAAA;AAAA,IAET,KAAK,OAAA,EAAS;AACZ,MAAA,IAAI,OAAO,KAAA,EAAO;AAChB,QAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAA;AAEhD,QAAA,MAAA,GAAU,OAAO,KAAA,CAAM,IAAA,KAAS,YAAY,MAAA,CAAO,KAAA,CAAM,aACrD,CAAA,MAAA,EAAS,QAAQ,CAAA,CAAA,CAAA,GAChB,QAAA,CAAS,SAAS,GAAG,CAAA,GAAI,IAAI,QAAQ,CAAA,GAAA,CAAA,GAAQ,GAAG,QAAQ,CAAA,EAAA,CAAA;AAAA,MAC/D,CAAA,MAAO;AACL,QAAA,MAAA,GAAS,WAAA;AAAA,MACX;AACA,MAAA;AAAA,IACF;AAAA,IAEA,KAAK,QAAA,EAAU;AACb,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,EAAC;AACrC,QAAA,MAAM,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,CAC5C,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,IAAI,CAAA,KAAM;AACpB,UAAA,MAAM,GAAA,GAAM,CAAC,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA;AAClC,UAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,GAAA,GAAM,MAAM,EAAE,CAAA,EAAA,EAAK,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA;AAAA,QAC7D,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACZ,QAAA,MAAA,GAAS,KAAK,MAAM,CAAA,EAAA,CAAA;AAAA,MACtB,WAAW,MAAA,CAAO,oBAAA,IAAwB,OAAO,MAAA,CAAO,yBAAyB,QAAA,EAAU;AACzF,QAAA,MAAA,GAAS,CAAA,eAAA,EAAkB,kBAAA,CAAmB,MAAA,CAAO,oBAAoB,CAAC,CAAA,CAAA,CAAA;AAAA,MAC5E,CAAA,MAAO;AACL,QAAA,MAAA,GAAS,yBAAA;AAAA,MACX;AACA,MAAA;AAAA,IACF;AAAA,IAEA;AACE,MAAA,MAAA,GAAS,SAAA;AAAA;AAIb,EAAA,IAAI,MAAA,CAAO,QAAA,IAAY,MAAA,KAAW,SAAA,EAAW;AAC3C,IAAA,OAAO,GAAG,MAAM,CAAA,OAAA,CAAA;AAAA,EAClB;AAEA,EAAA,OAAO,MAAA;AACT;;;AC3BO,SAAS,sBAAsB,IAAA,EAAsC;AAC1E,EAAA,MAAM,EAAA,GAAKC,GAAAA,CAAG,gBAAA,CAAiB,eAAA,EAAiB,IAAA,EAAMA,GAAAA,CAAG,YAAA,CAAa,MAAA,EAAQ,IAAA,EAAMA,GAAAA,CAAG,UAAA,CAAW,GAAG,CAAA;AACrG,EAAA,MAAM,QAAyB,EAAC;AAEhC,EAAA,SAAS,aAAa,OAAA,EAA6C;AACjE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAIA,GAAAA,CAAG,mBAAA,CAAoB,MAAM,CAAA,IAAK,OAAO,IAAA,EAAM;AACjD,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAA;AACnC,QAAA,MAAM,OAAO,MAAA,CAAO,IAAA,GAAO,OAAO,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAA,GAAI,SAAA;AACrD,QAAA,MAAM,QAAA,GAAW,CAAC,CAAC,MAAA,CAAO,aAAA;AAC1B,QAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,CAAA;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,SAAS,MAAM,IAAA,EAAqB;AAElC,IAAA,IAAIA,IAAG,sBAAA,CAAuB,IAAI,KAAK,IAAA,CAAK,IAAA,CAAK,SAAS,OAAA,EAAS;AACjE,MAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AACzB,MAAA;AAAA,IACF;AAEA,IAAA,IAAIA,IAAG,sBAAA,CAAuB,IAAI,KAAK,IAAA,CAAK,IAAA,CAAK,SAAS,OAAA,EAAS;AACjE,MAAA,IAAIA,GAAAA,CAAG,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA,EAAG;AACnC,QAAA,YAAA,CAAa,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,MAChC;AACA,MAAA;AAAA,IACF;AACA,IAAAA,GAAAA,CAAG,YAAA,CAAa,IAAA,EAAM,KAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,KAAA,CAAM,EAAE,CAAA;AACR,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,IAAA;AACpC;AAUO,SAAS,0BAAA,CACd,MACA,IAAA,EACiB;AACjB,EAAA,MAAM,SAA0B,EAAC;AACjC,EAAA,MAAM,SAAA,GAAY,sBAAsB,IAAI,CAAA;AAE5C,EAAA,IAAI,CAAC,SAAA,EAAW;AAEd,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAE9D,EAAA,KAAA,MAAW,CAAC,UAAU,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,UAAU,CAAA,EAAG;AAC/D,IAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA;AAE/C,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,IAAI,MAAM,QAAA,EAAU;AAClB,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA,EAAU,OAAA;AAAA,UACV,KAAA,EAAO,QAAA;AAAA,UACP,OAAA,EAAS,8CAA8C,QAAQ,CAAA,wBAAA,CAAA;AAAA,UAC/D,GAAA,EAAK,CAAA,MAAA,EAAS,QAAQ,CAAA,EAAG,KAAA,CAAM,QAAA,GAAW,EAAA,GAAK,GAAG,CAAA,EAAA,EAAK,kBAAA,CAAmB,KAAA,CAAM,MAAM,CAAC,CAAA,0BAAA;AAAA,SACxF,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA,EAAU,SAAA;AAAA,UACV,KAAA,EAAO,QAAA;AAAA,UACP,OAAA,EAAS,8CAA8C,QAAQ,CAAA,wBAAA,CAAA;AAAA,UAC/D,KAAK,CAAA,kBAAA,EAAqB,QAAQ,MAAM,kBAAA,CAAmB,KAAA,CAAM,MAAM,CAAC,CAAA,0BAAA;AAAA,SACzE,CAAA;AAAA,MACH;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,aAAA,CAAc,SAAS,SAAA,EAAW;AACpC,MAAA,MAAM,cAAA,GAAiB,kBAAA,CAAmB,KAAA,CAAM,MAAM,CAAA;AACtD,MAAA,IAAI,CAAC,gBAAA,CAAiB,aAAA,CAAc,MAAM,cAAA,EAAgB,KAAA,CAAM,MAAM,CAAA,EAAG;AACvE,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA,EAAU,SAAA;AAAA,UACV,KAAA,EAAO,QAAA;AAAA,UACP,SAAS,CAAA,OAAA,EAAU,QAAQ,eAAe,aAAA,CAAc,IAAI,2BAA2B,cAAc,CAAA,CAAA,CAAA;AAAA,UACrG,GAAA,EAAK,CAAA,SAAA,EAAY,QAAQ,CAAA,aAAA,EAAgB,cAAc,CAAA,EAAA;AAAA,SACxD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,gBAAA,CAAiB,MAAA,EAAgB,cAAA,EAAwB,MAAA,EAA6B;AAC7F,EAAA,MAAM,aAAa,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,EAAE,EAAE,WAAA,EAAY;AAEzD,EAAA,QAAQ,OAAO,IAAA;AAAM,IACnB,KAAK,QAAA;AACH,MAAA,OAAO,UAAA,CAAW,SAAS,QAAQ,CAAA;AAAA,IACrC,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AACH,MAAA,OAAO,UAAA,CAAW,SAAS,QAAQ,CAAA;AAAA,IACrC,KAAK,SAAA;AACH,MAAA,OAAO,UAAA,CAAW,SAAS,SAAS,CAAA;AAAA,IACtC,KAAK,OAAA;AACH,MAAA,OAAO,WAAW,QAAA,CAAS,IAAI,CAAA,IAAK,UAAA,CAAW,SAAS,OAAO,CAAA;AAAA,IACjE,KAAK,QAAA;AACH,MAAA,OAAO,CAAC,CAAC,QAAA,EAAU,QAAA,EAAU,SAAS,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,UAAA,KAAe,CAAC,CAAA;AAAA,IACtE;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AA8CO,SAAS,6BAAA,CACd,MACA,IAAA,EACiB;AACjB,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA;AAEhD,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,OAAA;AAAA,MACV,KAAA,EAAO,gBAAA;AAAA,MACP,OAAA,EAAS,gGAAA;AAAA,MACT,GAAA,EAAK;AAAA,KACN,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAIA,EAAA,KAAA,MAAW,CAAC,WAAA,EAAa,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvD,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,CAAG,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,CAAA,CAAA,EAAI,WAAW,GAAG,CAAA,EAAG;AAC5E,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,QAAA,EAAU,SAAA;AAAA,QACV,KAAA,EAAO,WAAA;AAAA,QACP,OAAA,EAAS,gCAAgC,WAAW,CAAA,oCAAA,CAAA;AAAA,QACpD,KAAK,CAAA,eAAA,EAAkB,WAAW,CAAA,cAAA,EAAiB,KAAA,CAAM,eAAe,WAAW,CAAA,OAAA;AAAA,OACpF,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,6BAAA,CACd,MACA,IAAA,EACiB;AACjB,EAAA,MAAM,SAA0B,EAAC;AAGjC,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAEpD,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,QAAA,CAAS,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,CAAG,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,CAAG,CAAA;AACpF,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACjD,IAAA,MAAM,YAAA,GAAe,CAAA,EAAA,EAAK,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,QAAA,CAAS,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC9E,IAAA,MAAM,kBAAA,GAAqB,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA;AAErD,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,eAAA,IAAmB,CAAC,kBAAA,EAAoB;AAC5D,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,QAAA,EAAU,OAAA;AAAA,QACV,KAAA,EAAO,QAAA;AAAA,QACP,OAAA,EAAS,CAAA,4BAAA,EAA+B,QAAQ,CAAA,IAAA,EAAO,MAAM,KAAK,CAAA,gCAAA,CAAA;AAAA,QAClE,GAAA,EAAK,sBAAsB,QAAQ,CAAA,mEAAA;AAAA,OACpC,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,oBAAA,CACd,MACA,QAAA,EACiB;AACjB,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,IAAI,SAAS,SAAA,EAAW;AACtB,IAAA,MAAA,CAAO,KAAK,GAAG,0BAAA,CAA2B,IAAA,EAAM,QAAA,CAAS,SAAS,CAAC,CAAA;AAAA,EACrE;AAEA,EAAA,IAAI,SAAS,UAAA,EAAY;AACvB,IAAA,MAAA,CAAO,KAAK,GAAG,6BAAA,CAA8B,IAAA,EAAM,QAAA,CAAS,UAAU,CAAC,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,SAAS,UAAA,EAAY;AACvB,IAAA,MAAA,CAAO,KAAK,GAAG,6BAAA,CAA8B,IAAA,EAAM,QAAA,CAAS,UAAU,CAAC,CAAA;AAAA,EACzE;AAEA,EAAA,OAAO,MAAA;AACT;ACpPA,IAAM,cAAA,uBAAqB,GAAA,CAAI;AAAA,EAC7B,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAIA,IAAA;AAAA;AAAA,EACA,IAAA;AAAA;AAAA,EACA,IAAA;AAAA;AAAA,EACA,IAAA;AAAA;AAAA,EACA,IAAA;AAAA;AAAA,EACA,KAAA;AAAA;AAAA,EACA,KAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAC,CAAA;AAMD,SAAS,WAAA,CAAY,IAAA,EAAc,OAAA,EAAkB,UAAA,EAA6B;AAKhF,EAAA,MAAM,UAAA,GACJ,UAAA,IAAc,UAAA,CAAW,MAAA,GAAS,CAAA,IAAK,WAAW,MAAA,IAAU,GAAA,GACxD,CAAA,mBAAA,EAAsB,UAAU,CAAA,EAAA,CAAA,GAChC,EAAA;AAGN,EAAA,IAAA,CAAK,IAAA,KAAS,QAAQ,IAAA,KAAS,IAAA,KAAS,WAAW,yDAAA,CAA0D,IAAA,CAAK,OAAO,CAAA,EAAG;AAC1H,IAAA,OAAO,uPAA6O,UAAU,CAAA,CAAA;AAAA,EAChQ;AAKA,EAAA,IAAI,SAAS,IAAA,IAAQ,OAAA,IAAW,qBAAA,CAAsB,IAAA,CAAK,OAAO,CAAA,EAAG;AACnE,IAAA,OAAO,2QAAsQ,UAAU,CAAA,CAAA;AAAA,EACzR;AAGA,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,OAAA,IAAW,CAAC,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,IAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC1F,IAAA,OAAO,4RAA4R,UAAU,CAAA,CAAA;AAAA,EAC/S;AAGA,EAAA,IAAA,CAAK,IAAA,KAAS,QAAQ,IAAA,KAAS,IAAA,KAAS,WAAW,uCAAA,CAAwC,IAAA,CAAK,OAAO,CAAA,EAAG;AACxG,IAAA,OAAO,gHAAgH,UAAU,CAAA,CAAA;AAAA,EACnI;AAEA,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,IAAA;AACH,MAAA,OAAO,CAAA,gCAAA,EAAmC,sBAAA,EAAwB,CAAA,EAAG,UAAU,CAAA,CAAA;AAAA,IACjF,KAAK,IAAA;AAAA,IACL,KAAK,IAAA;AACH,MAAA,OAAO,yKAAoK,UAAU,CAAA,CAAA;AAAA,IACvL,KAAK,IAAA;AACH,MAAA,OAAO,+KAA0K,UAAU,CAAA,CAAA;AAAA,IAC7L,KAAK,IAAA;AACH,MAAA,OAAO,0EAA0E,UAAU,CAAA,CAAA;AAAA,IAC7F,KAAK,IAAA;AACH,MAAA,OAAO,qEAAqE,UAAU,CAAA,CAAA;AAAA,IACxF,KAAK,KAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAA,OAAO,iPAA4O,UAAU,CAAA,CAAA;AAAA,IAC/P;AACE,MAAA,OAAO,sDAAsD,UAAU,CAAA,CAAA;AAAA;AAE7E;AAWA,IAAI,QAAA,GAAyC,IAAA;AAE7C,SAAS,aAAA,CACP,GAAA,EACA,WAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,aAAaA,GAAAA,CAAG,gBAAA;AAAA,IACpB,WAAA;AAAA,IACA,OAAA;AAAA,IACAA,IAAG,YAAA,CAAa,MAAA;AAAA,IAChB,IAAA;AAAA,IACA,WAAA,CAAY,SAAS,MAAM,CAAA,GAAIA,IAAG,UAAA,CAAW,GAAA,GAAMA,IAAG,UAAA,CAAW;AAAA,GACnE;AACA,EAAA,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,EAAE,OAAA,EAAS,YAAY,CAAA;AAC9C;AAKA,SAAS,OAAA,CAAQ,KAAa,MAAA,EAA0C;AACtE,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,KAAA,IAAS,GAAG,WAAA,CAAY,GAAA,EAAK,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA,EAAG;AAChE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AACtC,IAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,MAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAC,CAAA;AAAA,IACvC,CAAA,MAAA,IAAW,MAAA,CAAO,IAAI,CAAA,EAAG;AACvB,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAWA,SAAS,iBAAA,GAAmC;AAC1C,EAAA,IAAI;AAGF,IAAA,MAAM,WAAW,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,QAAQ,yBAAyB,CAAA;AACjF,IAAA,OAAO,IAAA,CAAK,QAAQ,QAAQ,CAAA;AAAA,EAC9B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAQA,SAAS,mBAAmB,GAAA,EAA4B;AACtD,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,cAAc,MAAA,CAAA,IAAA,CAAY,GAAG,EAAE,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAA,aAAA,CAAe,CAAA;AAC5E,IAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,KAAK,OAAA,CAAQ,OAAO,GAAG,MAAM,CAAA;AACpD,IAAA,OAAO,EAAA,CAAG,UAAA,CAAW,IAAI,CAAA,GAAI,IAAA,GAAO,IAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAe,OAAA,GAA0C;AACvD,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAsB;AAOtC,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC9C,EAAA,MAAM,QAAQ,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,OAAA,CAAQ,8BAA8B,CAAC,CAAA;AAC3E,EAAA,MAAM,QAAA,GAAW,EAAA,CAAG,WAAA,CAAY,KAAK,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,kBAAA,CAAmB,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/E,EAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,IAAA,MAAM,OAAA,GAAU,GAAG,YAAA,CAAa,IAAA,CAAK,KAAK,KAAA,EAAO,IAAI,GAAG,OAAO,CAAA;AAC/D,IAAA,aAAA,CAAc,GAAA,EAAK,MAAM,OAAO,CAAA;AAAA,EAClC;AAQA,EAAA,MAAM,WAAW,iBAAA,EAAkB;AACnC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAM,QAAA,GAAW,EAAA,CAAG,WAAA,CAAY,QAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAC,CAAA;AAC3E,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,MAAM,OAAA,GAAU,GAAG,YAAA,CAAa,IAAA,CAAK,KAAK,QAAA,EAAU,IAAI,GAAG,OAAO,CAAA;AAClE,MAAA,aAAA,CAAc,GAAA,EAAK,CAAA,0BAAA,EAA6B,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA;AAAA,IACjE;AAAA,EACF;AAGA,EAAA,MAAM,UAAA,GAAa,mBAAmB,iBAAiB,CAAA;AACvD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,EAAY,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,WAAW,CAAC,CAAA;AAC3F,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,UAAA,EAAY,IAAI,CAAA;AAC1C,MAAA,MAAM,OAAA,GAAU,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,OAAO,CAAA;AAC7C,MAAA,aAAA,CAAc,GAAA,EAAK,CAAA,6BAAA,EAAgC,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA;AAAA,IACnE;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAAW,mBAAmB,eAAe,CAAA;AACnD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,EAAU,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,WAAW,CAAC,CAAA;AACzF,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,QAAA,EAAU,IAAI,CAAA;AACxC,MAAA,MAAM,OAAA,GAAU,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,OAAO,CAAA;AAC7C,MAAA,aAAA,CAAc,GAAA,EAAK,CAAA,2BAAA,EAA8B,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA;AAAA,IACjE;AAAA,EACF;AASA,EAAA,MAAM,cAAA,GAAiB,mBAAmB,kBAAkB,CAAA;AAC5D,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,MAAM,QAAA,GAAW,OAAA;AAAA,MACf,cAAA;AAAA,MACA,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,WAAW;AAAA,KACvD;AACA,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,cAAA,EAAgB,IAAI,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,OAAO,CAAA;AAC7C,MAAA,aAAA,CAAc,GAAA,EAAK,CAAA,8BAAA,EAAiC,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA;AAAA,IACpE;AAAA,EACF;AAEA,EAAA,QAAA,GAAW,GAAA;AACX,EAAA,OAAO,GAAA;AACT;AAcA,SAAS,oBAAA,CACP,GAAA,EACA,cAAA,EACA,UAAA,EACoB;AAEpB,EAAA,MAAM,UAAA,GAAa,eAAe,UAAA,CAAW,GAAG,IAAI,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,GAAI,cAAA;AAC9E,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA;AACzC,EAAA,MAAMC,SAAAA,GAAW,KAAK,KAAA,CAAM,SAAA,CAAU,GAAG,GAAG,CAAA,CAAA,EAAI,UAAU,CAAA,CAAE,CAAA;AAG5D,EAAA,MAAM,OAAA,GAAU,GAAGA,SAAQ,CAAA,KAAA,CAAA;AAC3B,EAAA,IAAI,GAAA,CAAI,GAAA,CAAI,OAAO,CAAA,EAAG,OAAO,OAAA;AAG7B,EAAA,MAAM,YAAA,GAAe,GAAGA,SAAQ,CAAA,WAAA,CAAA;AAChC,EAAA,IAAI,GAAA,CAAI,GAAA,CAAI,YAAY,CAAA,EAAG,OAAO,YAAA;AAGlC,EAAA,MAAM,MAAA,GAAS,GAAGA,SAAQ,CAAA,GAAA,CAAA;AAC1B,EAAA,IAAI,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,MAAA;AAG5B,EAAA,IAAI,GAAA,CAAI,GAAA,CAAIA,SAAQ,CAAA,EAAG,OAAOA,SAAAA;AAE9B,EAAA,OAAO,MAAA;AACT;AAMA,IAAM,gBAAA,GAAuC;AAAA,EAC3C,MAAA,EAAQD,IAAG,YAAA,CAAa,MAAA;AAAA,EACxB,MAAA,EAAQA,IAAG,UAAA,CAAW,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtB,GAAA,EAAKA,IAAG,OAAA,CAAQ,KAAA;AAAA,EAChB,gBAAA,EAAkBA,IAAG,oBAAA,CAAqB,OAAA;AAAA,EAC1C,MAAA,EAAQ,KAAA;AAAA,EACR,gBAAA,EAAkB,IAAA;AAAA;AAAA,EAClB,MAAA,EAAQ,IAAA;AAAA,EACR,YAAA,EAAc,IAAA;AAAA,EACd,aAAA,EAAe,IAAA;AAAA,EACf,OAAO,EAAC;AAAA,EACR,eAAA,EAAiB;AACnB,CAAA;AAQA,SAAS,iBAAiB,CAAA,EAA0B;AAClD,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA,EAAG;AACrB,IAAA,OAAO,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,IAAA;AACT;AAOA,SAAS,iBAAA,CACP,GAAA,EACA,IAAA,EACA,cAAA,EAC4C;AAE5C,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,OAAO,SAAS,sCAAsC,CAAA;AAAA,EACxD;AACA,EAAA,IAAI,SAAS,mBAAA,EAAqB;AAChC,IAAA,OAAO,SAAS,4CAA4C,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,SAAS,uBAAA,EAAyB;AACpC,IAAA,MAAM,CAAA,GAAI,gDAAA;AACV,IAAA,IAAI,IAAI,GAAA,CAAI,CAAC,CAAA,EAAG,OAAO,SAAS,CAAC,CAAA;AACjC,IAAA,OAAO,SAAS,4CAA4C,CAAA;AAAA,EAC9D;AAGA,EAAA,MAAM,YAAA,GAAe,kBAAA;AACrB,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,YAAY,CAAA,EAAG;AACjC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,MAAM,CAAA;AAC9C,IAAA,MAAM,SAAA,GAAY,gCAAgC,OAAO,CAAA,WAAA,CAAA;AACzD,IAAA,IAAI,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG,OAAO,SAAS,SAAS,CAAA;AACjD,IAAA,MAAM,UAAA,GAAa,gCAAgC,OAAO,CAAA,KAAA,CAAA;AAC1D,IAAA,IAAI,IAAI,GAAA,CAAI,UAAU,CAAA,EAAG,OAAO,SAAS,UAAU,CAAA;AAAA,EACrD;AAGA,EAAA,IAAI,SAAS,iBAAA,EAAmB;AAC9B,IAAA,OAAO,SAAS,yCAAyC,CAAA;AAAA,EAC3D;AAGA,EAAA,IAAI,SAAS,eAAA,EAAiB;AAC5B,IAAA,OAAO,SAAS,uCAAuC,CAAA;AAAA,EACzD;AAMA,EAAA,IAAI,SAAS,kBAAA,EAAoB;AAC/B,IAAA,OAAO,SAAS,0CAA0C,CAAA;AAAA,EAC5D;AAGA,EAAA,IAAI,KAAK,UAAA,CAAW,IAAI,KAAK,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACnD,IAAA,MAAM,YAAA,GAAe,oBAAA,CAAqB,GAAA,EAAK,cAAA,EAAgB,IAAI,CAAA;AACnE,IAAA,IAAI,YAAA,EAAc,OAAO,QAAA,CAAS,YAAY,CAAA;AAAA,EAChD;AASA,EAAA,MAAM,SAAA,GAAY,gBAAgB,IAAI,CAAA,WAAA,CAAA;AACtC,EAAA,IAAI,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG,OAAO,SAAS,SAAS,CAAA;AAGjD,EAAA,OAAO,EAAE,gBAAgB,MAAA,EAAU;AACrC;AAEA,SAAS,aAAA,CACP,KACA,aAAA,EACiB;AAEjB,EAAA,MAAM,gBAAgBA,GAAAA,CAAG,gBAAA;AAAA,IACvB,eAAA;AAAA,IACA,aAAA;AAAA,IACAA,IAAG,YAAA,CAAa,MAAA;AAAA,IAChB,IAAA;AAAA,IACAA,IAAG,UAAA,CAAW;AAAA,GAChB;AAEA,EAAA,MAAM,IAAA,GAAwB;AAAA,IAC5B,cAAc,QAAA,EAAkB;AAC9B,MAAA,IAAI,QAAA,KAAa,iBAAiB,OAAO,aAAA;AACzC,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,GAAA,CAAI,QAAQ,CAAA;AAC9B,MAAA,IAAI,KAAA,SAAc,KAAA,CAAM,UAAA;AAExB,MAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,MAAA,IAAI,UAAA,EAAY,OAAO,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,EAAG,UAAA;AAC5C,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,qBAAA,GAAwB;AACtB,MAAA,OAAO,sBAAA;AAAA,IACT,CAAA;AAAA,IACA,SAAA,GAAY;AAAA,IAEZ,CAAA;AAAA,IACA,mBAAA,GAAsB;AACpB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA,qBAAqB,CAAA,EAAW;AAC9B,MAAA,OAAO,CAAA;AAAA,IACT,CAAA;AAAA,IACA,yBAAA,GAA4B;AAC1B,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA,UAAA,GAAa;AACX,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA,WAAW,CAAA,EAAW;AACpB,MAAA,IAAI,MAAM,eAAA,IAAmB,GAAA,CAAI,GAAA,CAAI,CAAC,GAAG,OAAO,IAAA;AAGhD,MAAA,MAAM,UAAA,GAAa,iBAAiB,CAAC,CAAA;AACrC,MAAA,IAAI,UAAA,IAAc,GAAA,CAAI,GAAA,CAAI,UAAU,GAAG,OAAO,IAAA;AAC9C,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IACA,SAAS,CAAA,EAAW;AAClB,MAAA,IAAI,CAAA,KAAM,iBAAiB,OAAO,aAAA;AAClC,MAAA,MAAM,MAAA,GAAS,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA;AACxB,MAAA,IAAI,MAAA,SAAe,MAAA,CAAO,OAAA;AAC1B,MAAA,MAAM,UAAA,GAAa,iBAAiB,CAAC,CAAA;AACrC,MAAA,IAAI,UAAA,EAAY,OAAO,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,EAAG,OAAA;AAC5C,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,yBAAA,CACE,gBACA,cAAA,EACuD;AACvD,MAAA,OAAO,cAAA,CAAe,GAAA;AAAA,QAAI,CAAC,OAAA,KACzB,iBAAA,CAAkB,GAAA,EAAK,OAAA,CAAQ,MAAM,cAAc;AAAA,OACrD;AAAA,IACF;AAAA,GACF;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,SAAS,gBAAA,EAAsE;AACtF,EAAA,OAAO;AAAA,IACL,cAAA,EAAgB;AAAA,MACd,gBAAA;AAAA,MACA,uBAAA,EAAyB,IAAA;AAAA,MACzB,SAAA,EAAWA,IAAG,SAAA,CAAU;AAAA;AAC1B,GACF;AACF;AAMA,eAAsB,SAAA,CACpB,MAiBA,MAAA,EAC0B;AAC1B,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAW1B,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,MAAM,aAA6D,EAAC;AACpE,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,MAAA,OAAO,GAAA;AAAA,IACT;AACA,IAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,GAAG,CAAA;AAC3B,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,OAAO,CAAA,IAAK,UAAA,EAAY;AACvC,MAAA,aAAA,CAAc,OAAA,EAAS,CAAA,aAAA,EAAgB,GAAG,CAAA,WAAA,CAAA,EAAe,OAAO,CAAA;AAAA,IAClE;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,GAAG;AAqBH,EAAA,MAAM,aAAA,GACJ,8gBAAA;AAUF,EAAA,MAAM,mBAAmB,8BAAA,GAAiC,aAAA;AAC1D,EAAA,MAAM,eAAe,gBAAA,GAAmB,IAAA;AACxC,EAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,KAAA,CAAM,IAAI,EAAE,MAAA,GAAS,CAAA;AAEzD,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,YAAA,EAAc,YAAY,CAAA;AAErD,EAAA,MAAM,UAAUA,GAAAA,CAAG,aAAA,CAAc,CAAC,eAAe,CAAA,EAAG,kBAAkB,IAAI,CAAA;AAC1E,EAAA,MAAM,WAAA,GAAcA,GAAAA,CAAG,qBAAA,CAAsB,OAAO,CAAA;AAEpD,EAAA,MAAM,SAAgC,EAAC;AACvC,EAAA,MAAM,WAAkC,EAAC;AAEzC,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAE9B,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,IAAA,CAAK,aAAa,eAAA,EAAiB;AAEzD,IAAA,IAAI,CAAC,KAAK,IAAA,EAAM;AAEhB,IAAA,MAAM,QAAA,GAAWA,IAAG,6BAAA,CAA8B,IAAA,CAAK,MAAM,IAAA,CAAK,KAAA,IAAS,CAAC,CAAA,CAAE,IAAA;AAC9E,IAAA,IAAI,WAAW,UAAA,EAAY;AAE3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,GACjBA,GAAAA,CAAG,6BAAA,CAA8B,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,KAAA,IAAS,CAAC,CAAA,CAAE,IAAA,GAAO,CAAA,GACpE,CAAA;AAEJ,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,UAAU,UAAU,CAAA;AAC7C,IAAA,MAAM,OAAA,GAAUA,GAAAA,CAAG,4BAAA,CAA6B,IAAA,CAAK,aAAa,IAAI,CAAA;AACtE,IAAA,MAAM,QAAQ,IAAA,CAAK,IAAA;AAMnB,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,MAAM,IAAI,CAAA;AAC7C,IAAA,MAAM,UAAA,GACJ,OAAA,IAAW,CAAA,IAAK,OAAA,IAAW,WAAA,CAAY,MAAA,GACnC,WAAA,CAAY,OAAA,GAAU,CAAC,CAAA,EAAG,IAAA,EAAK,IAAK,EAAA,GACpC,EAAA;AAEN,IAAA,MAAM,KAAA,GAA6B;AAAA,MACjC,IAAA,EAAM,KAAA;AAAA,MACN,IAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAA,EAAK,WAAA,CAAY,KAAA,EAAO,OAAA,EAAS,UAAU;AAAA,KAC7C;AAEA,IAAA,IAAI,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,MAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,IACnB,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,QAAQ,QAAA,EAAS;AAC5B;ACxnBA,IAAI,cAAA,GAAgC,IAAA;AAEpC,eAAe,SAAA,GAA6B;AAC1C,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,cAAA,GAAiB,IAAI,MAAA,EAAO;AAG5B,IAAA,MAAM,QAAA,GAAW,MAAM,OAAO,2BAA2B,CAAA;AACzD,IAAA,cAAA,CAAe,YAAA,CAAa,6BAA6B,QAAyB,CAAA;AAGlF,IAAA,MAAM,gBAAA,GAAmB,MAAM,OAAO,2BAA2B,CAAA;AACjE,IAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,OAAA,EAAS,KAAA,IAAS,gBAAA,CAAiB,KAAA;AACvE,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,MAAA,cAAA,CAAe,UAAA,CAAW,CAAA,YAAA,EAAe,IAAI,CAAA,CAAA,EAAI,IAAuB,CAAA;AAAA,IAC1E;AAGA,IAAA,MAAM,WAAA,GAAc,MAAM,OAAO,qBAAqB,CAAA;AACtD,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,OAAA,EAAS,KAAA,IAAS,WAAA,CAAY,KAAA;AAC7D,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,MAAA,cAAA,CAAe,UAAA,CAAW,CAAA,MAAA,EAAS,IAAI,CAAA,CAAA,EAAI,IAAuB,CAAA;AAAA,IACpE;AAAA,EACF;AACA,EAAA,OAAO,cAAA;AACT;AAMA,eAAsB,eAAe,IAAA,EAA8C;AACjF,EAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAAU;AAE/B,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAA8B;AAAA,MAClC,MAAA,EAAQ,2BAAA;AAAA,MACR,aAAA,EAAe;AAAA,QACb,WAAA,EAAa,IAAA;AAAA,QACb,UAAA,EAAY,QAAA;AAAA,QACZ,YAAA,EAAc,EAAE,GAAA,EAAK,IAAA;AAAK,OAC5B;AAAA,MACA,KAAA,EAAO;AAAA,QACL,4BAAA,EAA8B,CAAA;AAAA,QAC9B,6BAAA,EAA+B,CAAA;AAAA;AAAA,QAE/B,oBAAA,EAAsB,CAAA;AAAA;AAAA,QACtB,eAAA,EAAiB,CAAA;AAAA;AAAA,QACjB,gCAAA,EAAkC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQlC,gBAAA,EAAkB,CAAC,CAAA,EAAG;AAAA,UACpB,IAAA,EAAM,KAAA;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,kBAAA,EAAoB,IAAA;AAAA,UACpB,iBAAA,EAAmB,IAAA;AAAA,UACnB,YAAA,EAAc;AAAA,SACf;AAAA,OACH;AAAA,MACA,QAAA,EAAU;AAAA,QACR,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA;AAAO;AAC3B,KACF;AACA,IAAA,QAAA,GAAW,OAAO,MAAA,CAAO,IAAA,EAAM,QAAQ,EAAE,QAAA,EAAU,iBAAiB,CAAA;AAAA,EACtE,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,cAAqC,EAAC;AAK5C,EAAA,MAAM,cAAA,GAAiB,CAAC,EAAA,KACtB,EAAA,CAAG,UAAA,CAAW,cAAc,CAAA,IAC5B,EAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,IACtB,EAAA,KAAO,gBAAA;AAET,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAE1B,IAAA,IAAI,CAAC,IAAI,MAAA,EAAQ;AACjB,IAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,MAAM,CAAA,EAAG;AAEjC,IAAA,WAAA,CAAY,IAAA,CAAK;AAAA,MACf,MAAM,GAAA,CAAI,MAAA;AAAA,MACV,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,GAAA,EAAK,gBAAA,CAAiB,GAAA,CAAI,MAAA,EAAQ,IAAI,OAAO,CAAA;AAAA,MAC7C,QAAA,EAAU,eAAA,CAAgB,GAAA,EAAK,IAAI;AAAA,KACpC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,WAAA;AACT;AAwBA,SAAS,eAAA,CACP,KACA,IAAA,EACqB;AACrB,EAAA,MAAM,IAAA,GAA4B,GAAA,CAAI,QAAA,KAAa,CAAA,GAAI,OAAA,GAAU,SAAA;AACjE,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,gBAAA,IAAoB,IAAA,KAAS,SAAS,OAAO,IAAA;AAChE,EAAA,MAAM,OAAO,GAAA,CAAI,OAAA,CAAQ,KAAA,CAAM,WAAW,IAAI,CAAC,CAAA;AAC/C,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,SAAA;AAG/B,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AAMvD,EAAA,MAAM,WAAW,IAAI,MAAA;AAAA,IACnB,eAAe,IAAI,CAAA,+CAAA;AAAA,GACrB;AACA,EAAA,MAAM,iBAAiB,IAAI,MAAA;AAAA,IACzB,4BAA4B,IAAI,CAAA,4DAAA;AAAA,GAClC;AACA,EAAA,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA,IAAK,eAAe,IAAA,CAAK,IAAI,IAClD,OAAA,GACA,SAAA;AACN;AAEA,SAAS,gBAAA,CAAiB,QAAgB,OAAA,EAAyB;AACjE,EAAA,IAAI,WAAW,4BAAA,EAA8B;AAC3C,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,sBAAsB,CAAA,EAAG;AAC5C,MAAA,OAAO,4IAAA;AAAA,IACT;AACA,IAAA,OAAO,6JAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAW,6BAAA,EAA+B;AAC5C,IAAA,OAAO,mGAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA;AACrC,IAAA,MAAM,IAAA,GAAO,KAAA,GAAQ,CAAC,CAAA,IAAK,WAAA;AAC3B,IAAA,OAAO,IAAI,IAAI,CAAA,4EAAA,CAAA;AAAA,EACjB;AACA,EAAA,IAAI,WAAW,eAAA,EAAiB;AAC9B,IAAA,OAAO,+EAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAW,gCAAA,EAAkC;AAC/C,IAAA,OAAO,iFAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAW,gBAAA,EAAkB;AAG/B,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,WAAW,CAAA;AACvC,IAAA,MAAM,IAAA,GAAO,KAAA,GAAQ,CAAC,CAAA,IAAK,UAAA;AAI3B,IAAA,MAAM,mBAAA,GAAsB,0DAAA,CAA2D,IAAA,CAAK,OAAO,CAAA;AACnG,IAAA,IAAI,mBAAA,IAAuB,4CAAA,CAA6C,IAAA,CAAK,IAAI,CAAA,EAAG;AAClF,MAAA,OAAO,IAAI,IAAI,CAAA,0WAAA,CAAA;AAAA,IACjB;AACA,IAAA,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA,wHAAA,EAA2H,IAAI,CAAA,mCAAA,CAAA;AAAA,EAChJ;AACA,EAAA,OAAO,0BAAA;AACT;AC7LO,SAAS,oBAAoB,IAAA,EAA6B;AAC/D,EAAA,MAAM,QAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,CAAC,MAAM,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,UAAU,CAAA,EAAG;AAE3D,IAAA,IAAI,KAAA,CAAM,YAAY,MAAA,EAAW;AAC/B,MAAA,KAAA,CAAM,IAAI,IAAI,KAAA,CAAM,OAAA;AACpB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,YAAY,MAAA,EAAW;AAC/B,MAAA,KAAA,CAAM,IAAI,IAAI,KAAA,CAAM,OAAA;AACpB,MAAA;AAAA,IACF;AAGA,IAAA,KAAA,CAAM,IAAI,CAAA,GAAI,oBAAA,CAAqB,KAAA,CAAM,MAAM,CAAA;AAAA,EACjD;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,qBAAqB,MAAA,EAAiH;AAC7I,EAAA,QAAQ,OAAO,IAAA;AAAM,IACnB,KAAK,QAAA;AAAU,MAAA,OAAO,QAAA;AAAA,IACtB,KAAK,QAAA;AAAU,MAAA,OAAO,CAAA;AAAA,IACtB,KAAK,SAAA;AAAW,MAAA,OAAO,KAAA;AAAA,IACvB,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,aAAa,MAAA,CAAO,KAAA;AAC1B,MAAA,IAAI,YAAY,OAAO,CAAC,oBAAA,CAAqB,UAAU,KAAK,IAAI,CAAA;AAChE,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,MAAkB,EAAC;AACzB,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AACtD,UAAA,GAAA,CAAI,CAAC,CAAA,GAAI,oBAAA,CAAqB,CAAsB,CAAA;AAAA,QACtD;AAAA,MACF;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,IACA;AAAS,MAAA,OAAO,MAAA;AAAA;AAEpB;AASA,IAAM,iBAAA,GAAoB,IAAA;AAQ1B,IAAM,oBAAoB,GAAA,GAAM,IAAA;AAOhC,IAAM,mBAAA,GAAsB,GAAA;AAqB5B,SAAS,kBAAA,GAA0D;AAKjE,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,IAAI,GAAA,CAAI,0BAAA,EAA4B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAAA,IACnD,IAAI,GAAA,CAAI,iCAAA,EAAmC,MAAA,CAAA,IAAA,CAAY,GAAG;AAAA,GAC5D;AACA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,IAAI,GAAA,CAAI,0BAAA,EAA4B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAAA,IACnD,IAAI,GAAA,CAAI,iCAAA,EAAmC,MAAA,CAAA,IAAA,CAAY,GAAG;AAAA,GAC5D;AACA,EAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,IAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,IAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AACtB,MAAA,OAAO,EAAE,OAAA,EAAS,OAAA,CAAQ,UAAU,IAAA,EAAM,CAAC,MAAM,CAAA,EAAE;AAAA,IACrD;AAAA,EACF;AACA,EAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,IAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,IAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAItB,MAAA,MAAM,QAAA,GAAWE,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC9C,MAAA,MAAM,YAAY,aAAA,CAAc,QAAA,CAAS,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAE,IAAA;AACzD,MAAA,OAAO;AAAA,QACL,SAAS,OAAA,CAAQ,QAAA;AAAA,QACjB,IAAA,EAAM,CAAC,UAAA,EAAY,SAAA,EAAW,MAAM;AAAA,OACtC;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,YAAA,EAAc,GAAG,YAAY,CAAA,CAC5C,GAAA,CAAI,CAAC,MAAM,aAAA,CAAc,CAAC,CAAC,CAAA,CAC3B,KAAK,IAAI,CAAA;AACZ,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,6CAA6C,KAAK,CAAA,yBAAA;AAAA,GACpD;AACF;AAEA,eAAsB,SAAA,CACpB,YAAA,EACA,UAAA,EACA,WAAA,EACwB;AAOxB,EAAA,MAAM,UAAU,IAAA,CAAK,SAAA,CAAU,EAAE,UAAA,EAAY,aAAa,CAAA;AAC1D,EAAA,MAAM,QAAQ,kBAAA,EAAmB;AAEjC,EAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa;AAAA,IAChC,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,SAAA,EAAW,iBAAA;AAAA,IACX,cAAA,EAAgB,iBAAA;AAAA,IAChB,UAAA,EAAY,mBAAA;AAAA,IACZ,KAAA,EAAO,OAAA;AAAA;AAAA;AAAA;AAAA,IAIP,GAAA,EAAK;AAAA,MACH,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY;AAAA;AACpC,GACD,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,YAAY,SAAA,EAAW;AAChC,IAAA,OAAO,mDAAmD,iBAAiB,CAAA,+CAAA,CAAA;AAAA,EAC7E;AACA,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,iBAAA,IAAqB,MAAA,CAAO,YAAY,iBAAA,EAAmB;AAChF,IAAA,OAAO,CAAA,gDAAA,EAAmD,OAAO,OAAO,CAAA,mDAAA,CAAA;AAAA,EAC1E;AACA,EAAA,IAAI,MAAA,CAAO,YAAY,UAAA,EAAY;AACjC,IAAA,OAAO,0DAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,CAAO,YAAY,aAAA,EAAe;AACpC,IAAA,OAAO,CAAA,4CAAA,EAA0C,OAAO,YAAY,CAAA,CAAA;AAAA,EACtE;AACA,EAAA,IAAI,MAAA,CAAO,YAAY,MAAA,EAAQ;AAC7B,IAAA,OAAO,CAAA,0CAAA,EAA6C,OAAO,OAAO,CAAA,EAAA,CAAA;AAAA,EACpE;AAGA,EAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,IAAA,MAAM,OAAO,MAAA,CAAO,MAAA,CAAO,MAAK,IAAK,MAAA,CAAO,OAAO,IAAA,EAAK;AACxD,IAAA,OAAO,CAAA,4BAAA,EAA+B,OAAO,QAAQ,CAAA,EAAG,OAAO,CAAA,QAAA,EAAM,IAAI,KAAK,EAAE,CAAA,CAAA;AAAA,EAClF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,IAAA,EAAK;AAClC,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,0DAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,EAC7B,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO,iDACL,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CACjD,CAAA,CAAA;AAAA,EACF;AAEA,EAAA,OAAO,OAAA,CAAQ,EAAA,GAAK,IAAA,GAAO,OAAA,CAAQ,KAAA;AACrC;;;ACrLO,SAAS,oBAAA,CAAqB,OAAA,GAAiC,EAAC,EAAqB;AAC1F,EAAA,MAAM,KAAA,GAA0B;AAAA;AAAA,IAE9B;AAAA,MACE,IAAA,EAAM,gBAAA;AAAA,MACN,WAAA,EACE,yLAAA;AAAA,MACF,WAAA,EAAaC,CAAAA,CAAE,MAAA,CAAO,EAAE,CAAA;AAAA,MACxB,SAAS,aAAkC;AAAA,QACzC,SAAS,CAAC,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,0BAA0B;AAAA,OAC5D;AAAA,KACF;AAAA;AAAA,IAGA;AAAA,MACE,IAAA,EAAM,mBAAA;AAAA,MACN,WAAA,EACE,4IAAA;AAAA,MACF,WAAA,EAAaA,CAAAA,CAAE,MAAA,CAAO,EAAE,CAAA;AAAA,MACxB,SAAS,aAAkC;AAAA,QACzC,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM,QAAQ,aAAA,GACV,CAAA;;AAAA,EAAgC,QAAQ,aAAa;;AAAA,iFAAA,CAAA,GACrD;AAAA,SACL;AAAA,OACH;AAAA,KACF;AAAA;AAAA,IAGA;AAAA,MACE,IAAA,EAAM,oBAAA;AAAA,MACN,WAAA,EACE,sHAAA;AAAA,MACF,WAAA,EAAaA,CAAAA,CAAE,MAAA,CAAO,EAAE,CAAA;AAAA,MACxB,SAAS,aAAkC;AAAA,QACzC,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM,QAAQ,gBAAA,IAAoB;AAAA,SACnC;AAAA,OACH;AAAA,KACF;AAAA;AAAA,IAGA;AAAA,MACE,IAAA,EAAM,oBAAA;AAAA,MACN,WAAA,EACE,uIAAA;AAAA,MACF,WAAA,EAAaA,EAAE,MAAA,CAAO;AAAA,QACpB,IAAA,EAAMA,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,+CAA+C;AAAA,OAC1E,CAAA;AAAA,MACD,OAAA,EAAS,OAAO,IAAA,KAA8B;AAC5C,QAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,IAAA,CAAK,IAAc,CAAA;AAC5D,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM,gCAAgC,MAAM;AAAA;AAC9C,WACF;AAAA,UACA,OAAA,EAAS,CAAC,MAAA,CAAO;AAAA,SACnB;AAAA,MACF;AAAA,KACF;AAAA;AAAA,IAGA;AAAA,MACE,IAAA,EAAM,YAAA;AAAA,MACN,WAAA,EACE,gPAAA;AAAA,MACF,WAAA,EAAaA,EAAE,MAAA,CAAO;AAAA,QACpB,IAAA,EAAMA,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,4CAA4C;AAAA,OACvE,CAAA;AAAA,MACD,OAAA,EAAS,OAAO,IAAA,KAA8B;AAC5C,QAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,QAAA,MAAM,EAAE,QAAQ,YAAA,EAAa,GAAI,MAAM,aAAA,CAAc,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAG3E,QAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,UAAA,MAAM,cAAA,GAAiB,oBAAA,CAAqB,IAAA,EAAM,OAAA,CAAQ,QAAQ,CAAA;AAClE,UAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,YAAA,MAAA,CAAO,IAAA,CAAK;AAAA,cACV,KAAA,EAAO,CAAA,SAAA,EAAY,EAAA,CAAG,KAAK,CAAA,CAAA;AAAA,cAC3B,IAAA,EAAM,CAAA;AAAA,cACN,SAAS,CAAA,CAAA,EAAI,EAAA,CAAG,QAAQ,CAAA,EAAA,EAAK,GAAG,OAAO,CAAA,CAAA;AAAA,cACvC,KAAK,EAAA,CAAG;AAAA,aACT,CAAA;AAAA,UACH;AAAA,QACF;AAEA,QAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,UAAA,MAAM,WAAA,GAAc,YAAA,CAAa,MAAA,GAAS,CAAA,GACtC;;AAAA;AAAA,EAAsC,YAAA,CAAa,IAAI,CAAA,CAAA,KAAK,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,GAAO,CAAA,KAAA,EAAQ,CAAA,CAAE,IAAI,CAAA,EAAA,CAAA,GAAO,EAAE,GAAG,CAAA,CAAE,OAAO,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtI,EAAA;AACJ,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,CAAA,oCAAA,EAAuC,WAAW,CAAA,CAAA,EAAI;AAAA,WACxF;AAAA,QACF;AAEA,QAAA,MAAM,SAAS,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,GAAO,QAAQ,CAAA,CAAE,IAAI,OAAO,EAAE,CAAA,EAAG,EAAE,OAAO;AAAA,OAAA,EAAY,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA,CAAE,KAAK,MAAM,CAAA;AAC7H,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,CAAA,EAAG,OAAO,MAAM,CAAA;;AAAA,EAAuB,MAAM,IAAI,CAAA;AAAA,UACjF,OAAA,EAAS;AAAA,SACX;AAAA,MACF;AAAA,KACF;AAAA;AAAA,IAGA;AAAA,MACE,IAAA,EAAM,mBAAA;AAAA,MACN,WAAA,EACE,0MAAA;AAAA,MACF,WAAA,EAAaA,EAAE,MAAA,CAAO;AAAA,QACpB,IAAA,EAAMA,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,8CAA8C,CAAA;AAAA,QACxE,QAAA,EAAUA,EACP,MAAA,EAAO,CACP,QAAQ,eAAe,CAAA,CACvB,SAAS,6BAA6B;AAAA,OAC1C,CAAA;AAAA,MACD,OAAA,EAAS,OAAO,IAAA,KAA8B;AAC5C,QAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,QAAA,MAAM,QAAA,GAAY,KAAK,QAAA,IAAuB,eAAA;AAG9C,QAAA,MAAM,EAAE,QAAQ,eAAA,EAAgB,GAAI,MAAM,aAAA,CAAc,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAG9E,QAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,UAAA,MAAM,cAAA,GAAiB,oBAAA,CAAqB,IAAA,EAAM,OAAA,CAAQ,QAAQ,CAAA;AAClE,UAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,YAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,cACnB,KAAA,EAAO,CAAA,SAAA,EAAY,EAAA,CAAG,KAAK,CAAA,CAAA;AAAA,cAC3B,IAAA,EAAM,CAAA;AAAA,cACN,SAAS,CAAA,CAAA,EAAI,EAAA,CAAG,QAAQ,CAAA,EAAA,EAAK,GAAG,OAAO,CAAA,CAAA;AAAA,cACvC,KAAK,EAAA,CAAG;AAAA,aACT,CAAA;AAAA,UACH;AAAA,QACF;AAEA,QAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,UAAA,MAAM,SAAS,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,GAAO,QAAQ,CAAA,CAAE,IAAI,OAAO,EAAE,CAAA,EAAG,EAAE,OAAO;AAAA,OAAA,EAAY,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA,CAAE,KAAK,MAAM,CAAA;AACtI,UAAA,OAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,gBACnB,OAAA,EAAS,KAAA;AAAA,gBACT,KAAA,EAAO,YAAA;AAAA,gBACP,KAAA,EAAO,CAAA,EAAG,eAAA,CAAgB,MAAM,CAAA;;AAAA,EAAsD,MAAM,CAAA;AAAA,eAC9F,EAAG,MAAM,CAAC;AAAA,aACX,CAAA;AAAA,YACD,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAGA,QAAA,MAAM,UAAA,GAAa,0BAA0B,IAAI,CAAA;AACjD,QAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,UAAA,OAAO;AAAA,YACL,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,IAAA,EAAM,MAAA;AAAA,gBACN,MAAM,IAAA,CAAK,SAAA;AAAA,kBACT;AAAA,oBACE,OAAA,EAAS,KAAA;AAAA,oBACT,KAAA,EAAO,YAAA;AAAA,oBACP,KAAA,EAAO,gCAAgC,UAAU;AAAA,mBACnD;AAAA,kBACA,IAAA;AAAA,kBACA;AAAA;AACF;AACF,aACF;AAAA,YACA,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAEA,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,MAAcC,OAAA,CAAA,SAAA,CAAU,IAAA,EAAM;AAAA,YAC3C,MAAA,EAAQ,KAAA;AAAA,YACR,MAAA,EAAQ,QAAA;AAAA,YACR,MAAA,EAAQ,KAAA;AAAA,YACR,GAAA,EAAK,WAAA;AAAA,YACL,eAAA,EAAiB,OAAA;AAAA,YACjB,MAAA,EAAQ,IAAA;AAAA,YACR,UAAA,EAAY;AAAA,WACb,CAAA;AAED,UAAA,MAAM,QAAA,GAAW;AAAA,YACf,GAAG,MAAA,CAAO,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,YACpC,GAAG,WAAW,QAAA,CAAS,GAAA;AAAA,cACrB,CAAC,CAAA,KACC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,KAAK,CAAA,CAAE,OAAO,CAAA,EAAA,EAAK,CAAA,CAAE,UAAU,CAAA;AAAA;AAC7C,WACF;AAGA,UAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,YAAA,MAAM,cAAA,GAAiB,oBAAA,CAAqB,IAAA,EAAM,OAAA,CAAQ,QAAQ,CAAA;AAClE,YAAA,MAAM,SAAS,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,OAAO,CAAA;AAClE,YAAA,MAAM,mBAAmB,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,SAAS,CAAA;AAE9E,YAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,cAAA,MAAM,MAAA,GAAS,MAAA,CACZ,GAAA,CAAI,CAAC,CAAA,KAAM,MAAM,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO;AAAA,OAAA,EAAY,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA,CACzD,KAAK,IAAI,CAAA;AACZ,cAAA,OAAO;AAAA,gBACL,SAAS,CAAC;AAAA,kBACR,IAAA,EAAM,MAAA;AAAA,kBACN,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,oBACnB,OAAA,EAAS,KAAA;AAAA,oBACT,KAAA,EAAO,qBAAA;AAAA,oBACP,KAAA,EAAO,CAAA;;AAAA,EAAiE,MAAM;;AAAA,mEAAA;AAAA,mBAChF,EAAG,MAAM,CAAC;AAAA,iBACX,CAAA;AAAA,gBACD,OAAA,EAAS;AAAA,eACX;AAAA,YACF;AAEA,YAAA,QAAA,CAAS,IAAA,CAAK,GAAG,gBAAA,CAAiB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,UAAA,EAAa,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,EAAE,CAAC,CAAA;AAAA,UACpF;AAIA,UAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,WAAA,KACtB,OAAA,CAAQ,QAAA,EAAU,YAAY,mBAAA,CAAoB,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,GAAI,KAAA,CAAA,CAAA;AACtF,UAAA,MAAM,cAAc,MAAM,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,MAAM,WAAW,CAAA;AAClE,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,OAAO;AAAA,cACL,SAAS,CAAC;AAAA,gBACR,IAAA,EAAM,MAAA;AAAA,gBACN,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,kBACnB,OAAA,EAAS,KAAA;AAAA,kBACT,KAAA,EAAO,mBAAA;AAAA,kBACP,cAAc,MAAA,CAAO,IAAA;AAAA,kBACrB,KAAA,EAAO,GAAG,WAAW;;AAAA,2FAAA,CAAA;AAAA,kBACrB;AAAA,iBACF,EAAG,MAAM,CAAC;AAAA,eACX,CAAA;AAAA,cACD,OAAA,EAAS;AAAA,aACX;AAAA,UACF;AAEA,UAAA,OAAO;AAAA,YACL,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,IAAA,EAAM,MAAA;AAAA,gBACN,MAAM,IAAA,CAAK,SAAA;AAAA,kBACT;AAAA,oBACE,OAAA,EAAS,IAAA;AAAA,oBACT,cAAc,MAAA,CAAO,IAAA;AAAA,oBACrB;AAAA,mBACF;AAAA,kBACA,IAAA;AAAA,kBACA;AAAA;AACF;AACF;AACF,WACF;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,OAAO;AAAA,YACL,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,IAAA,EAAM,MAAA;AAAA,gBACN,MAAM,IAAA,CAAK,SAAA;AAAA,kBACT,EAAE,SAAS,KAAA,EAAO,KAAA,EAAO,eAAe,KAAA,EAAO,kBAAA,CAAmB,KAAA,EAAO,IAAI,CAAA,EAAE;AAAA,kBAC/E,IAAA;AAAA,kBACA;AAAA;AACF;AACF,aACF;AAAA,YACA,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAAA,MACF;AAAA;AACF,GACF;AAEA,EAAA,OAAO,KAAA;AACT;AAKA,SAAS,kBAAA,CAAmB,OAAgB,UAAA,EAA4B;AACtE,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,IACE,KAAA,IACA,OAAO,KAAA,KAAU,QAAA,IACjB,QAAA,IAAY,SACZ,KAAA,CAAM,OAAA,CAAS,KAAA,CAAgC,MAAM,CAAA,EACrD;AACA,IAAA,MAAM,YAAA,GAAe,KAAA;AACrB,IAAA,KAAA,MAAW,GAAA,IAAO,aAAa,MAAA,EAAQ;AACrC,MAAA,MAAM,IAAA,GAAO,IAAI,QAAA,EAAU,IAAA;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAI,QAAA,EAAU,MAAA;AAC1B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AACnC,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,KAAA,CAAM,KAAK,CAAA,mBAAA,EAAsB,IAAI,CAAA,SAAA,EAAY,GAAA,IAAO,CAAC,CAAA,CAAE,CAAA;AAC3D,QAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA;AACnC,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAC,CAAA;AAClC,QAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,MAAA,EAAQ,OAAO,CAAC,CAAA;AAC3C,QAAA,MAAM,OAAA,GAAU,MACb,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA,CAChB,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACb,UAAA,MAAM,EAAA,GAAK,QAAQ,CAAA,GAAI,CAAA;AACvB,UAAA,OAAO,CAAA,EAAG,OAAO,IAAA,GAAO,MAAA,GAAS,MAAM,CAAA,EAAG,EAAE,MAAM,CAAC,CAAA,CAAA;AAAA,QACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACZ,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA;AAAA;AAAA,EAAsB,OAAO;AAAA,MAAA,CAAU,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,KAAA,CAAM,KAAK,CAAA,WAAA,EAAc,KAAA,YAAiB,QAAQ,KAAA,CAAM,OAAA,GAAU,oBAAoB,CAAA,CAAE,CAAA;AAAA,EAC1F;AAEA,EAAA,KAAA,CAAM,KAAK,4FAA4F,CAAA;AACvG,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAkBA,IAAM,qCAAqB,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,UAAA,EAAY,QAAQ,CAAC,CAAA;AAOlE,SAAS,gBAAgB,IAAA,EAAgC;AACvD,EAAA,MAAM,EAAA,GAAKJ,GAAAA,CAAG,gBAAA,CAAiB,eAAA,EAAiB,IAAA,EAAMA,GAAAA,CAAG,YAAA,CAAa,MAAA,EAAQ,IAAA,EAAMA,GAAAA,CAAG,UAAA,CAAW,GAAG,CAAA;AACrG,EAAA,MAAM,SAA2B,EAAC;AAElC,EAAA,SAAS,MAAM,IAAA,EAAqB;AAClC,IAAA,IAAIA,IAAG,uBAAA,CAAwB,IAAI,KAAKA,GAAAA,CAAG,mBAAA,CAAoB,IAAI,CAAA,EAAG;AACpE,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA;AACvC,MAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,OAAO,CAAA,EAAG;AACnC,QAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,QAAA,IAAI,SAAA,GAAY,KAAA;AAChB,QAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,UAAA,CAAW,UAAA,EAAY;AAC7C,UAAA,IAAIA,GAAAA,CAAG,cAAA,CAAe,IAAI,CAAA,EAAG;AAC3B,YAAA,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAC,CAAA;AAAA,UACrC,CAAA,MAAA,IAAWA,GAAAA,CAAG,oBAAA,CAAqB,IAAI,CAAA,EAAG;AACxC,YAAA,SAAA,GAAY,IAAA;AAAA,UACd;AAAA,QACF;AACA,QAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA,IAAK,CAAC,SAAA,CAAU,GAAA,CAAI,YAAY,CAAA,EAAG;AACzE,UAAA,MAAM,IAAA,GAAO,GAAG,6BAAA,CAA8B,IAAA,CAAK,SAAS,EAAE,CAAC,EAAE,IAAA,GAAO,CAAA;AACxE,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,KAAA,EAAO,eAAA;AAAA,YACP,IAAA;AAAA,YACA,OAAA,EAAS,GAAG,OAAO,CAAA,mBAAA,CAAA;AAAA,YACnB,GAAA,EAAK,wCAAwC,OAAO,CAAA,uDAAA;AAAA,WACrD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,IAAAA,GAAAA,CAAG,YAAA,CAAa,IAAA,EAAM,KAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,KAAA,CAAM,EAAE,CAAA;AACR,EAAA,OAAO,MAAA;AACT;AAUA,eAAsB,aAAA,CACpB,MACA,QAAA,EACuE;AACvE,EAAA,MAAM,SAA2B,EAAC;AAClC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAI7B,EAAA,MAAM,wBAAwB,IAAI,GAAA;AAAA,IAChC,OAAO,IAAA,CAAK,QAAA,EAAU,kBAAA,EAAoB,OAAA,IAAW,EAAE;AAAA,GACzD;AAEA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,UAAU,CAAA,GAAI,CAAA;AAGpB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,qBAAqB,CAAA;AACjD,IAAA,IAAI,QAAA,IAAY,CAAC,IAAA,CAAK,QAAA,CAAS,aAAa,KAAK,CAAC,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,EAAG;AAC9E,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,WAAA;AAAA,QACP,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,CAAA,iBAAA,EAAoB,QAAA,CAAS,CAAC,CAAC,CAAA,+BAAA,CAAA;AAAA,QACxC,GAAA,EAAK,CAAA,iCAAA,EAAoC,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA;AAAA,OACrD,CAAA;AAAA,IACH;AAGA,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAA;AACtD,IAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC9G,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,oBAAA;AAAA,QACP,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,CAAA,UAAA,EAAa,YAAA,CAAa,CAAC,CAAC,CAAA,mCAAA,CAAA;AAAA,QACrC,GAAA,EAAK,CAAA,qHAAA;AAAA,OACN,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,gCAAgC,IAAA,CAAK,IAAI,KAAK,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AAC1E,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,iBAAA;AAAA,QACP,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,CAAA,mFAAA,CAAA;AAAA,QACT,GAAA,EAAK,CAAA,0EAAA;AAAA,OACN,CAAA;AAAA,IACH;AACA,IAAA,IAAI,gCAAA,CAAiC,IAAA,CAAK,IAAI,CAAA,IAAK,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,IAAK,CAAC,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AACnG,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,iBAAA;AAAA,QACP,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,CAAA,oFAAA,CAAA;AAAA,QACT,GAAA,EAAK,CAAA,8EAAA;AAAA,OACN,CAAA;AAAA,IACH;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,sDAAsD,CAAA;AACjF,IAAA,IAAI,OAAA,IAAW,CAAC,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,EAAG;AAC5C,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,YAAA;AAAA,QACP,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,CAAA,wDAAA,CAAA;AAAA,QACT,GAAA,EAAK,CAAA,4CAAA;AAAA,OACN,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,SAAS,OAAA,EAAS,qBAAA,EAAuB,GAAA,EAAK,6BAAA,EAA+B,CAAA;AAAA,IACtH;AACA,IAAA,IAAI,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA,EAAG;AAC7B,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,SAAS,OAAA,EAAS,gDAAA,EAA6C,GAAA,EAAK,wCAAA,EAA0C,CAAA;AAAA,IACvJ;AAGA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,oCAAoC,CAAA;AACnE,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,GAAA,GAAM,YAAY,CAAC,CAAA;AAKzB,MAAA,IAAI,CAAC,eAAA,CAAgB,GAAA,EAAK,qBAAqB,CAAA,EAAG;AAChD,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,KAAA,EAAO,QAAA;AAAA,UACP,IAAA,EAAM,OAAA;AAAA,UACN,OAAA,EAAS,gBAAgB,GAAG,CAAA,gBAAA,CAAA;AAAA,UAC5B,GAAA,EAAK,CAAA,kBAAA,EAAqB,sBAAA,EAAwB,CAAA;AAAA,SACnD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EAGF;AAIA,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAY,gBAAgB,IAAI,CAAA;AACtC,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,SAAS,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AAGA,EAAA,IAAI,CAAC,KAAK,QAAA,CAAS,iBAAiB,KAAK,CAAC,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AACrE,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,iBAAA;AAAA,MACP,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,0DAAA;AAAA,MACT,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,yBAAyB,CAAA,EAAG;AAC7C,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,QAAA;AAAA,MACP,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,iCAAA;AAAA,MACT,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,eAAiC,EAAC;AAGxC,EAAA,MAAM,CAAC,UAAA,EAAY,WAAW,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAClD,SAAA,CAAU,IAAI,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAC7B,MAAA,OAAA,CAAQ,IAAA,CAAK,uCAAuC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AACpG,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,IACD,cAAA,CAAe,IAAI,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAClC,MAAA,OAAA,CAAQ,IAAA,CAAK,wCAAwC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AACrG,MAAA,OAAO,EAAC;AAAA,IACV,CAAC;AAAA,GACF,CAAA;AAGD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,KAAA,MAAW,KAAA,IAAS,WAAW,MAAA,EAAQ;AACrC,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,CAAA,EAAA,EAAK,KAAA,CAAM,IAAI,CAAA,CAAA;AAAA,QACtB,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,KAAK,KAAA,CAAM;AAAA,OACZ,CAAA;AAAA,IACH;AACA,IAAA,KAAA,MAAW,OAAA,IAAW,WAAW,QAAA,EAAU;AACzC,MAAA,YAAA,CAAa,IAAA,CAAK;AAAA,QAChB,KAAA,EAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAI,CAAA,CAAA;AAAA,QACxB,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,SAAS,OAAA,CAAQ,OAAA;AAAA,QACjB,KAAK,OAAA,CAAQ;AAAA,OACd,CAAA;AAAA,IACH;AAAA,EACF;AAaA,EAAA,MAAM,cAAA,GAAiB,+BAAA,CAAgC,IAAA,CAAK,IAAI,CAAA;AAChE,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAAqD;AAC7E,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,6BAAA,EAA+B,OAAO,KAAA;AACxD,IAAA,IAAI,CAAC,gBAAgB,OAAO,KAAA;AAK5B,IAAA,OAAO,uGAAA,CAAwG,IAAA;AAAA,MAC7G,IAAA,CAAK;AAAA,KACP;AAAA,EACF,CAAA;AAEA,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,KAAa,OAAA,IAAW,iBAAiB,IAAI,CAAA;AACnE,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,OAAO,IAAA,CAAK,IAAA;AAAA,QACZ,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAA,EAAS,iBAAiB,IAAI,CAAA,GAC1B,GAAG,IAAA,CAAK,OAAO,wGACf,IAAA,CAAK,OAAA;AAAA,QACT,KAAK,IAAA,CAAK;AAAA,OACX,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,YAAA,CAAa,IAAA,CAAK;AAAA,QAChB,OAAO,IAAA,CAAK,IAAA;AAAA,QACZ,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,KAAK,IAAA,CAAK;AAAA,OACX,CAAA;AAAA,IACH;AAAA,EACF;AAMA,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA8B;AAClD,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,KAAK,EAAC;AACrC,IAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACX,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAA,EAAM,IAAI,CAAA;AAAA,EAC1B;AAEA,EAAA,MAAM,UAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,GAAG,KAAK,CAAA,IAAK,OAAA,EAAS;AAC/B,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACrB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,KAAA,CAAM,UAAA,CAAW,IAAI,CAAC,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA;AACrE,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,OAAO,CAAA;AAC9C,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,MAAA,MAAM,QAAA,GAAW,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA,CAAE,KAAK,IAAI,CAAA;AACnD,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,GAAG,OAAA;AAAA,QACH,OAAA,EAAS,CAAA,EAAG,OAAA,CAAQ,OAAO,sBAAsB,QAAQ,CAAA,CAAA;AAAA,OAC1D,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IACtB;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,YAAA,EAAa;AACzC;;;AXroBA,gBAAA,EAAA;AAKA,QAAA,EAAA;AACA,QAAA,EAAA;AACAb,SAAAA,EAAAA;AACAE,SAAAA,EAAAA;AACAF,SAAAA,EAAAA;AACAE,SAAAA,EAAAA","file":"index.js","sourcesContent":["// packages/ui-gen/src/adapters/base.ts\n//\n// Abstract base class for all generator adapters.\n\nimport type { McpServerConfig, AgentDefinition } from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from './types';\n\n/**\n * Core configuration shared by all adapters.\n */\nexport interface AdapterConfig {\n /** API key for the provider (BYOK) */\n apiKey?: string;\n /** Use Bedrock instead of direct API (Claude only) */\n useBedrock?: boolean;\n /**\n * Thinking level for models with extended thinking (Gemini 3.x Flash\n * via the Interactions API). Mirrors the API's `thinking_level` enum —\n * `'minimal'` is the floor (the API has NO true off), then `'low'` /\n * `'medium'` / `'high'`. Omitted → provider default, and Gemini 3.5\n * Flash defaults thinking ON with no cap — the dominant latency cost\n * in contract-bounded UI generation. Only the Google adapter consumes\n * this today.\n */\n thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';\n}\n\n/**\n * Extended configuration for Claude Agent SDK adapter.\n * Separated from AdapterConfig to avoid polluting the base interface\n * with provider-specific concerns.\n */\nexport interface ClaudeSdkConfig extends AdapterConfig {\n /** Working directory for SDK subprocess */\n cwd?: string;\n /** Environment variables for SDK subprocess */\n env?: Record<string, string>;\n /** MCP server configs for Claude Agent SDK (keyed by name) */\n mcpServers?: Record<string, McpServerConfig>;\n /** Allowed tool names for Claude Agent SDK */\n allowedTools?: string[];\n /** Subagent definitions for Claude Agent SDK */\n agents?: Record<string, AgentDefinition>;\n /** Custom CLI path for Docker deployments */\n cliPath?: string;\n /** stderr callback for debug logging */\n stderr?: (data: string) => void;\n /** Progress callback */\n onProgress?: (event: { type: string; [key: string]: unknown }) => void;\n}\n\n/**\n * Union config type — adapters accept their specific config\n * but the registry uses this union so callers can pass any config.\n */\nexport type AnyAdapterConfig = AdapterConfig | ClaudeSdkConfig;\n\n/**\n * Parameters for a single generation run.\n */\nexport interface GenerateParams {\n /** System prompt (HOW to build — shared across all SDKs) */\n systemPrompt: string;\n /** User prompt (WHAT to build — the specific request) */\n userPrompt: string;\n /** Model identifier (provider-native format, e.g., 'claude-sonnet-4-6') */\n model: string;\n /** SDK-agnostic tool definitions */\n tools: ToolDefinition[];\n /** Maximum agentic loop turns */\n maxTurns: number;\n /** Model-specific options (e.g., speed_priority for Claude fast mode) */\n modelOptions?: JsonObject;\n}\n\n/**\n * Abstract base class for generator adapters.\n *\n * Each adapter wraps a specific provider SDK (Claude, OpenAI, Google)\n * in either raw API mode or agent SDK mode, and implements the tool-use\n * loop using the SDK's native API. All adapters produce the same\n * output format (AdapterResult).\n */\nexport abstract class GeneratorAdapter {\n abstract readonly provider: ProviderName;\n abstract readonly mode: AdapterMode;\n abstract readonly displayName: string;\n\n constructor(protected readonly config: AnyAdapterConfig) {}\n\n /**\n * Run UI generation with the given tools, prompt, and model.\n */\n abstract generate(params: GenerateParams): Promise<AdapterResult>;\n\n /**\n * Check if this adapter can run (SDK installed, credentials available).\n */\n abstract isAvailable(): boolean;\n\n /**\n * Map a LiteLLM-format model ID to this SDK's native format.\n * Default: strips the provider prefix (e.g., 'anthropic/claude-sonnet-4-6' -> 'claude-sonnet-4-6').\n * Override only if the prefix convention differs.\n */\n resolveModelId(litellmModelId: string): string {\n return stripModelPrefix(litellmModelId);\n }\n}\n\n/**\n * Strip provider prefix from LiteLLM-format model IDs.\n * 'anthropic/claude-sonnet-4-6' -> 'claude-sonnet-4-6'\n * 'openai/gpt-5.3-codex' -> 'gpt-5.3-codex'\n * 'gemini/gemini-3-flash-preview' -> 'gemini-3-flash-preview'\n */\nfunction stripModelPrefix(modelId: string): string {\n const slashIndex = modelId.indexOf('/');\n return slashIndex >= 0 ? modelId.slice(slashIndex + 1) : modelId;\n}\n\n/**\n * Check if credentials are available from config or environment variables.\n */\nexport function hasCredentials(\n config: AdapterConfig,\n ...envVarNames: string[]\n): boolean {\n if (config.apiKey) return true;\n if (config.useBedrock) return true;\n return envVarNames.some((name) => !!process.env[name]);\n}\n","// packages/ui-gen/src/adapters/tool-bridge.ts\n//\n// Bridges between SDK tool wire formats and ggui's JSON types:\n// Zod → JSON Schema for tool declarations, and validated narrowing of\n// decoded tool-call arguments to `JsonObject`.\n\nimport { z } from 'zod';\nimport type { JsonObject, JsonValue } from '@ggui-ai/protocol';\n\n/**\n * Convert a Zod object schema to JSON Schema.\n * Uses Zod v4's built-in toJSONSchema() function.\n */\nexport function zodToJsonSchema(schema: z.ZodType): JsonObject {\n return z.toJSONSchema(schema) as JsonObject;\n}\n\n/**\n * Validate that a decoded tool-call `arguments` object is plain JSON data\n * and narrow it to {@link JsonObject}. Provider SDKs type tool-call\n * arguments as `{ [key: string]: unknown }`; values decoded from a JSON\n * wire payload are JSON by construction, so a failure here means the SDK\n * handed us something that never came from JSON — a bug worth surfacing,\n * not erasing with a cast.\n */\nexport function toolArgsToJsonObject(args: { [key: string]: unknown }): JsonObject {\n const out: JsonObject = {};\n for (const [key, value] of Object.entries(args)) {\n // `JsonObject` keys admit `undefined` (TS optional properties);\n // JSON.stringify omits them, so pass-through is JSON-safe.\n out[key] = value === undefined ? undefined : toJsonValue(value, key);\n }\n return out;\n}\n\nfunction toJsonValue(value: unknown, path: string): JsonValue {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item, i) => toJsonValue(item, `${path}[${i}]`));\n }\n if (typeof value === 'object') {\n const out: JsonObject = {};\n for (const [key, entry] of Object.entries(value)) {\n out[key] = entry === undefined ? undefined : toJsonValue(entry, `${path}.${key}`);\n }\n return out;\n }\n throw new Error(\n `Tool-call arguments contain a non-JSON value at '${path}' (${typeof value})`,\n );\n}\n","// packages/ui-gen/src/adapters/extract-code.ts\n//\n// Shared helpers for extracting artifacts from tool call results\n// and LLM text output. Used by all adapters to avoid duplication.\n\nimport * as esbuild from 'esbuild';\nimport type { ToolDefinition, ToolResult } from './types';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/**\n * Mutable state bag passed through the agentic loop.\n * Each adapter creates one of these and passes it to the\n * extraction helpers on every tool call and text output.\n */\nexport interface CodeCapture {\n compiledCode: string;\n sourceCode: string | undefined;\n stream: JsonObject | undefined;\n generatorMeta: { category: string; description: string } | undefined;\n}\n\nexport function createCapture(): CodeCapture {\n return { compiledCode: '', sourceCode: undefined, stream: undefined, generatorMeta: undefined };\n}\n\n/**\n * Before calling a tool handler: capture source code if this is\n * a compile_component call.\n */\nexport function captureSourceCode(\n capture: CodeCapture,\n toolName: string,\n args: JsonObject,\n): void {\n if (toolName === 'compile_component' && typeof args.code === 'string') {\n capture.sourceCode = args.code;\n }\n}\n\n/**\n * After a tool handler returns: extract compiled code if this was\n * a successful compile_component call.\n */\nexport function captureCompiledCode(\n capture: CodeCapture,\n toolName: string,\n result: ToolResult,\n): void {\n if (toolName !== 'compile_component' || result.isError) return;\n\n try {\n const parsed = JSON.parse(result.content[0].text);\n if (parsed.success && parsed.compiledCode) {\n capture.compiledCode = parsed.compiledCode;\n }\n } catch {\n // Not parseable — ignore\n }\n}\n\n/**\n * Scan text output for __GGUI_STREAM_SPEC__ and __GGUI_META__ markers.\n * Called on each text block in assistant messages (raw adapters)\n * or on the full message stream (SDK adapters via message-parser).\n */\nexport function captureMarkers(capture: CodeCapture, text: string): void {\n if (!capture.stream && text.includes('__GGUI_STREAM_SPEC__')) {\n const match = text.match(/__GGUI_STREAM_SPEC__\\s*([\\s\\S]*?)\\s*__GGUI_STREAM_SPEC_END__/);\n if (match) {\n try {\n capture.stream = JSON.parse(\n match[1].replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\'),\n );\n } catch { /* ignore */ }\n }\n }\n\n if (!capture.generatorMeta && text.includes('__GGUI_META__')) {\n const match = text.match(/__GGUI_META__\\s*([\\s\\S]*?)\\s*__GGUI_META_END__/);\n if (match) {\n try {\n const stripped = match[1].replace(/```(?:json)?\\s*/g, '').trim();\n const raw = stripped.replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\');\n const parsed = JSON.parse(raw) as { category?: string; description?: string };\n if (parsed.category) {\n capture.generatorMeta = { category: parsed.category, description: parsed.description ?? '' };\n }\n } catch { /* ignore */ }\n }\n }\n}\n\n/**\n * Fallback: try to extract code from a text output (used by OpenAI SDK\n * adapter when the model writes code as text instead of calling tools).\n */\nexport async function extractCodeFromText(\n finalOutput: string,\n tools: ToolDefinition[],\n capture: CodeCapture,\n): Promise<void> {\n if (finalOutput.length <= 100) return;\n\n const codeMatch =\n finalOutput.match(/```(?:tsx?|jsx?|typescript|javascript)?\\s*\\n([\\s\\S]*?)```/) ??\n finalOutput.match(/```\\s*\\n([\\s\\S]*?)```/);\n let code = codeMatch ? codeMatch[1].trim() : '';\n\n if (!code && (finalOutput.includes('export default') || finalOutput.includes('export function'))) {\n code = finalOutput;\n }\n\n if (!code || !(code.includes('export default') || code.includes('export function'))) {\n return;\n }\n\n capture.sourceCode = code;\n const compileTool = tools.find((t) => t.name === 'compile_component');\n if (!compileTool) return;\n\n const compileResult = await compileTool.handler({ code, filename: 'Component.tsx' });\n if (compileResult.isError) {\n console.warn('[extractCodeFromText] compile_component failed:', compileResult.content[0]?.text?.slice(0, 300));\n }\n captureCompiledCode(capture, 'compile_component', compileResult);\n}\n\n/**\n * Last-resort compilation: bypass self-checks and compile directly with esbuild.\n *\n * Used when compile_component kept rejecting code due to self-check violations\n * (hex colors, raw pixels, forbidden imports, etc.) but the model DID produce\n * source code. Getting imperfect compiled code is better than getting nothing.\n *\n * Also tries text output as a source if sourceCode is empty.\n */\nexport async function compileLastResort(\n capture: CodeCapture,\n allTextOutput?: string,\n): Promise<void> {\n if (capture.compiledCode) return; // Already have compiled code\n\n // Try capture.sourceCode first (from compile_component calls that failed self-checks)\n let code = capture.sourceCode;\n\n // Fallback: extract from text output\n if (!code && allTextOutput && allTextOutput.length > 100) {\n const codeMatch =\n allTextOutput.match(/```(?:tsx?|jsx?|typescript|javascript)?\\s*\\n([\\s\\S]*?)```/) ??\n allTextOutput.match(/```\\s*\\n([\\s\\S]*?)```/);\n code = codeMatch ? codeMatch[1].trim() : undefined;\n\n if (!code && (allTextOutput.includes('export default') || allTextOutput.includes('export function'))) {\n code = allTextOutput;\n }\n }\n\n if (!code || !(code.includes('export default') || code.includes('export function'))) {\n return;\n }\n\n try {\n const result = await esbuild.transform(code, {\n loader: 'tsx',\n target: 'es2020',\n format: 'esm',\n jsx: 'automatic',\n jsxImportSource: 'react',\n minify: true,\n sourcefile: 'Component.tsx',\n });\n\n capture.compiledCode = result.code;\n capture.sourceCode = code;\n console.warn('[compileLastResort] Compiled code bypassing self-checks — may have quality issues');\n } catch (err) {\n console.warn('[compileLastResort] esbuild failed:', err instanceof Error ? err.message : String(err));\n }\n}\n","// packages/ui-gen/src/adapters/claude/client.ts\n//\n// SINGLE SOURCE OF TRUTH for Anthropic SDK construction.\n//\n// The BYOK resolver writes the raw credential string into\n// `process.env.ANTHROPIC_API_KEY`, which the Anthropic SDK auto-reads as\n// `x-api-key`. Adapters MUST go through `createAnthropicClient` (no\n// inline `new Anthropic(...)`) so future header / baseURL tweaks land\n// in one place.\n\nimport Anthropic from '@anthropic-ai/sdk';\n\n/**\n * Construct an Anthropic SDK client from a raw API key string.\n *\n * - `string` → standard `apiKey` path (sends `x-api-key`).\n * - `undefined` → still construct a client; SDK auto-reads\n * `process.env.ANTHROPIC_API_KEY` or throws on first call.\n *\n * **SINGLE SOURCE OF TRUTH for Anthropic client construction.** Every\n * adapter that constructs an Anthropic client MUST go through this\n * helper — no inline `new Anthropic(...)` allowed in adapter code.\n */\nexport function createAnthropicClient(\n rawKey: string | undefined,\n): Anthropic {\n if (rawKey === undefined) {\n return new Anthropic({\n baseURL: 'https://api.anthropic.com',\n });\n }\n return new Anthropic({\n apiKey: rawKey,\n baseURL: 'https://api.anthropic.com',\n });\n}\n","// packages/ui-gen/src/adapters/claude/raw.ts\n//\n// Claude adapter using the raw Anthropic SDK (@anthropic-ai/sdk).\n// Manual tool-use loop: messages.create() -> tool_use -> handler -> repeat.\n//\n// SDK client construction is centralized in `./client.ts`. Do NOT\n// inline `new Anthropic(...)` here.\n\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport { createAnthropicClient } from './client';\n\nexport class ClaudeRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'claude';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'Claude (Raw API)';\n\n private client: Anthropic | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'ANTHROPIC_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n // Bedrock path: SDK reads AWS creds from the env / role chain;\n // skip the `apiKey` set entirely — `createAnthropicClient(undefined)`\n // gives us a constructed client and the SDK does the rest.\n if (this.config.useBedrock) {\n this.client = createAnthropicClient(undefined);\n } else {\n const rawKey = this.config.apiKey || process.env.ANTHROPIC_API_KEY;\n this.client = createAnthropicClient(rawKey);\n }\n }\n\n const anthropicTools = params.tools.map(toAnthropicTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n\n const messages: Anthropic.MessageParam[] = [\n { role: 'user', content: params.userPrompt },\n ];\n\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n const response = await this.client.messages.create({\n model: params.model,\n max_tokens: 16384,\n system: params.systemPrompt,\n messages,\n tools: anthropicTools,\n });\n\n totalInputTokens += response.usage.input_tokens;\n totalOutputTokens += response.usage.output_tokens;\n\n const toolUseBlocks = response.content.filter(\n (block): block is Anthropic.ToolUseBlock => block.type === 'tool_use',\n );\n\n // Scan text blocks for streamSpec/generatorMeta markers\n for (const block of response.content) {\n if (block.type === 'text') captureMarkers(capture, block.text);\n }\n\n if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn') {\n break;\n }\n\n messages.push({\n role: 'assistant',\n content: response.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: block.text };\n }\n return {\n type: 'tool_use' as const,\n id: (block as Anthropic.ToolUseBlock).id,\n name: (block as Anthropic.ToolUseBlock).name,\n input: (block as Anthropic.ToolUseBlock).input,\n };\n }),\n });\n\n const toolResults: Anthropic.ToolResultBlockParam[] = [];\n\n for (const toolBlock of toolUseBlocks) {\n const toolDef = params.tools.find((t) => t.name === toolBlock.name);\n if (!toolDef) {\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolBlock.id,\n content: `Tool '${toolBlock.name}' not found`,\n is_error: true,\n });\n continue;\n }\n\n const args = (toolBlock.input as JsonObject) ?? {};\n captureSourceCode(capture, toolBlock.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, toolBlock.name, result);\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolBlock.id,\n content: result.content.map((c) => ({ type: 'text' as const, text: c.text })),\n is_error: result.isError,\n });\n }\n\n messages.push({ role: 'user', content: toolResults });\n }\n\n if (!capture.compiledCode) {\n throw new Error('Claude raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\nfunction toAnthropicTool(def: ToolDefinition): Anthropic.Tool {\n return {\n name: def.name,\n description: def.description,\n input_schema: zodToJsonSchema(def.inputSchema) as Anthropic.Tool.InputSchema,\n };\n}\n","// packages/ui-gen/src/adapters/claude/message-parser.ts\n//\n// Focused helpers for extracting artifacts from Claude Agent SDK messages.\n// Each function handles one extraction concern, keeping the main loop clean.\n//\n// Uses proper discriminated union narrowing on SDKMessage variants.\n\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKResultMessage,\n SDKSystemMessage,\n SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/**\n * Mutable accumulator for artifacts extracted from the SDK message stream.\n */\nexport interface MessageArtifacts {\n compiledCode: string;\n sourceCode: string | undefined;\n stream: JsonObject | undefined;\n generatorMeta: { category: string; description: string } | undefined;\n sdkSessionId: string | undefined;\n turnCount: number;\n inputTokens: number;\n outputTokens: number;\n cacheCreationTokens: number;\n cacheReadTokens: number;\n estimatedCostUsd: number | undefined;\n subagentsUsed: string[];\n}\n\nexport function createArtifacts(): MessageArtifacts {\n return {\n compiledCode: '',\n sourceCode: undefined,\n stream: undefined,\n generatorMeta: undefined,\n sdkSessionId: undefined,\n turnCount: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationTokens: 0,\n cacheReadTokens: 0,\n estimatedCostUsd: undefined,\n subagentsUsed: [],\n };\n}\n\n/** Progress event emitted during generation. */\nexport type ProgressEvent = { type: string; [key: string]: string | number | boolean | undefined };\n\n/**\n * Process a single SDK message and update artifacts accordingly.\n */\nexport function processMessage(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n maxTurns?: number,\n): void {\n extractSessionId(message, artifacts);\n trackTurns(message, artifacts, onProgress, maxTurns);\n trackTokenUsage(message, artifacts);\n extractCompiledCode(message, artifacts, onProgress);\n extractSourceCode(message, artifacts);\n extractStreamSpec(message, artifacts);\n extractGeneratorMeta(message, artifacts);\n}\n\n// ── Individual extractors ────────────────────────────────────────────\n\nfunction extractSessionId(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'system') return;\n const systemMsg = message as SDKSystemMessage;\n if (systemMsg.subtype === 'init') {\n artifacts.sdkSessionId = systemMsg.session_id;\n }\n}\n\nfunction trackTurns(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n maxTurns?: number,\n): void {\n if (message.type !== 'assistant') return;\n const assistantMsg = message as SDKAssistantMessage;\n artifacts.turnCount++;\n\n const contentBlocks = assistantMsg.message?.content;\n if (Array.isArray(contentBlocks)) {\n for (const block of contentBlocks) {\n if (block.type === 'tool_use') {\n onProgress?.({ type: 'tool_call', tool: block.name || 'unknown' });\n }\n }\n }\n onProgress?.({ type: 'turn', turn: artifacts.turnCount, maxTurns: maxTurns ?? 0 });\n}\n\nfunction trackTokenUsage(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'result') return;\n const resultMsg = message as SDKResultMessage;\n\n if (resultMsg.subtype === 'success') {\n const usage = resultMsg.usage;\n artifacts.inputTokens = usage.input_tokens || 0;\n artifacts.cacheCreationTokens = usage.cache_creation_input_tokens || 0;\n artifacts.cacheReadTokens = usage.cache_read_input_tokens || 0;\n artifacts.outputTokens = usage.output_tokens || 0;\n artifacts.estimatedCostUsd = resultMsg.total_cost_usd;\n }\n}\n\nfunction extractCompiledCode(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n): void {\n if (artifacts.compiledCode) return; // Already found\n\n const msgStr = JSON.stringify(message);\n if (!msgStr.includes('compiledCode')) return;\n\n // Strategy 1: regex extraction from anywhere in the message\n const match = msgStr.match(/\"compiledCode\"\\s*:\\s*\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"/);\n if (match) {\n try {\n artifacts.compiledCode = JSON.parse(`\"${match[1]}\"`);\n onProgress?.({ type: 'compiled', bytes: artifacts.compiledCode.length });\n return;\n } catch {\n // Fall through to structured extraction\n }\n }\n\n // Strategy 2: structured extraction from tool_result content\n if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n const code = extractFromToolResults(userMsg);\n if (code) artifacts.compiledCode = code;\n }\n}\n\n/**\n * Walk the nested tool_result structures to find compiledCode.\n */\nfunction extractFromToolResults(message: SDKUserMessage): string | undefined {\n const content = message.message?.content;\n if (!Array.isArray(content)) return undefined;\n\n for (const item of content) {\n if (typeof item === 'object' && item !== null && 'type' in item && item.type === 'tool_result') {\n const toolResultItem = item as { type: 'tool_result'; content?: unknown };\n const code = parseCompiledCodeFromContent(toolResultItem.content);\n if (code) return code;\n }\n }\n\n return undefined;\n}\n\nfunction parseCompiledCodeFromContent(content: unknown): string | undefined {\n if (Array.isArray(content)) {\n for (const item of content) {\n const textItem = item as { type?: string; text?: string };\n if (textItem.type === 'text' && textItem.text?.includes('compiledCode')) {\n const code = tryParseCompiledCode(textItem.text);\n if (code) return code;\n }\n }\n }\n if (typeof content === 'string' && content.includes('compiledCode')) {\n return tryParseCompiledCode(content);\n }\n return undefined;\n}\n\nfunction tryParseCompiledCode(text: string): string | undefined {\n try {\n const parsed = JSON.parse(text);\n if (parsed.success && parsed.compiledCode) return parsed.compiledCode;\n } catch {\n // Not valid JSON\n }\n return undefined;\n}\n\nfunction extractSourceCode(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'assistant') return;\n const assistantMsg = message as SDKAssistantMessage;\n\n const content = assistantMsg.message?.content;\n if (!Array.isArray(content)) return;\n\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'Write') {\n const input = block.input as { content?: string } | undefined;\n if (input?.content) {\n artifacts.sourceCode = input.content;\n }\n }\n }\n}\n\n/**\n * Unescape a JSON string that was double-escaped inside another JSON string.\n */\nfunction unescapeJsonString(s: string): string {\n return s.replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\');\n}\n\n/**\n * Extract a delimited marker from a JSON-stringified message.\n * Returns the raw content between START and END markers, or undefined.\n */\nfunction extractMarker(msgStr: string, startMarker: string, endMarker: string): string | undefined {\n if (!msgStr.includes(startMarker)) return undefined;\n const match = msgStr.match(new RegExp(`${startMarker}\\\\s*([\\\\s\\\\S]*?)\\\\s*${endMarker}`));\n return match?.[1];\n}\n\nfunction extractStreamSpec(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (artifacts.stream) return;\n\n const raw = extractMarker(JSON.stringify(message), '__GGUI_STREAM_SPEC__', '__GGUI_STREAM_SPEC_END__');\n if (!raw) return;\n\n try {\n artifacts.stream = JSON.parse(unescapeJsonString(raw));\n } catch {\n // Failed to parse\n }\n}\n\nfunction extractGeneratorMeta(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (artifacts.generatorMeta) return;\n\n const raw = extractMarker(JSON.stringify(message), '__GGUI_META__', '__GGUI_META_END__');\n if (!raw) return;\n\n try {\n const stripped = raw.replace(/```(?:json)?\\s*/g, '').trim();\n const parsed = JSON.parse(unescapeJsonString(stripped)) as { category?: string; description?: string };\n if (parsed.category) {\n artifacts.generatorMeta = {\n category: parsed.category,\n description: parsed.description ?? '',\n };\n }\n } catch {\n // Failed to parse\n }\n}\n","// packages/ui-gen/src/adapters/claude/tool-bridge.ts\n//\n// Bridges ToolDefinition[] → in-process MCP server for Claude Agent SDK.\n//\n// The Claude Agent SDK doesn't support direct function-tool definitions.\n// All custom tools must go through MCP servers. This bridge creates an\n// in-process MCP server from our generic ToolDefinition[] using the SDK's\n// built-in tool() + createSdkMcpServer() helpers.\n//\n// Tool naming convention: mcp__{serverName}__{toolName}\n// e.g., mcp__ggui__compile_component\n\nimport type { ToolDefinition } from '../types';\nimport type { McpSdkServerConfigWithInstance } from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/** Name used for the in-process MCP server. */\nexport const MCP_SERVER_NAME = 'ggui';\n\n/**\n * Create an in-process MCP server from ToolDefinition[] using\n * the Claude Agent SDK's tool() + createSdkMcpServer() helpers.\n *\n * Returns the MCP server instance and the list of allowedTools names\n * (in mcp__{server}__{tool} format).\n */\nexport async function createToolMcpServer(\n tools: ToolDefinition[],\n): Promise<{\n server: McpSdkServerConfigWithInstance;\n allowedToolNames: string[];\n}> {\n const { tool, createSdkMcpServer } = await import('@anthropic-ai/claude-agent-sdk');\n\n const mcpTools = tools.map((def) => {\n // Extract Zod shape from the input schema\n const shape = def.inputSchema.shape ?? {};\n\n return tool(\n def.name,\n def.description,\n shape,\n async (args: JsonObject) => {\n const result = await def.handler(args);\n return {\n content: result.content.map((c) => ({\n type: 'text' as const,\n text: c.text,\n })),\n ...(result.isError && { isError: true }),\n };\n },\n );\n });\n\n const server = createSdkMcpServer({\n name: MCP_SERVER_NAME,\n version: '1.0.0',\n tools: mcpTools,\n });\n\n const allowedToolNames = tools.map((t) => `mcp__${MCP_SERVER_NAME}__${t.name}`);\n\n return { server, allowedToolNames };\n}\n\n/**\n * Filter tool names for a specific phase (e.g., context-only or build-only).\n * Takes the original tool names (without MCP prefix) and returns\n * MCP-formatted names.\n */\nexport function filterMcpToolNames(\n originalNames: string[],\n): string[] {\n return originalNames.map((name) => `mcp__${MCP_SERVER_NAME}__${name}`);\n}\n","// packages/ui-gen/src/adapters/claude/sdk.ts\n//\n// Claude adapter using the Claude Agent SDK (@anthropic-ai/claude-agent-sdk).\n// Uses query() async iterator with MCP servers for tool execution.\n//\n// Two modes:\n// 1. Pre-configured MCP servers (production) — pass mcpServers in ClaudeSdkConfig\n// 2. Direct tools (benchmark) — ToolDefinition[] auto-bridged to in-process MCP server\n\nimport type { McpServerConfig } from '@anthropic-ai/claude-agent-sdk';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { ClaudeSdkConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport { createArtifacts, processMessage } from './message-parser';\nimport { createToolMcpServer } from './tool-bridge';\n\nexport class ClaudeSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'claude';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'Claude (Agent SDK)';\n\n constructor(config: ClaudeSdkConfig = {}) {\n super(config);\n }\n\n /** Narrowed config access for Claude SDK-specific fields. */\n private get sdkConfig(): ClaudeSdkConfig {\n return this.config as ClaudeSdkConfig;\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'ANTHROPIC_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n const cfg = this.sdkConfig;\n\n // Dynamic import to avoid loading claude-agent-sdk in non-Claude contexts\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n\n // Build environment from config or process.env\n const env = buildEnv(cfg.env);\n\n const artifacts = createArtifacts();\n const onProgress = cfg.onProgress;\n\n // Determine MCP servers — use config's servers or bridge from tools\n let mcpServers: Record<string, McpServerConfig> | undefined = cfg.mcpServers;\n let allowedTools: string[] | undefined = cfg.allowedTools;\n\n if (!mcpServers && params.tools.length > 0) {\n // Bridge ToolDefinition[] to in-process MCP server\n const bridge = await createToolMcpServer(params.tools);\n mcpServers = { ggui: bridge.server };\n allowedTools = bridge.allowedToolNames;\n }\n\n // Run SDK query — message parsing is handled by processMessage()\n for await (const message of query({\n prompt: params.userPrompt,\n options: {\n cwd: cfg.cwd,\n env,\n model: params.model,\n maxTurns: params.maxTurns,\n systemPrompt: params.systemPrompt,\n ...(mcpServers && { mcpServers }),\n ...(cfg.agents && { agents: cfg.agents }),\n ...(allowedTools && { allowedTools }),\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n ...(cfg.cliPath && { pathToClaudeCodeExecutable: cfg.cliPath }),\n ...(cfg.stderr && { stderr: cfg.stderr }),\n },\n })) {\n processMessage(\n message,\n artifacts,\n onProgress,\n params.maxTurns,\n );\n }\n\n const generationTimeMs = Date.now() - startTime;\n\n // Cache audit telemetry. Track whether the Claude Agent SDK is\n // actually caching the system prompt\n // across turns. `read > 0` on turn 2+ means the SDK's internal\n // cache_control is firing. `read = 0` across all turns = we're\n // paying full input cost every turn; explicit cache_control needed.\n const totalCacheIn = artifacts.inputTokens + artifacts.cacheCreationTokens + artifacts.cacheReadTokens;\n const cacheReadPct = totalCacheIn > 0\n ? Math.round((artifacts.cacheReadTokens / totalCacheIn) * 100)\n : 0;\n console.log(\n `[claude-sdk] cache: created=${artifacts.cacheCreationTokens} read=${artifacts.cacheReadTokens} input=${artifacts.inputTokens} output=${artifacts.outputTokens} turns=${artifacts.turnCount} cache-read-pct=${cacheReadPct}%`,\n );\n\n if (!artifacts.compiledCode) {\n const wasExhausted = artifacts.turnCount >= params.maxTurns;\n throw new Error(\n wasExhausted\n ? `Generation used all ${params.maxTurns} turns without producing compiled code.`\n : 'Generation completed without compiled code',\n );\n }\n\n return {\n compiledCode: artifacts.compiledCode,\n sourceCode: artifacts.sourceCode,\n tokens: {\n input: artifacts.inputTokens,\n output: artifacts.outputTokens,\n total:\n artifacts.inputTokens +\n artifacts.cacheCreationTokens +\n artifacts.cacheReadTokens +\n artifacts.outputTokens,\n },\n generationTimeMs,\n turnsUsed: artifacts.turnCount,\n rawCostUsd: artifacts.estimatedCostUsd,\n stream: artifacts.stream,\n generatorMeta: artifacts.generatorMeta,\n subagentsUsed: artifacts.subagentsUsed,\n cacheCreationTokens: artifacts.cacheCreationTokens,\n cacheReadTokens: artifacts.cacheReadTokens,\n sdkSessionId: artifacts.sdkSessionId,\n };\n }\n}\n\nfunction buildEnv(configEnv?: Record<string, string>): Record<string, string> {\n if (configEnv) return sanitizeEnv({ ...configEnv });\n\n const env: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined) env[key] = value;\n }\n return sanitizeEnv(env);\n}\n\n/**\n * Remove env vars that would redirect the SDK subprocess to a non-running proxy.\n * The SDK subprocess must connect to the real Anthropic API.\n */\nfunction sanitizeEnv(env: Record<string, string>): Record<string, string> {\n // Strip ANTHROPIC_BASE_URL if it points to localhost (LiteLLM proxy)\n // — the SDK subprocess should always use the real Anthropic API\n if (env.ANTHROPIC_BASE_URL?.includes('localhost')) {\n delete env.ANTHROPIC_BASE_URL;\n }\n return env;\n}\n","// packages/ui-gen/src/adapters/openai/raw.ts\n//\n// OpenAI adapter using the raw OpenAI SDK (openai).\n// Uses the Responses API (responses.create) with previous_response_id\n// for multi-turn tool-calling loops.\n\nimport type OpenAI from 'openai';\nimport type { Responses } from 'openai/resources/responses/responses';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n compileLastResort,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/** Lazy-load the OpenAI SDK to avoid top-level import crashes in Lambda bundles. */\nasync function loadOpenAI(): Promise<typeof import('openai')> {\n return import('openai');\n}\n\nexport class OpenAiRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openai';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'OpenAI (Raw API)';\n\n private client: OpenAI | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENAI_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n const { default: OpenAIClient } = await loadOpenAI();\n this.client = new OpenAIClient({\n apiKey: this.config.apiKey || process.env.OPENAI_API_KEY,\n });\n }\n\n const tools = params.tools.map(toResponsesTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n let allTextOutput = '';\n\n // First request — user prompt + instructions\n let response: Responses.Response = await this.client.responses.create({\n model: params.model,\n instructions: params.systemPrompt,\n input: [{ role: 'user', content: params.userPrompt }],\n tools,\n store: true, // Required for previous_response_id to work on subsequent turns\n });\n\n // Agentic loop\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n // Track tokens\n if (response.usage) {\n totalInputTokens += response.usage.input_tokens ?? 0;\n totalOutputTokens += response.usage.output_tokens ?? 0;\n }\n\n // Process output items\n const output = response.output ?? [];\n const functionCalls = output.filter(\n (item): item is Responses.ResponseFunctionToolCall => item.type === 'function_call',\n );\n\n // Collect text output for markers and code extraction fallback\n for (const item of output) {\n if (item.type === 'message' && 'content' in item && item.content) {\n for (const part of item.content) {\n if (part.type === 'output_text' && part.text) {\n allTextOutput += part.text + '\\n';\n captureMarkers(capture, part.text);\n }\n }\n }\n }\n\n if (functionCalls.length === 0) break;\n\n // Only send function_call_output items — previous_response_id carries context\n const nextInput: Responses.ResponseInputItem.FunctionCallOutput[] = [];\n\n for (const fc of functionCalls) {\n const toolDef = params.tools.find((t) => t.name === fc.name);\n if (!toolDef) {\n nextInput.push({\n type: 'function_call_output',\n call_id: fc.call_id,\n output: JSON.stringify({ error: `Tool '${fc.name}' not found` }),\n });\n continue;\n }\n\n let args: JsonObject = {};\n try { args = JSON.parse(fc.arguments || '{}') as JsonObject; } catch { /* empty */ }\n\n captureSourceCode(capture, fc.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, fc.name, result);\n\n nextInput.push({\n type: 'function_call_output',\n call_id: fc.call_id,\n output: result.content[0]?.text ?? '',\n });\n }\n\n // Next turn — use previous_response_id for context continuity\n response = await this.client.responses.create({\n model: params.model,\n instructions: params.systemPrompt,\n input: nextInput,\n tools,\n previous_response_id: response.id,\n store: true,\n });\n }\n\n // Fallback: extract code from text output if no tool produced compiled code\n if (!capture.compiledCode && allTextOutput) {\n captureMarkers(capture, allTextOutput);\n await extractCodeFromText(allTextOutput, params.tools, capture);\n }\n\n // Last resort: compile sourceCode directly with esbuild, bypassing self-checks\n if (!capture.compiledCode) {\n await compileLastResort(capture, allTextOutput);\n }\n\n if (!capture.compiledCode) {\n throw new Error('OpenAI raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\n/**\n * Convert a ToolDefinition to OpenAI Responses API FunctionTool format.\n */\nfunction toResponsesTool(def: ToolDefinition): { type: 'function'; name: string; description: string; parameters: JsonObject; strict: boolean } {\n return {\n type: 'function',\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema) as JsonObject,\n strict: false,\n };\n}\n","// packages/ui-gen/src/adapters/openai/sdk.ts\n//\n// OpenAI adapter using @openai/agents SDK.\n// Creates an Agent with function tools and runs it via run().\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\nasync function loadOpenAIAgents() {\n return import('@openai/agents');\n}\n\nexport class OpenAiSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openai';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'OpenAI (Agents SDK)';\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENAI_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n const apiKey = this.config.apiKey || process.env.OPENAI_API_KEY;\n if (apiKey) process.env.OPENAI_API_KEY = apiKey;\n\n const capture = createCapture();\n\n // Build tools that call our handlers and capture compile results\n const { Agent, run, tool } = await loadOpenAIAgents();\n\n const wiredTools = params.tools.map((def) =>\n tool({\n name: def.name,\n description: def.description,\n parameters: def.inputSchema,\n execute: async (args) => {\n const typedArgs = (args ?? {}) as JsonObject;\n captureSourceCode(capture, def.name, typedArgs);\n\n const result = await def.handler(typedArgs);\n captureCompiledCode(capture, def.name, result);\n\n return result.content[0]?.text ?? '';\n },\n }),\n );\n\n const agent = new Agent({\n name: 'ui-generator',\n instructions: params.systemPrompt,\n model: params.model,\n tools: wiredTools,\n });\n\n const result = await run(agent, params.userPrompt, {\n maxTurns: params.maxTurns,\n });\n\n const finalOutput = String(result.finalOutput ?? '');\n\n // Scan final output for streamSpec/generatorMeta markers\n if (finalOutput) captureMarkers(capture, finalOutput);\n\n // Fallback: extract code from text output if no tool call produced it\n if (!capture.compiledCode) {\n await extractCodeFromText(finalOutput, params.tools, capture);\n\n if (!capture.compiledCode) {\n throw new Error('OpenAI SDK adapter: no compiled code produced after all turns');\n }\n }\n const usage = result.state.usage;\n const inputTokens = usage.inputTokens;\n const outputTokens = usage.outputTokens;\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: inputTokens,\n output: outputTokens,\n total: inputTokens + outputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed: result.rawResponses?.length ?? 0,\n };\n }\n}\n","// packages/ui-gen/src/adapters/google/raw.ts\n//\n// Google adapter using the Interactions API (@google/genai >= 2.0.0,\n// 'steps' schema). Uses interactions.create() with\n// previous_interaction_id for server-side state management. System\n// prompt and tools sent on turn 1, subsequent turns only send\n// function_result steps — server remembers context.\n\nimport type { GoogleGenAI as GoogleGenAIType, Interactions } from '@google/genai';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema, toolArgsToJsonObject } from '../tool-bridge';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\n\nasync function loadGoogleGenAI() {\n return import('@google/genai');\n}\n\nexport class GoogleRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'google';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'Google Gemini (Interactions API)';\n\n private client: GoogleGenAIType | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'GEMINI_API_KEY', 'GOOGLE_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n const { GoogleGenAI } = await loadGoogleGenAI();\n this.client = new GoogleGenAI({\n apiKey: this.config.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY,\n httpOptions: { timeout: 300_000 }, // 5 min — Pro models can be slow\n });\n }\n\n const tools = params.tools.map(toInteractionTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n\n // Thinking control. Gemini 3.x Flash defaults thinking ON — the\n // dominant latency cost in UI generation, where the task is\n // contract-bounded code emission, not open-ended reasoning. The\n // Interactions API exposes this as `generation_config.thinking_level`\n // ('minimal' is the floor — there is no true off — then 'low' /\n // 'medium' / 'high'). When the caller pins a level we forward it on\n // every turn. Omitted → provider default (unchanged behavior).\n const thinkingLevel = this.config.thinkingLevel;\n const generationConfig = thinkingLevel\n ? { thinking_level: thinkingLevel }\n : undefined;\n\n // Turn 1: send system instruction + tools + user prompt\n let interaction = await this.client.interactions.create({\n model: params.model,\n system_instruction: params.systemPrompt,\n tools,\n input: params.userPrompt,\n ...(generationConfig ? { generation_config: generationConfig } : {}),\n });\n\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n // Track tokens\n if (interaction.usage) {\n totalInputTokens += interaction.usage.total_input_tokens ?? 0;\n totalOutputTokens += interaction.usage.total_output_tokens ?? 0;\n }\n\n // Scan model-output text for streamSpec/generatorMeta markers.\n // `steps` is a discriminated union — even at thinking_level\n // 'minimal' a `thought` step is present, so iterate by\n // discriminant and skip step types we don't consume.\n for (const step of interaction.steps) {\n if (step.type === 'model_output') {\n for (const content of step.content ?? []) {\n if (content.type === 'text') {\n captureMarkers(capture, content.text);\n }\n }\n }\n }\n\n // Collect function calls\n const functionCalls = interaction.steps.filter(\n (s): s is Interactions.FunctionCallStep => s.type === 'function_call',\n );\n\n if (functionCalls.length === 0) break;\n\n // Execute tools and build function_result inputs\n const results: Interactions.FunctionResultStep[] = [];\n\n for (const fc of functionCalls) {\n const toolDef = params.tools.find((t) => t.name === fc.name);\n if (!toolDef) {\n results.push({\n type: 'function_result',\n call_id: fc.id,\n name: fc.name,\n result: JSON.stringify({ error: `Tool '${fc.name}' not found` }),\n is_error: true,\n });\n continue;\n }\n\n const args = toolArgsToJsonObject(fc.arguments);\n captureSourceCode(capture, fc.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, fc.name, result);\n\n results.push({\n type: 'function_result',\n call_id: fc.id,\n name: fc.name,\n result: result.content[0]?.text ?? '',\n });\n }\n\n // Next turn: only send function results — server has the history\n interaction = await this.client.interactions.create({\n model: params.model,\n previous_interaction_id: interaction.id,\n input: results,\n ...(generationConfig ? { generation_config: generationConfig } : {}),\n });\n }\n\n if (!capture.compiledCode) {\n throw new Error('Google raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\n/** Convert ToolDefinition to Interactions API function tool format. */\nfunction toInteractionTool(def: ToolDefinition): Interactions.Function {\n return {\n type: 'function',\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema),\n };\n}\n","// packages/ui-gen/src/adapters/google/sdk.ts\n//\n// Google adapter using @google/adk (Agent Development Kit).\n// Uses LlmAgent + InMemoryRunner + FunctionTool for agent-managed tool execution.\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\nimport type { Content, Part } from '@google/genai';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport type { ToolInputParameters } from '@google/adk';\n\nexport class GoogleSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'google';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'Google Gemini (ADK)';\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'GEMINI_API_KEY', 'GOOGLE_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const apiKey = this.config.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;\n\n return runAdkLoop({\n systemPrompt: params.systemPrompt,\n userPrompt: params.userPrompt,\n model: params.model,\n tools: params.tools,\n apiKey,\n });\n }\n}\n\n// =============================================================================\n// Core agentic loop — Google ADK (LlmAgent + InMemoryRunner)\n// =============================================================================\n\nimport type { ToolDefinition } from '../types';\n\nexport interface AdkLoopParams {\n systemPrompt: string;\n userPrompt: string;\n model: string;\n tools: ToolDefinition[];\n apiKey?: string;\n}\n\n/**\n * Run a single agentic loop using Google ADK.\n *\n * Uses InMemoryRunner.runAsync() which returns an async iterator of events.\n * FunctionTool wraps our ToolDefinition handlers with capture logic.\n */\nexport async function runAdkLoop(\n params: AdkLoopParams,\n): Promise<AdapterResult> {\n const startTime = Date.now();\n\n const { FunctionTool, LlmAgent, InMemoryRunner, isFinalResponse } = await import('@google/adk');\n\n const capture = createCapture();\n\n // Ensure ADK can find the API key\n if (params.apiKey && !process.env.GOOGLE_GENAI_API_KEY) {\n process.env.GOOGLE_GENAI_API_KEY = params.apiKey;\n }\n\n // Build tools with capture wrappers\n const adkTools = params.tools.map((def) =>\n new FunctionTool({\n name: def.name,\n description: def.description,\n // Pass Zod schema directly — ADK accepts ZodObject natively\n parameters: def.inputSchema as ToolInputParameters,\n execute: async (args: unknown) => {\n const typedArgs = (args ?? {}) as JsonObject;\n captureSourceCode(capture, def.name, typedArgs);\n const result = await def.handler(typedArgs);\n captureCompiledCode(capture, def.name, result);\n return result.content[0]?.text ?? '';\n },\n }),\n );\n\n const agent = new LlmAgent({\n name: 'ui_generator',\n model: params.model,\n instruction: params.systemPrompt,\n tools: adkTools,\n });\n\n const runner = new InMemoryRunner({ agent, appName: 'ggui_generator' });\n const session = await runner.sessionService.createSession({\n appName: 'ggui_generator',\n userId: 'benchmark',\n });\n\n const userMessage: Content = {\n role: 'user',\n parts: [{ text: params.userPrompt }],\n };\n\n let finalText = '';\n let turnCount = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n\n for await (const event of runner.runAsync({\n userId: 'benchmark',\n sessionId: session.id,\n newMessage: userMessage,\n })) {\n turnCount++;\n\n // Extract token usage from event's underlying LLM response\n const usage = event.usageMetadata;\n if (usage) {\n totalInputTokens += usage.promptTokenCount ?? 0;\n totalOutputTokens += usage.candidatesTokenCount ?? 0;\n }\n\n // Scan every event's content for markers and code\n if (event.content?.parts) {\n const text = event.content.parts.map((p: Part) => p.text ?? '').join('');\n if (text) captureMarkers(capture, text);\n }\n\n if (isFinalResponse(event)) {\n const parts = event.content?.parts;\n finalText = parts?.map((p: Part) => p.text ?? '').join('') ?? '';\n }\n }\n\n // Final scan of accumulated text\n if (finalText) captureMarkers(capture, finalText);\n\n if (!capture.compiledCode) {\n throw new Error('Google ADK adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed: turnCount,\n };\n}\n","// packages/ui-gen/src/adapters/openrouter/types.ts\n//\n// OpenRouter-specific types for the chat completion API.\n// Reference: https://openrouter.ai/docs/api-reference\n\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n// =============================================================================\n// Model metadata (from GET /api/v1/models)\n// =============================================================================\n\n/** Model entry from OpenRouter's /api/v1/models endpoint */\nexport interface OpenRouterModelEntry {\n id: string;\n name: string;\n description: string;\n pricing: { prompt: string; completion: string; image?: string };\n context_length: number;\n architecture: {\n modality: string;\n tokenizer: string;\n instruct_type: string | null;\n };\n top_provider: {\n context_length: number;\n max_completion_tokens: number;\n is_moderated: boolean;\n };\n per_request_limits: Record<string, string> | null;\n}\n\n// =============================================================================\n// Chat Completion API\n// =============================================================================\n\nexport interface OpenRouterMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | OpenRouterContentBlock[] | null;\n tool_calls?: OpenRouterToolCall[];\n tool_call_id?: string;\n}\n\nexport interface OpenRouterContentBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' };\n}\n\nexport interface OpenRouterTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: JsonObject;\n };\n}\n\nexport interface OpenRouterToolCall {\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n}\n\nexport interface OpenRouterChatRequest {\n model: string;\n messages: OpenRouterMessage[];\n tools?: OpenRouterTool[];\n tool_choice?: 'auto' | 'required' | 'none';\n max_tokens?: number;\n temperature?: number;\n stream?: boolean;\n thinking?: { type: 'enabled'; budget_tokens: number };\n}\n\nexport interface OpenRouterChatResponse {\n id: string;\n model: string;\n choices: Array<{\n index: number;\n message: {\n role: 'assistant';\n content: string | null;\n tool_calls?: OpenRouterToolCall[];\n thinking?: string;\n };\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n// =============================================================================\n// SSE Streaming\n// =============================================================================\n\nexport interface OpenRouterStreamDelta {\n id: string;\n model: string;\n choices: Array<{\n index: number;\n delta: {\n role?: 'assistant';\n content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n type?: 'function';\n function?: { name?: string; arguments?: string };\n }>;\n };\n finish_reason: string | null;\n }>;\n usage?: OpenRouterChatResponse['usage'];\n}\n\n// =============================================================================\n// Error\n// =============================================================================\n\nexport class OpenRouterError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OpenRouterError';\n }\n\n get isTransient(): boolean {\n return this.status === 408 || this.status === 429\n || this.status === 502 || this.status === 503;\n }\n}\n","// packages/ui-gen/src/adapters/openrouter/client.ts\n//\n// Direct fetch()-based HTTP client for OpenRouter's API.\n// No OpenAI SDK dependency — independent implementation.\n\nimport type {\n OpenRouterChatRequest,\n OpenRouterChatResponse,\n OpenRouterStreamDelta,\n} from './types';\nimport { OpenRouterError } from './types';\n\nexport interface OpenRouterClientConfig {\n apiKey: string;\n baseUrl?: string;\n siteUrl?: string;\n siteName?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';\n\nexport class OpenRouterClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n\n constructor(private readonly config: OpenRouterClientConfig) {\n this.baseUrl = config.baseUrl ?? process.env.OPENROUTER_BASE_URL ?? DEFAULT_BASE_URL;\n this.headers = {\n 'Authorization': `Bearer ${config.apiKey}`,\n 'Content-Type': 'application/json',\n 'HTTP-Referer': config.siteUrl ?? process.env.OPENROUTER_SITE_URL ?? 'https://ggui.ai',\n 'X-Title': config.siteName ?? process.env.OPENROUTER_SITE_NAME ?? 'ggui',\n };\n }\n\n /**\n * Non-streaming chat completion.\n */\n async chatCompletion(\n params: Omit<OpenRouterChatRequest, 'stream'>,\n ): Promise<OpenRouterChatResponse> {\n const body: OpenRouterChatRequest = { ...params, stream: false };\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: { message: response.statusText } }));\n const message = (errorBody as { error?: { message?: string } }).error?.message ?? response.statusText;\n throw new OpenRouterError(message, response.status);\n }\n\n return response.json() as Promise<OpenRouterChatResponse>;\n }\n\n /**\n * Streaming chat completion via SSE.\n * Yields delta chunks, accumulates the final usage from the last chunk.\n */\n async *chatCompletionStream(\n params: Omit<OpenRouterChatRequest, 'stream'>,\n ): AsyncGenerator<OpenRouterStreamDelta> {\n const body: OpenRouterChatRequest = { ...params, stream: true };\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: { message: response.statusText } }));\n const message = (errorBody as { error?: { message?: string } }).error?.message ?? response.statusText;\n throw new OpenRouterError(message, response.status);\n }\n\n if (!response.body) {\n throw new OpenRouterError('No response body for streaming request', 500);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(':')) continue;\n if (trimmed === 'data: [DONE]') return;\n if (!trimmed.startsWith('data: ')) continue;\n\n const json = trimmed.slice('data: '.length);\n try {\n yield JSON.parse(json) as OpenRouterStreamDelta;\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","// packages/ui-gen/src/adapters/openrouter/raw.ts\n//\n// OpenRouter adapter using direct fetch() — no OpenAI SDK dependency.\n// Uses OpenAI-compatible chat completions API with OpenRouter extensions\n// for caching and extended thinking.\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n compileLastResort,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport { OpenRouterClient } from './client';\nimport type { OpenRouterMessage, OpenRouterTool, OpenRouterChatResponse } from './types';\n\nexport class OpenRouterRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openrouter';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'OpenRouter (Raw API)';\n\n private client: OpenRouterClient | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENROUTER_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n this.client = new OpenRouterClient({\n apiKey: this.config.apiKey || process.env.OPENROUTER_API_KEY!,\n });\n }\n\n const tools = params.tools.map(toOpenRouterTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let cacheCreationTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let turnsUsed = 0;\n let allTextOutput = '';\n\n // Detect model capabilities for cache/thinking support\n const modelId = params.model;\n const isAnthropicModel = modelId.includes('anthropic/') || modelId.includes('claude');\n\n // Build initial messages with optional cache_control\n const systemMessage: OpenRouterMessage = isAnthropicModel\n ? {\n role: 'system',\n content: [{ type: 'text', text: params.systemPrompt, cache_control: { type: 'ephemeral' } }],\n }\n : { role: 'system', content: params.systemPrompt };\n\n const messages: OpenRouterMessage[] = [\n systemMessage,\n { role: 'user', content: params.userPrompt },\n ];\n\n // Agentic loop\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n const response: OpenRouterChatResponse = await this.client.chatCompletion({\n model: modelId,\n messages,\n tools: tools.length > 0 ? tools : undefined,\n tool_choice: tools.length > 0 ? 'auto' : undefined,\n max_tokens: 16384,\n });\n\n // Track tokens\n if (response.usage) {\n totalInputTokens += response.usage.prompt_tokens;\n totalOutputTokens += response.usage.completion_tokens;\n if (response.usage.cache_creation_input_tokens) {\n cacheCreationTokens = (cacheCreationTokens ?? 0) + response.usage.cache_creation_input_tokens;\n }\n if (response.usage.cache_read_input_tokens) {\n cacheReadTokens = (cacheReadTokens ?? 0) + response.usage.cache_read_input_tokens;\n }\n }\n\n const choice = response.choices[0];\n if (!choice) break;\n\n // Collect text output\n if (choice.message.content) {\n allTextOutput += choice.message.content + '\\n';\n captureMarkers(capture, choice.message.content);\n }\n\n const toolCalls = choice.message.tool_calls;\n if (!toolCalls || toolCalls.length === 0) break;\n\n // Add assistant message with tool_calls to conversation\n messages.push({\n role: 'assistant',\n content: choice.message.content,\n tool_calls: toolCalls,\n });\n\n // Execute tools and add results\n for (const tc of toolCalls) {\n const toolDef = params.tools.find((t) => t.name === tc.function.name);\n if (!toolDef) {\n messages.push({\n role: 'tool',\n tool_call_id: tc.id,\n content: JSON.stringify({ error: `Tool '${tc.function.name}' not found` }),\n });\n continue;\n }\n\n let args: JsonObject = {};\n try { args = JSON.parse(tc.function.arguments || '{}') as JsonObject; } catch { /* empty */ }\n\n captureSourceCode(capture, tc.function.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, tc.function.name, result);\n\n messages.push({\n role: 'tool',\n tool_call_id: tc.id,\n content: result.content[0]?.text ?? '',\n });\n }\n }\n\n // Fallback: extract code from text output\n if (!capture.compiledCode && allTextOutput) {\n captureMarkers(capture, allTextOutput);\n await extractCodeFromText(allTextOutput, params.tools, capture);\n }\n\n // Last resort: compile sourceCode directly\n if (!capture.compiledCode) {\n await compileLastResort(capture, allTextOutput);\n }\n\n if (!capture.compiledCode) {\n throw new Error('OpenRouter raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n cacheCreationTokens,\n cacheReadTokens,\n };\n }\n}\n\n/** Convert ToolDefinition to OpenRouter tool format (OpenAI-compatible). */\nfunction toOpenRouterTool(def: ToolDefinition): OpenRouterTool {\n return {\n type: 'function',\n function: {\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema) as JsonObject,\n },\n };\n}\n","// packages/ui-gen/src/adapters/types.ts\n//\n// Production adapter types — used by both Lambda generation and benchmarks.\n\nimport type { z } from 'zod';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n// =============================================================================\n// Provider & Mode\n// =============================================================================\n\nexport type ProviderName = 'claude' | 'openai' | 'google' | 'openrouter';\nexport type AdapterMode = 'raw' | 'sdk' | 'multi-agent';\n\nexport const PROVIDER_DISPLAY_NAMES: Record<ProviderName, string> = {\n claude: 'Anthropic Claude',\n openai: 'OpenAI',\n google: 'Google Gemini',\n openrouter: 'OpenRouter',\n};\n\n// =============================================================================\n// Tool Definition (SDK-agnostic)\n// =============================================================================\n\nexport interface ToolResultContent {\n type: 'text';\n text: string;\n}\n\nexport interface ToolResult {\n content: ToolResultContent[];\n isError?: boolean;\n}\n\n/**\n * SDK-agnostic tool definition.\n * Each adapter converts these to its native tool format.\n */\nexport interface ToolDefinition {\n /** Tool name (e.g., 'compile_component') */\n name: string;\n /** Tool description for the LLM */\n description: string;\n /** Zod schema for input parameters (always an object schema — tools take named args) */\n inputSchema: z.ZodObject<z.ZodRawShape>;\n /** Handler function — same signature regardless of SDK */\n handler: (args: JsonObject) => Promise<ToolResult>;\n}\n\n// =============================================================================\n// Adapter Result\n// =============================================================================\n\n/**\n * Result returned by any adapter's generate() method.\n *\n * Core fields are populated by all adapters. Extended fields are\n * populated by adapters that support richer output (e.g., Claude SDK).\n */\nexport interface AdapterResult {\n /** Final compiled JavaScript component code */\n compiledCode: string;\n /** TSX source code (captured from compile_component input) */\n sourceCode?: string;\n /** Token usage breakdown */\n tokens: {\n input: number;\n output: number;\n total: number;\n };\n /** Wall-clock generation time in ms */\n generationTimeMs: number;\n /** Total number of LLM API calls across all phases */\n turnsUsed: number;\n /** Number of harness iterations (Plan→Code→Evaluate→Regen cycles). 1 = single pass. */\n iterations?: number;\n /** Raw cost from SDK if available */\n rawCostUsd?: number;\n\n // ── Extended fields (production use) ───────────────────────────────\n\n /** Data spec for ggui_emit — describes what data the component accepts */\n stream?: JsonObject;\n /** LLM-generated metadata annotation for blueprint indexing */\n generatorMeta?: { category: string; description: string };\n /** Names of subagents invoked during generation */\n subagentsUsed?: string[];\n /** Tokens written to prompt cache (Claude-specific) */\n cacheCreationTokens?: number;\n /** Tokens read from prompt cache (Claude-specific) */\n cacheReadTokens?: number;\n /** SDK session ID for evaluation loop resume (Claude SDK-specific) */\n sdkSessionId?: string;\n}\n","// packages/ui-gen/src/adapters/index.ts\n//\n// Public API for the adapter module.\n// Use getAdapter() to obtain adapter instances — it lazy-loads provider SDKs.\n//\n// NOTE: Importing concrete adapters (ClaudeRawAdapter, etc.) directly from\n// this barrel file will statically pull in their provider SDKs. This is fine\n// for benchmarks and tests, but Lambda entry points should use getAdapter()\n// from './registry' to benefit from lazy loading and smaller bundles.\n\n// ── Types ────────────────────────────────────────────────────────────\nexport type {\n ProviderName,\n AdapterMode,\n ToolDefinition,\n ToolResult,\n ToolResultContent,\n AdapterResult,\n} from './types';\n\nexport { PROVIDER_DISPLAY_NAMES } from './types';\n\n// ── Base class & config ──────────────────────────────────────────────\nexport { GeneratorAdapter } from './base';\nexport type { AdapterConfig, ClaudeSdkConfig, AnyAdapterConfig, GenerateParams } from './base';\n\n// ── Registry (primary API) ───────────────────────────────────────────\nexport { getAdapter, listAdapters } from './registry';\n\n// ── Tools ────────────────────────────────────────────────────────────\nexport { createGeneratorTools } from './tools';\nexport { zodToJsonSchema } from './tool-bridge';\n\n// ── Concrete adapters (for benchmarks, tests, instanceof checks) ─────\n// WARNING: These static imports pull in provider SDKs. Lambda entry\n// points should NOT import from this barrel — use getAdapter() instead.\nexport { ClaudeRawAdapter } from './claude/raw';\nexport { ClaudeSdkAdapter } from './claude/sdk';\nexport { OpenAiRawAdapter } from './openai/raw';\nexport { OpenAiSdkAdapter } from './openai/sdk';\nexport { GoogleRawAdapter } from './google/raw';\nexport { GoogleSdkAdapter } from './google/sdk';\n","// packages/ui-gen/src/adapters/registry.ts\n//\n// Adapter registry — resolves provider + mode to the correct adapter instance.\n// Uses dynamic imports so per-provider Lambda bundles only include their own SDKs.\n//\n// For Lambda deployments, mark non-Claude SDKs as externalModules in esbuild config\n// so they're only loaded at runtime when the provider is actually requested.\n\nimport type { ProviderName, AdapterMode } from './types';\nimport type { AnyAdapterConfig } from './base';\nimport { GeneratorAdapter } from './base';\n\ntype AdapterFactory = (config: AnyAdapterConfig) => Promise<GeneratorAdapter>;\n\nconst ADAPTER_FACTORIES: Partial<Record<ProviderName, Partial<Record<AdapterMode, AdapterFactory>>>> = {};\n\nfunction registerProvider(provider: ProviderName, factories: Partial<Record<AdapterMode, AdapterFactory>>): void {\n ADAPTER_FACTORIES[provider] = factories;\n}\n\n// Claude\nregisterProvider('claude', {\n raw: async (config) => {\n const { ClaudeRawAdapter } = await import('./claude/raw');\n return new ClaudeRawAdapter(config);\n },\n sdk: async (config) => {\n const { ClaudeSdkAdapter } = await import('./claude/sdk');\n return new ClaudeSdkAdapter(config);\n },\n});\n\n// OpenAI\nregisterProvider('openai', {\n raw: async (config) => {\n const { OpenAiRawAdapter } = await import('./openai/raw');\n return new OpenAiRawAdapter(config);\n },\n sdk: async (config) => {\n const { OpenAiSdkAdapter } = await import('./openai/sdk');\n return new OpenAiSdkAdapter(config);\n },\n});\n\n// Google\nregisterProvider('google', {\n raw: async (config) => {\n const { GoogleRawAdapter } = await import('./google/raw');\n return new GoogleRawAdapter(config);\n },\n sdk: async (config) => {\n const { GoogleSdkAdapter } = await import('./google/sdk');\n return new GoogleSdkAdapter(config);\n },\n});\n\n// OpenRouter (raw only — no Agent SDK)\nregisterProvider('openrouter', {\n raw: async (config) => {\n const { OpenRouterRawAdapter } = await import('./openrouter/raw');\n return new OpenRouterRawAdapter(config);\n },\n});\n\n/**\n * Get an adapter instance for the given provider and mode.\n */\nexport async function getAdapter(\n provider: ProviderName,\n mode: AdapterMode,\n config: AnyAdapterConfig = {},\n): Promise<GeneratorAdapter> {\n const providerFactories = ADAPTER_FACTORIES[provider];\n if (!providerFactories) {\n throw new Error(\n `Unknown provider: ${provider}. Available: ${Object.keys(ADAPTER_FACTORIES).join(', ')}`,\n );\n }\n\n const factory = providerFactories[mode];\n if (!factory) {\n throw new Error(\n `Unknown mode '${mode}' for provider '${provider}'. Available: ${Object.keys(providerFactories).join(', ')}`,\n );\n }\n\n return factory(config);\n}\n\n/**\n * List all registered adapter combinations and their availability.\n */\nexport async function listAdapters(\n config: AnyAdapterConfig = {},\n): Promise<\n Array<{ provider: ProviderName; mode: AdapterMode; available: boolean; displayName: string }>\n> {\n const result: Array<{\n provider: ProviderName;\n mode: AdapterMode;\n available: boolean;\n displayName: string;\n }> = [];\n\n for (const [provider, modes] of Object.entries(ADAPTER_FACTORIES)) {\n for (const mode of Object.keys(modes)) {\n try {\n const factory = ADAPTER_FACTORIES[provider as ProviderName]?.[mode as AdapterMode];\n if (!factory) continue;\n const adapter = await factory(config);\n result.push({\n provider: provider as ProviderName,\n mode: mode as AdapterMode,\n available: adapter.isAvailable(),\n displayName: adapter.displayName,\n });\n } catch {\n result.push({\n provider: provider as ProviderName,\n mode: mode as AdapterMode,\n available: false,\n displayName: `${provider}/${mode} (not installed)`,\n });\n }\n }\n }\n\n return result;\n}\n","/**\n * AUTO-GENERATED from @ggui-ai/design JSDoc.\n * Do not edit manually. Run: pnpm --filter @ggui-ai/design generate:docs\n */\nexport const PRIMITIVES_DOCUMENTATION = \"# ggui Primitives & Design System Reference\\n\\n> You are a world-class UI engineer working with ggui's component library for the first time.\\n> This reference documents every available component, prop, and convention.\\n> Components handle theming automatically via built-in variants — pick the right variant and the theme does the rest.\\n> For custom styling beyond variants, use CSS variables: var(--ggui-*, fallback).\\n\\n## Primitives\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### Container\\n\\nContainer -- Width-constrained wrapper that centers content horizontally.\\n\\nRenders a `<div>` with `width: 100%` and a `maxWidth` constraint.\\nWhen `center` is true (the default), applies `margin: 0 auto`.\\nNo background, border, or shadow -- use Card for visual containment.\\n\\nCSS variables used: none (pure layout primitive).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| maxWidth | `'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| '3xl' \\\\| 'full' \\\\| string` | `'lg'` | Maximum width constraint. Accepts a preset token or any CSS width string. - `'xs'` -- 320px - `'sm'` -- 480px - `'md'` -- 640px - `'lg'` -- 768px - `'xl'` -- 1024px - `'2xl'` -- 1280px - `'3xl'` -- 1536px - `'full'` -- 100% Custom strings (e.g., `'900px'`, `'60ch'`) are passed through as-is. |\\n| center | `boolean` | `true` | Whether to center the container horizontally via `margin: 0 auto`. |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no padding)` | Padding applied to all sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n\\n**Example:**\\n```tsx\\n<Container maxWidth=\\\"xl\\\" padding=\\\"var(--ggui-spacing-6)\\\">\\n <Stack gap=\\\"var(--ggui-spacing-4)\\\">\\n <Heading level={1}>Dashboard</Heading>\\n <Card shadow=\\\"md\\\" padding=\\\"var(--ggui-spacing-5)\\\">\\n <Text>Welcome back!</Text>\\n </Card>\\n </Stack>\\n</Container>\\n```\\n\\n### Card\\n\\nCard -- Container with background, shadow, and optional border.\\n\\nRenders a `<div>` with:\\n- Background: `var(--ggui-color-surface)`\\n- Border (when enabled): `1px solid var(--ggui-color-outlineVariant)`\\n- Shadow and radius controlled by design tokens via CSS variables.\\n- No built-in transitions.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'lg'` | Padding applied to all sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| shadow | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'` | `'sm'` | Shadow elevation level. Maps to design tokens: - `'none'` -- no shadow - `'sm'` -- var(--ggui-shape-shadow-sm, 0 1px 2px 0 rgba(0,0,0,0.05)) -- subtle, default - `'md'` -- var(--ggui-shape-shadow-md, 0 4px 6px -1px rgba(0,0,0,0.1)) -- dialogs, emphasized sections - `'lg'` -- var(--ggui-shape-shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1)) -- floating panels - `'xl'` -- var(--ggui-shape-shadow-xl, 0 20px 25px -5px rgba(0,0,0,0.1)) -- popovers, modals |\\n| border | `boolean` | `true` | Whether to render a 1px border using `var(--ggui-color-outlineVariant)`. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `'lg'` | Corner radius. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| surface | `'default' \\\\| 'elevated' \\\\| 'sunken' \\\\| 'accent' \\\\| 'inverted' \\\\| 'transparent'` | `'default'` | Semantic surface slot. Same vocabulary as ; see that prop's docs for the full slot table. Default Card surface is `'default'` (the active theme's `--ggui-color-surface`); pair with `shadow=\\\"md\\\"\\\\|\\\"lg\\\"` for elevated cards, or use `'inverted'` for a dark testimonial-style card on a light theme. |\\n\\n**Example:**\\n```tsx\\n<Card shadow=\\\"md\\\" padding=\\\"lg\\\" radius=\\\"lg\\\">\\n <Stack gap=\\\"md\\\">\\n <Text size=\\\"sm\\\" weight=\\\"medium\\\">Settings</Text>\\n <Input label=\\\"Name\\\" value={name} onChange={setName} />\\n <Button variant=\\\"primary\\\">Save</Button>\\n </Stack>\\n</Card>\\n```\\n\\n### Stack\\n\\nStack -- Flexbox layout primitive for arranging children along a single axis.\\n\\nRenders a `<div>` with `display: flex`. Default layout is vertical (column).\\nAll flex shorthand values (`align`, `justify`, `wrap`) are abstracted into\\nsemantic prop names.\\n\\nCSS variables used: none (pure layout primitive).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| direction | `'vertical' \\\\| 'horizontal'` | `'vertical'` | Main axis direction. - `'vertical'` -- `flex-direction: column` - `'horizontal'` -- `flex-direction: row` |\\n| gap | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'sm'` | Gap between children. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| align | `'start' \\\\| 'center' \\\\| 'end' \\\\| 'stretch'` | `'stretch'` | Cross-axis alignment (maps to `align-items`). - `'start'` -- flex-start - `'center'` -- center - `'end'` -- flex-end - `'stretch'` -- stretch (children fill cross-axis) |\\n| justify | `'start' \\\\| 'center' \\\\| 'end' \\\\| 'between' \\\\| 'around' \\\\| 'evenly'` | `'start'` | Main-axis content distribution (maps to `justify-content`). - `'start'` -- flex-start - `'center'` -- center - `'end'` -- flex-end - `'between'` -- space-between - `'around'` -- space-around - `'evenly'` -- space-evenly |\\n| wrap | `boolean` | `false` | Whether children wrap to the next line when they overflow. Maps to `flex-wrap: wrap` when true. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"lg\\\" align=\\\"center\\\">\\n <Heading level={2}>Profile</Heading>\\n <Text>Edit your account details below.</Text>\\n <Stack direction=\\\"horizontal\\\" gap=\\\"sm\\\" justify=\\\"end\\\">\\n <Button variant=\\\"ghost\\\">Cancel</Button>\\n <Button variant=\\\"primary\\\">Save</Button>\\n </Stack>\\n</Stack>\\n```\\n\\n### Grid\\n\\nGrid -- 2-D layout primitive. Arranges children into rows AND\\ncolumns; reach for it when Stack/Row's single-axis flow isn't\\nenough (card galleries, dashboards, stat grids).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| columns | `number \\\\| ResponsiveColumns` | `2` | Column count. Three forms: - a number — that many equal columns at every width (`columns={3}`); - a map — explicit counts per breakpoint (`columns={{ base: 1, md: 3 }}` = 1 column on mobile, 3 from `md`). Use this when the request names exact per-breakpoint counts (\\\"3 per row on desktop, 1 on mobile\\\"). Ignored entirely when `minColumnWidth` is set. |\\n| gap | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'md'` | Gap between cells. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`); a number is pixels. |\\n| minColumnWidth | `number \\\\| string` | `undefined (use `columns`)` | When set, the grid becomes responsive — it fits as many equal columns as possible, each at least this wide, and `columns` is ignored. A number is treated as pixels. |\\n\\n**Example:**\\n```tsx\\n<Grid columns={3} gap=\\\"md\\\">\\n {items.map((it) => <Card key={it.id}>{it.name}</Card>)}\\n</Grid>\\n```\\n\\n### Skeleton\\n\\nSkeleton -- a pulsing placeholder for content that has not loaded\\nyet. ggui UIs are agent-driven (props arrive late, streams start\\nempty), so a loading frame is the rule — render `Skeleton` instead\\nof a blank screen or a hand-rolled pulsing `<div>`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| variant | `'rect' \\\\| 'text' \\\\| 'circle'` | `'rect'` | Shape preset. - `'rect'` -- a block (default); pair with `width` / `height`. - `'text'` -- a single text line (height ~1em). - `'circle'` -- equal width/height, fully rounded (avatar slot). |\\n| width | `number \\\\| string` | - | Width. A number is pixels. Defaults to `100%` (`2.5rem` for circle). |\\n| height | `number \\\\| string` | - | Height. A number is pixels. Defaults by variant when unset. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `'sm'` | Corner radius. Prefer a radius-scale name. Ignored for `variant=\\\"circle\\\"` (always fully round). |\\n\\n**Example:**\\n```tsx\\n{user === undefined\\n ? <Skeleton variant=\\\"text\\\" width=\\\"40%\\\" />\\n : <Text>{user.name}</Text>}\\n```\\n\\n### Box\\n\\nBox -- Generic container with padding, margin, background, and border-radius.\\n\\nRenders a plain `<div>`. Unlike Card, Box has no default background, shadow,\\nor border -- it is a blank canvas for custom styling. Use it for layout\\nspacing, colored sections, or wrapping arbitrary content.\\n\\nWhen both `paddingX`/`paddingY` and `padding` are provided, the axis-specific\\nprops take precedence and `padding` is ignored.\\n\\nCSS variables used: none (all values are passed through directly).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no padding)` | Padding applied to all four sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. Ignored when `paddingX` or `paddingY` is set. |\\n| paddingX | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined` | Horizontal (left + right) padding. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . When set alongside `paddingY`, they combine into a shorthand `padding: {Y} {X}`. When set without `paddingY`, vertical padding defaults to 0. |\\n| paddingY | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined` | Vertical (top + bottom) padding. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . When set alongside `paddingX`, they combine into a shorthand `padding: {Y} {X}`. When set without `paddingX`, horizontal padding defaults to 0. |\\n| margin | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no margin)` | Margin applied to all four sides. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . |\\n| surface | `'default' \\\\| 'elevated' \\\\| 'sunken' \\\\| 'accent' \\\\| 'inverted' \\\\| 'transparent'` | `undefined (transparent)` | Semantic surface slot. Picks the right `var(--ggui-color-*)` background token from the active theme. The ONLY way to set a theme-tracking background fill on Box. Available slots: - `'default'` — base container surface (most common) - `'elevated'` — same fill, intended to be paired with shadow (use Card.shadow for actual elevation) - `'sunken'` — recessed / inset region (`surfaceVariant` token) - `'accent'` — highlighted / branded fill (`primary-50` token) - `'inverted'` — dark surface in light mode, light in dark (testimonials, code-snippet cards). Pair with `'inverse'` for legible text. - `'transparent'` — explicit \\\"no fill\\\" For non-theme-mapped brand colors (e.g. a partner's exact brand hex like Stripe purple) use the escape — every other hex / rgba on Box is rejected by tier-0 self-check. |\\n| assetColor | `string` | `undefined` | Asset color escape — the typed valve for legitimate non-theme color values (a partner's exact brand hex, a fixed product surface, etc.). Renders as the Box background. **MUST be paired with .** The semantic name is human-readable documentation of why this color bypasses the theme — e.g. `\\\"stripe-brand-purple\\\"`, `\\\"slack-aubergine\\\"`. Tier-0 self-check allows hex / rgba inside `assetColor` ONLY when `assetSemantic` is a non-empty string; one without the other fails the check. Reach for `surface` first. This escape exists for the small set of cases where the operator's theme MUST NOT override the value (brand identity rendering). |\\n| assetSemantic | `string` | `undefined` | Human-readable semantic label that documents why bypasses the theme. Required when `assetColor` is set; tier-0 self-check rejects empty strings or a missing `assetSemantic` next to a hex `assetColor`. Examples: `\\\"stripe-brand-purple\\\"`, `\\\"slack-aubergine\\\"`, `\\\"partner-logo-orange\\\"`. Pure documentation — no rendering effect. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `undefined (no rounding)` | Corner radius. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n\\n**Example:**\\n```tsx\\n<Box paddingX=\\\"xl\\\" paddingY=\\\"lg\\\" surface=\\\"accent\\\" radius=\\\"lg\\\">\\n <Text size=\\\"sm\\\" tone=\\\"emphasized\\\">\\n Tip: You can customize your theme in Settings.\\n </Text>\\n</Box>\\n```\\n\\n### Divider\\n\\nDivider -- A 1px line to visually separate content sections.\\n\\nRenders an `<hr>` (horizontal) or `<div>` (vertical) with `role=\\\"separator\\\"`.\\n- Horizontal: 1px tall, full width, with vertical margin.\\n- Vertical: 1px wide, stretches to parent height via `align-self: stretch`,\\n with horizontal margin. Works best inside a horizontal Stack or Row.\\n\\nDefault color: `var(--ggui-color-outlineVariant)`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Line direction. - `'horizontal'` -- renders `<hr>`, full width, 1px height, margin top/bottom - `'vertical'` -- renders `<div>`, 1px width, `align-self: stretch`, margin left/right |\\n| margin | `number \\\\| string` | `16` | Spacing around the divider. Numbers are treated as pixels. Applied as vertical margin for horizontal dividers, horizontal margin for vertical. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-outlineVariant)`)` | Semantic color slot. Same vocabulary as ; the theme decides what each tone LOOKS like. Defaults to a quiet outline-variant tint when unset (independent of the tone slots). |\\n\\n**Example:**\\n```tsx\\n<Stack gap={0}>\\n <Text>Section A</Text>\\n <Divider margin=\\\"var(--ggui-spacing-3)\\\" />\\n <Text>Section B</Text>\\n</Stack>\\n```\\n\\n### Spacer\\n\\nSpacer -- Invisible spacing element, either fixed-size or flexible.\\n\\nRenders an empty `<div>`.\\n- Fixed mode (number): sets both `width` and `height` to the given pixel\\n value with `flex-shrink: 0`, creating rigid spacing in any direction.\\n- Flex mode (`'flex'`): sets `flex: 1`, expanding to fill remaining space\\n in a flex container. Useful for pushing siblings apart.\\n\\nCSS variables used: none.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| size | `number \\\\| 'flex'` | `16` | Spacing amount. - Number: fixed square spacer (width and height in pixels, `flex-shrink: 0`). - `'flex'`: expands to fill available space (`flex: 1`). |\\n\\n**Example:**\\n```tsx\\n<Stack direction=\\\"horizontal\\\" align=\\\"center\\\">\\n <Heading level={3}>Logo</Heading>\\n <Spacer size=\\\"flex\\\" />\\n <Button variant=\\\"ghost\\\">Login</Button>\\n</Stack>\\n```\\n\\n### Text\\n\\nText -- Versatile typography primitive for body copy, captions, and labels.\\n\\nRenders as `<p>` by default (configurable via `is`). Typography is\\ncomposed from three orthogonal axes: `size` (font size, with a\\nmatching line-height built in), `weight`, and `tone` (semantic\\ncolor). `caps` adds the uppercase, letter-spaced treatment for tiny\\nsection labels (the classic overline/eyebrow look).\\n\\nDefault text color: `var(--ggui-color-onSurface)`.\\nAll text renders with `margin: 0` (no default paragraph spacing).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| size | `'xs' \\\\| 'sm' \\\\| 'base' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| '3xl' \\\\| '4xl'` | `'base'` | Font size. Maps to CSS variables with pixel fallbacks; each size carries a matching line-height (1.5 for `xs`--`base`, 1.625 for `lg`, then tightening on display sizes: 1.375 at `xl`, 1.25 from `2xl` up): - `'xs'` -- var(--ggui-font-size-xs) (12px) - `'sm'` -- var(--ggui-font-size-sm) (14px) - `'base'` -- var(--ggui-font-size-base) (16px) - `'lg'` -- var(--ggui-font-size-lg) (18px) - `'xl'` -- var(--ggui-font-size-xl) (20px) - `'2xl'` -- var(--ggui-font-size-2xl) (24px) - `'3xl'` -- var(--ggui-font-size-3xl) (30px) - `'4xl'` -- var(--ggui-font-size-4xl) (36px) |\\n| weight | `'normal' \\\\| 'medium' \\\\| 'semibold' \\\\| 'bold'` | `'normal'` | Font weight. Maps to CSS variables with numeric fallbacks: - `'normal'` -- var(--ggui-font-weight-normal) - `'medium'` -- var(--ggui-font-weight-medium) - `'semibold'` -- var(--ggui-font-weight-semibold) - `'bold'` -- var(--ggui-font-weight-bold) |\\n| caps | `boolean` | `false` | When true, uppercases the text and adds 0.05em letter-spacing -- the eyebrow/overline treatment for tiny section labels. Pair with `size=\\\"xs\\\" weight=\\\"semibold\\\" tone=\\\"muted\\\"`. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `'default' (var(--ggui-color-onSurface))` | Semantic color slot. Picks the right `var(--ggui-color-*)` token from the active theme. The theme decides what each tone LOOKS like — `'muted'` is a quiet warm grey on Claudic, a cool slate on Indigo, dim cyan on Neon-Noir. Components that use `tone` track the operator's theme switch automatically. Available slots: `'default'` (primary body text), `'muted'` (secondary / metadata), `'subtle'` (very-low-emphasis hint), `'emphasized'` (branded accent), `'loud'` (strongest accent), `'success'` / `'warning'` / `'error'` / `'info'` (status text), `'inverse'` (text on dark surface), `'inherit'` (parent's color). `tone` is the ONLY way to set a Text color. The legacy `color?: string` escape was retired — raw color strings bypass theming and silently override the operator's preset. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | `undefined (inherits from parent)` | Horizontal text alignment. Maps directly to `text-align`. |\\n| truncate | `boolean` | `false` | When true, clips overflowing text with an ellipsis. Applies `overflow: hidden`, `text-overflow: ellipsis`, and `white-space: nowrap`. |\\n| is | `'p' \\\\| 'span' \\\\| 'div' \\\\| 'label'` | `'p'` | HTML element to render. Choose based on semantic context: - `'p'` -- paragraph (default, block-level) - `'span'` -- inline text within a sentence - `'div'` -- generic block container - `'label'` -- form label (pair with `htmlFor`) |\\n| id | `string` | - | `id` for the rendered element — anchor an in-page link, or pair with a form control's `aria-labelledby`. |\\n| htmlFor | `string` | - | Associates an `is=\\\"label\\\"` element with a form control by the control's `id`. Only meaningful when `is=\\\"label\\\"`. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"var(--ggui-spacing-1)\\\">\\n <Text size=\\\"xs\\\" weight=\\\"semibold\\\" caps tone=\\\"muted\\\">Account</Text>\\n <Text size=\\\"lg\\\">Welcome back, Jane.</Text>\\n <Text size=\\\"xs\\\" tone=\\\"muted\\\">\\n Last login: 2 hours ago\\n </Text>\\n</Stack>\\n```\\n\\n### Heading\\n\\nHeading -- Semantic heading element (h1-h6) with preset typography styles.\\n\\nRenders the corresponding `<h1>`-`<h6>` HTML element based on `level`.\\nEach level has a preset font size, weight, line height, and letter spacing\\nfrom the heading typography tokens:\\n- Level 1: 36px / bold / 1.25 line-height / -0.025em tracking\\n- Level 2: 30px / bold / 1.25 line-height / -0.025em tracking\\n- Level 3: 24px / semibold / 1.375 line-height / 0em tracking\\n- Level 4: 20px / semibold / 1.375 line-height / 0em tracking\\n- Level 5: 18px / semibold / 1.5 line-height / 0em tracking\\n- Level 6: 16px / semibold / 1.5 line-height / 0em tracking\\n\\nDefault text color: `var(--ggui-color-onSurface)`.\\nAll headings render with `margin: 0` (no default heading spacing).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| level | `1 \\\\| 2 \\\\| 3 \\\\| 4 \\\\| 5 \\\\| 6` | `2` | Semantic heading level. Determines both the HTML element (`<h1>`-`<h6>`) and the preset typography style. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `'default' (var(--ggui-color-onSurface))` | Semantic color slot. Same vocabulary as ; see that prop's docs for the full slot table. `tone` is the ONLY way to set a Heading color — the legacy `color?: string` escape was retired so the operator's theme always wins. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | `undefined (inherits from parent)` | Horizontal text alignment. Maps directly to `text-align`. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"var(--ggui-spacing-2)\\\">\\n <Heading level={1}>Page Title</Heading>\\n <Heading level={3} tone=\\\"emphasized\\\">\\n Subsection\\n </Heading>\\n <Text>Body content goes here.</Text>\\n</Stack>\\n```\\n\\n### Button\\n\\nButton -- A clickable button primitive with multiple visual variants and sizes.\\n\\nRenders a native `<button>` element styled with inline CSS derived from design-token\\nCSS variables. Supports a loading spinner, left/right icon slots, and a cross-platform\\n`onPress` alias for `onClick`.\\n\\nBase styles applied to every variant:\\n- `border-radius: var(--ggui-shape-radius-md)`\\n- `font-weight: var(--ggui-font-weight-medium)`\\n- `box-shadow: var(--ggui-shape-shadow-sm, 0 1px 2px rgba(0,0,0,0.05))`\\n- `gap: var(--ggui-spacing-2)` between icon and text\\n- Transitions: background-color, box-shadow, opacity at 200ms ease-in-out\\n\\nDisabled or loading: `opacity: 0.5`, `cursor: not-allowed`, click handler suppressed.\\n\\nAlso extends native `ButtonHTMLAttributes` (except `style`/`className`), so props\\nlike `type`, `form`, `aria-*`, and `data-*` are forwarded to the `<button>` element.\\nThe `type` prop defaults to `'button'` (not `'submit'`), preventing accidental form\\nsubmissions.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'primary' \\\\| 'secondary' \\\\| 'outline' \\\\| 'ghost' \\\\| 'danger'` | `'primary'` | Visual style. Maps to CSS variables: - `'primary'` -- `var(--ggui-color-primary-600)` background, white text, no border - `'secondary'` -- `var(--ggui-color-surfaceVariant)` background, `var(--ggui-color-onSurfaceVariant)` text, no border - `'outline'` -- transparent background, `1px solid var(--ggui-color-primary-600)` border, primary-600 text - `'ghost'` -- transparent background, `var(--ggui-color-onSurfaceVariant)` text, no border - `'danger'` -- `var(--ggui-color-error-600)` background, white text, no border |\\n| size | `'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding, font size, and minimum height: - `'xs'` -- padding `4px 8px`, font `var(--ggui-font-size-xs)`, min-height 24px - `'sm'` -- padding `6px 12px`, font `var(--ggui-font-size-sm)`, min-height 32px - `'md'` -- padding `10px 16px`, font `var(--ggui-font-size-sm)`, min-height 40px - `'lg'` -- padding `12px 24px`, font `var(--ggui-font-size-base)`, min-height 48px |\\n| fullWidth | `boolean` | `false` | When true, sets `width: 100%` so the button fills its container. |\\n| loading | `boolean` | `false` | When true, replaces children with a 16px `Spinner` (color: `currentColor`) and disables interaction (same effect as `disabled`). |\\n| leftIcon | `ReactNode` | - | ReactNode rendered before children, inside the flex layout with `var(--ggui-spacing-2)` gap. |\\n| rightIcon | `ReactNode` | - | ReactNode rendered after children, inside the flex layout with `var(--ggui-spacing-2)` gap. |\\n| onPress | `() => void` | - | Alias for `onClick` for cross-platform compatibility (React Native convention). If both `onClick` and `onPress` are provided, `onClick` takes precedence. |\\n\\n**Example:**\\n```tsx\\n<Button variant=\\\"primary\\\" size=\\\"md\\\" leftIcon={<Icon name=\\\"save\\\" />} onClick={handleSave}>\\n Save Changes\\n</Button>\\n```\\n\\n### Input\\n\\nInput -- A single-line text input with label, validation, and helper text.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<input>`,\\nand an optional message `<span>` for error or helper text.\\n\\nStyling:\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Text: `var(--ggui-color-onSurface)`\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Label: `var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`,\\n `var(--ggui-color-onSurfaceVariant)`\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: auto-generated `id` links `<label>` to `<input>` via `htmlFor`.\\nWhen `error` is set, `aria-invalid` is true and the message has `role=\\\"alert\\\"`.\\nWhen `required` is true, a red asterisk is appended to the label.\\n\\nAlso extends native `InputHTMLAttributes` (except `style`, `className`, `onChange`,\\n`size`), so props like `autoFocus`, `name`, `pattern`, `aria-*` are forwarded.\\n\\n**IMPORTANT:** `onChange` receives the string value directly, NOT a React\\n`ChangeEvent`. This differs from native `<input>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the input. Linked to the input via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| placeholder | `string` | - | Placeholder text shown when the input is empty. |\\n| value | `string` | - | Controlled value of the input. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the new string value directly, NOT a React event. |\\n| type | `'text' \\\\| 'email' \\\\| 'password' \\\\| 'number' \\\\| 'tel' \\\\| 'url' \\\\| 'search' \\\\| 'date' \\\\| 'time' \\\\| 'datetime-local'` | `'text'` | HTML input type. Determines browser behavior (keyboard on mobile, validation, masking). The date/time types render the browser's native, localized, keyboard-accessible picker; their `value` stays an ISO string (`'2026-07-29'`, `'14:30'`, `'2026-07-29T14:30'`) delivered through the usual value-first `onChange`. |\\n| error | `string` | - | Error message displayed below the input in `var(--ggui-color-error-500)`. When set, the border turns red and the message element gets `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the input in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute on the `<input>`. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `6px 10px`, font `var(--ggui-font-size-sm)` - `'md'` -- padding `10px 12px`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `12px 14px`, font `var(--ggui-font-size-base)` |\\n\\n**Example:**\\n```tsx\\n<Input label=\\\"Email\\\" type=\\\"email\\\" value={email} onChange={setEmail} error={emailError} />\\n```\\n\\n### TextArea\\n\\nTextArea -- A multiline text input with label, validation, character count, and auto-resize.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<textarea>`,\\nand a footer row with error/helper text on the left and character count on the right.\\n\\nStyling:\\n- Padding: `10px 12px`, font: `var(--ggui-font-size-sm)`, `font-family: inherit`\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Resize: `vertical` by default, `none` when `autoResize` is true\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: same label/error linking pattern as Input (auto-generated ids,\\n`aria-invalid`, `role=\\\"alert\\\"` on error message).\\n\\nAlso extends native `TextareaHTMLAttributes` (except `style`, `className`, `onChange`).\\n\\n**IMPORTANT:** `onChange` receives the string value directly, NOT a React\\n`ChangeEvent`. This differs from native `<textarea>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the textarea. Linked via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| placeholder | `string` | - | Placeholder text shown when the textarea is empty. |\\n| value | `string` | - | Controlled value of the textarea. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the new string value directly, NOT a React event. |\\n| rows | `number` | `4` | Number of visible text rows (native `rows` attribute on `<textarea>`). |\\n| error | `string` | - | Error message displayed below the textarea in `var(--ggui-color-error-500)`. When set, the border turns red and the message element gets `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the textarea in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute on the `<textarea>`. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)`. |\\n| maxLength | `number` | - | Maximum character length (native `maxLength` attribute). Also used as the denominator in the character count display when `showCount` is true. |\\n| showCount | `boolean` | `false` | When true AND `maxLength` is set, displays a `{current}/{max}` character counter in the footer row (right-aligned, `var(--ggui-font-size-xs)`). Has no effect without `maxLength`. |\\n| autoResize | `boolean` | `false` | When true, sets CSS `resize: none` on the textarea. The flag disables manual resizing to signal that external logic handles sizing. The component does NOT auto-adjust height based on content in the current implementation. |\\n\\n**Example:**\\n```tsx\\n<TextArea label=\\\"Bio\\\" value={bio} onChange={setBio} rows={6} maxLength={500} showCount />\\n```\\n\\n### Select\\n\\nSelect -- A native dropdown selection primitive with label and validation.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<select>`\\nwith custom styling, and an optional message `<span>`.\\n\\nThe native `<select>` has `appearance: none` with a custom chevron SVG rendered\\nas a `background-image` (right-aligned, 12px, onSurfaceVariant color). Extra right\\npadding (36px) accommodates the chevron.\\n\\nStyling:\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Text: `var(--ggui-color-onSurface)` when a value is selected,\\n `var(--ggui-color-onSurfaceVariant)` when showing placeholder\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Cursor: `pointer` (normal), `not-allowed` (disabled)\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: auto-generated `id` links `<label>` to `<select>`.\\nWhen `error` is set, `aria-invalid` is true and the message has `role=\\\"alert\\\"`.\\n\\nAlso extends native `SelectHTMLAttributes` (except `style`, `className`,\\n`onChange`, `size`).\\n\\n**IMPORTANT:** `onChange` receives the selected value string directly, NOT a\\nReact `ChangeEvent`. This differs from native `<select>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the select. Linked via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `string` | - | Controlled value. Should match one of the `options[].value` strings. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the selected option's value string directly, NOT a React event. |\\n| options | `SelectOption[]` | - | Array of selectable options. Rendered as native `<option>` elements. Must contain at least one option (or use `placeholder` for an empty-state prompt). |\\n| placeholder | `string` | - | Placeholder text rendered as a disabled `<option value=\\\"\\\">` at the top of the list. Shown when no value is selected. |\\n| error | `string` | - | Error message displayed below the select in `var(--ggui-color-error-500)`. When set, the border turns red and the message has `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the select in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)` and cursor becomes `not-allowed`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `6px 10px`, font `var(--ggui-font-size-sm)` - `'md'` -- padding `10px 12px`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `12px 14px`, font `var(--ggui-font-size-base)` |\\n\\n**Example:**\\n```tsx\\n<Select\\n label=\\\"Country\\\"\\n value={country}\\n onChange={setCountry}\\n options={[\\n { value: 'us', label: 'United States' },\\n { value: 'uk', label: 'United Kingdom' },\\n ]}\\n placeholder=\\\"Select a country\\\"\\n/>\\n```\\n\\n### Checkbox\\n\\nCheckbox -- A custom-styled checkbox with label and description.\\n\\nRenders a `<label>` wrapper containing a visually-hidden native `<input type=\\\"checkbox\\\">`\\noverlaid by a custom 18x18px visual box. Supports checked, unchecked, and indeterminate\\nstates, each with a distinct SVG icon (checkmark or horizontal dash).\\n\\nStyling:\\n- Box border: `2px solid var(--ggui-color-primary-600)` (checked/indeterminate),\\n `var(--ggui-color-outline)` (unchecked)\\n- Box fill: `var(--ggui-color-primary-600)` (checked/indeterminate),\\n `var(--ggui-color-surface)` (unchecked)\\n- Check/dash icon: white SVG, 12x12px\\n- Box radius: `var(--ggui-shape-radius-sm)`\\n- Transition: all 0.2s\\n- Label: `var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`\\n- Description: `var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`\\n- Disabled: `opacity: 0.5`, `cursor: not-allowed`\\n- Gap between box and text: `var(--ggui-spacing-2)`\\n\\n**IMPORTANT:** `onChange` receives the boolean checked state directly, NOT a\\nReact `ChangeEvent`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Primary label text rendered beside the checkbox box. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| checked | `boolean` | - | Controlled checked state. |\\n| onChange | `(checked: boolean) => void` | - | Change handler. Receives the new boolean checked state directly, NOT a React event. |\\n| disabled | `boolean` | `false` | When true, sets `opacity: 0.5` and `cursor: not-allowed`. The native input is also disabled, preventing keyboard and click interaction. |\\n| description | `string` | - | Secondary description text rendered below the label in smaller, muted type (`var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`). |\\n| indeterminate | `boolean` | `false` | When true, displays a horizontal dash instead of a checkmark. Used for \\\"select all\\\" states where some (but not all) children are checked. The `indeterminate` property is set via a ref on the native `<input>`. Visually identical to `checked` in terms of border and fill color. |\\n\\n**Example:**\\n```tsx\\n<Checkbox\\n label=\\\"Accept terms\\\"\\n description=\\\"You agree to the Terms of Service and Privacy Policy\\\"\\n checked={accepted}\\n onChange={setAccepted}\\n/>\\n```\\n\\n### Toggle\\n\\nToggle -- A switch/toggle input rendered as a pill-shaped track with a sliding knob.\\n\\nRenders a `<label>` wrapper with a `<div role=\\\"switch\\\">` track and an animated\\ncircular knob. Does NOT use a native `<input>` -- keyboard interaction is handled\\nmanually (Space and Enter keys toggle the state). The element is focusable via\\n`tabIndex={0}` and shows a focus ring on focus.\\n\\nStyling:\\n- Track (on): `var(--ggui-color-primary-600)`\\n- Track (off): `var(--ggui-color-outline)`\\n- Knob: white circle with `var(--ggui-shape-shadow-sm)`\\n- Focus ring: `0 0 0 3px var(--ggui-color-primary-200)`\\n- Transitions: background-color, box-shadow, knob position at 200ms ease-in-out\\n- Disabled: `opacity: 0.5`, `cursor: not-allowed`, `tabIndex: -1`\\n- Gap between toggle and label: `var(--ggui-spacing-2)`\\n\\n**IMPORTANT:** `onChange` receives the new boolean state directly (inverted from\\ncurrent), NOT a React event.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label text rendered to the right of the toggle track. Also used as `aria-label` on the switch element. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| checked | `boolean` | - | Controlled checked (on/off) state. |\\n| onChange | `(checked: boolean) => void` | - | Change handler. Receives the new boolean state directly (i.e., `!checked`), NOT a React event. |\\n| disabled | `boolean` | `false` | When true, sets `opacity: 0.5`, `cursor: not-allowed`, and removes the element from tab order (`tabIndex: -1`). Click and keyboard handlers are suppressed. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls track and knob dimensions: - `'sm'` -- track 36x20px, knob 16px diameter - `'md'` -- track 44x24px, knob 20px diameter - `'lg'` -- track 52x28px, knob 24px diameter |\\n\\n**Example:**\\n```tsx\\n<Toggle label=\\\"Enable notifications\\\" checked={enabled} onChange={setEnabled} size=\\\"md\\\" />\\n```\\n\\n### RadioGroup\\n\\nRadioGroup -- A group of mutually exclusive radio options with optional label and error.\\n\\nRenders a `<div role=\\\"radiogroup\\\">` containing a label span, a flex container of\\nradio options, and an optional error message. Each option is a `<label>` with a\\nvisually-hidden native `<input type=\\\"radio\\\">` and a custom 18px circle indicator.\\n\\nStyling:\\n- Selected circle: `2px solid var(--ggui-color-primary-600)` border with\\n an 8px `var(--ggui-color-primary-600)` filled inner dot\\n- Unselected circle: `2px solid var(--ggui-color-outline)` border,\\n `var(--ggui-color-surface)` fill\\n- Circle radius: `var(--ggui-shape-radius-full)`\\n- Transition: all 0.2s\\n- Vertical gap: `var(--ggui-spacing-2)`, horizontal gap: `var(--ggui-spacing-4)`\\n- Error: `var(--ggui-font-size-xs)`, `var(--ggui-color-error-500)`,\\n `role=\\\"alert\\\"`\\n- Disabled options: `opacity: 0.5`, `cursor: not-allowed`\\n\\nAccessibility: the group has `role=\\\"radiogroup\\\"` with `aria-labelledby` pointing\\nto the label and `aria-describedby` pointing to the error message (when present).\\nAll radio inputs share a common auto-generated `name` attribute.\\n\\n**IMPORTANT:** `onChange` receives the selected option's value string directly,\\nNOT a React `ChangeEvent`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Group label rendered above the options. Used as `aria-labelledby` target on the `role=\\\"radiogroup\\\"` container. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `string` | - | Controlled value. Should match one of `options[].value`. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the newly selected option's value string directly, NOT a React event. |\\n| options | `RadioOption[]` | - | Array of radio options. Must contain at least two options for meaningful selection. |\\n| direction | `'vertical' \\\\| 'horizontal'` | `'vertical'` | Layout direction for the options container: - `'vertical'` -- column layout, `var(--ggui-spacing-2)` gap - `'horizontal'` -- row layout with `flex-wrap: wrap`, `var(--ggui-spacing-4)` gap |\\n| disabled | `boolean` | `false` | When true, disables ALL options (individual `RadioOption.disabled` is additive). Each option gets `opacity: 0.5` and `cursor: not-allowed`. |\\n| error | `string` | - | Error message displayed below all options in `var(--ggui-color-error-500)` with `role=\\\"alert\\\"`. Linked to the radiogroup via `aria-describedby`. |\\n\\n**Example:**\\n```tsx\\n<RadioGroup\\n label=\\\"Plan\\\"\\n value={plan}\\n onChange={setPlan}\\n options={[\\n { value: 'free', label: 'Free', description: 'Up to 5 projects' },\\n { value: 'pro', label: 'Pro', description: 'Unlimited projects' },\\n ]}\\n/>\\n```\\n\\n### Slider\\n\\nSlider -- A range input with a custom-styled track, fill, and thumb.\\n\\nRenders a `<div>` wrapper containing an optional label/value header, and a\\ntrack area with three layers: background track, colored fill, and a circular\\nthumb. A native `<input type=\\\"range\\\">` is overlaid with `opacity: 0` to\\nprovide accessible keyboard and pointer interaction.\\n\\nStyling:\\n- Track: 6px tall, `var(--ggui-color-outlineVariant)` background, `border-radius: 3px`\\n- Fill: `var(--ggui-color-primary-600)` (normal),\\n `var(--ggui-color-outline)` (disabled)\\n- Thumb: 20px white circle with `2px solid var(--ggui-color-primary-600)`,\\n `var(--ggui-shape-shadow-sm)`; disabled border uses outline\\n- Value display (when `showValue`): `var(--ggui-color-primary-600)`,\\n `var(--ggui-font-size-sm)`, right-aligned in the header row\\n- Fill and thumb transitions: 0.1s for smooth dragging\\n\\nAccessibility: the native `<input type=\\\"range\\\">` carries `aria-valuenow`,\\n`aria-valuemin`, `aria-valuemax`, and is linked to the label via `aria-labelledby`.\\nFalls back to `aria-label=\\\"Slider\\\"` when no label is provided.\\n\\n**IMPORTANT:** `onChange` receives the numeric value directly, NOT a React\\n`ChangeEvent`. The value is coerced via `Number(e.target.value)`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the slider track (left-aligned). Used as `aria-labelledby` target on the native range input. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `number` | `0` | Controlled numeric value. Must be between `min` and `max`. |\\n| onChange | `(value: number) => void` | - | Change handler. Receives the new numeric value directly, NOT a React event. |\\n| min | `number` | `0` | Minimum allowed value. |\\n| max | `number` | `100` | Maximum allowed value. |\\n| step | `number` | `1` | Step increment for the slider. Determines the granularity of selectable values. |\\n| disabled | `boolean` | `false` | When true, sets `cursor: not-allowed` on the native input. The fill color changes to `var(--ggui-color-outline)` and the thumb border also uses outline. |\\n| showValue | `boolean` | `false` | When true, displays the current numeric value right-aligned in the header row (beside the label) in `var(--ggui-color-primary-600)`. |\\n\\n**Example:**\\n```tsx\\n<Slider label=\\\"Volume\\\" value={volume} onChange={setVolume} min={0} max={100} step={5} showValue />\\n```\\n\\n### Badge\\n\\nBadge -- Inline label for status indicators, counts, or categories.\\n\\nRenders a `<span>` with `display: inline-flex`, centered content, and\\n`white-space: nowrap`. Semantic variant colors use background/text pairings\\nfrom the 100/700 color scale. Pill shape uses `border-radius: 9999px`;\\nnon-pill uses `var(--ggui-shape-radius-sm)`.\\n\\nFont weight: `var(--ggui-font-weight-medium)` across all variants.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'default' \\\\| 'primary' \\\\| 'secondary' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info'` | `'default'` | Visual style. Maps to background/text color pairings: - `'default'` -- bg `var(--ggui-color-surfaceVariant)`, text `var(--ggui-color-onSurfaceVariant)` - `'primary'` -- bg `var(--ggui-color-primary-100)`, text `var(--ggui-color-primary-700)` - `'secondary'` -- bg `var(--ggui-color-outlineVariant)`, text `var(--ggui-color-onSurface)` - `'success'` -- bg `var(--ggui-color-success-100)`, text `var(--ggui-color-success-700)` - `'warning'` -- bg `var(--ggui-color-warning-100)`, text `var(--ggui-color-warning-700)` - `'error'` -- bg `var(--ggui-color-error-100)`, text `var(--ggui-color-error-700)` - `'info'` -- bg `var(--ggui-color-info-100)`, text `var(--ggui-color-info-700)` |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `2px 6px`, font `var(--ggui-font-size-xs)` - `'md'` -- padding `2px 8px`, font `var(--ggui-font-size-xs)` - `'lg'` -- padding `4px 10px`, font `var(--ggui-font-size-sm)` |\\n| pill | `boolean` | `true` | When true, uses fully rounded corners (`border-radius: 9999px`). When false, uses `var(--ggui-shape-radius-sm)`. |\\n\\n**Example:**\\n```tsx\\n<Badge variant=\\\"success\\\" size=\\\"sm\\\">Active</Badge>\\n```\\n\\n### Spinner\\n\\nSpinner -- Animated SVG loading indicator.\\n\\nRenders an `<svg>` with `role=\\\"status\\\"` and `aria-label=\\\"Loading\\\"`.\\nThe SVG contains a full outlineVariant background circle and a quarter-arc\\nforeground stroke in the spinner color.\\n\\nAnimation: `ggui-spin 1s linear infinite` (360-degree rotation).\\nThe `@keyframes ggui-spin` definition is injected inline via a `<style>` tag.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| size | `number` | `24` | Width and height of the SVG element in pixels. The internal viewBox is always `0 0 24 24`, so this controls rendered size only. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-primary-600)`)` | Semantic color slot for the animated foreground arc. Same vocabulary as ; the theme decides the resolved value. The background circle always uses `var(--ggui-color-outlineVariant)`. Use `'inherit'` when the spinner sits inside a colored container (e.g. inside a Button) — the stroke picks up `currentColor` from the parent so it tracks the container's foreground. |\\n\\n**Example:**\\n```tsx\\n<Spinner size={32} tone=\\\"success\\\" />\\n```\\n\\n### Avatar\\n\\nAvatar -- User or entity representation with image or auto-generated initials.\\n\\nRenders a `<div role=\\\"img\\\">` with `overflow: hidden` and `flex-shrink: 0`.\\nWhen `src` is provided and loads successfully, renders an `<img>` with\\n`object-fit: cover`. On image error (or when no `src`), falls back to\\ninitials derived from `name` (up to 2 characters, uppercase).\\n\\nInitials background: deterministic color from a 5-color palette based on\\nname hash (primary-500, success-500, warning-500, error-500, info-500).\\nFalls back to `var(--ggui-color-outline)` when no name is given.\\nInitials text: white, `font-weight: var(--ggui-font-weight-semibold)`,\\n`font-size: resolvedSize * 0.4`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| src | `string` | - | Image URL. When provided and the image loads, it is rendered with `object-fit: cover`. On load error, falls back to initials. |\\n| name | `string` | - | Name used for two purposes: 1. Generating initials (splits on spaces, takes first letter of each word, max 2). 2. Deterministic background color selection via character code hash. Also used as `aria-label` on the container. Falls back to `'Avatar'` if omitted. |\\n| size | `number \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'` | `'md'` | Avatar dimensions. Named sizes map to pixel values: - `'xs'` -- 24px - `'sm'` -- 32px - `'md'` -- 40px - `'lg'` -- 48px - `'xl'` -- 64px Numeric values are used directly as pixel dimensions. |\\n| shape | `'circle' \\\\| 'square'` | `'circle'` | Container shape. - `'circle'` -- `border-radius: 50%` - `'square'` -- `border-radius: var(--ggui-shape-radius-md)` |\\n\\n**Example:**\\n```tsx\\n<Avatar src=\\\"/photos/jane.jpg\\\" name=\\\"Jane Doe\\\" size=\\\"lg\\\" shape=\\\"circle\\\" />\\n```\\n\\n### Alert\\n\\nAlert -- Contextual message box for important information with icon and optional dismiss.\\n\\nRenders a `<div role=\\\"alert\\\">` with flex layout (12px gap), variant-specific\\nbackground, border, text color, and a leading icon. Each variant provides a\\ndefault SVG icon (info circle, checkmark, warning triangle, or X circle) that\\ncan be overridden via the `icon` prop.\\n\\nLayout: icon (flex-shrink: 0) | content column (title + body) | close button.\\nBorder radius: `var(--ggui-shape-radius-lg)`.\\nPadding: `12px 16px`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'info'` | Visual style. Maps to background/border/text/icon color sets: - `'info'` -- bg `var(--ggui-color-info-50)`, border `var(--ggui-color-info-200)`, text `var(--ggui-color-info-800)`, icon `var(--ggui-color-info-500)` - `'success'` -- bg `var(--ggui-color-success-50)`, border `var(--ggui-color-success-200)`, text `var(--ggui-color-success-800)`, icon `var(--ggui-color-success-500)` - `'warning'` -- bg `var(--ggui-color-warning-50)`, border `var(--ggui-color-warning-200)`, text `var(--ggui-color-warning-800)`, icon `var(--ggui-color-warning-500)` - `'error'` -- bg `var(--ggui-color-error-50)`, border `var(--ggui-color-error-200)`, text `var(--ggui-color-error-800)`, icon `var(--ggui-color-error-500)` |\\n| title | `string` | - | Optional title rendered above the body in semibold (`var(--ggui-font-weight-semibold)`), `var(--ggui-font-size-sm)`. Title and body are separated by `var(--ggui-spacing-1)` gap. |\\n| closable | `boolean` | `false` | When true, renders a close button (X icon) in the top-right area. The button has `min-width: 28px`, `min-height: 28px`, and `opacity: 0.7`. Requires `onClose` to be functional. |\\n| onClose | `() => void` | - | Callback fired when the close button is clicked. Only relevant when `closable` is true. |\\n| icon | `ReactNode` | - | Custom icon ReactNode to replace the default variant icon. Rendered at the leading position with the variant's icon color applied via `color` CSS property. |\\n\\n**Example:**\\n```tsx\\n<Alert variant=\\\"warning\\\" title=\\\"Rate limit\\\" closable onClose={() => setShow(false)}>\\n You have 3 requests remaining this minute.\\n</Alert>\\n```\\n\\n### Progress\\n\\nProgress -- Horizontal progress bar with determinate and indeterminate modes.\\n\\nRenders a track `<div role=\\\"progressbar\\\">` with a colored fill child.\\nThe track background is `var(--ggui-color-outlineVariant)` with\\npill-shaped corners (border-radius = height / 2).\\n\\nDeterminate mode: fill width transitions smoothly (`width 0.3s ease`).\\nIndeterminate mode: fill is 30% width, animated with\\n`ggui-progress-indeterminate 1.5s ease-in-out infinite`\\n(translateX from -100% to 400%). The `@keyframes` are injected inline.\\n\\nAccessibility: `aria-valuenow` is set in determinate mode, omitted in\\nindeterminate. `aria-valuemin` is always 0, `aria-valuemax` matches `max`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `number` | - | Current progress value. Clamped to `[0, max]` and converted to a percentage for the fill width: `Math.min(100, Math.max(0, (value / max) * 100))`. |\\n| max | `number` | `100` | Maximum value representing 100% progress. |\\n| variant | `'default' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'default'` | Fill bar color. Maps to CSS variables: - `'default'` -- `var(--ggui-color-primary-600)` - `'success'` -- `var(--ggui-color-success-500)` - `'warning'` -- `var(--ggui-color-warning-500)` - `'error'` -- `var(--ggui-color-error-500)` |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls track height in pixels: - `'sm'` -- 4px - `'md'` -- 8px - `'lg'` -- 12px |\\n| label | `string` | - | Accessible name describing what this bar measures, e.g. `\\\"Survey progress\\\"` or `\\\"Upload\\\"`. Becomes the progressbar's `aria-label` and — when `showLabel` is set — the visible header text in place of the generic word \\\"Progress\\\". Always pass this when the surrounding context does not already make the meaning obvious. |\\n| showLabel | `boolean` | `false` | When true, displays a header row above the track with the `label` text (or \\\"Progress\\\" if `label` is unset) on the left, and the rounded percentage value on the right. |\\n| indeterminate | `boolean` | `false` | When true, ignores `value` for visual width and plays a looping animation instead. The fill bar is 30% width and slides across the track. Animation: `ggui-progress-indeterminate 1.5s ease-in-out infinite`. `aria-valuenow` is omitted from the progressbar element. |\\n\\n**Example:**\\n```tsx\\n<Progress value={65} variant=\\\"success\\\" size=\\\"md\\\" showLabel />\\n```\\n\\n### Image\\n\\nImage -- An `<img>` element with built-in error handling and fallback support.\\n\\nRenders a native `<img>` with `display: block`. On load error, either renders\\nthe `fallback` ReactNode (if provided) or a default placeholder `<div>` with a\\nsurfaceVariant background and a centered image SVG icon in outline.\\n\\nSize values: numbers are treated as pixels, strings are passed through as-is.\\nWhen no `width` is set, defaults to `100%`. When no `height` is set, defaults\\nto `auto`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| src | `string` | - | Image source URL. Load failure triggers the fallback state. |\\n| alt | `string` | - | Alt text for the image. Used as `aria-label` in the error placeholder too. |\\n| width | `number \\\\| string` | `'100%' (applied at render time, not on the type)` | Image width. Numbers are pixels, strings are CSS values (e.g., `'100%'`, `'50vw'`). |\\n| height | `number \\\\| string` | `'auto' (applied at render time, not on the type)` | Image height. Numbers are pixels, strings are CSS values. |\\n| objectFit | `'cover' \\\\| 'contain' \\\\| 'fill' \\\\| 'none' \\\\| 'scale-down'` | `'cover'` | CSS `object-fit` value controlling how the image fills its box. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | - | Corner radius applied to both the image and the error placeholder. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through. |\\n| fallback | `ReactNode` | - | Custom ReactNode rendered when the image fails to load. When provided, completely replaces the default error placeholder (no wrapper div). When omitted, a surfaceVariant background div with an image icon is shown. |\\n\\n**Example:**\\n```tsx\\n<Image src=\\\"/hero.jpg\\\" alt=\\\"Hero banner\\\" width=\\\"100%\\\" height={400} objectFit=\\\"cover\\\" radius=\\\"md\\\" />\\n```\\n\\n### Icon\\n\\nIcon -- 185 Lucide icons + emoji passthrough.\\n\\nThree resolution layers:\\n1. **Lucide icon:** pass any common Lucide icon name (e.g. `sun`, `cloud-rain`, `heart`, `shopping-cart`).\\n Accepts kebab-case, camelCase, or PascalCase. Renders as stroke SVG.\\n2. **Emoji:** pass emoji/unicode directly (e.g. `☀️`, `🌧️`). Rendered as text.\\n3. **Custom SVG:** pass children (`<svg>` element) for full control.\\n\\nContainer: `<span>` with `display: inline-flex`, centered content.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| name | `string` | - | Lucide icon name (kebab-case, camelCase, or PascalCase all work). Also accepts emoji/unicode characters directly. |\\n| size | `number` | `24` | Icon dimensions in pixels (applied to both width and height of the wrapper and the inner SVG element). |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (icon uses `currentColor`)` | Semantic color slot. Same vocabulary as ; the theme decides what each tone LOOKS like. Resolves to a CSS `color` on the wrapper which the inner SVG inherits via `currentColor`. Use `'inherit'` (the default behavior when unset) for icons that should pick up the parent's foreground color. |\\n| children | `ReactNode` | - | Custom SVG children. When provided, `name` is ignored and children are rendered inside a sized `<span>` wrapper. |\\n| 'aria-label' | `string` | - | Accessible name for a standalone, meaning-bearing icon. When set, the icon exposes `role=\\\"img\\\"` + this label. When omitted (the default) the icon is decorative and hidden from screen readers (`aria-hidden`) — the right choice for an icon next to a text label. |\\n\\n**Example:**\\n```tsx\\n<Icon name=\\\"search\\\" size={20} tone=\\\"muted\\\" />\\n<Icon name=\\\"cloud-rain\\\" size={32} />\\n<Icon name=\\\"☀️\\\" size={24} />\\n```\\n\\n### Link\\n\\nLink -- Styled anchor element with external link support.\\n\\nRenders a native `<a>` element. When `external` is true, sets\\n`target=\\\"_blank\\\"` and `rel=\\\"noopener noreferrer\\\"`, and appends a small\\n(12px) external-link SVG icon after the children.\\n\\nTransition: `color 0.2s`.\\nUnderline behavior is controlled via mouseEnter/mouseLeave event handlers\\n(for the `'hover'` mode).\\n\\nAlso extends native `AnchorHTMLAttributes` (except `style`/`className`),\\nso props like `aria-*`, `data-*`, `title`, etc. are forwarded to the `<a>`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| href | `string` | - | Destination URL. Passed directly to the `<a href>` attribute. |\\n| external | `boolean` | `false` | When true, opens link in a new tab (`target=\\\"_blank\\\"`, `rel=\\\"noopener noreferrer\\\"`) and appends a 12px external-link icon after children. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-primary-600)`)` | Semantic color slot for the link text. Same vocabulary as ; the theme decides what each tone LOOKS like. Defaults to a primary-tinted accent (`'loud'`-ish) when unset. |\\n| underline | `'always' \\\\| 'hover' \\\\| 'none'` | `'hover'` | Underline behavior: - `'always'` -- `text-decoration: underline` at all times - `'hover'` -- underline appears on mouse enter, removed on mouse leave - `'none'` -- no underline ever |\\n\\n**Example:**\\n```tsx\\n<Link href=\\\"https://docs.ggui.ai\\\" external>Documentation</Link>\\n```\\n\\n### Tooltip\\n\\nTooltip -- Hoverable information popup positioned relative to a trigger element.\\n\\nWraps `children` in a `<div>` trigger (display: inline-block) and renders\\na fixed-position tooltip `<div role=\\\"tooltip\\\">` when visible.\\n\\nTooltip appearance:\\n- Background: `var(--ggui-color-onSurface)`\\n- Text: white, `var(--ggui-font-size-xs)`\\n- Padding: `6px 10px`, border-radius: `var(--ggui-shape-radius-md)`\\n- Max width: 200px, `white-space: nowrap`, `pointer-events: none`\\n- Z-index: `zIndex.tooltip` (1800)\\n\\nShow/hide: triggered by mouseEnter/mouseLeave AND focus/blur on the\\ntrigger element. Uses `position: fixed` with coordinates calculated from\\n`getBoundingClientRect()` and an 8px offset from the trigger edge.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Trigger element. Wrapped in a `<div>` with mouseEnter/mouseLeave and focus/blur handlers. |\\n| content | `ReactNode` | - | Tooltip content. Can be text or any ReactNode. |\\n| position | `'top' \\\\| 'bottom' \\\\| 'left' \\\\| 'right'` | `'top'` | Tooltip placement relative to the trigger element: - `'top'` -- above, centered horizontally, transformed `translateX(-50%) translateY(-100%)` - `'bottom'` -- below, centered horizontally, transformed `translateX(-50%)` - `'left'` -- to the left, centered vertically, transformed `translateX(-100%) translateY(-50%)` - `'right'` -- to the right, centered vertically, transformed `translateY(-50%)` |\\n| delay | `number` | `200` | Delay in milliseconds before the tooltip becomes visible after hover/focus. Hiding is immediate (no delay). |\\n\\n**Example:**\\n```tsx\\n<Tooltip content=\\\"Copy to clipboard\\\" position=\\\"top\\\">\\n <Button variant=\\\"ghost\\\"><Icon name=\\\"copy\\\" /></Button>\\n</Tooltip>\\n```\\n\\n### Table\\n\\nTable -- Data table with sortable columns, striped rows, and hover highlights.\\n\\nRenders a scrollable wrapper `<div>` containing a native `<table>` with\\n`border-collapse: collapse` and `width: 100%`. The wrapper has\\n`overflow-x: auto` for horizontal scrolling on narrow viewports.\\n\\nHeader row: 2px bottom border (`var(--ggui-color-outlineVariant)`).\\nData rows: 1px bottom border (`var(--ggui-color-surfaceVariant)`).\\nHover: `var(--ggui-color-surface)` background with 150ms ease transition.\\nStriped: alternating rows (odd index) get `var(--ggui-color-surface)`.\\n\\nSort behavior: clicking a sortable column header calls `onSort(key, direction)`.\\nIf the same column is clicked again while ascending, it toggles to descending.\\nThe component does NOT sort data internally -- the parent must sort `data` and\\npass updated `sortKey`/`sortDirection`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| columns | `TableColumn<T>[]` | - | Array of column definitions controlling header labels, data keys, and rendering. |\\n| data | `T[]` | - | Array of row data objects. Each object's keys should match the column `key` values. |\\n| sortKey | `string` | - | The `key` of the currently sorted column. Used to highlight the active sort indicator and determine toggle direction on next click. |\\n| sortDirection | `SortDirection` | `'asc'` | Current sort direction for the column identified by `sortKey`. Controls which triangle indicator is highlighted in the header. |\\n| onSort | `(key: string, direction: SortDirection) => void` | - | Sort change handler. Called when a sortable column header is clicked. Receives the column `key` and the new `SortDirection`. The component does NOT sort data internally -- you must sort `data` in your state and pass updated `sortKey`/`sortDirection`. |\\n| striped | `boolean` | `false` | When true, alternating rows (odd index) get a `var(--ggui-color-surface)` background. |\\n| hoverable | `boolean` | `true` | When true, rows highlight with `var(--ggui-color-surface)` on mouse enter, with a 150ms ease background-color transition. |\\n| compact | `boolean` | `false` | When true, reduces cell padding: - Compact: `var(--ggui-spacing-1) var(--ggui-spacing-2)` - Normal: `var(--ggui-spacing-2) var(--ggui-spacing-4)` |\\n| bordered | `boolean` | `false` | When true, adds a 1px border around the table wrapper and between cells. Wrapper border: `1px solid var(--ggui-color-outlineVariant)`. Cell borders: `1px solid var(--ggui-color-surfaceVariant)`. Wrapper border-radius: `var(--ggui-shape-radius-lg)`. |\\n| caption | `string` | - | Accessible table caption. Rendered as a `<caption>` element with `caption-side: top`, `var(--ggui-font-size-sm)`, `var(--ggui-color-onSurfaceVariant)`. |\\n\\n**Example:**\\n```tsx\\n<Table\\n columns={[\\n { key: 'name', header: 'Name', sortable: true },\\n { key: 'role', header: 'Role' },\\n { key: 'status', header: 'Status', render: (v) => <Badge variant={v as string}>{v as string}</Badge> },\\n ]}\\n data={users}\\n sortKey={sortKey}\\n sortDirection={sortDir}\\n onSort={(key, dir) => { setSortKey(key); setSortDir(dir); }}\\n striped\\n/>\\n```\\n\\n### Tabs\\n\\nTabs -- Accessible tab navigation with panels and keyboard support.\\n\\nRenders a `<div role=\\\"tablist\\\">` with `<button role=\\\"tab\\\">` elements and a\\n`<div role=\\\"tabpanel\\\">` for the active tab's content. Supports controlled\\n(`activeKey` + `onChange`) and uncontrolled (internal state) modes.\\n\\nKeyboard navigation: ArrowLeft/ArrowRight (and ArrowUp/ArrowDown) cycle\\nthrough enabled tabs. Home/End jump to first/last. Focus follows selection.\\nDisabled tabs are skipped during keyboard navigation.\\n\\n**IMPORTANT:** `onChange` receives the tab's `key` string directly, NOT a\\nReact event.\\n\\nTab panel padding: `var(--ggui-spacing-4) 0` (top/bottom only).\\nTransitions: color, background-color, border-color at 200ms ease-in-out.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `TabItem[]` | - | Array of tab definitions. Must contain at least one item. |\\n| activeKey | `string` | - | Controlled active tab key. When provided, the component is controlled and will not manage its own state. Must match one of `items[].key`. When omitted, defaults to the first item's key (uncontrolled mode). |\\n| onChange | `(key: string) => void` | - | Tab change handler. Receives the selected tab's `key` string directly, NOT a React event. In controlled mode, you must update `activeKey` in response to this callback. |\\n| variant | `'line' \\\\| 'pills' \\\\| 'enclosed'` | `'line'` | Visual style of the tab bar: - `'line'` -- underline indicator (2px solid primary-600 on active), border-bottom on tab list - `'pills'` -- filled pill buttons (primary-600 bg, white text on active), surfaceVariant container with radius-lg - `'enclosed'` -- bordered tab buttons with open bottom (card-style), border-bottom on tab list |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls tab button padding and font size: - `'sm'` -- padding `var(--ggui-spacing-1) var(--ggui-spacing-2)`, font `var(--ggui-font-size-xs)` - `'md'` -- padding `var(--ggui-spacing-2) var(--ggui-spacing-4)`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `var(--ggui-spacing-4) var(--ggui-spacing-6)`, font `var(--ggui-font-size-base)` |\\n| fullWidth | `boolean` | `false` | When true, tab buttons expand equally to fill the container width (`flex: 1`, `justify-content: center` on each button). |\\n\\n**Example:**\\n```tsx\\n<Tabs\\n variant=\\\"pills\\\"\\n items={[\\n { key: 'overview', label: 'Overview', content: <Overview /> },\\n { key: 'settings', label: 'Settings', content: <Settings /> },\\n ]}\\n activeKey={tab}\\n onChange={setTab}\\n/>\\n```\\n\\n### Toast\\n\\nToast -- Notification banner with auto-dismiss and slide-in animation.\\n\\nRenders a `<div role=\\\"alert\\\" aria-live=\\\"assertive\\\">` with a variant-specific\\nicon, optional title, message body, and optional close button.\\n\\nAnimation: `ggui-slideInUp 200ms ease-out both` on mount (from the motion\\ntoken system). The keyframes are provided by the MotionKeyframes provider.\\n\\nAuto-dismiss: when `onClose` is provided and `duration > 0`, a timer calls\\n`onClose` after `duration` ms. Setting `duration` to `0` disables auto-dismiss.\\nThe timer resets if `visible`, `duration`, or `onClose` changes.\\n\\nDimensions: `min-width: 280px`, `max-width: 420px`.\\nShadow: `var(--ggui-shape-shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1))`.\\nBorder radius: `var(--ggui-shape-radius-lg)`.\\n\\nWhen `visible` is false, renders nothing (returns `null`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| message | `ReactNode` | - | Message body content. Can be text or any ReactNode. |\\n| variant | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'info'` | Visual style. Maps to background/border/text/icon color sets (same palette as Alert): - `'info'` -- bg `var(--ggui-color-info-50)`, border `var(--ggui-color-info-200)`, text `var(--ggui-color-info-800)` - `'success'` -- bg `var(--ggui-color-success-50)`, border `var(--ggui-color-success-200)`, text `var(--ggui-color-success-800)` - `'warning'` -- bg `var(--ggui-color-warning-50)`, border `var(--ggui-color-warning-200)`, text `var(--ggui-color-warning-800)` - `'error'` -- bg `var(--ggui-color-error-50)`, border `var(--ggui-color-error-200)`, text `var(--ggui-color-error-800)` |\\n| title | `string` | - | Optional title rendered above the message in semibold (`var(--ggui-font-weight-semibold)`, `var(--ggui-font-size-sm)`). |\\n| duration | `number` | `5000` | Auto-dismiss delay in milliseconds. After this duration, `onClose` is called automatically. Set to `0` to disable auto-dismiss (toast stays until manually closed). The timer is only active when both `visible` is true and `onClose` is provided. |\\n| onClose | `() => void` | - | Callback fired on auto-dismiss timeout or when the close button is clicked. When provided, a close button (X icon, 16px) is rendered in the top-right area. When omitted, no close button is shown and auto-dismiss is disabled. |\\n| visible | `boolean` | `true` | Controls rendering. When false, the component returns `null`. Toggling from false to true triggers the slide-in animation. |\\n| position | `'top-right' \\\\| 'top-left' \\\\| 'bottom-right' \\\\| 'bottom-left' \\\\| 'top-center' \\\\| 'bottom-center'` | - | Intended screen position. This prop is defined on the interface but is NOT implemented by the Toast component itself -- positioning must be handled by a parent container or toast manager. |\\n\\n**Example:**\\n```tsx\\n<Toast variant=\\\"success\\\" title=\\\"Saved\\\" message=\\\"Your changes have been saved.\\\" onClose={() => setShow(false)} />\\n```\\n\\n### Accordion\\n\\nAccordion -- Collapsible content sections with chevron rotation animation.\\n\\nRenders a vertical list of items, each with a `<button>` header (inside `<h3>`)\\nand a `<div role=\\\"region\\\">` panel. Supports controlled (`expandedKeys` + `onChange`)\\nand uncontrolled (internal state) modes.\\n\\nChevron animation: the trailing chevron icon rotates from 0deg (collapsed) to\\n180deg (expanded) with `transition: transform 200ms ease-in-out`.\\n\\nHeader button: full-width flex layout (`justify-content: space-between`),\\n`var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`,\\n`var(--ggui-color-onSurface)`.\\nHeader padding: `var(--ggui-spacing-2) var(--ggui-spacing-4)`.\\nBackground transition: `background-color 100ms ease-in-out`.\\n\\n**IMPORTANT:** `onChange` receives the full array of currently expanded keys,\\nNOT a single key or a React event. In single mode (`multiple: false`), this\\narray will have at most one element.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `AccordionItem[]` | - | Array of collapsible section definitions. |\\n| expandedKeys | `string[]` | - | Controlled expanded state. Array of item `key` values that should be open. When provided, the component is controlled and will not manage its own expansion state. When omitted, defaults to `[]` (all collapsed, uncontrolled mode). |\\n| onChange | `(expandedKeys: string[]) => void` | - | Expand/collapse handler. Receives the complete array of expanded keys after a toggle. In controlled mode, you must update `expandedKeys` in response to this callback. |\\n| multiple | `boolean` | `false` | When true, multiple items can be open simultaneously. When false, opening one item closes any other open item (single-expand mode). |\\n| variant | `'default' \\\\| 'bordered' \\\\| 'separated'` | `'default'` | Visual style controlling borders and spacing: - `'default'` -- top border on first item, bottom border on all items (`var(--ggui-color-outlineVariant)`), no gap between items - `'bordered'` -- connected card style with left/right/bottom borders on all items, top border on first, shared rounded corners (radius-lg on first/last) - `'separated'` -- each item is an independent card with full border (`1px solid var(--ggui-color-outlineVariant)`), `var(--ggui-shape-radius-lg)` radius, `var(--ggui-spacing-2)` gap between items |\\n\\n**Example:**\\n```tsx\\n<Accordion\\n variant=\\\"separated\\\"\\n items={[\\n { key: 'faq1', title: 'How do I get started?', content: 'Sign up and...' },\\n { key: 'faq2', title: 'What is the pricing?', content: 'We offer...' },\\n ]}\\n expandedKeys={expanded}\\n onChange={setExpanded}\\n multiple\\n/>\\n```\\n\\n### Support Types\\n\\n**ResponsiveColumns:**\\n\\nExplicit column count per viewport breakpoint, mobile-first. `base`\\napplies from 0 up; each named key overrides at and above its\\nbreakpoint width (`sm` 640px, `md` 768px, `lg` 1024px, `xl` 1280px).\\nOmit `base` to default to a single column on the narrowest screens.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| base | `number` | Columns below the `sm` breakpoint. |\\n| sm | `number` | Columns from 640px up. |\\n| md | `number` | Columns from 768px up. |\\n| lg | `number` | Columns from 1024px up. |\\n| xl | `number` | Columns from 1280px up. |\\n\\n**SelectOption:**\\n\\nAn individual option within a `Select` dropdown.\\n\\nRendered as a native `<option>` element. When `disabled` is true, the option\\nis visible but not selectable.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | The value submitted when this option is selected. Must be unique within the options array. |\\n| label | `string` | The display text shown in the dropdown. |\\n| disabled | `boolean` | When true, the option is visible but cannot be selected (grayed out by the browser). |\\n\\n**RadioOption:**\\n\\nAn individual option within a `RadioGroup`.\\n\\nRendered as a `<label>` containing a visually-hidden `<input type=\\\"radio\\\">`\\nand a custom 18px circle indicator. Supports an optional description line\\nbelow the label text.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | The value emitted via `RadioGroupProps.onChange` when this option is selected. Must be unique. |\\n| label | `string` | Display text for this option. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| description | `string` | Optional secondary description rendered below the label in smaller, muted type (`var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`). |\\n| disabled | `boolean` | When true, this individual option is grayed out (`opacity: 0.5`) and cannot be selected, regardless of the group-level `disabled` prop. |\\n\\n**TableColumn:**\\n\\nColumn definition for the Table component.\\n\\nEach column maps a `key` in the row data object to a table column with\\na header label, optional sorting, alignment, width, and custom rendering.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Property key in the row data object. Used to extract cell values via `row[key]`. Must be unique across all columns in a Table. |\\n| header | `string` | Column header text. Rendered in uppercase, `var(--ggui-font-size-xs)`, `var(--ggui-font-weight-semibold)`, `var(--ggui-color-onSurfaceVariant)`, with `letter-spacing: 0.05em`. |\\n| width | `number \\\\| string` | Fixed column width. Numbers are pixels, strings are CSS values (e.g., `'200px'`, `'30%'`). When omitted, the column auto-sizes based on content. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | Horizontal text alignment for both the header and data cells. |\\n| sortable | `boolean` | When true, the header cell becomes clickable and shows sort direction indicators (ascending/descending triangles). Clicking toggles between `'asc'` and `'desc'`. The header gets `cursor: pointer`, `tabIndex: 0`, and keyboard support (Enter/Space to toggle). |\\n| render | `(value: unknown, row: T, index: number) => ReactNode` | Custom cell renderer. When provided, called instead of rendering `row[key]` directly. Receives the cell value, the full row object, and the row index. |\\n\\n**TabItem:**\\n\\nDefinition of a single tab within a Tabs component.\\n\\nEach item provides a unique `key` for identification, a `label` for the\\ntab button, and `content` for the associated panel.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Unique identifier for this tab. Used to match `activeKey` and as the value passed to `onChange`. |\\n| label | `ReactNode` | Tab button label. Can be text or any ReactNode. |\\n| content | `ReactNode` | Panel content rendered below the tab bar when this tab is active. |\\n| disabled | `boolean` | When true, the tab button shows `opacity: 0.5`, `cursor: not-allowed`, and cannot be selected via click or keyboard navigation. |\\n| icon | `ReactNode` | Optional icon rendered before the label inside the tab button, with `var(--ggui-spacing-1)` gap between icon and label. |\\n\\n**AccordionItem:**\\n\\nDefinition of a single collapsible section within an Accordion.\\n\\nEach item provides a unique `key`, a clickable `title` for the header button,\\nand `content` revealed when expanded.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Unique identifier for this item. Used in `expandedKeys` and passed to `onChange`. |\\n| title | `ReactNode` | Header label rendered inside the toggle button. Can be text or any ReactNode. |\\n| content | `ReactNode` | Panel content rendered below the header when expanded. Styled with `var(--ggui-font-size-sm)`, `var(--ggui-color-onSurfaceVariant)`, `line-height: var(--ggui-font-lineHeight-normal, 1.5)`. Padding: `0 var(--ggui-spacing-4) var(--ggui-spacing-4)`. |\\n| disabled | `boolean` | When true, the header button shows `opacity: 0.5`, `cursor: not-allowed`, and cannot be toggled. |\\n\\n\\n## Components\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### SearchField\\n\\nA text input with a leading search icon and optional submit button.\\n\\nComposes: `Input` (native `<input type=\\\"search\\\">`), `Button`, `Spinner`, `Icon`.\\n\\nSupports controlled and uncontrolled usage. When `value` is `undefined` the\\ncomponent tracks its own state internally. Pressing **Enter** triggers\\n`onSearch` with the current value. When `loading` is `true` the search icon\\nis replaced by a `Spinner` and the input is disabled.\\n\\nTokens used: `colors.gray[300]` border, `colors.gray[50]` disabled bg,\\n`colors.gray[400]` icon color, `colors.gray[900]` text color.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `string` | - | Current search value. When provided, the component is **controlled** and the caller must update this via `onChange`. When omitted, the component manages its own internal state. |\\n| onChange | `(value: string) => void` | - | Called on every keystroke with the new input string (value directly, not a React `ChangeEvent`). |\\n| onSearch | `(value: string) => void` | - | Called when the user presses **Enter** or clicks the search button (if `showButton` is `true`). Receives the current value directly. |\\n| placeholder | `string` | `'Search...'` | Placeholder text shown when the input is empty. |\\n| showButton | `boolean` | `false` | When `true`, renders a `Button` primitive to the right of the input. The button's label is set by `buttonText`. |\\n| buttonText | `string` | `'Search'` | Label rendered inside the submit button. Only visible when `showButton` is `true`. |\\n| loading | `boolean` | - | When `true`, replaces the search icon with a `Spinner`, disables the input, and disables the submit button. |\\n| disabled | `boolean` | - | When `true`, the input and button are visually disabled and do not respond to interaction. The input background changes to `colors.gray[50]`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls input height and font size. - `'sm'` -- 6px vertical padding, 14px font - `'md'` -- 10px vertical padding, 14px font - `'lg'` -- 12px vertical padding, 16px font The Button size maps `sm`->`sm`, `md`->`md`, `lg`->`md`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<SearchField\\n value={query}\\n onChange={setQuery}\\n onSearch={(q) => fetchResults(q)}\\n placeholder=\\\"Search products...\\\"\\n showButton\\n buttonText=\\\"Go\\\"\\n size=\\\"md\\\"\\n/>\\n```\\n```\\n\\n### FormField\\n\\nA wrapper that adds a label, optional description, error message,\\nand helper text around any form input passed as `children`.\\n\\nComposes: no other primitives -- pure layout with semantic `<label>` and\\n`<span>` elements.\\n\\nVisual hierarchy (top to bottom):\\n1. **Label** (required) -- `fontSize.sm`, `fontWeight.medium`, `colors.gray[700]`\\n2. **Required indicator** -- red asterisk (`colors.error[500]`) appended to label\\n3. **Description** -- `fontSize.xs`, `colors.gray[500]`, 4px bottom margin\\n4. **Children** -- the form control itself\\n5. **Error / Helper text** -- `fontSize.xs`; error in `colors.error[500]`,\\n helper in `colors.gray[500]`. Error takes priority when both are provided.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Text rendered inside the `<label>` element above the input. |\\n| children | `ReactNode` | - | The form control (typically an `Input`, `Select`, or `Textarea` primitive) rendered between the label/description and the error/helper row. |\\n| error | `string` | - | Error message displayed below `children` in `colors.error[500]`. When present, it takes precedence over `helperText`. |\\n| helperText | `string` | - | Neutral guidance text displayed below `children` in `colors.gray[500]`. Hidden when `error` is present. |\\n| required | `boolean` | - | When `true`, appends a red asterisk (`*`) after the label text. Does **not** add any HTML validation attributes -- handle that on the child input. |\\n| description | `string` | - | Secondary description rendered between the label and the child control in `fontSize.xs` / `colors.gray[500]`. Use for longer guidance that does not belong in `helperText`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<FormField\\n label=\\\"Email address\\\"\\n required\\n description=\\\"We will never share your email.\\\"\\n error={errors.email}\\n>\\n <Input value={email} onChange={setEmail} placeholder=\\\"you@example.com\\\" />\\n</FormField>\\n```\\n```\\n\\n### MenuItem\\n\\nA full-width clickable row for menus, sidebars, and action lists.\\n\\nComposes: none -- renders a native `<button>` element.\\n\\nBuilt-in transition: `background-color 0.15s` on hover.\\n\\nColor logic:\\n- **Normal**: text `colors.gray[700]`, hover bg `colors.gray[100]`\\n- **Active**: bg `colors.primary[50]`, text `colors.gray[700]`, `fontWeight.medium`\\n- **Danger**: text `colors.error[600]`, hover bg `colors.error[50]`, active bg `colors.error[100]`\\n- **Disabled**: text `colors.gray[400]`, `cursor: not-allowed`\\n\\nLayout: flexbox row with `8px` gap, `8px 12px` padding, `radius.md` border-radius.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Primary text content of the menu item. |\\n| icon | `ReactNode` | - | Icon or element rendered to the left of the label. Flex-shrink 0. |\\n| rightElement | `ReactNode` | - | Element rendered to the right of the label (e.g., a keyboard shortcut badge or a count). Colored `colors.gray[400]`, flex-shrink 0. |\\n| onClick | `() => void` | - | Called when the item is clicked. Suppressed when `disabled` is `true`. |\\n| disabled | `boolean` | - | When `true`, the item is non-interactive: `colors.gray[400]` text, `cursor: not-allowed`, click handler suppressed. |\\n| active | `boolean` | - | Marks this item as the current selection. Applies a tinted background (`colors.primary[50]`, or `colors.error[100]` when `danger` is also set) and `fontWeight.medium`. |\\n| danger | `boolean` | - | Switches the item to destructive styling: `colors.error[600]` text, `colors.error[50]` hover background. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<MenuItem\\n label=\\\"Delete project\\\"\\n icon={<Icon name=\\\"trash\\\" size={16} />}\\n danger\\n onClick={() => confirmDelete(projectId)}\\n/>\\n```\\n```\\n\\n### Tag\\n\\nAn inline label for categories, filters, statuses, or selections.\\nOptionally dismissable via a close button.\\n\\nComposes: none -- pure `<span>` with an optional close `<button>`.\\n\\nEach `variant` maps to a background / text / border color triple from the\\ndesign tokens:\\n- `'default'` -- `gray[100]` / `gray[700]` / `gray[200]`\\n- `'primary'` -- `primary[50]` / `primary[700]` / `primary[200]`\\n- `'success'` -- `success[50]` / `success[700]` / `success[200]`\\n- `'warning'` -- `warning[50]` / `warning[700]` / `warning[200]`\\n- `'error'` -- `error[50]` / `error[700]` / `error[200]`\\n- `'info'` -- `info[50]` / `info[700]` / `info[200]`\\n\\nThe close button renders an inline SVG \\\"x\\\" icon (12x12) with `opacity: 0.7`\\nand an `aria-label=\\\"Remove\\\"`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Tag content -- typically a short text string. |\\n| variant | `'default' \\\\| 'primary' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info'` | `'default'` | Semantic color variant applied to background, text, and border. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding, font size, and internal gap. - `'sm'` -- 2px/6px padding, `fontSize.xs`, 4px gap - `'md'` -- 4px/8px padding, `fontSize.xs`, 6px gap - `'lg'` -- 6px/10px padding, `fontSize.sm`, 6px gap |\\n| closable | `boolean` | - | When `true`, renders a small close (\\\"x\\\") button after the content. Clicking it fires `onClose`. |\\n| onClose | `() => void` | - | Called when the close button is clicked. Only relevant when `closable` is `true`. |\\n| icon | `ReactNode` | - | Icon or element rendered before the text content. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Tag variant=\\\"success\\\" size=\\\"md\\\" closable onClose={() => removeFilter(id)}>\\n Active\\n</Tag>\\n```\\n```\\n\\n### Dropdown\\n\\nA click-triggered menu anchored to a trigger element. Manages its own\\nopen/close state internally.\\n\\nComposes: `MenuItem` for each option.\\n\\nBehavior:\\n- Clicking the trigger toggles the menu open/closed.\\n- Selecting an option calls `onChange(option.value)` and closes the menu.\\n- Clicking outside the container or pressing **Escape** closes the menu.\\n- The currently selected option (matching `value`) is rendered with\\n `MenuItem`'s `active` state.\\n\\nMenu panel: `colors.white` bg, `colors.gray[200]` border, `radius.lg`\\nborder-radius, `shadow.lg`, `zIndex.dropdown`, 160px min-width, 4px padding.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| trigger | `ReactNode` | - | The element the user clicks to open the menu. Receives a wrapping `<div>` with `cursor: pointer` (or `not-allowed` when disabled). |\\n| options | `DropdownOption[]` | - | Array of selectable options rendered as `MenuItem` rows. |\\n| value | `string` | - | The `value` of the currently selected option. The matching `MenuItem` is rendered with `active` styling. |\\n| onChange | `(value: string) => void` | - | Called with the `value` string of the selected option (not the full `DropdownOption` object). The menu closes immediately after. |\\n| placement | `'bottom-start' \\\\| 'bottom-end' \\\\| 'top-start' \\\\| 'top-end'` | `'bottom-start'` | Where to anchor the menu panel relative to the trigger. - `'bottom-start'` -- below, aligned to left edge - `'bottom-end'` -- below, aligned to right edge - `'top-start'` -- above, aligned to left edge - `'top-end'` -- above, aligned to right edge |\\n| disabled | `boolean` | - | When `true`, the trigger shows `cursor: not-allowed` and clicking it does not open the menu. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Dropdown\\n trigger={<Button variant=\\\"outline\\\">Sort by</Button>}\\n options={[\\n { value: 'name', label: 'Name' },\\n { value: 'date', label: 'Date created' },\\n { value: 'delete', label: 'Delete', danger: true },\\n ]}\\n value={sortBy}\\n onChange={setSortBy}\\n placement=\\\"bottom-end\\\"\\n/>\\n```\\n```\\n\\n### Autocomplete\\n\\nA text input with a filterable suggestion dropdown, keyboard navigation,\\nand loading/empty states.\\n\\nComposes: `Input` primitive (with `label`, `error`, `placeholder` forwarded),\\n`Spinner` (loading state).\\n\\nFiltering: options are filtered client-side by case-insensitive substring\\nmatch against both `option.label` and `option.value`.\\n\\nKeyboard support:\\n- **ArrowDown / ArrowUp** -- move highlight through filtered options\\n (opens dropdown if closed)\\n- **Enter** -- selects the highlighted option\\n- **Escape** -- closes the dropdown\\n\\nOn selection, `onChange` is called with `option.label` (the display text)\\nand `onSelect` is called with the full `AutocompleteOption` object.\\n\\nDropdown panel: `colors.white` bg, `colors.gray[200]` border, `radius.lg`\\nborder-radius, `shadow.lg`, `zIndex.dropdown`, max-height 240px with\\noverflow scroll.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `string` | `''` | Current text in the input field. On selection, this is set to the selected option's `label`. |\\n| onChange | `(value: string) => void` | - | Called on every keystroke with the new input string (value directly, not a React event). Also called on selection with `option.label`. |\\n| onSelect | `(option: AutocompleteOption) => void` | - | Called when the user selects an option (click or Enter on highlighted item). Receives the full `AutocompleteOption` object, not just the value string. |\\n| options | `AutocompleteOption[]` | - | The full list of available options. Filtering is handled internally via case-insensitive substring match on `label` and `value`. |\\n| placeholder | `string` | - | Placeholder text forwarded to the inner `Input` primitive. |\\n| label | `string` | - | Label text forwarded to the inner `Input` primitive. |\\n| loading | `boolean` | - | When `true`, the dropdown shows a centered `Spinner` instead of the option list. The input remains interactive. |\\n| disabled | `boolean` | - | When `true`, the inner `Input` is disabled and the dropdown does not open. |\\n| error | `string` | - | Error message forwarded to the inner `Input` primitive. |\\n| noResultsText | `string` | `'No results found'` | Text shown in the dropdown when filtering produces zero matches. Rendered centered in `colors.gray[500]` / `fontSize.sm`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Autocomplete\\n label=\\\"Country\\\"\\n value={country}\\n onChange={setCountry}\\n onSelect={(opt) => setCountryCode(opt.value)}\\n options={countries}\\n placeholder=\\\"Type to search...\\\"\\n noResultsText=\\\"No countries found\\\"\\n/>\\n```\\n```\\n\\n### Breadcrumb\\n\\nA horizontal navigation trail showing the user's location within a\\nhierarchy. Renders a `<nav aria-label=\\\"Breadcrumb\\\">`.\\n\\nComposes: `Link` primitive (for items with `href`).\\n\\nRendering rules per item:\\n- **Last item**: static `<span>` with `colors.gray[900]`, `fontWeight: 500`,\\n and `aria-current=\\\"page\\\"`.\\n- **Non-last with `href`**: `Link` in `colors.gray[500]` with\\n `underline=\\\"hover\\\"`. If `onItemClick` is provided, `e.preventDefault()`\\n is called and the handler fires instead of navigating.\\n- **Non-last without `href`**: unstyled `<button>` in `colors.gray[500]`.\\n\\nLayout: flexbox row, `8px` gap, `fontSize.sm`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `BreadcrumbItem[]` | - | Ordered array of breadcrumb segments from root to current page. |\\n| separator | `ReactNode` | `'/'` | Separator rendered between each pair of items. Can be a string (e.g., `\\\"/\\\"`, `\\\">\\\"`) or a ReactNode (e.g., an `Icon`). Rendered in `colors.gray[400]`. |\\n| onItemClick | `(item: BreadcrumbItem, index: number) => void` | - | Called when a non-last item is clicked. Receives the `BreadcrumbItem` and its zero-based `index`. When provided on items that have `href`, the default navigation is prevented via `e.preventDefault()`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Breadcrumb\\n items={[\\n { label: 'Home', href: '/' },\\n { label: 'Projects', href: '/projects' },\\n { label: 'ggui' },\\n ]}\\n separator=\\\"/\\\"\\n onItemClick={(item) => router.push(item.href!)}\\n/>\\n```\\n```\\n\\n### Pagination\\n\\nPage navigation controls with previous/next arrows, numbered page buttons,\\nand optional first/last jumps. Renders a `<nav aria-label=\\\"Pagination\\\">`.\\n\\nComposes: `Button` (ghost variant for prev/next/first/last arrows),\\n`Icon` (`chevron-left`, `chevron-right`).\\n\\nBuilt-in transition: `all 0.15s` on page number buttons.\\n\\nPage windowing: when `totalPages > maxVisible`, the component shows the\\nfirst page, last page, a window of pages around `currentPage`, and\\nellipsis (\\\"...\\\") markers for gaps. The window adjusts when near the\\nstart or end of the range.\\n\\nActive page button: `colors.primary[600]` bg, `colors.white` text,\\n`fontWeight.medium`. Inactive: transparent bg, `colors.gray[700]` text.\\n\\nArrow buttons are automatically disabled at boundary pages (first/last).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| currentPage | `number` | - | Current active page. **1-indexed** (first page is `1`). |\\n| totalPages | `number` | - | Total number of pages. Determines when last-page / next-page buttons disable. |\\n| onPageChange | `(page: number) => void` | - | Called when the user clicks a page number, arrow, or first/last button. Receives the target page number (1-indexed) directly. |\\n| showFirstLast | `boolean` | `true` | When `true`, renders double-chevron buttons for jumping to the first and last page. These buttons are disabled when already on the respective boundary. |\\n| maxVisible | `number` | `5` | Maximum number of page buttons visible at once (including the first and last page, but excluding ellipsis markers). When `totalPages` exceeds this value, ellipsis gaps appear. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls button dimensions and icon sizes. - `'sm'` -- 28px buttons, 14px icons, Button size `xs` - `'md'` -- 32px buttons, 16px icons, Button size `sm` - `'lg'` -- 40px buttons, 20px icons, Button size `md` |\\n| disabled | `boolean` | - | When `true`, all page buttons and arrows are visually dimmed (`opacity: 0.5`) and clicks are suppressed. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Pagination\\n currentPage={page}\\n totalPages={20}\\n onPageChange={setPage}\\n maxVisible={7}\\n size=\\\"md\\\"\\n/>\\n```\\n```\\n\\n### EmptyState\\n\\nEmptyState -- placeholder for a region with no data: empty lists,\\nzero search results, an error fallback. Render it instead of\\nnothing whenever a data array could be empty — a list that shows\\nnothing when empty looks broken.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| icon | `string \\\\| ReactNode` | - | A Lucide icon name (kebab-case), rendered large and subtle above the title, or a custom node. Omit for a text-only empty state. |\\n| title | `string` | - | The headline, e.g. \\\"No results found\\\". |\\n| description | `string` | - | Optional supporting line below the title. |\\n| action | `ReactNode` | - | Optional call-to-action, typically a `<Button>`. |\\n\\n**Example:**\\n```tsx\\n{results.length === 0\\n ? <EmptyState icon=\\\"search-x\\\" title=\\\"No matches\\\" description=\\\"Try a broader query.\\\" />\\n : results.map((r) => <Row key={r.id}>…</Row>)}\\n```\\n\\n### Stat\\n\\nStat -- a single KPI / metric: a label, a large value, an optional\\ntrend-coloured delta and icon. Reach for it whenever the UI is\\n\\\"show a number\\\" — dashboards, weather and price cards, analytics\\ntiles. Drop several into a `<Grid>` for a stat grid.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | The metric name, e.g. \\\"Revenue\\\". Rendered small and uppercase above the value. |\\n| value | `string \\\\| number` | - | The headline value — the big number. A number, or a pre-formatted string (`\\\"$48.2k\\\"`, `\\\"18°C\\\"`). |\\n| delta | `string` | - | Optional change indicator, pre-formatted, e.g. `\\\"+12.5%\\\"` or `\\\"-3\\\"`. |\\n| trend | `'up' \\\\| 'down' \\\\| 'neutral'` | `'neutral'` | Direction of `delta` — colours it: `'up'` success, `'down'` error, `'neutral'` muted. |\\n| icon | `string \\\\| ReactNode` | - | Optional Lucide icon name (kebab-case) or custom node, shown next to the label. |\\n\\n**Example:**\\n```tsx\\n<Stat label=\\\"Revenue\\\" value=\\\"$48.2k\\\" delta=\\\"+12.5%\\\" trend=\\\"up\\\" icon=\\\"trending-up\\\" />\\n```\\n\\n### Stepper\\n\\nStepper -- a display-only step indicator for multi-step flows\\n(wizards, checkouts, onboarding): numbered markers joined by\\nconnector lines, with completed (check), current (filled), and\\nupcoming (outlined) states styled distinctly.\\n\\nStepper renders step state; it never owns it. Declare the step\\nlabels as a top-level `const`, track the current index in\\n`useState`, and advance it from your own Next/Back buttons (or\\n`onStepClick`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| steps | `string[]` | - | Ordered step labels, one per step. Declare as a top-level `const` array — never as state. |\\n| current | `number` | - | Zero-based index of the active step. Steps before it render as completed (check mark), steps after it as upcoming. |\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Flow direction. `'horizontal'` joins the markers with connector lines in a row; `'vertical'` stacks the steps with short connector columns — better for sidebars or long step labels. |\\n| onStepClick | `(index: number) => void` | - | When provided, each step becomes a real button and clicks receive the step's zero-based index. Typical use: jumping back to a completed step; guard forward jumps in the handler if the flow validates per step. |\\n\\n**Example:**\\n```tsx\\nconst STEPS = ['Account', 'Profile', 'Review'];\\n// In the component: const [step, setStep] = useState(0);\\n<Stack gap=\\\"lg\\\">\\n <Stepper steps={STEPS} current={step} />\\n {step === 0 && <AccountFields />}\\n <Row gap=\\\"sm\\\" justify=\\\"end\\\">\\n <Button variant=\\\"ghost\\\" disabled={step === 0} onClick={() => setStep(step - 1)}>Back</Button>\\n <Button onClick={() => setStep(step + 1)}>Next</Button>\\n </Row>\\n</Stack>\\n```\\n\\n### Support Types\\n\\n**DropdownOption:**\\n\\nA single option inside a `Dropdown`. Each option maps to one `MenuItem`\\ninternally.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | Unique identifier returned to `onChange` when this option is selected. |\\n| label | `string` | Human-readable text shown in the menu row. |\\n| icon | `ReactNode` | Optional icon rendered to the left of the label via `MenuItem.icon`. |\\n| disabled | `boolean` | When `true`, the option is visible but non-interactive. |\\n| danger | `boolean` | When `true`, the option uses destructive (red) styling via `MenuItem.danger`. |\\n\\n**AutocompleteOption:**\\n\\nA single option in the `Autocomplete` suggestion list.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | Unique identifier for this option. Also used for case-insensitive filtering against the input value. |\\n| label | `string` | Primary display text. Also used for case-insensitive filtering and is written into the input on selection. |\\n| description | `string` | Secondary description rendered below the label in `fontSize.xs` / `colors.gray[500]`. |\\n| icon | `ReactNode` | Icon rendered to the left of the label/description block. Flex-shrink 0. |\\n| disabled | `boolean` | When `true`, the option is visible but non-interactive (`cursor: not-allowed`, `colors.gray[400]` text). |\\n\\n**BreadcrumbItem:**\\n\\nA single segment in a `Breadcrumb` trail. Items with `href` render as\\n`Link` primitives; items without render as plain `<button>` elements.\\nThe last item in the array is always rendered as static text with\\n`aria-current=\\\"page\\\"`.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Display text for this breadcrumb segment. |\\n| href | `string` | URL for this segment. When provided (and this is not the last item), the segment renders as a `Link` primitive with `underline=\\\"hover\\\"`. When omitted, it renders as a `<button>`. |\\n| icon | `ReactNode` | Icon rendered immediately before the label. Its color follows the segment's text color: `colors.gray[500]` for navigable items, `colors.gray[900]` for the current (last) item. |\\n\\n\\n## Compositions\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### Header\\n\\nProps for the `Header` composition.\\n\\nA horizontal page header that arranges a logo, navigation, and action slots\\nin a flex row (`justify-content: space-between`). Internally renders a `<header>` element;\\ndoes not compose other ggui primitives.\\n\\nWhen `sticky` is true the header gets `position: sticky; top: 0` with `zIndex.sticky`\\nand a `shadow.sm` box-shadow.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| logo | `ReactNode` | - | Logo or brand element rendered at the start (flex-shrink: 0). |\\n| navigation | `ReactNode` | - | Navigation content rendered in a `<nav>` element with `flex: 1` and a 32 px left margin. |\\n| actions | `ReactNode` | - | Right-side action elements (buttons, avatar, etc.) rendered with a 12 px gap. |\\n| sticky | `boolean` | `false` | When true, the header becomes `position: sticky` at the top of its scroll container with `zIndex.sticky` and `shadow.sm`. |\\n| background | `string` | `colors.white` | Background color of the header. |\\n| bordered | `boolean` | `true` | When true, renders a 1 px bottom border in `colors.gray[200]`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Header\\n logo={<img src=\\\"/logo.svg\\\" alt=\\\"Acme\\\" />}\\n navigation={<a href=\\\"/docs\\\">Docs</a>}\\n actions={<Button size=\\\"sm\\\">Sign In</Button>}\\n sticky\\n bordered\\n/>\\n```\\n```\\n\\n### Sidebar\\n\\nProps for the `Sidebar` composition.\\n\\nA vertical navigation panel that composes the `Icon` primitive for chevron indicators.\\nItems are rendered as `<button>` elements inside a scrollable `<nav>`. Nested items\\nare indented 16 px per depth level. The sidebar animates width changes with a 200 ms\\nCSS transition. Active items are highlighted with `colors.primary[50]` background\\nand `colors.primary[700]` text.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `SidebarItem[]` | - | Array of navigation items to render. |\\n| activeId | `string` | - | ID of the currently active item. Matched items get a highlighted background and bold text. |\\n| onItemClick | `(item: SidebarItem) => void` | - | Called when any item (including parent items with children) is clicked. |\\n| collapsed | `boolean` | `false` | When true, hides labels and badges; only icons remain visible, centered in the collapsed width. Nested children are hidden entirely. |\\n| header | `ReactNode` | - | Content rendered above the item list, separated by a bottom border. |\\n| footer | `ReactNode` | - | Content rendered below the item list, separated by a top border. |\\n| width | `number` | `256` | Width in pixels when expanded. |\\n| collapsedWidth | `number` | `64` | Width in pixels when collapsed. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Sidebar\\n items={[\\n { id: 'home', label: 'Home', icon: <Icon name=\\\"home\\\" /> },\\n { id: 'settings', label: 'Settings', icon: <Icon name=\\\"settings\\\" />,\\n children: [\\n { id: 'profile', label: 'Profile' },\\n { id: 'billing', label: 'Billing' },\\n ]},\\n ]}\\n activeId=\\\"home\\\"\\n onItemClick={(item) => navigate(item.href)}\\n collapsed={false}\\n width={256}\\n/>\\n```\\n```\\n\\n### CardGrid\\n\\nProps for the `CardGrid` composition.\\n\\nA CSS Grid wrapper that arranges children in equal-width columns. When `columns`\\nis a number, it produces `repeat(N, 1fr)`. When it is a responsive object,\\nit falls back to `repeat(auto-fit, minmax(280px, 1fr))` for fluid responsive behavior.\\n\\nDoes not compose any ggui primitives internally — it is a pure layout container.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Card elements to arrange in the grid. |\\n| columns | `number \\\\| { sm?: number; md?: number; lg?: number }` | `3` | Number of columns, or a responsive breakpoint map. - `number` — fixed column count via `repeat(N, 1fr)`. - `{ sm?, md?, lg? }` — triggers `repeat(auto-fit, minmax(280px, 1fr))` for fluid layout. |\\n| gap | `number` | `16` | Gap between grid items in pixels. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CardGrid columns={3} gap={24}>\\n <Card>A</Card>\\n <Card>B</Card>\\n <Card>C</Card>\\n</CardGrid>\\n```\\n```\\n\\n### CommentThread\\n\\nProps for the `CommentThread` composition.\\n\\nA threaded comment section that composes `Avatar`, `Button`, `TextArea`, and `Spinner`\\nprimitives. Comments are rendered recursively with 40 px indentation per nesting level.\\nEach comment shows author avatar, name, timestamp, content, reactions, and a \\\"Reply\\\" toggle.\\nWhen `currentUser` is provided, a new-comment input with avatar and submit button is shown\\nabove the thread.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| comments | `Comment[]` | - | Array of top-level comments to render. Replies are nested within each comment. |\\n| currentUser | `{ /** Display name for the current user's avatar. */ name: string; /** Avatar image URL for the current user. */ avatar?: string; }` | - | Current user info. When provided, a new-comment input area is rendered above the thread. |\\n| onAddComment | `(content: string, parentId?: string) => void` | - | Called when the user submits a new top-level comment. |\\n| onReply | `(commentId: string, content: string) => void` | - | Called when the user submits a reply to an existing comment. |\\n| onReaction | `(commentId: string, emoji: string) => void` | - | Called when the user clicks an emoji reaction on a comment. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the comment list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CommentThread\\n comments={[\\n { id: '1', author: { name: 'Alice' }, content: 'Great work!', timestamp: new Date(),\\n replies: [{ id: '2', author: { name: 'Bob' }, content: 'Thanks!', timestamp: new Date() }] }\\n ]}\\n currentUser={{ name: 'Alice', avatar: '/alice.jpg' }}\\n onAddComment={(content) => post(content)}\\n onReply={(commentId, content) => reply(commentId, content)}\\n onReaction={(commentId, emoji) => react(commentId, emoji)}\\n/>\\n```\\n```\\n\\n### DataTable\\n\\nProps for the `DataTable` composition.\\n\\nA sortable, selectable data table that composes `Checkbox`, `Spinner`, and `Icon`\\nprimitives. Renders a `<table>` inside a bordered container with 8 px border-radius.\\nThe header row has a `colors.gray[50]` background. Sortable columns show a chevron\\nicon on click (toggles asc/desc). Selected rows are highlighted with `colors.primary[50]`.\\nRow background transitions use a 150 ms ease. The \\\"select all\\\" checkbox supports an\\nindeterminate state when a subset of rows is selected.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| columns | `DataTableColumn<T>[]` | - | Column definitions that control header, alignment, sorting, and rendering. |\\n| data | `T[]` | - | Row data array. Each entry corresponds to one table row. |\\n| rowKey | `string \\\\| ((row: T) => string)` | `'id'` | Property name or function used to derive a unique key for each row. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of table body rows. |\\n| emptyText | `string` | `'No data'` | Text shown when `data` is empty and not loading. |\\n| onSort | `(key: string, direction: 'asc' \\\\| 'desc') => void` | - | Called when a sortable column header is clicked. Toggles direction automatically (asc -> desc) if the same column is clicked again. |\\n| sortKey | `string` | - | The column key currently being sorted. |\\n| sortDirection | `'asc' \\\\| 'desc'` | - | The current sort direction. |\\n| onRowClick | `(row: T, index: number) => void` | - | Called when a row is clicked. Rows get `cursor: pointer` when this handler is provided. |\\n| selectable | `boolean` | - | When true, adds a checkbox column at the start of each row. |\\n| selectedKeys | `string[]` | `[]` | Array of currently selected row keys. |\\n| onSelectionChange | `(keys: string[]) => void` | - | Called when the set of selected row keys changes (via row checkbox or select-all). |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<DataTable\\n columns={[\\n { key: 'name', header: 'Name', sortable: true },\\n { key: 'email', header: 'Email' },\\n { key: 'role', header: 'Role', render: (v) => <Badge>{v}</Badge> },\\n ]}\\n data={users}\\n rowKey=\\\"id\\\"\\n selectable\\n selectedKeys={selected}\\n onSelectionChange={setSelected}\\n onSort={(key, dir) => sort(key, dir)}\\n sortKey=\\\"name\\\"\\n sortDirection=\\\"asc\\\"\\n/>\\n```\\n```\\n\\n### ChatWindow\\n\\nProps for the `ChatWindow` composition.\\n\\nA messaging interface that composes `Avatar`, `Button`, `Spinner`, and `Icon` primitives.\\nLayout is a flex column filling 100% height with a bordered `radius.lg` container.\\nMessages from the current user align right with `colors.primary[600]` bubbles and white text.\\nOther users' messages align left with `colors.gray[100]` bubbles. The message area\\nauto-scrolls to the bottom on new messages via `scrollIntoView({ behavior: 'smooth' })`.\\nThe text input sends on Enter (Shift+Enter for newline).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| messages | `ChatMessage[]` | - | Array of chat messages to display in chronological order. |\\n| currentUserId | `string` | - | ID of the current user. Messages from this user render right-aligned with a primary color bubble. |\\n| onSendMessage | `(content: string) => void` | - | Called when the user submits a message (Enter key or send button). |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the message list. |\\n| typing | `{ name: string } \\\\| null` | - | When non-null, displays a typing indicator below the last message (e.g., \\\"Alice is typing...\\\"). |\\n| placeholder | `string` | `'Type a message...'` | Placeholder text for the message input field. |\\n| header | `ReactNode` | - | Optional header content rendered above the message area, separated by a bottom border. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<ChatWindow\\n messages={messages}\\n currentUserId=\\\"user-1\\\"\\n onSendMessage={(content) => send(content)}\\n typing={{ name: 'Alice' }}\\n placeholder=\\\"Type a message...\\\"\\n header={<h3>Chat with Alice</h3>}\\n/>\\n```\\n```\\n\\n### NavigationBar\\n\\nProps for the `NavigationBar` composition.\\n\\nA horizontal or vertical navigation menu. Does not compose other ggui primitives\\n(uses plain `<button>` and `<a>` elements). Active items are styled per variant:\\n\\n- `'default'` — active item gets `colors.primary[600]` text and medium font weight.\\n- `'pills'` — active item gets a `radius.full` pill with `colors.primary[100]` background.\\n- `'underline'` — active item gets a 2 px bottom border in `colors.primary[600]`.\\n When horizontal, the entire nav also has a 1 px bottom border.\\n\\nAll items have a 150 ms transition on all properties.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `NavItem[]` | - | Array of navigation items to render. |\\n| activeId | `string` | - | ID of the currently active item. Controls visual highlighting per variant style. |\\n| onItemClick | `(item: NavItem) => void` | - | Called when a non-disabled item is clicked. For `<a>` elements, `preventDefault` is called first. |\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Layout direction. - `'horizontal'` — flex-row with 4 px gap. - `'vertical'` — flex-column with 2 px gap. |\\n| variant | `'default' \\\\| 'pills' \\\\| 'underline'` | `'default'` | Visual style for active/inactive items. - `'default'` — text color change only. - `'pills'` — rounded pill background on active items. - `'underline'` — bottom border on active items. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<NavigationBar\\n items={[\\n { id: 'home', label: 'Home', icon: <Icon name=\\\"home\\\" /> },\\n { id: 'about', label: 'About' },\\n { id: 'contact', label: 'Contact' },\\n ]}\\n activeId=\\\"home\\\"\\n onItemClick={(item) => navigate(item.id)}\\n orientation=\\\"horizontal\\\"\\n variant=\\\"pills\\\"\\n/>\\n```\\n```\\n\\n### FileUploader\\n\\nProps for the `FileUploader` composition.\\n\\nA drag-and-drop file upload area that composes `Button`, `Progress`, and `Icon` primitives.\\nThe drop zone is a dashed-border container that highlights in `colors.primary[400]`/`colors.primary[50]`\\non drag-over. Below the drop zone, each file in `files` is listed with its name, size,\\noptional progress bar (for uploading status), and a remove button.\\n\\nFile validation (max size, max count) is applied client-side before calling `onFilesSelected`.\\nFiles exceeding `maxSize` are silently filtered out; files exceeding `maxFiles` are truncated.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| files | `UploadedFile[]` | `[]` | Array of files currently in the upload queue, shown below the drop zone. |\\n| onFilesSelected | `(files: File[]) => void` | - | Called when the user selects files via click or drag-and-drop. Receives native `File` objects after client-side filtering (maxSize, maxFiles). |\\n| onFileRemove | `(fileId: string) => void` | - | Called when the user clicks the remove button on a file entry. |\\n| accept | `string` | - | Accepted file types passed to the hidden `<input type=\\\"file\\\" accept=\\\"...\\\">`. E.g., `'image/*,.pdf'`. |\\n| multiple | `boolean` | `true` | When true, allows selecting multiple files at once. |\\n| maxSize | `number` | - | Maximum file size in bytes. Files exceeding this are silently excluded from the selection. |\\n| maxFiles | `number` | - | Maximum number of files. Excess files beyond `maxFiles - files.length` are truncated. |\\n| disabled | `boolean` | - | When true, the drop zone is visually dimmed (opacity 0.5) and non-interactive. |\\n| dragDrop | `boolean` | `true` | When true, enables drag-and-drop on the drop zone. When false, the prompt text changes to \\\"Click to browse files\\\". |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<FileUploader\\n files={uploadedFiles}\\n onFilesSelected={(files) => startUpload(files)}\\n onFileRemove={(id) => removeFile(id)}\\n accept=\\\"image/*,.pdf\\\"\\n multiple\\n maxSize={5 * 1024 * 1024}\\n maxFiles={10}\\n dragDrop\\n/>\\n```\\n```\\n\\n### NotificationCenter\\n\\nProps for the `NotificationCenter` composition.\\n\\nA notification list with a header bar that composes `Button`, `Spinner`, and `Icon`\\nprimitives. The header shows a \\\"Notifications\\\" title, an unread count badge\\n(pill in `colors.primary[100]`), and \\\"Mark all read\\\" / \\\"Clear all\\\" buttons.\\nEach notification item shows a colored status dot, title, message, timestamp,\\n\\\"Mark as read\\\" link, and optional action. The list is scrollable (`overflowY: auto`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| notifications | `Notification[]` | - | Array of notifications to display, in the order provided. |\\n| onMarkAsRead | `(id: string) => void` | - | Called when the user clicks \\\"Mark as read\\\" on an individual notification. |\\n| onMarkAllAsRead | `() => void` | - | Called when the user clicks the \\\"Mark all read\\\" header button. Only shown when there are unread items. |\\n| onDismiss | `(id: string) => void` | - | Called when the user clicks the dismiss (X) button on an individual notification. |\\n| onClearAll | `() => void` | - | Called when the user clicks the \\\"Clear all\\\" header button. Only shown when there are any notifications. |\\n| emptyText | `string` | `'No notifications'` | Text shown when `notifications` is empty and not loading. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the notification list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<NotificationCenter\\n notifications={[\\n { id: '1', title: 'Deployment complete', type: 'success', timestamp: new Date(), read: false },\\n { id: '2', title: 'Build failed', type: 'error', message: 'Lint errors', timestamp: new Date() },\\n ]}\\n onMarkAsRead={(id) => markRead(id)}\\n onMarkAllAsRead={() => markAllRead()}\\n onDismiss={(id) => dismiss(id)}\\n onClearAll={() => clearAll()}\\n/>\\n```\\n```\\n\\n### Modal\\n\\nProps for the `Modal` composition.\\n\\nA dialog overlay that composes `Button`, `Icon`, and `Heading` primitives.\\nThe overlay uses `animation.fadeIn` (`ggui-fadeIn`) and the dialog panel uses\\n`animation.scaleIn` (`ggui-scaleIn`) — both GPU-composited (opacity + transform).\\nWhen open, `document.body.style.overflow` is set to `'hidden'` to prevent background\\nscrolling, and restored on close. The dialog has `role=\\\"dialog\\\"` and `aria-modal=\\\"true\\\"`.\\n\\nSize widths: `sm` = 400 px, `md` = 500 px, `lg` = 640 px, `xl` = 800 px,\\n`full` = 100vw (no border-radius, no padding).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| open | `boolean` | - | Controls modal visibility. When false, the component renders nothing. |\\n| onClose | `() => void` | - | Called to close the modal (overlay click, escape key, or close button). |\\n| title | `string` | - | Optional title rendered in the modal header via the `Heading` primitive (level 4). |\\n| children | `ReactNode` | - | Modal body content rendered in a scrollable area (`overflowY: auto`). |\\n| footer | `ReactNode` | - | Footer content rendered below the body, right-aligned with an 8 px gap, separated by a top border. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| 'full'` | `'md'` | Controls the width of the modal panel. - `'sm'` — 400 px - `'md'` — 500 px - `'lg'` — 640 px - `'xl'` — 800 px - `'full'` — 100vw, no border-radius, stretches to fill viewport |\\n| closeOnOverlayClick | `boolean` | `true` | When true, clicking the semi-transparent overlay behind the modal calls `onClose`. |\\n| closeOnEscape | `boolean` | `true` | When true, pressing the Escape key calls `onClose`. |\\n| showCloseButton | `boolean` | `true` | When true, renders a ghost close button (X icon) in the modal header. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Modal\\n open={isOpen}\\n onClose={() => setOpen(false)}\\n title=\\\"Confirm Action\\\"\\n size=\\\"md\\\"\\n footer={\\n <>\\n <Button variant=\\\"ghost\\\" onClick={() => setOpen(false)}>Cancel</Button>\\n <Button onClick={handleConfirm}>Confirm</Button>\\n </>\\n }\\n>\\n <p>Are you sure you want to proceed?</p>\\n</Modal>\\n```\\n```\\n\\n### CommandPalette\\n\\nProps for the `CommandPalette` composition.\\n\\nA searchable command menu (Cmd+K / Ctrl+K pattern) that composes `Spinner` and `Icon`\\nprimitives. Appears as a centered overlay at 15vh from the top. Commands are filtered\\nby label and description (case-insensitive substring match). Results are grouped under\\nuppercase section headers. Keyboard navigation is fully supported:\\nArrow Up/Down to navigate, Enter to select, Escape to close.\\n\\nWhen `recentIds` are provided and the search query is empty, matching commands appear\\nin a \\\"Recent\\\" section at the top (deduplicated from their original groups).\\n\\nThe footer shows navigation hints: \\\"Up/Down Navigate\\\", \\\"Enter Select\\\", \\\"Esc Close\\\".\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| open | `boolean` | - | Controls palette visibility. When false, the component renders nothing. |\\n| onClose | `() => void` | - | Called to close the palette (overlay click, Escape key, or after command selection). |\\n| commands | `Command[]` | - | Full array of available commands. Filtered client-side by the search query. |\\n| onSelect | `(command: Command) => void` | - | Called when a non-disabled command is selected (Enter key or click). The palette auto-closes after selection. |\\n| placeholder | `string` | `'Search commands...'` | Placeholder text for the search input. |\\n| recentIds | `string[]` | `[]` | IDs of recently used commands. When the query is empty, these appear in a \\\"Recent\\\" section at the top of the results. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the command list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CommandPalette\\n open={isOpen}\\n onClose={() => setOpen(false)}\\n commands={[\\n { id: 'new', label: 'New File', shortcut: 'Ctrl+N', group: 'File' },\\n { id: 'save', label: 'Save', shortcut: 'Ctrl+S', group: 'File' },\\n { id: 'theme', label: 'Toggle Theme', group: 'Preferences' },\\n ]}\\n onSelect={(cmd) => executeCommand(cmd.id)}\\n recentIds={['save']}\\n placeholder=\\\"Search commands...\\\"\\n/>\\n```\\n```\\n\\n### Footer\\n\\nProps for the `Footer` composition.\\n\\nA site footer with `role=\\\"contentinfo\\\"` that lays out a brand slot, link columns,\\nsocial icons, and a bottom bar. Does not compose other ggui primitives (uses plain\\nHTML elements). Content is constrained to `max-width: 1280px` with auto margins.\\nLink columns use a responsive flex layout (`flex: 0 1 180px`). The bottom bar\\nincludes copyright text, social links, and bottom-bar links separated by a top border.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| brand | `ReactNode` | - | Brand element (logo, tagline) rendered in a flexible column (`flex: 1 1 280px`). |\\n| columns | `FooterColumn[]` | - | Array of link columns rendered in a flex-wrap layout with 48 px gap. |\\n| socialLinks | `FooterSocialLink[]` | - | Social media icon links rendered in the bottom bar. |\\n| bottomText | `string` | - | Text displayed at the start of the bottom bar (e.g., copyright notice). |\\n| bottomLinks | `FooterLink[]` | - | Links displayed in the bottom bar after social icons (e.g., Privacy, Terms). |\\n| background | `string` | `colors.gray[50]` | Background color of the footer. |\\n| bordered | `boolean` | `true` | When true, renders a 1 px top border in `colors.gray[200]`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Footer\\n brand={<img src=\\\"/logo.svg\\\" alt=\\\"Acme\\\" />}\\n columns={[\\n { title: 'Product', links: [{ label: 'Features', href: '/features' }] },\\n { title: 'Company', links: [{ label: 'About', href: '/about' }] },\\n ]}\\n socialLinks={[\\n { label: 'Twitter', href: 'https://twitter.com/acme', icon: <TwitterIcon /> },\\n ]}\\n bottomText=\\\"&copy; 2026 Acme Inc.\\\"\\n bottomLinks={[{ label: 'Privacy', href: '/privacy' }]}\\n bordered\\n/>\\n```\\n```\\n\\n### Hero\\n\\nProps for the `Hero` composition.\\n\\nA prominent landing-page hero section that renders heading, description, CTA buttons,\\nand an optional media slot. Does not compose other ggui primitives (uses plain HTML\\nelements styled with design tokens). Content is constrained to `max-width: 1280px`.\\n\\nLayout modes:\\n- `align='center'` — single-column centered layout with `max-width: 800px` text area.\\n- `align='left'` — two-column side-by-side layout (50/50 split with media slot).\\n\\nSize controls vertical padding and font sizes:\\n- `'sm'` — 48 px vertical padding, 3xl heading, lg description.\\n- `'md'` — 80 px vertical padding, 4xl heading, xl description.\\n- `'lg'` — 120 px vertical padding, 5xl heading, xl description.\\n\\nThe primary action button uses `colors.primary[600]` fill; the secondary action uses\\nan outlined style. When `overlay` is true with a `backgroundImage`, text switches to white\\nand borders become semi-transparent.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| heading | `string` | - | Main heading text rendered as an `<h1>` with bold weight and tight line-height. |\\n| description | `string` | - | Description paragraph rendered below the heading with relaxed line-height. |\\n| primaryAction | `HeroAction` | - | Primary CTA button rendered with `colors.primary[600]` background and white text. |\\n| secondaryAction | `HeroAction` | - | Secondary CTA button rendered with a transparent background and a 1 px border. |\\n| media | `ReactNode` | - | Media element (image, video, illustration) rendered beside or below the text content. |\\n| align | `'center' \\\\| 'left'` | `'center'` | Text and layout alignment. - `'center'` — centered single-column layout. - `'left'` — left-aligned text with media in a right column (50/50 split). |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls vertical padding and heading/description font sizes. - `'sm'` — compact (48 px padding, 3xl/lg fonts). - `'md'` — standard (80 px padding, 4xl/xl fonts). - `'lg'` — spacious (120 px padding, 5xl/xl fonts). |\\n| background | `string` | `colors.white (when no backgroundImage is set)` | Background color of the hero section. |\\n| backgroundImage | `string` | - | Background image URL applied as `background-size: cover; background-position: center`. |\\n| overlay | `boolean` | `false` | When true and `backgroundImage` is set, renders a semi-transparent black overlay (`rgba(0,0,0,0.5)`) and switches text to white/semi-transparent white for contrast. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Hero\\n heading=\\\"Build Better UIs, Faster\\\"\\n description=\\\"The universal interface layer between AI agents and humans.\\\"\\n primaryAction={{ label: 'Get Started', onClick: () => navigate('/signup') }}\\n secondaryAction={{ label: 'Learn More', href: '/docs' }}\\n media={<img src=\\\"/hero.png\\\" alt=\\\"Hero\\\" />}\\n align=\\\"left\\\"\\n size=\\\"lg\\\"\\n/>\\n```\\n```\\n\\n### Support Types\\n\\n**SidebarItem:**\\n\\nA single navigation entry in a `Sidebar`. Supports nested children for\\ncollapsible sub-menus and an optional badge slot.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier used for active-state matching and React keys. |\\n| label | `string` | Display label for the item. Hidden when the sidebar is collapsed. |\\n| icon | `ReactNode` | Leading icon rendered before the label. Remains visible when collapsed. |\\n| href | `string` | Optional URL associated with this item (not rendered as a link by default). |\\n| badge | `ReactNode` | Trailing badge element (e.g., unread count). Hidden when collapsed. |\\n| children | `SidebarItem[]` | Nested child items. When present, the item acts as a collapsible section (chevron indicator shown). |\\n| disabled | `boolean` | When true, the item is visually dimmed and non-interactive (`cursor: not-allowed`). |\\n\\n**Comment:**\\n\\nA single comment entry in a `CommentThread`. Supports nested replies\\nand emoji reactions with counts.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this comment. |\\n| author | `{ /** Display name of the author. */ name: string; /** URL for the author's avatar image. Passed to the `Avatar` primitive. */ avatar?: string; }` | Comment author metadata. |\\n| content | `string` | The comment body text. |\\n| timestamp | `string \\\\| Date` | Timestamp of the comment. Rendered via `toLocaleString()` when a `Date` object. |\\n| replies | `Comment[]` | Nested reply comments. Each reply is rendered indented 40 px deeper. |\\n| reactions | `{ emoji: string; count: number }[]` | Emoji reactions with their aggregated counts (e.g., `{ emoji: \\\"👍\\\", count: 3 }`). |\\n\\n**DataTableColumn:**\\n\\nColumn definition for a `DataTable`. Controls header text, width, alignment,\\nsorting, and custom cell rendering.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Property key on the row object used to extract cell values. Also serves as the sort key. |\\n| header | `string` | Column header text displayed in the `<thead>`. |\\n| width | `number \\\\| string` | Column width as a CSS value (number for pixels, string for any CSS unit). |\\n| sortable | `boolean` | When true, the column header is clickable and triggers `onSort`. An arrow icon indicates direction. |\\n| render | `(value: unknown, row: T, index: number) => ReactNode` | Custom cell renderer. When omitted, the raw value is stringified via `String()`. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | Text alignment for both header and body cells. |\\n\\n**ChatMessage:**\\n\\nA single message in a `ChatWindow`. Includes sender metadata, delivery status,\\nand a timestamp.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this message. |\\n| content | `string` | The message body text. |\\n| sender | `{ /** Unique ID of the sender. Compared to `currentUserId` to determine alignment. */ id: string; /** Display name of the sender. */ name: string; /** Avatar image URL. Only shown for non-current-user messages (xs size). */ avatar?: string; }` | Sender metadata used for avatar rendering and alignment. |\\n| timestamp | `string \\\\| Date` | Message timestamp. Rendered as `HH:MM` via `toLocaleTimeString` when a `Date` object. |\\n| status | `'sending' \\\\| 'sent' \\\\| 'delivered' \\\\| 'read' \\\\| 'error'` | Delivery status indicator shown on the current user's messages. - `'sending'` — shows a dot bullet - `'sent'` — shows a single checkmark - `'delivered'` — shows double checkmarks - `'read'` — shows double checkmarks (same visual as delivered) - `'error'` — shows an exclamation mark |\\n\\n**NavItem:**\\n\\nA single navigation entry in a `NavigationBar`. Supports nested children\\nfor sub-menus (rendered by the parent via dropdown, not built-in).\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier used for active-state matching and React keys. |\\n| label | `string` | Display label for the navigation link. |\\n| href | `string` | URL for the item. When provided, renders an `<a>` element instead of `<button>`. |\\n| icon | `ReactNode` | Optional icon rendered before the label. |\\n| children | `NavItem[]` | Nested child items (for sub-menu structures; rendering is consumer-defined). |\\n| disabled | `boolean` | When true, the item is visually dimmed (opacity 0.5) and non-interactive. |\\n\\n**UploadedFile:**\\n\\nA file entry in the `FileUploader` composition. Tracks upload progress,\\nstatus, and optional error messages.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this file entry. Used as a key and for removal callbacks. |\\n| name | `string` | Original file name. Rendered with text-overflow ellipsis when too long. |\\n| size | `number` | File size in bytes. Formatted as B/KB/MB/GB for display. |\\n| type | `string` | MIME type of the file (e.g., `'image/png'`). |\\n| progress | `number` | Upload progress as a percentage (0-100). Shown via the `Progress` primitive when status is `'uploading'`. |\\n| status | `'pending' \\\\| 'uploading' \\\\| 'success' \\\\| 'error'` | Current upload lifecycle status. - `'pending'` — file selected but upload not started. - `'uploading'` — upload in progress; `progress` bar is shown. - `'success'` — upload completed. - `'error'` — upload failed; `error` message is shown in `colors.error[500]`. |\\n| error | `string` | Error message displayed when status is `'error'`. |\\n| url | `string` | The remote URL of the uploaded file after successful upload. |\\n\\n**Notification:**\\n\\nA single notification entry in the `NotificationCenter`. Supports semantic type coloring,\\nread state, and an optional inline action button.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this notification. |\\n| title | `string` | Notification title rendered in medium weight. |\\n| message | `string` | Optional body text rendered below the title in a smaller font. |\\n| timestamp | `string \\\\| Date` | Timestamp of the notification. Rendered via `toLocaleString()` when a `Date` object. |\\n| read | `boolean` | Read state. Unread notifications get a `colors.primary[50]` background and a colored status dot matching the notification type. |\\n| type | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | Semantic type that controls the status dot color on unread notifications. - `'info'` — `colors.info[500]` (blue) - `'success'` — `colors.success[500]` (green) - `'warning'` — `colors.warning[500]` (amber) - `'error'` — `colors.error[500]` (red) |\\n| icon | `ReactNode` | Optional icon rendered alongside the notification (not used by the default implementation). |\\n| action | `{ /** Button label text. */ label: string; /** Click handler for the action. */ onClick: () => void; }` | Optional inline action button rendered next to the timestamp. |\\n\\n**Command:**\\n\\nA single command entry in a `CommandPalette`. Commands can be grouped,\\nhave keyboard shortcuts, and support a disabled state.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this command. |\\n| label | `string` | Display label for the command. Searchable by the palette's query filter. |\\n| description | `string` | Optional description text shown below the label. Also searchable. |\\n| icon | `ReactNode` | Icon rendered at the start of the command row. |\\n| shortcut | `string` | Keyboard shortcut hint displayed at the end of the row in a `<kbd>` element. |\\n| group | `string` | Group name for visual sectioning. Commands with the same group are rendered under a shared header. Defaults to `'Commands'` if omitted. |\\n| disabled | `boolean` | When true, the command is visually dimmed and cannot be selected. |\\n\\n**FooterLink:**\\n\\nA single link entry in a footer column or the bottom bar. Supports both\\n`href` navigation and `onClick` handlers (onClick takes precedence via `preventDefault`).\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Display text for the link. |\\n| href | `string` | URL for the link. |\\n| onClick | `() => void` | Click handler. When provided, `preventDefault` is called on the anchor click. |\\n\\n**FooterColumn:**\\n\\nA named column of links in the `Footer` layout. Each column has an optional title\\nand a list of links rendered as a vertical stack with 10 px gap.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| title | `string` | Column heading rendered as an `<h4>` with semibold weight. |\\n| links | `FooterLink[]` | Links displayed in this column. |\\n\\n**FooterSocialLink:**\\n\\nA social media link in the `Footer` bottom bar. Rendered as an icon-only anchor\\nwith `aria-label` for accessibility.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Accessible label for the social link (used as `aria-label`). |\\n| href | `string` | URL for the social media profile or page. |\\n| icon | `ReactNode` | Icon element rendered inside the anchor (typically an SVG or `Icon` primitive). |\\n\\n**HeroAction:**\\n\\nA call-to-action button definition for the `Hero` composition.\\nUsed for both the primary (filled) and secondary (outlined) action buttons.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Button label text. |\\n| onClick | `() => void` | Click handler for the button. |\\n| href | `string` | Optional URL (not used by the default implementation; available for consumer routing). |\\n\\n\\n## System Conventions\\n\\n### onChange Behavior (CRITICAL)\\n\\nAll form control onChange handlers receive the VALUE DIRECTLY, not a React event object.\\n\\n```tsx\\n// CORRECT — onChange receives value directly\\n<Input value={name} onChange={setName} />\\n<Input value={email} onChange={(value) => setEmail(value)} />\\n<Select value={country} onChange={setCountry} options={countries} />\\n<Checkbox checked={agreed} onChange={setAgreed} />\\n\\n// WRONG — DO NOT use e.target.value!\\n<Input value={name} onChange={(e) => setName(e.target.value)} /> // WILL BREAK\\n```\\n\\nApplies to: Input, TextArea, Select, Checkbox, RadioGroup, Slider, Tabs, Accordion.\\n\\n### Available Motion & Animation\\n\\nRender `<MotionKeyframes />` once (anywhere in tree) to enable all keyframes.\\n\\n**Entrance/exit:** fadeIn, fadeOut, slideInUp, slideInDown, scaleIn, scaleOut\\n**State feedback:** flash (background-color highlight), pulse (opacity breathing), bounce (scale overshoot)\\n**Easing:** linear, easeIn, easeOut, easeInOut, spring (bouncy)\\n**Durations:** instant(0ms), fast(100ms), normal(200ms), slow(300ms), slower(500ms)\\n\\n```tsx\\n// Entrance animation on mount\\n<div style={{ animation: 'ggui-fadeIn 200ms ease-out' }}>Content</div>\\n\\n// Stagger list items\\n{items.map((item, i) => (\\n <div key={item.id} style={{ animation: \\\\`ggui-slideInUp 300ms ease-out \\\\${i * 50}ms both\\\\` }}>\\n {item.name}\\n </div>\\n))}\\n\\n// Flash highlight when data changes (e.g., stock price update)\\n// useAnimationKey returns a key that increments when dep changes → remounts element → replays animation\\nconst priceKey = useAnimationKey(stock.price);\\n<div key={priceKey} style={{\\n animation: animation.flash,\\n '--ggui-flash-color': stock.change > 0 ? 'var(--ggui-color-success-100)' : 'var(--ggui-color-error-100)',\\n} as React.CSSProperties}>\\n {stock.price}\\n</div>\\n\\n// Respect reduced-motion preference\\nconst { motionEnabled } = useMotion();\\n<div style={motionEnabled ? { animation: 'ggui-scaleIn 200ms ease-out' } : undefined}>\\n Content\\n</div>\\n```\\n\\n### Elevation System\\n\\n6 levels mapping shadow intensity to z-index for layering:\\n- Level 0: flat (no shadow, z: auto) — inline content\\n- Level 1: sm shadow (z: auto) — cards, sections\\n- Level 2: md shadow (z: 1000) — dropdowns, popovers\\n- Level 3: lg shadow (z: 1200) — sticky banners\\n- Level 4: xl shadow (z: 1400) — modals, dialogs\\n- Level 5: 2xl shadow (z: 1800) — tooltips, toasts\\n\\n### Import Constraints\\n\\nOnly these imports are allowed:\\n- `react`\\n- `@ggui-ai/design` — the whole design system (primitives, components, compositions, and the `Clickable` / `Hoverable` / `Pressable` traits) is one import; there are no subpaths\\n- `@ggui-ai/wire` (wire hooks)\\n\\nNo external libraries (lodash, date-fns, etc.). No fetch(). No eval().\";\n\n/**\n * Get primitives documentation for the UI generator.\n * Returns comprehensive TypeScript interfaces, examples, and usage patterns.\n */\nexport function getPrimitives(): string {\n return PRIMITIVES_DOCUMENTATION;\n}\n\n/**\n * List of all valid primitive names for validation.\n */\nexport const VALID_PRIMITIVES = [\n 'Container',\n 'Card',\n 'Stack',\n 'Row',\n 'Grid',\n 'Box',\n 'Divider',\n 'Spacer',\n 'Text',\n 'Heading',\n 'Button',\n 'Input',\n 'TextArea',\n 'Select',\n 'Checkbox',\n 'Toggle',\n 'RadioGroup',\n 'Slider',\n 'Badge',\n 'Spinner',\n 'Skeleton',\n 'Avatar',\n 'Alert',\n 'Progress',\n 'Image',\n 'Icon',\n 'Link',\n 'Tooltip',\n 'Table',\n 'Tabs',\n 'Toast',\n 'Accordion',\n 'MotionKeyframes',\n 'SearchField',\n 'FormField',\n 'MenuItem',\n 'Tag',\n 'Dropdown',\n 'Autocomplete',\n 'Breadcrumb',\n 'Pagination',\n 'EmptyState',\n 'Stat',\n 'Stepper',\n 'Markdown',\n 'MarkdownInline',\n 'Header',\n 'Sidebar',\n 'CardGrid',\n 'CommentThread',\n 'DataTable',\n 'ChatWindow',\n 'NavigationBar',\n 'FileUploader',\n 'NotificationCenter',\n 'Modal',\n 'CommandPalette',\n 'Footer',\n 'Hero',\n] as const;\n\nexport type ValidPrimitive = (typeof VALID_PRIMITIVES)[number];\n\n/**\n * Check if a primitive name is valid.\n */\nexport function isValidPrimitive(name: string): name is ValidPrimitive {\n return VALID_PRIMITIVES.includes(name as ValidPrimitive);\n}\n","/**\n * The single source of truth for which packages LLM-generated\n * component code may import.\n *\n * Before this module the allowlist was duplicated — as `startsWith`\n * chains, as literal arrays, as hand-written error strings — across\n * `adapters/tools.ts`, `check/run-tier0.ts`, `check/type-checker.ts`\n * and `validation/component-detailed.ts`. The copies had already\n * drifted (one rejected `react-dom`, others allowed it). Every\n * import-validation site now derives from {@link isAllowedImport}.\n *\n * The design system is imported through ONE specifier — `@ggui-ai/design`\n * — never the `/primitives`, `/components`, `/compositions`, `/interact`\n * subpaths. The barrel re-exports every layer, so the generation LLM\n * never has to predict which subpath a component lives in. Subpaths\n * still resolve (the predicate allows any `@ggui-ai/design/...`), but\n * the prompt and catalog teach the barrel exclusively.\n */\n\n/**\n * Static package specifiers generated code may import. A subpath of\n * any base (`<base>/...`) is allowed too. Per-contract gadget packages\n * are dynamic — pass them to {@link isAllowedImport}.\n */\nexport const ALLOWED_IMPORT_BASES = [\n 'react',\n 'react-dom',\n '@ggui-ai/design',\n '@ggui-ai/wire',\n '@ggui-ai/gadgets',\n] as const;\n\n/**\n * True if `specifier` is a package generated component code may import:\n * one of {@link ALLOWED_IMPORT_BASES} (or a subpath of one), or a\n * contract-declared gadget package.\n */\nexport function isAllowedImport(\n specifier: string,\n gadgetPackages?: ReadonlySet<string>,\n): boolean {\n for (const base of ALLOWED_IMPORT_BASES) {\n if (specifier === base || specifier.startsWith(`${base}/`)) return true;\n }\n return gadgetPackages?.has(specifier) ?? false;\n}\n\n/**\n * Human-readable allowed-import list for error messages shown to the\n * generation LLM.\n */\nexport function describeAllowedImports(): string {\n return 'react, @ggui-ai/design, @ggui-ai/wire, @ggui-ai/gadgets, or a gadget package declared on the contract';\n}\n","import { VALID_PRIMITIVES } from './primitives.js';\nimport { isAllowedImport, describeAllowedImports } from './allowed-imports.js';\nimport { DANGEROUS_PATTERNS as SHARED_DANGEROUS_PATTERNS } from '@ggui-ai/protocol';\n\n/**\n * Validation error types for classification\n */\nexport type ValidationErrorType = 'import' | 'primitive' | 'security' | 'syntax' | 'size' | 'structure';\n\n/**\n * Validation warning types\n */\nexport type ValidationWarningType = 'accessibility' | 'best-practice' | 'performance';\n\n/**\n * Detailed validation error with actionable suggestions\n */\nexport interface ValidationError {\n type: ValidationErrorType;\n message: string;\n line?: number;\n column?: number;\n suggestion: string;\n code?: string;\n}\n\n/**\n * Validation warning (non-blocking)\n */\nexport interface ValidationWarning {\n type: ValidationWarningType;\n message: string;\n line?: number;\n suggestion: string;\n}\n\n/**\n * Comprehensive validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n suggestions: string[];\n stats: {\n lineCount: number;\n charCount: number;\n importCount: number;\n primitiveCount: number;\n };\n}\n\n// Size limits\nconst MAX_FILE_SIZE = 50 * 1024; // 50KB\nconst MAX_LINE_COUNT = 500;\n\n// Security patterns — single source of truth in @ggui-ai/protocol.\n// Re-exported here so existing consumers don't break.\nconst DANGEROUS_PATTERNS = SHARED_DANGEROUS_PATTERNS;\n\n/**\n * Extract line number from code for a match\n */\nfunction getLineNumber(code: string, match: RegExpExecArray): number {\n const upToMatch = code.substring(0, match.index);\n return upToMatch.split('\\n').length;\n}\n\n/**\n * Extract imports from code\n */\nfunction extractImports(code: string): Array<{ source: string; line: number }> {\n const imports: Array<{ source: string; line: number }> = [];\n const importRegex = /import\\s+(?:[\\w\\s{},*]+\\s+from\\s+)?['\"]([^'\"]+)['\"]/g;\n let match;\n\n while ((match = importRegex.exec(code)) !== null) {\n imports.push({\n source: match[1],\n line: getLineNumber(code, match),\n });\n }\n\n return imports;\n}\n\n/**\n * Extract primitives used in code\n */\nfunction extractPrimitivesUsed(code: string): string[] {\n // Look for JSX tags that start with capital letters (React components)\n const jsxTagRegex = /<([A-Z][a-zA-Z0-9]*)/g;\n const used = new Set<string>();\n let match;\n\n while ((match = jsxTagRegex.exec(code)) !== null) {\n used.add(match[1]);\n }\n\n return Array.from(used);\n}\n\nexport interface ValidationOptions {\n /**\n * Skip import allowlist validation.\n * Used when bundle mode is enabled — external imports will be resolved\n * by esbuild at build time, not by the runtime.\n * Security patterns (eval, fetch, etc.) are still enforced.\n */\n skipImportValidation?: boolean;\n /**\n * Skip size limits (line count, file size).\n * Used for user-registered UIs where the developer controls the size.\n * LLM-generated UIs keep the limits to constrain generation.\n */\n skipSizeLimits?: boolean;\n /**\n * Skip dangerous-pattern security scan (eval, fetch, location, etc.).\n * Used for user-registered UIs where the developer controls the code.\n * LLM-generated UIs always get the security scan.\n */\n skipSecurityPatterns?: boolean;\n}\n\n/**\n * Validate component code with rich feedback.\n * Returns detailed errors, warnings, and suggestions.\n */\nexport function validateComponentDetailed(code: string, options: ValidationOptions = {}): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n const suggestions: string[] = [];\n const lines = code.split('\\n');\n const lineCount = lines.length;\n const charCount = code.length;\n\n // Size validation — skipped for user-registered UIs (developer controls size)\n if (!options.skipSizeLimits) {\n if (charCount > MAX_FILE_SIZE) {\n errors.push({\n type: 'size',\n message: `Component is too large: ${(charCount / 1024).toFixed(1)}KB exceeds ${MAX_FILE_SIZE / 1024}KB limit`,\n suggestion: 'Split the component into smaller sub-components or simplify the implementation.',\n });\n }\n\n if (lineCount > MAX_LINE_COUNT) {\n errors.push({\n type: 'size',\n message: `Component has too many lines: ${lineCount} exceeds ${MAX_LINE_COUNT} line limit`,\n suggestion: 'Split the component into smaller sub-components.',\n });\n }\n }\n\n // Import validation\n // Skipped in bundle mode — external imports are resolved by esbuild at build time.\n // The ALLOWED_IMPORTS list is for LLM-generated UIs (case 2) where only sandbox-provided\n // packages are available. Developer-registered UIs (case 1) with bundle mode can import anything.\n const imports = extractImports(code);\n if (!options.skipImportValidation) {\n for (const imp of imports) {\n const isAllowed = isAllowedImport(imp.source);\n // `@app/components` is the registered-component mechanism specific\n // to this validator — kept local, not part of the shared\n // design-system import allowlist.\n const isAppComponents =\n imp.source === '@app/components' ||\n imp.source.startsWith('@app/components/');\n if (!isAllowed && !isAppComponents) {\n errors.push({\n type: 'import',\n message: `Invalid import: \"${imp.source}\" is not allowed`,\n line: imp.line,\n suggestion: `Only import from: ${describeAllowedImports()}. Remove this import and use ggui primitives instead.`,\n });\n }\n }\n\n // Check for missing required imports\n if (!imports.some((i) => i.source === 'react')) {\n // Check if useState or other hooks are used\n if (/\\buseState\\b|\\buseEffect\\b|\\buseMemo\\b|\\buseCallback\\b|\\buseRef\\b/.test(code)) {\n warnings.push({\n type: 'best-practice',\n message: 'React hooks are used but react is not explicitly imported',\n suggestion: \"Add: import { useState } from 'react';\",\n });\n }\n }\n\n if (!imports.some((i) => i.source === '@ggui-ai/design')) {\n warnings.push({\n type: 'best-practice',\n message: 'No primitives imported from @ggui-ai/design',\n suggestion:\n \"Import primitives: import { Container, Card, Stack, Text, Button } from '@ggui-ai/design';\",\n });\n }\n } // end skipImportValidation check\n\n // Primitive validation\n const primitivesUsed = extractPrimitivesUsed(code);\n\n // Check if any imports come from @app/components\n const hasAppComponentImport = imports.some((i) => i.source.startsWith('@app/components'));\n\n // Extract component names imported from @app/components\n const importedComponentNames = new Set<string>();\n\n if (hasAppComponentImport) {\n // Match named imports: import { Foo, Bar } from '@app/components'\n const namedImportRegex = /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]@app\\/components['\"]/g;\n let match;\n while ((match = namedImportRegex.exec(code)) !== null) {\n const names = match[1].split(',').map((n) => n.trim().split(' as ')[0].trim());\n for (const name of names) {\n if (name) importedComponentNames.add(name);\n }\n }\n // Match default imports: import Foo from '@app/components/Foo'\n const defaultImportRegex = /import\\s+(\\w+)\\s+from\\s*['\"]@app\\/components\\/[^'\"]+['\"]/g;\n while ((match = defaultImportRegex.exec(code)) !== null) {\n importedComponentNames.add(match[1]);\n }\n }\n\n for (const primitive of primitivesUsed) {\n if (!VALID_PRIMITIVES.includes(primitive as (typeof VALID_PRIMITIVES)[number])) {\n // Check if it's imported from @app/components\n if (importedComponentNames.has(primitive)) {\n continue; // Valid imported component\n }\n\n // Check if it's a user-defined component (starts with capital and not a primitive)\n const isImported = code.includes(`import`) && code.includes(primitive);\n if (!isImported) {\n errors.push({\n type: 'primitive',\n message: `Unknown component: \"${primitive}\" is not a valid ggui primitive`,\n suggestion: `Use one of the valid primitives: ${VALID_PRIMITIVES.slice(0, 10).join(', ')}... or import from @app/components, or define it within this component.`,\n });\n }\n }\n }\n\n // Security validation — skipped for user-registered UIs (developer controls code)\n if (!options.skipSecurityPatterns) {\n for (const { pattern, name, suggestion } of DANGEROUS_PATTERNS) {\n const match = pattern.exec(code);\n if (match) {\n errors.push({\n type: 'security',\n message: `Security violation: ${name} is not allowed`,\n line: getLineNumber(code, match),\n suggestion,\n code: match[0],\n });\n }\n }\n }\n\n // Structure validation\n if (!code.includes('export default')) {\n errors.push({\n type: 'structure',\n message: 'Component must have a default export',\n suggestion: 'Add \"export default\" before your main component function.',\n });\n }\n\n // Check for class components\n if (/class\\s+\\w+\\s+extends\\s+(React\\.)?Component/.test(code)) {\n errors.push({\n type: 'structure',\n message: 'Class components are not allowed',\n suggestion: 'Convert to a functional component using hooks.',\n });\n }\n\n // Best practice warnings\n if (!code.includes('interface') && !code.includes('type ') && code.includes('Props')) {\n warnings.push({\n type: 'best-practice',\n message: 'Props are used but no TypeScript interface is defined',\n suggestion: 'Define a Props interface: interface Props { onSubmit: (data: FormData) => void; }',\n });\n }\n\n // Check for e.target.value pattern (common mistake)\n if (/e\\.target\\.value|event\\.target\\.value/.test(code)) {\n errors.push({\n type: 'syntax',\n message:\n 'Using e.target.value with ggui primitives will fail - onChange receives value directly',\n suggestion:\n 'Change from onChange={(e) => setValue(e.target.value)} to onChange={setValue} or onChange={(value) => setValue(value)}',\n });\n }\n\n // Check for missing key prop in map\n if (code.includes('.map(') && !code.includes('key=')) {\n warnings.push({\n type: 'best-practice',\n message: 'List rendering detected but no key prop found',\n suggestion: 'Add key prop to mapped elements: {items.map(item => <Card key={item.id}>...)}',\n });\n }\n\n // Accessibility warnings\n if (code.includes('<Image') && !code.includes('alt=')) {\n warnings.push({\n type: 'accessibility',\n message: 'Image without alt attribute',\n suggestion: 'Add alt attribute to Image: <Image src={...} alt=\"Description\" />',\n });\n }\n\n // Check form inputs have labels\n const hasInputs = /<Input\\b/.test(code) || /<TextArea\\b/.test(code) || /<Select\\b/.test(code);\n if (hasInputs) {\n const hasLabels = /label=/.test(code) || /htmlFor=/.test(code) || /aria-label=/.test(code) || /aria-labelledby=/.test(code);\n if (!hasLabels) {\n warnings.push({\n type: 'accessibility',\n message: 'Form inputs detected without labels',\n suggestion: 'Add label prop to inputs or associate with <Text is=\"label\" htmlFor=\"id\">. Screen readers need labels to identify form fields.',\n });\n }\n }\n\n // Check forms have role and aria-label\n if ((code.includes('onSubmit') || code.includes('role=\"form\"')) && !code.includes('aria-label')) {\n warnings.push({\n type: 'accessibility',\n message: 'Form without aria-label',\n suggestion: 'Add aria-label to your form container: <Stack role=\"form\" aria-label=\"Contact form\">',\n });\n }\n\n // Check for icon-only buttons without aria-label\n // Match buttons with single-character content (likely icons) and no aria-label\n const iconButtonPattern = /<Button(?![^>]*aria-label)[^>]*>\\s*.\\s*<\\/Button>/;\n if (iconButtonPattern.test(code)) {\n warnings.push({\n type: 'accessibility',\n message: 'Icon-only button detected without text content',\n suggestion: 'Add aria-label to icon-only buttons: <Button aria-label=\"Close\">×</Button>',\n });\n }\n\n if (code.includes('<Button') && !/disabled=|loading=/.test(code)) {\n if (code.includes('onSubmit') || code.includes('submit')) {\n warnings.push({\n type: 'best-practice',\n message: 'Submit button without disabled state',\n suggestion: 'Consider adding disabled={isSubmitting || !isValid} to prevent double submission',\n });\n }\n }\n\n // Generate suggestions based on analysis\n if (errors.length > 0) {\n suggestions.push('Fix all errors before compiling - the component will not work with errors.');\n }\n\n if (errors.some((e) => e.type === 'import')) {\n suggestions.push(\n 'Only react and @ggui-ai/design imports are allowed. All UI should be built with primitives.'\n );\n }\n\n if (errors.some((e) => e.type === 'security')) {\n suggestions.push('Avoid browser APIs - use props and callbacks for data flow.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n suggestions,\n stats: {\n lineCount,\n charCount,\n importCount: imports.length,\n primitiveCount: primitivesUsed.filter((p) =>\n VALID_PRIMITIVES.includes(p as (typeof VALID_PRIMITIVES)[number])\n ).length,\n },\n };\n}\n\n/**\n * Simple validation that throws on error (backward compatible).\n * Use validateComponentDetailed for rich feedback.\n */\nexport function validateComponent(code: string): void {\n const result = validateComponentDetailed(code);\n\n if (!result.valid) {\n const firstError = result.errors[0];\n const lineInfo = firstError.line ? ` (line ${firstError.line})` : '';\n throw new Error(`Validation failed${lineInfo}: ${firstError.message}\\n\\nSuggestion: ${firstError.suggestion}`);\n }\n}\n\n/**\n * Format validation result as a string for Claude feedback.\n * Provides context-rich error messages for the AI to understand and fix issues.\n */\nexport function formatValidationResultForClaude(result: ValidationResult): string {\n if (result.valid && result.warnings.length === 0) {\n return 'Validation passed. Component is ready for compilation.';\n }\n\n const parts: string[] = [];\n\n if (!result.valid) {\n parts.push('## Validation Errors (must fix)\\n');\n for (const error of result.errors) {\n const lineInfo = error.line ? ` (line ${error.line})` : '';\n parts.push(`- **${error.type.toUpperCase()}**${lineInfo}: ${error.message}`);\n parts.push(` - Fix: ${error.suggestion}`);\n if (error.code) {\n parts.push(` - Code: \\`${error.code}\\``);\n }\n }\n }\n\n if (result.warnings.length > 0) {\n parts.push('\\n## Warnings (recommended to fix)\\n');\n for (const warning of result.warnings) {\n const lineInfo = warning.line ? ` (line ${warning.line})` : '';\n parts.push(`- **${warning.type}**${lineInfo}: ${warning.message}`);\n parts.push(` - Suggestion: ${warning.suggestion}`);\n }\n }\n\n if (result.suggestions.length > 0) {\n parts.push('\\n## General Suggestions\\n');\n for (const suggestion of result.suggestions) {\n parts.push(`- ${suggestion}`);\n }\n }\n\n parts.push(\n `\\n## Stats: ${result.stats.lineCount} lines, ${result.stats.primitiveCount} primitives used`\n );\n\n return parts.join('\\n');\n}\n","/**\n * Default design system documentation for the `get_design_system` MCP tool.\n *\n * This large string documents all available CSS variables, design tokens,\n * animation presets, elevation levels, and typography scales. It is served\n * to the LLM when no app-specific design context is configured.\n *\n * Any changes here must stay in sync with the design tokens, CSS\n * variables, and component APIs published by `@ggui-ai/design`\n * (`packages/design/`). A drift between this doc and the real design\n * system causes the LLM to emit styling that the renderer cannot\n * honor.\n */\n\n/** Default light-theme design system documentation served to the LLM. */\nexport const DEFAULT_DESIGN_SYSTEM_DOCS = `# Design System - Default Light Theme\n\n**IMPORTANT:** Always use CSS variables (var(--ggui-*)) for styling to ensure components respect the app theme.\n\n## Colors\n\n### Primary\n- var(--ggui-color-primary-50) - #f0f9ff\n- var(--ggui-color-primary-100) - #e0f2fe\n- var(--ggui-color-primary-200) - #bae6fd\n- var(--ggui-color-primary-300) - #7dd3fc\n- var(--ggui-color-primary-400) - #38bdf8\n- var(--ggui-color-primary-500) - #0ea5e9\n- var(--ggui-color-primary-600) - #0284c7 (main action color)\n- var(--ggui-color-primary-700) - #0369a1\n- var(--ggui-color-primary-800) - #075985\n- var(--ggui-color-primary-900) - #0c4a6e\n\n### Semantic Surface & Text Colors (REQUIRED for theme compatibility)\nThese tokens adapt automatically to any theme (light, dark, branded). **ALWAYS use these for surfaces and text — never use raw neutral-* scale values.**\n\n| Token | CSS Variable | Default | Role |\n|-------|-------------|---------|------|\n| surface | var(--ggui-color-surface) | Main content background |\n| onSurface | var(--ggui-color-onSurface) | Primary text on surface |\n| surfaceVariant | var(--ggui-color-surfaceVariant) | Card/panel background |\n| onSurfaceVariant | var(--ggui-color-onSurfaceVariant) | Muted/secondary text |\n| container | var(--ggui-color-container) | Primary-branded containers |\n| onContainer | var(--ggui-color-onContainer) | Text on branded containers |\n| outline | var(--ggui-color-outline) | Borders, dividers |\n| outlineVariant | var(--ggui-color-outlineVariant) | Subtle borders |\n\n**Usage pattern:**\n- Page/section background → \\`var(--ggui-color-surface)\\`\n- Body text → \\`var(--ggui-color-onSurface)\\`\n- Card/panel background → \\`var(--ggui-color-surfaceVariant)\\`\n- Secondary/muted text → \\`var(--ggui-color-onSurfaceVariant)\\`\n- Branded section/header → \\`var(--ggui-color-container)\\` bg + \\`var(--ggui-color-onContainer)\\` text\n- Borders/dividers → \\`var(--ggui-color-outline)\\` or \\`var(--ggui-color-outlineVariant)\\`\n\n### State Colors\n- var(--ggui-color-success) — success states\n- var(--ggui-color-warning) — warning states\n- var(--ggui-color-error) — error states, destructive actions\n- var(--ggui-color-info) — informational\n\n### IMPORTANT: Color Rules\n- **NEVER** use hardcoded hex colors. ONLY use var(--ggui-color-*) tokens.\n- **NEVER** use rgba(), hsl(), or other CSS color functions with hardcoded values.\n- **NEVER** use raw neutral-* or gray-* scale tokens (neutral-50, neutral-900, etc.) — these are internal to the theme and break in dark mode.\n- **ALWAYS** use semantic tokens for text and backgrounds:\n - Text: \\`var(--ggui-color-onSurface)\\` or \\`var(--ggui-color-onSurfaceVariant)\\`\n - Backgrounds: \\`var(--ggui-color-surface)\\` or \\`var(--ggui-color-surfaceVariant)\\`\n - Borders: \\`var(--ggui-color-outline)\\` or \\`var(--ggui-color-outlineVariant)\\`\n- For branded elements use \\`var(--ggui-color-primary-*)\\` scale tokens — these ARE safe because primary adapts per theme.\n- For card backgrounds use \\`var(--ggui-color-surfaceVariant)\\` or \\`var(--ggui-color-primary-50)\\`\n\n## Spacing\n\nUse \\`var(--ggui-spacing-N)\\` for all padding, gap, and margin values. **Never use raw numbers** like \\`padding={16}\\` — always use the token: \\`padding=\"var(--ggui-spacing-4)\"\\`.\n\n| Token | Value | Common use |\n|-------|-------|------------|\n| var(--ggui-spacing-1) | 4px | Icon gaps, tight spacing |\n| var(--ggui-spacing-2) | 8px | Button padding, small gaps |\n| var(--ggui-spacing-3) | 12px | List item spacing, form gaps |\n| var(--ggui-spacing-4) | 16px | Card padding, section gaps |\n| var(--ggui-spacing-5) | 20px | Medium padding |\n| var(--ggui-spacing-6) | 24px | Container padding, large gaps |\n| var(--ggui-spacing-8) | 32px | Section spacing |\n| var(--ggui-spacing-10) | 40px | Page margins |\n| var(--ggui-spacing-12) | 48px | Hero/large section spacing |\n\n**Quick lookup (px → token):** 4→1, 8→2, 12→3, 16→4, 20→5, 24→6, 28→7, 32→8, 36→9, 40→10, 48→12\n\n**Usage on primitives:**\n\\`\\`\\`tsx\n<Container padding=\"var(--ggui-spacing-6)\">\n <Stack gap=\"var(--ggui-spacing-4)\">\n <Card padding=\"var(--ggui-spacing-4)\">\n <Row gap=\"var(--ggui-spacing-2)\">...</Row>\n </Card>\n </Stack>\n</Container>\n\\`\\`\\`\n\n## Typography\n\n### Font Sizes\n- var(--ggui-font-size-xs) - 12px\n- var(--ggui-font-size-sm) - 14px\n- var(--ggui-font-size-base) - 16px\n- var(--ggui-font-size-lg) - 18px\n- var(--ggui-font-size-xl) - 20px\n- var(--ggui-font-size-2xl) - 24px\n- var(--ggui-font-size-3xl) - 30px\n- var(--ggui-font-size-4xl) - 36px\n\n### Font Weights\n- var(--ggui-font-weight-normal) - 400\n- var(--ggui-font-weight-medium) - 500\n- var(--ggui-font-weight-semibold) - 600\n- var(--ggui-font-weight-bold) - 700\n\n## Border Radius\n- var(--ggui-shape-radius-sm) - 4px\n- var(--ggui-shape-radius-md) - 8px\n- var(--ggui-shape-radius-lg) - 12px\n- var(--ggui-shape-radius-xl) - 16px\n- var(--ggui-shape-radius-full) - 9999px\n\n## Shadows\n- var(--ggui-shape-shadow-sm) - 0 1px 2px rgba(0,0,0,0.05)\n- var(--ggui-shape-shadow-md) - 0 4px 6px -1px rgba(0,0,0,0.1)\n- var(--ggui-shape-shadow-lg) - 0 10px 15px -3px rgba(0,0,0,0.1)\n- var(--ggui-shape-shadow-xl) - 0 20px 25px -5px rgba(0,0,0,0.1)\n\n## Usage Examples (always use ggui primitives — never raw <div>, <button>, <input>)\n\n### Branded section header\n\\`\\`\\`tsx\n<Box padding=\"var(--ggui-spacing-4)\" surface=\"accent\">\n <Heading level={2} tone=\"emphasized\">Contact Us</Heading>\n <Text tone=\"emphasized\">We'd love to hear from you</Text>\n</Box>\n\\`\\`\\`\n\n### Form input\n\\`\\`\\`tsx\n<Input label=\"Email\" placeholder=\"you@example.com\" />\n\\`\\`\\`\n\n### Buttons\n\\`\\`\\`tsx\n<Button variant=\"primary\">Submit</Button>\n<Button variant=\"outline\">Cancel</Button>\n<Button variant=\"ghost\">Skip</Button>\n\\`\\`\\`\n\n### Card with spacing tokens\n\\`\\`\\`tsx\n<Card padding=\"var(--ggui-spacing-4)\" shadow=\"md\">\n <Stack gap=\"var(--ggui-spacing-3)\">\n <Heading level={3}>Title</Heading>\n <Text tone=\"muted\">Description</Text>\n </Stack>\n</Card>\n\\`\\`\\`\n\n### Color usage guide\n- **Semantic roles** (surface, onSurface, container, outline): Use for all surface/text/border decisions — these adapt to any theme\n- **primary-50/100**: Section backgrounds, highlight strips, card headers\n- **primary-200/300**: Borders, dividers, focus rings, input outlines\n- **primary-500/600**: Icons, links, labels, badges, buttons, CTAs\n- **primary-700/800/900**: Headings and text on light primary backgrounds\n- **neutral-***: Only when you need a specific shade that semantic tokens don't cover\n\nThe primary palette is the app's brand — use it throughout (headers, accents, borders, interactive elements), not just on the submit button.\n\n**Note:** Do NOT add fallback values to var() (e.g., var(--ggui-color-surface, #fafafa)). Just use var(--ggui-color-surface) — the theme provides all values.\n\n## Motion & Animation\n\n### Duration Scale\n- \\`instant\\`: 0ms\n- \\`fast\\`: 100ms\n- \\`normal\\`: 200ms\n- \\`slow\\`: 300ms\n- \\`slower\\`: 500ms\n\n### Easing Curves\n- \\`linear\\`: linear\n- \\`easeIn\\`: cubic-bezier(0.4, 0, 1, 1)\n- \\`easeOut\\`: cubic-bezier(0, 0, 0.2, 1)\n- \\`easeInOut\\`: cubic-bezier(0.4, 0, 0.2, 1)\n- \\`spring\\`: cubic-bezier(0.175, 0.885, 0.32, 1.275)\n\n### Transition Presets (import from '@ggui-ai/design/tokens')\n\\`\\`\\`tsx\nimport { duration, easing, transition } from '@ggui-ai/design/tokens';\n// transition.fast → \"100ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.normal → \"200ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.slow → \"300ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.colors → color + background-color + border-color (200ms each)\n// transition.opacity → opacity 200ms\n// transition.transform → transform 200ms\n\\`\\`\\`\n\n### Animation Keyframes\nUse \\`<MotionKeyframes />\\` once in your component to inject all keyframes, then reference by name.\n\n**Entrance / exit** (GPU-composited, transform + opacity):\n- \\`ggui-fadeIn\\` / \\`ggui-fadeOut\\`\n- \\`ggui-slideInUp\\` / \\`ggui-slideInDown\\`\n- \\`ggui-scaleIn\\` / \\`ggui-scaleOut\\`\n\n**State feedback** (color-based, for data-change highlights):\n- \\`ggui-flash\\` — background-color highlight that fades out. Set \\`--ggui-flash-color\\` on the element (default: \\`var(--ggui-color-primary-100)\\`)\n- \\`ggui-pulse\\` — gentle opacity breathing (infinite, for \"live\" indicators)\n- \\`ggui-bounce\\` — subtle scale overshoot (one-shot, for confirmations)\n\n\\`\\`\\`tsx\nimport { MotionKeyframes, useMotion, useAnimationKey } from '@ggui-ai/design';\nimport { animation } from '@ggui-ai/design/tokens';\n\nfunction MyComponent() {\n const { motionEnabled } = useMotion(); // respects prefers-reduced-motion\n return (\n <>\n <MotionKeyframes />\n {/* Entrance animation */}\n <div style={{ animation: motionEnabled ? animation.slideInUp : 'none' }}>\n Content slides in\n </div>\n </>\n );\n}\n\\`\\`\\`\n\n### Retriggering Animations on Data Changes\nWhen data updates (e.g., stock price from a stream), CSS animations don't replay automatically.\nUse \\`useAnimationKey(dep)\\` — returns a key that increments when \\`dep\\` changes, causing React to remount the element and replay the animation.\n\n\\`\\`\\`tsx\nimport { MotionKeyframes, useAnimationKey } from '@ggui-ai/design';\nimport { animation } from '@ggui-ai/design/tokens';\n\n// Flash a stock card green/red when the price changes\nconst priceKey = useAnimationKey(stock.price);\n<div\n key={priceKey}\n style={{\n animation: animation.flash,\n '--ggui-flash-color': stock.change > 0\n ? 'var(--ggui-color-success-100)'\n : 'var(--ggui-color-error-100)',\n } as React.CSSProperties}\n>\n {stock.price}\n</div>\n\\`\\`\\`\n\n## Chart / Data Visualization Colors\nSemantic chart tokens for data visualizations:\n- \\`var(--ggui-color-primary-600)\\` — primary series\n- \\`var(--ggui-color-success-500)\\` — positive / success\n- \\`var(--ggui-color-error-500)\\` — negative / error\n- \\`var(--ggui-color-warning-500)\\` — warning / caution\n- \\`var(--ggui-color-info-500)\\` — informational\n- \\`var(--ggui-color-neutral-400)\\` — neutral series\n- \\`var(--ggui-color-neutral-200)\\` — light background series\n- \\`var(--ggui-color-neutral-600)\\` — dark series\n\n## Accessibility Tokens\n\n### Focus Ring (for keyboard focus states)\n- Color: \\`var(--ggui-color-primary-600)\\`\n- Width: 2px\n- Offset: 2px\n- Style: solid\n\\`\\`\\`tsx\n// Apply to focusable elements:\noutline: '2px solid var(--ggui-color-primary-600)',\noutlineOffset: '2px',\n\\`\\`\\`\n\n### Reduced Motion\nUse \\`useMotion()\\` hook to check user preference. If disabled, set animation/transition to \\`none\\`.\n\n## Elevation System\nSemantic depth levels combining shadow + z-index:\n| Level | Shadow | Z-Index | Use For |\n|-------|--------|---------|---------|\n| 0 | none | 0 | Flat content |\n| 1 | sm | auto | Cards, slight lift |\n| 2 | md | 1000 | Dropdowns, popovers |\n| 3 | lg | 1200 | Banners, sticky bars |\n| 4 | xl | 1400 | Modals, dialogs |\n| 5 | 2xl | 1800 | Tooltips, toasts |\n\n\\`\\`\\`tsx\nimport { elevation } from '@ggui-ai/design/tokens';\n// elevation.level1 → { shadow: 'var(--ggui-shape-shadow-sm)', zIndex: 'auto' }\n// elevation.level2 → { shadow: 'var(--ggui-shape-shadow-md)', zIndex: 1000 }\n<div style={{ boxShadow: elevation.level1.shadow, zIndex: elevation.level1.zIndex }}>\n Card content\n</div>\n\\`\\`\\`\n\n## Typography Presets\n\n### Heading Styles (import { headingStyles } from '@ggui-ai/design/tokens')\n| Level | Size | Weight | Line Height | Letter Spacing |\n|-------|------|--------|-------------|----------------|\n| h1 | 36px | bold (700) | 1.25 | -0.025em |\n| h2 | 30px | bold (700) | 1.25 | -0.025em |\n| h3 | 24px | semibold (600) | 1.375 | 0 |\n| h4 | 20px | semibold (600) | 1.375 | 0 |\n| h5 | 18px | semibold (600) | 1.5 | 0 |\n| h6 | 16px | semibold (600) | 1.5 | 0 |\n\n### Text Sizing\n\\`<Text>\\` composes from \\`size\\` / \\`weight\\` / \\`tone\\` (+ \\`caps\\` for the\nuppercase eyebrow look) — there is no preset text-style table. Line\nheight derives from \\`size\\` automatically (1.5 for xs-base, 1.625 at lg,\ntighter on display sizes).\n\n### Letter Spacing Scale\n- \\`tighter\\`: -0.05em\n- \\`tight\\`: -0.025em\n- \\`normal\\`: 0\n- \\`wide\\`: 0.025em\n- \\`wider\\`: 0.05em\n- \\`widest\\`: 0.1em\n\n### Line Height Scale\n- \\`none\\`: 1\n- \\`tight\\`: 1.25\n- \\`snug\\`: 1.375\n- \\`normal\\`: 1.5\n- \\`relaxed\\`: 1.625\n- \\`loose\\`: 2`;\n","// packages/ui-gen/src/boilerplate/json-schema-ts.ts\n//\n// JSON Schema → TypeScript type string converter.\n//\n// Pure, self-contained, no env reads, no framework deps. Exposed\n// publicly on `@ggui-ai/ui-gen/boilerplate` because it's the primitive\n// that turns a contract's JSON Schema into the `interface Props { ... }`\n// block the boilerplate generator writes.\n\nimport type { JsonSchema } from '@ggui-ai/protocol';\n\n/**\n * Convert a JsonSchema to a TypeScript type string — recursive.\n *\n * Handles: string, number, integer, boolean, null, array (+ tuples), object,\n * enum, oneOf/anyOf (unions), nullable, const, additionalProperties.\n */\nexport function jsonSchemaTypeToTs(schema: JsonSchema): string {\n // ── Union types (oneOf / anyOf) ──\n const unionMembers = schema.oneOf ?? schema.anyOf;\n if (unionMembers?.length) {\n const types = [...new Set(unionMembers.map(s => jsonSchemaTypeToTs(s)))];\n return types.length === 1 ? types[0] : types.join(' | ');\n }\n\n // ── Const (literal type) ──\n if (schema.const !== undefined) {\n return typeof schema.const === 'string' ? `'${schema.const}'` : String(schema.const);\n }\n\n // ── Enum (union of literals) ──\n if (schema.enum?.length) {\n return schema.enum\n .map(v => typeof v === 'string' ? `'${v}'` : String(v))\n .join(' | ');\n }\n\n let result: string;\n\n switch (schema.type) {\n case 'string':\n result = 'string';\n break;\n case 'number':\n case 'integer':\n result = 'number';\n break;\n case 'boolean':\n result = 'boolean';\n break;\n case 'null':\n return 'null';\n\n case 'array': {\n if (schema.items) {\n const itemType = jsonSchemaTypeToTs(schema.items);\n // Use Array<T> for complex object types, T[] for simple\n result = (schema.items.type === 'object' && schema.items.properties)\n ? `Array<${itemType}>`\n : (itemType.includes('|') ? `(${itemType})[]` : `${itemType}[]`);\n } else {\n result = 'unknown[]';\n }\n break;\n }\n\n case 'object': {\n if (schema.properties) {\n const required = schema.required ?? [];\n const fields = Object.entries(schema.properties)\n .map(([key, prop]) => {\n const opt = !required.includes(key);\n return `${key}${opt ? '?' : ''}: ${jsonSchemaTypeToTs(prop)}`;\n })\n .join('; ');\n result = `{ ${fields} }`;\n } else if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n result = `Record<string, ${jsonSchemaTypeToTs(schema.additionalProperties)}>`;\n } else {\n result = 'Record<string, unknown>';\n }\n break;\n }\n\n default:\n result = 'unknown';\n }\n\n // Apply nullable (OpenAPI 3.0 shorthand)\n if (schema.nullable && result !== 'unknown') {\n return `${result} | null`;\n }\n\n return result;\n}\n","// packages/ui-gen/src/check/contract-validation.ts\n//\n// Shared validation utilities for data-contract conformance —\n// deterministic tier-0 gate for `PropsSpec` / `StreamSpec` / `ActionSpec`\n// agreement between the LLM-emitted componentCode and the contract the\n// agent handed to `ggui_render`.\n//\n// Used by:\n// (1) Self-check soft gate in the coding agent\n// (`coding-agent/self-check.ts`) — surfaces mismatches as\n// structured violations for the LLM retry loop.\n// (2) Tier-0 hard gate in the evaluation pipeline — errors (severity\n// `error`) are blocking; warnings surface as advisory.\n// (3) Adapter tool-family wiring for multi-SDK generation runs.\n// (4) Benchmarks + LLM prompt construction — `jsonSchemaTypeToTs` +\n// `propsSpecToTypeScript` + `inferPropsSpecFromSampleData` are\n// pure helpers reused outside the check path. Re-exported here so\n// those callers don't need a separate import for the subpath.\n//\n// Deps are pure: `@ggui-ai/protocol` (public types) + `typescript`\n// (compiler API) + the in-package `jsonSchemaTypeToTs` primitive from\n// `../boilerplate/json-schema-ts.js`.\n\nimport type {\n PropsSpec,\n StreamSpec,\n ActionSpec,\n DataContract,\n JsonSchema,\n JsonValue,\n PropEntry,\n JsonObject,\n} from \"@ggui-ai/protocol\";\nimport ts from \"typescript\";\n\n// Re-export the pure JSON-Schema → TypeScript-type converter from the\n// in-package `boilerplate/` primitive, so consumers of the tier-0 check\n// surface (self-check, tiers, benchmarks, prompts, adapters) import a\n// single symbol from a single subpath.\nexport { jsonSchemaTypeToTs } from \"../boilerplate/json-schema-ts.js\";\nimport { jsonSchemaTypeToTs } from \"../boilerplate/json-schema-ts.js\";\n\n// =============================================================================\n// Contract Issue\n// =============================================================================\n\nexport interface ContractIssue {\n severity: \"error\" | \"warning\";\n field: string;\n message: string;\n fix: string;\n}\n\n// =============================================================================\n// Props Interface Extraction (AST-based)\n// =============================================================================\n\ninterface ExtractedProp {\n name: string;\n type: string;\n optional: boolean;\n}\n\n/**\n * Extract field names and types from a TypeScript Props interface in source code.\n * Uses the TypeScript compiler API — handles nested types, generics, unions correctly.\n */\nexport function extractPropsInterface(code: string): ExtractedProp[] | null {\n const sf = ts.createSourceFile(\"component.tsx\", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n const props: ExtractedProp[] = [];\n\n function visitMembers(members: ts.NodeArray<ts.TypeElement>): void {\n for (const member of members) {\n if (ts.isPropertySignature(member) && member.name) {\n const name = member.name.getText(sf);\n const type = member.type ? member.type.getText(sf) : \"unknown\";\n const optional = !!member.questionToken;\n props.push({ name, type, optional });\n }\n }\n }\n\n function visit(node: ts.Node): void {\n // interface Props { ... }\n if (ts.isInterfaceDeclaration(node) && node.name.text === \"Props\") {\n visitMembers(node.members);\n return;\n }\n // type Props = { ... }\n if (ts.isTypeAliasDeclaration(node) && node.name.text === \"Props\") {\n if (ts.isTypeLiteralNode(node.type)) {\n visitMembers(node.type.members);\n }\n return;\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sf);\n return props.length > 0 ? props : null;\n}\n\n// =============================================================================\n// Contract Validation\n// =============================================================================\n\n/**\n * Compare extracted Props interface against a PropsSpec contract.\n * Returns issues: errors for missing required fields, warnings for type mismatches.\n */\nexport function validatePropsAgainstSchema(\n code: string,\n spec: PropsSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n const extracted = extractPropsInterface(code);\n\n if (!extracted) {\n // Can't extract — not necessarily an error (might use inline types)\n return [];\n }\n\n const extractedMap = new Map(extracted.map((p) => [p.name, p]));\n\n for (const [propName, entry] of Object.entries(spec.properties)) {\n const extractedProp = extractedMap.get(propName);\n\n if (!extractedProp) {\n if (entry.required) {\n issues.push({\n severity: \"error\",\n field: propName,\n message: `Props interface is missing required field '${propName}' from the data contract`,\n fix: `Add \\`${propName}${entry.required ? \"\" : \"?\"}: ${jsonSchemaTypeToTs(entry.schema)}\\` to your Props interface`,\n });\n } else {\n issues.push({\n severity: \"warning\",\n field: propName,\n message: `Props interface is missing optional field '${propName}' from the data contract`,\n fix: `Consider adding \\`${propName}?: ${jsonSchemaTypeToTs(entry.schema)}\\` to your Props interface`,\n });\n }\n continue;\n }\n\n // Basic type compatibility check (only if we have type info)\n if (extractedProp.type !== \"unknown\") {\n const expectedTsType = jsonSchemaTypeToTs(entry.schema);\n if (!isTypeCompatible(extractedProp.type, expectedTsType, entry.schema)) {\n issues.push({\n severity: \"warning\",\n field: propName,\n message: `Field '${propName}' has type '${extractedProp.type}' but contract expects '${expectedTsType}'`,\n fix: `Change \\`${propName}\\` type to \\`${expectedTsType}\\``,\n });\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Check if a TypeScript type string is compatible with a JSON Schema type.\n * Loose comparison — we only check the base type, not full structural equality.\n */\nfunction isTypeCompatible(tsType: string, expectedTsType: string, schema: JsonSchema): boolean {\n const normalized = tsType.replace(/\\s/g, \"\").toLowerCase();\n\n switch (schema.type) {\n case \"string\":\n return normalized.includes(\"string\");\n case \"number\":\n case \"integer\":\n return normalized.includes(\"number\");\n case \"boolean\":\n return normalized.includes(\"boolean\");\n case \"array\":\n return normalized.includes(\"[]\") || normalized.includes(\"array\");\n case \"object\":\n return ![\"string\", \"number\", \"boolean\"].some((t) => normalized === t);\n default:\n return true;\n }\n}\n\n// =============================================================================\n// JSON Schema → TypeScript Conversion (for LLM prompts)\n// =============================================================================\n\n// `jsonSchemaTypeToTs` lives in `@ggui-ai/ui-gen/boilerplate` and is\n// re-exported at the top of this file.\n\n/**\n * Convert a full PropsSpec to a TypeScript interface string for LLM prompt injection.\n * Includes required/optional markers and descriptions as comments.\n */\nexport function propsSpecToTypeScript(spec: PropsSpec, indent = 2): string {\n const pad = \" \".repeat(indent);\n const lines: string[] = [];\n\n for (const [propName, entry] of Object.entries(spec.properties)) {\n if (entry.description) {\n lines.push(`${pad}/** ${entry.description} */`);\n }\n const optional = !entry.required;\n const tsType = jsonSchemaTypeToTs(entry.schema);\n const defaultStr = entry.default !== undefined ? ` // default: ${JSON.stringify(entry.default)}` : \"\";\n lines.push(`${pad}${propName}${optional ? \"?\" : \"\"}: ${tsType};${defaultStr}`);\n // Include example as a comment so the LLM sees the exact data shape\n if (entry.example !== undefined) {\n const exampleStr = JSON.stringify(entry.example, null, 2)\n .split(\"\\n\")\n .map((l, i) => (i === 0 ? `${pad}// Example: ${l}` : `${pad}// ${l}`))\n .join(\"\\n\");\n lines.push(exampleStr);\n }\n }\n\n return `{\\n${lines.join(\"\\n\")}\\n}`;\n}\n\n// =============================================================================\n// StreamSpec Validation\n// =============================================================================\n\n/**\n * Validate that the generated source code properly handles stream events.\n * Requires useStream() wire hooks — legacy DOM event patterns are no longer accepted.\n */\nexport function validateStreamSpecConformance(\n code: string,\n spec: StreamSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n const usesWireStream = code.includes(\"useStream\");\n\n if (!usesWireStream) {\n issues.push({\n severity: \"error\",\n field: \"__streamSpec__\",\n message: \"Component does not handle stream events — use useStream() from the boilerplate wire hooks\",\n fix: \"Use the useStream('eventName') hook from the boilerplate to receive real-time data from the agent\",\n });\n return issues;\n }\n\n // Check each declared channel is referenced in the code. `spec` is a\n // flat `Record<channelName, StreamChannelEntry>` — iterate directly.\n for (const [channelName, entry] of Object.entries(spec)) {\n if (!code.includes(`'${channelName}'`) && !code.includes(`\"${channelName}\"`)) {\n issues.push({\n severity: \"warning\",\n field: channelName,\n message: `StreamSpec declares channel '${channelName}' but component doesn't reference it`,\n fix: `Add useStream('${channelName}') to receive ${entry.description || channelName} events`,\n });\n }\n }\n\n return issues;\n}\n\n// =============================================================================\n// ActionSpec Validation\n// =============================================================================\n\n/**\n * Validate that the generated source code wires the declared actions.\n * Checks that action IDs are referenced via useAction() wire hooks, string literals, or prop callbacks.\n */\nexport function validateActionSpecConformance(\n code: string,\n spec: ActionSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n // `spec` is a flat `Record<actionId, ActionEntry>` — iterate directly.\n for (const [actionId, entry] of Object.entries(spec)) {\n // Check the action ID or its label is referenced in the code\n const idReferenced = code.includes(`'${actionId}'`) || code.includes(`\"${actionId}\"`);\n const labelReferenced = code.includes(entry.label);\n const callbackName = `on${actionId.charAt(0).toUpperCase()}${actionId.slice(1)}`;\n const callbackReferenced = code.includes(callbackName);\n\n if (!idReferenced && !labelReferenced && !callbackReferenced) {\n issues.push({\n severity: \"error\",\n field: actionId,\n message: `ActionSpec declares action '${actionId}' (\"${entry.label}\") but component doesn't wire it`,\n fix: `Use the useAction('${actionId}') hook from the boilerplate and wire it to a button or form submit`,\n });\n }\n }\n\n return issues;\n}\n\n// =============================================================================\n// Unified Contract Validation\n// =============================================================================\n\n/**\n * Validate all contract (props, stream, actions) against the source code.\n * Returns combined issues from all three validations.\n */\nexport function validateAllContracts(\n code: string,\n contract: DataContract,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n if (contract.propsSpec) {\n issues.push(...validatePropsAgainstSchema(code, contract.propsSpec));\n }\n\n if (contract.streamSpec) {\n issues.push(...validateStreamSpecConformance(code, contract.streamSpec));\n }\n\n if (contract.actionSpec) {\n issues.push(...validateActionSpecConformance(code, contract.actionSpec));\n }\n\n return issues;\n}\n\n// =============================================================================\n// Sample Data → PropsSpec Inference (backward compat)\n// =============================================================================\n\n/**\n * Infer a PropsSpec from sample data.\n * Convenience utility for migration and for agents that pass sample data instead of schemas.\n * All fields are marked as required (can't distinguish required/optional from data alone).\n */\nexport function inferPropsSpecFromSampleData(data: JsonObject): PropsSpec {\n const properties: Record<string, PropEntry> = {};\n\n for (const [key, value] of Object.entries(data)) {\n properties[key] = {\n schema: inferJsonSchema(value),\n required: true,\n example: value as JsonValue,\n };\n }\n\n return { properties };\n}\n\nfunction inferJsonSchema(value: unknown): JsonSchema {\n if (value === null || value === undefined) return { type: \"null\" };\n if (typeof value === \"string\") return { type: \"string\" };\n if (typeof value === \"number\") return { type: \"number\" };\n if (typeof value === \"boolean\") return { type: \"boolean\" };\n\n if (Array.isArray(value)) {\n if (value.length === 0) return { type: \"array\" };\n return {\n type: \"array\",\n items: inferJsonSchema(value[0]),\n };\n }\n\n if (typeof value === \"object\") {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const [k, v] of Object.entries(value as JsonObject)) {\n properties[k] = inferJsonSchema(v);\n required.push(k);\n }\n return { type: \"object\", properties, required };\n }\n\n return { type: \"string\" };\n}\n","// packages/ui-gen/src/check/type-checker.ts\n//\n// TypeScript type-checker for LLM-generated UI components. Uses the\n// TypeScript compiler API with a virtual filesystem to type-check TSX\n// code against React types and `@ggui-ai/design` primitives, giving\n// the LLM familiar TS error feedback without writing anything to disk.\n//\n// The checker builds a virtual filesystem seeded with `typescript/lib`,\n// `@types/react`, `@ggui-ai/design/dist`, and `@ggui-ai/wire/dist`\n// `.d.ts` content, then drives `ts.createProgram` against a synthetic\n// `Component.tsx`. Exposed on `@ggui-ai/ui-gen/check` so\n// `createUiGenerator` runs the same tier-0 gate as the hosted\n// generation path.\n//\n// Path-resolution note: the three workspace-rooted lookups —\n// `.pnpm/@types+react@*`, `packages/design/dist`, and\n// `packages/wire/dist` — are anchored relative to this file. tsup\n// bundles `src/check/index.ts` (splitting: false) into a flat\n// `dist/check/index.js`, so the src and dist locations sit at the same\n// depth and both resolve correctly. `typescript/lib/typescript.js`\n// keeps using `createRequire(import.meta.url).resolve` —\n// position-independent, so no change.\n//\n// Used by:\n// (1) Tier-0 `type_check` — blocking errors (see BLOCKING_CODES)\n// map to PRODUCTION_FAILED; non-blocking TS diagnostics surface\n// as warnings so the LLM can iterate on non-crash-risk findings\n// without stalling the harness.\n// (2) The `self_check` tool — called from generator SDKs (Anthropic /\n// OpenAI / Google) to give the LLM TS feedback mid-generation.\n// (3) The tier-0 orchestrator `runTier0Checks` — runs in parallel\n// with the wire-preservation + lint checks under the same tier\n// budget.\n//\n// Design notes that motivate non-obvious choices:\n// - Classic React JSX mode (`ts.JsxEmit.React`). The synthetic\n// prefix (see SYNTHETIC_PREFIX) supplies `import React from\n// 'react'` for the classic JSX factory PLUS a self-contained\n// global `JSX` namespace. `@types/react` v19 removed the global\n// `JSX` namespace that classic mode resolves intrinsic elements +\n// the `key`/`ref` carve-out through; without the shim, `<div>`\n// degrades to `any` and every typed component falsely rejects the\n// intrinsic `key` prop. Automatic mode was tried but its\n// `react/jsx-runtime` resolution does not survive the VFS.\n// - `strict: false` + `strictNullChecks: true`: we want the runtime\n// crash classes (`undefined.foo()`, `null.bar`) to surface as\n// blocking, but not the optional-chaining / exhaustive-check\n// noise that full `strict` would emit on LLM code.\n// - `types: []`: prevents the VFS from auto-pulling every\n// `@types/*` package that happens to be hoisted — only react and\n// the design/wire dist types should be reachable, matching the\n// forbidden-import policy enforced by `react-linter` elsewhere.\n// - TS2307 (\"Cannot find module\") is deliberately NOT blocking —\n// Lambda bundles code without type declarations, so the VFS can't\n// see every package that may exist at runtime. Forbidden imports\n// are caught by `runSelfChecks` regex instead.\n\nimport ts from 'typescript';\nimport fs from 'fs';\nimport path from 'path';\nimport { createRequire } from 'module';\nimport { describeAllowedImports } from '../validation/allowed-imports.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface TypeCheckDiagnostic {\n code: number;\n line: number;\n message: string;\n fix: string;\n}\n\nexport interface TypeCheckResult {\n errors: TypeCheckDiagnostic[]; // Blocking\n warnings: TypeCheckDiagnostic[]; // Non-blocking\n}\n\n// ---------------------------------------------------------------------------\n// Blocking error codes — these would break at runtime\n// ---------------------------------------------------------------------------\n\nconst BLOCKING_CODES = new Set([\n 2304, // Cannot find name\n // 2307 (Cannot find module) is NOT blocking — Lambda bundles code without\n // type declarations, so the VFS can't resolve react/@ggui-ai/design.\n // Forbidden imports are caught by runSelfChecks regex instead.\n 2305, // Module has no exported member\n 2322, // Type not assignable\n 2339, // Property does not exist on type\n 2741, // Missing required property\n 2769, // No overload matches this call\n 17004, // Cannot use JSX unless '--jsx' flag\n 18047, // 'X' is possibly 'null' — causes runtime crash\n 18048, // 'X' is possibly 'undefined' — causes runtime crash\n]);\n\n// ---------------------------------------------------------------------------\n// Fix suggestions per error code\n// ---------------------------------------------------------------------------\n\nfunction generateFix(code: number, message?: string, sourceLine?: string): string {\n // Source-line hint: when the failing line is short and self-contained,\n // appending it gives the LLM a precise target. Skip for very long lines\n // (>140 chars — usually multi-prop JSX where the line itself is the\n // diagnostic) since they bloat the violation envelope without helping.\n const sourceHint =\n sourceLine && sourceLine.length > 0 && sourceLine.length <= 140\n ? ` Offending line: \\`${sourceLine}\\``\n : '';\n\n // Detect event handler on non-interactive primitive\n if ((code === 2322 || code === 2339) && message && /onClick|onDoubleClick|onMouseEnter|onMouseLeave|onPress/.test(message)) {\n return `This structural primitive has no event handlers of its own — add the trait as a PROP: as={Clickable} (then onClick works), imported from @ggui-ai/design. Do NOT wrap it in <Clickable>…</Clickable>; as is a prop, not a wrapper element.${sourceHint}`;\n }\n\n // Detect underscore-prefix-on-prop trap: `Property '_X' does not exist`.\n // LLM saw an unused-var warning on `X` and tried to silence it by renaming\n // the destructure to `_X`, breaking prop access. Steer back.\n if (code === 2339 && message && /Property '_[a-zA-Z]/.test(message)) {\n return `You renamed a prop with a leading underscore to silence \\`no-unused-vars\\`, but the prop on \\`Props\\` doesn't have that prefix. Restore the original name; better, don't destructure props you won't render — access them via \\`props.fieldName\\` only when needed.${sourceHint}`;\n }\n\n // Detect \"Cannot find name\" for destructured props\n if (code === 2304 && message && !message.includes('module') && !message.includes('import')) {\n return `This name is not defined in scope. Either you destructured props (use \\`props.fieldName\\` directly instead) OR you removed a helper declaration in this patch but kept a JSX/expression reference to it. Read your full patch and either restore the declaration or remove the reference.${sourceHint}`;\n }\n\n // Detect \"unknown is not assignable to ReactNode\"\n if ((code === 2322 || code === 2769) && message && /unknown.*ReactNode|ReactNode.*unknown/.test(message)) {\n return `This value has type 'unknown' and cannot be rendered in JSX. Cast it: String(value) or add a type annotation.${sourceHint}`;\n }\n\n switch (code) {\n case 2307:\n return `Only these imports are allowed: ${describeAllowedImports()}${sourceHint}`;\n case 2322:\n case 2769:\n return `Type mismatch on this expression. Check the offending line below — the prop name in JSX is what TypeScript is rejecting; the message tells you the expected type.${sourceHint}`;\n case 2339:\n return `This prop doesn't exist on this component — check the available props on the component's interface (visible at the top of the file, or in the design-system reference).${sourceHint}`;\n case 2305:\n return `This name is not defined. Check your imports and variable declarations.${sourceHint}`;\n case 2741:\n return `A required prop is missing. Check the component's Props interface.${sourceHint}`;\n case 18047:\n case 18048:\n return `This value might be null/undefined. Every dereference on the same nullable still needs \\`?.\\` — \\`x?.foo && x?.bar\\`, NOT \\`x?.foo && x.bar\\`. Or hoist: \\`const v = x; if (!v) return null;\\` then access \\`v.foo\\`/\\`v.bar\\` unguarded.${sourceHint}`;\n default:\n return `Review the TypeScript error and fix the type issue.${sourceHint}`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Virtual Filesystem — lazy singleton\n// ---------------------------------------------------------------------------\n\ninterface VfsEntry {\n content: string;\n sourceFile: ts.SourceFile;\n}\n\nlet vfsCache: Map<string, VfsEntry> | null = null;\n\nfunction parseAndStore(\n vfs: Map<string, VfsEntry>,\n virtualPath: string,\n content: string,\n): void {\n const sourceFile = ts.createSourceFile(\n virtualPath,\n content,\n ts.ScriptTarget.ES2020,\n true,\n virtualPath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n vfs.set(virtualPath, { content, sourceFile });\n}\n\n/**\n * Recursively walk a directory and return all file paths matching a filter.\n */\nfunction walkDir(dir: string, filter: (f: string) => boolean): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...walkDir(full, filter));\n } else if (filter(full)) {\n results.push(full);\n }\n }\n return results;\n}\n\n/**\n * Resolve `@types/react`'s root directory through Node's module\n * resolution. Position-independent — walks the consumer's node_modules\n * chain. Works in monorepo (where the type package is hoisted under\n * `<root>/node_modules/.pnpm/@types+react@*`) and in standalone\n * `packages/`-only installs (e.g. the projected public OSS repo where\n * the `packages/` prefix is stripped, so a hardcoded `../../../..`\n * walk lands in the wrong place).\n */\nfunction findReactTypesDir(): string | null {\n try {\n // `@types/react` doesn't expose `package.json` as a public subpath,\n // so resolve via the always-present `index.d.ts`.\n const indexDts = createRequire(import.meta.url).resolve('@types/react/index.d.ts');\n return path.dirname(indexDts);\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a workspace package's `dist/` directory through Node's\n * module resolution. Like `findReactTypesDir`, this works in both\n * monorepo (where the package is hoisted/symlinked) and standalone\n * installs — no relative-path math required.\n */\nfunction findPackageDistDir(pkg: string): string | null {\n try {\n const pkgJson = createRequire(import.meta.url).resolve(`${pkg}/package.json`);\n const dist = path.join(path.dirname(pkgJson), 'dist');\n return fs.existsSync(dist) ? dist : null;\n } catch {\n return null;\n }\n}\n\nasync function loadVfs(): Promise<Map<string, VfsEntry>> {\n if (vfsCache) return vfsCache;\n\n const vfs = new Map<string, VfsEntry>();\n\n // ---- 1. TypeScript lib files ----\n // `createRequire(import.meta.url).resolve('typescript/lib/typescript.js')`\n // is position-independent — it walks the consumer's node_modules chain,\n // so this lookup works identically from core/, packages/ui-gen/, and any\n // future host package.\n const require_ = createRequire(import.meta.url);\n const tsDir = path.dirname(require_.resolve('typescript/lib/typescript.js'));\n const libFiles = fs.readdirSync(tsDir).filter((f) => /^lib\\..*\\.d\\.ts$/.test(f));\n for (const file of libFiles) {\n const content = fs.readFileSync(path.join(tsDir, file), 'utf-8');\n parseAndStore(vfs, file, content);\n }\n\n // ---- 2. React types ----\n // Resolved through `createRequire(import.meta.url).resolve('@types/\n // react/index.d.ts')` — position-independent. Works the same in\n // monorepo (hoisted to root) and in standalone `packages/`-only\n // installs (the projected public OSS repo strips the `packages/`\n // prefix, so a hardcoded `../../../..` walk would miss).\n const reactDir = findReactTypesDir();\n if (reactDir) {\n const reactDts = fs.readdirSync(reactDir).filter((f) => f.endsWith('.d.ts'));\n for (const file of reactDts) {\n const content = fs.readFileSync(path.join(reactDir, file), 'utf-8');\n parseAndStore(vfs, `node_modules/@types/react/${file}`, content);\n }\n }\n\n // ---- 3. Design system types ----\n const designDist = findPackageDistDir('@ggui-ai/design');\n if (designDist) {\n const dtsFiles = walkDir(designDist, (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'));\n for (const file of dtsFiles) {\n const rel = path.relative(designDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/design/${rel}`, content);\n }\n }\n\n // ---- 4. Wire module types ----\n const wireDist = findPackageDistDir('@ggui-ai/wire');\n if (wireDist) {\n const dtsFiles = walkDir(wireDist, (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'));\n for (const file of dtsFiles) {\n const rel = path.relative(wireDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/wire/${rel}`, content);\n }\n }\n\n // ---- 5. Gadgets types ----\n // Generated component code direct-imports standard-library gadget\n // hooks — `import { useGeolocation } from '@ggui-ai/gadgets'`.\n // Loading the `@ggui-ai/gadgets` package's shipped `.d.ts` into the\n // VFS makes those bare-named imports resolve against the real hook\n // declarations (named option/return types preserved). The standard\n // gadget hooks are plain named exports the resolver finds directly.\n const clientLibsDist = findPackageDistDir('@ggui-ai/gadgets');\n if (clientLibsDist) {\n const dtsFiles = walkDir(\n clientLibsDist,\n (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'),\n );\n for (const file of dtsFiles) {\n const rel = path.relative(clientLibsDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/gadgets/${rel}`, content);\n }\n }\n\n vfsCache = vfs;\n return vfs;\n}\n\n// ---------------------------------------------------------------------------\n// Module resolution helper\n// ---------------------------------------------------------------------------\n\n/**\n * Try to resolve a relative import within the VFS.\n * Given `containingFile` (e.g. `node_modules/@ggui-ai/design/primitives/index.d.ts`)\n * and `importPath` (e.g. `./Card`), try:\n * - <resolved>.d.ts\n * - <resolved>/index.d.ts\n * - <resolved>.ts\n */\nfunction resolveRelativeInVfs(\n vfs: Map<string, VfsEntry>,\n containingFile: string,\n importPath: string,\n): string | undefined {\n // Strip leading '/' from containingFile — TS may prepend getCurrentDirectory()\n const normalized = containingFile.startsWith('/') ? containingFile.slice(1) : containingFile;\n const dir = path.posix.dirname(normalized);\n const resolved = path.posix.normalize(`${dir}/${importPath}`);\n\n // Try .d.ts extension\n const withDts = `${resolved}.d.ts`;\n if (vfs.has(withDts)) return withDts;\n\n // Try /index.d.ts\n const withIndexDts = `${resolved}/index.d.ts`;\n if (vfs.has(withIndexDts)) return withIndexDts;\n\n // Try .ts extension\n const withTs = `${resolved}.ts`;\n if (vfs.has(withTs)) return withTs;\n\n // Might already be the exact path\n if (vfs.has(resolved)) return resolved;\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// CompilerHost factory\n// ---------------------------------------------------------------------------\n\nconst COMPILER_OPTIONS: ts.CompilerOptions = {\n target: ts.ScriptTarget.ES2020,\n module: ts.ModuleKind.ESNext,\n // Classic React JSX mode. The synthetic prefix (SYNTHETIC_PREFIX)\n // supplies `import React from 'react'` plus a `declare global` JSX\n // namespace shim: `@types/react` v19 removed the *global* `JSX`\n // namespace (it lives at `React.JSX` now), which classic mode needs\n // for `JSX.IntrinsicElements` and the `key`/`ref` carve-out. Without\n // the shim, `<div>` degrades to `any` and every typed component\n // falsely rejects the intrinsic `key` prop.\n jsx: ts.JsxEmit.React,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n strict: false,\n strictNullChecks: true, // Catch undefined.foo() errors that cause runtime crashes\n noEmit: true,\n skipLibCheck: true,\n noImplicitAny: true,\n types: [],\n esModuleInterop: true,\n};\n\n/**\n * Normalize a path that TS's internal module resolution might generate.\n * Since getCurrentDirectory() returns '/', TS will probe paths like\n * '/node_modules/@types/react/jsx-runtime.d.ts'. We strip the leading\n * '/' to match our VFS keys.\n */\nfunction normalizeVfsPath(f: string): string | null {\n if (f.startsWith('/')) {\n return f.slice(1);\n }\n return null;\n}\n\n/**\n * Core module resolution logic shared between resolveModuleNameLiterals\n * (for user imports) and resolveModuleNames (for TS-internal imports\n * like jsxImportSource).\n */\nfunction resolveModuleName(\n vfs: Map<string, VfsEntry>,\n name: string,\n containingFile: string,\n): ts.ResolvedModuleWithFailedLookupLocations {\n // React core\n if (name === 'react') {\n return resolved('node_modules/@types/react/index.d.ts');\n }\n if (name === 'react/jsx-runtime') {\n return resolved('node_modules/@types/react/jsx-runtime.d.ts');\n }\n if (name === 'react/jsx-dev-runtime') {\n const p = 'node_modules/@types/react/jsx-dev-runtime.d.ts';\n if (vfs.has(p)) return resolved(p);\n return resolved('node_modules/@types/react/jsx-runtime.d.ts');\n }\n\n // @ggui-ai/design sub-paths\n const designPrefix = '@ggui-ai/design/';\n if (name.startsWith(designPrefix)) {\n const subpath = name.slice(designPrefix.length);\n const indexPath = `node_modules/@ggui-ai/design/${subpath}/index.d.ts`;\n if (vfs.has(indexPath)) return resolved(indexPath);\n const directPath = `node_modules/@ggui-ai/design/${subpath}.d.ts`;\n if (vfs.has(directPath)) return resolved(directPath);\n }\n\n // @ggui-ai/design root\n if (name === '@ggui-ai/design') {\n return resolved('node_modules/@ggui-ai/design/index.d.ts');\n }\n\n // @ggui-ai/wire\n if (name === '@ggui-ai/wire') {\n return resolved('node_modules/@ggui-ai/wire/index.d.ts');\n }\n\n // @ggui-ai/gadgets — the STDLIB gadget package. Generated\n // code direct-imports the seven STDLIB hooks (`useGeolocation`, …)\n // as plain named exports from this specifier. The shipped `.d.ts`\n // (loaded into the VFS above) carries their real declarations.\n if (name === '@ggui-ai/gadgets') {\n return resolved('node_modules/@ggui-ai/gadgets/index.d.ts');\n }\n\n // Relative imports — resolve within VFS\n if (name.startsWith('./') || name.startsWith('../')) {\n const resolvedPath = resolveRelativeInVfs(vfs, containingFile, name);\n if (resolvedPath) return resolved(resolvedPath);\n }\n\n // Third-party gadget wrapper packages. The render handler fetches each\n // non-stdlib gadget's `.d.ts` and `typecheck` overlays it at\n // `node_modules/<package>/index.d.ts`. A generated direct import\n // `import { useX } from '<package>'` resolves through this\n // bare-specifier branch against the overlaid `.d.ts` — named\n // option/return types preserved instead of collapsing to `any`.\n // Generic VFS lookup — no per-package allow-list.\n const bareIndex = `node_modules/${name}/index.d.ts`;\n if (vfs.has(bareIndex)) return resolved(bareIndex);\n\n // Unknown module\n return { resolvedModule: undefined };\n}\n\nfunction createVfsHost(\n vfs: Map<string, VfsEntry>,\n componentCode: string,\n): ts.CompilerHost {\n // Create fresh source file for the user component\n const componentFile = ts.createSourceFile(\n 'Component.tsx',\n componentCode,\n ts.ScriptTarget.ES2020,\n true,\n ts.ScriptKind.TSX,\n );\n\n const host: ts.CompilerHost = {\n getSourceFile(fileName: string) {\n if (fileName === 'Component.tsx') return componentFile;\n const entry = vfs.get(fileName);\n if (entry) return entry.sourceFile;\n // Try normalized path (strip leading '/')\n const normalized = normalizeVfsPath(fileName);\n if (normalized) return vfs.get(normalized)?.sourceFile;\n return undefined;\n },\n getDefaultLibFileName() {\n return 'lib.es2020.full.d.ts';\n },\n writeFile() {\n // no-op\n },\n getCurrentDirectory() {\n return '/';\n },\n getCanonicalFileName(f: string) {\n return f;\n },\n useCaseSensitiveFileNames() {\n return true;\n },\n getNewLine() {\n return '\\n';\n },\n fileExists(f: string) {\n if (f === 'Component.tsx' || vfs.has(f)) return true;\n // Normalize bare-specifier lookups that TS's internal resolver\n // turns into relative-looking paths from getCurrentDirectory '/'.\n const normalized = normalizeVfsPath(f);\n if (normalized && vfs.has(normalized)) return true;\n return false;\n },\n readFile(f: string) {\n if (f === 'Component.tsx') return componentCode;\n const direct = vfs.get(f);\n if (direct) return direct.content;\n const normalized = normalizeVfsPath(f);\n if (normalized) return vfs.get(normalized)?.content;\n return undefined;\n },\n resolveModuleNameLiterals(\n moduleLiterals: readonly ts.StringLiteralLike[],\n containingFile: string,\n ): readonly ts.ResolvedModuleWithFailedLookupLocations[] {\n return moduleLiterals.map((literal) =>\n resolveModuleName(vfs, literal.text, containingFile),\n );\n },\n };\n\n return host;\n}\n\nfunction resolved(resolvedFileName: string): ts.ResolvedModuleWithFailedLookupLocations {\n return {\n resolvedModule: {\n resolvedFileName,\n isExternalLibraryImport: true,\n extension: ts.Extension.Dts,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport async function typecheck(\n code: string,\n /**\n * A `package -> .d.ts content` map for third-party gadget wrappers.\n * The render handler parallel-fetches each non-stdlib gadget's `.d.ts`\n * (via `GadgetDescriptor.typesUrl` + SRI) and threads the result\n * here. Each entry is overlaid into the per-call VFS at\n * `node_modules/<package>/index.d.ts`. A generated direct import\n * `import { useX } from '<package>'` resolves through the\n * bare-specifier branch in `resolveModuleName` directly against this\n * overlaid entry — named option/return types preserved, so a\n * wrong-typed hook call surfaces a blocking TS error instead of\n * collapsing to `any`.\n *\n * Stdlib gadgets (`package: '@ggui-ai/gadgets'`) need no entry —\n * `@ggui-ai/gadgets` ships its `.d.ts` into the VFS unconditionally.\n * Omit for standard-library-only callers.\n */\n dtsMap?: Readonly<Record<string, string>>,\n): Promise<TypeCheckResult> {\n const vfs = await loadVfs();\n\n // Overlay each third-party gadget wrapper's `.d.ts` per-call without\n // mutating the cached VFS. The bare-specifier branch in\n // `resolveModuleName` resolves a generated `import { useX } from\n // '<package>'` against the overlaid entry, so the LLM sandbox sees\n // the wrapper's strict hook/component types (named option/return\n // shapes) rather than `any`. A third-party wrapper with no `dtsMap`\n // entry collapses to `any` (TS2307 is non-blocking) — degraded UX,\n // not a generation blocker; the fix is to thread `gadgetTypes`.\n // Stdlib (`@ggui-ai/gadgets`) ships its `.d.ts` unconditionally.\n const effectiveVfs = (() => {\n const dtsEntries = dtsMap !== undefined ? Object.entries(dtsMap) : [];\n if (dtsEntries.length === 0) {\n return vfs;\n }\n const overlay = new Map(vfs);\n for (const [pkg, content] of dtsEntries) {\n parseAndStore(overlay, `node_modules/${pkg}/index.d.ts`, content);\n }\n return overlay;\n })();\n\n // Prepend a synthetic prefix for classic JSX mode:\n // - `import React from 'react'` — the classic-mode JSX factory\n // (`React.createElement`) needs the React namespace in scope.\n // - a `declare global` JSX shim — `@types/react` v19 dropped the\n // GLOBAL `JSX` namespace (it is `React.JSX` now); classic mode\n // resolves intrinsic elements + the `key`/`ref` carve-out through\n // the global `JSX`, so without this `<div>` degrades to `any` and\n // every typed component falsely rejects the intrinsic `key` prop.\n // Mirrors `react/jsx-runtime`'s own JSX namespace, hoisted global.\n // All prefix lines are skipped from diagnostics via `lineOffset`.\n // `@types/react` v19 removed the GLOBAL `JSX` namespace (it lives at\n // `React.JSX` now — un-exported, not reliably reachable through the\n // VFS). Classic JSX mode resolves intrinsic elements + the `key`\n // carve-out through the global `JSX`, so declare a self-contained\n // one. Intrinsic elements are permissive (`[elem]: any`): the\n // type-checker's value is on the design components — which keep\n // their real prop types regardless of this namespace — and on\n // runtime-crash detection, not on deep typing of raw HTML (which the\n // generation prompt discourages anyway).\n const globalJsxShim =\n 'declare global { namespace JSX {' +\n ' type ElementType = string | ((props: any) => any) | (new (props: any) => any);' +\n ' interface Element { type: any; props: any; key: string | number | null; }' +\n ' interface ElementClass { render(): any; }' +\n ' interface ElementAttributesProperty { props: object; }' +\n ' interface ElementChildrenAttribute { children: object; }' +\n ' interface IntrinsicAttributes { key?: string | number | bigint | null; }' +\n ' interface IntrinsicClassAttributes<T> { ref?: any; }' +\n ' interface IntrinsicElements { [elem: string]: any; }' +\n ' } }\\n';\n const SYNTHETIC_PREFIX = \"import React from 'react';\\n\" + globalJsxShim;\n const prefixedCode = SYNTHETIC_PREFIX + code;\n const lineOffset = SYNTHETIC_PREFIX.split('\\n').length - 1;\n\n const host = createVfsHost(effectiveVfs, prefixedCode);\n\n const program = ts.createProgram(['Component.tsx'], COMPILER_OPTIONS, host);\n const diagnostics = ts.getPreEmitDiagnostics(program);\n\n const errors: TypeCheckDiagnostic[] = [];\n const warnings: TypeCheckDiagnostic[] = [];\n\n for (const diag of diagnostics) {\n // Only report diagnostics from the user's component file\n if (diag.file && diag.file.fileName !== 'Component.tsx') continue;\n // Global diagnostics (no file) — skip as they come from config\n if (!diag.file) continue;\n // Skip diagnostics on the synthetic import prefix line\n const diagLine = ts.getLineAndCharacterOfPosition(diag.file, diag.start ?? 0).line;\n if (diagLine < lineOffset) continue;\n\n const rawLine = diag.file\n ? ts.getLineAndCharacterOfPosition(diag.file, diag.start ?? 0).line + 1\n : 0;\n // Subtract the synthetic import line to get the user's original line number\n const line = Math.max(1, rawLine - lineOffset);\n const message = ts.flattenDiagnosticMessageText(diag.messageText, '\\n');\n const code_ = diag.code;\n\n // Extract the offending source line for the fix hint — without it\n // \"Type 'string' is not assignable to type 'number'\" is unactionable\n // because the LLM doesn't know which prop on which primitive. With\n // the line (\"<Icon size=\\\"md\\\" ...>\"), the LLM can target precisely.\n const sourceLines = diag.file.text.split('\\n');\n const sourceLine =\n rawLine >= 1 && rawLine <= sourceLines.length\n ? sourceLines[rawLine - 1]?.trim() ?? ''\n : '';\n\n const entry: TypeCheckDiagnostic = {\n code: code_,\n line,\n message,\n fix: generateFix(code_, message, sourceLine),\n };\n\n if (BLOCKING_CODES.has(code_)) {\n errors.push(entry);\n } else {\n warnings.push(entry);\n }\n }\n\n return { errors, warnings };\n}\n","// packages/ui-gen/src/check/react-linter.ts\n//\n// React linter — runs eslint-plugin-react-hooks via ESLint's Linter API.\n//\n// Exposed on `@ggui-ai/ui-gen/check` so `createUiGenerator` can invoke\n// the same lint gate as the hosted generation path.\n//\n// Dep surface: the linter imports the `Linter` / `Rule` types from\n// `eslint` at module load and lazily imports `@typescript-eslint/parser`,\n// `eslint-plugin-react-hooks`, and `eslint-plugin-react` inside\n// `getLinter()` — those four packages are runtime deps of this package.\n//\n// Catches Rules of Hooks violations that the TS type-checker misses:\n// - Hooks inside conditionals, loops, nested functions\n// - Hooks after early returns\n// - Missing/extra dependencies in useEffect/useMemo/useCallback\n//\n// Also carries the core ESLint `no-unused-vars` rule to\n// catch wire hooks the LLM declared but never consumed — an unused\n// `const submit = useAction('submit')` ships a subscription with no\n// render/callback wiring and will not actually drive the UI. Rule 14\n// (`wire_preservation`) in self-check.ts catches the DELETION case;\n// this lint pass catches the ABANDONMENT case. Together they seal\n// bidirectional contract completeness: contract -> code.\n//\n// Uses the lightweight Linter API (no file system, no config resolution).\n// Runs in parallel with the TS type-checker during self-check.\n\nimport { Linter, type Rule } from 'eslint';\n\nexport interface ReactLintDiagnostic {\n rule: string;\n line: number;\n message: string;\n fix: string;\n severity: 'error' | 'warning';\n}\n\n// Singleton Linter instance — reused across calls.\nlet linterInstance: Linter | null = null;\n\nasync function getLinter(): Promise<Linter> {\n if (!linterInstance) {\n linterInstance = new Linter();\n\n // Register @typescript-eslint/parser so ESLint can parse TS/TSX\n const tsParser = await import('@typescript-eslint/parser');\n linterInstance.defineParser('@typescript-eslint/parser', tsParser as Linter.Parser);\n\n // Register react-hooks plugin rules\n const reactHooksPlugin = await import('eslint-plugin-react-hooks');\n const hooksRules = reactHooksPlugin.default?.rules ?? reactHooksPlugin.rules;\n for (const [name, rule] of Object.entries(hooksRules)) {\n linterInstance.defineRule(`react-hooks/${name}`, rule as Rule.RuleModule);\n }\n\n // Register eslint-plugin-react rules\n const reactPlugin = await import('eslint-plugin-react');\n const reactRules = reactPlugin.default?.rules ?? reactPlugin.rules;\n for (const [name, rule] of Object.entries(reactRules)) {\n linterInstance.defineRule(`react/${name}`, rule as Rule.RuleModule);\n }\n }\n return linterInstance;\n}\n\n/**\n * Lint TSX code for React hooks violations.\n * Returns diagnostics with line numbers and fix suggestions.\n */\nexport async function lintReactHooks(code: string): Promise<ReactLintDiagnostic[]> {\n const linter = await getLinter();\n\n let messages: Linter.LintMessage[];\n try {\n const config: Linter.LegacyConfig = {\n parser: '@typescript-eslint/parser',\n parserOptions: {\n ecmaVersion: 2022,\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n rules: {\n 'react-hooks/rules-of-hooks': 2,\n 'react-hooks/exhaustive-deps': 1,\n // React rules\n 'react/jsx-no-undef': 2, // undefined JSX components\n 'react/jsx-key': 1, // missing key in lists\n 'react/no-direct-mutation-state': 2, // direct state mutation\n // An unused `const submit = useAction('submit')` is a\n // dead contract wire. Narrow the rule to variable bindings we\n // care about: skip function args (LLMs legitimately omit unused\n // params), skip destructured `rest` collectors, respect a `_`-\n // prefix escape hatch for intentionally-ignored declarations,\n // and silence the caught-error slot (async error handling can\n // leave `catch (err)` unused at a boundary).\n 'no-unused-vars': [2, {\n vars: 'all',\n args: 'none',\n ignoreRestSiblings: true,\n varsIgnorePattern: '^_',\n caughtErrors: 'none',\n }],\n },\n settings: {\n react: { version: '19.0' },\n },\n };\n messages = linter.verify(code, config, { filename: 'component.tsx' });\n } catch {\n // Parser not available or code too malformed — skip\n return [];\n }\n\n const diagnostics: ReactLintDiagnostic[] = [];\n\n // Rules surfaced from the Linter run. `no-unused-vars` is the core\n // ESLint rule (no plugin prefix) — admitted alongside react-hooks/\n // and react/ rules so the no-unused-vars diagnostic reaches self_check.\n const ADMITTED_RULES = (id: string): boolean =>\n id.startsWith('react-hooks/') ||\n id.startsWith('react/') ||\n id === 'no-unused-vars';\n\n for (const msg of messages) {\n // Skip parser errors — caught by TS type-checker\n if (!msg.ruleId) continue;\n if (!ADMITTED_RULES(msg.ruleId)) continue;\n\n diagnostics.push({\n rule: msg.ruleId,\n line: msg.line,\n message: msg.message,\n fix: generateReactFix(msg.ruleId, msg.message),\n severity: resolveSeverity(msg, code),\n });\n }\n\n return diagnostics;\n}\n\n/**\n * Resolve the self-check severity of a lint diagnostic.\n *\n * Most rules map straight from ESLint severity (2 → error, 1 → warning).\n * `no-unused-vars` is special-cased: it stays a hard `error` ONLY when\n * the unused binding is a CONTRACT WIRE — `const x = useAction(...)` /\n * `useStream(...)` / `useGguiContext(...)` — because an abandoned wire\n * ships a dead subscription. For every other unused binding (a local\n * helper the LLM declared mid-generation, a `useMemo` result, a state-\n * read gadget binding) it is downgraded to `warning`.\n *\n * Rationale: a half-wired local helper is transient coding state, not a\n * defect — blocking tier-0 self-check on it forces a whole coding-turn\n * round-trip and is the single largest turn-thrash driver on the\n * benchmark (kanban/chat hit the turn cap oscillating on `'handleNext'\n * is assigned a value but never used`). The dead-CONTRACT-wire case it\n * was built to catch is independently enforced at\n * `error` severity by `validateActionSpecConformance` /\n * `validateStreamSpecConformance` in contract-validation.ts, so the\n * downgrade loses no correctness coverage. The diagnostic still surfaces\n * as a `warn` and is fed back to the LLM during eval rounds.\n */\nfunction resolveSeverity(\n msg: Linter.LintMessage,\n code: string,\n): 'error' | 'warning' {\n const base: 'error' | 'warning' = msg.severity === 2 ? 'error' : 'warning';\n if (msg.ruleId !== 'no-unused-vars' || base !== 'error') return base;\n const name = msg.message.match(/'([^']+)'/)?.[1];\n if (name === undefined) return 'warning';\n // Escape regex metacharacters in the identifier (defensive — JS\n // identifiers can't contain them, but the message text is untrusted).\n const safe = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Contract-wire binding. Two declaration shapes:\n // - direct: `const submit = useAction('submit')`\n // - destructured: `const [step, setStep] = useGguiContext<number>('step')`\n // The destructured form covers `useGguiContext` (and a defensive\n // `useStream`), where the unused name is one tuple slot.\n const directRe = new RegExp(\n `\\\\bconst\\\\s+${safe}\\\\s*=\\\\s*use(Action|Stream|GguiContext)\\\\s*[<(]`,\n );\n const destructuredRe = new RegExp(\n `\\\\bconst\\\\s+\\\\[[^\\\\]]*\\\\b${safe}\\\\b[^\\\\]]*\\\\]\\\\s*=\\\\s*use(Action|Stream|GguiContext)\\\\s*[<(]`,\n );\n return directRe.test(code) || destructuredRe.test(code)\n ? 'error'\n : 'warning';\n}\n\nfunction generateReactFix(ruleId: string, message: string): string {\n if (ruleId === 'react-hooks/rules-of-hooks') {\n if (message.includes('called conditionally')) {\n return 'Move this hook to the top level of the component, before any early returns or conditionals. Hooks must run in the same order every render.';\n }\n return 'Hooks can only be called at the top level of a React function component or custom hook. Move it out of any conditional, loop, nested function, or callback.';\n }\n if (ruleId === 'react-hooks/exhaustive-deps') {\n return 'Add the missing dependencies to the dependency array, or remove the array to run on every render.';\n }\n if (ruleId === 'react/jsx-no-undef') {\n const match = message.match(/'(\\w+)'/);\n const name = match?.[1] ?? 'Component';\n return `'${name}' is not defined. Import it from the design system or define it in the file.`;\n }\n if (ruleId === 'react/jsx-key') {\n return 'Add a unique \"key\" prop to each element rendered inside a .map() or iterator.';\n }\n if (ruleId === 'react/no-direct-mutation-state') {\n return 'Do not mutate state directly. Use setState or the setter from useState instead.';\n }\n if (ruleId === 'no-unused-vars') {\n // Extract the identifier name from the ESLint message shape:\n // \"'submit' is assigned a value but never used.\" (varsIgnorePattern also referenced)\n const match = message.match(/'([^']+)'/);\n const name = match?.[1] ?? 'variable';\n // Wire-hook shape — if the binding is an obvious contract wire, route\n // the LLM to the right remediation. Heuristic lives on the message\n // text because we only see the rule output here, not the AST.\n const isLikelyWireBinding = /\\bconst\\s+[A-Za-z_$][\\w$]*\\s*=\\s*use(Action|Stream)\\s*\\(/.test(message);\n if (isLikelyWireBinding || /^(submit|cancel|search|progress|snapshot)$/.test(name)) {\n return `'${name}' is declared but never used. If this binding came from a wire hook (useAction / useStream) or a clientCapabilities hook (useGeolocation / useCamera / etc. from @ggui-ai/gadgets), consume it somewhere in the component — render its value in JSX, bind it to a callback prop, or use it in an effect. A contract-declared hook without consumption is a dead wire.`;\n }\n return `'${name}' is declared but never used. Remove the declaration, or consume it somewhere in the component. Prefix with '_' (e.g. '_${name}') to mark it intentionally unused.`;\n }\n return 'Fix the React violation.';\n}\n","/**\n * Lightweight render smoke test for compiled components.\n *\n * Uses ReactDOMServer.renderToString() to verify the component\n * can render without throwing. Catches runtime errors that tsc misses\n * (undefined.toLowerCase(), missing prop access, etc.)\n *\n * Returns null on success, or an error message string on failure.\n *\n * **Execution model**: the actual `renderToString` runs in a\n * subprocess via `@ggui-ai/sandbox` — LLM-generated TSX never\n * executes in the parent Node process. The subprocess gets:\n *\n * - wall-clock timeout (12s — generous for weird LLM output)\n * - stdout cap (512 KiB — worker's JSON verdict is tiny; cap is\n * defensive)\n * - V8 heap cap (256 MB — bounds runaway allocations)\n * - owned tmpdir as cwd (cleaned up at finish)\n * - env allowlist (PATH/HOME/TMPDIR bootstrap only — no secrets\n * from the parent process.env reach the child)\n *\n * See `@ggui-ai/sandbox/README.md` for the honest boundary: this\n * setup does NOT block network egress, does NOT prevent FS reads\n * outside cwd, and does NOT cap CPU. Those need OS primitives that\n * aren't portable from Node user-space.\n */\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL, fileURLToPath } from 'node:url';\nimport { runSandboxed } from '@ggui-ai/sandbox';\nimport type { PropsSpec, JsonObject, JsonValue } from '@ggui-ai/protocol';\n\n/**\n * Generate sample props from a PropsSpec contract.\n * Uses `example` values from each PropEntry when available,\n * otherwise synthesizes plausible defaults from the JSON Schema.\n */\nexport function generateSampleProps(spec: PropsSpec): JsonObject {\n const props: JsonObject = {};\n\n for (const [name, entry] of Object.entries(spec.properties)) {\n // Prefer explicit example value\n if (entry.example !== undefined) {\n props[name] = entry.example;\n continue;\n }\n\n // Prefer explicit default value\n if (entry.default !== undefined) {\n props[name] = entry.default;\n continue;\n }\n\n // Synthesize from JSON Schema\n props[name] = synthesizeFromSchema(entry.schema);\n }\n\n return props;\n}\n\nfunction synthesizeFromSchema(schema: { type?: string; items?: unknown; properties?: JsonObject; required?: string[] }): JsonValue | undefined {\n switch (schema.type) {\n case 'string': return 'sample';\n case 'number': return 0;\n case 'boolean': return false;\n case 'array': {\n const itemSchema = schema.items as { type?: string } | undefined;\n if (itemSchema) return [synthesizeFromSchema(itemSchema) ?? null];\n return [];\n }\n case 'object': {\n const obj: JsonObject = {};\n if (schema.properties) {\n for (const [k, v] of Object.entries(schema.properties)) {\n obj[k] = synthesizeFromSchema(v as { type?: string });\n }\n }\n return obj;\n }\n default: return undefined;\n }\n}\n\n/**\n * Timeout for a single render smoke test. Generous — some LLM-\n * produced components hit pathological code paths (deep prop-drill\n * recursion, accidental infinite loops on null-guarded maps). 12s is\n * well above the ~100ms real renderToString cost + ~50ms subprocess\n * spawn, while still bounding runaway execution.\n */\nconst RENDER_TIMEOUT_MS = 12_000;\n\n/**\n * stdout byte cap. The worker writes a single JSON verdict\n * (`{ok: true}` or `{ok: false, error: \"...\"}`), which is tiny — a\n * few KiB is plenty for the longest useful error message. Cap\n * defensively at 512 KiB so a pathological worker can't flood.\n */\nconst RENDER_STDOUT_CAP = 512 * 1024;\n\n/**\n * V8 heap cap for the worker. 256 MB bounds runaway allocations\n * (e.g. a component that builds a massive array in render) while\n * leaving headroom for `react-dom/server` + esbuild's own heap.\n */\nconst RENDER_NODE_HEAP_MB = 256;\n\n/**\n * Resolve the worker entry + the spawn command to launch it.\n *\n * - **Built (`dist/`)**: the compiled `render-check-worker.js`\n * lives at `dist/tools/render-check-worker.js`. Some consumers\n * import via subpath entries (e.g. `@ggui-ai/ui-gen/adapters`)\n * that inline this function into a different dist directory\n * (e.g. `dist/adapters/index.js`); the worker lookup must still\n * find the worker file in `dist/tools/`. We search siblings AND\n * `../tools/` to cover both.\n * - **Dev / test (vitest imports `src/`)**: only the `.ts` source\n * exists at `src/tools/render-check-worker.ts`; spawn\n * `node --import tsx <tsPath>`. tsx is already a dev-dep of core\n * for the `dev` / `bench` scripts, so it's a safe assumption in\n * the test environment.\n *\n * Fails loudly at first call when none of the candidates exist —\n * that means a broken build, not a missing test fixture.\n */\nfunction resolveWorkerSpawn(): { command: string; args: string[] } {\n // Sibling-first, then `../tools/`. When this function is inlined\n // into `dist/adapters/index.js`, sibling resolves to a nonexistent\n // `dist/adapters/render-check-worker.js`; the `../tools/` candidate\n // then lands on the real `dist/tools/render-check-worker.js`.\n const jsCandidates = [\n new URL('./render-check-worker.js', import.meta.url),\n new URL('../tools/render-check-worker.js', import.meta.url),\n ];\n const tsCandidates = [\n new URL('./render-check-worker.ts', import.meta.url),\n new URL('../tools/render-check-worker.ts', import.meta.url),\n ];\n for (const jsUrl of jsCandidates) {\n const jsPath = fileURLToPath(jsUrl);\n if (existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] };\n }\n }\n for (const tsUrl of tsCandidates) {\n const tsPath = fileURLToPath(tsUrl);\n if (existsSync(tsPath)) {\n // Pre-resolve tsx to an absolute file: URL so Node can find it\n // regardless of the subprocess's cwd (the sandbox mints a fresh\n // tmpdir for cwd by default; relative tsx lookup would fail).\n const require_ = createRequire(import.meta.url);\n const tsxLoader = pathToFileURL(require_.resolve('tsx')).href;\n return {\n command: process.execPath,\n args: ['--import', tsxLoader, tsPath],\n };\n }\n }\n const tried = [...jsCandidates, ...tsCandidates]\n .map((u) => fileURLToPath(u))\n .join(', ');\n throw new Error(\n `render-check: worker not found at any of: ${tried}. Did \\`pnpm build\\` run?`,\n );\n}\n\nexport async function tryRender(\n compiledCode: string,\n sourceCode: string,\n sampleProps?: JsonObject,\n): Promise<string | null> {\n // `compiledCode` is intentionally ignored — the worker re-compiles\n // as CJS internally. Keeping the parameter preserves the callsite\n // signature so upstream callers (tools.ts, lambda-handler.ts) don't\n // churn.\n void compiledCode;\n\n const payload = JSON.stringify({ sourceCode, sampleProps });\n const spawn = resolveWorkerSpawn();\n\n const result = await runSandboxed({\n command: spawn.command,\n args: spawn.args,\n timeoutMs: RENDER_TIMEOUT_MS,\n maxStdoutBytes: RENDER_STDOUT_CAP,\n nodeHeapMb: RENDER_NODE_HEAP_MB,\n stdin: payload,\n // Forward only what the worker needs. NODE_ENV lets React pick\n // production vs development builds; everything else stays at the\n // sandbox's default allowlist (PATH/HOME/TMPDIR bootstrap).\n env: {\n NODE_ENV: process.env.NODE_ENV ?? 'production',\n },\n });\n\n if (result.outcome === 'timeout') {\n return `Render timeout: component did not finish within ${RENDER_TIMEOUT_MS}ms (likely infinite loop or runaway recursion).`;\n }\n if (result.outcome === 'overflow-stdout' || result.outcome === 'overflow-stderr') {\n return `Render error: worker produced excessive output (${result.outcome}). The component is likely in a pathological state.`;\n }\n if (result.outcome === 'canceled') {\n return 'Render error: smoke test was canceled before completing.';\n }\n if (result.outcome === 'spawn-error') {\n return `Render error: failed to start worker — ${result.errorMessage}`;\n }\n if (result.outcome !== 'exit') {\n return `Render error: unexpected sandbox outcome '${result.outcome}'.`;\n }\n\n // Worker exited cleanly. Parse its verdict.\n if (result.exitCode !== 0) {\n const tail = result.stderr.trim() || result.stdout.trim();\n return `Render error: worker exited ${result.exitCode}${tail ? ` — ${tail}` : ''}`;\n }\n\n const stdout = result.stdout.trim();\n if (stdout.length === 0) {\n return 'Render error: worker exited without producing a verdict.';\n }\n\n type Verdict = { ok: true } | { ok: false; error: string };\n let verdict: Verdict;\n try {\n verdict = JSON.parse(stdout) as Verdict;\n } catch (err) {\n return `Render error: malformed worker verdict — ${\n err instanceof Error ? err.message : String(err)\n }`;\n }\n\n return verdict.ok ? null : verdict.error;\n}\n","// packages/ui-gen/src/adapters/tools.ts\n//\n// SDK-agnostic tool definitions for UI generation.\n// These use the same Zod schemas and handlers as the production MCP server\n// but without Claude Agent SDK dependencies, making them portable across\n// OpenAI, Google, and Anthropic SDKs.\n\nimport { z } from 'zod';\nimport * as esbuild from 'esbuild';\nimport { PRIMITIVES_DOCUMENTATION } from '../validation/index.js';\nimport {\n validateComponentDetailed,\n formatValidationResultForClaude,\n} from '../validation/index.js';\nimport { DEFAULT_DESIGN_SYSTEM_DOCS } from '../design-system-docs.js';\nimport { isAllowedImport, describeAllowedImports } from '../validation/allowed-imports.js';\nimport type { ToolDefinition, ToolResult } from './types';\nimport type { DataContract, JsonObject } from '@ggui-ai/protocol';\nimport { validateAllContracts } from '../check/index.js';\nimport { typecheck } from '../check/index.js';\nimport { lintReactHooks } from '../check/index.js';\nimport ts from 'typescript';\nimport { tryRender, generateSampleProps } from '../tools/render-check.js';\n\n/**\n * Context for creating generator tools.\n * Allows passing app-specific component docs.\n */\nexport interface GeneratorToolsContext {\n /** App-specific design context (DESIGN.md content) */\n designContext?: string;\n /** App-specific reusable component documentation */\n componentContext?: string;\n /** Data contract for validation (props, stream, actions) */\n contract?: DataContract;\n /** Sample props for render smoke test (realistic data matching the contract) */\n sampleProps?: JsonObject;\n}\n\n/**\n * Create the SDK-agnostic tool definitions for UI generation.\n *\n * 6 tools matching the MCP server:\n * 1. get_primitives — available UI components\n * 2. get_design_system — CSS variable tokens\n * 3. get_app_components — app-specific reusable components\n * 4. validate_component — pre-compilation check\n * 5. self_check — typecheck + lint + render smoke test\n * 6. compile_component — TSX→JS via esbuild\n *\n * Each tool uses the exact same handlers as the production MCP server,\n * but wrapped in a provider-neutral format.\n */\nexport function createGeneratorTools(context: GeneratorToolsContext = {}): ToolDefinition[] {\n const tools: ToolDefinition[] = [\n // --- get_primitives ---\n {\n name: 'get_primitives',\n description:\n 'Get the list of available ggui UI primitives (Container, Card, Stack, Button, Input, etc.) that can be used in components. Call this first to understand what components are available.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{ type: 'text', text: PRIMITIVES_DOCUMENTATION }],\n }),\n },\n\n // --- get_design_system ---\n {\n name: 'get_design_system',\n description:\n 'Get the design system tokens and CSS variables for this app. Use these CSS variables (var(--ggui-*)) for colors, spacing, typography, etc.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{\n type: 'text',\n text: context.designContext\n ? `# App Theme Configuration\\n\\n${context.designContext}\\n\\n**IMPORTANT:** Always use CSS variables (var(--ggui-*)) for colors, spacing, etc.`\n : DEFAULT_DESIGN_SYSTEM_DOCS,\n }],\n }),\n },\n\n // --- get_app_components ---\n {\n name: 'get_app_components',\n description:\n 'Get predefined reusable components specific to this app. These can be imported and used in your generated component.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{\n type: 'text',\n text: context.componentContext || 'No predefined components available for this app.',\n }],\n }),\n },\n\n // --- validate_component ---\n {\n name: 'validate_component',\n description:\n 'Validate component code before compilation. Checks for security issues, syntax errors, and best practices. Returns detailed feedback.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to validate'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const result = validateComponentDetailed(args.code as string);\n return {\n content: [\n {\n type: 'text',\n text: formatValidationResultForClaude(result),\n },\n ],\n isError: !result.valid,\n };\n },\n },\n\n // --- self_check ---\n {\n name: 'self_check',\n description:\n 'Run deterministic quality checks on your code BEFORE compiling. Catches common issues instantly (zero cost). Returns pass/fail per check with line numbers and fix instructions. Call this after writing code, fix any failures, then compile.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to check'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const code = args.code as string;\n const { issues, typeWarnings } = await runSelfChecks(code, context.contract);\n\n // Contract validation — check props, stream, actions conformance\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n for (const ci of contractIssues) {\n issues.push({\n check: `contract:${ci.field}`,\n line: 0,\n message: `[${ci.severity}] ${ci.message}`,\n fix: ci.fix,\n });\n }\n }\n\n if (issues.length === 0) {\n const warningText = typeWarnings.length > 0\n ? `\\n\\nType warnings (non-blocking):\\n${typeWarnings.map(w => `[${w.check}] ${w.line ? `Line ${w.line}: ` : ''}${w.message}`).join('\\n')}`\n : '';\n return {\n content: [{ type: 'text', text: `All checks passed. Ready to compile.${warningText}` }],\n };\n }\n\n const report = issues.map((i) => `[${i.check}] ${i.line ? `Line ${i.line}: ` : ''}${i.message}\\n Fix: ${i.fix}`).join('\\n\\n');\n return {\n content: [{ type: 'text', text: `${issues.length} issue(s) found:\\n\\n${report}` }],\n isError: true,\n };\n },\n },\n\n // --- compile_component ---\n {\n name: 'compile_component',\n description:\n 'Compile a TypeScript/TSX component to JavaScript using esbuild. Returns the compiled code ready for browser execution. On failure, returns detailed error context with line numbers and fix suggestions.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to compile'),\n filename: z\n .string()\n .default('Component.tsx')\n .describe('Filename for error messages'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const code = args.code as string;\n const filename = (args.filename as string) || 'Component.tsx';\n\n // Run self-checks first (catches hex colors, raw pixels, forbidden imports, etc.)\n const { issues: selfCheckIssues } = await runSelfChecks(code, context.contract);\n\n // Contract validation\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n for (const ci of contractIssues) {\n selfCheckIssues.push({\n check: `contract:${ci.field}`,\n line: 0,\n message: `[${ci.severity}] ${ci.message}`,\n fix: ci.fix,\n });\n }\n }\n\n if (selfCheckIssues.length > 0) {\n const report = selfCheckIssues.map((i) => `[${i.check}] ${i.line ? `Line ${i.line}: ` : ''}${i.message}\\n Fix: ${i.fix}`).join('\\n\\n');\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'self_check',\n error: `${selfCheckIssues.length} issue(s) found — fix these before recompiling:\\n\\n${report}`,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n // Run validation first\n const validation = validateComponentDetailed(code);\n if (!validation.valid) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n phase: 'validation',\n error: formatValidationResultForClaude(validation),\n },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n\n try {\n const result = await esbuild.transform(code, {\n loader: 'tsx',\n target: 'es2020',\n format: 'esm',\n jsx: 'automatic',\n jsxImportSource: 'react',\n minify: true,\n sourcefile: filename,\n });\n\n const warnings = [\n ...result.warnings.map((w) => w.text),\n ...validation.warnings.map(\n (w: { type: string; message: string; suggestion: string }) =>\n `[${w.type}] ${w.message}: ${w.suggestion}`\n ),\n ];\n\n // Post-compilation: validate all contract (hard gate for errors)\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n const errors = contractIssues.filter((i) => i.severity === 'error');\n const contractWarnings = contractIssues.filter((i) => i.severity === 'warning');\n\n if (errors.length > 0) {\n const report = errors\n .map((i) => `- [${i.field}] ${i.message}\\n Fix: ${i.fix}`)\n .join('\\n');\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'contract_validation',\n error: `Compilation succeeded but data contract validation failed:\\n\\n${report}\\n\\nFix the Props interface to match the data contract, then recompile.`,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n warnings.push(...contractWarnings.map((i) => `[contract:${i.field}] ${i.message}`));\n }\n\n // Render smoke test — catches runtime errors tsc misses\n // Prefer explicit sampleProps (realistic data), fall back to contract-derived\n const sampleProps = context.sampleProps\n ?? (context.contract?.propsSpec ? generateSampleProps(context.contract.propsSpec) : undefined);\n const renderError = await tryRender(result.code, code, sampleProps);\n if (renderError) {\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'render_smoke_test',\n compiledCode: result.code,\n error: `${renderError}\\n\\nThe component compiled but crashes at runtime. Fix the null/undefined access and recompile.`,\n warnings,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n compiledCode: result.code,\n warnings,\n },\n null,\n 2\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: false, phase: 'compilation', error: formatEsbuildError(error, code) },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n },\n },\n ];\n\n return tools;\n}\n\n/**\n * Format an esbuild error into a readable error message with code context.\n */\nfunction formatEsbuildError(error: unknown, sourceCode: string): string {\n const parts: string[] = [];\n\n if (\n error &&\n typeof error === 'object' &&\n 'errors' in error &&\n Array.isArray((error as { errors: unknown[] }).errors)\n ) {\n const esbuildError = error as esbuild.TransformFailure;\n for (const err of esbuildError.errors) {\n const line = err.location?.line;\n const col = err.location?.column;\n parts.push(`**Error:** ${err.text}`);\n if (line) {\n parts.push(`**Location:** Line ${line}, Column ${col ?? 0}`);\n const lines = sourceCode.split('\\n');\n const start = Math.max(0, line - 3);\n const end = Math.min(lines.length, line + 2);\n const context = lines\n .slice(start, end)\n .map((l, i) => {\n const ln = start + i + 1;\n return `${ln === line ? '>>> ' : ' '}${ln} | ${l}`;\n })\n .join('\\n');\n parts.push(`**Code:**\\n\\`\\`\\`\\n${context}\\n\\`\\`\\``);\n }\n }\n } else {\n parts.push(`**Error:** ${error instanceof Error ? error.message : 'Compilation failed'}`);\n }\n\n parts.push('\\n**How to fix:** Review the error above, fix the code, then call compile_component again.');\n return parts.join('\\n');\n}\n\n// =============================================================================\n// Self-Check: Deterministic Quality Checks\n// =============================================================================\n\nexport interface SelfCheckIssue {\n check: string;\n line: number;\n message: string;\n fix: string;\n}\n\n// =============================================================================\n// AST-Based React Rules Checker\n// =============================================================================\n\n// Form components that require a label or aria-label prop for accessibility.\nconst LABELED_COMPONENTS = new Set(['Input', 'TextArea', 'Select']);\n\n/**\n * AST-based JSX prop checker.\n * Parses TSX with TypeScript compiler to verify required props on form elements.\n * React hooks rules are handled by eslint-plugin-react-hooks (see react-linter.ts).\n */\nfunction checkReactRules(code: string): SelfCheckIssue[] {\n const sf = ts.createSourceFile('component.tsx', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n const issues: SelfCheckIssue[] = [];\n\n function visit(node: ts.Node): void {\n if (ts.isJsxSelfClosingElement(node) || ts.isJsxOpeningElement(node)) {\n const tagName = node.tagName.getText(sf);\n if (LABELED_COMPONENTS.has(tagName)) {\n const propNames = new Set<string>();\n let hasSpread = false;\n for (const attr of node.attributes.properties) {\n if (ts.isJsxAttribute(attr)) {\n propNames.add(attr.name.getText(sf));\n } else if (ts.isJsxSpreadAttribute(attr)) {\n hasSpread = true;\n }\n }\n if (!hasSpread && !propNames.has('label') && !propNames.has('aria-label')) {\n const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n issues.push({\n check: 'accessibility',\n line,\n message: `${tagName} missing label prop`,\n fix: `Add label=\"...\" prop directly on the ${tagName} component. The label prop is built into the primitive.`,\n });\n }\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sf);\n return issues;\n}\n\n/**\n * Run deterministic quality checks on component source code.\n * Returns actionable issues with line numbers and fix instructions.\n *\n * `contract` (optional) feeds the import allowlist: generated\n * code direct-imports gadget exports, so every gadget package the\n * contract declares is a permitted import source.\n */\nexport async function runSelfChecks(\n code: string,\n contract?: DataContract,\n): Promise<{ issues: SelfCheckIssue[]; typeWarnings: SelfCheckIssue[] }> {\n const issues: SelfCheckIssue[] = [];\n const lines = code.split('\\n');\n // Gadget packages the contract declares are import-allowlisted.\n // `clientCapabilities.gadgets` is package-keyed, so the map's\n // own keys ARE the allowlisted import sources.\n const allowedGadgetPackages = new Set<string>(\n Object.keys(contract?.clientCapabilities?.gadgets ?? {}),\n );\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Check: hardcoded hex colors\n const hexMatch = line.match(/#[0-9a-fA-F]{3,8}\\b/);\n if (hexMatch && !line.includes('var(--ggui-') && !line.includes('// fallback')) {\n issues.push({\n check: 'hex-color',\n line: lineNum,\n message: `Hardcoded color \"${hexMatch[0]}\" — must use design tokens`,\n fix: `Replace with var(--ggui-color-*, ${hexMatch[0]})`,\n });\n }\n\n // Check: rgba()/hsl() hardcoded color functions\n const colorFnMatch = line.match(/\\b(rgba?|hsla?)\\s*\\(/);\n if (colorFnMatch && !line.includes('var(--ggui-') && !line.includes('// fallback') && !line.includes('$value')) {\n issues.push({\n check: 'hardcoded-color-fn',\n line: lineNum,\n message: `Hardcoded ${colorFnMatch[1]}() — use design tokens instead`,\n fix: `Replace with semantic tokens: var(--ggui-color-surface), var(--ggui-color-onSurface), var(--ggui-color-outline), etc.`,\n });\n }\n\n // Check: neutral-50/900 used for background/text — suggest semantic tokens\n if (/--ggui-color-neutral-50[^0-9]/.test(line) && /background/i.test(line)) {\n issues.push({\n check: 'prefer-semantic',\n line: lineNum,\n message: `neutral-50 for background — prefer semantic token for dark-theme compatibility`,\n fix: `Replace with var(--ggui-color-surface) or var(--ggui-color-surfaceVariant)`,\n });\n }\n if (/--ggui-color-neutral-900[^0-9]/.test(line) && /color/i.test(line) && !/background/i.test(line)) {\n issues.push({\n check: 'prefer-semantic',\n line: lineNum,\n message: `neutral-900 for text color — prefer semantic token for dark-theme compatibility`,\n fix: `Replace with var(--ggui-color-onSurface) or var(--ggui-color-onSurfaceVariant)`,\n });\n }\n\n // Check: raw pixel values in padding/margin/gap (not in var() or calc())\n const pxMatch = line.match(/(?:padding|margin|gap|borderRadius)\\s*:\\s*['\"]?\\d+px/);\n if (pxMatch && !line.includes('var(--ggui-')) {\n issues.push({\n check: 'raw-pixels',\n line: lineNum,\n message: `Raw pixel value in spacing — must use design tokens`,\n fix: `Replace with var(--ggui-spacing-*, fallback)`,\n });\n }\n\n // Check: forbidden APIs\n if (/\\beval\\s*\\(/.test(line)) {\n issues.push({ check: 'security', line: lineNum, message: 'eval() is forbidden', fix: 'Remove eval() call entirely' });\n }\n if (/\\bfetch\\s*\\(/.test(line)) {\n issues.push({ check: 'security', line: lineNum, message: 'fetch() is forbidden — use props for data', fix: 'Remove fetch() and pass data via props' });\n }\n\n // Check: forbidden imports\n const importMatch = line.match(/import\\s+.*from\\s+['\"]([^'\"]+)['\"]/);\n if (importMatch) {\n const pkg = importMatch[1];\n // Import allowlist — single source of truth in\n // `validation/allowed-imports.ts`. Generated code\n // direct-imports gadget exports, so every gadget package the\n // contract declares is allowlisted alongside STDLIB `@ggui-ai/gadgets`.\n if (!isAllowedImport(pkg, allowedGadgetPackages)) {\n issues.push({\n check: 'import',\n line: lineNum,\n message: `Import from \"${pkg}\" is not allowed`,\n fix: `Only import from: ${describeAllowedImports()}`,\n });\n }\n }\n\n // NOTE: Input/TextArea/Select label checks moved to AST-based checkJsxProps() below\n }\n\n // ── AST-based JSX prop checks ──────────────────────────\n // Uses TypeScript compiler to parse JSX — handles multi-line, spread props, etc.\n try {\n const jsxIssues = checkReactRules(code);\n issues.push(...jsxIssues);\n } catch {\n // Parsing may fail on malformed code — fall through to other checks\n }\n\n // Check: no Props interface\n if (!code.includes('interface Props') && !code.includes('type Props')) {\n issues.push({\n check: 'props-interface',\n line: 1,\n message: 'No Props interface found — data is likely hardcoded',\n fix: 'Add interface Props { ... } with typed fields and default values in the function signature',\n });\n }\n\n // Check: no default export\n if (!code.includes('export default function')) {\n issues.push({\n check: 'export',\n line: 1,\n message: 'Missing default export function',\n fix: 'Add export default function GeneratedComponent(props: Props) { ... }',\n });\n }\n\n const typeWarnings: SelfCheckIssue[] = [];\n\n // Run TS type-checker + React hooks linter in parallel\n const [typeResult, reactResult] = await Promise.all([\n typecheck(code).catch((err) => {\n console.warn('[runSelfChecks] TypeChecker failed:', err instanceof Error ? err.message : String(err));\n return null;\n }),\n lintReactHooks(code).catch((err) => {\n console.warn('[runSelfChecks] React linter failed:', err instanceof Error ? err.message : String(err));\n return [] as import('../check/index.js').ReactLintDiagnostic[];\n }),\n ]);\n\n // TS type errors\n if (typeResult) {\n for (const error of typeResult.errors) {\n issues.push({\n check: `ts${error.code}`,\n line: error.line,\n message: error.message,\n fix: error.fix,\n });\n }\n for (const warning of typeResult.warnings) {\n typeWarnings.push({\n check: `ts${warning.code}`,\n line: warning.line,\n message: warning.message,\n fix: warning.fix,\n });\n }\n }\n\n // React hooks violations. Errors (rules-of-hooks, jsx-no-undef, direct-\n // mutation) always block. exhaustive-deps warnings are usually advisory —\n // except when the effect body mutates state (setState / setX / dispatch),\n // in which case a missing dep is a near-certain infinite-render loop once\n // the component renders at runtime. The happy-dom probe catches this only\n // AFTER burning CPU; we'd rather fail preflight.\n //\n // Narrow promotion heuristic: file has a setter-like call AND diagnostic\n // message indicates a missing-dep / unstable-ref class. Inline-object\n // warnings on effects that DON'T mutate state stay advisory to avoid\n // over-constraining.\n const hasStateSetter = /\\b(set[A-Z]\\w*|dispatch)\\s*\\(/.test(code);\n const isSetterLoopRisk = (diag: { rule: string; message: string }): boolean => {\n if (diag.rule !== 'react-hooks/exhaustive-deps') return false;\n if (!hasStateSetter) return false;\n // eslint-plugin-react-hooks message shapes for the loop-risk class:\n // \"React Hook useEffect has a missing dependency: 'x'. Either include it...\"\n // \"The 'x' object / 'x' array makes the dependencies of useEffect Hook\n // change on every render.\"\n return /missing dependenc|changes on every render|object makes the dependencies|array makes the dependencies/i.test(\n diag.message,\n );\n };\n\n for (const diag of reactResult) {\n const blocking = diag.severity === 'error' || isSetterLoopRisk(diag);\n if (blocking) {\n issues.push({\n check: diag.rule,\n line: diag.line,\n message: isSetterLoopRisk(diag)\n ? `${diag.message} (promoted to error: effect mutates state — missing/unstable deps cause infinite render loops)`\n : diag.message,\n fix: diag.fix,\n });\n } else {\n typeWarnings.push({\n check: diag.rule,\n line: diag.line,\n message: diag.message,\n fix: diag.fix,\n });\n }\n }\n\n // Merge overlapping issues: when multiple checkers flag the same line,\n // combine into one issue with the clearest actionable message.\n // e.g. AST says \"Input missing label prop\" + TS says \"ts2786 type mismatch\"\n // → single issue: \"Input missing label prop [also: ts2786]\"\n const lineMap = new Map<number, SelfCheckIssue[]>();\n for (const i of issues) {\n const list = lineMap.get(i.line) ?? [];\n list.push(i);\n lineMap.set(i.line, list);\n }\n\n const deduped: SelfCheckIssue[] = [];\n for (const [, group] of lineMap) {\n if (group.length === 1) {\n deduped.push(group[0]);\n continue;\n }\n // Prefer the non-TS issue (AST/ESLint) as primary — it's more actionable\n const primary = group.find(i => !i.check.startsWith('ts')) ?? group[0];\n const others = group.filter(i => i !== primary);\n if (others.length > 0) {\n const alsoTags = others.map(o => o.check).join(', ');\n deduped.push({\n ...primary,\n message: `${primary.message} [also flagged by: ${alsoTags}]`,\n });\n } else {\n deduped.push(primary);\n }\n }\n\n return { issues: deduped, typeWarnings };\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/base.ts","../../src/adapters/tool-bridge.ts","../../src/adapters/extract-code.ts","../../src/adapters/claude/client.ts","../../src/adapters/claude/raw.ts","../../src/adapters/claude/message-parser.ts","../../src/adapters/claude/tool-bridge.ts","../../src/adapters/claude/sdk.ts","../../src/adapters/openai/raw.ts","../../src/adapters/openai/sdk.ts","../../src/adapters/google/raw.ts","../../src/adapters/google/sdk.ts","../../src/adapters/openrouter/types.ts","../../src/adapters/openrouter/client.ts","../../src/adapters/openrouter/raw.ts","../../src/adapters/types.ts","../../src/adapters/index.ts","../../src/adapters/registry.ts","../../src/validation/primitives.ts","../../src/validation/allowed-imports.ts","../../src/validation/component-detailed.ts","../../src/design-system-docs.ts","../../src/boilerplate/json-schema-ts.ts","../../src/check/contract-validation.ts","../../src/check/type-checker.ts","../../src/check/react-linter.ts","../../src/tools/render-check.ts","../../src/adapters/tools.ts"],"names":["path","init_tool_bridge","raw_exports","init_raw","sdk_exports","init_sdk","result","init_client","ClaudeRawAdapter","ClaudeSdkAdapter","OpenAiRawAdapter","OpenAiSdkAdapter","GoogleRawAdapter","GoogleSdkAdapter","OpenRouterRawAdapter","SHARED_DANGEROUS_PATTERNS","ts","resolved","createRequire","z","esbuild3"],"mappings":"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","file":"index.js","sourcesContent":["// packages/ui-gen/src/adapters/base.ts\n//\n// Abstract base class for all generator adapters.\n\nimport type { McpServerConfig, AgentDefinition } from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from './types';\n\n/**\n * Core configuration shared by all adapters.\n */\nexport interface AdapterConfig {\n /** API key for the provider (BYOK) */\n apiKey?: string;\n /** Use Bedrock instead of direct API (Claude only) */\n useBedrock?: boolean;\n /**\n * Thinking level for models with extended thinking (Gemini 3.x Flash\n * via the Interactions API). Mirrors the API's `thinking_level` enum —\n * `'minimal'` is the floor (the API has NO true off), then `'low'` /\n * `'medium'` / `'high'`. Omitted → provider default, and Gemini 3.5\n * Flash defaults thinking ON with no cap — the dominant latency cost\n * in contract-bounded UI generation. Only the Google adapter consumes\n * this today.\n */\n thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';\n}\n\n/**\n * Extended configuration for Claude Agent SDK adapter.\n * Separated from AdapterConfig to avoid polluting the base interface\n * with provider-specific concerns.\n */\nexport interface ClaudeSdkConfig extends AdapterConfig {\n /** Working directory for SDK subprocess */\n cwd?: string;\n /** Environment variables for SDK subprocess */\n env?: Record<string, string>;\n /** MCP server configs for Claude Agent SDK (keyed by name) */\n mcpServers?: Record<string, McpServerConfig>;\n /** Allowed tool names for Claude Agent SDK */\n allowedTools?: string[];\n /** Subagent definitions for Claude Agent SDK */\n agents?: Record<string, AgentDefinition>;\n /** Custom CLI path for Docker deployments */\n cliPath?: string;\n /** stderr callback for debug logging */\n stderr?: (data: string) => void;\n /** Progress callback */\n onProgress?: (event: { type: string; [key: string]: unknown }) => void;\n}\n\n/**\n * Union config type — adapters accept their specific config\n * but the registry uses this union so callers can pass any config.\n */\nexport type AnyAdapterConfig = AdapterConfig | ClaudeSdkConfig;\n\n/**\n * Parameters for a single generation run.\n */\nexport interface GenerateParams {\n /** System prompt (HOW to build — shared across all SDKs) */\n systemPrompt: string;\n /** User prompt (WHAT to build — the specific request) */\n userPrompt: string;\n /** Model identifier (provider-native format, e.g., 'claude-sonnet-4-6') */\n model: string;\n /** SDK-agnostic tool definitions */\n tools: ToolDefinition[];\n /** Maximum agentic loop turns */\n maxTurns: number;\n /** Model-specific options (e.g., speed_priority for Claude fast mode) */\n modelOptions?: JsonObject;\n}\n\n/**\n * Abstract base class for generator adapters.\n *\n * Each adapter wraps a specific provider SDK (Claude, OpenAI, Google)\n * in either raw API mode or agent SDK mode, and implements the tool-use\n * loop using the SDK's native API. All adapters produce the same\n * output format (AdapterResult).\n */\nexport abstract class GeneratorAdapter {\n abstract readonly provider: ProviderName;\n abstract readonly mode: AdapterMode;\n abstract readonly displayName: string;\n\n constructor(protected readonly config: AnyAdapterConfig) {}\n\n /**\n * Run UI generation with the given tools, prompt, and model.\n */\n abstract generate(params: GenerateParams): Promise<AdapterResult>;\n\n /**\n * Check if this adapter can run (SDK installed, credentials available).\n */\n abstract isAvailable(): boolean;\n\n /**\n * Map a LiteLLM-format model ID to this SDK's native format.\n * Default: strips the provider prefix (e.g., 'anthropic/claude-sonnet-4-6' -> 'claude-sonnet-4-6').\n * Override only if the prefix convention differs.\n */\n resolveModelId(litellmModelId: string): string {\n return stripModelPrefix(litellmModelId);\n }\n}\n\n/**\n * Strip provider prefix from LiteLLM-format model IDs.\n * 'anthropic/claude-sonnet-4-6' -> 'claude-sonnet-4-6'\n * 'openai/gpt-5.3-codex' -> 'gpt-5.3-codex'\n * 'gemini/gemini-3-flash-preview' -> 'gemini-3-flash-preview'\n */\nfunction stripModelPrefix(modelId: string): string {\n const slashIndex = modelId.indexOf('/');\n return slashIndex >= 0 ? modelId.slice(slashIndex + 1) : modelId;\n}\n\n/**\n * Check if credentials are available from config or environment variables.\n */\nexport function hasCredentials(\n config: AdapterConfig,\n ...envVarNames: string[]\n): boolean {\n if (config.apiKey) return true;\n if (config.useBedrock) return true;\n return envVarNames.some((name) => !!process.env[name]);\n}\n","// packages/ui-gen/src/adapters/tool-bridge.ts\n//\n// Bridges between SDK tool wire formats and ggui's JSON types:\n// Zod → JSON Schema for tool declarations, and validated narrowing of\n// decoded tool-call arguments to `JsonObject`.\n\nimport { z } from 'zod';\nimport type { JsonObject, JsonValue } from '@ggui-ai/protocol';\n\n/**\n * Convert a Zod object schema to JSON Schema.\n * Uses Zod v4's built-in toJSONSchema() function.\n */\nexport function zodToJsonSchema(schema: z.ZodType): JsonObject {\n return z.toJSONSchema(schema) as JsonObject;\n}\n\n/**\n * Validate that a decoded tool-call `arguments` object is plain JSON data\n * and narrow it to {@link JsonObject}. Provider SDKs type tool-call\n * arguments as `{ [key: string]: unknown }`; values decoded from a JSON\n * wire payload are JSON by construction, so a failure here means the SDK\n * handed us something that never came from JSON — a bug worth surfacing,\n * not erasing with a cast.\n */\nexport function toolArgsToJsonObject(args: { [key: string]: unknown }): JsonObject {\n const out: JsonObject = {};\n for (const [key, value] of Object.entries(args)) {\n // `JsonObject` keys admit `undefined` (TS optional properties);\n // JSON.stringify omits them, so pass-through is JSON-safe.\n out[key] = value === undefined ? undefined : toJsonValue(value, key);\n }\n return out;\n}\n\nfunction toJsonValue(value: unknown, path: string): JsonValue {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item, i) => toJsonValue(item, `${path}[${i}]`));\n }\n if (typeof value === 'object') {\n const out: JsonObject = {};\n for (const [key, entry] of Object.entries(value)) {\n out[key] = entry === undefined ? undefined : toJsonValue(entry, `${path}.${key}`);\n }\n return out;\n }\n throw new Error(\n `Tool-call arguments contain a non-JSON value at '${path}' (${typeof value})`,\n );\n}\n","// packages/ui-gen/src/adapters/extract-code.ts\n//\n// Shared helpers for extracting artifacts from tool call results\n// and LLM text output. Used by all adapters to avoid duplication.\n\nimport * as esbuild from 'esbuild';\nimport type { ToolDefinition, ToolResult } from './types';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/**\n * Mutable state bag passed through the agentic loop.\n * Each adapter creates one of these and passes it to the\n * extraction helpers on every tool call and text output.\n */\nexport interface CodeCapture {\n compiledCode: string;\n sourceCode: string | undefined;\n stream: JsonObject | undefined;\n generatorMeta: { category: string; description: string } | undefined;\n}\n\nexport function createCapture(): CodeCapture {\n return { compiledCode: '', sourceCode: undefined, stream: undefined, generatorMeta: undefined };\n}\n\n/**\n * Before calling a tool handler: capture source code if this is\n * a compile_component call.\n */\nexport function captureSourceCode(\n capture: CodeCapture,\n toolName: string,\n args: JsonObject,\n): void {\n if (toolName === 'compile_component' && typeof args.code === 'string') {\n capture.sourceCode = args.code;\n }\n}\n\n/**\n * After a tool handler returns: extract compiled code if this was\n * a successful compile_component call.\n */\nexport function captureCompiledCode(\n capture: CodeCapture,\n toolName: string,\n result: ToolResult,\n): void {\n if (toolName !== 'compile_component' || result.isError) return;\n\n try {\n const parsed = JSON.parse(result.content[0].text);\n if (parsed.success && parsed.compiledCode) {\n capture.compiledCode = parsed.compiledCode;\n }\n } catch {\n // Not parseable — ignore\n }\n}\n\n/**\n * Scan text output for __GGUI_STREAM_SPEC__ and __GGUI_META__ markers.\n * Called on each text block in assistant messages (raw adapters)\n * or on the full message stream (SDK adapters via message-parser).\n */\nexport function captureMarkers(capture: CodeCapture, text: string): void {\n if (!capture.stream && text.includes('__GGUI_STREAM_SPEC__')) {\n const match = text.match(/__GGUI_STREAM_SPEC__\\s*([\\s\\S]*?)\\s*__GGUI_STREAM_SPEC_END__/);\n if (match) {\n try {\n capture.stream = JSON.parse(\n match[1].replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\'),\n );\n } catch { /* ignore */ }\n }\n }\n\n if (!capture.generatorMeta && text.includes('__GGUI_META__')) {\n const match = text.match(/__GGUI_META__\\s*([\\s\\S]*?)\\s*__GGUI_META_END__/);\n if (match) {\n try {\n const stripped = match[1].replace(/```(?:json)?\\s*/g, '').trim();\n const raw = stripped.replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\');\n const parsed = JSON.parse(raw) as { category?: string; description?: string };\n if (parsed.category) {\n capture.generatorMeta = { category: parsed.category, description: parsed.description ?? '' };\n }\n } catch { /* ignore */ }\n }\n }\n}\n\n/**\n * Fallback: try to extract code from a text output (used by OpenAI SDK\n * adapter when the model writes code as text instead of calling tools).\n */\nexport async function extractCodeFromText(\n finalOutput: string,\n tools: ToolDefinition[],\n capture: CodeCapture,\n): Promise<void> {\n if (finalOutput.length <= 100) return;\n\n const codeMatch =\n finalOutput.match(/```(?:tsx?|jsx?|typescript|javascript)?\\s*\\n([\\s\\S]*?)```/) ??\n finalOutput.match(/```\\s*\\n([\\s\\S]*?)```/);\n let code = codeMatch ? codeMatch[1].trim() : '';\n\n if (!code && (finalOutput.includes('export default') || finalOutput.includes('export function'))) {\n code = finalOutput;\n }\n\n if (!code || !(code.includes('export default') || code.includes('export function'))) {\n return;\n }\n\n capture.sourceCode = code;\n const compileTool = tools.find((t) => t.name === 'compile_component');\n if (!compileTool) return;\n\n const compileResult = await compileTool.handler({ code, filename: 'Component.tsx' });\n if (compileResult.isError) {\n console.warn('[extractCodeFromText] compile_component failed:', compileResult.content[0]?.text?.slice(0, 300));\n }\n captureCompiledCode(capture, 'compile_component', compileResult);\n}\n\n/**\n * Last-resort compilation: bypass self-checks and compile directly with esbuild.\n *\n * Used when compile_component kept rejecting code due to self-check violations\n * (hex colors, raw pixels, forbidden imports, etc.) but the model DID produce\n * source code. Getting imperfect compiled code is better than getting nothing.\n *\n * Also tries text output as a source if sourceCode is empty.\n */\nexport async function compileLastResort(\n capture: CodeCapture,\n allTextOutput?: string,\n): Promise<void> {\n if (capture.compiledCode) return; // Already have compiled code\n\n // Try capture.sourceCode first (from compile_component calls that failed self-checks)\n let code = capture.sourceCode;\n\n // Fallback: extract from text output\n if (!code && allTextOutput && allTextOutput.length > 100) {\n const codeMatch =\n allTextOutput.match(/```(?:tsx?|jsx?|typescript|javascript)?\\s*\\n([\\s\\S]*?)```/) ??\n allTextOutput.match(/```\\s*\\n([\\s\\S]*?)```/);\n code = codeMatch ? codeMatch[1].trim() : undefined;\n\n if (!code && (allTextOutput.includes('export default') || allTextOutput.includes('export function'))) {\n code = allTextOutput;\n }\n }\n\n if (!code || !(code.includes('export default') || code.includes('export function'))) {\n return;\n }\n\n try {\n const result = await esbuild.transform(code, {\n loader: 'tsx',\n target: 'es2020',\n format: 'esm',\n jsx: 'automatic',\n jsxImportSource: 'react',\n minify: true,\n sourcefile: 'Component.tsx',\n });\n\n capture.compiledCode = result.code;\n capture.sourceCode = code;\n console.warn('[compileLastResort] Compiled code bypassing self-checks — may have quality issues');\n } catch (err) {\n console.warn('[compileLastResort] esbuild failed:', err instanceof Error ? err.message : String(err));\n }\n}\n","// packages/ui-gen/src/adapters/claude/client.ts\n//\n// SINGLE SOURCE OF TRUTH for Anthropic SDK construction.\n//\n// The BYOK resolver writes the raw credential string into\n// `process.env.ANTHROPIC_API_KEY`, which the Anthropic SDK auto-reads as\n// `x-api-key`. Adapters MUST go through `createAnthropicClient` (no\n// inline `new Anthropic(...)`) so future header / baseURL tweaks land\n// in one place.\n\nimport Anthropic from '@anthropic-ai/sdk';\n\n/**\n * Construct an Anthropic SDK client from a raw API key string.\n *\n * - `string` → standard `apiKey` path (sends `x-api-key`).\n * - `undefined` → still construct a client; SDK auto-reads\n * `process.env.ANTHROPIC_API_KEY` or throws on first call.\n *\n * **SINGLE SOURCE OF TRUTH for Anthropic client construction.** Every\n * adapter that constructs an Anthropic client MUST go through this\n * helper — no inline `new Anthropic(...)` allowed in adapter code.\n */\nexport function createAnthropicClient(\n rawKey: string | undefined,\n): Anthropic {\n if (rawKey === undefined) {\n return new Anthropic({\n baseURL: 'https://api.anthropic.com',\n });\n }\n return new Anthropic({\n apiKey: rawKey,\n baseURL: 'https://api.anthropic.com',\n });\n}\n","// packages/ui-gen/src/adapters/claude/raw.ts\n//\n// Claude adapter using the raw Anthropic SDK (@anthropic-ai/sdk).\n// Manual tool-use loop: messages.create() -> tool_use -> handler -> repeat.\n//\n// SDK client construction is centralized in `./client.ts`. Do NOT\n// inline `new Anthropic(...)` here.\n\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport { createAnthropicClient } from './client';\n\nexport class ClaudeRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'claude';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'Claude (Raw API)';\n\n private client: Anthropic | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'ANTHROPIC_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n // Bedrock path: SDK reads AWS creds from the env / role chain;\n // skip the `apiKey` set entirely — `createAnthropicClient(undefined)`\n // gives us a constructed client and the SDK does the rest.\n if (this.config.useBedrock) {\n this.client = createAnthropicClient(undefined);\n } else {\n const rawKey = this.config.apiKey || process.env.ANTHROPIC_API_KEY;\n this.client = createAnthropicClient(rawKey);\n }\n }\n\n const anthropicTools = params.tools.map(toAnthropicTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n\n const messages: Anthropic.MessageParam[] = [\n { role: 'user', content: params.userPrompt },\n ];\n\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n const response = await this.client.messages.create({\n model: params.model,\n max_tokens: 16384,\n system: params.systemPrompt,\n messages,\n tools: anthropicTools,\n });\n\n totalInputTokens += response.usage.input_tokens;\n totalOutputTokens += response.usage.output_tokens;\n\n const toolUseBlocks = response.content.filter(\n (block): block is Anthropic.ToolUseBlock => block.type === 'tool_use',\n );\n\n // Scan text blocks for streamSpec/generatorMeta markers\n for (const block of response.content) {\n if (block.type === 'text') captureMarkers(capture, block.text);\n }\n\n if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn') {\n break;\n }\n\n messages.push({\n role: 'assistant',\n content: response.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: block.text };\n }\n return {\n type: 'tool_use' as const,\n id: (block as Anthropic.ToolUseBlock).id,\n name: (block as Anthropic.ToolUseBlock).name,\n input: (block as Anthropic.ToolUseBlock).input,\n };\n }),\n });\n\n const toolResults: Anthropic.ToolResultBlockParam[] = [];\n\n for (const toolBlock of toolUseBlocks) {\n const toolDef = params.tools.find((t) => t.name === toolBlock.name);\n if (!toolDef) {\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolBlock.id,\n content: `Tool '${toolBlock.name}' not found`,\n is_error: true,\n });\n continue;\n }\n\n const args = (toolBlock.input as JsonObject) ?? {};\n captureSourceCode(capture, toolBlock.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, toolBlock.name, result);\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolBlock.id,\n content: result.content.map((c) => ({ type: 'text' as const, text: c.text })),\n is_error: result.isError,\n });\n }\n\n messages.push({ role: 'user', content: toolResults });\n }\n\n if (!capture.compiledCode) {\n throw new Error('Claude raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\nfunction toAnthropicTool(def: ToolDefinition): Anthropic.Tool {\n return {\n name: def.name,\n description: def.description,\n input_schema: zodToJsonSchema(def.inputSchema) as Anthropic.Tool.InputSchema,\n };\n}\n","// packages/ui-gen/src/adapters/claude/message-parser.ts\n//\n// Focused helpers for extracting artifacts from Claude Agent SDK messages.\n// Each function handles one extraction concern, keeping the main loop clean.\n//\n// Uses proper discriminated union narrowing on SDKMessage variants.\n\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKResultMessage,\n SDKSystemMessage,\n SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/**\n * Mutable accumulator for artifacts extracted from the SDK message stream.\n */\nexport interface MessageArtifacts {\n compiledCode: string;\n sourceCode: string | undefined;\n stream: JsonObject | undefined;\n generatorMeta: { category: string; description: string } | undefined;\n sdkSessionId: string | undefined;\n turnCount: number;\n inputTokens: number;\n outputTokens: number;\n cacheCreationTokens: number;\n cacheReadTokens: number;\n estimatedCostUsd: number | undefined;\n subagentsUsed: string[];\n}\n\nexport function createArtifacts(): MessageArtifacts {\n return {\n compiledCode: '',\n sourceCode: undefined,\n stream: undefined,\n generatorMeta: undefined,\n sdkSessionId: undefined,\n turnCount: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationTokens: 0,\n cacheReadTokens: 0,\n estimatedCostUsd: undefined,\n subagentsUsed: [],\n };\n}\n\n/** Progress event emitted during generation. */\nexport type ProgressEvent = { type: string; [key: string]: string | number | boolean | undefined };\n\n/**\n * Process a single SDK message and update artifacts accordingly.\n */\nexport function processMessage(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n maxTurns?: number,\n): void {\n extractSessionId(message, artifacts);\n trackTurns(message, artifacts, onProgress, maxTurns);\n trackTokenUsage(message, artifacts);\n extractCompiledCode(message, artifacts, onProgress);\n extractSourceCode(message, artifacts);\n extractStreamSpec(message, artifacts);\n extractGeneratorMeta(message, artifacts);\n}\n\n// ── Individual extractors ────────────────────────────────────────────\n\nfunction extractSessionId(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'system') return;\n const systemMsg = message as SDKSystemMessage;\n if (systemMsg.subtype === 'init') {\n artifacts.sdkSessionId = systemMsg.session_id;\n }\n}\n\nfunction trackTurns(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n maxTurns?: number,\n): void {\n if (message.type !== 'assistant') return;\n const assistantMsg = message as SDKAssistantMessage;\n artifacts.turnCount++;\n\n const contentBlocks = assistantMsg.message?.content;\n if (Array.isArray(contentBlocks)) {\n for (const block of contentBlocks) {\n if (block.type === 'tool_use') {\n onProgress?.({ type: 'tool_call', tool: block.name || 'unknown' });\n }\n }\n }\n onProgress?.({ type: 'turn', turn: artifacts.turnCount, maxTurns: maxTurns ?? 0 });\n}\n\nfunction trackTokenUsage(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'result') return;\n const resultMsg = message as SDKResultMessage;\n\n if (resultMsg.subtype === 'success') {\n const usage = resultMsg.usage;\n artifacts.inputTokens = usage.input_tokens || 0;\n artifacts.cacheCreationTokens = usage.cache_creation_input_tokens || 0;\n artifacts.cacheReadTokens = usage.cache_read_input_tokens || 0;\n artifacts.outputTokens = usage.output_tokens || 0;\n artifacts.estimatedCostUsd = resultMsg.total_cost_usd;\n }\n}\n\nfunction extractCompiledCode(\n message: SDKMessage,\n artifacts: MessageArtifacts,\n onProgress?: (event: ProgressEvent) => void,\n): void {\n if (artifacts.compiledCode) return; // Already found\n\n const msgStr = JSON.stringify(message);\n if (!msgStr.includes('compiledCode')) return;\n\n // Strategy 1: regex extraction from anywhere in the message\n const match = msgStr.match(/\"compiledCode\"\\s*:\\s*\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"/);\n if (match) {\n try {\n artifacts.compiledCode = JSON.parse(`\"${match[1]}\"`);\n onProgress?.({ type: 'compiled', bytes: artifacts.compiledCode.length });\n return;\n } catch {\n // Fall through to structured extraction\n }\n }\n\n // Strategy 2: structured extraction from tool_result content\n if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n const code = extractFromToolResults(userMsg);\n if (code) artifacts.compiledCode = code;\n }\n}\n\n/**\n * Walk the nested tool_result structures to find compiledCode.\n */\nfunction extractFromToolResults(message: SDKUserMessage): string | undefined {\n const content = message.message?.content;\n if (!Array.isArray(content)) return undefined;\n\n for (const item of content) {\n if (typeof item === 'object' && item !== null && 'type' in item && item.type === 'tool_result') {\n const toolResultItem = item as { type: 'tool_result'; content?: unknown };\n const code = parseCompiledCodeFromContent(toolResultItem.content);\n if (code) return code;\n }\n }\n\n return undefined;\n}\n\nfunction parseCompiledCodeFromContent(content: unknown): string | undefined {\n if (Array.isArray(content)) {\n for (const item of content) {\n const textItem = item as { type?: string; text?: string };\n if (textItem.type === 'text' && textItem.text?.includes('compiledCode')) {\n const code = tryParseCompiledCode(textItem.text);\n if (code) return code;\n }\n }\n }\n if (typeof content === 'string' && content.includes('compiledCode')) {\n return tryParseCompiledCode(content);\n }\n return undefined;\n}\n\nfunction tryParseCompiledCode(text: string): string | undefined {\n try {\n const parsed = JSON.parse(text);\n if (parsed.success && parsed.compiledCode) return parsed.compiledCode;\n } catch {\n // Not valid JSON\n }\n return undefined;\n}\n\nfunction extractSourceCode(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (message.type !== 'assistant') return;\n const assistantMsg = message as SDKAssistantMessage;\n\n const content = assistantMsg.message?.content;\n if (!Array.isArray(content)) return;\n\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'Write') {\n const input = block.input as { content?: string } | undefined;\n if (input?.content) {\n artifacts.sourceCode = input.content;\n }\n }\n }\n}\n\n/**\n * Unescape a JSON string that was double-escaped inside another JSON string.\n */\nfunction unescapeJsonString(s: string): string {\n return s.replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\');\n}\n\n/**\n * Extract a delimited marker from a JSON-stringified message.\n * Returns the raw content between START and END markers, or undefined.\n */\nfunction extractMarker(msgStr: string, startMarker: string, endMarker: string): string | undefined {\n if (!msgStr.includes(startMarker)) return undefined;\n const match = msgStr.match(new RegExp(`${startMarker}\\\\s*([\\\\s\\\\S]*?)\\\\s*${endMarker}`));\n return match?.[1];\n}\n\nfunction extractStreamSpec(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (artifacts.stream) return;\n\n const raw = extractMarker(JSON.stringify(message), '__GGUI_STREAM_SPEC__', '__GGUI_STREAM_SPEC_END__');\n if (!raw) return;\n\n try {\n artifacts.stream = JSON.parse(unescapeJsonString(raw));\n } catch {\n // Failed to parse\n }\n}\n\nfunction extractGeneratorMeta(message: SDKMessage, artifacts: MessageArtifacts): void {\n if (artifacts.generatorMeta) return;\n\n const raw = extractMarker(JSON.stringify(message), '__GGUI_META__', '__GGUI_META_END__');\n if (!raw) return;\n\n try {\n const stripped = raw.replace(/```(?:json)?\\s*/g, '').trim();\n const parsed = JSON.parse(unescapeJsonString(stripped)) as { category?: string; description?: string };\n if (parsed.category) {\n artifacts.generatorMeta = {\n category: parsed.category,\n description: parsed.description ?? '',\n };\n }\n } catch {\n // Failed to parse\n }\n}\n","// packages/ui-gen/src/adapters/claude/tool-bridge.ts\n//\n// Bridges ToolDefinition[] → in-process MCP server for Claude Agent SDK.\n//\n// The Claude Agent SDK doesn't support direct function-tool definitions.\n// All custom tools must go through MCP servers. This bridge creates an\n// in-process MCP server from our generic ToolDefinition[] using the SDK's\n// built-in tool() + createSdkMcpServer() helpers.\n//\n// Tool naming convention: mcp__{serverName}__{toolName}\n// e.g., mcp__ggui__compile_component\n\nimport type { ToolDefinition } from '../types';\nimport type { McpSdkServerConfigWithInstance } from '@anthropic-ai/claude-agent-sdk';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/** Name used for the in-process MCP server. */\nexport const MCP_SERVER_NAME = 'ggui';\n\n/**\n * Create an in-process MCP server from ToolDefinition[] using\n * the Claude Agent SDK's tool() + createSdkMcpServer() helpers.\n *\n * Returns the MCP server instance and the list of allowedTools names\n * (in mcp__{server}__{tool} format).\n */\nexport async function createToolMcpServer(\n tools: ToolDefinition[],\n): Promise<{\n server: McpSdkServerConfigWithInstance;\n allowedToolNames: string[];\n}> {\n const { tool, createSdkMcpServer } = await import('@anthropic-ai/claude-agent-sdk');\n\n const mcpTools = tools.map((def) => {\n // Extract Zod shape from the input schema\n const shape = def.inputSchema.shape ?? {};\n\n return tool(\n def.name,\n def.description,\n shape,\n async (args: JsonObject) => {\n const result = await def.handler(args);\n return {\n content: result.content.map((c) => ({\n type: 'text' as const,\n text: c.text,\n })),\n ...(result.isError && { isError: true }),\n };\n },\n );\n });\n\n const server = createSdkMcpServer({\n name: MCP_SERVER_NAME,\n version: '1.0.0',\n tools: mcpTools,\n });\n\n const allowedToolNames = tools.map((t) => `mcp__${MCP_SERVER_NAME}__${t.name}`);\n\n return { server, allowedToolNames };\n}\n\n/**\n * Filter tool names for a specific phase (e.g., context-only or build-only).\n * Takes the original tool names (without MCP prefix) and returns\n * MCP-formatted names.\n */\nexport function filterMcpToolNames(\n originalNames: string[],\n): string[] {\n return originalNames.map((name) => `mcp__${MCP_SERVER_NAME}__${name}`);\n}\n","// packages/ui-gen/src/adapters/claude/sdk.ts\n//\n// Claude adapter using the Claude Agent SDK (@anthropic-ai/claude-agent-sdk).\n// Uses query() async iterator with MCP servers for tool execution.\n//\n// Two modes:\n// 1. Pre-configured MCP servers (production) — pass mcpServers in ClaudeSdkConfig\n// 2. Direct tools (benchmark) — ToolDefinition[] auto-bridged to in-process MCP server\n\nimport type { McpServerConfig } from '@anthropic-ai/claude-agent-sdk';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { ClaudeSdkConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport { createArtifacts, processMessage } from './message-parser';\nimport { createToolMcpServer } from './tool-bridge';\n\nexport class ClaudeSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'claude';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'Claude (Agent SDK)';\n\n constructor(config: ClaudeSdkConfig = {}) {\n super(config);\n }\n\n /** Narrowed config access for Claude SDK-specific fields. */\n private get sdkConfig(): ClaudeSdkConfig {\n return this.config as ClaudeSdkConfig;\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'ANTHROPIC_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n const cfg = this.sdkConfig;\n\n // Dynamic import to avoid loading claude-agent-sdk in non-Claude contexts\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n\n // Build environment from config or process.env\n const env = buildEnv(cfg.env);\n\n const artifacts = createArtifacts();\n const onProgress = cfg.onProgress;\n\n // Determine MCP servers — use config's servers or bridge from tools\n let mcpServers: Record<string, McpServerConfig> | undefined = cfg.mcpServers;\n let allowedTools: string[] | undefined = cfg.allowedTools;\n\n if (!mcpServers && params.tools.length > 0) {\n // Bridge ToolDefinition[] to in-process MCP server\n const bridge = await createToolMcpServer(params.tools);\n mcpServers = { ggui: bridge.server };\n allowedTools = bridge.allowedToolNames;\n }\n\n // Run SDK query — message parsing is handled by processMessage()\n for await (const message of query({\n prompt: params.userPrompt,\n options: {\n cwd: cfg.cwd,\n env,\n model: params.model,\n maxTurns: params.maxTurns,\n systemPrompt: params.systemPrompt,\n ...(mcpServers && { mcpServers }),\n ...(cfg.agents && { agents: cfg.agents }),\n ...(allowedTools && { allowedTools }),\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n ...(cfg.cliPath && { pathToClaudeCodeExecutable: cfg.cliPath }),\n ...(cfg.stderr && { stderr: cfg.stderr }),\n },\n })) {\n processMessage(\n message,\n artifacts,\n onProgress,\n params.maxTurns,\n );\n }\n\n const generationTimeMs = Date.now() - startTime;\n\n // Cache audit telemetry. Track whether the Claude Agent SDK is\n // actually caching the system prompt\n // across turns. `read > 0` on turn 2+ means the SDK's internal\n // cache_control is firing. `read = 0` across all turns = we're\n // paying full input cost every turn; explicit cache_control needed.\n const totalCacheIn = artifacts.inputTokens + artifacts.cacheCreationTokens + artifacts.cacheReadTokens;\n const cacheReadPct = totalCacheIn > 0\n ? Math.round((artifacts.cacheReadTokens / totalCacheIn) * 100)\n : 0;\n console.log(\n `[claude-sdk] cache: created=${artifacts.cacheCreationTokens} read=${artifacts.cacheReadTokens} input=${artifacts.inputTokens} output=${artifacts.outputTokens} turns=${artifacts.turnCount} cache-read-pct=${cacheReadPct}%`,\n );\n\n if (!artifacts.compiledCode) {\n const wasExhausted = artifacts.turnCount >= params.maxTurns;\n throw new Error(\n wasExhausted\n ? `Generation used all ${params.maxTurns} turns without producing compiled code.`\n : 'Generation completed without compiled code',\n );\n }\n\n return {\n compiledCode: artifacts.compiledCode,\n sourceCode: artifacts.sourceCode,\n tokens: {\n input: artifacts.inputTokens,\n output: artifacts.outputTokens,\n total:\n artifacts.inputTokens +\n artifacts.cacheCreationTokens +\n artifacts.cacheReadTokens +\n artifacts.outputTokens,\n },\n generationTimeMs,\n turnsUsed: artifacts.turnCount,\n rawCostUsd: artifacts.estimatedCostUsd,\n stream: artifacts.stream,\n generatorMeta: artifacts.generatorMeta,\n subagentsUsed: artifacts.subagentsUsed,\n cacheCreationTokens: artifacts.cacheCreationTokens,\n cacheReadTokens: artifacts.cacheReadTokens,\n sdkSessionId: artifacts.sdkSessionId,\n };\n }\n}\n\nfunction buildEnv(configEnv?: Record<string, string>): Record<string, string> {\n if (configEnv) return sanitizeEnv({ ...configEnv });\n\n const env: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined) env[key] = value;\n }\n return sanitizeEnv(env);\n}\n\n/**\n * Remove env vars that would redirect the SDK subprocess to a non-running proxy.\n * The SDK subprocess must connect to the real Anthropic API.\n */\nfunction sanitizeEnv(env: Record<string, string>): Record<string, string> {\n // Strip ANTHROPIC_BASE_URL if it points to localhost (LiteLLM proxy)\n // — the SDK subprocess should always use the real Anthropic API\n if (env.ANTHROPIC_BASE_URL?.includes('localhost')) {\n delete env.ANTHROPIC_BASE_URL;\n }\n return env;\n}\n","// packages/ui-gen/src/adapters/openai/raw.ts\n//\n// OpenAI adapter using the raw OpenAI SDK (openai).\n// Uses the Responses API (responses.create) with previous_response_id\n// for multi-turn tool-calling loops.\n\nimport type OpenAI from 'openai';\nimport type { Responses } from 'openai/resources/responses/responses';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n compileLastResort,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n/** Lazy-load the OpenAI SDK to avoid top-level import crashes in Lambda bundles. */\nasync function loadOpenAI(): Promise<typeof import('openai')> {\n return import('openai');\n}\n\nexport class OpenAiRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openai';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'OpenAI (Raw API)';\n\n private client: OpenAI | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENAI_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n const { default: OpenAIClient } = await loadOpenAI();\n this.client = new OpenAIClient({\n apiKey: this.config.apiKey || process.env.OPENAI_API_KEY,\n });\n }\n\n const tools = params.tools.map(toResponsesTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n let allTextOutput = '';\n\n // First request — user prompt + instructions\n let response: Responses.Response = await this.client.responses.create({\n model: params.model,\n instructions: params.systemPrompt,\n input: [{ role: 'user', content: params.userPrompt }],\n tools,\n store: true, // Required for previous_response_id to work on subsequent turns\n });\n\n // Agentic loop\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n // Track tokens\n if (response.usage) {\n totalInputTokens += response.usage.input_tokens ?? 0;\n totalOutputTokens += response.usage.output_tokens ?? 0;\n }\n\n // Process output items\n const output = response.output ?? [];\n const functionCalls = output.filter(\n (item): item is Responses.ResponseFunctionToolCall => item.type === 'function_call',\n );\n\n // Collect text output for markers and code extraction fallback\n for (const item of output) {\n if (item.type === 'message' && 'content' in item && item.content) {\n for (const part of item.content) {\n if (part.type === 'output_text' && part.text) {\n allTextOutput += part.text + '\\n';\n captureMarkers(capture, part.text);\n }\n }\n }\n }\n\n if (functionCalls.length === 0) break;\n\n // Only send function_call_output items — previous_response_id carries context\n const nextInput: Responses.ResponseInputItem.FunctionCallOutput[] = [];\n\n for (const fc of functionCalls) {\n const toolDef = params.tools.find((t) => t.name === fc.name);\n if (!toolDef) {\n nextInput.push({\n type: 'function_call_output',\n call_id: fc.call_id,\n output: JSON.stringify({ error: `Tool '${fc.name}' not found` }),\n });\n continue;\n }\n\n let args: JsonObject = {};\n try { args = JSON.parse(fc.arguments || '{}') as JsonObject; } catch { /* empty */ }\n\n captureSourceCode(capture, fc.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, fc.name, result);\n\n nextInput.push({\n type: 'function_call_output',\n call_id: fc.call_id,\n output: result.content[0]?.text ?? '',\n });\n }\n\n // Next turn — use previous_response_id for context continuity\n response = await this.client.responses.create({\n model: params.model,\n instructions: params.systemPrompt,\n input: nextInput,\n tools,\n previous_response_id: response.id,\n store: true,\n });\n }\n\n // Fallback: extract code from text output if no tool produced compiled code\n if (!capture.compiledCode && allTextOutput) {\n captureMarkers(capture, allTextOutput);\n await extractCodeFromText(allTextOutput, params.tools, capture);\n }\n\n // Last resort: compile sourceCode directly with esbuild, bypassing self-checks\n if (!capture.compiledCode) {\n await compileLastResort(capture, allTextOutput);\n }\n\n if (!capture.compiledCode) {\n throw new Error('OpenAI raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\n/**\n * Convert a ToolDefinition to OpenAI Responses API FunctionTool format.\n */\nfunction toResponsesTool(def: ToolDefinition): { type: 'function'; name: string; description: string; parameters: JsonObject; strict: boolean } {\n return {\n type: 'function',\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema) as JsonObject,\n strict: false,\n };\n}\n","// packages/ui-gen/src/adapters/openai/sdk.ts\n//\n// OpenAI adapter using @openai/agents SDK.\n// Creates an Agent with function tools and runs it via run().\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\nasync function loadOpenAIAgents() {\n return import('@openai/agents');\n}\n\nexport class OpenAiSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openai';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'OpenAI (Agents SDK)';\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENAI_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n const apiKey = this.config.apiKey || process.env.OPENAI_API_KEY;\n if (apiKey) process.env.OPENAI_API_KEY = apiKey;\n\n const capture = createCapture();\n\n // Build tools that call our handlers and capture compile results\n const { Agent, run, tool } = await loadOpenAIAgents();\n\n const wiredTools = params.tools.map((def) =>\n tool({\n name: def.name,\n description: def.description,\n parameters: def.inputSchema,\n execute: async (args) => {\n const typedArgs = (args ?? {}) as JsonObject;\n captureSourceCode(capture, def.name, typedArgs);\n\n const result = await def.handler(typedArgs);\n captureCompiledCode(capture, def.name, result);\n\n return result.content[0]?.text ?? '';\n },\n }),\n );\n\n const agent = new Agent({\n name: 'ui-generator',\n instructions: params.systemPrompt,\n model: params.model,\n tools: wiredTools,\n });\n\n const result = await run(agent, params.userPrompt, {\n maxTurns: params.maxTurns,\n });\n\n const finalOutput = String(result.finalOutput ?? '');\n\n // Scan final output for streamSpec/generatorMeta markers\n if (finalOutput) captureMarkers(capture, finalOutput);\n\n // Fallback: extract code from text output if no tool call produced it\n if (!capture.compiledCode) {\n await extractCodeFromText(finalOutput, params.tools, capture);\n\n if (!capture.compiledCode) {\n throw new Error('OpenAI SDK adapter: no compiled code produced after all turns');\n }\n }\n const usage = result.state.usage;\n const inputTokens = usage.inputTokens;\n const outputTokens = usage.outputTokens;\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: inputTokens,\n output: outputTokens,\n total: inputTokens + outputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed: result.rawResponses?.length ?? 0,\n };\n }\n}\n","// packages/ui-gen/src/adapters/google/raw.ts\n//\n// Google adapter using the Interactions API (@google/genai >= 2.0.0,\n// 'steps' schema). Uses interactions.create() with\n// previous_interaction_id for server-side state management. System\n// prompt and tools sent on turn 1, subsequent turns only send\n// function_result steps — server remembers context.\n\nimport type { GoogleGenAI as GoogleGenAIType, Interactions } from '@google/genai';\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema, toolArgsToJsonObject } from '../tool-bridge';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\n\nasync function loadGoogleGenAI() {\n return import('@google/genai');\n}\n\nexport class GoogleRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'google';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'Google Gemini (Interactions API)';\n\n private client: GoogleGenAIType | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'GEMINI_API_KEY', 'GOOGLE_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n const { GoogleGenAI } = await loadGoogleGenAI();\n this.client = new GoogleGenAI({\n apiKey: this.config.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY,\n httpOptions: { timeout: 300_000 }, // 5 min — Pro models can be slow\n });\n }\n\n const tools = params.tools.map(toInteractionTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let turnsUsed = 0;\n\n // Thinking control. Gemini 3.x Flash defaults thinking ON — the\n // dominant latency cost in UI generation, where the task is\n // contract-bounded code emission, not open-ended reasoning. The\n // Interactions API exposes this as `generation_config.thinking_level`\n // ('minimal' is the floor — there is no true off — then 'low' /\n // 'medium' / 'high'). When the caller pins a level we forward it on\n // every turn. Omitted → provider default (unchanged behavior).\n const thinkingLevel = this.config.thinkingLevel;\n const generationConfig = thinkingLevel\n ? { thinking_level: thinkingLevel }\n : undefined;\n\n // Turn 1: send system instruction + tools + user prompt\n let interaction = await this.client.interactions.create({\n model: params.model,\n system_instruction: params.systemPrompt,\n tools,\n input: params.userPrompt,\n ...(generationConfig ? { generation_config: generationConfig } : {}),\n });\n\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n // Track tokens\n if (interaction.usage) {\n totalInputTokens += interaction.usage.total_input_tokens ?? 0;\n totalOutputTokens += interaction.usage.total_output_tokens ?? 0;\n }\n\n // Scan model-output text for streamSpec/generatorMeta markers.\n // `steps` is a discriminated union — even at thinking_level\n // 'minimal' a `thought` step is present, so iterate by\n // discriminant and skip step types we don't consume.\n for (const step of interaction.steps) {\n if (step.type === 'model_output') {\n for (const content of step.content ?? []) {\n if (content.type === 'text') {\n captureMarkers(capture, content.text);\n }\n }\n }\n }\n\n // Collect function calls\n const functionCalls = interaction.steps.filter(\n (s): s is Interactions.FunctionCallStep => s.type === 'function_call',\n );\n\n if (functionCalls.length === 0) break;\n\n // Execute tools and build function_result inputs\n const results: Interactions.FunctionResultStep[] = [];\n\n for (const fc of functionCalls) {\n const toolDef = params.tools.find((t) => t.name === fc.name);\n if (!toolDef) {\n results.push({\n type: 'function_result',\n call_id: fc.id,\n name: fc.name,\n result: JSON.stringify({ error: `Tool '${fc.name}' not found` }),\n is_error: true,\n });\n continue;\n }\n\n const args = toolArgsToJsonObject(fc.arguments);\n captureSourceCode(capture, fc.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, fc.name, result);\n\n results.push({\n type: 'function_result',\n call_id: fc.id,\n name: fc.name,\n result: result.content[0]?.text ?? '',\n });\n }\n\n // Next turn: only send function results — server has the history\n interaction = await this.client.interactions.create({\n model: params.model,\n previous_interaction_id: interaction.id,\n input: results,\n ...(generationConfig ? { generation_config: generationConfig } : {}),\n });\n }\n\n if (!capture.compiledCode) {\n throw new Error('Google raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n };\n }\n}\n\n/** Convert ToolDefinition to Interactions API function tool format. */\nfunction toInteractionTool(def: ToolDefinition): Interactions.Function {\n return {\n type: 'function',\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema),\n };\n}\n","// packages/ui-gen/src/adapters/google/sdk.ts\n//\n// Google adapter using @google/adk (Agent Development Kit).\n// Uses LlmAgent + InMemoryRunner + FunctionTool for agent-managed tool execution.\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ProviderName, AdapterMode } from '../types';\nimport { createCapture, captureSourceCode, captureCompiledCode, captureMarkers } from '../extract-code';\nimport type { Content, Part } from '@google/genai';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport type { ToolInputParameters } from '@google/adk';\n\nexport class GoogleSdkAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'google';\n readonly mode: AdapterMode = 'sdk';\n readonly displayName = 'Google Gemini (ADK)';\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'GEMINI_API_KEY', 'GOOGLE_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const apiKey = this.config.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;\n\n return runAdkLoop({\n systemPrompt: params.systemPrompt,\n userPrompt: params.userPrompt,\n model: params.model,\n tools: params.tools,\n apiKey,\n });\n }\n}\n\n// =============================================================================\n// Core agentic loop — Google ADK (LlmAgent + InMemoryRunner)\n// =============================================================================\n\nimport type { ToolDefinition } from '../types';\n\nexport interface AdkLoopParams {\n systemPrompt: string;\n userPrompt: string;\n model: string;\n tools: ToolDefinition[];\n apiKey?: string;\n}\n\n/**\n * Run a single agentic loop using Google ADK.\n *\n * Uses InMemoryRunner.runAsync() which returns an async iterator of events.\n * FunctionTool wraps our ToolDefinition handlers with capture logic.\n */\nexport async function runAdkLoop(\n params: AdkLoopParams,\n): Promise<AdapterResult> {\n const startTime = Date.now();\n\n const { FunctionTool, LlmAgent, InMemoryRunner, isFinalResponse } = await import('@google/adk');\n\n const capture = createCapture();\n\n // Ensure ADK can find the API key\n if (params.apiKey && !process.env.GOOGLE_GENAI_API_KEY) {\n process.env.GOOGLE_GENAI_API_KEY = params.apiKey;\n }\n\n // Build tools with capture wrappers\n const adkTools = params.tools.map((def) =>\n new FunctionTool({\n name: def.name,\n description: def.description,\n // Pass Zod schema directly — ADK accepts ZodObject natively\n parameters: def.inputSchema as ToolInputParameters,\n execute: async (args: unknown) => {\n const typedArgs = (args ?? {}) as JsonObject;\n captureSourceCode(capture, def.name, typedArgs);\n const result = await def.handler(typedArgs);\n captureCompiledCode(capture, def.name, result);\n return result.content[0]?.text ?? '';\n },\n }),\n );\n\n const agent = new LlmAgent({\n name: 'ui_generator',\n model: params.model,\n instruction: params.systemPrompt,\n tools: adkTools,\n });\n\n const runner = new InMemoryRunner({ agent, appName: 'ggui_generator' });\n const session = await runner.sessionService.createSession({\n appName: 'ggui_generator',\n userId: 'benchmark',\n });\n\n const userMessage: Content = {\n role: 'user',\n parts: [{ text: params.userPrompt }],\n };\n\n let finalText = '';\n let turnCount = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n\n for await (const event of runner.runAsync({\n userId: 'benchmark',\n sessionId: session.id,\n newMessage: userMessage,\n })) {\n turnCount++;\n\n // Extract token usage from event's underlying LLM response\n const usage = event.usageMetadata;\n if (usage) {\n totalInputTokens += usage.promptTokenCount ?? 0;\n totalOutputTokens += usage.candidatesTokenCount ?? 0;\n }\n\n // Scan every event's content for markers and code\n if (event.content?.parts) {\n const text = event.content.parts.map((p: Part) => p.text ?? '').join('');\n if (text) captureMarkers(capture, text);\n }\n\n if (isFinalResponse(event)) {\n const parts = event.content?.parts;\n finalText = parts?.map((p: Part) => p.text ?? '').join('') ?? '';\n }\n }\n\n // Final scan of accumulated text\n if (finalText) captureMarkers(capture, finalText);\n\n if (!capture.compiledCode) {\n throw new Error('Google ADK adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed: turnCount,\n };\n}\n","// packages/ui-gen/src/adapters/openrouter/types.ts\n//\n// OpenRouter-specific types for the chat completion API.\n// Reference: https://openrouter.ai/docs/api-reference\n\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n// =============================================================================\n// Model metadata (from GET /api/v1/models)\n// =============================================================================\n\n/** Model entry from OpenRouter's /api/v1/models endpoint */\nexport interface OpenRouterModelEntry {\n id: string;\n name: string;\n description: string;\n pricing: { prompt: string; completion: string; image?: string };\n context_length: number;\n architecture: {\n modality: string;\n tokenizer: string;\n instruct_type: string | null;\n };\n top_provider: {\n context_length: number;\n max_completion_tokens: number;\n is_moderated: boolean;\n };\n per_request_limits: Record<string, string> | null;\n}\n\n// =============================================================================\n// Chat Completion API\n// =============================================================================\n\nexport interface OpenRouterMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | OpenRouterContentBlock[] | null;\n tool_calls?: OpenRouterToolCall[];\n tool_call_id?: string;\n}\n\nexport interface OpenRouterContentBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' };\n}\n\nexport interface OpenRouterTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: JsonObject;\n };\n}\n\nexport interface OpenRouterToolCall {\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n}\n\nexport interface OpenRouterChatRequest {\n model: string;\n messages: OpenRouterMessage[];\n tools?: OpenRouterTool[];\n tool_choice?: 'auto' | 'required' | 'none';\n max_tokens?: number;\n temperature?: number;\n stream?: boolean;\n thinking?: { type: 'enabled'; budget_tokens: number };\n}\n\nexport interface OpenRouterChatResponse {\n id: string;\n model: string;\n choices: Array<{\n index: number;\n message: {\n role: 'assistant';\n content: string | null;\n tool_calls?: OpenRouterToolCall[];\n thinking?: string;\n };\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n// =============================================================================\n// SSE Streaming\n// =============================================================================\n\nexport interface OpenRouterStreamDelta {\n id: string;\n model: string;\n choices: Array<{\n index: number;\n delta: {\n role?: 'assistant';\n content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n type?: 'function';\n function?: { name?: string; arguments?: string };\n }>;\n };\n finish_reason: string | null;\n }>;\n usage?: OpenRouterChatResponse['usage'];\n}\n\n// =============================================================================\n// Error\n// =============================================================================\n\nexport class OpenRouterError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OpenRouterError';\n }\n\n get isTransient(): boolean {\n return this.status === 408 || this.status === 429\n || this.status === 502 || this.status === 503;\n }\n}\n","// packages/ui-gen/src/adapters/openrouter/client.ts\n//\n// Direct fetch()-based HTTP client for OpenRouter's API.\n// No OpenAI SDK dependency — independent implementation.\n\nimport type {\n OpenRouterChatRequest,\n OpenRouterChatResponse,\n OpenRouterStreamDelta,\n} from './types';\nimport { OpenRouterError } from './types';\n\nexport interface OpenRouterClientConfig {\n apiKey: string;\n baseUrl?: string;\n siteUrl?: string;\n siteName?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';\n\nexport class OpenRouterClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n\n constructor(private readonly config: OpenRouterClientConfig) {\n this.baseUrl = config.baseUrl ?? process.env.OPENROUTER_BASE_URL ?? DEFAULT_BASE_URL;\n this.headers = {\n 'Authorization': `Bearer ${config.apiKey}`,\n 'Content-Type': 'application/json',\n 'HTTP-Referer': config.siteUrl ?? process.env.OPENROUTER_SITE_URL ?? 'https://ggui.ai',\n 'X-Title': config.siteName ?? process.env.OPENROUTER_SITE_NAME ?? 'ggui',\n };\n }\n\n /**\n * Non-streaming chat completion.\n */\n async chatCompletion(\n params: Omit<OpenRouterChatRequest, 'stream'>,\n ): Promise<OpenRouterChatResponse> {\n const body: OpenRouterChatRequest = { ...params, stream: false };\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: { message: response.statusText } }));\n const message = (errorBody as { error?: { message?: string } }).error?.message ?? response.statusText;\n throw new OpenRouterError(message, response.status);\n }\n\n return response.json() as Promise<OpenRouterChatResponse>;\n }\n\n /**\n * Streaming chat completion via SSE.\n * Yields delta chunks, accumulates the final usage from the last chunk.\n */\n async *chatCompletionStream(\n params: Omit<OpenRouterChatRequest, 'stream'>,\n ): AsyncGenerator<OpenRouterStreamDelta> {\n const body: OpenRouterChatRequest = { ...params, stream: true };\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: { message: response.statusText } }));\n const message = (errorBody as { error?: { message?: string } }).error?.message ?? response.statusText;\n throw new OpenRouterError(message, response.status);\n }\n\n if (!response.body) {\n throw new OpenRouterError('No response body for streaming request', 500);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(':')) continue;\n if (trimmed === 'data: [DONE]') return;\n if (!trimmed.startsWith('data: ')) continue;\n\n const json = trimmed.slice('data: '.length);\n try {\n yield JSON.parse(json) as OpenRouterStreamDelta;\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","// packages/ui-gen/src/adapters/openrouter/raw.ts\n//\n// OpenRouter adapter using direct fetch() — no OpenAI SDK dependency.\n// Uses OpenAI-compatible chat completions API with OpenRouter extensions\n// for caching and extended thinking.\n\nimport { GeneratorAdapter, hasCredentials } from '../base';\nimport type { AdapterConfig, GenerateParams } from '../base';\nimport type { AdapterResult, ToolDefinition, ProviderName, AdapterMode } from '../types';\nimport { zodToJsonSchema } from '../tool-bridge';\nimport {\n createCapture,\n captureSourceCode,\n captureCompiledCode,\n captureMarkers,\n extractCodeFromText,\n compileLastResort,\n} from '../extract-code';\nimport type { JsonObject } from '@ggui-ai/protocol';\nimport { OpenRouterClient } from './client';\nimport type { OpenRouterMessage, OpenRouterTool, OpenRouterChatResponse } from './types';\n\nexport class OpenRouterRawAdapter extends GeneratorAdapter {\n readonly provider: ProviderName = 'openrouter';\n readonly mode: AdapterMode = 'raw';\n readonly displayName = 'OpenRouter (Raw API)';\n\n private client: OpenRouterClient | null = null;\n\n constructor(config: AdapterConfig = {}) {\n super(config);\n }\n\n isAvailable(): boolean {\n return hasCredentials(this.config, 'OPENROUTER_API_KEY');\n }\n\n async generate(params: GenerateParams): Promise<AdapterResult> {\n const startTime = Date.now();\n\n if (!this.client) {\n this.client = new OpenRouterClient({\n apiKey: this.config.apiKey || process.env.OPENROUTER_API_KEY!,\n });\n }\n\n const tools = params.tools.map(toOpenRouterTool);\n const capture = createCapture();\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let cacheCreationTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let turnsUsed = 0;\n let allTextOutput = '';\n\n // Detect model capabilities for cache/thinking support\n const modelId = params.model;\n const isAnthropicModel = modelId.includes('anthropic/') || modelId.includes('claude');\n\n // Build initial messages with optional cache_control\n const systemMessage: OpenRouterMessage = isAnthropicModel\n ? {\n role: 'system',\n content: [{ type: 'text', text: params.systemPrompt, cache_control: { type: 'ephemeral' } }],\n }\n : { role: 'system', content: params.systemPrompt };\n\n const messages: OpenRouterMessage[] = [\n systemMessage,\n { role: 'user', content: params.userPrompt },\n ];\n\n // Agentic loop\n for (let turn = 0; turn < params.maxTurns; turn++) {\n turnsUsed = turn + 1;\n\n const response: OpenRouterChatResponse = await this.client.chatCompletion({\n model: modelId,\n messages,\n tools: tools.length > 0 ? tools : undefined,\n tool_choice: tools.length > 0 ? 'auto' : undefined,\n max_tokens: 16384,\n });\n\n // Track tokens\n if (response.usage) {\n totalInputTokens += response.usage.prompt_tokens;\n totalOutputTokens += response.usage.completion_tokens;\n if (response.usage.cache_creation_input_tokens) {\n cacheCreationTokens = (cacheCreationTokens ?? 0) + response.usage.cache_creation_input_tokens;\n }\n if (response.usage.cache_read_input_tokens) {\n cacheReadTokens = (cacheReadTokens ?? 0) + response.usage.cache_read_input_tokens;\n }\n }\n\n const choice = response.choices[0];\n if (!choice) break;\n\n // Collect text output\n if (choice.message.content) {\n allTextOutput += choice.message.content + '\\n';\n captureMarkers(capture, choice.message.content);\n }\n\n const toolCalls = choice.message.tool_calls;\n if (!toolCalls || toolCalls.length === 0) break;\n\n // Add assistant message with tool_calls to conversation\n messages.push({\n role: 'assistant',\n content: choice.message.content,\n tool_calls: toolCalls,\n });\n\n // Execute tools and add results\n for (const tc of toolCalls) {\n const toolDef = params.tools.find((t) => t.name === tc.function.name);\n if (!toolDef) {\n messages.push({\n role: 'tool',\n tool_call_id: tc.id,\n content: JSON.stringify({ error: `Tool '${tc.function.name}' not found` }),\n });\n continue;\n }\n\n let args: JsonObject = {};\n try { args = JSON.parse(tc.function.arguments || '{}') as JsonObject; } catch { /* empty */ }\n\n captureSourceCode(capture, tc.function.name, args);\n\n const result = await toolDef.handler(args);\n captureCompiledCode(capture, tc.function.name, result);\n\n messages.push({\n role: 'tool',\n tool_call_id: tc.id,\n content: result.content[0]?.text ?? '',\n });\n }\n }\n\n // Fallback: extract code from text output\n if (!capture.compiledCode && allTextOutput) {\n captureMarkers(capture, allTextOutput);\n await extractCodeFromText(allTextOutput, params.tools, capture);\n }\n\n // Last resort: compile sourceCode directly\n if (!capture.compiledCode) {\n await compileLastResort(capture, allTextOutput);\n }\n\n if (!capture.compiledCode) {\n throw new Error('OpenRouter raw adapter: no compiled code produced after all turns');\n }\n\n return {\n compiledCode: capture.compiledCode,\n sourceCode: capture.sourceCode,\n stream: capture.stream,\n generatorMeta: capture.generatorMeta,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n generationTimeMs: Date.now() - startTime,\n turnsUsed,\n cacheCreationTokens,\n cacheReadTokens,\n };\n }\n}\n\n/** Convert ToolDefinition to OpenRouter tool format (OpenAI-compatible). */\nfunction toOpenRouterTool(def: ToolDefinition): OpenRouterTool {\n return {\n type: 'function',\n function: {\n name: def.name,\n description: def.description,\n parameters: zodToJsonSchema(def.inputSchema) as JsonObject,\n },\n };\n}\n","// packages/ui-gen/src/adapters/types.ts\n//\n// Production adapter types — used by both Lambda generation and benchmarks.\n\nimport type { z } from 'zod';\nimport type { JsonObject } from '@ggui-ai/protocol';\n\n// =============================================================================\n// Provider & Mode\n// =============================================================================\n\nexport type ProviderName = 'claude' | 'openai' | 'google' | 'openrouter';\nexport type AdapterMode = 'raw' | 'sdk' | 'multi-agent';\n\nexport const PROVIDER_DISPLAY_NAMES: Record<ProviderName, string> = {\n claude: 'Anthropic Claude',\n openai: 'OpenAI',\n google: 'Google Gemini',\n openrouter: 'OpenRouter',\n};\n\n// =============================================================================\n// Tool Definition (SDK-agnostic)\n// =============================================================================\n\nexport interface ToolResultContent {\n type: 'text';\n text: string;\n}\n\nexport interface ToolResult {\n content: ToolResultContent[];\n isError?: boolean;\n}\n\n/**\n * SDK-agnostic tool definition.\n * Each adapter converts these to its native tool format.\n */\nexport interface ToolDefinition {\n /** Tool name (e.g., 'compile_component') */\n name: string;\n /** Tool description for the LLM */\n description: string;\n /** Zod schema for input parameters (always an object schema — tools take named args) */\n inputSchema: z.ZodObject<z.ZodRawShape>;\n /** Handler function — same signature regardless of SDK */\n handler: (args: JsonObject) => Promise<ToolResult>;\n}\n\n// =============================================================================\n// Adapter Result\n// =============================================================================\n\n/**\n * Result returned by any adapter's generate() method.\n *\n * Core fields are populated by all adapters. Extended fields are\n * populated by adapters that support richer output (e.g., Claude SDK).\n */\nexport interface AdapterResult {\n /** Final compiled JavaScript component code */\n compiledCode: string;\n /** TSX source code (captured from compile_component input) */\n sourceCode?: string;\n /** Token usage breakdown */\n tokens: {\n input: number;\n output: number;\n total: number;\n };\n /** Wall-clock generation time in ms */\n generationTimeMs: number;\n /** Total number of LLM API calls across all phases */\n turnsUsed: number;\n /** Number of harness iterations (Plan→Code→Evaluate→Regen cycles). 1 = single pass. */\n iterations?: number;\n /** Raw cost from SDK if available */\n rawCostUsd?: number;\n\n // ── Extended fields (production use) ───────────────────────────────\n\n /** Data spec for ggui_emit — describes what data the component accepts */\n stream?: JsonObject;\n /** LLM-generated metadata annotation for blueprint indexing */\n generatorMeta?: { category: string; description: string };\n /** Names of subagents invoked during generation */\n subagentsUsed?: string[];\n /** Tokens written to prompt cache (Claude-specific) */\n cacheCreationTokens?: number;\n /** Tokens read from prompt cache (Claude-specific) */\n cacheReadTokens?: number;\n /** SDK session ID for evaluation loop resume (Claude SDK-specific) */\n sdkSessionId?: string;\n}\n","// packages/ui-gen/src/adapters/index.ts\n//\n// Public API for the adapter module.\n// Use getAdapter() to obtain adapter instances — it lazy-loads provider SDKs.\n//\n// NOTE: Importing concrete adapters (ClaudeRawAdapter, etc.) directly from\n// this barrel file will statically pull in their provider SDKs. This is fine\n// for benchmarks and tests, but Lambda entry points should use getAdapter()\n// from './registry' to benefit from lazy loading and smaller bundles.\n\n// ── Types ────────────────────────────────────────────────────────────\nexport type {\n ProviderName,\n AdapterMode,\n ToolDefinition,\n ToolResult,\n ToolResultContent,\n AdapterResult,\n} from './types';\n\nexport { PROVIDER_DISPLAY_NAMES } from './types';\n\n// ── Base class & config ──────────────────────────────────────────────\nexport { GeneratorAdapter } from './base';\nexport type { AdapterConfig, ClaudeSdkConfig, AnyAdapterConfig, GenerateParams } from './base';\n\n// ── Registry (primary API) ───────────────────────────────────────────\nexport { getAdapter, listAdapters } from './registry';\n\n// ── Tools ────────────────────────────────────────────────────────────\nexport { createGeneratorTools } from './tools';\nexport { zodToJsonSchema } from './tool-bridge';\n\n// ── Concrete adapters (for benchmarks, tests, instanceof checks) ─────\n// WARNING: These static imports pull in provider SDKs. Lambda entry\n// points should NOT import from this barrel — use getAdapter() instead.\nexport { ClaudeRawAdapter } from './claude/raw';\nexport { ClaudeSdkAdapter } from './claude/sdk';\nexport { OpenAiRawAdapter } from './openai/raw';\nexport { OpenAiSdkAdapter } from './openai/sdk';\nexport { GoogleRawAdapter } from './google/raw';\nexport { GoogleSdkAdapter } from './google/sdk';\n","// packages/ui-gen/src/adapters/registry.ts\n//\n// Adapter registry — resolves provider + mode to the correct adapter instance.\n// Uses dynamic imports so per-provider Lambda bundles only include their own SDKs.\n//\n// For Lambda deployments, mark non-Claude SDKs as externalModules in esbuild config\n// so they're only loaded at runtime when the provider is actually requested.\n\nimport type { ProviderName, AdapterMode } from './types';\nimport type { AnyAdapterConfig } from './base';\nimport { GeneratorAdapter } from './base';\n\ntype AdapterFactory = (config: AnyAdapterConfig) => Promise<GeneratorAdapter>;\n\nconst ADAPTER_FACTORIES: Partial<Record<ProviderName, Partial<Record<AdapterMode, AdapterFactory>>>> = {};\n\nfunction registerProvider(provider: ProviderName, factories: Partial<Record<AdapterMode, AdapterFactory>>): void {\n ADAPTER_FACTORIES[provider] = factories;\n}\n\n// Claude\nregisterProvider('claude', {\n raw: async (config) => {\n const { ClaudeRawAdapter } = await import('./claude/raw');\n return new ClaudeRawAdapter(config);\n },\n sdk: async (config) => {\n const { ClaudeSdkAdapter } = await import('./claude/sdk');\n return new ClaudeSdkAdapter(config);\n },\n});\n\n// OpenAI\nregisterProvider('openai', {\n raw: async (config) => {\n const { OpenAiRawAdapter } = await import('./openai/raw');\n return new OpenAiRawAdapter(config);\n },\n sdk: async (config) => {\n const { OpenAiSdkAdapter } = await import('./openai/sdk');\n return new OpenAiSdkAdapter(config);\n },\n});\n\n// Google\nregisterProvider('google', {\n raw: async (config) => {\n const { GoogleRawAdapter } = await import('./google/raw');\n return new GoogleRawAdapter(config);\n },\n sdk: async (config) => {\n const { GoogleSdkAdapter } = await import('./google/sdk');\n return new GoogleSdkAdapter(config);\n },\n});\n\n// OpenRouter (raw only — no Agent SDK)\nregisterProvider('openrouter', {\n raw: async (config) => {\n const { OpenRouterRawAdapter } = await import('./openrouter/raw');\n return new OpenRouterRawAdapter(config);\n },\n});\n\n/**\n * Get an adapter instance for the given provider and mode.\n */\nexport async function getAdapter(\n provider: ProviderName,\n mode: AdapterMode,\n config: AnyAdapterConfig = {},\n): Promise<GeneratorAdapter> {\n const providerFactories = ADAPTER_FACTORIES[provider];\n if (!providerFactories) {\n throw new Error(\n `Unknown provider: ${provider}. Available: ${Object.keys(ADAPTER_FACTORIES).join(', ')}`,\n );\n }\n\n const factory = providerFactories[mode];\n if (!factory) {\n throw new Error(\n `Unknown mode '${mode}' for provider '${provider}'. Available: ${Object.keys(providerFactories).join(', ')}`,\n );\n }\n\n return factory(config);\n}\n\n/**\n * List all registered adapter combinations and their availability.\n */\nexport async function listAdapters(\n config: AnyAdapterConfig = {},\n): Promise<\n Array<{ provider: ProviderName; mode: AdapterMode; available: boolean; displayName: string }>\n> {\n const result: Array<{\n provider: ProviderName;\n mode: AdapterMode;\n available: boolean;\n displayName: string;\n }> = [];\n\n for (const [provider, modes] of Object.entries(ADAPTER_FACTORIES)) {\n for (const mode of Object.keys(modes)) {\n try {\n const factory = ADAPTER_FACTORIES[provider as ProviderName]?.[mode as AdapterMode];\n if (!factory) continue;\n const adapter = await factory(config);\n result.push({\n provider: provider as ProviderName,\n mode: mode as AdapterMode,\n available: adapter.isAvailable(),\n displayName: adapter.displayName,\n });\n } catch {\n result.push({\n provider: provider as ProviderName,\n mode: mode as AdapterMode,\n available: false,\n displayName: `${provider}/${mode} (not installed)`,\n });\n }\n }\n }\n\n return result;\n}\n","/**\n * AUTO-GENERATED from @ggui-ai/design JSDoc.\n * Do not edit manually. Run: pnpm --filter @ggui-ai/design generate:docs\n */\nexport const PRIMITIVES_DOCUMENTATION = \"# ggui Primitives & Design System Reference\\n\\n> You are a world-class UI engineer working with ggui's component library for the first time.\\n> This reference documents every available component, prop, and convention.\\n> Components handle theming automatically via built-in variants — pick the right variant and the theme does the rest.\\n> For custom styling beyond variants, use CSS variables: var(--ggui-*, fallback).\\n\\n## Primitives\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### Container\\n\\nContainer -- Width-constrained wrapper that centers content horizontally.\\n\\nRenders a `<div>` with `width: 100%` and a `maxWidth` constraint.\\nWhen `center` is true (the default), applies `margin: 0 auto`.\\nNo background, border, or shadow -- use Card for visual containment.\\n\\nCSS variables used: none (pure layout primitive).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| maxWidth | `'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| '3xl' \\\\| 'full' \\\\| string` | `'lg'` | Maximum width constraint. Accepts a preset token or any CSS width string. - `'xs'` -- 320px - `'sm'` -- 480px - `'md'` -- 640px - `'lg'` -- 768px - `'xl'` -- 1024px - `'2xl'` -- 1280px - `'3xl'` -- 1536px - `'full'` -- 100% Custom strings (e.g., `'900px'`, `'60ch'`) are passed through as-is. |\\n| center | `boolean` | `true` | Whether to center the container horizontally via `margin: 0 auto`. |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no padding)` | Padding applied to all sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n\\n**Example:**\\n```tsx\\n<Container maxWidth=\\\"xl\\\" padding=\\\"var(--ggui-spacing-6)\\\">\\n <Stack gap=\\\"var(--ggui-spacing-4)\\\">\\n <Heading level={1}>Dashboard</Heading>\\n <Card shadow=\\\"md\\\" padding=\\\"var(--ggui-spacing-5)\\\">\\n <Text>Welcome back!</Text>\\n </Card>\\n </Stack>\\n</Container>\\n```\\n\\n### Card\\n\\nCard -- Container with background, shadow, and optional border.\\n\\nRenders a `<div>` with:\\n- Background: `var(--ggui-color-surface)`\\n- Border (when enabled): `1px solid var(--ggui-color-outlineVariant)`\\n- Shadow and radius controlled by design tokens via CSS variables.\\n- No built-in transitions.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'lg'` | Padding applied to all sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| shadow | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'` | `'sm'` | Shadow elevation level. Maps to design tokens: - `'none'` -- no shadow - `'sm'` -- var(--ggui-shape-shadow-sm, 0 1px 2px 0 rgba(0,0,0,0.05)) -- subtle, default - `'md'` -- var(--ggui-shape-shadow-md, 0 4px 6px -1px rgba(0,0,0,0.1)) -- dialogs, emphasized sections - `'lg'` -- var(--ggui-shape-shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1)) -- floating panels - `'xl'` -- var(--ggui-shape-shadow-xl, 0 20px 25px -5px rgba(0,0,0,0.1)) -- popovers, modals |\\n| border | `boolean` | `true` | Whether to render a 1px border using `var(--ggui-color-outlineVariant)`. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `'lg'` | Corner radius. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| surface | `'default' \\\\| 'elevated' \\\\| 'sunken' \\\\| 'accent' \\\\| 'inverted' \\\\| 'transparent'` | `'default'` | Semantic surface slot. Same vocabulary as ; see that prop's docs for the full slot table. Default Card surface is `'default'` (the active theme's `--ggui-color-surface`); pair with `shadow=\\\"md\\\"\\\\|\\\"lg\\\"` for elevated cards, or use `'inverted'` for a dark testimonial-style card on a light theme. |\\n\\n**Example:**\\n```tsx\\n<Card shadow=\\\"md\\\" padding=\\\"lg\\\" radius=\\\"lg\\\">\\n <Stack gap=\\\"md\\\">\\n <Text size=\\\"sm\\\" weight=\\\"medium\\\">Settings</Text>\\n <Input label=\\\"Name\\\" value={name} onChange={setName} />\\n <Button variant=\\\"primary\\\">Save</Button>\\n </Stack>\\n</Card>\\n```\\n\\n### Stack\\n\\nStack -- Flexbox layout primitive for arranging children along a single axis.\\n\\nRenders a `<div>` with `display: flex`. Default layout is vertical (column).\\nAll flex shorthand values (`align`, `justify`, `wrap`) are abstracted into\\nsemantic prop names.\\n\\nCSS variables used: none (pure layout primitive).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| direction | `'vertical' \\\\| 'horizontal'` | `'vertical'` | Main axis direction. - `'vertical'` -- `flex-direction: column` - `'horizontal'` -- `flex-direction: row` |\\n| gap | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'sm'` | Gap between children. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n| align | `'start' \\\\| 'center' \\\\| 'end' \\\\| 'stretch'` | `'stretch'` | Cross-axis alignment (maps to `align-items`). - `'start'` -- flex-start - `'center'` -- center - `'end'` -- flex-end - `'stretch'` -- stretch (children fill cross-axis) |\\n| justify | `'start' \\\\| 'center' \\\\| 'end' \\\\| 'between' \\\\| 'around' \\\\| 'evenly'` | `'start'` | Main-axis content distribution (maps to `justify-content`). - `'start'` -- flex-start - `'center'` -- center - `'end'` -- flex-end - `'between'` -- space-between - `'around'` -- space-around - `'evenly'` -- space-evenly |\\n| wrap | `boolean` | `false` | Whether children wrap to the next line when they overflow. Maps to `flex-wrap: wrap` when true. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"lg\\\" align=\\\"center\\\">\\n <Heading level={2}>Profile</Heading>\\n <Text>Edit your account details below.</Text>\\n <Stack direction=\\\"horizontal\\\" gap=\\\"sm\\\" justify=\\\"end\\\">\\n <Button variant=\\\"ghost\\\">Cancel</Button>\\n <Button variant=\\\"primary\\\">Save</Button>\\n </Stack>\\n</Stack>\\n```\\n\\n### Grid\\n\\nGrid -- 2-D layout primitive. Arranges children into rows AND\\ncolumns; reach for it when Stack/Row's single-axis flow isn't\\nenough (card galleries, dashboards, stat grids).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| columns | `number \\\\| ResponsiveColumns` | `2` | Column count. Three forms: - a number — that many equal columns at every width (`columns={3}`); - a map — explicit counts per breakpoint (`columns={{ base: 1, md: 3 }}` = 1 column on mobile, 3 from `md`). Use this when the request names exact per-breakpoint counts (\\\"3 per row on desktop, 1 on mobile\\\"). Ignored entirely when `minColumnWidth` is set. |\\n| gap | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `'md'` | Gap between cells. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`); a number is pixels. |\\n| minColumnWidth | `number \\\\| string` | `undefined (use `columns`)` | When set, the grid becomes responsive — it fits as many equal columns as possible, each at least this wide, and `columns` is ignored. A number is treated as pixels. |\\n\\n**Example:**\\n```tsx\\n<Grid columns={3} gap=\\\"md\\\">\\n {items.map((it) => <Card key={it.id}>{it.name}</Card>)}\\n</Grid>\\n```\\n\\n### Skeleton\\n\\nSkeleton -- a pulsing placeholder for content that has not loaded\\nyet. ggui UIs are agent-driven (props arrive late, streams start\\nempty), so a loading frame is the rule — render `Skeleton` instead\\nof a blank screen or a hand-rolled pulsing `<div>`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| variant | `'rect' \\\\| 'text' \\\\| 'circle'` | `'rect'` | Shape preset. - `'rect'` -- a block (default); pair with `width` / `height`. - `'text'` -- a single text line (height ~1em). - `'circle'` -- equal width/height, fully rounded (avatar slot). |\\n| width | `number \\\\| string` | - | Width. A number is pixels. Defaults to `100%` (`2.5rem` for circle). |\\n| height | `number \\\\| string` | - | Height. A number is pixels. Defaults by variant when unset. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `'sm'` | Corner radius. Prefer a radius-scale name. Ignored for `variant=\\\"circle\\\"` (always fully round). |\\n\\n**Example:**\\n```tsx\\n{user === undefined\\n ? <Skeleton variant=\\\"text\\\" width=\\\"40%\\\" />\\n : <Text>{user.name}</Text>}\\n```\\n\\n### Box\\n\\nBox -- Generic container with padding, margin, background, and border-radius.\\n\\nRenders a plain `<div>`. Unlike Card, Box has no default background, shadow,\\nor border -- it is a blank canvas for custom styling. Use it for layout\\nspacing, colored sections, or wrapping arbitrary content.\\n\\nWhen both `paddingX`/`paddingY` and `padding` are provided, the axis-specific\\nprops take precedence and `padding` is ignored.\\n\\nCSS variables used: none (all values are passed through directly).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| padding | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no padding)` | Padding applied to all four sides. Prefer a spacing-scale name (`'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl'`) — each resolves to the matching `--ggui-spacing-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. Ignored when `paddingX` or `paddingY` is set. |\\n| paddingX | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined` | Horizontal (left + right) padding. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . When set alongside `paddingY`, they combine into a shorthand `padding: {Y} {X}`. When set without `paddingY`, vertical padding defaults to 0. |\\n| paddingY | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined` | Vertical (top + bottom) padding. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . When set alongside `paddingX`, they combine into a shorthand `padding: {Y} {X}`. When set without `paddingX`, horizontal padding defaults to 0. |\\n| margin | `'none' \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| number \\\\| string` | `undefined (no margin)` | Margin applied to all four sides. Accepts a spacing-scale name, a pixel number, or a raw CSS string — see . |\\n| surface | `'default' \\\\| 'elevated' \\\\| 'sunken' \\\\| 'accent' \\\\| 'inverted' \\\\| 'transparent'` | `undefined (transparent)` | Semantic surface slot. Picks the right `var(--ggui-color-*)` background token from the active theme. The ONLY way to set a theme-tracking background fill on Box. Available slots: - `'default'` — base container surface (most common) - `'elevated'` — same fill, intended to be paired with shadow (use Card.shadow for actual elevation) - `'sunken'` — recessed / inset region (`surfaceVariant` token) - `'accent'` — highlighted / branded fill (`primary-50` token) - `'inverted'` — dark surface in light mode, light in dark (testimonials, code-snippet cards). Pair with `'inverse'` for legible text. - `'transparent'` — explicit \\\"no fill\\\" For non-theme-mapped brand colors (e.g. a partner's exact brand hex like Stripe purple) use the escape — every other hex / rgba on Box is rejected by tier-0 self-check. |\\n| assetColor | `string` | `undefined` | Asset color escape — the typed valve for legitimate non-theme color values (a partner's exact brand hex, a fixed product surface, etc.). Renders as the Box background. **MUST be paired with .** The semantic name is human-readable documentation of why this color bypasses the theme — e.g. `\\\"stripe-brand-purple\\\"`, `\\\"slack-aubergine\\\"`. Tier-0 self-check allows hex / rgba inside `assetColor` ONLY when `assetSemantic` is a non-empty string; one without the other fails the check. Reach for `surface` first. This escape exists for the small set of cases where the operator's theme MUST NOT override the value (brand identity rendering). |\\n| assetSemantic | `string` | `undefined` | Human-readable semantic label that documents why bypasses the theme. Required when `assetColor` is set; tier-0 self-check rejects empty strings or a missing `assetSemantic` next to a hex `assetColor`. Examples: `\\\"stripe-brand-purple\\\"`, `\\\"slack-aubergine\\\"`, `\\\"partner-logo-orange\\\"`. Pure documentation — no rendering effect. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | `undefined (no rounding)` | Corner radius. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through as a raw CSS value. |\\n\\n**Example:**\\n```tsx\\n<Box paddingX=\\\"xl\\\" paddingY=\\\"lg\\\" surface=\\\"accent\\\" radius=\\\"lg\\\">\\n <Text size=\\\"sm\\\" tone=\\\"emphasized\\\">\\n Tip: You can customize your theme in Settings.\\n </Text>\\n</Box>\\n```\\n\\n### Divider\\n\\nDivider -- A 1px line to visually separate content sections.\\n\\nRenders an `<hr>` (horizontal) or `<div>` (vertical) with `role=\\\"separator\\\"`.\\n- Horizontal: 1px tall, full width, with vertical margin.\\n- Vertical: 1px wide, stretches to parent height via `align-self: stretch`,\\n with horizontal margin. Works best inside a horizontal Stack or Row.\\n\\nDefault color: `var(--ggui-color-outlineVariant)`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Line direction. - `'horizontal'` -- renders `<hr>`, full width, 1px height, margin top/bottom - `'vertical'` -- renders `<div>`, 1px width, `align-self: stretch`, margin left/right |\\n| margin | `number \\\\| string` | `16` | Spacing around the divider. Numbers are treated as pixels. Applied as vertical margin for horizontal dividers, horizontal margin for vertical. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-outlineVariant)`)` | Semantic color slot. Same vocabulary as ; the theme decides what each tone LOOKS like. Defaults to a quiet outline-variant tint when unset (independent of the tone slots). |\\n\\n**Example:**\\n```tsx\\n<Stack gap={0}>\\n <Text>Section A</Text>\\n <Divider margin=\\\"var(--ggui-spacing-3)\\\" />\\n <Text>Section B</Text>\\n</Stack>\\n```\\n\\n### Spacer\\n\\nSpacer -- Invisible spacing element, either fixed-size or flexible.\\n\\nRenders an empty `<div>`.\\n- Fixed mode (number): sets both `width` and `height` to the given pixel\\n value with `flex-shrink: 0`, creating rigid spacing in any direction.\\n- Flex mode (`'flex'`): sets `flex: 1`, expanding to fill remaining space\\n in a flex container. Useful for pushing siblings apart.\\n\\nCSS variables used: none.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| size | `number \\\\| 'flex'` | `16` | Spacing amount. - Number: fixed square spacer (width and height in pixels, `flex-shrink: 0`). - `'flex'`: expands to fill available space (`flex: 1`). |\\n\\n**Example:**\\n```tsx\\n<Stack direction=\\\"horizontal\\\" align=\\\"center\\\">\\n <Heading level={3}>Logo</Heading>\\n <Spacer size=\\\"flex\\\" />\\n <Button variant=\\\"ghost\\\">Login</Button>\\n</Stack>\\n```\\n\\n### Text\\n\\nText -- Versatile typography primitive for body copy, captions, and labels.\\n\\nRenders as `<p>` by default (configurable via `is`). Typography is\\ncomposed from three orthogonal axes: `size` (font size, with a\\nmatching line-height built in), `weight`, and `tone` (semantic\\ncolor). `caps` adds the uppercase, letter-spaced treatment for tiny\\nsection labels (the classic overline/eyebrow look).\\n\\nDefault text color: `var(--ggui-color-onSurface)`.\\nAll text renders with `margin: 0` (no default paragraph spacing).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| size | `'xs' \\\\| 'sm' \\\\| 'base' \\\\| 'lg' \\\\| 'xl' \\\\| '2xl' \\\\| '3xl' \\\\| '4xl'` | `'base'` | Font size. Maps to CSS variables with pixel fallbacks; each size carries a matching line-height (1.5 for `xs`--`base`, 1.625 for `lg`, then tightening on display sizes: 1.375 at `xl`, 1.25 from `2xl` up): - `'xs'` -- var(--ggui-font-size-xs) (12px) - `'sm'` -- var(--ggui-font-size-sm) (14px) - `'base'` -- var(--ggui-font-size-base) (16px) - `'lg'` -- var(--ggui-font-size-lg) (18px) - `'xl'` -- var(--ggui-font-size-xl) (20px) - `'2xl'` -- var(--ggui-font-size-2xl) (24px) - `'3xl'` -- var(--ggui-font-size-3xl) (30px) - `'4xl'` -- var(--ggui-font-size-4xl) (36px) |\\n| weight | `'normal' \\\\| 'medium' \\\\| 'semibold' \\\\| 'bold'` | `'normal'` | Font weight. Maps to CSS variables with numeric fallbacks: - `'normal'` -- var(--ggui-font-weight-normal) - `'medium'` -- var(--ggui-font-weight-medium) - `'semibold'` -- var(--ggui-font-weight-semibold) - `'bold'` -- var(--ggui-font-weight-bold) |\\n| caps | `boolean` | `false` | When true, uppercases the text and adds 0.05em letter-spacing -- the eyebrow/overline treatment for tiny section labels. Pair with `size=\\\"xs\\\" weight=\\\"semibold\\\" tone=\\\"muted\\\"`. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `'default' (var(--ggui-color-onSurface))` | Semantic color slot. Picks the right `var(--ggui-color-*)` token from the active theme. The theme decides what each tone LOOKS like — `'muted'` is a quiet warm grey on Claudic, a cool slate on Indigo, dim cyan on Neon-Noir. Components that use `tone` track the operator's theme switch automatically. Available slots: `'default'` (primary body text), `'muted'` (secondary / metadata), `'subtle'` (very-low-emphasis hint), `'emphasized'` (branded accent), `'loud'` (strongest accent), `'success'` / `'warning'` / `'error'` / `'info'` (status text), `'inverse'` (text on dark surface), `'inherit'` (parent's color). `tone` is the ONLY way to set a Text color. The legacy `color?: string` escape was retired — raw color strings bypass theming and silently override the operator's preset. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | `undefined (inherits from parent)` | Horizontal text alignment. Maps directly to `text-align`. |\\n| truncate | `boolean` | `false` | When true, clips overflowing text with an ellipsis. Applies `overflow: hidden`, `text-overflow: ellipsis`, and `white-space: nowrap`. |\\n| is | `'p' \\\\| 'span' \\\\| 'div' \\\\| 'label'` | `'p'` | HTML element to render. Choose based on semantic context: - `'p'` -- paragraph (default, block-level) - `'span'` -- inline text within a sentence - `'div'` -- generic block container - `'label'` -- form label (pair with `htmlFor`) |\\n| id | `string` | - | `id` for the rendered element — anchor an in-page link, or pair with a form control's `aria-labelledby`. |\\n| htmlFor | `string` | - | Associates an `is=\\\"label\\\"` element with a form control by the control's `id`. Only meaningful when `is=\\\"label\\\"`. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"var(--ggui-spacing-1)\\\">\\n <Text size=\\\"xs\\\" weight=\\\"semibold\\\" caps tone=\\\"muted\\\">Account</Text>\\n <Text size=\\\"lg\\\">Welcome back, Jane.</Text>\\n <Text size=\\\"xs\\\" tone=\\\"muted\\\">\\n Last login: 2 hours ago\\n </Text>\\n</Stack>\\n```\\n\\n### Heading\\n\\nHeading -- Semantic heading element (h1-h6) with preset typography styles.\\n\\nRenders the corresponding `<h1>`-`<h6>` HTML element based on `level`.\\nEach level has a preset font size, weight, line height, and letter spacing\\nfrom the heading typography tokens:\\n- Level 1: 36px / bold / 1.25 line-height / -0.025em tracking\\n- Level 2: 30px / bold / 1.25 line-height / -0.025em tracking\\n- Level 3: 24px / semibold / 1.375 line-height / 0em tracking\\n- Level 4: 20px / semibold / 1.375 line-height / 0em tracking\\n- Level 5: 18px / semibold / 1.5 line-height / 0em tracking\\n- Level 6: 16px / semibold / 1.5 line-height / 0em tracking\\n\\nDefault text color: `var(--ggui-color-onSurface)`.\\nAll headings render with `margin: 0` (no default heading spacing).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| level | `1 \\\\| 2 \\\\| 3 \\\\| 4 \\\\| 5 \\\\| 6` | `2` | Semantic heading level. Determines both the HTML element (`<h1>`-`<h6>`) and the preset typography style. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `'default' (var(--ggui-color-onSurface))` | Semantic color slot. Same vocabulary as ; see that prop's docs for the full slot table. `tone` is the ONLY way to set a Heading color — the legacy `color?: string` escape was retired so the operator's theme always wins. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | `undefined (inherits from parent)` | Horizontal text alignment. Maps directly to `text-align`. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"var(--ggui-spacing-2)\\\">\\n <Heading level={1}>Page Title</Heading>\\n <Heading level={3} tone=\\\"emphasized\\\">\\n Subsection\\n </Heading>\\n <Text>Body content goes here.</Text>\\n</Stack>\\n```\\n\\n### Button\\n\\nButton -- A clickable button primitive with multiple visual variants and sizes.\\n\\nRenders a native `<button>` element styled with inline CSS derived from design-token\\nCSS variables. Supports a loading spinner, left/right icon slots, and a cross-platform\\n`onPress` alias for `onClick`.\\n\\nBase styles applied to every variant:\\n- `border-radius: var(--ggui-shape-radius-md)`\\n- `font-weight: var(--ggui-font-weight-medium)`\\n- `box-shadow: var(--ggui-shape-shadow-sm, 0 1px 2px rgba(0,0,0,0.05))`\\n- `gap: var(--ggui-spacing-2)` between icon and text\\n- Transitions: background-color, box-shadow, opacity at 200ms ease-in-out\\n\\nDisabled or loading: `opacity: 0.5`, `cursor: not-allowed`, click handler suppressed.\\n\\nAlso extends native `ButtonHTMLAttributes` (except `style`/`className`), so props\\nlike `type`, `form`, `aria-*`, and `data-*` are forwarded to the `<button>` element.\\nThe `type` prop defaults to `'button'` (not `'submit'`), preventing accidental form\\nsubmissions.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'primary' \\\\| 'secondary' \\\\| 'outline' \\\\| 'ghost' \\\\| 'danger'` | `'primary'` | Visual style. Maps to CSS variables: - `'primary'` -- `var(--ggui-color-primary-600)` background, white text, no border - `'secondary'` -- `var(--ggui-color-surfaceVariant)` background, `var(--ggui-color-onSurfaceVariant)` text, no border - `'outline'` -- transparent background, `1px solid var(--ggui-color-primary-600)` border, primary-600 text - `'ghost'` -- transparent background, `var(--ggui-color-onSurfaceVariant)` text, no border - `'danger'` -- `var(--ggui-color-error-600)` background, white text, no border |\\n| size | `'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding, font size, and minimum height: - `'xs'` -- padding `4px 8px`, font `var(--ggui-font-size-xs)`, min-height 24px - `'sm'` -- padding `6px 12px`, font `var(--ggui-font-size-sm)`, min-height 32px - `'md'` -- padding `10px 16px`, font `var(--ggui-font-size-sm)`, min-height 40px - `'lg'` -- padding `12px 24px`, font `var(--ggui-font-size-base)`, min-height 48px |\\n| fullWidth | `boolean` | `false` | When true, sets `width: 100%` so the button fills its container. |\\n| loading | `boolean` | `false` | When true, replaces children with a 16px `Spinner` (color: `currentColor`) and disables interaction (same effect as `disabled`). |\\n| leftIcon | `ReactNode` | - | ReactNode rendered before children, inside the flex layout with `var(--ggui-spacing-2)` gap. |\\n| rightIcon | `ReactNode` | - | ReactNode rendered after children, inside the flex layout with `var(--ggui-spacing-2)` gap. |\\n| onPress | `() => void` | - | Alias for `onClick` for cross-platform compatibility (React Native convention). If both `onClick` and `onPress` are provided, `onClick` takes precedence. |\\n\\n**Example:**\\n```tsx\\n<Button variant=\\\"primary\\\" size=\\\"md\\\" leftIcon={<Icon name=\\\"save\\\" />} onClick={handleSave}>\\n Save Changes\\n</Button>\\n```\\n\\n### Input\\n\\nInput -- A single-line text input with label, validation, and helper text.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<input>`,\\nand an optional message `<span>` for error or helper text.\\n\\nStyling:\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Text: `var(--ggui-color-onSurface)`\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Label: `var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`,\\n `var(--ggui-color-onSurfaceVariant)`\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: auto-generated `id` links `<label>` to `<input>` via `htmlFor`.\\nWhen `error` is set, `aria-invalid` is true and the message has `role=\\\"alert\\\"`.\\nWhen `required` is true, a red asterisk is appended to the label.\\n\\nAlso extends native `InputHTMLAttributes` (except `style`, `className`, `onChange`,\\n`size`), so props like `autoFocus`, `name`, `pattern`, `aria-*` are forwarded.\\n\\n**IMPORTANT:** `onChange` receives the string value directly, NOT a React\\n`ChangeEvent`. This differs from native `<input>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the input. Linked to the input via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| placeholder | `string` | - | Placeholder text shown when the input is empty. |\\n| value | `string` | - | Controlled value of the input. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the new string value directly, NOT a React event. |\\n| type | `'text' \\\\| 'email' \\\\| 'password' \\\\| 'number' \\\\| 'tel' \\\\| 'url' \\\\| 'search' \\\\| 'date' \\\\| 'time' \\\\| 'datetime-local'` | `'text'` | HTML input type. Determines browser behavior (keyboard on mobile, validation, masking). The date/time types render the browser's native, localized, keyboard-accessible picker; their `value` stays an ISO string (`'2026-07-29'`, `'14:30'`, `'2026-07-29T14:30'`) delivered through the usual value-first `onChange`. |\\n| error | `string` | - | Error message displayed below the input in `var(--ggui-color-error-500)`. When set, the border turns red and the message element gets `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the input in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute on the `<input>`. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `6px 10px`, font `var(--ggui-font-size-sm)` - `'md'` -- padding `10px 12px`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `12px 14px`, font `var(--ggui-font-size-base)` |\\n\\n**Example:**\\n```tsx\\n<Input label=\\\"Email\\\" type=\\\"email\\\" value={email} onChange={setEmail} error={emailError} />\\n```\\n\\n### TextArea\\n\\nTextArea -- A multiline text input with label, validation, character count, and auto-resize.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<textarea>`,\\nand a footer row with error/helper text on the left and character count on the right.\\n\\nStyling:\\n- Padding: `10px 12px`, font: `var(--ggui-font-size-sm)`, `font-family: inherit`\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Resize: `vertical` by default, `none` when `autoResize` is true\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: same label/error linking pattern as Input (auto-generated ids,\\n`aria-invalid`, `role=\\\"alert\\\"` on error message).\\n\\nAlso extends native `TextareaHTMLAttributes` (except `style`, `className`, `onChange`).\\n\\n**IMPORTANT:** `onChange` receives the string value directly, NOT a React\\n`ChangeEvent`. This differs from native `<textarea>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the textarea. Linked via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| placeholder | `string` | - | Placeholder text shown when the textarea is empty. |\\n| value | `string` | - | Controlled value of the textarea. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the new string value directly, NOT a React event. |\\n| rows | `number` | `4` | Number of visible text rows (native `rows` attribute on `<textarea>`). |\\n| error | `string` | - | Error message displayed below the textarea in `var(--ggui-color-error-500)`. When set, the border turns red and the message element gets `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the textarea in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute on the `<textarea>`. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)`. |\\n| maxLength | `number` | - | Maximum character length (native `maxLength` attribute). Also used as the denominator in the character count display when `showCount` is true. |\\n| showCount | `boolean` | `false` | When true AND `maxLength` is set, displays a `{current}/{max}` character counter in the footer row (right-aligned, `var(--ggui-font-size-xs)`). Has no effect without `maxLength`. |\\n| autoResize | `boolean` | `false` | When true, sets CSS `resize: none` on the textarea. The flag disables manual resizing to signal that external logic handles sizing. The component does NOT auto-adjust height based on content in the current implementation. |\\n\\n**Example:**\\n```tsx\\n<TextArea label=\\\"Bio\\\" value={bio} onChange={setBio} rows={6} maxLength={500} showCount />\\n```\\n\\n### Select\\n\\nSelect -- A native dropdown selection primitive with label and validation.\\n\\nRenders a `<div>` wrapper containing an optional `<label>`, a native `<select>`\\nwith custom styling, and an optional message `<span>`.\\n\\nThe native `<select>` has `appearance: none` with a custom chevron SVG rendered\\nas a `background-image` (right-aligned, 12px, onSurfaceVariant color). Extra right\\npadding (36px) accommodates the chevron.\\n\\nStyling:\\n- Border: `1px solid var(--ggui-color-outline)` (normal),\\n `var(--ggui-color-error-500)` (error)\\n- Background: `var(--ggui-color-surface)` (normal),\\n `var(--ggui-color-surface)` (disabled)\\n- Text: `var(--ggui-color-onSurface)` when a value is selected,\\n `var(--ggui-color-onSurfaceVariant)` when showing placeholder\\n- Border radius: `var(--ggui-shape-radius-md)`\\n- Cursor: `pointer` (normal), `not-allowed` (disabled)\\n- Transitions: border-color, box-shadow at 200ms ease-in-out\\n\\nAccessibility: auto-generated `id` links `<label>` to `<select>`.\\nWhen `error` is set, `aria-invalid` is true and the message has `role=\\\"alert\\\"`.\\n\\nAlso extends native `SelectHTMLAttributes` (except `style`, `className`,\\n`onChange`, `size`).\\n\\n**IMPORTANT:** `onChange` receives the selected value string directly, NOT a\\nReact `ChangeEvent`. This differs from native `<select>` behavior.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the select. Linked via auto-generated `htmlFor`/`id`. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `string` | - | Controlled value. Should match one of the `options[].value` strings. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the selected option's value string directly, NOT a React event. |\\n| options | `SelectOption[]` | - | Array of selectable options. Rendered as native `<option>` elements. Must contain at least one option (or use `placeholder` for an empty-state prompt). |\\n| placeholder | `string` | - | Placeholder text rendered as a disabled `<option value=\\\"\\\">` at the top of the list. Shown when no value is selected. |\\n| error | `string` | - | Error message displayed below the select in `var(--ggui-color-error-500)`. When set, the border turns red and the message has `role=\\\"alert\\\"`. Takes precedence over `helperText`. |\\n| helperText | `string` | - | Helper text displayed below the select in `var(--ggui-color-onSurfaceVariant)`. Only shown when `error` is not set. |\\n| required | `boolean` | `false` | When true, appends a red asterisk (`*`) to the label and sets the native `required` attribute. |\\n| disabled | `boolean` | `false` | When true, sets the native `disabled` attribute. Background changes to `var(--ggui-color-surface)` and cursor becomes `not-allowed`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `6px 10px`, font `var(--ggui-font-size-sm)` - `'md'` -- padding `10px 12px`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `12px 14px`, font `var(--ggui-font-size-base)` |\\n\\n**Example:**\\n```tsx\\n<Select\\n label=\\\"Country\\\"\\n value={country}\\n onChange={setCountry}\\n options={[\\n { value: 'us', label: 'United States' },\\n { value: 'uk', label: 'United Kingdom' },\\n ]}\\n placeholder=\\\"Select a country\\\"\\n/>\\n```\\n\\n### Checkbox\\n\\nCheckbox -- A custom-styled checkbox with label and description.\\n\\nRenders a `<label>` wrapper containing a visually-hidden native `<input type=\\\"checkbox\\\">`\\noverlaid by a custom 18x18px visual box. Supports checked, unchecked, and indeterminate\\nstates, each with a distinct SVG icon (checkmark or horizontal dash).\\n\\nStyling:\\n- Box border: `2px solid var(--ggui-color-primary-600)` (checked/indeterminate),\\n `var(--ggui-color-outline)` (unchecked)\\n- Box fill: `var(--ggui-color-primary-600)` (checked/indeterminate),\\n `var(--ggui-color-surface)` (unchecked)\\n- Check/dash icon: white SVG, 12x12px\\n- Box radius: `var(--ggui-shape-radius-sm)`\\n- Transition: all 0.2s\\n- Label: `var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`\\n- Description: `var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`\\n- Disabled: `opacity: 0.5`, `cursor: not-allowed`\\n- Gap between box and text: `var(--ggui-spacing-2)`\\n\\n**IMPORTANT:** `onChange` receives the boolean checked state directly, NOT a\\nReact `ChangeEvent`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Primary label text rendered beside the checkbox box. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| checked | `boolean` | - | Controlled checked state. |\\n| onChange | `(checked: boolean) => void` | - | Change handler. Receives the new boolean checked state directly, NOT a React event. |\\n| disabled | `boolean` | `false` | When true, sets `opacity: 0.5` and `cursor: not-allowed`. The native input is also disabled, preventing keyboard and click interaction. |\\n| description | `string` | - | Secondary description text rendered below the label in smaller, muted type (`var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`). |\\n| indeterminate | `boolean` | `false` | When true, displays a horizontal dash instead of a checkmark. Used for \\\"select all\\\" states where some (but not all) children are checked. The `indeterminate` property is set via a ref on the native `<input>`. Visually identical to `checked` in terms of border and fill color. |\\n\\n**Example:**\\n```tsx\\n<Checkbox\\n label=\\\"Accept terms\\\"\\n description=\\\"You agree to the Terms of Service and Privacy Policy\\\"\\n checked={accepted}\\n onChange={setAccepted}\\n/>\\n```\\n\\n### Toggle\\n\\nToggle -- A switch/toggle input rendered as a pill-shaped track with a sliding knob.\\n\\nRenders a `<label>` wrapper with a `<div role=\\\"switch\\\">` track and an animated\\ncircular knob. Does NOT use a native `<input>` -- keyboard interaction is handled\\nmanually (Space and Enter keys toggle the state). The element is focusable via\\n`tabIndex={0}` and shows a focus ring on focus.\\n\\nStyling:\\n- Track (on): `var(--ggui-color-primary-600)`\\n- Track (off): `var(--ggui-color-outline)`\\n- Knob: white circle with `var(--ggui-shape-shadow-sm)`\\n- Focus ring: `0 0 0 3px var(--ggui-color-primary-200)`\\n- Transitions: background-color, box-shadow, knob position at 200ms ease-in-out\\n- Disabled: `opacity: 0.5`, `cursor: not-allowed`, `tabIndex: -1`\\n- Gap between toggle and label: `var(--ggui-spacing-2)`\\n\\n**IMPORTANT:** `onChange` receives the new boolean state directly (inverted from\\ncurrent), NOT a React event.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label text rendered to the right of the toggle track. Also used as `aria-label` on the switch element. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| checked | `boolean` | - | Controlled checked (on/off) state. |\\n| onChange | `(checked: boolean) => void` | - | Change handler. Receives the new boolean state directly (i.e., `!checked`), NOT a React event. |\\n| disabled | `boolean` | `false` | When true, sets `opacity: 0.5`, `cursor: not-allowed`, and removes the element from tab order (`tabIndex: -1`). Click and keyboard handlers are suppressed. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls track and knob dimensions: - `'sm'` -- track 36x20px, knob 16px diameter - `'md'` -- track 44x24px, knob 20px diameter - `'lg'` -- track 52x28px, knob 24px diameter |\\n\\n**Example:**\\n```tsx\\n<Toggle label=\\\"Enable notifications\\\" checked={enabled} onChange={setEnabled} size=\\\"md\\\" />\\n```\\n\\n### RadioGroup\\n\\nRadioGroup -- A group of mutually exclusive radio options with optional label and error.\\n\\nRenders a `<div role=\\\"radiogroup\\\">` containing a label span, a flex container of\\nradio options, and an optional error message. Each option is a `<label>` with a\\nvisually-hidden native `<input type=\\\"radio\\\">` and a custom 18px circle indicator.\\n\\nStyling:\\n- Selected circle: `2px solid var(--ggui-color-primary-600)` border with\\n an 8px `var(--ggui-color-primary-600)` filled inner dot\\n- Unselected circle: `2px solid var(--ggui-color-outline)` border,\\n `var(--ggui-color-surface)` fill\\n- Circle radius: `var(--ggui-shape-radius-full)`\\n- Transition: all 0.2s\\n- Vertical gap: `var(--ggui-spacing-2)`, horizontal gap: `var(--ggui-spacing-4)`\\n- Error: `var(--ggui-font-size-xs)`, `var(--ggui-color-error-500)`,\\n `role=\\\"alert\\\"`\\n- Disabled options: `opacity: 0.5`, `cursor: not-allowed`\\n\\nAccessibility: the group has `role=\\\"radiogroup\\\"` with `aria-labelledby` pointing\\nto the label and `aria-describedby` pointing to the error message (when present).\\nAll radio inputs share a common auto-generated `name` attribute.\\n\\n**IMPORTANT:** `onChange` receives the selected option's value string directly,\\nNOT a React `ChangeEvent`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Group label rendered above the options. Used as `aria-labelledby` target on the `role=\\\"radiogroup\\\"` container. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `string` | - | Controlled value. Should match one of `options[].value`. |\\n| onChange | `(value: string) => void` | - | Change handler. Receives the newly selected option's value string directly, NOT a React event. |\\n| options | `RadioOption[]` | - | Array of radio options. Must contain at least two options for meaningful selection. |\\n| direction | `'vertical' \\\\| 'horizontal'` | `'vertical'` | Layout direction for the options container: - `'vertical'` -- column layout, `var(--ggui-spacing-2)` gap - `'horizontal'` -- row layout with `flex-wrap: wrap`, `var(--ggui-spacing-4)` gap |\\n| disabled | `boolean` | `false` | When true, disables ALL options (individual `RadioOption.disabled` is additive). Each option gets `opacity: 0.5` and `cursor: not-allowed`. |\\n| error | `string` | - | Error message displayed below all options in `var(--ggui-color-error-500)` with `role=\\\"alert\\\"`. Linked to the radiogroup via `aria-describedby`. |\\n\\n**Example:**\\n```tsx\\n<RadioGroup\\n label=\\\"Plan\\\"\\n value={plan}\\n onChange={setPlan}\\n options={[\\n { value: 'free', label: 'Free', description: 'Up to 5 projects' },\\n { value: 'pro', label: 'Pro', description: 'Unlimited projects' },\\n ]}\\n/>\\n```\\n\\n### Slider\\n\\nSlider -- A range input with a custom-styled track, fill, and thumb.\\n\\nRenders a `<div>` wrapper containing an optional label/value header, and a\\ntrack area with three layers: background track, colored fill, and a circular\\nthumb. A native `<input type=\\\"range\\\">` is overlaid with `opacity: 0` to\\nprovide accessible keyboard and pointer interaction.\\n\\nStyling:\\n- Track: 6px tall, `var(--ggui-color-outlineVariant)` background, `border-radius: 3px`\\n- Fill: `var(--ggui-color-primary-600)` (normal),\\n `var(--ggui-color-outline)` (disabled)\\n- Thumb: 20px white circle with `2px solid var(--ggui-color-primary-600)`,\\n `var(--ggui-shape-shadow-sm)`; disabled border uses outline\\n- Value display (when `showValue`): `var(--ggui-color-primary-600)`,\\n `var(--ggui-font-size-sm)`, right-aligned in the header row\\n- Fill and thumb transitions: 0.1s for smooth dragging\\n\\nAccessibility: the native `<input type=\\\"range\\\">` carries `aria-valuenow`,\\n`aria-valuemin`, `aria-valuemax`, and is linked to the label via `aria-labelledby`.\\nFalls back to `aria-label=\\\"Slider\\\"` when no label is provided.\\n\\n**IMPORTANT:** `onChange` receives the numeric value directly, NOT a React\\n`ChangeEvent`. The value is coerced via `Number(e.target.value)`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Label rendered above the slider track (left-aligned). Used as `aria-labelledby` target on the native range input. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| value | `number` | `0` | Controlled numeric value. Must be between `min` and `max`. |\\n| onChange | `(value: number) => void` | - | Change handler. Receives the new numeric value directly, NOT a React event. |\\n| min | `number` | `0` | Minimum allowed value. |\\n| max | `number` | `100` | Maximum allowed value. |\\n| step | `number` | `1` | Step increment for the slider. Determines the granularity of selectable values. |\\n| disabled | `boolean` | `false` | When true, sets `cursor: not-allowed` on the native input. The fill color changes to `var(--ggui-color-outline)` and the thumb border also uses outline. |\\n| showValue | `boolean` | `false` | When true, displays the current numeric value right-aligned in the header row (beside the label) in `var(--ggui-color-primary-600)`. |\\n\\n**Example:**\\n```tsx\\n<Slider label=\\\"Volume\\\" value={volume} onChange={setVolume} min={0} max={100} step={5} showValue />\\n```\\n\\n### Badge\\n\\nBadge -- Inline label for status indicators, counts, or categories.\\n\\nRenders a `<span>` with `display: inline-flex`, centered content, and\\n`white-space: nowrap`. Semantic variant colors use background/text pairings\\nfrom the 100/700 color scale. Pill shape uses `border-radius: 9999px`;\\nnon-pill uses `var(--ggui-shape-radius-sm)`.\\n\\nFont weight: `var(--ggui-font-weight-medium)` across all variants.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'default' \\\\| 'primary' \\\\| 'secondary' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info'` | `'default'` | Visual style. Maps to background/text color pairings: - `'default'` -- bg `var(--ggui-color-surfaceVariant)`, text `var(--ggui-color-onSurfaceVariant)` - `'primary'` -- bg `var(--ggui-color-primary-100)`, text `var(--ggui-color-primary-700)` - `'secondary'` -- bg `var(--ggui-color-outlineVariant)`, text `var(--ggui-color-onSurface)` - `'success'` -- bg `var(--ggui-color-success-100)`, text `var(--ggui-color-success-700)` - `'warning'` -- bg `var(--ggui-color-warning-100)`, text `var(--ggui-color-warning-700)` - `'error'` -- bg `var(--ggui-color-error-100)`, text `var(--ggui-color-error-700)` - `'info'` -- bg `var(--ggui-color-info-100)`, text `var(--ggui-color-info-700)` |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding and font size: - `'sm'` -- padding `2px 6px`, font `var(--ggui-font-size-xs)` - `'md'` -- padding `2px 8px`, font `var(--ggui-font-size-xs)` - `'lg'` -- padding `4px 10px`, font `var(--ggui-font-size-sm)` |\\n| pill | `boolean` | `true` | When true, uses fully rounded corners (`border-radius: 9999px`). When false, uses `var(--ggui-shape-radius-sm)`. |\\n\\n**Example:**\\n```tsx\\n<Badge variant=\\\"success\\\" size=\\\"sm\\\">Active</Badge>\\n```\\n\\n### Spinner\\n\\nSpinner -- Animated SVG loading indicator.\\n\\nRenders an `<svg>` with `role=\\\"status\\\"` and `aria-label=\\\"Loading\\\"`.\\nThe SVG contains a full outlineVariant background circle and a quarter-arc\\nforeground stroke in the spinner color.\\n\\nAnimation: `ggui-spin 1s linear infinite` (360-degree rotation).\\nThe `@keyframes ggui-spin` definition is injected inline via a `<style>` tag.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| size | `number` | `24` | Width and height of the SVG element in pixels. The internal viewBox is always `0 0 24 24`, so this controls rendered size only. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-primary-600)`)` | Semantic color slot for the animated foreground arc. Same vocabulary as ; the theme decides the resolved value. The background circle always uses `var(--ggui-color-outlineVariant)`. Use `'inherit'` when the spinner sits inside a colored container (e.g. inside a Button) — the stroke picks up `currentColor` from the parent so it tracks the container's foreground. |\\n\\n**Example:**\\n```tsx\\n<Spinner size={32} tone=\\\"success\\\" />\\n```\\n\\n### Avatar\\n\\nAvatar -- User or entity representation with image or auto-generated initials.\\n\\nRenders a `<div role=\\\"img\\\">` with `overflow: hidden` and `flex-shrink: 0`.\\nWhen `src` is provided and loads successfully, renders an `<img>` with\\n`object-fit: cover`. On image error (or when no `src`), falls back to\\ninitials derived from `name` (up to 2 characters, uppercase).\\n\\nInitials background: deterministic color from a 5-color palette based on\\nname hash (primary-500, success-500, warning-500, error-500, info-500).\\nFalls back to `var(--ggui-color-outline)` when no name is given.\\nInitials text: white, `font-weight: var(--ggui-font-weight-semibold)`,\\n`font-size: resolvedSize * 0.4`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| src | `string` | - | Image URL. When provided and the image loads, it is rendered with `object-fit: cover`. On load error, falls back to initials. |\\n| name | `string` | - | Name used for two purposes: 1. Generating initials (splits on spaces, takes first letter of each word, max 2). 2. Deterministic background color selection via character code hash. Also used as `aria-label` on the container. Falls back to `'Avatar'` if omitted. |\\n| size | `number \\\\| 'xs' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'` | `'md'` | Avatar dimensions. Named sizes map to pixel values: - `'xs'` -- 24px - `'sm'` -- 32px - `'md'` -- 40px - `'lg'` -- 48px - `'xl'` -- 64px Numeric values are used directly as pixel dimensions. |\\n| shape | `'circle' \\\\| 'square'` | `'circle'` | Container shape. - `'circle'` -- `border-radius: 50%` - `'square'` -- `border-radius: var(--ggui-shape-radius-md)` |\\n\\n**Example:**\\n```tsx\\n<Avatar src=\\\"/photos/jane.jpg\\\" name=\\\"Jane Doe\\\" size=\\\"lg\\\" shape=\\\"circle\\\" />\\n```\\n\\n### Alert\\n\\nAlert -- Contextual message box for important information with icon and optional dismiss.\\n\\nRenders a `<div role=\\\"alert\\\">` with flex layout (12px gap), variant-specific\\nbackground, border, text color, and a leading icon. Each variant provides a\\ndefault SVG icon (info circle, checkmark, warning triangle, or X circle) that\\ncan be overridden via the `icon` prop.\\n\\nLayout: icon (flex-shrink: 0) | content column (title + body) | close button.\\nBorder radius: `var(--ggui-shape-radius-lg)`.\\nPadding: `12px 16px`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| variant | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'info'` | Visual style. Maps to background/border/text/icon color sets: - `'info'` -- bg `var(--ggui-color-info-50)`, border `var(--ggui-color-info-200)`, text `var(--ggui-color-info-800)`, icon `var(--ggui-color-info-500)` - `'success'` -- bg `var(--ggui-color-success-50)`, border `var(--ggui-color-success-200)`, text `var(--ggui-color-success-800)`, icon `var(--ggui-color-success-500)` - `'warning'` -- bg `var(--ggui-color-warning-50)`, border `var(--ggui-color-warning-200)`, text `var(--ggui-color-warning-800)`, icon `var(--ggui-color-warning-500)` - `'error'` -- bg `var(--ggui-color-error-50)`, border `var(--ggui-color-error-200)`, text `var(--ggui-color-error-800)`, icon `var(--ggui-color-error-500)` |\\n| title | `string` | - | Optional title rendered above the body in semibold (`var(--ggui-font-weight-semibold)`), `var(--ggui-font-size-sm)`. Title and body are separated by `var(--ggui-spacing-1)` gap. |\\n| closable | `boolean` | `false` | When true, renders a close button (X icon) in the top-right area. The button has `min-width: 28px`, `min-height: 28px`, and `opacity: 0.7`. Requires `onClose` to be functional. |\\n| onClose | `() => void` | - | Callback fired when the close button is clicked. Only relevant when `closable` is true. |\\n| icon | `ReactNode` | - | Custom icon ReactNode to replace the default variant icon. Rendered at the leading position with the variant's icon color applied via `color` CSS property. |\\n\\n**Example:**\\n```tsx\\n<Alert variant=\\\"warning\\\" title=\\\"Rate limit\\\" closable onClose={() => setShow(false)}>\\n You have 3 requests remaining this minute.\\n</Alert>\\n```\\n\\n### Progress\\n\\nProgress -- Horizontal progress bar with determinate and indeterminate modes.\\n\\nRenders a track `<div role=\\\"progressbar\\\">` with a colored fill child.\\nThe track background is `var(--ggui-color-outlineVariant)` with\\npill-shaped corners (border-radius = height / 2).\\n\\nDeterminate mode: fill width transitions smoothly (`width 0.3s ease`).\\nIndeterminate mode: fill is 30% width, animated with\\n`ggui-progress-indeterminate 1.5s ease-in-out infinite`\\n(translateX from -100% to 400%). The `@keyframes` are injected inline.\\n\\nAccessibility: `aria-valuenow` is set in determinate mode, omitted in\\nindeterminate. `aria-valuemin` is always 0, `aria-valuemax` matches `max`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `number` | - | Current progress value. Clamped to `[0, max]` and converted to a percentage for the fill width: `Math.min(100, Math.max(0, (value / max) * 100))`. |\\n| max | `number` | `100` | Maximum value representing 100% progress. |\\n| variant | `'default' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'default'` | Fill bar color. Maps to CSS variables: - `'default'` -- `var(--ggui-color-primary-600)` - `'success'` -- `var(--ggui-color-success-500)` - `'warning'` -- `var(--ggui-color-warning-500)` - `'error'` -- `var(--ggui-color-error-500)` |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls track height in pixels: - `'sm'` -- 4px - `'md'` -- 8px - `'lg'` -- 12px |\\n| label | `string` | - | Accessible name describing what this bar measures, e.g. `\\\"Survey progress\\\"` or `\\\"Upload\\\"`. Becomes the progressbar's `aria-label` and — when `showLabel` is set — the visible header text in place of the generic word \\\"Progress\\\". Always pass this when the surrounding context does not already make the meaning obvious. |\\n| showLabel | `boolean` | `false` | When true, displays a header row above the track with the `label` text (or \\\"Progress\\\" if `label` is unset) on the left, and the rounded percentage value on the right. |\\n| indeterminate | `boolean` | `false` | When true, ignores `value` for visual width and plays a looping animation instead. The fill bar is 30% width and slides across the track. Animation: `ggui-progress-indeterminate 1.5s ease-in-out infinite`. `aria-valuenow` is omitted from the progressbar element. |\\n\\n**Example:**\\n```tsx\\n<Progress value={65} variant=\\\"success\\\" size=\\\"md\\\" showLabel />\\n```\\n\\n### Image\\n\\nImage -- An `<img>` element with built-in error handling and fallback support.\\n\\nRenders a native `<img>` with `display: block`. On load error, either renders\\nthe `fallback` ReactNode (if provided) or a default placeholder `<div>` with a\\nsurfaceVariant background and a centered image SVG icon in outline.\\n\\nSize values: numbers are treated as pixels, strings are passed through as-is.\\nWhen no `width` is set, defaults to `100%`. When no `height` is set, defaults\\nto `auto`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| src | `string` | - | Image source URL. Load failure triggers the fallback state. |\\n| alt | `string` | - | Alt text for the image. Used as `aria-label` in the error placeholder too. |\\n| width | `number \\\\| string` | `'100%' (applied at render time, not on the type)` | Image width. Numbers are pixels, strings are CSS values (e.g., `'100%'`, `'50vw'`). |\\n| height | `number \\\\| string` | `'auto' (applied at render time, not on the type)` | Image height. Numbers are pixels, strings are CSS values. |\\n| objectFit | `'cover' \\\\| 'contain' \\\\| 'fill' \\\\| 'none' \\\\| 'scale-down'` | `'cover'` | CSS `object-fit` value controlling how the image fills its box. |\\n| radius | `'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| number \\\\| string` | - | Corner radius applied to both the image and the error placeholder. Prefer a radius-scale name (`'none' \\\\| 'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl'`) — each resolves to the matching `--ggui-shape-radius-*` token. A number is treated as pixels; any other string is passed through. |\\n| fallback | `ReactNode` | - | Custom ReactNode rendered when the image fails to load. When provided, completely replaces the default error placeholder (no wrapper div). When omitted, a surfaceVariant background div with an image icon is shown. |\\n\\n**Example:**\\n```tsx\\n<Image src=\\\"/hero.jpg\\\" alt=\\\"Hero banner\\\" width=\\\"100%\\\" height={400} objectFit=\\\"cover\\\" radius=\\\"md\\\" />\\n```\\n\\n### Icon\\n\\nIcon -- 185 Lucide icons + emoji passthrough.\\n\\nThree resolution layers:\\n1. **Lucide icon:** pass any common Lucide icon name (e.g. `sun`, `cloud-rain`, `heart`, `shopping-cart`).\\n Accepts kebab-case, camelCase, or PascalCase. Renders as stroke SVG.\\n2. **Emoji:** pass emoji/unicode directly (e.g. `☀️`, `🌧️`). Rendered as text.\\n3. **Custom SVG:** pass children (`<svg>` element) for full control.\\n\\nContainer: `<span>` with `display: inline-flex`, centered content.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| name | `string` | - | Lucide icon name (kebab-case, camelCase, or PascalCase all work). Also accepts emoji/unicode characters directly. |\\n| size | `number` | `24` | Icon dimensions in pixels (applied to both width and height of the wrapper and the inner SVG element). |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (icon uses `currentColor`)` | Semantic color slot. Same vocabulary as ; the theme decides what each tone LOOKS like. Resolves to a CSS `color` on the wrapper which the inner SVG inherits via `currentColor`. Use `'inherit'` (the default behavior when unset) for icons that should pick up the parent's foreground color. |\\n| children | `ReactNode` | - | Custom SVG children. When provided, `name` is ignored and children are rendered inside a sized `<span>` wrapper. |\\n| 'aria-label' | `string` | - | Accessible name for a standalone, meaning-bearing icon. When set, the icon exposes `role=\\\"img\\\"` + this label. When omitted (the default) the icon is decorative and hidden from screen readers (`aria-hidden`) — the right choice for an icon next to a text label. |\\n\\n**Example:**\\n```tsx\\n<Icon name=\\\"search\\\" size={20} tone=\\\"muted\\\" />\\n<Icon name=\\\"cloud-rain\\\" size={32} />\\n<Icon name=\\\"☀️\\\" size={24} />\\n```\\n\\n### Link\\n\\nLink -- Styled anchor element with external link support.\\n\\nRenders a native `<a>` element. When `external` is true, sets\\n`target=\\\"_blank\\\"` and `rel=\\\"noopener noreferrer\\\"`, and appends a small\\n(12px) external-link SVG icon after the children.\\n\\nTransition: `color 0.2s`.\\nUnderline behavior is controlled via mouseEnter/mouseLeave event handlers\\n(for the `'hover'` mode).\\n\\nAlso extends native `AnchorHTMLAttributes` (except `style`/`className`),\\nso props like `aria-*`, `data-*`, `title`, etc. are forwarded to the `<a>`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | children |\\n| href | `string` | - | Destination URL. Passed directly to the `<a href>` attribute. |\\n| external | `boolean` | `false` | When true, opens link in a new tab (`target=\\\"_blank\\\"`, `rel=\\\"noopener noreferrer\\\"`) and appends a 12px external-link icon after children. |\\n| tone | `\\\\| 'default' \\\\| 'muted' \\\\| 'subtle' \\\\| 'emphasized' \\\\| 'loud' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info' \\\\| 'inverse' \\\\| 'inherit'` | `undefined (uses `var(--ggui-color-primary-600)`)` | Semantic color slot for the link text. Same vocabulary as ; the theme decides what each tone LOOKS like. Defaults to a primary-tinted accent (`'loud'`-ish) when unset. |\\n| underline | `'always' \\\\| 'hover' \\\\| 'none'` | `'hover'` | Underline behavior: - `'always'` -- `text-decoration: underline` at all times - `'hover'` -- underline appears on mouse enter, removed on mouse leave - `'none'` -- no underline ever |\\n\\n**Example:**\\n```tsx\\n<Link href=\\\"https://docs.ggui.ai\\\" external>Documentation</Link>\\n```\\n\\n### Tooltip\\n\\nTooltip -- Hoverable information popup positioned relative to a trigger element.\\n\\nWraps `children` in a `<div>` trigger (display: inline-block) and renders\\na fixed-position tooltip `<div role=\\\"tooltip\\\">` when visible.\\n\\nTooltip appearance:\\n- Background: `var(--ggui-color-onSurface)`\\n- Text: white, `var(--ggui-font-size-xs)`\\n- Padding: `6px 10px`, border-radius: `var(--ggui-shape-radius-md)`\\n- Max width: 200px, `white-space: nowrap`, `pointer-events: none`\\n- Z-index: `zIndex.tooltip` (1800)\\n\\nShow/hide: triggered by mouseEnter/mouseLeave AND focus/blur on the\\ntrigger element. Uses `position: fixed` with coordinates calculated from\\n`getBoundingClientRect()` and an 8px offset from the trigger edge.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Trigger element. Wrapped in a `<div>` with mouseEnter/mouseLeave and focus/blur handlers. |\\n| content | `ReactNode` | - | Tooltip content. Can be text or any ReactNode. |\\n| position | `'top' \\\\| 'bottom' \\\\| 'left' \\\\| 'right'` | `'top'` | Tooltip placement relative to the trigger element: - `'top'` -- above, centered horizontally, transformed `translateX(-50%) translateY(-100%)` - `'bottom'` -- below, centered horizontally, transformed `translateX(-50%)` - `'left'` -- to the left, centered vertically, transformed `translateX(-100%) translateY(-50%)` - `'right'` -- to the right, centered vertically, transformed `translateY(-50%)` |\\n| delay | `number` | `200` | Delay in milliseconds before the tooltip becomes visible after hover/focus. Hiding is immediate (no delay). |\\n\\n**Example:**\\n```tsx\\n<Tooltip content=\\\"Copy to clipboard\\\" position=\\\"top\\\">\\n <Button variant=\\\"ghost\\\"><Icon name=\\\"copy\\\" /></Button>\\n</Tooltip>\\n```\\n\\n### Table\\n\\nTable -- Data table with sortable columns, striped rows, and hover highlights.\\n\\nRenders a scrollable wrapper `<div>` containing a native `<table>` with\\n`border-collapse: collapse` and `width: 100%`. The wrapper has\\n`overflow-x: auto` for horizontal scrolling on narrow viewports.\\n\\nHeader row: 2px bottom border (`var(--ggui-color-outlineVariant)`).\\nData rows: 1px bottom border (`var(--ggui-color-surfaceVariant)`).\\nHover: `var(--ggui-color-surface)` background with 150ms ease transition.\\nStriped: alternating rows (odd index) get `var(--ggui-color-surface)`.\\n\\nSort behavior: clicking a sortable column header calls `onSort(key, direction)`.\\nIf the same column is clicked again while ascending, it toggles to descending.\\nThe component does NOT sort data internally -- the parent must sort `data` and\\npass updated `sortKey`/`sortDirection`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| columns | `TableColumn<T>[]` | - | Array of column definitions controlling header labels, data keys, and rendering. |\\n| data | `T[]` | - | Array of row data objects. Each object's keys should match the column `key` values. |\\n| sortKey | `string` | - | The `key` of the currently sorted column. Used to highlight the active sort indicator and determine toggle direction on next click. |\\n| sortDirection | `SortDirection` | `'asc'` | Current sort direction for the column identified by `sortKey`. Controls which triangle indicator is highlighted in the header. |\\n| onSort | `(key: string, direction: SortDirection) => void` | - | Sort change handler. Called when a sortable column header is clicked. Receives the column `key` and the new `SortDirection`. The component does NOT sort data internally -- you must sort `data` in your state and pass updated `sortKey`/`sortDirection`. |\\n| striped | `boolean` | `false` | When true, alternating rows (odd index) get a `var(--ggui-color-surface)` background. |\\n| hoverable | `boolean` | `true` | When true, rows highlight with `var(--ggui-color-surface)` on mouse enter, with a 150ms ease background-color transition. |\\n| compact | `boolean` | `false` | When true, reduces cell padding: - Compact: `var(--ggui-spacing-1) var(--ggui-spacing-2)` - Normal: `var(--ggui-spacing-2) var(--ggui-spacing-4)` |\\n| bordered | `boolean` | `false` | When true, adds a 1px border around the table wrapper and between cells. Wrapper border: `1px solid var(--ggui-color-outlineVariant)`. Cell borders: `1px solid var(--ggui-color-surfaceVariant)`. Wrapper border-radius: `var(--ggui-shape-radius-lg)`. |\\n| caption | `string` | - | Accessible table caption. Rendered as a `<caption>` element with `caption-side: top`, `var(--ggui-font-size-sm)`, `var(--ggui-color-onSurfaceVariant)`. |\\n\\n**Example:**\\n```tsx\\n<Table\\n columns={[\\n { key: 'name', header: 'Name', sortable: true },\\n { key: 'role', header: 'Role' },\\n { key: 'status', header: 'Status', render: (v) => <Badge variant={v as string}>{v as string}</Badge> },\\n ]}\\n data={users}\\n sortKey={sortKey}\\n sortDirection={sortDir}\\n onSort={(key, dir) => { setSortKey(key); setSortDir(dir); }}\\n striped\\n/>\\n```\\n\\n### Tabs\\n\\nTabs -- Accessible tab navigation with panels and keyboard support.\\n\\nRenders a `<div role=\\\"tablist\\\">` with `<button role=\\\"tab\\\">` elements and a\\n`<div role=\\\"tabpanel\\\">` for the active tab's content. Supports controlled\\n(`activeKey` + `onChange`) and uncontrolled (internal state) modes.\\n\\nKeyboard navigation: ArrowLeft/ArrowRight (and ArrowUp/ArrowDown) cycle\\nthrough enabled tabs. Home/End jump to first/last. Focus follows selection.\\nDisabled tabs are skipped during keyboard navigation.\\n\\n**IMPORTANT:** `onChange` receives the tab's `key` string directly, NOT a\\nReact event.\\n\\nTab panel padding: `var(--ggui-spacing-4) 0` (top/bottom only).\\nTransitions: color, background-color, border-color at 200ms ease-in-out.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `TabItem[]` | - | Array of tab definitions. Must contain at least one item. |\\n| activeKey | `string` | - | Controlled active tab key. When provided, the component is controlled and will not manage its own state. Must match one of `items[].key`. When omitted, defaults to the first item's key (uncontrolled mode). |\\n| onChange | `(key: string) => void` | - | Tab change handler. Receives the selected tab's `key` string directly, NOT a React event. In controlled mode, you must update `activeKey` in response to this callback. |\\n| variant | `'line' \\\\| 'pills' \\\\| 'enclosed'` | `'line'` | Visual style of the tab bar: - `'line'` -- underline indicator (2px solid primary-600 on active), border-bottom on tab list - `'pills'` -- filled pill buttons (primary-600 bg, white text on active), surfaceVariant container with radius-lg - `'enclosed'` -- bordered tab buttons with open bottom (card-style), border-bottom on tab list |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls tab button padding and font size: - `'sm'` -- padding `var(--ggui-spacing-1) var(--ggui-spacing-2)`, font `var(--ggui-font-size-xs)` - `'md'` -- padding `var(--ggui-spacing-2) var(--ggui-spacing-4)`, font `var(--ggui-font-size-sm)` - `'lg'` -- padding `var(--ggui-spacing-4) var(--ggui-spacing-6)`, font `var(--ggui-font-size-base)` |\\n| fullWidth | `boolean` | `false` | When true, tab buttons expand equally to fill the container width (`flex: 1`, `justify-content: center` on each button). |\\n\\n**Example:**\\n```tsx\\n<Tabs\\n variant=\\\"pills\\\"\\n items={[\\n { key: 'overview', label: 'Overview', content: <Overview /> },\\n { key: 'settings', label: 'Settings', content: <Settings /> },\\n ]}\\n activeKey={tab}\\n onChange={setTab}\\n/>\\n```\\n\\n### Toast\\n\\nToast -- Notification banner with auto-dismiss and slide-in animation.\\n\\nRenders a `<div role=\\\"alert\\\" aria-live=\\\"assertive\\\">` with a variant-specific\\nicon, optional title, message body, and optional close button.\\n\\nAnimation: `ggui-slideInUp 200ms ease-out both` on mount (from the motion\\ntoken system). The keyframes are provided by the MotionKeyframes provider.\\n\\nAuto-dismiss: when `onClose` is provided and `duration > 0`, a timer calls\\n`onClose` after `duration` ms. Setting `duration` to `0` disables auto-dismiss.\\nThe timer resets if `visible`, `duration`, or `onClose` changes.\\n\\nDimensions: `min-width: 280px`, `max-width: 420px`.\\nShadow: `var(--ggui-shape-shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1))`.\\nBorder radius: `var(--ggui-shape-radius-lg)`.\\n\\nWhen `visible` is false, renders nothing (returns `null`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| message | `ReactNode` | - | Message body content. Can be text or any ReactNode. |\\n| variant | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | `'info'` | Visual style. Maps to background/border/text/icon color sets (same palette as Alert): - `'info'` -- bg `var(--ggui-color-info-50)`, border `var(--ggui-color-info-200)`, text `var(--ggui-color-info-800)` - `'success'` -- bg `var(--ggui-color-success-50)`, border `var(--ggui-color-success-200)`, text `var(--ggui-color-success-800)` - `'warning'` -- bg `var(--ggui-color-warning-50)`, border `var(--ggui-color-warning-200)`, text `var(--ggui-color-warning-800)` - `'error'` -- bg `var(--ggui-color-error-50)`, border `var(--ggui-color-error-200)`, text `var(--ggui-color-error-800)` |\\n| title | `string` | - | Optional title rendered above the message in semibold (`var(--ggui-font-weight-semibold)`, `var(--ggui-font-size-sm)`). |\\n| duration | `number` | `5000` | Auto-dismiss delay in milliseconds. After this duration, `onClose` is called automatically. Set to `0` to disable auto-dismiss (toast stays until manually closed). The timer is only active when both `visible` is true and `onClose` is provided. |\\n| onClose | `() => void` | - | Callback fired on auto-dismiss timeout or when the close button is clicked. When provided, a close button (X icon, 16px) is rendered in the top-right area. When omitted, no close button is shown and auto-dismiss is disabled. |\\n| visible | `boolean` | `true` | Controls rendering. When false, the component returns `null`. Toggling from false to true triggers the slide-in animation. |\\n| position | `'top-right' \\\\| 'top-left' \\\\| 'bottom-right' \\\\| 'bottom-left' \\\\| 'top-center' \\\\| 'bottom-center'` | - | Intended screen position. This prop is defined on the interface but is NOT implemented by the Toast component itself -- positioning must be handled by a parent container or toast manager. |\\n\\n**Example:**\\n```tsx\\n<Toast variant=\\\"success\\\" title=\\\"Saved\\\" message=\\\"Your changes have been saved.\\\" onClose={() => setShow(false)} />\\n```\\n\\n### Accordion\\n\\nAccordion -- Collapsible content sections with chevron rotation animation.\\n\\nRenders a vertical list of items, each with a `<button>` header (inside `<h3>`)\\nand a `<div role=\\\"region\\\">` panel. Supports controlled (`expandedKeys` + `onChange`)\\nand uncontrolled (internal state) modes.\\n\\nChevron animation: the trailing chevron icon rotates from 0deg (collapsed) to\\n180deg (expanded) with `transition: transform 200ms ease-in-out`.\\n\\nHeader button: full-width flex layout (`justify-content: space-between`),\\n`var(--ggui-font-size-sm)`, `var(--ggui-font-weight-medium)`,\\n`var(--ggui-color-onSurface)`.\\nHeader padding: `var(--ggui-spacing-2) var(--ggui-spacing-4)`.\\nBackground transition: `background-color 100ms ease-in-out`.\\n\\n**IMPORTANT:** `onChange` receives the full array of currently expanded keys,\\nNOT a single key or a React event. In single mode (`multiple: false`), this\\narray will have at most one element.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `AccordionItem[]` | - | Array of collapsible section definitions. |\\n| expandedKeys | `string[]` | - | Controlled expanded state. Array of item `key` values that should be open. When provided, the component is controlled and will not manage its own expansion state. When omitted, defaults to `[]` (all collapsed, uncontrolled mode). |\\n| onChange | `(expandedKeys: string[]) => void` | - | Expand/collapse handler. Receives the complete array of expanded keys after a toggle. In controlled mode, you must update `expandedKeys` in response to this callback. |\\n| multiple | `boolean` | `false` | When true, multiple items can be open simultaneously. When false, opening one item closes any other open item (single-expand mode). |\\n| variant | `'default' \\\\| 'bordered' \\\\| 'separated'` | `'default'` | Visual style controlling borders and spacing: - `'default'` -- top border on first item, bottom border on all items (`var(--ggui-color-outlineVariant)`), no gap between items - `'bordered'` -- connected card style with left/right/bottom borders on all items, top border on first, shared rounded corners (radius-lg on first/last) - `'separated'` -- each item is an independent card with full border (`1px solid var(--ggui-color-outlineVariant)`), `var(--ggui-shape-radius-lg)` radius, `var(--ggui-spacing-2)` gap between items |\\n\\n**Example:**\\n```tsx\\n<Accordion\\n variant=\\\"separated\\\"\\n items={[\\n { key: 'faq1', title: 'How do I get started?', content: 'Sign up and...' },\\n { key: 'faq2', title: 'What is the pricing?', content: 'We offer...' },\\n ]}\\n expandedKeys={expanded}\\n onChange={setExpanded}\\n multiple\\n/>\\n```\\n\\n### Support Types\\n\\n**ResponsiveColumns:**\\n\\nExplicit column count per viewport breakpoint, mobile-first. `base`\\napplies from 0 up; each named key overrides at and above its\\nbreakpoint width (`sm` 640px, `md` 768px, `lg` 1024px, `xl` 1280px).\\nOmit `base` to default to a single column on the narrowest screens.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| base | `number` | Columns below the `sm` breakpoint. |\\n| sm | `number` | Columns from 640px up. |\\n| md | `number` | Columns from 768px up. |\\n| lg | `number` | Columns from 1024px up. |\\n| xl | `number` | Columns from 1280px up. |\\n\\n**SelectOption:**\\n\\nAn individual option within a `Select` dropdown.\\n\\nRendered as a native `<option>` element. When `disabled` is true, the option\\nis visible but not selectable.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | The value submitted when this option is selected. Must be unique within the options array. |\\n| label | `string` | The display text shown in the dropdown. |\\n| disabled | `boolean` | When true, the option is visible but cannot be selected (grayed out by the browser). |\\n\\n**RadioOption:**\\n\\nAn individual option within a `RadioGroup`.\\n\\nRendered as a `<label>` containing a visually-hidden `<input type=\\\"radio\\\">`\\nand a custom 18px circle indicator. Supports an optional description line\\nbelow the label text.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | The value emitted via `RadioGroupProps.onChange` when this option is selected. Must be unique. |\\n| label | `string` | Display text for this option. Styled with `var(--ggui-font-size-sm)` and `var(--ggui-color-onSurfaceVariant)`. |\\n| description | `string` | Optional secondary description rendered below the label in smaller, muted type (`var(--ggui-font-size-xs)`, `var(--ggui-color-onSurfaceVariant)`). |\\n| disabled | `boolean` | When true, this individual option is grayed out (`opacity: 0.5`) and cannot be selected, regardless of the group-level `disabled` prop. |\\n\\n**TableColumn:**\\n\\nColumn definition for the Table component.\\n\\nEach column maps a `key` in the row data object to a table column with\\na header label, optional sorting, alignment, width, and custom rendering.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Property key in the row data object. Used to extract cell values via `row[key]`. Must be unique across all columns in a Table. |\\n| header | `string` | Column header text. Rendered in uppercase, `var(--ggui-font-size-xs)`, `var(--ggui-font-weight-semibold)`, `var(--ggui-color-onSurfaceVariant)`, with `letter-spacing: 0.05em`. |\\n| width | `number \\\\| string` | Fixed column width. Numbers are pixels, strings are CSS values (e.g., `'200px'`, `'30%'`). When omitted, the column auto-sizes based on content. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | Horizontal text alignment for both the header and data cells. |\\n| sortable | `boolean` | When true, the header cell becomes clickable and shows sort direction indicators (ascending/descending triangles). Clicking toggles between `'asc'` and `'desc'`. The header gets `cursor: pointer`, `tabIndex: 0`, and keyboard support (Enter/Space to toggle). |\\n| render | `(value: unknown, row: T, index: number) => ReactNode` | Custom cell renderer. When provided, called instead of rendering `row[key]` directly. Receives the cell value, the full row object, and the row index. |\\n\\n**TabItem:**\\n\\nDefinition of a single tab within a Tabs component.\\n\\nEach item provides a unique `key` for identification, a `label` for the\\ntab button, and `content` for the associated panel.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Unique identifier for this tab. Used to match `activeKey` and as the value passed to `onChange`. |\\n| label | `ReactNode` | Tab button label. Can be text or any ReactNode. |\\n| content | `ReactNode` | Panel content rendered below the tab bar when this tab is active. |\\n| disabled | `boolean` | When true, the tab button shows `opacity: 0.5`, `cursor: not-allowed`, and cannot be selected via click or keyboard navigation. |\\n| icon | `ReactNode` | Optional icon rendered before the label inside the tab button, with `var(--ggui-spacing-1)` gap between icon and label. |\\n\\n**AccordionItem:**\\n\\nDefinition of a single collapsible section within an Accordion.\\n\\nEach item provides a unique `key`, a clickable `title` for the header button,\\nand `content` revealed when expanded.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Unique identifier for this item. Used in `expandedKeys` and passed to `onChange`. |\\n| title | `ReactNode` | Header label rendered inside the toggle button. Can be text or any ReactNode. |\\n| content | `ReactNode` | Panel content rendered below the header when expanded. Styled with `var(--ggui-font-size-sm)`, `var(--ggui-color-onSurfaceVariant)`, `line-height: var(--ggui-font-lineHeight-normal, 1.5)`. Padding: `0 var(--ggui-spacing-4) var(--ggui-spacing-4)`. |\\n| disabled | `boolean` | When true, the header button shows `opacity: 0.5`, `cursor: not-allowed`, and cannot be toggled. |\\n\\n\\n## Components\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### SearchField\\n\\nA text input with a leading search icon and optional submit button.\\n\\nComposes: `Input` (native `<input type=\\\"search\\\">`), `Button`, `Spinner`, `Icon`.\\n\\nSupports controlled and uncontrolled usage. When `value` is `undefined` the\\ncomponent tracks its own state internally. Pressing **Enter** triggers\\n`onSearch` with the current value. When `loading` is `true` the search icon\\nis replaced by a `Spinner` and the input is disabled.\\n\\nTokens used: `colors.gray[300]` border, `colors.gray[50]` disabled bg,\\n`colors.gray[400]` icon color, `colors.gray[900]` text color.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `string` | - | Current search value. When provided, the component is **controlled** and the caller must update this via `onChange`. When omitted, the component manages its own internal state. |\\n| onChange | `(value: string) => void` | - | Called on every keystroke with the new input string (value directly, not a React `ChangeEvent`). |\\n| onSearch | `(value: string) => void` | - | Called when the user presses **Enter** or clicks the search button (if `showButton` is `true`). Receives the current value directly. |\\n| placeholder | `string` | `'Search...'` | Placeholder text shown when the input is empty. |\\n| showButton | `boolean` | `false` | When `true`, renders a `Button` primitive to the right of the input. The button's label is set by `buttonText`. |\\n| buttonText | `string` | `'Search'` | Label rendered inside the submit button. Only visible when `showButton` is `true`. |\\n| loading | `boolean` | - | When `true`, replaces the search icon with a `Spinner`, disables the input, and disables the submit button. |\\n| disabled | `boolean` | - | When `true`, the input and button are visually disabled and do not respond to interaction. The input background changes to `colors.gray[50]`. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls input height and font size. - `'sm'` -- 6px vertical padding, 14px font - `'md'` -- 10px vertical padding, 14px font - `'lg'` -- 12px vertical padding, 16px font The Button size maps `sm`->`sm`, `md`->`md`, `lg`->`md`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<SearchField\\n value={query}\\n onChange={setQuery}\\n onSearch={(q) => fetchResults(q)}\\n placeholder=\\\"Search products...\\\"\\n showButton\\n buttonText=\\\"Go\\\"\\n size=\\\"md\\\"\\n/>\\n```\\n```\\n\\n### FormField\\n\\nA wrapper that adds a label, optional description, error message,\\nand helper text around any form input passed as `children`.\\n\\nComposes: no other primitives -- pure layout with semantic `<label>` and\\n`<span>` elements.\\n\\nVisual hierarchy (top to bottom):\\n1. **Label** (required) -- `fontSize.sm`, `fontWeight.medium`, `colors.gray[700]`\\n2. **Required indicator** -- red asterisk (`colors.error[500]`) appended to label\\n3. **Description** -- `fontSize.xs`, `colors.gray[500]`, 4px bottom margin\\n4. **Children** -- the form control itself\\n5. **Error / Helper text** -- `fontSize.xs`; error in `colors.error[500]`,\\n helper in `colors.gray[500]`. Error takes priority when both are provided.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Text rendered inside the `<label>` element above the input. |\\n| children | `ReactNode` | - | The form control (typically an `Input`, `Select`, or `Textarea` primitive) rendered between the label/description and the error/helper row. |\\n| error | `string` | - | Error message displayed below `children` in `colors.error[500]`. When present, it takes precedence over `helperText`. |\\n| helperText | `string` | - | Neutral guidance text displayed below `children` in `colors.gray[500]`. Hidden when `error` is present. |\\n| required | `boolean` | - | When `true`, appends a red asterisk (`*`) after the label text. Does **not** add any HTML validation attributes -- handle that on the child input. |\\n| description | `string` | - | Secondary description rendered between the label and the child control in `fontSize.xs` / `colors.gray[500]`. Use for longer guidance that does not belong in `helperText`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<FormField\\n label=\\\"Email address\\\"\\n required\\n description=\\\"We will never share your email.\\\"\\n error={errors.email}\\n>\\n <Input value={email} onChange={setEmail} placeholder=\\\"you@example.com\\\" />\\n</FormField>\\n```\\n```\\n\\n### MenuItem\\n\\nA full-width clickable row for menus, sidebars, and action lists.\\n\\nComposes: none -- renders a native `<button>` element.\\n\\nBuilt-in transition: `background-color 0.15s` on hover.\\n\\nColor logic:\\n- **Normal**: text `colors.gray[700]`, hover bg `colors.gray[100]`\\n- **Active**: bg `colors.primary[50]`, text `colors.gray[700]`, `fontWeight.medium`\\n- **Danger**: text `colors.error[600]`, hover bg `colors.error[50]`, active bg `colors.error[100]`\\n- **Disabled**: text `colors.gray[400]`, `cursor: not-allowed`\\n\\nLayout: flexbox row with `8px` gap, `8px 12px` padding, `radius.md` border-radius.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | Primary text content of the menu item. |\\n| icon | `ReactNode` | - | Icon or element rendered to the left of the label. Flex-shrink 0. |\\n| rightElement | `ReactNode` | - | Element rendered to the right of the label (e.g., a keyboard shortcut badge or a count). Colored `colors.gray[400]`, flex-shrink 0. |\\n| onClick | `() => void` | - | Called when the item is clicked. Suppressed when `disabled` is `true`. |\\n| disabled | `boolean` | - | When `true`, the item is non-interactive: `colors.gray[400]` text, `cursor: not-allowed`, click handler suppressed. |\\n| active | `boolean` | - | Marks this item as the current selection. Applies a tinted background (`colors.primary[50]`, or `colors.error[100]` when `danger` is also set) and `fontWeight.medium`. |\\n| danger | `boolean` | - | Switches the item to destructive styling: `colors.error[600]` text, `colors.error[50]` hover background. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<MenuItem\\n label=\\\"Delete project\\\"\\n icon={<Icon name=\\\"trash\\\" size={16} />}\\n danger\\n onClick={() => confirmDelete(projectId)}\\n/>\\n```\\n```\\n\\n### Tag\\n\\nAn inline label for categories, filters, statuses, or selections.\\nOptionally dismissable via a close button.\\n\\nComposes: none -- pure `<span>` with an optional close `<button>`.\\n\\nEach `variant` maps to a background / text / border color triple from the\\ndesign tokens:\\n- `'default'` -- `gray[100]` / `gray[700]` / `gray[200]`\\n- `'primary'` -- `primary[50]` / `primary[700]` / `primary[200]`\\n- `'success'` -- `success[50]` / `success[700]` / `success[200]`\\n- `'warning'` -- `warning[50]` / `warning[700]` / `warning[200]`\\n- `'error'` -- `error[50]` / `error[700]` / `error[200]`\\n- `'info'` -- `info[50]` / `info[700]` / `info[200]`\\n\\nThe close button renders an inline SVG \\\"x\\\" icon (12x12) with `opacity: 0.7`\\nand an `aria-label=\\\"Remove\\\"`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Tag content -- typically a short text string. |\\n| variant | `'default' \\\\| 'primary' \\\\| 'success' \\\\| 'warning' \\\\| 'error' \\\\| 'info'` | `'default'` | Semantic color variant applied to background, text, and border. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls padding, font size, and internal gap. - `'sm'` -- 2px/6px padding, `fontSize.xs`, 4px gap - `'md'` -- 4px/8px padding, `fontSize.xs`, 6px gap - `'lg'` -- 6px/10px padding, `fontSize.sm`, 6px gap |\\n| closable | `boolean` | - | When `true`, renders a small close (\\\"x\\\") button after the content. Clicking it fires `onClose`. |\\n| onClose | `() => void` | - | Called when the close button is clicked. Only relevant when `closable` is `true`. |\\n| icon | `ReactNode` | - | Icon or element rendered before the text content. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Tag variant=\\\"success\\\" size=\\\"md\\\" closable onClose={() => removeFilter(id)}>\\n Active\\n</Tag>\\n```\\n```\\n\\n### Dropdown\\n\\nA click-triggered menu anchored to a trigger element. Manages its own\\nopen/close state internally.\\n\\nComposes: `MenuItem` for each option.\\n\\nBehavior:\\n- Clicking the trigger toggles the menu open/closed.\\n- Selecting an option calls `onChange(option.value)` and closes the menu.\\n- Clicking outside the container or pressing **Escape** closes the menu.\\n- The currently selected option (matching `value`) is rendered with\\n `MenuItem`'s `active` state.\\n\\nMenu panel: `colors.white` bg, `colors.gray[200]` border, `radius.lg`\\nborder-radius, `shadow.lg`, `zIndex.dropdown`, 160px min-width, 4px padding.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| trigger | `ReactNode` | - | The element the user clicks to open the menu. Receives a wrapping `<div>` with `cursor: pointer` (or `not-allowed` when disabled). |\\n| options | `DropdownOption[]` | - | Array of selectable options rendered as `MenuItem` rows. |\\n| value | `string` | - | The `value` of the currently selected option. The matching `MenuItem` is rendered with `active` styling. |\\n| onChange | `(value: string) => void` | - | Called with the `value` string of the selected option (not the full `DropdownOption` object). The menu closes immediately after. |\\n| placement | `'bottom-start' \\\\| 'bottom-end' \\\\| 'top-start' \\\\| 'top-end'` | `'bottom-start'` | Where to anchor the menu panel relative to the trigger. - `'bottom-start'` -- below, aligned to left edge - `'bottom-end'` -- below, aligned to right edge - `'top-start'` -- above, aligned to left edge - `'top-end'` -- above, aligned to right edge |\\n| disabled | `boolean` | - | When `true`, the trigger shows `cursor: not-allowed` and clicking it does not open the menu. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Dropdown\\n trigger={<Button variant=\\\"outline\\\">Sort by</Button>}\\n options={[\\n { value: 'name', label: 'Name' },\\n { value: 'date', label: 'Date created' },\\n { value: 'delete', label: 'Delete', danger: true },\\n ]}\\n value={sortBy}\\n onChange={setSortBy}\\n placement=\\\"bottom-end\\\"\\n/>\\n```\\n```\\n\\n### Autocomplete\\n\\nA text input with a filterable suggestion dropdown, keyboard navigation,\\nand loading/empty states.\\n\\nComposes: `Input` primitive (with `label`, `error`, `placeholder` forwarded),\\n`Spinner` (loading state).\\n\\nFiltering: options are filtered client-side by case-insensitive substring\\nmatch against both `option.label` and `option.value`.\\n\\nKeyboard support:\\n- **ArrowDown / ArrowUp** -- move highlight through filtered options\\n (opens dropdown if closed)\\n- **Enter** -- selects the highlighted option\\n- **Escape** -- closes the dropdown\\n\\nOn selection, `onChange` is called with `option.label` (the display text)\\nand `onSelect` is called with the full `AutocompleteOption` object.\\n\\nDropdown panel: `colors.white` bg, `colors.gray[200]` border, `radius.lg`\\nborder-radius, `shadow.lg`, `zIndex.dropdown`, max-height 240px with\\noverflow scroll.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| value | `string` | `''` | Current text in the input field. On selection, this is set to the selected option's `label`. |\\n| onChange | `(value: string) => void` | - | Called on every keystroke with the new input string (value directly, not a React event). Also called on selection with `option.label`. |\\n| onSelect | `(option: AutocompleteOption) => void` | - | Called when the user selects an option (click or Enter on highlighted item). Receives the full `AutocompleteOption` object, not just the value string. |\\n| options | `AutocompleteOption[]` | - | The full list of available options. Filtering is handled internally via case-insensitive substring match on `label` and `value`. |\\n| placeholder | `string` | - | Placeholder text forwarded to the inner `Input` primitive. |\\n| label | `string` | - | Label text forwarded to the inner `Input` primitive. |\\n| loading | `boolean` | - | When `true`, the dropdown shows a centered `Spinner` instead of the option list. The input remains interactive. |\\n| disabled | `boolean` | - | When `true`, the inner `Input` is disabled and the dropdown does not open. |\\n| error | `string` | - | Error message forwarded to the inner `Input` primitive. |\\n| noResultsText | `string` | `'No results found'` | Text shown in the dropdown when filtering produces zero matches. Rendered centered in `colors.gray[500]` / `fontSize.sm`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Autocomplete\\n label=\\\"Country\\\"\\n value={country}\\n onChange={setCountry}\\n onSelect={(opt) => setCountryCode(opt.value)}\\n options={countries}\\n placeholder=\\\"Type to search...\\\"\\n noResultsText=\\\"No countries found\\\"\\n/>\\n```\\n```\\n\\n### Breadcrumb\\n\\nA horizontal navigation trail showing the user's location within a\\nhierarchy. Renders a `<nav aria-label=\\\"Breadcrumb\\\">`.\\n\\nComposes: `Link` primitive (for items with `href`).\\n\\nRendering rules per item:\\n- **Last item**: static `<span>` with `colors.gray[900]`, `fontWeight: 500`,\\n and `aria-current=\\\"page\\\"`.\\n- **Non-last with `href`**: `Link` in `colors.gray[500]` with\\n `underline=\\\"hover\\\"`. If `onItemClick` is provided, `e.preventDefault()`\\n is called and the handler fires instead of navigating.\\n- **Non-last without `href`**: unstyled `<button>` in `colors.gray[500]`.\\n\\nLayout: flexbox row, `8px` gap, `fontSize.sm`.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `BreadcrumbItem[]` | - | Ordered array of breadcrumb segments from root to current page. |\\n| separator | `ReactNode` | `'/'` | Separator rendered between each pair of items. Can be a string (e.g., `\\\"/\\\"`, `\\\">\\\"`) or a ReactNode (e.g., an `Icon`). Rendered in `colors.gray[400]`. |\\n| onItemClick | `(item: BreadcrumbItem, index: number) => void` | - | Called when a non-last item is clicked. Receives the `BreadcrumbItem` and its zero-based `index`. When provided on items that have `href`, the default navigation is prevented via `e.preventDefault()`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Breadcrumb\\n items={[\\n { label: 'Home', href: '/' },\\n { label: 'Projects', href: '/projects' },\\n { label: 'ggui' },\\n ]}\\n separator=\\\"/\\\"\\n onItemClick={(item) => router.push(item.href!)}\\n/>\\n```\\n```\\n\\n### Pagination\\n\\nPage navigation controls with previous/next arrows, numbered page buttons,\\nand optional first/last jumps. Renders a `<nav aria-label=\\\"Pagination\\\">`.\\n\\nComposes: `Button` (ghost variant for prev/next/first/last arrows),\\n`Icon` (`chevron-left`, `chevron-right`).\\n\\nBuilt-in transition: `all 0.15s` on page number buttons.\\n\\nPage windowing: when `totalPages > maxVisible`, the component shows the\\nfirst page, last page, a window of pages around `currentPage`, and\\nellipsis (\\\"...\\\") markers for gaps. The window adjusts when near the\\nstart or end of the range.\\n\\nActive page button: `colors.primary[600]` bg, `colors.white` text,\\n`fontWeight.medium`. Inactive: transparent bg, `colors.gray[700]` text.\\n\\nArrow buttons are automatically disabled at boundary pages (first/last).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| currentPage | `number` | - | Current active page. **1-indexed** (first page is `1`). |\\n| totalPages | `number` | - | Total number of pages. Determines when last-page / next-page buttons disable. |\\n| onPageChange | `(page: number) => void` | - | Called when the user clicks a page number, arrow, or first/last button. Receives the target page number (1-indexed) directly. |\\n| showFirstLast | `boolean` | `true` | When `true`, renders double-chevron buttons for jumping to the first and last page. These buttons are disabled when already on the respective boundary. |\\n| maxVisible | `number` | `5` | Maximum number of page buttons visible at once (including the first and last page, but excluding ellipsis markers). When `totalPages` exceeds this value, ellipsis gaps appear. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls button dimensions and icon sizes. - `'sm'` -- 28px buttons, 14px icons, Button size `xs` - `'md'` -- 32px buttons, 16px icons, Button size `sm` - `'lg'` -- 40px buttons, 20px icons, Button size `md` |\\n| disabled | `boolean` | - | When `true`, all page buttons and arrows are visually dimmed (`opacity: 0.5`) and clicks are suppressed. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Pagination\\n currentPage={page}\\n totalPages={20}\\n onPageChange={setPage}\\n maxVisible={7}\\n size=\\\"md\\\"\\n/>\\n```\\n```\\n\\n### EmptyState\\n\\nEmptyState -- placeholder for a region with no data: empty lists,\\nzero search results, an error fallback. Render it instead of\\nnothing whenever a data array could be empty — a list that shows\\nnothing when empty looks broken.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| icon | `string \\\\| ReactNode` | - | A Lucide icon name (kebab-case), rendered large and subtle above the title, or a custom node. Omit for a text-only empty state. |\\n| title | `string` | - | The headline, e.g. \\\"No results found\\\". |\\n| description | `string` | - | Optional supporting line below the title. |\\n| action | `ReactNode` | - | Optional call-to-action, typically a `<Button>`. |\\n\\n**Example:**\\n```tsx\\n{results.length === 0\\n ? <EmptyState icon=\\\"search-x\\\" title=\\\"No matches\\\" description=\\\"Try a broader query.\\\" />\\n : results.map((r) => <Row key={r.id}>…</Row>)}\\n```\\n\\n### Stat\\n\\nStat -- a single KPI / metric: a label, a large value, an optional\\ntrend-coloured delta and icon. Reach for it whenever the UI is\\n\\\"show a number\\\" — dashboards, weather and price cards, analytics\\ntiles. Drop several into a `<Grid>` for a stat grid.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| label | `string` | - | The metric name, e.g. \\\"Revenue\\\". Rendered small and uppercase above the value. |\\n| value | `string \\\\| number` | - | The headline value — the big number. A number, or a pre-formatted string (`\\\"$48.2k\\\"`, `\\\"18°C\\\"`). |\\n| delta | `string` | - | Optional change indicator, pre-formatted, e.g. `\\\"+12.5%\\\"` or `\\\"-3\\\"`. |\\n| trend | `'up' \\\\| 'down' \\\\| 'neutral'` | `'neutral'` | Direction of `delta` — colours it: `'up'` success, `'down'` error, `'neutral'` muted. |\\n| icon | `string \\\\| ReactNode` | - | Optional Lucide icon name (kebab-case) or custom node, shown next to the label. |\\n\\n**Example:**\\n```tsx\\n<Stat label=\\\"Revenue\\\" value=\\\"$48.2k\\\" delta=\\\"+12.5%\\\" trend=\\\"up\\\" icon=\\\"trending-up\\\" />\\n```\\n\\n### Stepper\\n\\nStepper -- a display-only step indicator for multi-step flows\\n(wizards, checkouts, onboarding): numbered markers joined by\\nconnector lines, with completed (check), current (filled), and\\nupcoming (outlined) states styled distinctly.\\n\\nStepper renders step state; it never owns it. Declare the step\\nlabels as a top-level `const`, track the current index in\\n`useState`, and advance it from your own Next/Back buttons (or\\n`onStepClick`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| steps | `string[]` | - | Ordered step labels, one per step. Declare as a top-level `const` array — never as state. |\\n| current | `number` | - | Zero-based index of the active step. Steps before it render as completed (check mark), steps after it as upcoming. |\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Flow direction. `'horizontal'` joins the markers with connector lines in a row; `'vertical'` stacks the steps with short connector columns — better for sidebars or long step labels. |\\n| onStepClick | `(index: number) => void` | - | When provided, each step becomes a real button and clicks receive the step's zero-based index. Typical use: jumping back to a completed step; guard forward jumps in the handler if the flow validates per step. |\\n\\n**Example:**\\n```tsx\\nconst STEPS = ['Account', 'Profile', 'Review'];\\n// In the component: const [step, setStep] = useState(0);\\n<Stack gap=\\\"lg\\\">\\n <Stepper steps={STEPS} current={step} />\\n {step === 0 && <AccountFields />}\\n <Row gap=\\\"sm\\\" justify=\\\"end\\\">\\n <Button variant=\\\"ghost\\\" disabled={step === 0} onClick={() => setStep(step - 1)}>Back</Button>\\n <Button onClick={() => setStep(step + 1)}>Next</Button>\\n </Row>\\n</Stack>\\n```\\n\\n### Markdown\\n\\nMarkdown -- renders markdown-formatted text as styled content:\\nheadings, paragraphs, **bold** / *italic*, `inline code`, fenced\\ncode blocks, bulleted and numbered lists, and links.\\n\\nUse it whenever a prop or context slot carries prose the agent\\nauthors in markdown -- article bodies, AI-generated explanations,\\ndescriptions, notes, help text. Pass the raw markdown string\\nstraight through; never pre-parse it, never split it into per-line\\n`Text` elements, and never rebuild formatting with nested\\n`<strong>`/`<em>` markup yourself.\\n\\nSafe by construction: raw HTML in the source displays as literal\\ntext (never markup), and links render inert unless their scheme is\\nhttp(s)/mailto. Streaming-tolerant: a mid-stream prefix parses\\ncleanly and completed constructs never change shape, so binding a\\ngrowing string re-renders correctly.\\n\\nFor a single line of formatted text INSIDE another element (a table\\ncell, a list row, a caption), use `MarkdownInline` instead -- same\\n`markdown` prop, inline-level constructs only (no headings, lists,\\nor code fences), renders inside the parent's typography.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| markdown | `string` | - | Markdown source text, passed through verbatim. Supports the conversational subset: `#`-`###` headings, paragraphs, bold, italic, inline code, fenced code blocks, `-`/`1.` lists, and `[label](url)` links. Bind stateful or streamed prose directly. |\\n\\n**Example:**\\n```tsx\\n<Stack gap=\\\"md\\\">\\n <Markdown markdown={recipe.instructions} />\\n</Stack>\\n```\\n\\n### Support Types\\n\\n**DropdownOption:**\\n\\nA single option inside a `Dropdown`. Each option maps to one `MenuItem`\\ninternally.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | Unique identifier returned to `onChange` when this option is selected. |\\n| label | `string` | Human-readable text shown in the menu row. |\\n| icon | `ReactNode` | Optional icon rendered to the left of the label via `MenuItem.icon`. |\\n| disabled | `boolean` | When `true`, the option is visible but non-interactive. |\\n| danger | `boolean` | When `true`, the option uses destructive (red) styling via `MenuItem.danger`. |\\n\\n**AutocompleteOption:**\\n\\nA single option in the `Autocomplete` suggestion list.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| value | `string` | Unique identifier for this option. Also used for case-insensitive filtering against the input value. |\\n| label | `string` | Primary display text. Also used for case-insensitive filtering and is written into the input on selection. |\\n| description | `string` | Secondary description rendered below the label in `fontSize.xs` / `colors.gray[500]`. |\\n| icon | `ReactNode` | Icon rendered to the left of the label/description block. Flex-shrink 0. |\\n| disabled | `boolean` | When `true`, the option is visible but non-interactive (`cursor: not-allowed`, `colors.gray[400]` text). |\\n\\n**BreadcrumbItem:**\\n\\nA single segment in a `Breadcrumb` trail. Items with `href` render as\\n`Link` primitives; items without render as plain `<button>` elements.\\nThe last item in the array is always rendered as static text with\\n`aria-current=\\\"page\\\"`.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Display text for this breadcrumb segment. |\\n| href | `string` | URL for this segment. When provided (and this is not the last item), the segment renders as a `Link` primitive with `underline=\\\"hover\\\"`. When omitted, it renders as a `<button>`. |\\n| icon | `ReactNode` | Icon rendered immediately before the label. Its color follows the segment's text color: `colors.gray[500]` for navigable items, `colors.gray[900]` for the current (last) item. |\\n\\n\\n## Compositions\\n\\nImport: `import { Component } from '@ggui-ai/design'`\\n\\n### Header\\n\\nProps for the `Header` composition.\\n\\nA horizontal page header that arranges a logo, navigation, and action slots\\nin a flex row (`justify-content: space-between`). Internally renders a `<header>` element;\\ndoes not compose other ggui primitives.\\n\\nWhen `sticky` is true the header gets `position: sticky; top: 0` with `zIndex.sticky`\\nand a `shadow.sm` box-shadow.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| logo | `ReactNode` | - | Logo or brand element rendered at the start (flex-shrink: 0). |\\n| navigation | `ReactNode` | - | Navigation content rendered in a `<nav>` element with `flex: 1` and a 32 px left margin. |\\n| actions | `ReactNode` | - | Right-side action elements (buttons, avatar, etc.) rendered with a 12 px gap. |\\n| sticky | `boolean` | `false` | When true, the header becomes `position: sticky` at the top of its scroll container with `zIndex.sticky` and `shadow.sm`. |\\n| background | `string` | `colors.white` | Background color of the header. |\\n| bordered | `boolean` | `true` | When true, renders a 1 px bottom border in `colors.gray[200]`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Header\\n logo={<img src=\\\"/logo.svg\\\" alt=\\\"Acme\\\" />}\\n navigation={<a href=\\\"/docs\\\">Docs</a>}\\n actions={<Button size=\\\"sm\\\">Sign In</Button>}\\n sticky\\n bordered\\n/>\\n```\\n```\\n\\n### Sidebar\\n\\nProps for the `Sidebar` composition.\\n\\nA vertical navigation panel that composes the `Icon` primitive for chevron indicators.\\nItems are rendered as `<button>` elements inside a scrollable `<nav>`. Nested items\\nare indented 16 px per depth level. The sidebar animates width changes with a 200 ms\\nCSS transition. Active items are highlighted with `colors.primary[50]` background\\nand `colors.primary[700]` text.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `SidebarItem[]` | - | Array of navigation items to render. |\\n| activeId | `string` | - | ID of the currently active item. Matched items get a highlighted background and bold text. |\\n| onItemClick | `(item: SidebarItem) => void` | - | Called when any item (including parent items with children) is clicked. |\\n| collapsed | `boolean` | `false` | When true, hides labels and badges; only icons remain visible, centered in the collapsed width. Nested children are hidden entirely. |\\n| header | `ReactNode` | - | Content rendered above the item list, separated by a bottom border. |\\n| footer | `ReactNode` | - | Content rendered below the item list, separated by a top border. |\\n| width | `number` | `256` | Width in pixels when expanded. |\\n| collapsedWidth | `number` | `64` | Width in pixels when collapsed. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Sidebar\\n items={[\\n { id: 'home', label: 'Home', icon: <Icon name=\\\"home\\\" /> },\\n { id: 'settings', label: 'Settings', icon: <Icon name=\\\"settings\\\" />,\\n children: [\\n { id: 'profile', label: 'Profile' },\\n { id: 'billing', label: 'Billing' },\\n ]},\\n ]}\\n activeId=\\\"home\\\"\\n onItemClick={(item) => navigate(item.href)}\\n collapsed={false}\\n width={256}\\n/>\\n```\\n```\\n\\n### CardGrid\\n\\nProps for the `CardGrid` composition.\\n\\nA CSS Grid wrapper that arranges children in equal-width columns. When `columns`\\nis a number, it produces `repeat(N, 1fr)`. When it is a responsive object,\\nit falls back to `repeat(auto-fit, minmax(280px, 1fr))` for fluid responsive behavior.\\n\\nDoes not compose any ggui primitives internally — it is a pure layout container.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| children | `ReactNode` | - | Card elements to arrange in the grid. |\\n| columns | `number \\\\| { sm?: number; md?: number; lg?: number }` | `3` | Number of columns, or a responsive breakpoint map. - `number` — fixed column count via `repeat(N, 1fr)`. - `{ sm?, md?, lg? }` — triggers `repeat(auto-fit, minmax(280px, 1fr))` for fluid layout. |\\n| gap | `number` | `16` | Gap between grid items in pixels. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CardGrid columns={3} gap={24}>\\n <Card>A</Card>\\n <Card>B</Card>\\n <Card>C</Card>\\n</CardGrid>\\n```\\n```\\n\\n### CommentThread\\n\\nProps for the `CommentThread` composition.\\n\\nA threaded comment section that composes `Avatar`, `Button`, `TextArea`, and `Spinner`\\nprimitives. Comments are rendered recursively with 40 px indentation per nesting level.\\nEach comment shows author avatar, name, timestamp, content, reactions, and a \\\"Reply\\\" toggle.\\nWhen `currentUser` is provided, a new-comment input with avatar and submit button is shown\\nabove the thread.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| comments | `Comment[]` | - | Array of top-level comments to render. Replies are nested within each comment. |\\n| currentUser | `{ /** Display name for the current user's avatar. */ name: string; /** Avatar image URL for the current user. */ avatar?: string; }` | - | Current user info. When provided, a new-comment input area is rendered above the thread. |\\n| onAddComment | `(content: string, parentId?: string) => void` | - | Called when the user submits a new top-level comment. |\\n| onReply | `(commentId: string, content: string) => void` | - | Called when the user submits a reply to an existing comment. |\\n| onReaction | `(commentId: string, emoji: string) => void` | - | Called when the user clicks an emoji reaction on a comment. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the comment list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CommentThread\\n comments={[\\n { id: '1', author: { name: 'Alice' }, content: 'Great work!', timestamp: new Date(),\\n replies: [{ id: '2', author: { name: 'Bob' }, content: 'Thanks!', timestamp: new Date() }] }\\n ]}\\n currentUser={{ name: 'Alice', avatar: '/alice.jpg' }}\\n onAddComment={(content) => post(content)}\\n onReply={(commentId, content) => reply(commentId, content)}\\n onReaction={(commentId, emoji) => react(commentId, emoji)}\\n/>\\n```\\n```\\n\\n### DataTable\\n\\nProps for the `DataTable` composition.\\n\\nA sortable, selectable data table that composes `Checkbox`, `Spinner`, and `Icon`\\nprimitives. Renders a `<table>` inside a bordered container with 8 px border-radius.\\nThe header row has a `colors.gray[50]` background. Sortable columns show a chevron\\nicon on click (toggles asc/desc). Selected rows are highlighted with `colors.primary[50]`.\\nRow background transitions use a 150 ms ease. The \\\"select all\\\" checkbox supports an\\nindeterminate state when a subset of rows is selected.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| columns | `DataTableColumn<T>[]` | - | Column definitions that control header, alignment, sorting, and rendering. |\\n| data | `T[]` | - | Row data array. Each entry corresponds to one table row. |\\n| rowKey | `string \\\\| ((row: T) => string)` | `'id'` | Property name or function used to derive a unique key for each row. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of table body rows. |\\n| emptyText | `string` | `'No data'` | Text shown when `data` is empty and not loading. |\\n| onSort | `(key: string, direction: 'asc' \\\\| 'desc') => void` | - | Called when a sortable column header is clicked. Toggles direction automatically (asc -> desc) if the same column is clicked again. |\\n| sortKey | `string` | - | The column key currently being sorted. |\\n| sortDirection | `'asc' \\\\| 'desc'` | - | The current sort direction. |\\n| onRowClick | `(row: T, index: number) => void` | - | Called when a row is clicked. Rows get `cursor: pointer` when this handler is provided. |\\n| selectable | `boolean` | - | When true, adds a checkbox column at the start of each row. |\\n| selectedKeys | `string[]` | `[]` | Array of currently selected row keys. |\\n| onSelectionChange | `(keys: string[]) => void` | - | Called when the set of selected row keys changes (via row checkbox or select-all). |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<DataTable\\n columns={[\\n { key: 'name', header: 'Name', sortable: true },\\n { key: 'email', header: 'Email' },\\n { key: 'role', header: 'Role', render: (v) => <Badge>{v}</Badge> },\\n ]}\\n data={users}\\n rowKey=\\\"id\\\"\\n selectable\\n selectedKeys={selected}\\n onSelectionChange={setSelected}\\n onSort={(key, dir) => sort(key, dir)}\\n sortKey=\\\"name\\\"\\n sortDirection=\\\"asc\\\"\\n/>\\n```\\n```\\n\\n### ChatWindow\\n\\nProps for the `ChatWindow` composition.\\n\\nA messaging interface that composes `Avatar`, `Button`, `Spinner`, and `Icon` primitives.\\nLayout is a flex column filling 100% height with a bordered `radius.lg` container.\\nMessages from the current user align right with `colors.primary[600]` bubbles and white text.\\nOther users' messages align left with `colors.gray[100]` bubbles. The message area\\nauto-scrolls to the bottom on new messages via `scrollIntoView({ behavior: 'smooth' })`.\\nThe text input sends on Enter (Shift+Enter for newline).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| messages | `ChatMessage[]` | - | Array of chat messages to display in chronological order. |\\n| currentUserId | `string` | - | ID of the current user. Messages from this user render right-aligned with a primary color bubble. |\\n| onSendMessage | `(content: string) => void` | - | Called when the user submits a message (Enter key or send button). |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the message list. |\\n| typing | `{ name: string } \\\\| null` | - | When non-null, displays a typing indicator below the last message (e.g., \\\"Alice is typing...\\\"). |\\n| placeholder | `string` | `'Type a message...'` | Placeholder text for the message input field. |\\n| header | `ReactNode` | - | Optional header content rendered above the message area, separated by a bottom border. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<ChatWindow\\n messages={messages}\\n currentUserId=\\\"user-1\\\"\\n onSendMessage={(content) => send(content)}\\n typing={{ name: 'Alice' }}\\n placeholder=\\\"Type a message...\\\"\\n header={<h3>Chat with Alice</h3>}\\n/>\\n```\\n```\\n\\n### NavigationBar\\n\\nProps for the `NavigationBar` composition.\\n\\nA horizontal or vertical navigation menu. Does not compose other ggui primitives\\n(uses plain `<button>` and `<a>` elements). Active items are styled per variant:\\n\\n- `'default'` — active item gets `colors.primary[600]` text and medium font weight.\\n- `'pills'` — active item gets a `radius.full` pill with `colors.primary[100]` background.\\n- `'underline'` — active item gets a 2 px bottom border in `colors.primary[600]`.\\n When horizontal, the entire nav also has a 1 px bottom border.\\n\\nAll items have a 150 ms transition on all properties.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| items | `NavItem[]` | - | Array of navigation items to render. |\\n| activeId | `string` | - | ID of the currently active item. Controls visual highlighting per variant style. |\\n| onItemClick | `(item: NavItem) => void` | - | Called when a non-disabled item is clicked. For `<a>` elements, `preventDefault` is called first. |\\n| orientation | `'horizontal' \\\\| 'vertical'` | `'horizontal'` | Layout direction. - `'horizontal'` — flex-row with 4 px gap. - `'vertical'` — flex-column with 2 px gap. |\\n| variant | `'default' \\\\| 'pills' \\\\| 'underline'` | `'default'` | Visual style for active/inactive items. - `'default'` — text color change only. - `'pills'` — rounded pill background on active items. - `'underline'` — bottom border on active items. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<NavigationBar\\n items={[\\n { id: 'home', label: 'Home', icon: <Icon name=\\\"home\\\" /> },\\n { id: 'about', label: 'About' },\\n { id: 'contact', label: 'Contact' },\\n ]}\\n activeId=\\\"home\\\"\\n onItemClick={(item) => navigate(item.id)}\\n orientation=\\\"horizontal\\\"\\n variant=\\\"pills\\\"\\n/>\\n```\\n```\\n\\n### FileUploader\\n\\nProps for the `FileUploader` composition.\\n\\nA drag-and-drop file upload area that composes `Button`, `Progress`, and `Icon` primitives.\\nThe drop zone is a dashed-border container that highlights in `colors.primary[400]`/`colors.primary[50]`\\non drag-over. Below the drop zone, each file in `files` is listed with its name, size,\\noptional progress bar (for uploading status), and a remove button.\\n\\nFile validation (max size, max count) is applied client-side before calling `onFilesSelected`.\\nFiles exceeding `maxSize` are silently filtered out; files exceeding `maxFiles` are truncated.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| files | `UploadedFile[]` | `[]` | Array of files currently in the upload queue, shown below the drop zone. |\\n| onFilesSelected | `(files: File[]) => void` | - | Called when the user selects files via click or drag-and-drop. Receives native `File` objects after client-side filtering (maxSize, maxFiles). |\\n| onFileRemove | `(fileId: string) => void` | - | Called when the user clicks the remove button on a file entry. |\\n| accept | `string` | - | Accepted file types passed to the hidden `<input type=\\\"file\\\" accept=\\\"...\\\">`. E.g., `'image/*,.pdf'`. |\\n| multiple | `boolean` | `true` | When true, allows selecting multiple files at once. |\\n| maxSize | `number` | - | Maximum file size in bytes. Files exceeding this are silently excluded from the selection. |\\n| maxFiles | `number` | - | Maximum number of files. Excess files beyond `maxFiles - files.length` are truncated. |\\n| disabled | `boolean` | - | When true, the drop zone is visually dimmed (opacity 0.5) and non-interactive. |\\n| dragDrop | `boolean` | `true` | When true, enables drag-and-drop on the drop zone. When false, the prompt text changes to \\\"Click to browse files\\\". |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<FileUploader\\n files={uploadedFiles}\\n onFilesSelected={(files) => startUpload(files)}\\n onFileRemove={(id) => removeFile(id)}\\n accept=\\\"image/*,.pdf\\\"\\n multiple\\n maxSize={5 * 1024 * 1024}\\n maxFiles={10}\\n dragDrop\\n/>\\n```\\n```\\n\\n### NotificationCenter\\n\\nProps for the `NotificationCenter` composition.\\n\\nA notification list with a header bar that composes `Button`, `Spinner`, and `Icon`\\nprimitives. The header shows a \\\"Notifications\\\" title, an unread count badge\\n(pill in `colors.primary[100]`), and \\\"Mark all read\\\" / \\\"Clear all\\\" buttons.\\nEach notification item shows a colored status dot, title, message, timestamp,\\n\\\"Mark as read\\\" link, and optional action. The list is scrollable (`overflowY: auto`).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| notifications | `Notification[]` | - | Array of notifications to display, in the order provided. |\\n| onMarkAsRead | `(id: string) => void` | - | Called when the user clicks \\\"Mark as read\\\" on an individual notification. |\\n| onMarkAllAsRead | `() => void` | - | Called when the user clicks the \\\"Mark all read\\\" header button. Only shown when there are unread items. |\\n| onDismiss | `(id: string) => void` | - | Called when the user clicks the dismiss (X) button on an individual notification. |\\n| onClearAll | `() => void` | - | Called when the user clicks the \\\"Clear all\\\" header button. Only shown when there are any notifications. |\\n| emptyText | `string` | `'No notifications'` | Text shown when `notifications` is empty and not loading. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the notification list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<NotificationCenter\\n notifications={[\\n { id: '1', title: 'Deployment complete', type: 'success', timestamp: new Date(), read: false },\\n { id: '2', title: 'Build failed', type: 'error', message: 'Lint errors', timestamp: new Date() },\\n ]}\\n onMarkAsRead={(id) => markRead(id)}\\n onMarkAllAsRead={() => markAllRead()}\\n onDismiss={(id) => dismiss(id)}\\n onClearAll={() => clearAll()}\\n/>\\n```\\n```\\n\\n### Modal\\n\\nProps for the `Modal` composition.\\n\\nA dialog overlay that composes `Button`, `Icon`, and `Heading` primitives.\\nThe overlay uses `animation.fadeIn` (`ggui-fadeIn`) and the dialog panel uses\\n`animation.scaleIn` (`ggui-scaleIn`) — both GPU-composited (opacity + transform).\\nWhen open, `document.body.style.overflow` is set to `'hidden'` to prevent background\\nscrolling, and restored on close. The dialog has `role=\\\"dialog\\\"` and `aria-modal=\\\"true\\\"`.\\n\\nSize widths: `sm` = 400 px, `md` = 500 px, `lg` = 640 px, `xl` = 800 px,\\n`full` = 100vw (no border-radius, no padding).\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| open | `boolean` | - | Controls modal visibility. When false, the component renders nothing. |\\n| onClose | `() => void` | - | Called to close the modal (overlay click, escape key, or close button). |\\n| title | `string` | - | Optional title rendered in the modal header via the `Heading` primitive (level 4). |\\n| children | `ReactNode` | - | Modal body content rendered in a scrollable area (`overflowY: auto`). |\\n| footer | `ReactNode` | - | Footer content rendered below the body, right-aligned with an 8 px gap, separated by a top border. |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg' \\\\| 'xl' \\\\| 'full'` | `'md'` | Controls the width of the modal panel. - `'sm'` — 400 px - `'md'` — 500 px - `'lg'` — 640 px - `'xl'` — 800 px - `'full'` — 100vw, no border-radius, stretches to fill viewport |\\n| closeOnOverlayClick | `boolean` | `true` | When true, clicking the semi-transparent overlay behind the modal calls `onClose`. |\\n| closeOnEscape | `boolean` | `true` | When true, pressing the Escape key calls `onClose`. |\\n| showCloseButton | `boolean` | `true` | When true, renders a ghost close button (X icon) in the modal header. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Modal\\n open={isOpen}\\n onClose={() => setOpen(false)}\\n title=\\\"Confirm Action\\\"\\n size=\\\"md\\\"\\n footer={\\n <>\\n <Button variant=\\\"ghost\\\" onClick={() => setOpen(false)}>Cancel</Button>\\n <Button onClick={handleConfirm}>Confirm</Button>\\n </>\\n }\\n>\\n <p>Are you sure you want to proceed?</p>\\n</Modal>\\n```\\n```\\n\\n### CommandPalette\\n\\nProps for the `CommandPalette` composition.\\n\\nA searchable command menu (Cmd+K / Ctrl+K pattern) that composes `Spinner` and `Icon`\\nprimitives. Appears as a centered overlay at 15vh from the top. Commands are filtered\\nby label and description (case-insensitive substring match). Results are grouped under\\nuppercase section headers. Keyboard navigation is fully supported:\\nArrow Up/Down to navigate, Enter to select, Escape to close.\\n\\nWhen `recentIds` are provided and the search query is empty, matching commands appear\\nin a \\\"Recent\\\" section at the top (deduplicated from their original groups).\\n\\nThe footer shows navigation hints: \\\"Up/Down Navigate\\\", \\\"Enter Select\\\", \\\"Esc Close\\\".\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| open | `boolean` | - | Controls palette visibility. When false, the component renders nothing. |\\n| onClose | `() => void` | - | Called to close the palette (overlay click, Escape key, or after command selection). |\\n| commands | `Command[]` | - | Full array of available commands. Filtered client-side by the search query. |\\n| onSelect | `(command: Command) => void` | - | Called when a non-disabled command is selected (Enter key or click). The palette auto-closes after selection. |\\n| placeholder | `string` | `'Search commands...'` | Placeholder text for the search input. |\\n| recentIds | `string[]` | `[]` | IDs of recently used commands. When the query is empty, these appear in a \\\"Recent\\\" section at the top of the results. |\\n| loading | `boolean` | - | When true, shows a centered `Spinner` instead of the command list. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<CommandPalette\\n open={isOpen}\\n onClose={() => setOpen(false)}\\n commands={[\\n { id: 'new', label: 'New File', shortcut: 'Ctrl+N', group: 'File' },\\n { id: 'save', label: 'Save', shortcut: 'Ctrl+S', group: 'File' },\\n { id: 'theme', label: 'Toggle Theme', group: 'Preferences' },\\n ]}\\n onSelect={(cmd) => executeCommand(cmd.id)}\\n recentIds={['save']}\\n placeholder=\\\"Search commands...\\\"\\n/>\\n```\\n```\\n\\n### Footer\\n\\nProps for the `Footer` composition.\\n\\nA site footer with `role=\\\"contentinfo\\\"` that lays out a brand slot, link columns,\\nsocial icons, and a bottom bar. Does not compose other ggui primitives (uses plain\\nHTML elements). Content is constrained to `max-width: 1280px` with auto margins.\\nLink columns use a responsive flex layout (`flex: 0 1 180px`). The bottom bar\\nincludes copyright text, social links, and bottom-bar links separated by a top border.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| brand | `ReactNode` | - | Brand element (logo, tagline) rendered in a flexible column (`flex: 1 1 280px`). |\\n| columns | `FooterColumn[]` | - | Array of link columns rendered in a flex-wrap layout with 48 px gap. |\\n| socialLinks | `FooterSocialLink[]` | - | Social media icon links rendered in the bottom bar. |\\n| bottomText | `string` | - | Text displayed at the start of the bottom bar (e.g., copyright notice). |\\n| bottomLinks | `FooterLink[]` | - | Links displayed in the bottom bar after social icons (e.g., Privacy, Terms). |\\n| background | `string` | `colors.gray[50]` | Background color of the footer. |\\n| bordered | `boolean` | `true` | When true, renders a 1 px top border in `colors.gray[200]`. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Footer\\n brand={<img src=\\\"/logo.svg\\\" alt=\\\"Acme\\\" />}\\n columns={[\\n { title: 'Product', links: [{ label: 'Features', href: '/features' }] },\\n { title: 'Company', links: [{ label: 'About', href: '/about' }] },\\n ]}\\n socialLinks={[\\n { label: 'Twitter', href: 'https://twitter.com/acme', icon: <TwitterIcon /> },\\n ]}\\n bottomText=\\\"&copy; 2026 Acme Inc.\\\"\\n bottomLinks={[{ label: 'Privacy', href: '/privacy' }]}\\n bordered\\n/>\\n```\\n```\\n\\n### Hero\\n\\nProps for the `Hero` composition.\\n\\nA prominent landing-page hero section that renders heading, description, CTA buttons,\\nand an optional media slot. Does not compose other ggui primitives (uses plain HTML\\nelements styled with design tokens). Content is constrained to `max-width: 1280px`.\\n\\nLayout modes:\\n- `align='center'` — single-column centered layout with `max-width: 800px` text area.\\n- `align='left'` — two-column side-by-side layout (50/50 split with media slot).\\n\\nSize controls vertical padding and font sizes:\\n- `'sm'` — 48 px vertical padding, 3xl heading, lg description.\\n- `'md'` — 80 px vertical padding, 4xl heading, xl description.\\n- `'lg'` — 120 px vertical padding, 5xl heading, xl description.\\n\\nThe primary action button uses `colors.primary[600]` fill; the secondary action uses\\nan outlined style. When `overlay` is true with a `backgroundImage`, text switches to white\\nand borders become semi-transparent.\\n\\n**Props:**\\n\\n| Prop | Type | Default | Description |\\n|------|------|---------|-------------|\\n| heading | `string` | - | Main heading text rendered as an `<h1>` with bold weight and tight line-height. |\\n| description | `string` | - | Description paragraph rendered below the heading with relaxed line-height. |\\n| primaryAction | `HeroAction` | - | Primary CTA button rendered with `colors.primary[600]` background and white text. |\\n| secondaryAction | `HeroAction` | - | Secondary CTA button rendered with a transparent background and a 1 px border. |\\n| media | `ReactNode` | - | Media element (image, video, illustration) rendered beside or below the text content. |\\n| align | `'center' \\\\| 'left'` | `'center'` | Text and layout alignment. - `'center'` — centered single-column layout. - `'left'` — left-aligned text with media in a right column (50/50 split). |\\n| size | `'sm' \\\\| 'md' \\\\| 'lg'` | `'md'` | Controls vertical padding and heading/description font sizes. - `'sm'` — compact (48 px padding, 3xl/lg fonts). - `'md'` — standard (80 px padding, 4xl/xl fonts). - `'lg'` — spacious (120 px padding, 5xl/xl fonts). |\\n| background | `string` | `colors.white (when no backgroundImage is set)` | Background color of the hero section. |\\n| backgroundImage | `string` | - | Background image URL applied as `background-size: cover; background-position: center`. |\\n| overlay | `boolean` | `false` | When true and `backgroundImage` is set, renders a semi-transparent black overlay (`rgba(0,0,0,0.5)`) and switches text to white/semi-transparent white for contrast. |\\n\\n**Example:**\\n```tsx\\n```tsx\\n<Hero\\n heading=\\\"Build Better UIs, Faster\\\"\\n description=\\\"The universal interface layer between AI agents and humans.\\\"\\n primaryAction={{ label: 'Get Started', onClick: () => navigate('/signup') }}\\n secondaryAction={{ label: 'Learn More', href: '/docs' }}\\n media={<img src=\\\"/hero.png\\\" alt=\\\"Hero\\\" />}\\n align=\\\"left\\\"\\n size=\\\"lg\\\"\\n/>\\n```\\n```\\n\\n### Support Types\\n\\n**SidebarItem:**\\n\\nA single navigation entry in a `Sidebar`. Supports nested children for\\ncollapsible sub-menus and an optional badge slot.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier used for active-state matching and React keys. |\\n| label | `string` | Display label for the item. Hidden when the sidebar is collapsed. |\\n| icon | `ReactNode` | Leading icon rendered before the label. Remains visible when collapsed. |\\n| href | `string` | Optional URL associated with this item (not rendered as a link by default). |\\n| badge | `ReactNode` | Trailing badge element (e.g., unread count). Hidden when collapsed. |\\n| children | `SidebarItem[]` | Nested child items. When present, the item acts as a collapsible section (chevron indicator shown). |\\n| disabled | `boolean` | When true, the item is visually dimmed and non-interactive (`cursor: not-allowed`). |\\n\\n**Comment:**\\n\\nA single comment entry in a `CommentThread`. Supports nested replies\\nand emoji reactions with counts.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this comment. |\\n| author | `{ /** Display name of the author. */ name: string; /** URL for the author's avatar image. Passed to the `Avatar` primitive. */ avatar?: string; }` | Comment author metadata. |\\n| content | `string` | The comment body text. |\\n| timestamp | `string \\\\| Date` | Timestamp of the comment. Rendered via `toLocaleString()` when a `Date` object. |\\n| replies | `Comment[]` | Nested reply comments. Each reply is rendered indented 40 px deeper. |\\n| reactions | `{ emoji: string; count: number }[]` | Emoji reactions with their aggregated counts (e.g., `{ emoji: \\\"👍\\\", count: 3 }`). |\\n\\n**DataTableColumn:**\\n\\nColumn definition for a `DataTable`. Controls header text, width, alignment,\\nsorting, and custom cell rendering.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| key | `string` | Property key on the row object used to extract cell values. Also serves as the sort key. |\\n| header | `string` | Column header text displayed in the `<thead>`. |\\n| width | `number \\\\| string` | Column width as a CSS value (number for pixels, string for any CSS unit). |\\n| sortable | `boolean` | When true, the column header is clickable and triggers `onSort`. An arrow icon indicates direction. |\\n| render | `(value: unknown, row: T, index: number) => ReactNode` | Custom cell renderer. When omitted, the raw value is stringified via `String()`. |\\n| align | `'left' \\\\| 'center' \\\\| 'right'` | Text alignment for both header and body cells. |\\n\\n**ChatMessage:**\\n\\nA single message in a `ChatWindow`. Includes sender metadata, delivery status,\\nand a timestamp.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this message. |\\n| content | `string` | The message body text. |\\n| sender | `{ /** Unique ID of the sender. Compared to `currentUserId` to determine alignment. */ id: string; /** Display name of the sender. */ name: string; /** Avatar image URL. Only shown for non-current-user messages (xs size). */ avatar?: string; }` | Sender metadata used for avatar rendering and alignment. |\\n| timestamp | `string \\\\| Date` | Message timestamp. Rendered as `HH:MM` via `toLocaleTimeString` when a `Date` object. |\\n| status | `'sending' \\\\| 'sent' \\\\| 'delivered' \\\\| 'read' \\\\| 'error'` | Delivery status indicator shown on the current user's messages. - `'sending'` — shows a dot bullet - `'sent'` — shows a single checkmark - `'delivered'` — shows double checkmarks - `'read'` — shows double checkmarks (same visual as delivered) - `'error'` — shows an exclamation mark |\\n\\n**NavItem:**\\n\\nA single navigation entry in a `NavigationBar`. Supports nested children\\nfor sub-menus (rendered by the parent via dropdown, not built-in).\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier used for active-state matching and React keys. |\\n| label | `string` | Display label for the navigation link. |\\n| href | `string` | URL for the item. When provided, renders an `<a>` element instead of `<button>`. |\\n| icon | `ReactNode` | Optional icon rendered before the label. |\\n| children | `NavItem[]` | Nested child items (for sub-menu structures; rendering is consumer-defined). |\\n| disabled | `boolean` | When true, the item is visually dimmed (opacity 0.5) and non-interactive. |\\n\\n**UploadedFile:**\\n\\nA file entry in the `FileUploader` composition. Tracks upload progress,\\nstatus, and optional error messages.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this file entry. Used as a key and for removal callbacks. |\\n| name | `string` | Original file name. Rendered with text-overflow ellipsis when too long. |\\n| size | `number` | File size in bytes. Formatted as B/KB/MB/GB for display. |\\n| type | `string` | MIME type of the file (e.g., `'image/png'`). |\\n| progress | `number` | Upload progress as a percentage (0-100). Shown via the `Progress` primitive when status is `'uploading'`. |\\n| status | `'pending' \\\\| 'uploading' \\\\| 'success' \\\\| 'error'` | Current upload lifecycle status. - `'pending'` — file selected but upload not started. - `'uploading'` — upload in progress; `progress` bar is shown. - `'success'` — upload completed. - `'error'` — upload failed; `error` message is shown in `colors.error[500]`. |\\n| error | `string` | Error message displayed when status is `'error'`. |\\n| url | `string` | The remote URL of the uploaded file after successful upload. |\\n\\n**Notification:**\\n\\nA single notification entry in the `NotificationCenter`. Supports semantic type coloring,\\nread state, and an optional inline action button.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this notification. |\\n| title | `string` | Notification title rendered in medium weight. |\\n| message | `string` | Optional body text rendered below the title in a smaller font. |\\n| timestamp | `string \\\\| Date` | Timestamp of the notification. Rendered via `toLocaleString()` when a `Date` object. |\\n| read | `boolean` | Read state. Unread notifications get a `colors.primary[50]` background and a colored status dot matching the notification type. |\\n| type | `'info' \\\\| 'success' \\\\| 'warning' \\\\| 'error'` | Semantic type that controls the status dot color on unread notifications. - `'info'` — `colors.info[500]` (blue) - `'success'` — `colors.success[500]` (green) - `'warning'` — `colors.warning[500]` (amber) - `'error'` — `colors.error[500]` (red) |\\n| icon | `ReactNode` | Optional icon rendered alongside the notification (not used by the default implementation). |\\n| action | `{ /** Button label text. */ label: string; /** Click handler for the action. */ onClick: () => void; }` | Optional inline action button rendered next to the timestamp. |\\n\\n**Command:**\\n\\nA single command entry in a `CommandPalette`. Commands can be grouped,\\nhave keyboard shortcuts, and support a disabled state.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| id | `string` | Unique identifier for this command. |\\n| label | `string` | Display label for the command. Searchable by the palette's query filter. |\\n| description | `string` | Optional description text shown below the label. Also searchable. |\\n| icon | `ReactNode` | Icon rendered at the start of the command row. |\\n| shortcut | `string` | Keyboard shortcut hint displayed at the end of the row in a `<kbd>` element. |\\n| group | `string` | Group name for visual sectioning. Commands with the same group are rendered under a shared header. Defaults to `'Commands'` if omitted. |\\n| disabled | `boolean` | When true, the command is visually dimmed and cannot be selected. |\\n\\n**FooterLink:**\\n\\nA single link entry in a footer column or the bottom bar. Supports both\\n`href` navigation and `onClick` handlers (onClick takes precedence via `preventDefault`).\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Display text for the link. |\\n| href | `string` | URL for the link. |\\n| onClick | `() => void` | Click handler. When provided, `preventDefault` is called on the anchor click. |\\n\\n**FooterColumn:**\\n\\nA named column of links in the `Footer` layout. Each column has an optional title\\nand a list of links rendered as a vertical stack with 10 px gap.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| title | `string` | Column heading rendered as an `<h4>` with semibold weight. |\\n| links | `FooterLink[]` | Links displayed in this column. |\\n\\n**FooterSocialLink:**\\n\\nA social media link in the `Footer` bottom bar. Rendered as an icon-only anchor\\nwith `aria-label` for accessibility.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Accessible label for the social link (used as `aria-label`). |\\n| href | `string` | URL for the social media profile or page. |\\n| icon | `ReactNode` | Icon element rendered inside the anchor (typically an SVG or `Icon` primitive). |\\n\\n**HeroAction:**\\n\\nA call-to-action button definition for the `Hero` composition.\\nUsed for both the primary (filled) and secondary (outlined) action buttons.\\n\\n| Property | Type | Description |\\n|----------|------|-------------|\\n| label | `string` | Button label text. |\\n| onClick | `() => void` | Click handler for the button. |\\n| href | `string` | Optional URL (not used by the default implementation; available for consumer routing). |\\n\\n\\n## System Conventions\\n\\n### onChange Behavior (CRITICAL)\\n\\nAll form control onChange handlers receive the VALUE DIRECTLY, not a React event object.\\n\\n```tsx\\n// CORRECT — onChange receives value directly\\n<Input value={name} onChange={setName} />\\n<Input value={email} onChange={(value) => setEmail(value)} />\\n<Select value={country} onChange={setCountry} options={countries} />\\n<Checkbox checked={agreed} onChange={setAgreed} />\\n\\n// WRONG — DO NOT use e.target.value!\\n<Input value={name} onChange={(e) => setName(e.target.value)} /> // WILL BREAK\\n```\\n\\nApplies to: Input, TextArea, Select, Checkbox, RadioGroup, Slider, Tabs, Accordion.\\n\\n### Available Motion & Animation\\n\\nRender `<MotionKeyframes />` once (anywhere in tree) to enable all keyframes.\\n\\n**Entrance/exit:** fadeIn, fadeOut, slideInUp, slideInDown, scaleIn, scaleOut\\n**State feedback:** flash (background-color highlight), pulse (opacity breathing), bounce (scale overshoot)\\n**Easing:** linear, easeIn, easeOut, easeInOut, spring (bouncy)\\n**Durations:** instant(0ms), fast(100ms), normal(200ms), slow(300ms), slower(500ms)\\n\\n```tsx\\n// Entrance animation on mount\\n<div style={{ animation: 'ggui-fadeIn 200ms ease-out' }}>Content</div>\\n\\n// Stagger list items\\n{items.map((item, i) => (\\n <div key={item.id} style={{ animation: \\\\`ggui-slideInUp 300ms ease-out \\\\${i * 50}ms both\\\\` }}>\\n {item.name}\\n </div>\\n))}\\n\\n// Flash highlight when data changes (e.g., stock price update)\\n// useAnimationKey returns a key that increments when dep changes → remounts element → replays animation\\nconst priceKey = useAnimationKey(stock.price);\\n<div key={priceKey} style={{\\n animation: animation.flash,\\n '--ggui-flash-color': stock.change > 0 ? 'var(--ggui-color-success-100)' : 'var(--ggui-color-error-100)',\\n} as React.CSSProperties}>\\n {stock.price}\\n</div>\\n\\n// Respect reduced-motion preference\\nconst { motionEnabled } = useMotion();\\n<div style={motionEnabled ? { animation: 'ggui-scaleIn 200ms ease-out' } : undefined}>\\n Content\\n</div>\\n```\\n\\n### Elevation System\\n\\n6 levels mapping shadow intensity to z-index for layering:\\n- Level 0: flat (no shadow, z: auto) — inline content\\n- Level 1: sm shadow (z: auto) — cards, sections\\n- Level 2: md shadow (z: 1000) — dropdowns, popovers\\n- Level 3: lg shadow (z: 1200) — sticky banners\\n- Level 4: xl shadow (z: 1400) — modals, dialogs\\n- Level 5: 2xl shadow (z: 1800) — tooltips, toasts\\n\\n### Import Constraints\\n\\nOnly these imports are allowed:\\n- `react`\\n- `@ggui-ai/design` — the whole design system (primitives, components, compositions, and the `Clickable` / `Hoverable` / `Pressable` traits) is one import; there are no subpaths\\n- `@ggui-ai/wire` (wire hooks)\\n\\nNo external libraries (lodash, date-fns, etc.). No fetch(). No eval().\";\n\n/**\n * Get primitives documentation for the UI generator.\n * Returns comprehensive TypeScript interfaces, examples, and usage patterns.\n */\nexport function getPrimitives(): string {\n return PRIMITIVES_DOCUMENTATION;\n}\n\n/**\n * List of all valid primitive names for validation.\n */\nexport const VALID_PRIMITIVES = [\n 'Container',\n 'Card',\n 'Stack',\n 'Row',\n 'Grid',\n 'Box',\n 'Divider',\n 'Spacer',\n 'Text',\n 'Heading',\n 'Button',\n 'Input',\n 'TextArea',\n 'Select',\n 'Checkbox',\n 'Toggle',\n 'RadioGroup',\n 'Slider',\n 'Badge',\n 'Spinner',\n 'Skeleton',\n 'Avatar',\n 'Alert',\n 'Progress',\n 'Image',\n 'Icon',\n 'Link',\n 'Tooltip',\n 'Table',\n 'Tabs',\n 'Toast',\n 'Accordion',\n 'MotionKeyframes',\n 'SearchField',\n 'FormField',\n 'MenuItem',\n 'Tag',\n 'Dropdown',\n 'Autocomplete',\n 'Breadcrumb',\n 'Pagination',\n 'EmptyState',\n 'Stat',\n 'Stepper',\n 'Markdown',\n 'MarkdownInline',\n 'Header',\n 'Sidebar',\n 'CardGrid',\n 'CommentThread',\n 'DataTable',\n 'ChatWindow',\n 'NavigationBar',\n 'FileUploader',\n 'NotificationCenter',\n 'Modal',\n 'CommandPalette',\n 'Footer',\n 'Hero',\n] as const;\n\nexport type ValidPrimitive = (typeof VALID_PRIMITIVES)[number];\n\n/**\n * Check if a primitive name is valid.\n */\nexport function isValidPrimitive(name: string): name is ValidPrimitive {\n return VALID_PRIMITIVES.includes(name as ValidPrimitive);\n}\n","/**\n * The single source of truth for which packages LLM-generated\n * component code may import.\n *\n * Before this module the allowlist was duplicated — as `startsWith`\n * chains, as literal arrays, as hand-written error strings — across\n * `adapters/tools.ts`, `check/run-tier0.ts`, `check/type-checker.ts`\n * and `validation/component-detailed.ts`. The copies had already\n * drifted (one rejected `react-dom`, others allowed it). Every\n * import-validation site now derives from {@link isAllowedImport}.\n *\n * The design system is imported through ONE specifier — `@ggui-ai/design`\n * — never the `/primitives`, `/components`, `/compositions`, `/interact`\n * subpaths. The barrel re-exports every layer, so the generation LLM\n * never has to predict which subpath a component lives in. Subpaths\n * still resolve (the predicate allows any `@ggui-ai/design/...`), but\n * the prompt and catalog teach the barrel exclusively.\n */\n\n/**\n * Static package specifiers generated code may import. A subpath of\n * any base (`<base>/...`) is allowed too. Per-contract gadget packages\n * are dynamic — pass them to {@link isAllowedImport}.\n */\nexport const ALLOWED_IMPORT_BASES = [\n 'react',\n 'react-dom',\n '@ggui-ai/design',\n '@ggui-ai/wire',\n '@ggui-ai/gadgets',\n] as const;\n\n/**\n * True if `specifier` is a package generated component code may import:\n * one of {@link ALLOWED_IMPORT_BASES} (or a subpath of one), or a\n * contract-declared gadget package.\n */\nexport function isAllowedImport(\n specifier: string,\n gadgetPackages?: ReadonlySet<string>,\n): boolean {\n for (const base of ALLOWED_IMPORT_BASES) {\n if (specifier === base || specifier.startsWith(`${base}/`)) return true;\n }\n return gadgetPackages?.has(specifier) ?? false;\n}\n\n/**\n * Human-readable allowed-import list for error messages shown to the\n * generation LLM.\n */\nexport function describeAllowedImports(): string {\n return 'react, @ggui-ai/design, @ggui-ai/wire, @ggui-ai/gadgets, or a gadget package declared on the contract';\n}\n","import { VALID_PRIMITIVES } from './primitives.js';\nimport { isAllowedImport, describeAllowedImports } from './allowed-imports.js';\nimport { DANGEROUS_PATTERNS as SHARED_DANGEROUS_PATTERNS } from '@ggui-ai/protocol';\n\n/**\n * Validation error types for classification\n */\nexport type ValidationErrorType = 'import' | 'primitive' | 'security' | 'syntax' | 'size' | 'structure';\n\n/**\n * Validation warning types\n */\nexport type ValidationWarningType = 'accessibility' | 'best-practice' | 'performance';\n\n/**\n * Detailed validation error with actionable suggestions\n */\nexport interface ValidationError {\n type: ValidationErrorType;\n message: string;\n line?: number;\n column?: number;\n suggestion: string;\n code?: string;\n}\n\n/**\n * Validation warning (non-blocking)\n */\nexport interface ValidationWarning {\n type: ValidationWarningType;\n message: string;\n line?: number;\n suggestion: string;\n}\n\n/**\n * Comprehensive validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n suggestions: string[];\n stats: {\n lineCount: number;\n charCount: number;\n importCount: number;\n primitiveCount: number;\n };\n}\n\n// Size limits\nconst MAX_FILE_SIZE = 50 * 1024; // 50KB\nconst MAX_LINE_COUNT = 500;\n\n// Security patterns — single source of truth in @ggui-ai/protocol.\n// Re-exported here so existing consumers don't break.\nconst DANGEROUS_PATTERNS = SHARED_DANGEROUS_PATTERNS;\n\n/**\n * Extract line number from code for a match\n */\nfunction getLineNumber(code: string, match: RegExpExecArray): number {\n const upToMatch = code.substring(0, match.index);\n return upToMatch.split('\\n').length;\n}\n\n/**\n * Extract imports from code\n */\nfunction extractImports(code: string): Array<{ source: string; line: number }> {\n const imports: Array<{ source: string; line: number }> = [];\n const importRegex = /import\\s+(?:[\\w\\s{},*]+\\s+from\\s+)?['\"]([^'\"]+)['\"]/g;\n let match;\n\n while ((match = importRegex.exec(code)) !== null) {\n imports.push({\n source: match[1],\n line: getLineNumber(code, match),\n });\n }\n\n return imports;\n}\n\n/**\n * Extract primitives used in code\n */\nfunction extractPrimitivesUsed(code: string): string[] {\n // Look for JSX tags that start with capital letters (React components)\n const jsxTagRegex = /<([A-Z][a-zA-Z0-9]*)/g;\n const used = new Set<string>();\n let match;\n\n while ((match = jsxTagRegex.exec(code)) !== null) {\n used.add(match[1]);\n }\n\n return Array.from(used);\n}\n\nexport interface ValidationOptions {\n /**\n * Skip import allowlist validation.\n * Used when bundle mode is enabled — external imports will be resolved\n * by esbuild at build time, not by the runtime.\n * Security patterns (eval, fetch, etc.) are still enforced.\n */\n skipImportValidation?: boolean;\n /**\n * Skip size limits (line count, file size).\n * Used for user-registered UIs where the developer controls the size.\n * LLM-generated UIs keep the limits to constrain generation.\n */\n skipSizeLimits?: boolean;\n /**\n * Skip dangerous-pattern security scan (eval, fetch, location, etc.).\n * Used for user-registered UIs where the developer controls the code.\n * LLM-generated UIs always get the security scan.\n */\n skipSecurityPatterns?: boolean;\n}\n\n/**\n * Validate component code with rich feedback.\n * Returns detailed errors, warnings, and suggestions.\n */\nexport function validateComponentDetailed(code: string, options: ValidationOptions = {}): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n const suggestions: string[] = [];\n const lines = code.split('\\n');\n const lineCount = lines.length;\n const charCount = code.length;\n\n // Size validation — skipped for user-registered UIs (developer controls size)\n if (!options.skipSizeLimits) {\n if (charCount > MAX_FILE_SIZE) {\n errors.push({\n type: 'size',\n message: `Component is too large: ${(charCount / 1024).toFixed(1)}KB exceeds ${MAX_FILE_SIZE / 1024}KB limit`,\n suggestion: 'Split the component into smaller sub-components or simplify the implementation.',\n });\n }\n\n if (lineCount > MAX_LINE_COUNT) {\n errors.push({\n type: 'size',\n message: `Component has too many lines: ${lineCount} exceeds ${MAX_LINE_COUNT} line limit`,\n suggestion: 'Split the component into smaller sub-components.',\n });\n }\n }\n\n // Import validation\n // Skipped in bundle mode — external imports are resolved by esbuild at build time.\n // The ALLOWED_IMPORTS list is for LLM-generated UIs (case 2) where only sandbox-provided\n // packages are available. Developer-registered UIs (case 1) with bundle mode can import anything.\n const imports = extractImports(code);\n if (!options.skipImportValidation) {\n for (const imp of imports) {\n const isAllowed = isAllowedImport(imp.source);\n // `@app/components` is the registered-component mechanism specific\n // to this validator — kept local, not part of the shared\n // design-system import allowlist.\n const isAppComponents =\n imp.source === '@app/components' ||\n imp.source.startsWith('@app/components/');\n if (!isAllowed && !isAppComponents) {\n errors.push({\n type: 'import',\n message: `Invalid import: \"${imp.source}\" is not allowed`,\n line: imp.line,\n suggestion: `Only import from: ${describeAllowedImports()}. Remove this import and use ggui primitives instead.`,\n });\n }\n }\n\n // Check for missing required imports\n if (!imports.some((i) => i.source === 'react')) {\n // Check if useState or other hooks are used\n if (/\\buseState\\b|\\buseEffect\\b|\\buseMemo\\b|\\buseCallback\\b|\\buseRef\\b/.test(code)) {\n warnings.push({\n type: 'best-practice',\n message: 'React hooks are used but react is not explicitly imported',\n suggestion: \"Add: import { useState } from 'react';\",\n });\n }\n }\n\n if (!imports.some((i) => i.source === '@ggui-ai/design')) {\n warnings.push({\n type: 'best-practice',\n message: 'No primitives imported from @ggui-ai/design',\n suggestion:\n \"Import primitives: import { Container, Card, Stack, Text, Button } from '@ggui-ai/design';\",\n });\n }\n } // end skipImportValidation check\n\n // Primitive validation\n const primitivesUsed = extractPrimitivesUsed(code);\n\n // Check if any imports come from @app/components\n const hasAppComponentImport = imports.some((i) => i.source.startsWith('@app/components'));\n\n // Extract component names imported from @app/components\n const importedComponentNames = new Set<string>();\n\n if (hasAppComponentImport) {\n // Match named imports: import { Foo, Bar } from '@app/components'\n const namedImportRegex = /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]@app\\/components['\"]/g;\n let match;\n while ((match = namedImportRegex.exec(code)) !== null) {\n const names = match[1].split(',').map((n) => n.trim().split(' as ')[0].trim());\n for (const name of names) {\n if (name) importedComponentNames.add(name);\n }\n }\n // Match default imports: import Foo from '@app/components/Foo'\n const defaultImportRegex = /import\\s+(\\w+)\\s+from\\s*['\"]@app\\/components\\/[^'\"]+['\"]/g;\n while ((match = defaultImportRegex.exec(code)) !== null) {\n importedComponentNames.add(match[1]);\n }\n }\n\n for (const primitive of primitivesUsed) {\n if (!VALID_PRIMITIVES.includes(primitive as (typeof VALID_PRIMITIVES)[number])) {\n // Check if it's imported from @app/components\n if (importedComponentNames.has(primitive)) {\n continue; // Valid imported component\n }\n\n // Check if it's a user-defined component (starts with capital and not a primitive)\n const isImported = code.includes(`import`) && code.includes(primitive);\n if (!isImported) {\n errors.push({\n type: 'primitive',\n message: `Unknown component: \"${primitive}\" is not a valid ggui primitive`,\n suggestion: `Use one of the valid primitives: ${VALID_PRIMITIVES.slice(0, 10).join(', ')}... or import from @app/components, or define it within this component.`,\n });\n }\n }\n }\n\n // Security validation — skipped for user-registered UIs (developer controls code)\n if (!options.skipSecurityPatterns) {\n for (const { pattern, name, suggestion } of DANGEROUS_PATTERNS) {\n const match = pattern.exec(code);\n if (match) {\n errors.push({\n type: 'security',\n message: `Security violation: ${name} is not allowed`,\n line: getLineNumber(code, match),\n suggestion,\n code: match[0],\n });\n }\n }\n }\n\n // Structure validation\n if (!code.includes('export default')) {\n errors.push({\n type: 'structure',\n message: 'Component must have a default export',\n suggestion: 'Add \"export default\" before your main component function.',\n });\n }\n\n // Check for class components\n if (/class\\s+\\w+\\s+extends\\s+(React\\.)?Component/.test(code)) {\n errors.push({\n type: 'structure',\n message: 'Class components are not allowed',\n suggestion: 'Convert to a functional component using hooks.',\n });\n }\n\n // Best practice warnings\n if (!code.includes('interface') && !code.includes('type ') && code.includes('Props')) {\n warnings.push({\n type: 'best-practice',\n message: 'Props are used but no TypeScript interface is defined',\n suggestion: 'Define a Props interface: interface Props { onSubmit: (data: FormData) => void; }',\n });\n }\n\n // Check for e.target.value pattern (common mistake)\n if (/e\\.target\\.value|event\\.target\\.value/.test(code)) {\n errors.push({\n type: 'syntax',\n message:\n 'Using e.target.value with ggui primitives will fail - onChange receives value directly',\n suggestion:\n 'Change from onChange={(e) => setValue(e.target.value)} to onChange={setValue} or onChange={(value) => setValue(value)}',\n });\n }\n\n // Check for missing key prop in map\n if (code.includes('.map(') && !code.includes('key=')) {\n warnings.push({\n type: 'best-practice',\n message: 'List rendering detected but no key prop found',\n suggestion: 'Add key prop to mapped elements: {items.map(item => <Card key={item.id}>...)}',\n });\n }\n\n // Accessibility warnings\n if (code.includes('<Image') && !code.includes('alt=')) {\n warnings.push({\n type: 'accessibility',\n message: 'Image without alt attribute',\n suggestion: 'Add alt attribute to Image: <Image src={...} alt=\"Description\" />',\n });\n }\n\n // Check form inputs have labels\n const hasInputs = /<Input\\b/.test(code) || /<TextArea\\b/.test(code) || /<Select\\b/.test(code);\n if (hasInputs) {\n const hasLabels = /label=/.test(code) || /htmlFor=/.test(code) || /aria-label=/.test(code) || /aria-labelledby=/.test(code);\n if (!hasLabels) {\n warnings.push({\n type: 'accessibility',\n message: 'Form inputs detected without labels',\n suggestion: 'Add label prop to inputs or associate with <Text is=\"label\" htmlFor=\"id\">. Screen readers need labels to identify form fields.',\n });\n }\n }\n\n // Check forms have role and aria-label\n if ((code.includes('onSubmit') || code.includes('role=\"form\"')) && !code.includes('aria-label')) {\n warnings.push({\n type: 'accessibility',\n message: 'Form without aria-label',\n suggestion: 'Add aria-label to your form container: <Stack role=\"form\" aria-label=\"Contact form\">',\n });\n }\n\n // Check for icon-only buttons without aria-label\n // Match buttons with single-character content (likely icons) and no aria-label\n const iconButtonPattern = /<Button(?![^>]*aria-label)[^>]*>\\s*.\\s*<\\/Button>/;\n if (iconButtonPattern.test(code)) {\n warnings.push({\n type: 'accessibility',\n message: 'Icon-only button detected without text content',\n suggestion: 'Add aria-label to icon-only buttons: <Button aria-label=\"Close\">×</Button>',\n });\n }\n\n if (code.includes('<Button') && !/disabled=|loading=/.test(code)) {\n if (code.includes('onSubmit') || code.includes('submit')) {\n warnings.push({\n type: 'best-practice',\n message: 'Submit button without disabled state',\n suggestion: 'Consider adding disabled={isSubmitting || !isValid} to prevent double submission',\n });\n }\n }\n\n // Generate suggestions based on analysis\n if (errors.length > 0) {\n suggestions.push('Fix all errors before compiling - the component will not work with errors.');\n }\n\n if (errors.some((e) => e.type === 'import')) {\n suggestions.push(\n 'Only react and @ggui-ai/design imports are allowed. All UI should be built with primitives.'\n );\n }\n\n if (errors.some((e) => e.type === 'security')) {\n suggestions.push('Avoid browser APIs - use props and callbacks for data flow.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n suggestions,\n stats: {\n lineCount,\n charCount,\n importCount: imports.length,\n primitiveCount: primitivesUsed.filter((p) =>\n VALID_PRIMITIVES.includes(p as (typeof VALID_PRIMITIVES)[number])\n ).length,\n },\n };\n}\n\n/**\n * Simple validation that throws on error (backward compatible).\n * Use validateComponentDetailed for rich feedback.\n */\nexport function validateComponent(code: string): void {\n const result = validateComponentDetailed(code);\n\n if (!result.valid) {\n const firstError = result.errors[0];\n const lineInfo = firstError.line ? ` (line ${firstError.line})` : '';\n throw new Error(`Validation failed${lineInfo}: ${firstError.message}\\n\\nSuggestion: ${firstError.suggestion}`);\n }\n}\n\n/**\n * Format validation result as a string for Claude feedback.\n * Provides context-rich error messages for the AI to understand and fix issues.\n */\nexport function formatValidationResultForClaude(result: ValidationResult): string {\n if (result.valid && result.warnings.length === 0) {\n return 'Validation passed. Component is ready for compilation.';\n }\n\n const parts: string[] = [];\n\n if (!result.valid) {\n parts.push('## Validation Errors (must fix)\\n');\n for (const error of result.errors) {\n const lineInfo = error.line ? ` (line ${error.line})` : '';\n parts.push(`- **${error.type.toUpperCase()}**${lineInfo}: ${error.message}`);\n parts.push(` - Fix: ${error.suggestion}`);\n if (error.code) {\n parts.push(` - Code: \\`${error.code}\\``);\n }\n }\n }\n\n if (result.warnings.length > 0) {\n parts.push('\\n## Warnings (recommended to fix)\\n');\n for (const warning of result.warnings) {\n const lineInfo = warning.line ? ` (line ${warning.line})` : '';\n parts.push(`- **${warning.type}**${lineInfo}: ${warning.message}`);\n parts.push(` - Suggestion: ${warning.suggestion}`);\n }\n }\n\n if (result.suggestions.length > 0) {\n parts.push('\\n## General Suggestions\\n');\n for (const suggestion of result.suggestions) {\n parts.push(`- ${suggestion}`);\n }\n }\n\n parts.push(\n `\\n## Stats: ${result.stats.lineCount} lines, ${result.stats.primitiveCount} primitives used`\n );\n\n return parts.join('\\n');\n}\n","/**\n * Default design system documentation for the `get_design_system` MCP tool.\n *\n * This large string documents all available CSS variables, design tokens,\n * animation presets, elevation levels, and typography scales. It is served\n * to the LLM when no app-specific design context is configured.\n *\n * Any changes here must stay in sync with the design tokens, CSS\n * variables, and component APIs published by `@ggui-ai/design`\n * (`packages/design/`). A drift between this doc and the real design\n * system causes the LLM to emit styling that the renderer cannot\n * honor.\n */\n\n/** Default light-theme design system documentation served to the LLM. */\nexport const DEFAULT_DESIGN_SYSTEM_DOCS = `# Design System - Default Light Theme\n\n**IMPORTANT:** Always use CSS variables (var(--ggui-*)) for styling to ensure components respect the app theme.\n\n## Colors\n\n### Primary\n- var(--ggui-color-primary-50) - #f0f9ff\n- var(--ggui-color-primary-100) - #e0f2fe\n- var(--ggui-color-primary-200) - #bae6fd\n- var(--ggui-color-primary-300) - #7dd3fc\n- var(--ggui-color-primary-400) - #38bdf8\n- var(--ggui-color-primary-500) - #0ea5e9\n- var(--ggui-color-primary-600) - #0284c7 (main action color)\n- var(--ggui-color-primary-700) - #0369a1\n- var(--ggui-color-primary-800) - #075985\n- var(--ggui-color-primary-900) - #0c4a6e\n\n### Semantic Surface & Text Colors (REQUIRED for theme compatibility)\nThese tokens adapt automatically to any theme (light, dark, branded). **ALWAYS use these for surfaces and text — never use raw neutral-* scale values.**\n\n| Token | CSS Variable | Default | Role |\n|-------|-------------|---------|------|\n| surface | var(--ggui-color-surface) | Main content background |\n| onSurface | var(--ggui-color-onSurface) | Primary text on surface |\n| surfaceVariant | var(--ggui-color-surfaceVariant) | Card/panel background |\n| onSurfaceVariant | var(--ggui-color-onSurfaceVariant) | Muted/secondary text |\n| container | var(--ggui-color-container) | Primary-branded containers |\n| onContainer | var(--ggui-color-onContainer) | Text on branded containers |\n| outline | var(--ggui-color-outline) | Borders, dividers |\n| outlineVariant | var(--ggui-color-outlineVariant) | Subtle borders |\n\n**Usage pattern:**\n- Page/section background → \\`var(--ggui-color-surface)\\`\n- Body text → \\`var(--ggui-color-onSurface)\\`\n- Card/panel background → \\`var(--ggui-color-surfaceVariant)\\`\n- Secondary/muted text → \\`var(--ggui-color-onSurfaceVariant)\\`\n- Branded section/header → \\`var(--ggui-color-container)\\` bg + \\`var(--ggui-color-onContainer)\\` text\n- Borders/dividers → \\`var(--ggui-color-outline)\\` or \\`var(--ggui-color-outlineVariant)\\`\n\n### State Colors\n- var(--ggui-color-success) — success states\n- var(--ggui-color-warning) — warning states\n- var(--ggui-color-error) — error states, destructive actions\n- var(--ggui-color-info) — informational\n\n### IMPORTANT: Color Rules\n- **NEVER** use hardcoded hex colors. ONLY use var(--ggui-color-*) tokens.\n- **NEVER** use rgba(), hsl(), or other CSS color functions with hardcoded values.\n- **NEVER** use raw neutral-* or gray-* scale tokens (neutral-50, neutral-900, etc.) — these are internal to the theme and break in dark mode.\n- **ALWAYS** use semantic tokens for text and backgrounds:\n - Text: \\`var(--ggui-color-onSurface)\\` or \\`var(--ggui-color-onSurfaceVariant)\\`\n - Backgrounds: \\`var(--ggui-color-surface)\\` or \\`var(--ggui-color-surfaceVariant)\\`\n - Borders: \\`var(--ggui-color-outline)\\` or \\`var(--ggui-color-outlineVariant)\\`\n- For branded elements use \\`var(--ggui-color-primary-*)\\` scale tokens — these ARE safe because primary adapts per theme.\n- For card backgrounds use \\`var(--ggui-color-surfaceVariant)\\` or \\`var(--ggui-color-primary-50)\\`\n\n## Spacing\n\nUse \\`var(--ggui-spacing-N)\\` for all padding, gap, and margin values. **Never use raw numbers** like \\`padding={16}\\` — always use the token: \\`padding=\"var(--ggui-spacing-4)\"\\`.\n\n| Token | Value | Common use |\n|-------|-------|------------|\n| var(--ggui-spacing-1) | 4px | Icon gaps, tight spacing |\n| var(--ggui-spacing-2) | 8px | Button padding, small gaps |\n| var(--ggui-spacing-3) | 12px | List item spacing, form gaps |\n| var(--ggui-spacing-4) | 16px | Card padding, section gaps |\n| var(--ggui-spacing-5) | 20px | Medium padding |\n| var(--ggui-spacing-6) | 24px | Container padding, large gaps |\n| var(--ggui-spacing-8) | 32px | Section spacing |\n| var(--ggui-spacing-10) | 40px | Page margins |\n| var(--ggui-spacing-12) | 48px | Hero/large section spacing |\n\n**Quick lookup (px → token):** 4→1, 8→2, 12→3, 16→4, 20→5, 24→6, 28→7, 32→8, 36→9, 40→10, 48→12\n\n**Usage on primitives:**\n\\`\\`\\`tsx\n<Container padding=\"var(--ggui-spacing-6)\">\n <Stack gap=\"var(--ggui-spacing-4)\">\n <Card padding=\"var(--ggui-spacing-4)\">\n <Row gap=\"var(--ggui-spacing-2)\">...</Row>\n </Card>\n </Stack>\n</Container>\n\\`\\`\\`\n\n## Typography\n\n### Font Sizes\n- var(--ggui-font-size-xs) - 12px\n- var(--ggui-font-size-sm) - 14px\n- var(--ggui-font-size-base) - 16px\n- var(--ggui-font-size-lg) - 18px\n- var(--ggui-font-size-xl) - 20px\n- var(--ggui-font-size-2xl) - 24px\n- var(--ggui-font-size-3xl) - 30px\n- var(--ggui-font-size-4xl) - 36px\n\n### Font Weights\n- var(--ggui-font-weight-normal) - 400\n- var(--ggui-font-weight-medium) - 500\n- var(--ggui-font-weight-semibold) - 600\n- var(--ggui-font-weight-bold) - 700\n\n## Border Radius\n- var(--ggui-shape-radius-sm) - 4px\n- var(--ggui-shape-radius-md) - 8px\n- var(--ggui-shape-radius-lg) - 12px\n- var(--ggui-shape-radius-xl) - 16px\n- var(--ggui-shape-radius-full) - 9999px\n\n## Shadows\n- var(--ggui-shape-shadow-sm) - 0 1px 2px rgba(0,0,0,0.05)\n- var(--ggui-shape-shadow-md) - 0 4px 6px -1px rgba(0,0,0,0.1)\n- var(--ggui-shape-shadow-lg) - 0 10px 15px -3px rgba(0,0,0,0.1)\n- var(--ggui-shape-shadow-xl) - 0 20px 25px -5px rgba(0,0,0,0.1)\n\n## Usage Examples (always use ggui primitives — never raw <div>, <button>, <input>)\n\n### Branded section header\n\\`\\`\\`tsx\n<Box padding=\"var(--ggui-spacing-4)\" surface=\"accent\">\n <Heading level={2} tone=\"emphasized\">Contact Us</Heading>\n <Text tone=\"emphasized\">We'd love to hear from you</Text>\n</Box>\n\\`\\`\\`\n\n### Form input\n\\`\\`\\`tsx\n<Input label=\"Email\" placeholder=\"you@example.com\" />\n\\`\\`\\`\n\n### Buttons\n\\`\\`\\`tsx\n<Button variant=\"primary\">Submit</Button>\n<Button variant=\"outline\">Cancel</Button>\n<Button variant=\"ghost\">Skip</Button>\n\\`\\`\\`\n\n### Card with spacing tokens\n\\`\\`\\`tsx\n<Card padding=\"var(--ggui-spacing-4)\" shadow=\"md\">\n <Stack gap=\"var(--ggui-spacing-3)\">\n <Heading level={3}>Title</Heading>\n <Text tone=\"muted\">Description</Text>\n </Stack>\n</Card>\n\\`\\`\\`\n\n### Color usage guide\n- **Semantic roles** (surface, onSurface, container, outline): Use for all surface/text/border decisions — these adapt to any theme\n- **primary-50/100**: Section backgrounds, highlight strips, card headers\n- **primary-200/300**: Borders, dividers, focus rings, input outlines\n- **primary-500/600**: Icons, links, labels, badges, buttons, CTAs\n- **primary-700/800/900**: Headings and text on light primary backgrounds\n- **neutral-***: Only when you need a specific shade that semantic tokens don't cover\n\nThe primary palette is the app's brand — use it throughout (headers, accents, borders, interactive elements), not just on the submit button.\n\n**Note:** Do NOT add fallback values to var() (e.g., var(--ggui-color-surface, #fafafa)). Just use var(--ggui-color-surface) — the theme provides all values.\n\n## Motion & Animation\n\n### Duration Scale\n- \\`instant\\`: 0ms\n- \\`fast\\`: 100ms\n- \\`normal\\`: 200ms\n- \\`slow\\`: 300ms\n- \\`slower\\`: 500ms\n\n### Easing Curves\n- \\`linear\\`: linear\n- \\`easeIn\\`: cubic-bezier(0.4, 0, 1, 1)\n- \\`easeOut\\`: cubic-bezier(0, 0, 0.2, 1)\n- \\`easeInOut\\`: cubic-bezier(0.4, 0, 0.2, 1)\n- \\`spring\\`: cubic-bezier(0.175, 0.885, 0.32, 1.275)\n\n### Transition Presets (import from '@ggui-ai/design/tokens')\n\\`\\`\\`tsx\nimport { duration, easing, transition } from '@ggui-ai/design/tokens';\n// transition.fast → \"100ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.normal → \"200ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.slow → \"300ms cubic-bezier(0.4, 0, 0.2, 1)\"\n// transition.colors → color + background-color + border-color (200ms each)\n// transition.opacity → opacity 200ms\n// transition.transform → transform 200ms\n\\`\\`\\`\n\n### Animation Keyframes\nUse \\`<MotionKeyframes />\\` once in your component to inject all keyframes, then reference by name.\n\n**Entrance / exit** (GPU-composited, transform + opacity):\n- \\`ggui-fadeIn\\` / \\`ggui-fadeOut\\`\n- \\`ggui-slideInUp\\` / \\`ggui-slideInDown\\`\n- \\`ggui-scaleIn\\` / \\`ggui-scaleOut\\`\n\n**State feedback** (color-based, for data-change highlights):\n- \\`ggui-flash\\` — background-color highlight that fades out. Set \\`--ggui-flash-color\\` on the element (default: \\`var(--ggui-color-primary-100)\\`)\n- \\`ggui-pulse\\` — gentle opacity breathing (infinite, for \"live\" indicators)\n- \\`ggui-bounce\\` — subtle scale overshoot (one-shot, for confirmations)\n\n\\`\\`\\`tsx\nimport { MotionKeyframes, useMotion, useAnimationKey } from '@ggui-ai/design';\nimport { animation } from '@ggui-ai/design/tokens';\n\nfunction MyComponent() {\n const { motionEnabled } = useMotion(); // respects prefers-reduced-motion\n return (\n <>\n <MotionKeyframes />\n {/* Entrance animation */}\n <div style={{ animation: motionEnabled ? animation.slideInUp : 'none' }}>\n Content slides in\n </div>\n </>\n );\n}\n\\`\\`\\`\n\n### Retriggering Animations on Data Changes\nWhen data updates (e.g., stock price from a stream), CSS animations don't replay automatically.\nUse \\`useAnimationKey(dep)\\` — returns a key that increments when \\`dep\\` changes, causing React to remount the element and replay the animation.\n\n\\`\\`\\`tsx\nimport { MotionKeyframes, useAnimationKey } from '@ggui-ai/design';\nimport { animation } from '@ggui-ai/design/tokens';\n\n// Flash a stock card green/red when the price changes\nconst priceKey = useAnimationKey(stock.price);\n<div\n key={priceKey}\n style={{\n animation: animation.flash,\n '--ggui-flash-color': stock.change > 0\n ? 'var(--ggui-color-success-100)'\n : 'var(--ggui-color-error-100)',\n } as React.CSSProperties}\n>\n {stock.price}\n</div>\n\\`\\`\\`\n\n## Chart / Data Visualization Colors\nSemantic chart tokens for data visualizations:\n- \\`var(--ggui-color-primary-600)\\` — primary series\n- \\`var(--ggui-color-success-500)\\` — positive / success\n- \\`var(--ggui-color-error-500)\\` — negative / error\n- \\`var(--ggui-color-warning-500)\\` — warning / caution\n- \\`var(--ggui-color-info-500)\\` — informational\n- \\`var(--ggui-color-neutral-400)\\` — neutral series\n- \\`var(--ggui-color-neutral-200)\\` — light background series\n- \\`var(--ggui-color-neutral-600)\\` — dark series\n\n## Accessibility Tokens\n\n### Focus Ring (for keyboard focus states)\n- Color: \\`var(--ggui-color-primary-600)\\`\n- Width: 2px\n- Offset: 2px\n- Style: solid\n\\`\\`\\`tsx\n// Apply to focusable elements:\noutline: '2px solid var(--ggui-color-primary-600)',\noutlineOffset: '2px',\n\\`\\`\\`\n\n### Reduced Motion\nUse \\`useMotion()\\` hook to check user preference. If disabled, set animation/transition to \\`none\\`.\n\n## Elevation System\nSemantic depth levels combining shadow + z-index:\n| Level | Shadow | Z-Index | Use For |\n|-------|--------|---------|---------|\n| 0 | none | 0 | Flat content |\n| 1 | sm | auto | Cards, slight lift |\n| 2 | md | 1000 | Dropdowns, popovers |\n| 3 | lg | 1200 | Banners, sticky bars |\n| 4 | xl | 1400 | Modals, dialogs |\n| 5 | 2xl | 1800 | Tooltips, toasts |\n\n\\`\\`\\`tsx\nimport { elevation } from '@ggui-ai/design/tokens';\n// elevation.level1 → { shadow: 'var(--ggui-shape-shadow-sm)', zIndex: 'auto' }\n// elevation.level2 → { shadow: 'var(--ggui-shape-shadow-md)', zIndex: 1000 }\n<div style={{ boxShadow: elevation.level1.shadow, zIndex: elevation.level1.zIndex }}>\n Card content\n</div>\n\\`\\`\\`\n\n## Typography Presets\n\n### Heading Styles (import { headingStyles } from '@ggui-ai/design/tokens')\n| Level | Size | Weight | Line Height | Letter Spacing |\n|-------|------|--------|-------------|----------------|\n| h1 | 36px | bold (700) | 1.25 | -0.025em |\n| h2 | 30px | bold (700) | 1.25 | -0.025em |\n| h3 | 24px | semibold (600) | 1.375 | 0 |\n| h4 | 20px | semibold (600) | 1.375 | 0 |\n| h5 | 18px | semibold (600) | 1.5 | 0 |\n| h6 | 16px | semibold (600) | 1.5 | 0 |\n\n### Text Sizing\n\\`<Text>\\` composes from \\`size\\` / \\`weight\\` / \\`tone\\` (+ \\`caps\\` for the\nuppercase eyebrow look) — there is no preset text-style table. Line\nheight derives from \\`size\\` automatically (1.5 for xs-base, 1.625 at lg,\ntighter on display sizes).\n\n### Letter Spacing Scale\n- \\`tighter\\`: -0.05em\n- \\`tight\\`: -0.025em\n- \\`normal\\`: 0\n- \\`wide\\`: 0.025em\n- \\`wider\\`: 0.05em\n- \\`widest\\`: 0.1em\n\n### Line Height Scale\n- \\`none\\`: 1\n- \\`tight\\`: 1.25\n- \\`snug\\`: 1.375\n- \\`normal\\`: 1.5\n- \\`relaxed\\`: 1.625\n- \\`loose\\`: 2`;\n","// packages/ui-gen/src/boilerplate/json-schema-ts.ts\n//\n// JSON Schema → TypeScript type string converter.\n//\n// Pure, self-contained, no env reads, no framework deps. Exposed\n// publicly on `@ggui-ai/ui-gen/boilerplate` because it's the primitive\n// that turns a contract's JSON Schema into the `interface Props { ... }`\n// block the boilerplate generator writes.\n\nimport type { JsonSchema } from '@ggui-ai/protocol';\n\n/**\n * Convert a JsonSchema to a TypeScript type string — recursive.\n *\n * Handles: string, number, integer, boolean, null, array (+ tuples), object,\n * enum, oneOf/anyOf (unions), nullable, const, additionalProperties.\n */\nexport function jsonSchemaTypeToTs(schema: JsonSchema): string {\n // ── Union types (oneOf / anyOf) ──\n const unionMembers = schema.oneOf ?? schema.anyOf;\n if (unionMembers?.length) {\n const types = [...new Set(unionMembers.map(s => jsonSchemaTypeToTs(s)))];\n return types.length === 1 ? types[0] : types.join(' | ');\n }\n\n // ── Const (literal type) ──\n if (schema.const !== undefined) {\n return typeof schema.const === 'string' ? `'${schema.const}'` : String(schema.const);\n }\n\n // ── Enum (union of literals) ──\n if (schema.enum?.length) {\n return schema.enum\n .map(v => typeof v === 'string' ? `'${v}'` : String(v))\n .join(' | ');\n }\n\n let result: string;\n\n switch (schema.type) {\n case 'string':\n result = 'string';\n break;\n case 'number':\n case 'integer':\n result = 'number';\n break;\n case 'boolean':\n result = 'boolean';\n break;\n case 'null':\n return 'null';\n\n case 'array': {\n if (schema.items) {\n const itemType = jsonSchemaTypeToTs(schema.items);\n // Use Array<T> for complex object types, T[] for simple\n result = (schema.items.type === 'object' && schema.items.properties)\n ? `Array<${itemType}>`\n : (itemType.includes('|') ? `(${itemType})[]` : `${itemType}[]`);\n } else {\n result = 'unknown[]';\n }\n break;\n }\n\n case 'object': {\n if (schema.properties) {\n const required = schema.required ?? [];\n const fields = Object.entries(schema.properties)\n .map(([key, prop]) => {\n const opt = !required.includes(key);\n return `${key}${opt ? '?' : ''}: ${jsonSchemaTypeToTs(prop)}`;\n })\n .join('; ');\n result = `{ ${fields} }`;\n } else if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n result = `Record<string, ${jsonSchemaTypeToTs(schema.additionalProperties)}>`;\n } else {\n result = 'Record<string, unknown>';\n }\n break;\n }\n\n default:\n result = 'unknown';\n }\n\n // Apply nullable (OpenAPI 3.0 shorthand)\n if (schema.nullable && result !== 'unknown') {\n return `${result} | null`;\n }\n\n return result;\n}\n","// packages/ui-gen/src/check/contract-validation.ts\n//\n// Shared validation utilities for data-contract conformance —\n// deterministic tier-0 gate for `PropsSpec` / `StreamSpec` / `ActionSpec`\n// agreement between the LLM-emitted componentCode and the contract the\n// agent handed to `ggui_render`.\n//\n// Used by:\n// (1) Self-check soft gate in the coding agent\n// (`coding-agent/self-check.ts`) — surfaces mismatches as\n// structured violations for the LLM retry loop.\n// (2) Tier-0 hard gate in the evaluation pipeline — errors (severity\n// `error`) are blocking; warnings surface as advisory.\n// (3) Adapter tool-family wiring for multi-SDK generation runs.\n// (4) Benchmarks + LLM prompt construction — `jsonSchemaTypeToTs` +\n// `propsSpecToTypeScript` + `inferPropsSpecFromSampleData` are\n// pure helpers reused outside the check path. Re-exported here so\n// those callers don't need a separate import for the subpath.\n//\n// Deps are pure: `@ggui-ai/protocol` (public types) + `typescript`\n// (compiler API) + the in-package `jsonSchemaTypeToTs` primitive from\n// `../boilerplate/json-schema-ts.js`.\n\nimport type {\n PropsSpec,\n StreamSpec,\n ActionSpec,\n DataContract,\n JsonSchema,\n JsonValue,\n PropEntry,\n JsonObject,\n} from \"@ggui-ai/protocol\";\nimport ts from \"typescript\";\n\n// Re-export the pure JSON-Schema → TypeScript-type converter from the\n// in-package `boilerplate/` primitive, so consumers of the tier-0 check\n// surface (self-check, tiers, benchmarks, prompts, adapters) import a\n// single symbol from a single subpath.\nexport { jsonSchemaTypeToTs } from \"../boilerplate/json-schema-ts.js\";\nimport { jsonSchemaTypeToTs } from \"../boilerplate/json-schema-ts.js\";\n\n// =============================================================================\n// Contract Issue\n// =============================================================================\n\nexport interface ContractIssue {\n severity: \"error\" | \"warning\";\n field: string;\n message: string;\n fix: string;\n}\n\n// =============================================================================\n// Props Interface Extraction (AST-based)\n// =============================================================================\n\ninterface ExtractedProp {\n name: string;\n type: string;\n optional: boolean;\n}\n\n/**\n * Extract field names and types from a TypeScript Props interface in source code.\n * Uses the TypeScript compiler API — handles nested types, generics, unions correctly.\n */\nexport function extractPropsInterface(code: string): ExtractedProp[] | null {\n const sf = ts.createSourceFile(\"component.tsx\", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n const props: ExtractedProp[] = [];\n\n function visitMembers(members: ts.NodeArray<ts.TypeElement>): void {\n for (const member of members) {\n if (ts.isPropertySignature(member) && member.name) {\n const name = member.name.getText(sf);\n const type = member.type ? member.type.getText(sf) : \"unknown\";\n const optional = !!member.questionToken;\n props.push({ name, type, optional });\n }\n }\n }\n\n function visit(node: ts.Node): void {\n // interface Props { ... }\n if (ts.isInterfaceDeclaration(node) && node.name.text === \"Props\") {\n visitMembers(node.members);\n return;\n }\n // type Props = { ... }\n if (ts.isTypeAliasDeclaration(node) && node.name.text === \"Props\") {\n if (ts.isTypeLiteralNode(node.type)) {\n visitMembers(node.type.members);\n }\n return;\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sf);\n return props.length > 0 ? props : null;\n}\n\n// =============================================================================\n// Contract Validation\n// =============================================================================\n\n/**\n * Compare extracted Props interface against a PropsSpec contract.\n * Returns issues: errors for missing required fields, warnings for type mismatches.\n */\nexport function validatePropsAgainstSchema(\n code: string,\n spec: PropsSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n const extracted = extractPropsInterface(code);\n\n if (!extracted) {\n // Can't extract — not necessarily an error (might use inline types)\n return [];\n }\n\n const extractedMap = new Map(extracted.map((p) => [p.name, p]));\n\n for (const [propName, entry] of Object.entries(spec.properties)) {\n const extractedProp = extractedMap.get(propName);\n\n if (!extractedProp) {\n if (entry.required) {\n issues.push({\n severity: \"error\",\n field: propName,\n message: `Props interface is missing required field '${propName}' from the data contract`,\n fix: `Add \\`${propName}${entry.required ? \"\" : \"?\"}: ${jsonSchemaTypeToTs(entry.schema)}\\` to your Props interface`,\n });\n } else {\n issues.push({\n severity: \"warning\",\n field: propName,\n message: `Props interface is missing optional field '${propName}' from the data contract`,\n fix: `Consider adding \\`${propName}?: ${jsonSchemaTypeToTs(entry.schema)}\\` to your Props interface`,\n });\n }\n continue;\n }\n\n // Basic type compatibility check (only if we have type info)\n if (extractedProp.type !== \"unknown\") {\n const expectedTsType = jsonSchemaTypeToTs(entry.schema);\n if (!isTypeCompatible(extractedProp.type, expectedTsType, entry.schema)) {\n issues.push({\n severity: \"warning\",\n field: propName,\n message: `Field '${propName}' has type '${extractedProp.type}' but contract expects '${expectedTsType}'`,\n fix: `Change \\`${propName}\\` type to \\`${expectedTsType}\\``,\n });\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Check if a TypeScript type string is compatible with a JSON Schema type.\n * Loose comparison — we only check the base type, not full structural equality.\n */\nfunction isTypeCompatible(tsType: string, expectedTsType: string, schema: JsonSchema): boolean {\n const normalized = tsType.replace(/\\s/g, \"\").toLowerCase();\n\n switch (schema.type) {\n case \"string\":\n return normalized.includes(\"string\");\n case \"number\":\n case \"integer\":\n return normalized.includes(\"number\");\n case \"boolean\":\n return normalized.includes(\"boolean\");\n case \"array\":\n return normalized.includes(\"[]\") || normalized.includes(\"array\");\n case \"object\":\n return ![\"string\", \"number\", \"boolean\"].some((t) => normalized === t);\n default:\n return true;\n }\n}\n\n// =============================================================================\n// JSON Schema → TypeScript Conversion (for LLM prompts)\n// =============================================================================\n\n// `jsonSchemaTypeToTs` lives in `@ggui-ai/ui-gen/boilerplate` and is\n// re-exported at the top of this file.\n\n/**\n * Convert a full PropsSpec to a TypeScript interface string for LLM prompt injection.\n * Includes required/optional markers and descriptions as comments.\n */\nexport function propsSpecToTypeScript(spec: PropsSpec, indent = 2): string {\n const pad = \" \".repeat(indent);\n const lines: string[] = [];\n\n for (const [propName, entry] of Object.entries(spec.properties)) {\n if (entry.description) {\n lines.push(`${pad}/** ${entry.description} */`);\n }\n const optional = !entry.required;\n const tsType = jsonSchemaTypeToTs(entry.schema);\n const defaultStr = entry.default !== undefined ? ` // default: ${JSON.stringify(entry.default)}` : \"\";\n lines.push(`${pad}${propName}${optional ? \"?\" : \"\"}: ${tsType};${defaultStr}`);\n // Include example as a comment so the LLM sees the exact data shape\n if (entry.example !== undefined) {\n const exampleStr = JSON.stringify(entry.example, null, 2)\n .split(\"\\n\")\n .map((l, i) => (i === 0 ? `${pad}// Example: ${l}` : `${pad}// ${l}`))\n .join(\"\\n\");\n lines.push(exampleStr);\n }\n }\n\n return `{\\n${lines.join(\"\\n\")}\\n}`;\n}\n\n// =============================================================================\n// StreamSpec Validation\n// =============================================================================\n\n/**\n * Validate that the generated source code properly handles stream events.\n * Requires useStream() wire hooks — legacy DOM event patterns are no longer accepted.\n */\nexport function validateStreamSpecConformance(\n code: string,\n spec: StreamSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n const usesWireStream = code.includes(\"useStream\");\n\n if (!usesWireStream) {\n issues.push({\n severity: \"error\",\n field: \"__streamSpec__\",\n message: \"Component does not handle stream events — use useStream() from the boilerplate wire hooks\",\n fix: \"Use the useStream('eventName') hook from the boilerplate to receive real-time data from the agent\",\n });\n return issues;\n }\n\n // Check each declared channel is referenced in the code. `spec` is a\n // flat `Record<channelName, StreamChannelEntry>` — iterate directly.\n for (const [channelName, entry] of Object.entries(spec)) {\n if (!code.includes(`'${channelName}'`) && !code.includes(`\"${channelName}\"`)) {\n issues.push({\n severity: \"warning\",\n field: channelName,\n message: `StreamSpec declares channel '${channelName}' but component doesn't reference it`,\n fix: `Add useStream('${channelName}') to receive ${entry.description || channelName} events`,\n });\n }\n }\n\n return issues;\n}\n\n// =============================================================================\n// ActionSpec Validation\n// =============================================================================\n\n/**\n * Validate that the generated source code wires the declared actions.\n * Checks that action IDs are referenced via useAction() wire hooks, string literals, or prop callbacks.\n */\nexport function validateActionSpecConformance(\n code: string,\n spec: ActionSpec,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n // `spec` is a flat `Record<actionId, ActionEntry>` — iterate directly.\n for (const [actionId, entry] of Object.entries(spec)) {\n // Check the action ID or its label is referenced in the code\n const idReferenced = code.includes(`'${actionId}'`) || code.includes(`\"${actionId}\"`);\n const labelReferenced = code.includes(entry.label);\n const callbackName = `on${actionId.charAt(0).toUpperCase()}${actionId.slice(1)}`;\n const callbackReferenced = code.includes(callbackName);\n\n if (!idReferenced && !labelReferenced && !callbackReferenced) {\n issues.push({\n severity: \"error\",\n field: actionId,\n message: `ActionSpec declares action '${actionId}' (\"${entry.label}\") but component doesn't wire it`,\n fix: `Use the useAction('${actionId}') hook from the boilerplate and wire it to a button or form submit`,\n });\n }\n }\n\n return issues;\n}\n\n// =============================================================================\n// Unified Contract Validation\n// =============================================================================\n\n/**\n * Validate all contract (props, stream, actions) against the source code.\n * Returns combined issues from all three validations.\n */\nexport function validateAllContracts(\n code: string,\n contract: DataContract,\n): ContractIssue[] {\n const issues: ContractIssue[] = [];\n\n if (contract.propsSpec) {\n issues.push(...validatePropsAgainstSchema(code, contract.propsSpec));\n }\n\n if (contract.streamSpec) {\n issues.push(...validateStreamSpecConformance(code, contract.streamSpec));\n }\n\n if (contract.actionSpec) {\n issues.push(...validateActionSpecConformance(code, contract.actionSpec));\n }\n\n return issues;\n}\n\n// =============================================================================\n// Sample Data → PropsSpec Inference (backward compat)\n// =============================================================================\n\n/**\n * Infer a PropsSpec from sample data.\n * Convenience utility for migration and for agents that pass sample data instead of schemas.\n * All fields are marked as required (can't distinguish required/optional from data alone).\n */\nexport function inferPropsSpecFromSampleData(data: JsonObject): PropsSpec {\n const properties: Record<string, PropEntry> = {};\n\n for (const [key, value] of Object.entries(data)) {\n properties[key] = {\n schema: inferJsonSchema(value),\n required: true,\n example: value as JsonValue,\n };\n }\n\n return { properties };\n}\n\nfunction inferJsonSchema(value: unknown): JsonSchema {\n if (value === null || value === undefined) return { type: \"null\" };\n if (typeof value === \"string\") return { type: \"string\" };\n if (typeof value === \"number\") return { type: \"number\" };\n if (typeof value === \"boolean\") return { type: \"boolean\" };\n\n if (Array.isArray(value)) {\n if (value.length === 0) return { type: \"array\" };\n return {\n type: \"array\",\n items: inferJsonSchema(value[0]),\n };\n }\n\n if (typeof value === \"object\") {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const [k, v] of Object.entries(value as JsonObject)) {\n properties[k] = inferJsonSchema(v);\n required.push(k);\n }\n return { type: \"object\", properties, required };\n }\n\n return { type: \"string\" };\n}\n","// packages/ui-gen/src/check/type-checker.ts\n//\n// TypeScript type-checker for LLM-generated UI components. Uses the\n// TypeScript compiler API with a virtual filesystem to type-check TSX\n// code against React types and `@ggui-ai/design` primitives, giving\n// the LLM familiar TS error feedback without writing anything to disk.\n//\n// The checker builds a virtual filesystem seeded with `typescript/lib`,\n// `@types/react`, `@ggui-ai/design/dist`, and `@ggui-ai/wire/dist`\n// `.d.ts` content, then drives `ts.createProgram` against a synthetic\n// `Component.tsx`. Exposed on `@ggui-ai/ui-gen/check` so\n// `createUiGenerator` runs the same tier-0 gate as the hosted\n// generation path.\n//\n// Path-resolution note: the three workspace-rooted lookups —\n// `.pnpm/@types+react@*`, `packages/design/dist`, and\n// `packages/wire/dist` — are anchored relative to this file. tsup\n// bundles `src/check/index.ts` (splitting: false) into a flat\n// `dist/check/index.js`, so the src and dist locations sit at the same\n// depth and both resolve correctly. `typescript/lib/typescript.js`\n// keeps using `createRequire(import.meta.url).resolve` —\n// position-independent, so no change.\n//\n// Used by:\n// (1) Tier-0 `type_check` — blocking errors (see BLOCKING_CODES)\n// map to PRODUCTION_FAILED; non-blocking TS diagnostics surface\n// as warnings so the LLM can iterate on non-crash-risk findings\n// without stalling the harness.\n// (2) The `self_check` tool — called from generator SDKs (Anthropic /\n// OpenAI / Google) to give the LLM TS feedback mid-generation.\n// (3) The tier-0 orchestrator `runTier0Checks` — runs in parallel\n// with the wire-preservation + lint checks under the same tier\n// budget.\n//\n// Design notes that motivate non-obvious choices:\n// - Classic React JSX mode (`ts.JsxEmit.React`). The synthetic\n// prefix (see SYNTHETIC_PREFIX) supplies `import React from\n// 'react'` for the classic JSX factory PLUS a self-contained\n// global `JSX` namespace. `@types/react` v19 removed the global\n// `JSX` namespace that classic mode resolves intrinsic elements +\n// the `key`/`ref` carve-out through; without the shim, `<div>`\n// degrades to `any` and every typed component falsely rejects the\n// intrinsic `key` prop. Automatic mode was tried but its\n// `react/jsx-runtime` resolution does not survive the VFS.\n// - `strict: false` + `strictNullChecks: true`: we want the runtime\n// crash classes (`undefined.foo()`, `null.bar`) to surface as\n// blocking, but not the optional-chaining / exhaustive-check\n// noise that full `strict` would emit on LLM code.\n// - `types: []`: prevents the VFS from auto-pulling every\n// `@types/*` package that happens to be hoisted — only react and\n// the design/wire dist types should be reachable, matching the\n// forbidden-import policy enforced by `react-linter` elsewhere.\n// - TS2307 (\"Cannot find module\") is deliberately NOT blocking —\n// Lambda bundles code without type declarations, so the VFS can't\n// see every package that may exist at runtime. Forbidden imports\n// are caught by `runSelfChecks` regex instead.\n\nimport ts from 'typescript';\nimport fs from 'fs';\nimport path from 'path';\nimport { createRequire } from 'module';\nimport { describeAllowedImports } from '../validation/allowed-imports.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface TypeCheckDiagnostic {\n code: number;\n line: number;\n message: string;\n fix: string;\n}\n\nexport interface TypeCheckResult {\n errors: TypeCheckDiagnostic[]; // Blocking\n warnings: TypeCheckDiagnostic[]; // Non-blocking\n}\n\n// ---------------------------------------------------------------------------\n// Blocking error codes — these would break at runtime\n// ---------------------------------------------------------------------------\n\nconst BLOCKING_CODES = new Set([\n 2304, // Cannot find name\n // 2307 (Cannot find module) is NOT blocking — Lambda bundles code without\n // type declarations, so the VFS can't resolve react/@ggui-ai/design.\n // Forbidden imports are caught by runSelfChecks regex instead.\n 2305, // Module has no exported member\n 2322, // Type not assignable\n 2339, // Property does not exist on type\n 2741, // Missing required property\n 2769, // No overload matches this call\n 17004, // Cannot use JSX unless '--jsx' flag\n 18047, // 'X' is possibly 'null' — causes runtime crash\n 18048, // 'X' is possibly 'undefined' — causes runtime crash\n]);\n\n// ---------------------------------------------------------------------------\n// Fix suggestions per error code\n// ---------------------------------------------------------------------------\n\nfunction generateFix(code: number, message?: string, sourceLine?: string): string {\n // Source-line hint: when the failing line is short and self-contained,\n // appending it gives the LLM a precise target. Skip for very long lines\n // (>140 chars — usually multi-prop JSX where the line itself is the\n // diagnostic) since they bloat the violation envelope without helping.\n const sourceHint =\n sourceLine && sourceLine.length > 0 && sourceLine.length <= 140\n ? ` Offending line: \\`${sourceLine}\\``\n : '';\n\n // Detect event handler on non-interactive primitive\n if ((code === 2322 || code === 2339) && message && /onClick|onDoubleClick|onMouseEnter|onMouseLeave|onPress/.test(message)) {\n return `This structural primitive has no event handlers of its own — add the trait as a PROP: as={Clickable} (then onClick works), imported from @ggui-ai/design. Do NOT wrap it in <Clickable>…</Clickable>; as is a prop, not a wrapper element.${sourceHint}`;\n }\n\n // Detect underscore-prefix-on-prop trap: `Property '_X' does not exist`.\n // LLM saw an unused-var warning on `X` and tried to silence it by renaming\n // the destructure to `_X`, breaking prop access. Steer back.\n if (code === 2339 && message && /Property '_[a-zA-Z]/.test(message)) {\n return `You renamed a prop with a leading underscore to silence \\`no-unused-vars\\`, but the prop on \\`Props\\` doesn't have that prefix. Restore the original name; better, don't destructure props you won't render — access them via \\`props.fieldName\\` only when needed.${sourceHint}`;\n }\n\n // Detect \"Cannot find name\" for destructured props\n if (code === 2304 && message && !message.includes('module') && !message.includes('import')) {\n return `This name is not defined in scope. Either you destructured props (use \\`props.fieldName\\` directly instead) OR you removed a helper declaration in this patch but kept a JSX/expression reference to it. Read your full patch and either restore the declaration or remove the reference.${sourceHint}`;\n }\n\n // Detect \"unknown is not assignable to ReactNode\"\n if ((code === 2322 || code === 2769) && message && /unknown.*ReactNode|ReactNode.*unknown/.test(message)) {\n return `This value has type 'unknown' and cannot be rendered in JSX. Cast it: String(value) or add a type annotation.${sourceHint}`;\n }\n\n switch (code) {\n case 2307:\n return `Only these imports are allowed: ${describeAllowedImports()}${sourceHint}`;\n case 2322:\n case 2769:\n return `Type mismatch on this expression. Check the offending line below — the prop name in JSX is what TypeScript is rejecting; the message tells you the expected type.${sourceHint}`;\n case 2339:\n return `This prop doesn't exist on this component — check the available props on the component's interface (visible at the top of the file, or in the design-system reference).${sourceHint}`;\n case 2305:\n return `This name is not defined. Check your imports and variable declarations.${sourceHint}`;\n case 2741:\n return `A required prop is missing. Check the component's Props interface.${sourceHint}`;\n case 18047:\n case 18048:\n return `This value might be null/undefined. Every dereference on the same nullable still needs \\`?.\\` — \\`x?.foo && x?.bar\\`, NOT \\`x?.foo && x.bar\\`. Or hoist: \\`const v = x; if (!v) return null;\\` then access \\`v.foo\\`/\\`v.bar\\` unguarded.${sourceHint}`;\n default:\n return `Review the TypeScript error and fix the type issue.${sourceHint}`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Virtual Filesystem — lazy singleton\n// ---------------------------------------------------------------------------\n\ninterface VfsEntry {\n content: string;\n sourceFile: ts.SourceFile;\n}\n\nlet vfsCache: Map<string, VfsEntry> | null = null;\n\nfunction parseAndStore(\n vfs: Map<string, VfsEntry>,\n virtualPath: string,\n content: string,\n): void {\n const sourceFile = ts.createSourceFile(\n virtualPath,\n content,\n ts.ScriptTarget.ES2020,\n true,\n virtualPath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n vfs.set(virtualPath, { content, sourceFile });\n}\n\n/**\n * Recursively walk a directory and return all file paths matching a filter.\n */\nfunction walkDir(dir: string, filter: (f: string) => boolean): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...walkDir(full, filter));\n } else if (filter(full)) {\n results.push(full);\n }\n }\n return results;\n}\n\n/**\n * Resolve `@types/react`'s root directory through Node's module\n * resolution. Position-independent — walks the consumer's node_modules\n * chain. Works in monorepo (where the type package is hoisted under\n * `<root>/node_modules/.pnpm/@types+react@*`) and in standalone\n * `packages/`-only installs (e.g. the projected public OSS repo where\n * the `packages/` prefix is stripped, so a hardcoded `../../../..`\n * walk lands in the wrong place).\n */\nfunction findReactTypesDir(): string | null {\n try {\n // `@types/react` doesn't expose `package.json` as a public subpath,\n // so resolve via the always-present `index.d.ts`.\n const indexDts = createRequire(import.meta.url).resolve('@types/react/index.d.ts');\n return path.dirname(indexDts);\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a workspace package's `dist/` directory through Node's\n * module resolution. Like `findReactTypesDir`, this works in both\n * monorepo (where the package is hoisted/symlinked) and standalone\n * installs — no relative-path math required.\n */\nfunction findPackageDistDir(pkg: string): string | null {\n try {\n const pkgJson = createRequire(import.meta.url).resolve(`${pkg}/package.json`);\n const dist = path.join(path.dirname(pkgJson), 'dist');\n return fs.existsSync(dist) ? dist : null;\n } catch {\n return null;\n }\n}\n\nasync function loadVfs(): Promise<Map<string, VfsEntry>> {\n if (vfsCache) return vfsCache;\n\n const vfs = new Map<string, VfsEntry>();\n\n // ---- 1. TypeScript lib files ----\n // `createRequire(import.meta.url).resolve('typescript/lib/typescript.js')`\n // is position-independent — it walks the consumer's node_modules chain,\n // so this lookup works identically from core/, packages/ui-gen/, and any\n // future host package.\n const require_ = createRequire(import.meta.url);\n const tsDir = path.dirname(require_.resolve('typescript/lib/typescript.js'));\n const libFiles = fs.readdirSync(tsDir).filter((f) => /^lib\\..*\\.d\\.ts$/.test(f));\n for (const file of libFiles) {\n const content = fs.readFileSync(path.join(tsDir, file), 'utf-8');\n parseAndStore(vfs, file, content);\n }\n\n // ---- 2. React types ----\n // Resolved through `createRequire(import.meta.url).resolve('@types/\n // react/index.d.ts')` — position-independent. Works the same in\n // monorepo (hoisted to root) and in standalone `packages/`-only\n // installs (the projected public OSS repo strips the `packages/`\n // prefix, so a hardcoded `../../../..` walk would miss).\n const reactDir = findReactTypesDir();\n if (reactDir) {\n const reactDts = fs.readdirSync(reactDir).filter((f) => f.endsWith('.d.ts'));\n for (const file of reactDts) {\n const content = fs.readFileSync(path.join(reactDir, file), 'utf-8');\n parseAndStore(vfs, `node_modules/@types/react/${file}`, content);\n }\n }\n\n // ---- 3. Design system types ----\n const designDist = findPackageDistDir('@ggui-ai/design');\n if (designDist) {\n const dtsFiles = walkDir(designDist, (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'));\n for (const file of dtsFiles) {\n const rel = path.relative(designDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/design/${rel}`, content);\n }\n }\n\n // ---- 4. Wire module types ----\n const wireDist = findPackageDistDir('@ggui-ai/wire');\n if (wireDist) {\n const dtsFiles = walkDir(wireDist, (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'));\n for (const file of dtsFiles) {\n const rel = path.relative(wireDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/wire/${rel}`, content);\n }\n }\n\n // ---- 5. Gadgets types ----\n // Generated component code direct-imports standard-library gadget\n // hooks — `import { useGeolocation } from '@ggui-ai/gadgets'`.\n // Loading the `@ggui-ai/gadgets` package's shipped `.d.ts` into the\n // VFS makes those bare-named imports resolve against the real hook\n // declarations (named option/return types preserved). The standard\n // gadget hooks are plain named exports the resolver finds directly.\n const clientLibsDist = findPackageDistDir('@ggui-ai/gadgets');\n if (clientLibsDist) {\n const dtsFiles = walkDir(\n clientLibsDist,\n (f) => f.endsWith('.d.ts') && !f.endsWith('.d.ts.map'),\n );\n for (const file of dtsFiles) {\n const rel = path.relative(clientLibsDist, file);\n const content = fs.readFileSync(file, 'utf-8');\n parseAndStore(vfs, `node_modules/@ggui-ai/gadgets/${rel}`, content);\n }\n }\n\n vfsCache = vfs;\n return vfs;\n}\n\n// ---------------------------------------------------------------------------\n// Module resolution helper\n// ---------------------------------------------------------------------------\n\n/**\n * Try to resolve a relative import within the VFS.\n * Given `containingFile` (e.g. `node_modules/@ggui-ai/design/primitives/index.d.ts`)\n * and `importPath` (e.g. `./Card`), try:\n * - <resolved>.d.ts\n * - <resolved>/index.d.ts\n * - <resolved>.ts\n */\nfunction resolveRelativeInVfs(\n vfs: Map<string, VfsEntry>,\n containingFile: string,\n importPath: string,\n): string | undefined {\n // Strip leading '/' from containingFile — TS may prepend getCurrentDirectory()\n const normalized = containingFile.startsWith('/') ? containingFile.slice(1) : containingFile;\n const dir = path.posix.dirname(normalized);\n const resolved = path.posix.normalize(`${dir}/${importPath}`);\n\n // Try .d.ts extension\n const withDts = `${resolved}.d.ts`;\n if (vfs.has(withDts)) return withDts;\n\n // Try /index.d.ts\n const withIndexDts = `${resolved}/index.d.ts`;\n if (vfs.has(withIndexDts)) return withIndexDts;\n\n // Try .ts extension\n const withTs = `${resolved}.ts`;\n if (vfs.has(withTs)) return withTs;\n\n // Might already be the exact path\n if (vfs.has(resolved)) return resolved;\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// CompilerHost factory\n// ---------------------------------------------------------------------------\n\nconst COMPILER_OPTIONS: ts.CompilerOptions = {\n target: ts.ScriptTarget.ES2020,\n module: ts.ModuleKind.ESNext,\n // Classic React JSX mode. The synthetic prefix (SYNTHETIC_PREFIX)\n // supplies `import React from 'react'` plus a `declare global` JSX\n // namespace shim: `@types/react` v19 removed the *global* `JSX`\n // namespace (it lives at `React.JSX` now), which classic mode needs\n // for `JSX.IntrinsicElements` and the `key`/`ref` carve-out. Without\n // the shim, `<div>` degrades to `any` and every typed component\n // falsely rejects the intrinsic `key` prop.\n jsx: ts.JsxEmit.React,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n strict: false,\n strictNullChecks: true, // Catch undefined.foo() errors that cause runtime crashes\n noEmit: true,\n skipLibCheck: true,\n noImplicitAny: true,\n types: [],\n esModuleInterop: true,\n};\n\n/**\n * Normalize a path that TS's internal module resolution might generate.\n * Since getCurrentDirectory() returns '/', TS will probe paths like\n * '/node_modules/@types/react/jsx-runtime.d.ts'. We strip the leading\n * '/' to match our VFS keys.\n */\nfunction normalizeVfsPath(f: string): string | null {\n if (f.startsWith('/')) {\n return f.slice(1);\n }\n return null;\n}\n\n/**\n * Core module resolution logic shared between resolveModuleNameLiterals\n * (for user imports) and resolveModuleNames (for TS-internal imports\n * like jsxImportSource).\n */\nfunction resolveModuleName(\n vfs: Map<string, VfsEntry>,\n name: string,\n containingFile: string,\n): ts.ResolvedModuleWithFailedLookupLocations {\n // React core\n if (name === 'react') {\n return resolved('node_modules/@types/react/index.d.ts');\n }\n if (name === 'react/jsx-runtime') {\n return resolved('node_modules/@types/react/jsx-runtime.d.ts');\n }\n if (name === 'react/jsx-dev-runtime') {\n const p = 'node_modules/@types/react/jsx-dev-runtime.d.ts';\n if (vfs.has(p)) return resolved(p);\n return resolved('node_modules/@types/react/jsx-runtime.d.ts');\n }\n\n // @ggui-ai/design sub-paths\n const designPrefix = '@ggui-ai/design/';\n if (name.startsWith(designPrefix)) {\n const subpath = name.slice(designPrefix.length);\n const indexPath = `node_modules/@ggui-ai/design/${subpath}/index.d.ts`;\n if (vfs.has(indexPath)) return resolved(indexPath);\n const directPath = `node_modules/@ggui-ai/design/${subpath}.d.ts`;\n if (vfs.has(directPath)) return resolved(directPath);\n }\n\n // @ggui-ai/design root\n if (name === '@ggui-ai/design') {\n return resolved('node_modules/@ggui-ai/design/index.d.ts');\n }\n\n // @ggui-ai/wire\n if (name === '@ggui-ai/wire') {\n return resolved('node_modules/@ggui-ai/wire/index.d.ts');\n }\n\n // @ggui-ai/gadgets — the STDLIB gadget package. Generated\n // code direct-imports the seven STDLIB hooks (`useGeolocation`, …)\n // as plain named exports from this specifier. The shipped `.d.ts`\n // (loaded into the VFS above) carries their real declarations.\n if (name === '@ggui-ai/gadgets') {\n return resolved('node_modules/@ggui-ai/gadgets/index.d.ts');\n }\n\n // Relative imports — resolve within VFS\n if (name.startsWith('./') || name.startsWith('../')) {\n const resolvedPath = resolveRelativeInVfs(vfs, containingFile, name);\n if (resolvedPath) return resolved(resolvedPath);\n }\n\n // Third-party gadget wrapper packages. The render handler fetches each\n // non-stdlib gadget's `.d.ts` and `typecheck` overlays it at\n // `node_modules/<package>/index.d.ts`. A generated direct import\n // `import { useX } from '<package>'` resolves through this\n // bare-specifier branch against the overlaid `.d.ts` — named\n // option/return types preserved instead of collapsing to `any`.\n // Generic VFS lookup — no per-package allow-list.\n const bareIndex = `node_modules/${name}/index.d.ts`;\n if (vfs.has(bareIndex)) return resolved(bareIndex);\n\n // Unknown module\n return { resolvedModule: undefined };\n}\n\nfunction createVfsHost(\n vfs: Map<string, VfsEntry>,\n componentCode: string,\n): ts.CompilerHost {\n // Create fresh source file for the user component\n const componentFile = ts.createSourceFile(\n 'Component.tsx',\n componentCode,\n ts.ScriptTarget.ES2020,\n true,\n ts.ScriptKind.TSX,\n );\n\n const host: ts.CompilerHost = {\n getSourceFile(fileName: string) {\n if (fileName === 'Component.tsx') return componentFile;\n const entry = vfs.get(fileName);\n if (entry) return entry.sourceFile;\n // Try normalized path (strip leading '/')\n const normalized = normalizeVfsPath(fileName);\n if (normalized) return vfs.get(normalized)?.sourceFile;\n return undefined;\n },\n getDefaultLibFileName() {\n return 'lib.es2020.full.d.ts';\n },\n writeFile() {\n // no-op\n },\n getCurrentDirectory() {\n return '/';\n },\n getCanonicalFileName(f: string) {\n return f;\n },\n useCaseSensitiveFileNames() {\n return true;\n },\n getNewLine() {\n return '\\n';\n },\n fileExists(f: string) {\n if (f === 'Component.tsx' || vfs.has(f)) return true;\n // Normalize bare-specifier lookups that TS's internal resolver\n // turns into relative-looking paths from getCurrentDirectory '/'.\n const normalized = normalizeVfsPath(f);\n if (normalized && vfs.has(normalized)) return true;\n return false;\n },\n readFile(f: string) {\n if (f === 'Component.tsx') return componentCode;\n const direct = vfs.get(f);\n if (direct) return direct.content;\n const normalized = normalizeVfsPath(f);\n if (normalized) return vfs.get(normalized)?.content;\n return undefined;\n },\n resolveModuleNameLiterals(\n moduleLiterals: readonly ts.StringLiteralLike[],\n containingFile: string,\n ): readonly ts.ResolvedModuleWithFailedLookupLocations[] {\n return moduleLiterals.map((literal) =>\n resolveModuleName(vfs, literal.text, containingFile),\n );\n },\n };\n\n return host;\n}\n\nfunction resolved(resolvedFileName: string): ts.ResolvedModuleWithFailedLookupLocations {\n return {\n resolvedModule: {\n resolvedFileName,\n isExternalLibraryImport: true,\n extension: ts.Extension.Dts,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport async function typecheck(\n code: string,\n /**\n * A `package -> .d.ts content` map for third-party gadget wrappers.\n * The render handler parallel-fetches each non-stdlib gadget's `.d.ts`\n * (via `GadgetDescriptor.typesUrl` + SRI) and threads the result\n * here. Each entry is overlaid into the per-call VFS at\n * `node_modules/<package>/index.d.ts`. A generated direct import\n * `import { useX } from '<package>'` resolves through the\n * bare-specifier branch in `resolveModuleName` directly against this\n * overlaid entry — named option/return types preserved, so a\n * wrong-typed hook call surfaces a blocking TS error instead of\n * collapsing to `any`.\n *\n * Stdlib gadgets (`package: '@ggui-ai/gadgets'`) need no entry —\n * `@ggui-ai/gadgets` ships its `.d.ts` into the VFS unconditionally.\n * Omit for standard-library-only callers.\n */\n dtsMap?: Readonly<Record<string, string>>,\n): Promise<TypeCheckResult> {\n const vfs = await loadVfs();\n\n // Overlay each third-party gadget wrapper's `.d.ts` per-call without\n // mutating the cached VFS. The bare-specifier branch in\n // `resolveModuleName` resolves a generated `import { useX } from\n // '<package>'` against the overlaid entry, so the LLM sandbox sees\n // the wrapper's strict hook/component types (named option/return\n // shapes) rather than `any`. A third-party wrapper with no `dtsMap`\n // entry collapses to `any` (TS2307 is non-blocking) — degraded UX,\n // not a generation blocker; the fix is to thread `gadgetTypes`.\n // Stdlib (`@ggui-ai/gadgets`) ships its `.d.ts` unconditionally.\n const effectiveVfs = (() => {\n const dtsEntries = dtsMap !== undefined ? Object.entries(dtsMap) : [];\n if (dtsEntries.length === 0) {\n return vfs;\n }\n const overlay = new Map(vfs);\n for (const [pkg, content] of dtsEntries) {\n parseAndStore(overlay, `node_modules/${pkg}/index.d.ts`, content);\n }\n return overlay;\n })();\n\n // Prepend a synthetic prefix for classic JSX mode:\n // - `import React from 'react'` — the classic-mode JSX factory\n // (`React.createElement`) needs the React namespace in scope.\n // - a `declare global` JSX shim — `@types/react` v19 dropped the\n // GLOBAL `JSX` namespace (it is `React.JSX` now); classic mode\n // resolves intrinsic elements + the `key`/`ref` carve-out through\n // the global `JSX`, so without this `<div>` degrades to `any` and\n // every typed component falsely rejects the intrinsic `key` prop.\n // Mirrors `react/jsx-runtime`'s own JSX namespace, hoisted global.\n // All prefix lines are skipped from diagnostics via `lineOffset`.\n // `@types/react` v19 removed the GLOBAL `JSX` namespace (it lives at\n // `React.JSX` now — un-exported, not reliably reachable through the\n // VFS). Classic JSX mode resolves intrinsic elements + the `key`\n // carve-out through the global `JSX`, so declare a self-contained\n // one. Intrinsic elements are permissive (`[elem]: any`): the\n // type-checker's value is on the design components — which keep\n // their real prop types regardless of this namespace — and on\n // runtime-crash detection, not on deep typing of raw HTML (which the\n // generation prompt discourages anyway).\n const globalJsxShim =\n 'declare global { namespace JSX {' +\n ' type ElementType = string | ((props: any) => any) | (new (props: any) => any);' +\n ' interface Element { type: any; props: any; key: string | number | null; }' +\n ' interface ElementClass { render(): any; }' +\n ' interface ElementAttributesProperty { props: object; }' +\n ' interface ElementChildrenAttribute { children: object; }' +\n ' interface IntrinsicAttributes { key?: string | number | bigint | null; }' +\n ' interface IntrinsicClassAttributes<T> { ref?: any; }' +\n ' interface IntrinsicElements { [elem: string]: any; }' +\n ' } }\\n';\n const SYNTHETIC_PREFIX = \"import React from 'react';\\n\" + globalJsxShim;\n const prefixedCode = SYNTHETIC_PREFIX + code;\n const lineOffset = SYNTHETIC_PREFIX.split('\\n').length - 1;\n\n const host = createVfsHost(effectiveVfs, prefixedCode);\n\n const program = ts.createProgram(['Component.tsx'], COMPILER_OPTIONS, host);\n const diagnostics = ts.getPreEmitDiagnostics(program);\n\n const errors: TypeCheckDiagnostic[] = [];\n const warnings: TypeCheckDiagnostic[] = [];\n\n for (const diag of diagnostics) {\n // Only report diagnostics from the user's component file\n if (diag.file && diag.file.fileName !== 'Component.tsx') continue;\n // Global diagnostics (no file) — skip as they come from config\n if (!diag.file) continue;\n // Skip diagnostics on the synthetic import prefix line\n const diagLine = ts.getLineAndCharacterOfPosition(diag.file, diag.start ?? 0).line;\n if (diagLine < lineOffset) continue;\n\n const rawLine = diag.file\n ? ts.getLineAndCharacterOfPosition(diag.file, diag.start ?? 0).line + 1\n : 0;\n // Subtract the synthetic import line to get the user's original line number\n const line = Math.max(1, rawLine - lineOffset);\n const message = ts.flattenDiagnosticMessageText(diag.messageText, '\\n');\n const code_ = diag.code;\n\n // Extract the offending source line for the fix hint — without it\n // \"Type 'string' is not assignable to type 'number'\" is unactionable\n // because the LLM doesn't know which prop on which primitive. With\n // the line (\"<Icon size=\\\"md\\\" ...>\"), the LLM can target precisely.\n const sourceLines = diag.file.text.split('\\n');\n const sourceLine =\n rawLine >= 1 && rawLine <= sourceLines.length\n ? sourceLines[rawLine - 1]?.trim() ?? ''\n : '';\n\n const entry: TypeCheckDiagnostic = {\n code: code_,\n line,\n message,\n fix: generateFix(code_, message, sourceLine),\n };\n\n if (BLOCKING_CODES.has(code_)) {\n errors.push(entry);\n } else {\n warnings.push(entry);\n }\n }\n\n return { errors, warnings };\n}\n","// packages/ui-gen/src/check/react-linter.ts\n//\n// React linter — runs eslint-plugin-react-hooks via ESLint's Linter API.\n//\n// Exposed on `@ggui-ai/ui-gen/check` so `createUiGenerator` can invoke\n// the same lint gate as the hosted generation path.\n//\n// Dep surface: the linter imports the `Linter` / `Rule` types from\n// `eslint` at module load and lazily imports `@typescript-eslint/parser`,\n// `eslint-plugin-react-hooks`, and `eslint-plugin-react` inside\n// `getLinter()` — those four packages are runtime deps of this package.\n//\n// Catches Rules of Hooks violations that the TS type-checker misses:\n// - Hooks inside conditionals, loops, nested functions\n// - Hooks after early returns\n// - Missing/extra dependencies in useEffect/useMemo/useCallback\n//\n// Also carries the core ESLint `no-unused-vars` rule to\n// catch wire hooks the LLM declared but never consumed — an unused\n// `const submit = useAction('submit')` ships a subscription with no\n// render/callback wiring and will not actually drive the UI. Rule 14\n// (`wire_preservation`) in self-check.ts catches the DELETION case;\n// this lint pass catches the ABANDONMENT case. Together they seal\n// bidirectional contract completeness: contract -> code.\n//\n// Uses the lightweight Linter API (no file system, no config resolution).\n// Runs in parallel with the TS type-checker during self-check.\n\nimport { Linter, type Rule } from 'eslint';\n\nexport interface ReactLintDiagnostic {\n rule: string;\n line: number;\n message: string;\n fix: string;\n severity: 'error' | 'warning';\n}\n\n// Singleton Linter instance — reused across calls.\nlet linterInstance: Linter | null = null;\n\nasync function getLinter(): Promise<Linter> {\n if (!linterInstance) {\n linterInstance = new Linter();\n\n // Register @typescript-eslint/parser so ESLint can parse TS/TSX\n const tsParser = await import('@typescript-eslint/parser');\n linterInstance.defineParser('@typescript-eslint/parser', tsParser as Linter.Parser);\n\n // Register react-hooks plugin rules\n const reactHooksPlugin = await import('eslint-plugin-react-hooks');\n const hooksRules = reactHooksPlugin.default?.rules ?? reactHooksPlugin.rules;\n for (const [name, rule] of Object.entries(hooksRules)) {\n linterInstance.defineRule(`react-hooks/${name}`, rule as Rule.RuleModule);\n }\n\n // Register eslint-plugin-react rules\n const reactPlugin = await import('eslint-plugin-react');\n const reactRules = reactPlugin.default?.rules ?? reactPlugin.rules;\n for (const [name, rule] of Object.entries(reactRules)) {\n linterInstance.defineRule(`react/${name}`, rule as Rule.RuleModule);\n }\n }\n return linterInstance;\n}\n\n/**\n * Lint TSX code for React hooks violations.\n * Returns diagnostics with line numbers and fix suggestions.\n */\nexport async function lintReactHooks(code: string): Promise<ReactLintDiagnostic[]> {\n const linter = await getLinter();\n\n let messages: Linter.LintMessage[];\n try {\n const config: Linter.LegacyConfig = {\n parser: '@typescript-eslint/parser',\n parserOptions: {\n ecmaVersion: 2022,\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n rules: {\n 'react-hooks/rules-of-hooks': 2,\n 'react-hooks/exhaustive-deps': 1,\n // React rules\n 'react/jsx-no-undef': 2, // undefined JSX components\n 'react/jsx-key': 1, // missing key in lists\n 'react/no-direct-mutation-state': 2, // direct state mutation\n // An unused `const submit = useAction('submit')` is a\n // dead contract wire. Narrow the rule to variable bindings we\n // care about: skip function args (LLMs legitimately omit unused\n // params), skip destructured `rest` collectors, respect a `_`-\n // prefix escape hatch for intentionally-ignored declarations,\n // and silence the caught-error slot (async error handling can\n // leave `catch (err)` unused at a boundary).\n 'no-unused-vars': [2, {\n vars: 'all',\n args: 'none',\n ignoreRestSiblings: true,\n varsIgnorePattern: '^_',\n caughtErrors: 'none',\n }],\n },\n settings: {\n react: { version: '19.0' },\n },\n };\n messages = linter.verify(code, config, { filename: 'component.tsx' });\n } catch {\n // Parser not available or code too malformed — skip\n return [];\n }\n\n const diagnostics: ReactLintDiagnostic[] = [];\n\n // Rules surfaced from the Linter run. `no-unused-vars` is the core\n // ESLint rule (no plugin prefix) — admitted alongside react-hooks/\n // and react/ rules so the no-unused-vars diagnostic reaches self_check.\n const ADMITTED_RULES = (id: string): boolean =>\n id.startsWith('react-hooks/') ||\n id.startsWith('react/') ||\n id === 'no-unused-vars';\n\n for (const msg of messages) {\n // Skip parser errors — caught by TS type-checker\n if (!msg.ruleId) continue;\n if (!ADMITTED_RULES(msg.ruleId)) continue;\n\n diagnostics.push({\n rule: msg.ruleId,\n line: msg.line,\n message: msg.message,\n fix: generateReactFix(msg.ruleId, msg.message),\n severity: resolveSeverity(msg, code),\n });\n }\n\n return diagnostics;\n}\n\n/**\n * Resolve the self-check severity of a lint diagnostic.\n *\n * Most rules map straight from ESLint severity (2 → error, 1 → warning).\n * `no-unused-vars` is special-cased: it stays a hard `error` ONLY when\n * the unused binding is a CONTRACT WIRE — `const x = useAction(...)` /\n * `useStream(...)` / `useGguiContext(...)` — because an abandoned wire\n * ships a dead subscription. For every other unused binding (a local\n * helper the LLM declared mid-generation, a `useMemo` result, a state-\n * read gadget binding) it is downgraded to `warning`.\n *\n * Rationale: a half-wired local helper is transient coding state, not a\n * defect — blocking tier-0 self-check on it forces a whole coding-turn\n * round-trip and is the single largest turn-thrash driver on the\n * benchmark (kanban/chat hit the turn cap oscillating on `'handleNext'\n * is assigned a value but never used`). The dead-CONTRACT-wire case it\n * was built to catch is independently enforced at\n * `error` severity by `validateActionSpecConformance` /\n * `validateStreamSpecConformance` in contract-validation.ts, so the\n * downgrade loses no correctness coverage. The diagnostic still surfaces\n * as a `warn` and is fed back to the LLM during eval rounds.\n */\nfunction resolveSeverity(\n msg: Linter.LintMessage,\n code: string,\n): 'error' | 'warning' {\n const base: 'error' | 'warning' = msg.severity === 2 ? 'error' : 'warning';\n if (msg.ruleId !== 'no-unused-vars' || base !== 'error') return base;\n const name = msg.message.match(/'([^']+)'/)?.[1];\n if (name === undefined) return 'warning';\n // Escape regex metacharacters in the identifier (defensive — JS\n // identifiers can't contain them, but the message text is untrusted).\n const safe = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Contract-wire binding. Two declaration shapes:\n // - direct: `const submit = useAction('submit')`\n // - destructured: `const [step, setStep] = useGguiContext<number>('step')`\n // The destructured form covers `useGguiContext` (and a defensive\n // `useStream`), where the unused name is one tuple slot.\n const directRe = new RegExp(\n `\\\\bconst\\\\s+${safe}\\\\s*=\\\\s*use(Action|Stream|GguiContext)\\\\s*[<(]`,\n );\n const destructuredRe = new RegExp(\n `\\\\bconst\\\\s+\\\\[[^\\\\]]*\\\\b${safe}\\\\b[^\\\\]]*\\\\]\\\\s*=\\\\s*use(Action|Stream|GguiContext)\\\\s*[<(]`,\n );\n return directRe.test(code) || destructuredRe.test(code)\n ? 'error'\n : 'warning';\n}\n\nfunction generateReactFix(ruleId: string, message: string): string {\n if (ruleId === 'react-hooks/rules-of-hooks') {\n if (message.includes('called conditionally')) {\n return 'Move this hook to the top level of the component, before any early returns or conditionals. Hooks must run in the same order every render.';\n }\n return 'Hooks can only be called at the top level of a React function component or custom hook. Move it out of any conditional, loop, nested function, or callback.';\n }\n if (ruleId === 'react-hooks/exhaustive-deps') {\n return 'Add the missing dependencies to the dependency array, or remove the array to run on every render.';\n }\n if (ruleId === 'react/jsx-no-undef') {\n const match = message.match(/'(\\w+)'/);\n const name = match?.[1] ?? 'Component';\n return `'${name}' is not defined. Import it from the design system or define it in the file.`;\n }\n if (ruleId === 'react/jsx-key') {\n return 'Add a unique \"key\" prop to each element rendered inside a .map() or iterator.';\n }\n if (ruleId === 'react/no-direct-mutation-state') {\n return 'Do not mutate state directly. Use setState or the setter from useState instead.';\n }\n if (ruleId === 'no-unused-vars') {\n // Extract the identifier name from the ESLint message shape:\n // \"'submit' is assigned a value but never used.\" (varsIgnorePattern also referenced)\n const match = message.match(/'([^']+)'/);\n const name = match?.[1] ?? 'variable';\n // Wire-hook shape — if the binding is an obvious contract wire, route\n // the LLM to the right remediation. Heuristic lives on the message\n // text because we only see the rule output here, not the AST.\n const isLikelyWireBinding = /\\bconst\\s+[A-Za-z_$][\\w$]*\\s*=\\s*use(Action|Stream)\\s*\\(/.test(message);\n if (isLikelyWireBinding || /^(submit|cancel|search|progress|snapshot)$/.test(name)) {\n return `'${name}' is declared but never used. If this binding came from a wire hook (useAction / useStream) or a clientCapabilities hook (useGeolocation / useCamera / etc. from @ggui-ai/gadgets), consume it somewhere in the component — render its value in JSX, bind it to a callback prop, or use it in an effect. A contract-declared hook without consumption is a dead wire.`;\n }\n return `'${name}' is declared but never used. Remove the declaration, or consume it somewhere in the component. Prefix with '_' (e.g. '_${name}') to mark it intentionally unused.`;\n }\n return 'Fix the React violation.';\n}\n","/**\n * Lightweight render smoke test for compiled components.\n *\n * Uses ReactDOMServer.renderToString() to verify the component\n * can render without throwing. Catches runtime errors that tsc misses\n * (undefined.toLowerCase(), missing prop access, etc.)\n *\n * Returns null on success, or an error message string on failure.\n *\n * **Execution model**: the actual `renderToString` runs in a\n * subprocess via `@ggui-ai/sandbox` — LLM-generated TSX never\n * executes in the parent Node process. The subprocess gets:\n *\n * - wall-clock timeout (12s — generous for weird LLM output)\n * - stdout cap (512 KiB — worker's JSON verdict is tiny; cap is\n * defensive)\n * - V8 heap cap (256 MB — bounds runaway allocations)\n * - owned tmpdir as cwd (cleaned up at finish)\n * - env allowlist (PATH/HOME/TMPDIR bootstrap only — no secrets\n * from the parent process.env reach the child)\n *\n * See `@ggui-ai/sandbox/README.md` for the honest boundary: this\n * setup does NOT block network egress, does NOT prevent FS reads\n * outside cwd, and does NOT cap CPU. Those need OS primitives that\n * aren't portable from Node user-space.\n */\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL, fileURLToPath } from 'node:url';\nimport { runSandboxed } from '@ggui-ai/sandbox';\nimport type { PropsSpec, JsonObject, JsonValue } from '@ggui-ai/protocol';\n\n/**\n * Generate sample props from a PropsSpec contract.\n * Uses `example` values from each PropEntry when available,\n * otherwise synthesizes plausible defaults from the JSON Schema.\n */\nexport function generateSampleProps(spec: PropsSpec): JsonObject {\n const props: JsonObject = {};\n\n for (const [name, entry] of Object.entries(spec.properties)) {\n // Prefer explicit example value\n if (entry.example !== undefined) {\n props[name] = entry.example;\n continue;\n }\n\n // Prefer explicit default value\n if (entry.default !== undefined) {\n props[name] = entry.default;\n continue;\n }\n\n // Synthesize from JSON Schema\n props[name] = synthesizeFromSchema(entry.schema);\n }\n\n return props;\n}\n\nfunction synthesizeFromSchema(schema: { type?: string; items?: unknown; properties?: JsonObject; required?: string[] }): JsonValue | undefined {\n switch (schema.type) {\n case 'string': return 'sample';\n case 'number': return 0;\n case 'boolean': return false;\n case 'array': {\n const itemSchema = schema.items as { type?: string } | undefined;\n if (itemSchema) return [synthesizeFromSchema(itemSchema) ?? null];\n return [];\n }\n case 'object': {\n const obj: JsonObject = {};\n if (schema.properties) {\n for (const [k, v] of Object.entries(schema.properties)) {\n obj[k] = synthesizeFromSchema(v as { type?: string });\n }\n }\n return obj;\n }\n default: return undefined;\n }\n}\n\n/**\n * Timeout for a single render smoke test. Generous — some LLM-\n * produced components hit pathological code paths (deep prop-drill\n * recursion, accidental infinite loops on null-guarded maps). 12s is\n * well above the ~100ms real renderToString cost + ~50ms subprocess\n * spawn, while still bounding runaway execution.\n */\nconst RENDER_TIMEOUT_MS = 12_000;\n\n/**\n * stdout byte cap. The worker writes a single JSON verdict\n * (`{ok: true}` or `{ok: false, error: \"...\"}`), which is tiny — a\n * few KiB is plenty for the longest useful error message. Cap\n * defensively at 512 KiB so a pathological worker can't flood.\n */\nconst RENDER_STDOUT_CAP = 512 * 1024;\n\n/**\n * V8 heap cap for the worker. 256 MB bounds runaway allocations\n * (e.g. a component that builds a massive array in render) while\n * leaving headroom for `react-dom/server` + esbuild's own heap.\n */\nconst RENDER_NODE_HEAP_MB = 256;\n\n/**\n * Resolve the worker entry + the spawn command to launch it.\n *\n * - **Built (`dist/`)**: the compiled `render-check-worker.js`\n * lives at `dist/tools/render-check-worker.js`. Some consumers\n * import via subpath entries (e.g. `@ggui-ai/ui-gen/adapters`)\n * that inline this function into a different dist directory\n * (e.g. `dist/adapters/index.js`); the worker lookup must still\n * find the worker file in `dist/tools/`. We search siblings AND\n * `../tools/` to cover both.\n * - **Dev / test (vitest imports `src/`)**: only the `.ts` source\n * exists at `src/tools/render-check-worker.ts`; spawn\n * `node --import tsx <tsPath>`. tsx is already a dev-dep of core\n * for the `dev` / `bench` scripts, so it's a safe assumption in\n * the test environment.\n *\n * Fails loudly at first call when none of the candidates exist —\n * that means a broken build, not a missing test fixture.\n */\nfunction resolveWorkerSpawn(): { command: string; args: string[] } {\n // Sibling-first, then `../tools/`. When this function is inlined\n // into `dist/adapters/index.js`, sibling resolves to a nonexistent\n // `dist/adapters/render-check-worker.js`; the `../tools/` candidate\n // then lands on the real `dist/tools/render-check-worker.js`.\n const jsCandidates = [\n new URL('./render-check-worker.js', import.meta.url),\n new URL('../tools/render-check-worker.js', import.meta.url),\n ];\n const tsCandidates = [\n new URL('./render-check-worker.ts', import.meta.url),\n new URL('../tools/render-check-worker.ts', import.meta.url),\n ];\n for (const jsUrl of jsCandidates) {\n const jsPath = fileURLToPath(jsUrl);\n if (existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] };\n }\n }\n for (const tsUrl of tsCandidates) {\n const tsPath = fileURLToPath(tsUrl);\n if (existsSync(tsPath)) {\n // Pre-resolve tsx to an absolute file: URL so Node can find it\n // regardless of the subprocess's cwd (the sandbox mints a fresh\n // tmpdir for cwd by default; relative tsx lookup would fail).\n const require_ = createRequire(import.meta.url);\n const tsxLoader = pathToFileURL(require_.resolve('tsx')).href;\n return {\n command: process.execPath,\n args: ['--import', tsxLoader, tsPath],\n };\n }\n }\n const tried = [...jsCandidates, ...tsCandidates]\n .map((u) => fileURLToPath(u))\n .join(', ');\n throw new Error(\n `render-check: worker not found at any of: ${tried}. Did \\`pnpm build\\` run?`,\n );\n}\n\nexport async function tryRender(\n compiledCode: string,\n sourceCode: string,\n sampleProps?: JsonObject,\n): Promise<string | null> {\n // `compiledCode` is intentionally ignored — the worker re-compiles\n // as CJS internally. Keeping the parameter preserves the callsite\n // signature so upstream callers (tools.ts, lambda-handler.ts) don't\n // churn.\n void compiledCode;\n\n const payload = JSON.stringify({ sourceCode, sampleProps });\n const spawn = resolveWorkerSpawn();\n\n const result = await runSandboxed({\n command: spawn.command,\n args: spawn.args,\n timeoutMs: RENDER_TIMEOUT_MS,\n maxStdoutBytes: RENDER_STDOUT_CAP,\n nodeHeapMb: RENDER_NODE_HEAP_MB,\n stdin: payload,\n // Forward only what the worker needs. NODE_ENV lets React pick\n // production vs development builds; everything else stays at the\n // sandbox's default allowlist (PATH/HOME/TMPDIR bootstrap).\n env: {\n NODE_ENV: process.env.NODE_ENV ?? 'production',\n },\n });\n\n if (result.outcome === 'timeout') {\n return `Render timeout: component did not finish within ${RENDER_TIMEOUT_MS}ms (likely infinite loop or runaway recursion).`;\n }\n if (result.outcome === 'overflow-stdout' || result.outcome === 'overflow-stderr') {\n return `Render error: worker produced excessive output (${result.outcome}). The component is likely in a pathological state.`;\n }\n if (result.outcome === 'canceled') {\n return 'Render error: smoke test was canceled before completing.';\n }\n if (result.outcome === 'spawn-error') {\n return `Render error: failed to start worker — ${result.errorMessage}`;\n }\n if (result.outcome !== 'exit') {\n return `Render error: unexpected sandbox outcome '${result.outcome}'.`;\n }\n\n // Worker exited cleanly. Parse its verdict.\n if (result.exitCode !== 0) {\n const tail = result.stderr.trim() || result.stdout.trim();\n return `Render error: worker exited ${result.exitCode}${tail ? ` — ${tail}` : ''}`;\n }\n\n const stdout = result.stdout.trim();\n if (stdout.length === 0) {\n return 'Render error: worker exited without producing a verdict.';\n }\n\n type Verdict = { ok: true } | { ok: false; error: string };\n let verdict: Verdict;\n try {\n verdict = JSON.parse(stdout) as Verdict;\n } catch (err) {\n return `Render error: malformed worker verdict — ${\n err instanceof Error ? err.message : String(err)\n }`;\n }\n\n return verdict.ok ? null : verdict.error;\n}\n","// packages/ui-gen/src/adapters/tools.ts\n//\n// SDK-agnostic tool definitions for UI generation.\n// These use the same Zod schemas and handlers as the production MCP server\n// but without Claude Agent SDK dependencies, making them portable across\n// OpenAI, Google, and Anthropic SDKs.\n\nimport { z } from 'zod';\nimport * as esbuild from 'esbuild';\nimport { PRIMITIVES_DOCUMENTATION } from '../validation/index.js';\nimport {\n validateComponentDetailed,\n formatValidationResultForClaude,\n} from '../validation/index.js';\nimport { DEFAULT_DESIGN_SYSTEM_DOCS } from '../design-system-docs.js';\nimport { isAllowedImport, describeAllowedImports } from '../validation/allowed-imports.js';\nimport type { ToolDefinition, ToolResult } from './types';\nimport type { DataContract, JsonObject } from '@ggui-ai/protocol';\nimport { validateAllContracts } from '../check/index.js';\nimport { typecheck } from '../check/index.js';\nimport { lintReactHooks } from '../check/index.js';\nimport ts from 'typescript';\nimport { tryRender, generateSampleProps } from '../tools/render-check.js';\n\n/**\n * Context for creating generator tools.\n * Allows passing app-specific component docs.\n */\nexport interface GeneratorToolsContext {\n /** App-specific design context (DESIGN.md content) */\n designContext?: string;\n /** App-specific reusable component documentation */\n componentContext?: string;\n /** Data contract for validation (props, stream, actions) */\n contract?: DataContract;\n /** Sample props for render smoke test (realistic data matching the contract) */\n sampleProps?: JsonObject;\n}\n\n/**\n * Create the SDK-agnostic tool definitions for UI generation.\n *\n * 6 tools matching the MCP server:\n * 1. get_primitives — available UI components\n * 2. get_design_system — CSS variable tokens\n * 3. get_app_components — app-specific reusable components\n * 4. validate_component — pre-compilation check\n * 5. self_check — typecheck + lint + render smoke test\n * 6. compile_component — TSX→JS via esbuild\n *\n * Each tool uses the exact same handlers as the production MCP server,\n * but wrapped in a provider-neutral format.\n */\nexport function createGeneratorTools(context: GeneratorToolsContext = {}): ToolDefinition[] {\n const tools: ToolDefinition[] = [\n // --- get_primitives ---\n {\n name: 'get_primitives',\n description:\n 'Get the list of available ggui UI primitives (Container, Card, Stack, Button, Input, etc.) that can be used in components. Call this first to understand what components are available.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{ type: 'text', text: PRIMITIVES_DOCUMENTATION }],\n }),\n },\n\n // --- get_design_system ---\n {\n name: 'get_design_system',\n description:\n 'Get the design system tokens and CSS variables for this app. Use these CSS variables (var(--ggui-*)) for colors, spacing, typography, etc.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{\n type: 'text',\n text: context.designContext\n ? `# App Theme Configuration\\n\\n${context.designContext}\\n\\n**IMPORTANT:** Always use CSS variables (var(--ggui-*)) for colors, spacing, etc.`\n : DEFAULT_DESIGN_SYSTEM_DOCS,\n }],\n }),\n },\n\n // --- get_app_components ---\n {\n name: 'get_app_components',\n description:\n 'Get predefined reusable components specific to this app. These can be imported and used in your generated component.',\n inputSchema: z.object({}),\n handler: async (): Promise<ToolResult> => ({\n content: [{\n type: 'text',\n text: context.componentContext || 'No predefined components available for this app.',\n }],\n }),\n },\n\n // --- validate_component ---\n {\n name: 'validate_component',\n description:\n 'Validate component code before compilation. Checks for security issues, syntax errors, and best practices. Returns detailed feedback.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to validate'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const result = validateComponentDetailed(args.code as string);\n return {\n content: [\n {\n type: 'text',\n text: formatValidationResultForClaude(result),\n },\n ],\n isError: !result.valid,\n };\n },\n },\n\n // --- self_check ---\n {\n name: 'self_check',\n description:\n 'Run deterministic quality checks on your code BEFORE compiling. Catches common issues instantly (zero cost). Returns pass/fail per check with line numbers and fix instructions. Call this after writing code, fix any failures, then compile.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to check'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const code = args.code as string;\n const { issues, typeWarnings } = await runSelfChecks(code, context.contract);\n\n // Contract validation — check props, stream, actions conformance\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n for (const ci of contractIssues) {\n issues.push({\n check: `contract:${ci.field}`,\n line: 0,\n message: `[${ci.severity}] ${ci.message}`,\n fix: ci.fix,\n });\n }\n }\n\n if (issues.length === 0) {\n const warningText = typeWarnings.length > 0\n ? `\\n\\nType warnings (non-blocking):\\n${typeWarnings.map(w => `[${w.check}] ${w.line ? `Line ${w.line}: ` : ''}${w.message}`).join('\\n')}`\n : '';\n return {\n content: [{ type: 'text', text: `All checks passed. Ready to compile.${warningText}` }],\n };\n }\n\n const report = issues.map((i) => `[${i.check}] ${i.line ? `Line ${i.line}: ` : ''}${i.message}\\n Fix: ${i.fix}`).join('\\n\\n');\n return {\n content: [{ type: 'text', text: `${issues.length} issue(s) found:\\n\\n${report}` }],\n isError: true,\n };\n },\n },\n\n // --- compile_component ---\n {\n name: 'compile_component',\n description:\n 'Compile a TypeScript/TSX component to JavaScript using esbuild. Returns the compiled code ready for browser execution. On failure, returns detailed error context with line numbers and fix suggestions.',\n inputSchema: z.object({\n code: z.string().describe('The TypeScript/TSX component code to compile'),\n filename: z\n .string()\n .default('Component.tsx')\n .describe('Filename for error messages'),\n }),\n handler: async (args): Promise<ToolResult> => {\n const code = args.code as string;\n const filename = (args.filename as string) || 'Component.tsx';\n\n // Run self-checks first (catches hex colors, raw pixels, forbidden imports, etc.)\n const { issues: selfCheckIssues } = await runSelfChecks(code, context.contract);\n\n // Contract validation\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n for (const ci of contractIssues) {\n selfCheckIssues.push({\n check: `contract:${ci.field}`,\n line: 0,\n message: `[${ci.severity}] ${ci.message}`,\n fix: ci.fix,\n });\n }\n }\n\n if (selfCheckIssues.length > 0) {\n const report = selfCheckIssues.map((i) => `[${i.check}] ${i.line ? `Line ${i.line}: ` : ''}${i.message}\\n Fix: ${i.fix}`).join('\\n\\n');\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'self_check',\n error: `${selfCheckIssues.length} issue(s) found — fix these before recompiling:\\n\\n${report}`,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n // Run validation first\n const validation = validateComponentDetailed(code);\n if (!validation.valid) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n phase: 'validation',\n error: formatValidationResultForClaude(validation),\n },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n\n try {\n const result = await esbuild.transform(code, {\n loader: 'tsx',\n target: 'es2020',\n format: 'esm',\n jsx: 'automatic',\n jsxImportSource: 'react',\n minify: true,\n sourcefile: filename,\n });\n\n const warnings = [\n ...result.warnings.map((w) => w.text),\n ...validation.warnings.map(\n (w: { type: string; message: string; suggestion: string }) =>\n `[${w.type}] ${w.message}: ${w.suggestion}`\n ),\n ];\n\n // Post-compilation: validate all contract (hard gate for errors)\n if (context.contract) {\n const contractIssues = validateAllContracts(code, context.contract);\n const errors = contractIssues.filter((i) => i.severity === 'error');\n const contractWarnings = contractIssues.filter((i) => i.severity === 'warning');\n\n if (errors.length > 0) {\n const report = errors\n .map((i) => `- [${i.field}] ${i.message}\\n Fix: ${i.fix}`)\n .join('\\n');\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'contract_validation',\n error: `Compilation succeeded but data contract validation failed:\\n\\n${report}\\n\\nFix the Props interface to match the data contract, then recompile.`,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n warnings.push(...contractWarnings.map((i) => `[contract:${i.field}] ${i.message}`));\n }\n\n // Render smoke test — catches runtime errors tsc misses\n // Prefer explicit sampleProps (realistic data), fall back to contract-derived\n const sampleProps = context.sampleProps\n ?? (context.contract?.propsSpec ? generateSampleProps(context.contract.propsSpec) : undefined);\n const renderError = await tryRender(result.code, code, sampleProps);\n if (renderError) {\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: false,\n phase: 'render_smoke_test',\n compiledCode: result.code,\n error: `${renderError}\\n\\nThe component compiled but crashes at runtime. Fix the null/undefined access and recompile.`,\n warnings,\n }, null, 2),\n }],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n compiledCode: result.code,\n warnings,\n },\n null,\n 2\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: false, phase: 'compilation', error: formatEsbuildError(error, code) },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n },\n },\n ];\n\n return tools;\n}\n\n/**\n * Format an esbuild error into a readable error message with code context.\n */\nfunction formatEsbuildError(error: unknown, sourceCode: string): string {\n const parts: string[] = [];\n\n if (\n error &&\n typeof error === 'object' &&\n 'errors' in error &&\n Array.isArray((error as { errors: unknown[] }).errors)\n ) {\n const esbuildError = error as esbuild.TransformFailure;\n for (const err of esbuildError.errors) {\n const line = err.location?.line;\n const col = err.location?.column;\n parts.push(`**Error:** ${err.text}`);\n if (line) {\n parts.push(`**Location:** Line ${line}, Column ${col ?? 0}`);\n const lines = sourceCode.split('\\n');\n const start = Math.max(0, line - 3);\n const end = Math.min(lines.length, line + 2);\n const context = lines\n .slice(start, end)\n .map((l, i) => {\n const ln = start + i + 1;\n return `${ln === line ? '>>> ' : ' '}${ln} | ${l}`;\n })\n .join('\\n');\n parts.push(`**Code:**\\n\\`\\`\\`\\n${context}\\n\\`\\`\\``);\n }\n }\n } else {\n parts.push(`**Error:** ${error instanceof Error ? error.message : 'Compilation failed'}`);\n }\n\n parts.push('\\n**How to fix:** Review the error above, fix the code, then call compile_component again.');\n return parts.join('\\n');\n}\n\n// =============================================================================\n// Self-Check: Deterministic Quality Checks\n// =============================================================================\n\nexport interface SelfCheckIssue {\n check: string;\n line: number;\n message: string;\n fix: string;\n}\n\n// =============================================================================\n// AST-Based React Rules Checker\n// =============================================================================\n\n// Form components that require a label or aria-label prop for accessibility.\nconst LABELED_COMPONENTS = new Set(['Input', 'TextArea', 'Select']);\n\n/**\n * AST-based JSX prop checker.\n * Parses TSX with TypeScript compiler to verify required props on form elements.\n * React hooks rules are handled by eslint-plugin-react-hooks (see react-linter.ts).\n */\nfunction checkReactRules(code: string): SelfCheckIssue[] {\n const sf = ts.createSourceFile('component.tsx', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n const issues: SelfCheckIssue[] = [];\n\n function visit(node: ts.Node): void {\n if (ts.isJsxSelfClosingElement(node) || ts.isJsxOpeningElement(node)) {\n const tagName = node.tagName.getText(sf);\n if (LABELED_COMPONENTS.has(tagName)) {\n const propNames = new Set<string>();\n let hasSpread = false;\n for (const attr of node.attributes.properties) {\n if (ts.isJsxAttribute(attr)) {\n propNames.add(attr.name.getText(sf));\n } else if (ts.isJsxSpreadAttribute(attr)) {\n hasSpread = true;\n }\n }\n if (!hasSpread && !propNames.has('label') && !propNames.has('aria-label')) {\n const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n issues.push({\n check: 'accessibility',\n line,\n message: `${tagName} missing label prop`,\n fix: `Add label=\"...\" prop directly on the ${tagName} component. The label prop is built into the primitive.`,\n });\n }\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sf);\n return issues;\n}\n\n/**\n * Run deterministic quality checks on component source code.\n * Returns actionable issues with line numbers and fix instructions.\n *\n * `contract` (optional) feeds the import allowlist: generated\n * code direct-imports gadget exports, so every gadget package the\n * contract declares is a permitted import source.\n */\nexport async function runSelfChecks(\n code: string,\n contract?: DataContract,\n): Promise<{ issues: SelfCheckIssue[]; typeWarnings: SelfCheckIssue[] }> {\n const issues: SelfCheckIssue[] = [];\n const lines = code.split('\\n');\n // Gadget packages the contract declares are import-allowlisted.\n // `clientCapabilities.gadgets` is package-keyed, so the map's\n // own keys ARE the allowlisted import sources.\n const allowedGadgetPackages = new Set<string>(\n Object.keys(contract?.clientCapabilities?.gadgets ?? {}),\n );\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Check: hardcoded hex colors\n const hexMatch = line.match(/#[0-9a-fA-F]{3,8}\\b/);\n if (hexMatch && !line.includes('var(--ggui-') && !line.includes('// fallback')) {\n issues.push({\n check: 'hex-color',\n line: lineNum,\n message: `Hardcoded color \"${hexMatch[0]}\" — must use design tokens`,\n fix: `Replace with var(--ggui-color-*, ${hexMatch[0]})`,\n });\n }\n\n // Check: rgba()/hsl() hardcoded color functions\n const colorFnMatch = line.match(/\\b(rgba?|hsla?)\\s*\\(/);\n if (colorFnMatch && !line.includes('var(--ggui-') && !line.includes('// fallback') && !line.includes('$value')) {\n issues.push({\n check: 'hardcoded-color-fn',\n line: lineNum,\n message: `Hardcoded ${colorFnMatch[1]}() — use design tokens instead`,\n fix: `Replace with semantic tokens: var(--ggui-color-surface), var(--ggui-color-onSurface), var(--ggui-color-outline), etc.`,\n });\n }\n\n // Check: neutral-50/900 used for background/text — suggest semantic tokens\n if (/--ggui-color-neutral-50[^0-9]/.test(line) && /background/i.test(line)) {\n issues.push({\n check: 'prefer-semantic',\n line: lineNum,\n message: `neutral-50 for background — prefer semantic token for dark-theme compatibility`,\n fix: `Replace with var(--ggui-color-surface) or var(--ggui-color-surfaceVariant)`,\n });\n }\n if (/--ggui-color-neutral-900[^0-9]/.test(line) && /color/i.test(line) && !/background/i.test(line)) {\n issues.push({\n check: 'prefer-semantic',\n line: lineNum,\n message: `neutral-900 for text color — prefer semantic token for dark-theme compatibility`,\n fix: `Replace with var(--ggui-color-onSurface) or var(--ggui-color-onSurfaceVariant)`,\n });\n }\n\n // Check: raw pixel values in padding/margin/gap (not in var() or calc())\n const pxMatch = line.match(/(?:padding|margin|gap|borderRadius)\\s*:\\s*['\"]?\\d+px/);\n if (pxMatch && !line.includes('var(--ggui-')) {\n issues.push({\n check: 'raw-pixels',\n line: lineNum,\n message: `Raw pixel value in spacing — must use design tokens`,\n fix: `Replace with var(--ggui-spacing-*, fallback)`,\n });\n }\n\n // Check: forbidden APIs\n if (/\\beval\\s*\\(/.test(line)) {\n issues.push({ check: 'security', line: lineNum, message: 'eval() is forbidden', fix: 'Remove eval() call entirely' });\n }\n if (/\\bfetch\\s*\\(/.test(line)) {\n issues.push({ check: 'security', line: lineNum, message: 'fetch() is forbidden — use props for data', fix: 'Remove fetch() and pass data via props' });\n }\n\n // Check: forbidden imports\n const importMatch = line.match(/import\\s+.*from\\s+['\"]([^'\"]+)['\"]/);\n if (importMatch) {\n const pkg = importMatch[1];\n // Import allowlist — single source of truth in\n // `validation/allowed-imports.ts`. Generated code\n // direct-imports gadget exports, so every gadget package the\n // contract declares is allowlisted alongside STDLIB `@ggui-ai/gadgets`.\n if (!isAllowedImport(pkg, allowedGadgetPackages)) {\n issues.push({\n check: 'import',\n line: lineNum,\n message: `Import from \"${pkg}\" is not allowed`,\n fix: `Only import from: ${describeAllowedImports()}`,\n });\n }\n }\n\n // NOTE: Input/TextArea/Select label checks moved to AST-based checkJsxProps() below\n }\n\n // ── AST-based JSX prop checks ──────────────────────────\n // Uses TypeScript compiler to parse JSX — handles multi-line, spread props, etc.\n try {\n const jsxIssues = checkReactRules(code);\n issues.push(...jsxIssues);\n } catch {\n // Parsing may fail on malformed code — fall through to other checks\n }\n\n // Check: no Props interface\n if (!code.includes('interface Props') && !code.includes('type Props')) {\n issues.push({\n check: 'props-interface',\n line: 1,\n message: 'No Props interface found — data is likely hardcoded',\n fix: 'Add interface Props { ... } with typed fields and default values in the function signature',\n });\n }\n\n // Check: no default export\n if (!code.includes('export default function')) {\n issues.push({\n check: 'export',\n line: 1,\n message: 'Missing default export function',\n fix: 'Add export default function GeneratedComponent(props: Props) { ... }',\n });\n }\n\n const typeWarnings: SelfCheckIssue[] = [];\n\n // Run TS type-checker + React hooks linter in parallel\n const [typeResult, reactResult] = await Promise.all([\n typecheck(code).catch((err) => {\n console.warn('[runSelfChecks] TypeChecker failed:', err instanceof Error ? err.message : String(err));\n return null;\n }),\n lintReactHooks(code).catch((err) => {\n console.warn('[runSelfChecks] React linter failed:', err instanceof Error ? err.message : String(err));\n return [] as import('../check/index.js').ReactLintDiagnostic[];\n }),\n ]);\n\n // TS type errors\n if (typeResult) {\n for (const error of typeResult.errors) {\n issues.push({\n check: `ts${error.code}`,\n line: error.line,\n message: error.message,\n fix: error.fix,\n });\n }\n for (const warning of typeResult.warnings) {\n typeWarnings.push({\n check: `ts${warning.code}`,\n line: warning.line,\n message: warning.message,\n fix: warning.fix,\n });\n }\n }\n\n // React hooks violations. Errors (rules-of-hooks, jsx-no-undef, direct-\n // mutation) always block. exhaustive-deps warnings are usually advisory —\n // except when the effect body mutates state (setState / setX / dispatch),\n // in which case a missing dep is a near-certain infinite-render loop once\n // the component renders at runtime. The happy-dom probe catches this only\n // AFTER burning CPU; we'd rather fail preflight.\n //\n // Narrow promotion heuristic: file has a setter-like call AND diagnostic\n // message indicates a missing-dep / unstable-ref class. Inline-object\n // warnings on effects that DON'T mutate state stay advisory to avoid\n // over-constraining.\n const hasStateSetter = /\\b(set[A-Z]\\w*|dispatch)\\s*\\(/.test(code);\n const isSetterLoopRisk = (diag: { rule: string; message: string }): boolean => {\n if (diag.rule !== 'react-hooks/exhaustive-deps') return false;\n if (!hasStateSetter) return false;\n // eslint-plugin-react-hooks message shapes for the loop-risk class:\n // \"React Hook useEffect has a missing dependency: 'x'. Either include it...\"\n // \"The 'x' object / 'x' array makes the dependencies of useEffect Hook\n // change on every render.\"\n return /missing dependenc|changes on every render|object makes the dependencies|array makes the dependencies/i.test(\n diag.message,\n );\n };\n\n for (const diag of reactResult) {\n const blocking = diag.severity === 'error' || isSetterLoopRisk(diag);\n if (blocking) {\n issues.push({\n check: diag.rule,\n line: diag.line,\n message: isSetterLoopRisk(diag)\n ? `${diag.message} (promoted to error: effect mutates state — missing/unstable deps cause infinite render loops)`\n : diag.message,\n fix: diag.fix,\n });\n } else {\n typeWarnings.push({\n check: diag.rule,\n line: diag.line,\n message: diag.message,\n fix: diag.fix,\n });\n }\n }\n\n // Merge overlapping issues: when multiple checkers flag the same line,\n // combine into one issue with the clearest actionable message.\n // e.g. AST says \"Input missing label prop\" + TS says \"ts2786 type mismatch\"\n // → single issue: \"Input missing label prop [also: ts2786]\"\n const lineMap = new Map<number, SelfCheckIssue[]>();\n for (const i of issues) {\n const list = lineMap.get(i.line) ?? [];\n list.push(i);\n lineMap.set(i.line, list);\n }\n\n const deduped: SelfCheckIssue[] = [];\n for (const [, group] of lineMap) {\n if (group.length === 1) {\n deduped.push(group[0]);\n continue;\n }\n // Prefer the non-TS issue (AST/ESLint) as primary — it's more actionable\n const primary = group.find(i => !i.check.startsWith('ts')) ?? group[0];\n const others = group.filter(i => i !== primary);\n if (others.length > 0) {\n const alsoTags = others.map(o => o.check).join(', ');\n deduped.push({\n ...primary,\n message: `${primary.message} [also flagged by: ${alsoTags}]`,\n });\n } else {\n deduped.push(primary);\n }\n }\n\n return { issues: deduped, typeWarnings };\n}\n"]}