sonamu 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{base-model-CWRKUX49.d.ts → base-model-C24du9JT.d.ts} +1 -1
- package/dist/{base-model-BzMJ2E_I.d.mts → base-model-IZdmwmB5.d.mts} +1 -1
- package/dist/bin/cli.js +51 -51
- package/dist/bin/cli.mjs +2 -2
- package/dist/{chunk-WJGRXAXE.js → chunk-FXWN5PEO.js} +84 -65
- package/dist/chunk-FXWN5PEO.js.map +1 -0
- package/dist/{chunk-6SP5N5ND.mjs → chunk-GQVZQZ5J.mjs} +2 -2
- package/dist/{chunk-HVVCQLAU.mjs → chunk-IEP5SWTY.mjs} +2 -2
- package/dist/{chunk-N6N3LENC.js → chunk-IEXW7P6A.js} +4 -4
- package/dist/{chunk-4K2F3SOM.mjs → chunk-OBPWSOYN.mjs} +2 -2
- package/dist/{chunk-ZFLQLW37.mjs → chunk-VBBKB2LD.mjs} +46 -27
- package/dist/chunk-VBBKB2LD.mjs.map +1 -0
- package/dist/{chunk-UAG3SKFM.js → chunk-WZJODZL6.js} +7 -7
- package/dist/{chunk-EUP6N7EK.js → chunk-ZNWZQLRN.js} +100 -100
- package/dist/database/drivers/knex/base-model.d.mts +2 -2
- package/dist/database/drivers/knex/base-model.d.ts +2 -2
- package/dist/database/drivers/knex/base-model.js +8 -8
- package/dist/database/drivers/knex/base-model.mjs +3 -3
- package/dist/database/drivers/kysely/base-model.d.mts +2 -2
- package/dist/database/drivers/kysely/base-model.d.ts +2 -2
- package/dist/database/drivers/kysely/base-model.js +9 -9
- package/dist/database/drivers/kysely/base-model.mjs +3 -3
- package/dist/index.d.mts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{model-CAH_4oQh.d.ts → model-Dbbfpk2X.d.mts} +1 -1
- package/dist/{model-CAH_4oQh.d.mts → model-Dbbfpk2X.d.ts} +1 -1
- package/package.json +1 -1
- package/src/api/sonamu.ts +43 -25
- package/src/database/drivers/knex/db.ts +10 -5
- package/src/database/drivers/kysely/db.ts +1 -1
- package/src/database/types.ts +2 -1
- package/src/index.ts +2 -0
- package/dist/chunk-WJGRXAXE.js.map +0 -1
- package/dist/chunk-ZFLQLW37.mjs.map +0 -1
- /package/dist/{chunk-6SP5N5ND.mjs.map → chunk-GQVZQZ5J.mjs.map} +0 -0
- /package/dist/{chunk-HVVCQLAU.mjs.map → chunk-IEP5SWTY.mjs.map} +0 -0
- /package/dist/{chunk-N6N3LENC.js.map → chunk-IEXW7P6A.js.map} +0 -0
- /package/dist/{chunk-4K2F3SOM.mjs.map → chunk-OBPWSOYN.mjs.map} +0 -0
- /package/dist/{chunk-UAG3SKFM.js.map → chunk-WZJODZL6.js.map} +0 -0
- /package/dist/{chunk-EUP6N7EK.js.map → chunk-ZNWZQLRN.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/types.ts","../src/api/code-converters.ts","../src/api/decorators.ts","../src/exceptions/so-exceptions.ts","../src/utils/utils.ts","../src/entity/entity.ts","../src/entity/entity-manager.ts","../src/api/sonamu.ts","../src/api/caster.ts","../src/syncer/syncer.ts","../src/utils/lodash-able.ts","../src/templates/generated.template.ts","../src/templates/base-template.ts","../src/templates/init_types.template.ts","../src/templates/entity.template.ts","../src/templates/view_list.template.ts","../src/database/db.ts","../src/database/drivers/knex/db.ts","../src/database/drivers/knex/client.ts","../src/utils/model.ts","../src/database/drivers/knex/generator.ts","../src/database/code-generator.ts","../src/database/db.abstract.ts","../src/database/drivers/kysely/client.ts","../src/database/drivers/knex/plugins/knex-on-duplicate-update.ts","../src/database/drivers/kysely/db.ts","../src/database/drivers/kysely/generator.ts","../src/templates/model.template.ts","../src/templates/model_test.template.ts","../src/templates/service.template.ts","../src/templates/view_form.template.ts","../src/templates/view_id_all_select.template.ts","../src/templates/view_id_async_select.template.ts","../src/templates/view_enums_dropdown.template.ts","../src/templates/view_enums_select.template.ts","../src/templates/view_enums_buttonset.template.ts","../src/templates/view_search_input.template.ts","../src/templates/view_list_columns.template.ts","../src/templates/generated_http.template.ts","../src/templates/generated_sso.template.ts","../src/templates/kysely_types.template.ts","../src/utils/controller.ts","../src/utils/zod-error.ts"],"names":["ApiParamType","z","api","_","chalk","glob","inflection","path","fs","equal","ts","entity","knex","Kysely","originalSQL","originalBindings","createPool","MysqlDialect","sql","prettier","key","options","target","p","cacheKey","cacheTtl","cachedData","fields","prop"],"mappings":";;;;;;;;AAAA,SAAS,SAAS;AAaX,IAAM,oBAAoB,EAC9B,OAAO,EACP,MAAM,+DAA+D;AAAA,EACpE,SAAS;AACX,CAAC,EACA,IAAI,EAAE,EACN,IAAI,EAAE,EACN,SAAS,mBAAmB;AAMxB,SAAS,WACd,OACwC;AACxC,SAAO,EAAE,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,CAAC;AACvC;AA2NO,SAAS,cAAc,GAA0B;AACtD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,iBAAiB,GAA6B;AAC5D,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,aAAa,GAAyB;AACpD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,YAAY,GAAwB;AAClD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,aAAa,GAAyB;AACpD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,cAAc,GAA0B;AACtD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,cAAc,GAA0B;AACtD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,eAAe,GAA2B;AACxD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,gBAAgB,GAA4B;AAC1D,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,WAAW,GAAuB;AAChD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,cAAc,GAA0B;AACtD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,eAAe,GAA2B;AACxD,SAAO,GAAG,SAAS;AACrB;AACO,SAAS,uBAAuB,GAAmC;AACxE,SAAO,GAAG,iBAAiB;AAC7B;AACO,SAAS,2BACd,GAC+B;AAC/B,SAAO,GAAG,iBAAiB;AAC7B;AACO,SAAS,sBAAsB,GAAkC;AACtE,SAAO,GAAG,iBAAiB;AAC7B;AACO,SAAS,yBAAyB,GAAqC;AAC5E,SAAO,GAAG,iBAAiB;AAC7B;AAUO,SAAS,mBAAmB,GAAiC;AAClE,SAAO,GAAG;AACZ;AAyEO,IAAM,kBAAkB,EAAE,KAAK,CAAC,QAAQ,QAAQ,OAAO,CAAC;AAWxD,SAAS,YAAY,GAAwB;AAClD,SAAO,EAAE,QAAQ,EAAE,cAAc,EAAE;AACrC;AACO,SAAS,cAAc,GAAwB;AACpD,SAAO,EAAE,QAAQ,EAAE,cAAc,EAAE;AACrC;AAqEO,IAAU;AAAA,CAAV,CAAUA,kBAAV;AAiEE,WAAS,SAAS,GAAkC;AACzD,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,QAAQ,GAAiC;AACvD,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,eAAe,GAAwC;AACrE,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,gBAAgB,GAAyC;AACvE,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,iBAAiB,GAA0C;AACzE,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,QAAQ,GAAiC;AACvD,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,MAAM,GAA+B;AACnD,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,gBAAgB,GAAyC;AACvE,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,YAAY,GAAqC;AAC/D,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAGT,WAAS,OAAO,GAAgC;AACrD,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,OAAO,GAAgC;AACrD,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,UAAU,GAAmC;AAC3D,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,UAAU,GAAmC;AAC3D,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,UAAU,GAAmC;AAC3D,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,UAAU,GAA+B;AACvD,WAAO,GAAG,MAAM,SAAS,EAAE,OAAO;AAAA,EACpC;AAFO,EAAAA,cAAS;AAGT,WAAS,YAAY,GAA+B;AACzD,WACE,GAAG,MAAM,UAAU,EAAE,OAAO,YAAY,EAAE,GAAG,WAAW,aAAa;AAAA,EAEzE;AAJO,EAAAA,cAAS;AAKT,WAAS,YAAY,GAAqC;AAC/D,WAAO,GAAG,MAAM;AAAA,EAClB;AAFO,EAAAA,cAAS;AAAA,GAnHD;AA+IV,IAAM,gBAAgB,EAAE,IAAI;AA6B5B,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,QAAQ,EAAE,OAAO;AAAA,IACf,UAAU,EAAE,OAAO;AAAA,IACnB,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,OAAO,EAAE,OAAO;AAAA,IAChB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS;AAAA,IACtC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS;AAAA,IACxC,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,IAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EAC/B,CAAC;AAAA,EACD,YAAY,EAAE,OAAO;AAAA,IACnB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,WAAW,EAAE,OAAO,CAAC,CAAC;AAAA,EACtB,eAAe,EAAE,OAAO,CAAC,CAAC;AAAA,EAC1B,gBAAgB,EAAE,OAAO;AAAA,IACvB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,OAAO,EAAE,OAAO;AAAA,IACd,UAAU,EAAE,OAAO;AAAA,IACnB,oBAAoB,EAAE,OAAO;AAAA,IAC7B,gBAAgB,EAAE,OAAO;AAAA,EAC3B,CAAC;AAAA,EACD,YAAY,EAAE,OAAO;AAAA,IACnB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,QAAQ,EAAE,OAAO;AAAA,IACf,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,SAAS,EAAE,OAAO;AAAA,IAChB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,WAAW,EAAE,OAAO;AAAA,IAClB,UAAU,EAAE,OAAO;AAAA,IACnB,OAAO,EAAE,QAAQ;AAAA,EACnB,CAAC;AAAA,EACD,mBAAmB,EAAE,OAAO;AAAA,IAC1B,UAAU,EAAE,OAAO;AAAA,IACnB,SAAS,EACN,OAAO;AAAA,MACN,MAAM,EAAE,OAAO;AAAA,MACf,OAAO,EAAE,OAAO;AAAA,MAChB,IAAI,EAAE,OAAO;AAAA,IACf,CAAC,EACA,MAAM;AAAA,IACT,eAAe,EAAE,OAAO;AAAA,EAC1B,CAAC;AAAA,EACD,mBAAmB,EAAE,OAAO;AAAA,IAC1B,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,WAAW,EAAE,OAAO;AAAA,IAClB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,oBAAoB,EAAE,OAAO;AAAA,IAC3B,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,sBAAsB,EAAE,OAAO;AAAA,IAC7B,UAAU,EAAE,OAAO;AAAA,IACnB,WAAW,EAAE,OAAO;AAAA,EACtB,CAAC;AAAA,EACD,mBAAmB,EAAE,OAAO;AAAA,IAC1B,UAAU,EAAE,OAAO;AAAA,IACnB,QAAQ,EAAE,OAAO;AAAA,EACnB,CAAC;AAAA,EACD,qBAAqB,EAAE,OAAO;AAAA,IAC5B,UAAU,EAAE,OAAO;AAAA,IACnB,QAAQ,EAAE,OAAO;AAAA,EACnB,CAAC;AAAA,EACD,sBAAsB,EAAE,OAAO;AAAA,IAC7B,UAAU,EAAE,OAAO;AAAA,IACnB,QAAQ,EAAE,OAAO;AAAA,EACnB,CAAC;AAAA,EACD,kBAAkB,EAAE,OAAO,CAAC,CAAC;AAC/B,CAAC;AAGM,IAAM,cAAc,EAAE,KAAK;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAGM,IAAM,cAAc,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO;AACjB,CAAC;;;AC3vBD,SAAS,KAAAC,UAAoB;AAgCtB,SAAS,oBACdC,MACA,aAEI,CAAC,GACL;AACA,MAAIA,KAAI,gBAAgB,SAAS,GAAG;AAClC,IAAAA,KAAI,eAAe,IAAI,CAAC,cAAc;AACpC,UAAI,UAAU,YAAY;AACxB,YAAI,UAAU;AAAA,UACZ,UAAU;AAAA,UACV;AAAA,QACF;AACA,QAAC,WAAW,UAAU,EAAE,IAAY;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,UAAU;AAAA,IACdA,KAAI,WAAW;AAAA,MACb,CAAC,UACC,CAAC,aAAa,UAAU,MAAM,IAAI,KAClC,CAAC,aAAa,UAAU,MAAM,IAAI,KAClC,CAAC,aAAa,YAAY,MAAM,IAAI,KACpC,EAAE,MAAM,aAAa,QAAQ,MAAM,KAAK,WAAW,GAAG;AAAA;AAAA,IAC1D;AAAA,IACA;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,0BACd,WACA,aAEI,CAAC,GAC2C;AAChD,SAAOD,GAAE;AAAA,IACP,UAAU,OAAO,CAAC,GAAG,UAAU;AAC7B,UAAI,UAAU,2BAA2B,MAAM,MAAM,UAAU;AAC/D,UAAI,MAAM,UAAU;AAClB,kBAAU,QAAQ,SAAS;AAAA,MAC7B;AACA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,MAAM,IAAI,GAAG;AAAA,MAChB;AAAA,IACF,GAAG,CAAC,CAAC;AAAA,EACP;AACF;AAKO,SAAS,2BACd,WACA,YAGoB;AACpB,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAOA,GAAE,OAAO;AAAA,IAClB,KAAK;AACH,aAAOA,GAAE,OAAO;AAAA,IAClB,KAAK;AACH,aAAOA,GAAE,QAAQ;AAAA,IACnB;AACE,YAAM,UAAU;AAChB,cAAQ,QAAQ,GAAG;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AACH,iBAAOA,GAAE,QAAS,QAAgB,KAAK;AAAA,QACzC,KAAK;AACH,gBAAM,UAAU;AAChB,iBAAO,0BAA0B,QAAQ,KAAK;AAAA,QAChD,KAAK;AACH,gBAAM,UAAU;AAIhB,iBAAOA,GAAE;AAAA,YACP,2BAA2B,QAAQ,cAAc,UAAU;AAAA,UAC7D;AAAA,QACF,KAAK;AACH,gBAAM,UAAU;AAOhB,cAAI,CAAC,QAAQ,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG;AACzC,gBAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,oBAAM,IAAI,MAAM,sBAAO,QAAQ,EAAE,EAAE;AAAA,YACrC;AACA,kBAAM,CAAC,KAAK,cAAc,IAAI,QAAQ,KAAM;AAAA,cAAI,CAAC,QAC/C,2BAA2B,KAAK,UAAU;AAAA,YAC5C;AACA,gBAAI,OAAiB,CAAC;AACtB,gBAAI,0BAA0BA,GAAE,UAAU;AACxC,qBAAO,eAAe,KAAK,QAAQ;AAAA,gBACjC,CAAC,WAAwC,OAAO,KAAK;AAAA,cACvD;AAAA,YACF,OAAO;AACL,qBAAO,CAAE,eAAwC,KAAK,KAAK;AAAA,YAC7D;AACA,kBAAM,YAAY,KAAK,OAAO,CAAC,QAAQ,QAAQ;AAC7C,qBAAO;AAAA,gBACL,GAAG;AAAA,gBACH,CAAC,GAAG,GAAG;AAAA,cACT;AAAA,YACF,GAAG,CAAC,CAAQ;AAEZ,gBAAI,QAAQ,OAAO,QAAQ;AACzB,kBAAI,IAAI,MAAM;AACZ,uBAAO,IAAI,KAAK,SAAS;AAAA,cAC3B;AAAA,YACF,OAAO;AACL,kBAAI,IAAI,MAAM;AACZ,uBAAO,IAAI,KAAK,SAAS;AAAA,cAC3B;AAAA,YACF;AAAA,UACF;AACA,cAAI,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG;AACpC,gBAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,oBAAM,IAAI,MAAM,sBAAO,QAAQ,EAAE,EAAE;AAAA,YACrC;AACA,kBAAM,MAAM,2BAA2B,QAAQ,KAAK,CAAC,GAAG,UAAU;AAClE,mBAAQ,IAAY,QAAQ;AAAA,UAC9B;AAEA,gBAAM,YAAY,WAAW,QAAQ,EAAE;AACvC,cAAI,cAAc,QAAW;AAC3B,mBAAOA,GAAE,OAAO;AAAA,UAElB;AACA,iBAAO;AAAA,QACT,KAAK;AACH,gBAAM,YAAY;AAKlB,cACE,UAAU,MAAM,WAAW,KAC3B,UAAU,MAAM,KAAK,CAAC,SAAS,SAAS,MAAM,GAC9C;AACA,gBAAI,UAAU,MAAM,CAAC,MAAM,QAAQ;AACjC,qBAAO;AAAA,gBACL,UAAU,MAAM,CAAC;AAAA,gBACjB;AAAA,cACF,EAAE,SAAS;AAAA,YACb,OAAO;AACL,qBAAO;AAAA,gBACL,UAAU,MAAM,CAAC;AAAA,gBACjB;AAAA,cACF,EAAE,SAAS;AAAA,YACb;AAAA,UACF;AAGA,iBAAOA,GAAE;AAAA,YACP,UAAU,MAAM;AAAA,cAAI,CAAC,SACnB,2BAA2B,MAAM,UAAU;AAAA,YAC7C;AAAA,UACF;AAAA,QACF,KAAK;AACH,gBAAM,mBAAmB;AAIzB,iBAAO,iBAAiB,MAAM,OAAO,CAAC,QAAQ,MAAM,UAAU;AAC5D,kBAAM,eAAe,2BAA2B,MAAM,UAAU;AAChE,gBAAI,UAAU,GAAG;AACf,qBAAO;AAAA,YACT,OAAO;AACL,qBAAOA,GAAE,aAAa,QAAe,YAAY;AAAA,YACnD;AAAA,UACF,GAAGA,GAAE,QAAQ,CAAQ;AAAA,QACvB,KAAK;AACH,gBAAM,YAAY;AAClB,iBAAOA,GAAE;AAAA,YACP,UAAU,SAAS;AAAA,cAAI,CAAC,SACtB,2BAA2B,MAAM,UAAU;AAAA,YAC7C;AAAA,UACF;AAAA,MACJ;AACA,aAAOA,GAAE,QAAQ;AAAA,EACrB;AACF;AAEO,SAAS,qBACd,UACA,kBACQ;AACR,MAAI,SAAS,aAAa,SAAS;AACjC,WAAO,iBAAiB,SAAS,MAAM,gBAAgB;AAAA,EACzD,WAAW,SAAS,aAAa,SAAS;AACxC,WAAO;AAAA,MACL,SAAS,OAAO,GAAG,SAAS,KAAK,IAAI,OAAO;AAAA,MAC5C;AAAA,MACA,SAAS,SACN;AAAA,QAAI,CAAC,kBACJ,qBAAqB,eAAe,gBAAgB;AAAA,MACtD,EACC,KAAK,IAAI;AAAA,MACZ;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,WAAW,SAAS,aAAa,UAAU;AACzC,WAAO;AAAA,MACL,SAAS,OAAO,GAAG,SAAS,KAAK,IAAI,OAAO;AAAA,MAC5C;AAAA,MACA,SAAS,SACN;AAAA,QAAI,CAAC,kBACJ,qBAAqB,eAAe,gBAAgB;AAAA,MACtD,EACC,KAAK,IAAI;AAAA,MACZ;AAAA,MACA,KAAK,SAAS,QAAQ,SAAS,KAAK,WAAW,gBAAgB,EAAE;AAAA,IACnE,EAAE,KAAK,IAAI;AAAA,EACb,OAAO;AACL,UAAM;AAAA,EACR;AACF;AAEO,SAAS,kBAAkB,UAAwC;AACxE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,OAAO,KAAK;AAAA,IACrB,KAAK;AACH,aAAO,OAAO,OAAO,KAAK;AAAA,IAC5B,KAAK;AACH,aAAO,OAAO,OAAO,OAAO,IAAI;AAAA,EACpC;AACF;AAEO,SAAS,iBACd,MACA,kBACQ;AACR,MAAI;AACJ,MAAI,cAAc,IAAI,GAAG;AACvB,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,iBAAiB,IAAI,GAAG;AACjC,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI,oBAAoB,kBAAkB,KAAK,QAAQ,CAAC;AAAA,EACzE,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE;AAC/B,qBAAiB,KAAK,KAAK,EAAE;AAAA,EAC/B,WAAW,aAAa,IAAI,GAAG;AAC7B,WAAO,GAAG,KAAK,IAAI,oBAAoB,KAAK,MAAM;AAAA,EACpD,WAAW,cAAc,IAAI,GAAG;AAC9B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,YAAY,IAAI,KAAK,aAAa,IAAI,GAAG;AAClD,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,cAAc,IAAI,GAAG;AAC9B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,eAAe,IAAI,GAAG;AAC/B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,gBAAgB,IAAI,GAAG;AAChC,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE;AAC/B,qBAAiB,KAAK,KAAK,EAAE;AAAA,EAC/B,WAAW,WAAW,IAAI,GAAG;AAC3B,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB,WAAW,cAAc,IAAI,GAAG;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE;AAC/B,qBAAiB,KAAK,KAAK,EAAE;AAAA,EAC/B,WAAW,eAAe,IAAI,GAAG;AAC/B,QACE,2BAA2B,IAAI,KAC9B,uBAAuB,IAAI,KAAK,KAAK,eACtC;AACA,aAAO,GAAG,KAAK,IAAI;AAAA,IACrB,OAAO;AAEL,aAAO,MAAM,KAAK,IAAI,KAAK,KAAK,YAAY,IAAI,KAAK,IAAI;AAAA,IAC3D;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AAEA,MAAK,KAAgC,UAAU;AAC7C,YAAQ;AAAA,EACV;AACA,MAAI,KAAK,UAAU;AACjB,YAAQ;AAAA,EACV;AAEA,SAAO,OAAO;AAChB;AAEO,SAAS,iBACd,IACQ;AACR,UAAQ,GAAG,KAAK,UAAU;AAAA,IACxB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,iBAAiB,GAAG,KAAK,SAAS,IAAI;AAAA,IAC/C,KAAK;AACH,aACE,iBAAiB,GAAG,KAAK,SAAS,IAClC,YAAY,GAAG,KAAK,aAAa,CAAC;AAAA,IAEtC,KAAK;AACH,aAAO,YAAY,iBAAiB,GAAG,KAAK,OAAO,CAAC,KAAK;AAAA,QACvD,GAAG,KAAK;AAAA,MACV,CAAC;AAAA,IACH,KAAK;AACH,UAAI,OAAO,GAAG,KAAK,UAAU,UAAU;AACrC,eAAO,cAAc,GAAG,KAAK,KAAK;AAAA,MACpC,OAAO;AACL,eAAO,aAAa,GAAG,KAAK,KAAK;AAAA,MACnC;AAAA,IACF,KAAK;AACH,aAAO,YAAY,GAAG,KAAK,QACxB,IAAI,CAAC,WAAyB,iBAAiB,MAAM,CAAC,EACtD,KAAK,GAAG,CAAC;AAAA,IACd,KAAK;AACH,aAAO,WAAW,GAAG,KAAK,OACvB,IAAI,CAAC,QAAgB,IAAI,GAAG,GAAG,EAC/B,KAAK,IAAI,CAAC;AAAA,IACf,KAAK;AACH,aAAO,WAAW,iBAAiB,GAAG,KAAK,IAAI,CAAC;AAAA,IAClD,KAAK;AACH,YAAM,QAAS,GAAW;AAC1B,aAAO;AAAA,QACL;AAAA,QACA,GAAG,OAAO,KAAK,KAAK,EAAE;AAAA,UACpB,CAAC,QAAQ,GAAG,GAAG,KAAK,iBAAiB,MAAM,GAAG,CAAC,CAAC;AAAA,QAClD;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO,iBAAiB,GAAG,KAAK,SAAS,IAAI;AAAA,IAC/C;AACE,YAAM,IAAI,MAAM,iDAAmB,GAAG,KAAK,QAAQ,EAAE;AAAA,EACzD;AACF;AAEO,SAAS,iBACd,QACA,kBACQ;AACR,SAAO,OACJ,IAAI,CAAC,UAAU;AACd,WAAO,GAAG,MAAM,IAAI,GAClB,MAAM,YAAY,CAAC,MAAM,aAAa,MAAM,EAC9C,KAAK,qBAAqB,MAAM,MAAM,gBAAgB,CAAC,GACrD,MAAM,aAAa,KAAK,MAAM,UAAU,KAAK,EAC/C;AAAA,EACF,CAAC,EACA,KAAK,IAAI;AACd;AAEO,SAAS,qBACd,WACA,kBACQ;AACR,MACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,SAAmB,GAC9B;AACA,WAAO;AAAA,EACT,WAAW,aAAa,SAAS,SAAS,GAAG;AAC3C,WAAO,KAAK,iBAAiB,UAAU,OAAO,gBAAgB,CAAC;AAAA,EACjE,WAAW,aAAa,gBAAgB,SAAS,GAAG;AAClD,WAAO,IAAI,UAAU,KAAK;AAAA,EAC5B,WAAW,aAAa,iBAAiB,SAAS,GAAG;AACnD,WAAO,OAAO,UAAU,KAAK;AAAA,EAC/B,WAAW,aAAa,QAAQ,SAAS,GAAG;AAC1C,WAAO,UAAU,MACd,IAAI,CAAC,SAAS,qBAAqB,MAAM,gBAAgB,CAAC,EAC1D,KAAK,KAAK;AAAA,EACf,WAAW,aAAa,eAAe,SAAS,GAAG;AACjD,WAAO,UAAU,MACd,IAAI,CAAC,SAAS,qBAAqB,MAAM,gBAAgB,CAAC,EAC1D,KAAK,KAAK;AAAA,EACf,WAAW,aAAa,QAAQ,SAAS,GAAG;AAC1C,WACE,qBAAqB,UAAU,cAAc,gBAAgB,IAAI;AAAA,EAErE,WAAW,aAAa,MAAM,SAAS,GAAG;AACxC,QACE,CAAC,QAAQ,QAAQ,WAAW,SAAS,EAAE,SAAS,UAAU,EAAE,MAAM,OAClE;AAEA,uBAAiB,KAAK,UAAU,EAAE;AAAA,IACpC;AACA,QAAI,UAAU,SAAS,UAAa,UAAU,KAAK,WAAW,GAAG;AAC/D,aAAO,UAAU;AAAA,IACnB,OAAO;AACL,aAAO,GAAG,UAAU,EAAE,IAAI,UAAU,KACjC,IAAI,CAAC,QAAQ,qBAAqB,KAAK,gBAAgB,CAAC,EACxD,KAAK,GAAG,CAAC;AAAA,IACd;AAAA,EACF,WAAW,aAAa,gBAAgB,SAAS,GAAG;AAClD,WAAO,GAAG;AAAA,MACR,UAAU;AAAA,MACV;AAAA,IACF,CAAC,IAAI,qBAAqB,UAAU,OAAO,gBAAgB,CAAC;AAAA,EAC9D,WAAW,aAAa,YAAY,SAAS,GAAG;AAC9C,WAAO,KAAK,UAAU,SAAS;AAAA,MAAI,CAAC,SAClC,qBAAqB,MAAM,gBAAgB;AAAA,IAC7C,CAAC;AAAA,EACH,WAAW,aAAa,YAAY,SAAS,GAAG;AAC9C,WAAO,IAAI,UAAU,EAAE,GACrB,UAAU,aACN,YAAY;AAAA,MACV,UAAU;AAAA,MACV;AAAA,IACF,CAAC,KACD,EACN;AAAA,EACF,OAAO;AACL,UAAM,IAAI,MAAM,qCAA2B,SAAS,EAAE;AAAA,EACxD;AACF;AAEO,SAAS,kBAAkB,WAAyB;AACzD,MAAI,aAAa,UAAU,SAAS,GAAG;AACrC,WAAO,UAAU,KAAM,CAAC;AAAA,EAC1B,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,SAAS,iBAAiB,IAAuB;AACtD,UAAQ,GAAG,KAAK,UAAU;AAAA,IACxB,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,OAAO,KAAM,GAAwB,KAAK,EAAE;AAAA,UACjD,CAAC,QAAQ,QAAQ;AACf,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,CAAC,GAAG,GAAG,iBAAkB,GAAwB,MAAM,GAAG,CAAC;AAAA,YAC7D;AAAA,UACF;AAAA,UACA,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,iBAAiB,GAAG,KAAK,IAAI;AAAA,MACxC;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,GAAG,KAAK;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,GAAG,KAAK;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,GAAG,KAAK;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,MACR;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG,iBAAiB,GAAG,KAAK,SAAS;AAAA,QACrC,UAAU;AAAA,MACZ;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG,iBAAiB,GAAG,KAAK,SAAS;AAAA,QACrC,UAAU;AAAA,MACZ;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,MACR;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,iBAAkB,GAAiB,KAAK,OAAO;AAAA,QACxD,WAAW,iBAAkB,GAAiB,KAAK,SAAS;AAAA,MAC9D;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAU,GAAG,KAAuB,QAAQ;AAAA,UAAI,CAAC,WAC/C,iBAAiB,MAAM;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AACE,YAAM,IAAI;AAAA,QACR,+EAAkC,GAAG,KAAK,QAAQ;AAAA,MACpD;AAAA,EACJ;AACF;AAEO,SAAS,mBACd,IACQ;AACR,MAAI,GAAG,KAAK,aAAa;AACvB,WAAO,GAAG,KAAK;AAAA,EACjB;AAEA,UAAQ,GAAG,KAAK,UAAU;AAAA,IACxB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,mBAAmB,GAAG,KAAK,SAAS,IAAI;AAAA,IACjD,KAAK;AACH,aAAO,mBAAmB,GAAG,KAAK,SAAS;AAAA,IAC7C,KAAK;AACH,aAAO,YAAY;AAAA,QACjB,GAAG,KAAK;AAAA,MACV,CAAC,OAAO,mBAAmB,GAAG,KAAK,SAAS,CAAC;AAAA,IAC/C,KAAK;AACH,UAAI,OAAO,GAAG,KAAK,UAAU,UAAU;AACrC,eAAO,IAAI,GAAG,KAAK,KAAK;AAAA,MAC1B,OAAO;AACL,eAAO,GAAG,GAAG,KAAK,KAAK;AAAA,MACzB;AAAA,IACF,KAAK;AACH,aAAO,GAAG,GAAG,KAAK,QACf,IAAI,CAAC,WAAyB,mBAAmB,MAAM,CAAC,EACxD,KAAK,KAAK,CAAC;AAAA,IAChB,KAAK;AACH,aAAO,GAAG,GAAG,KAAK,OAAO,IAAI,CAAC,QAAgB,IAAI,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC;AAAA,IACvE,KAAK;AACH,aAAO,GAAG,mBAAmB,GAAG,KAAK,IAAI,CAAC;AAAA,IAC5C,KAAK;AACH,YAAM,QAAS,GAAW;AAC1B,aAAO;AAAA,QACL;AAAA,QACA,GAAG,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,QAAQ;AACjC,cAAI,MAAM,GAAG,EAAE,KAAK,aAAa,eAAe;AAC9C,mBAAO,GAAG,GAAG,MAAM,mBAAmB,MAAM,GAAG,EAAE,KAAK,SAAS,CAAC;AAAA,UAClE,OAAO;AACL,mBAAO,GAAG,GAAG,KAAK,mBAAmB,MAAM,GAAG,CAAC,CAAC;AAAA,UAClD;AAAA,QACF,CAAC;AAAA,QACD;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO,mBAAmB,GAAG,KAAK,SAAS,IAAI;AAAA,IACjD;AACE,YAAM,IAAI,MAAM,iDAAmB,GAAG,KAAK,QAAQ,EAAE;AAAA,EACzD;AACF;;;AC/nBA,OAAO,gBAAgB;AAuBhB,IAAM,iBAKP,CAAC;AAWA,SAAS,IAAI,UAA+B,CAAC,GAAG;AACrD,YAAU;AAAA,IACR,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,SAAS,CAAC,OAAO;AAAA,IACjB,GAAG;AAAA,EACL;AAEA,SAAO,SAAU,QAAgB,aAAqB;AACpD,UAAM,YAAY,OAAO,YAAY,KAAK,MAAM,YAAY,EAAG,CAAC;AAChE,UAAM,aAAa;AACnB,UAAM,cAAc,IAAI,WAAW;AAAA,MACjC,UAAU,QAAQ,UAAU,EAAE;AAAA,MAC9B;AAAA,IACF,CAAC,IAAI,WAAW,SAAS,aAAa,IAAI,CAAC;AAE3C,UAAMC,OAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA,MAAM,QAAQ,QAAQ;AAAA,MACtB;AAAA,IACF;AACA,mBAAe,KAAKA,IAAG;AAAA,EACzB;AACF;;;AChEO,IAAe,cAAf,cAAmC,MAAM;AAAA,EAC9C,YACkB,YACT,SACA,SACP;AACA,UAAM,OAAO;AAJG;AACT;AACA;AAAA,EAGT;AACF;AAEO,SAAS,cAAc,KAA8B;AAC1D,SAAO,IAAI,eAAe;AAC5B;AAKO,IAAM,sBAAN,cAAkC,YAAY;AAAA,EACnD,YACS,UAAU,eACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EACrD,YACS,UAAU,gBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,oBAAN,cAAgC,YAAY;AAAA,EACjD,YACS,UAAU,aACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,8BAAN,cAA0C,YAAY;AAAA,EAC3D,YACS,UAAU,uBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,+BAAN,cAA2C,YAAY;AAAA,EAC5D,YACS,UAAU,yBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,4BAAN,cAAwC,YAAY;AAAA,EACzD,YACS,UAAU,qBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EACrD,YACS,UAAU,iBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;AAKO,IAAM,0BAAN,cAAsC,YAAY;AAAA,EACvD,YACS,UAAU,oBACV,SACP;AACA,UAAM,KAAK,SAAS,OAAO;AAHpB;AACA;AAAA,EAGT;AACF;;;AC5GA,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,OAAO;AAEP,SAAS,UAAU,aAAwC;AAChE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,KAAK,QAAQ,WAAW,GAAG,CAAC,KAAK,UAAU;AAC9C,UAAI,KAAK;AACP,eAAO,GAAG;AAAA,MACZ,OAAO;AACL,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AACA,eAAsB,eACpB,WACA,YAAqB,OAC2B;AAChD,QAAM,UAAiD,CAAC;AAExD,aAAW,YAAY,WAAW;AAChC,QAAI,aAAa,OAAO,KAAK,SAAS,WAAW,QAAQ;AAEzD,QAAI,WAAW;AACb,UAAI,UAAQ,SAAS;AACnB,eAAO,UAAQ,MAAM,UAAQ,QAAQ,UAAU,CAAC;AAAA,MAClD,OAAO;AACL,sBAAc,MAAM,KAAK,IAAI,CAAC;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,OAAO;AAC9B,YAAQ,KAAK;AAAA,MACX;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AACA,eAAsB,kBAAkB;AACtC,QAAM,cAAc,gBAAgB;AACpC,SAAO,YAAY,MAAM,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,KAAK,GAAG;AAC/D;AAEO,SAAS,kBAAkB;AAChC,QAAM,WAAW,UAAQ,MAAM,QAAQ;AACvC,MAAI,MAAM,KAAK,QAAQ,QAAQ;AAC/B,MAAI,IAAI,SAAS,SAAS,GAAG;AAC3B,UAAM,IAAI,MAAM,SAAS,EAAE,CAAC;AAAA,EAC9B;AACA,KAAG;AACD,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,eAAe,CAAC,GAAG;AAClD,aAAO,IAAI,MAAM,KAAK,GAAG,EAAE,KAAK,KAAK,GAAG;AAAA,IAC1C;AACA,UAAM,IAAI,MAAM,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,KAAK,GAAG;AAAA,EACtD,SAAS,IAAI,MAAM,KAAK,GAAG,EAAE,SAAS;AACtC,QAAM,IAAI,MAAM,qCAAqC;AACvD;AAEO,SAAS,YAAe,OAAmC;AAChE,SAAO,UAAU,QAAQ,UAAU;AACrC;AAEO,SAAS,QAAW,MAAgB;AACzC,SAAO,KAAK,IAAI,CAAC,QAAa;AAE5B,UAAM,aAAa,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,QAAQ,IAAI,SAAS,IAAI,CAAC;AACtE,UAAM,SAAS,EAAE,QAAQ,YAAY,CAAC,QAAQ,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC;AAChE,UAAM,WAAW,OAAO,KAAK,MAAM,EAAE;AAAA,MACnC,CAAC,QACC,OAAO,GAAG,EAAE,SAAS,KACrB,OAAO,GAAG,EAAE,MAAM,CAAC,UAAU,IAAI,KAAK,MAAM,IAAI;AAAA,IACpD;AAEA,UAAM,WAAW,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,GAAG,UAAU;AACrD,UAAI,CAAC,MAAM,SAAS,IAAI,GAAG;AACzB,YAAI,MAAM,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC,GAAG;AAC1D,YAAE,KAAK,IAAI,QAAQ,IAAI,KAAK,CAAC;AAC7B,iBAAO;AAAA,QACT,OAAO;AACL,YAAE,KAAK,IAAI,IAAI,KAAK;AACpB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,YAAM,UACJ,MAAM,CAAC,IACP,MACG,MAAM,CAAC,EACP,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EACzB,KAAK,EAAE;AACZ,QAAE;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,KAAK,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC,IAC/D,QAAQ,IAAI,KAAK,CAAC,IAClB,IAAI,KAAK;AAAA,MACf;AAEA,aAAO;AAAA,IACT,GAAG,CAAC,CAAQ;AACZ,aAAS,IAAI,CAAC,YAAa,SAAS,OAAO,IAAI,IAAK;AAEpD,WAAO;AAAA,EACT,CAAC;AACH;;;AC7GA,OAAOC,SAAO;;;ACAd,OAAOC,YAAW;AAClB,OAAOC,WAAU;AACjB,OAAOC,kBAAgB;AAEvB,OAAOC,WAAU;;;ACJjB,OAAOH,YAAW;AAGlB,SAAS,gBAAgB;AACzB,OAAOG,WAAU;AACjB,OAAOC,SAAQ;;;ACLf,SAAS,KAAAP,UAAS;AAGlB,SAAS,kBAAkB,SAAyB;AAClD,MAAI,mBAAmBA,GAAE,WAAW;AAClC,WAAO;AAAA,EACT,WACE,mBAAmBA,GAAE,eACrB,QAAQ,KAAK,qBAAqBA,GAAE,WACpC;AACA,WAAO;AAAA,EACT,WACE,mBAAmBA,GAAE,eACrB,QAAQ,KAAK,qBAAqBA,GAAE,WACpC;AAAA,EACF,WACE,mBAAmBA,GAAE,eACrB,QAAQ,KAAK,qBAAqBA,GAAE,eACpC,QAAQ,MAAM,IAAI,qBAAqBA,GAAE,WACzC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAGO,SAAS,OAAO,SAAyB,KAAe;AAC7D,MAAI,kBAAkB,OAAO,KAAK,OAAO,QAAQ,UAAU;AAEzD,WAAO,OAAO,GAAG;AAAA,EACnB,WACE,mBAAmBA,GAAE,YACrB,QAAQ,QAAQ,KAAK,CAAC,QAAwB,kBAAkB,GAAG,CAAC,GACpE;AAEA,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,YAAM,UAAU,QAAQ,QAAQ;AAAA,QAC9B,CAAC,QAAwB,eAAeA,GAAE;AAAA,MAC5C;AACA,aAAO,IAAI,IAAI,CAAC,SAAc,OAAO,SAAS,IAAI,CAAC;AAAA,IACrD,OAAO;AACL,aAAO,OAAO,GAAG;AAAA,IACnB;AAAA,EACF,WACE,mBAAmBA,GAAE,eACpB,QAAQ,UAAU,QAAQ,UAC3B;AAEA,WAAO,QAAQ;AAAA,EACjB,WACE,QAAQ,QACR,MAAM,QAAQ,GAAG,KACjB,mBAAmBA,GAAE,UACrB;AAEA,WAAO,IAAI,IAAI,CAAC,SAAc,OAAO,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC7D,WACE,mBAAmBA,GAAE,aACrB,OAAO,QAAQ,YACf,QAAQ,MACR;AAEA,WAAO,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,GAAG,WAAW;AAC5C,QAAE,MAAM,IAAI,OAAO,QAAQ,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;AACrD,aAAO;AAAA,IACT,GAAG,CAAC,CAAQ;AAAA,EACd,WAAW,mBAAmBA,GAAE,aAAa;AAE3C,WAAO,OAAO,QAAQ,KAAK,WAAW,GAAG;AAAA,EAC3C,WAAW,mBAAmBA,GAAE,aAAa;AAE3C,WAAO,OAAO,QAAQ,KAAK,WAAW,GAAG;AAAA,EAC3C,WACE,mBAAmBA,GAAE,WACrB,IAAI,KAAK,GAAG,EAAE,SAAS,MAAM,gBAC7B;AAEA,WAAO,IAAI,KAAK,GAAG;AAAA,EACrB,OAAO;AAEL,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,QAA0B;AACtD,SAAOA,GAAE,WAAW,CAAC,QAAa;AAChC,WAAO,OAAO,QAAQ,GAAG;AAAA,EAC3B,GAAG,MAAM;AACX;;;ACzFA,OAAOM,SAAQ,eAAe;AAE9B,OAAOC,SAAQ;AACf,OAAO,YAAY;AACnB,OAAOC,YAAW;AAClB,OAAON,SAAO;AACd,OAAOG,iBAAgB;AAEvB,OAAO,QAAQ;AAgCf,SAAS,KAAAL,UAAS;AAClB,OAAO,WAAW;;;ACzCX,SAAS,OACd,QACA,WACQ;AACR,QAAM,CAAC,IAAI,OAAO,IAAI,UAAU,MAAM;AACtC,SAAO,KAAK,UAAU;AACxB;;;ACNA,OAAOE,QAAO;;;ACIP,IAAe,WAAf,MAAwB;AAAA,EAC7B,YAAmB,KAAkB;AAAlB;AAAA,EAAmB;AAaxC;;;ADHO,IAAM,sBAAN,cAAkC,SAAS;AAAA,EAChD,cAAc;AACZ,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,mBAAmB;AACjB,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,OAAO,CAAC,GAAiC;AACvC,UAAM,YAAY,cAAc,UAAU;AAC1C,UAAM,WAAW,UAAU,IAAI,CAAC,OAAO,cAAc,IAAI,EAAE,CAAC;AAG5D,UAAM,cAAc,SACjB,IAAI,CAAC,WAAW;AACf,aAAO;AAAA,QACL,KAAK,mBAAmB,MAAM;AAAA,QAC9B,KAAK,wBAAwB,MAAM;AAAA,QACnC,KAAK,4BAA4B,MAAM;AAAA,QACvC,KAAK,oBAAoB,MAAM;AAAA,MACjC,EAAE,OAAO,WAAW;AAAA,IACtB,CAAC,EACA,KAAK;AAGR,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,gBAAY,KAAK,CAAC,GAAG,MAAM;AACzB,YAAM,CAAC,IAAI,IAAI,EAAE,MAAM,MAAM,GAAG;AAChC,YAAM,CAAC,IAAI,IAAI,EAAE,MAAM,MAAM,GAAG;AAChC,YAAM,SAAS,gBAAgB,QAAQ,IAAI;AAC3C,YAAM,SAAS,gBAAgB,QAAQ,IAAI;AAC3C,UAAI,SAAS,QAAQ;AACnB,eAAO;AAAA,MACT,WAAW,SAAS,QAAQ;AAC1B,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,UAAM,aAAa,YAAY;AAAA,MAC7B,CAAC,QAAQO,QAAO;AACd,YAAIA,QAAO,MAAM;AACf,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,UACL,OAAO,CAAC,GAAG,OAAQ,OAAO,MAAMA,IAAG,KAAK,IAAI,GAAGA,IAAG,OAAO,EAAE;AAAA,UAC3D,YAAYP,GAAE,KAAK,CAAC,GAAG,OAAQ,YAAY,GAAGO,IAAG,UAAU,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO,CAAC;AAAA,QACR,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAGA,UAAM,cAAc,SACjB,IAAI,CAAC,WAAW,OAAO,KAAK,OAAO,KAAK,CAAC,EACzC,KAAK;AACR,UAAM,eAAe,WAAW,WAAW;AAAA,MAAO,CAAC,cACjD,YAAY,SAAS,SAAS;AAAA,IAChC;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,YAAM,oBAAoB,aACvB,IAAI,CAAC,cAAc;AAClB,cAAM,SAAS,SAAS,KAAK,CAACC,YAAWA,QAAO,MAAM,SAAS,CAAC;AAChE,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,qBAAqB,SAAS,EAAE;AAAA,QAClD;AACA,cAAM,UAAU,OAAO,MAAM,SAAS;AAEtC,eAAO;AAAA,UACL,oBAAoB,SAAS;AAAA,UAC7B,SAAS,SAAS,MAAM,iBAAiB,OAAO,CAAC;AAAA,UACjD,QAAQ,SAAS,qBAAqB,SAAS;AAAA,UAC/C;AAAA,QACF;AAAA,MACF,CAAC,EACA,KAAK;AACR,iBAAW,QAAQ,CAAC,GAAG,mBAAmB,GAAG,WAAW,KAAK;AAC7D,iBAAW,aAAa,WAAW,WAAW;AAAA,QAC5C,CAAC,cAAc,CAAC,aAAa,SAAS,SAAS;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,OAAO,WAAW,MAAM,KAAK,IAAI;AAGvC,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,OAAO,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC;AAEpC,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB;AAAA,MACzB;AAAA,MACA,YAAY,WAAW;AAAA,MACvB,eAAe;AAAA,QACb;AAAA,QACA,YAAY,cAAc,KAAK,GAAG,CAAC;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBAAmB,QAAmC;AACpD,QAAI,OAAO,KAAK,OAAO,UAAU,EAAE,WAAW,GAAG;AAC/C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,OAAO,UAAU,OAAO,EAAE;AAAA,MAC1B,OAAO;AAAA,QACL,GAAG,OAAO,QAAQ,OAAO,UAAU,EAChC,OAAO,CAAC,CAACR,KAAG,SAAS,MAAM,OAAO,KAAK,SAAS,EAAE,SAAS,CAAC,EAC5D,IAAI,CAAC,CAAC,QAAQ,SAAS,MAAM;AAAA,UAC5B,gBAAgB,MAAM,cAAc,OAAO,KAAK,SAAS,EAAE;AAAA,YACzD,CAAC,OAAO,IAAI,EAAE;AAAA,UAChB,CAAC,gBAAgB,MAAM;AAAA,UACvB,eAAe,MAAM,qBAAqB,MAAM;AAAA,UAChD,gBAAgB,MAAM,WAAW,KAAK,UAAU,SAAS,CAAC;AAAA,QAC5D,CAAC,EACA,KAAK;AAAA,MACV;AAAA,MACA,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EAEA,wBACE,QACA,aAAuB,CAAC,GACZ;AACZ,UAAM,aAAa,GAAG,OAAO,MAAM,MAAM;AACzC,UAAM,WAA2B;AAAA,MAC/B,UAAU;AAAA,MACV,UAAU,OAAO,MAAM,IAAI,CAAC,SAAS;AACnC,eAAO;AAAA,UACL,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,aAAa,qBAAqB,UAAU,UAAU;AAE5D,UAAM,QAAQ;AAAA,MACZ,gBAAgB,UAAU,MAAM,UAAU;AAAA,MAC1C,eAAe,UAAU,qBAAqB,UAAU;AAAA,IAC1D;AAEA,WAAO;AAAA,MACL,OAAO,eAAe,OAAO,EAAE;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,4BAA4B,QAAmC;AAE7D,QAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,aAAO;AAAA,IACT,WAAW,OAAO,aAAa,QAAW;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,GAAG,OAAO,MAAM,MAAM;AAEzC,UAAM,cAAc,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,aAAa,IAAI;AAExE,UAAM,YAA8B,YAAY,IAAI,CAAC,SAAS;AAC5D,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA,UAAU,CAAC;AAAA,MACb;AAAA,IACF,CAAC;AAED,UAAM,aAAuB,CAAC;AAC9B,UAAM,aAAa,UAChB,IAAI,CAAC,aAAa,qBAAqB,UAAU,UAAU,CAAC,EAC5D,KAAK,IAAI;AAEZ,UAAM,aAAa;AAAA;AAAA;AAAA;AAAA,YAIX,OAAO,EAAE;AAAA;AAAA,aAER,OAAO,EAAE;AAAA;AAAA,gDAE0B,UAAU;AAAA;AAAA,EAExD,KAAK;AAEH,UAAM,QAAQ;AAAA,MACZ,gBAAgB,UAAU,MAAM,UAAU;AAAA,MAC1C,eAAe,UAAU,qBAAqB,UAAU;AAAA,IAC1D;AAEA,WAAO;AAAA,MACL,OAAO,mBAAmB,OAAO,EAAE;AAAA,MACnC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,oBAAoB,QAAmC;AACrD,QAAI,OAAO,KAAK,OAAO,OAAO,EAAE,UAAU,GAAG;AAC3C,aAAO;AAAA,IACT,WAAW,OAAO,aAAa,QAAW;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,OAAO,KAAK,OAAO,OAAO;AAC7C,UAAM,aAAuB,CAAC;AAC9B,UAAM,QAAkB;AAAA,MACtB,GAAG,WACA,IAAI,CAAC,cAAc;AAElB,cAAM,aAAa,OAAO,QAAQ,SAAS;AAG3C,cAAM,YAAY,OAAO,sBAAsB,UAAU;AACzD,cAAM,aAAa,GAAG,OAAO,MAAM,MAAM,SAAS,SAAS;AAC3D,cAAM,WAA2B;AAAA,UAC/B,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAGA,cAAM,OAAO,qBAAqB,UAAU,UAAU;AAEtD,eAAO;AAAA,UACL,gBAAgB,UAAU,MAAM,IAAI;AAAA,UACpC,eAAe,UAAU,qBAAqB,UAAU;AAAA,QAC1D;AAAA,MACF,CAAC,EACA,KAAK;AAAA,MACR,eAAe,OAAO,MAAM,MAAM;AAAA,MAClC,GAAG,WAAW;AAAA,QACZ,CAAC,cACC,KAAK,SAAS,KAAK,OAAO,MAAM,MAAM,SAAS,SAAS;AAAA,MAC5D;AAAA,MACA;AAAA,MACA,gBAAgB,OAAO,MAAM,MAAM,uBAAuB,WACvD,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EACnB,KAAK,GAAG,CAAC;AAAA,MACZ,eAAe,OAAO,MAAM,MAAM,8BAA8B,OAAO,MAAM,MAAM;AAAA,MACnF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,YAAY,OAAO,EAAE;AAAA,MAC5B;AAAA,MACA,YAAYA,GAAE,KAAK,UAAU;AAAA,IAC/B;AAAA,EACF;AACF;;;AExRO,IAAM,uBAAN,cAAmC,SAAS;AAAA,EACjD,cAAc;AACZ,UAAM,YAAY;AAAA,EACpB;AAAA,EAEA,iBAAiB,OAA0B;AACzC,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,GAAkC;AAClD,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,UAAM,eACJ,cAAc,IAAI,QAAQ,EAAE,MAAM;AAAA,MAChC,CAAC,SAAS,KAAK,SAAS;AAAA,IAC1B,MAAM;AAER,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA,WAED,QAAQ,eAAe,QAAQ;AAAA;AAAA,KAErC,QAAQ;AAAA,eACE,QAAQ,gBAAgB,QAAQ;AAAA,cACjC,QAAQ,+BAA+B,QAAQ;AAAA;AAAA,KAExD,QAAQ;AAAA,eACE,QAAQ,gBAAgB,QAAQ,gCACvC,eAAe,uBAAuB,EACxC;AAAA,cACQ,QAAQ,+BAA+B,QAAQ;AAAA;AAAA,QAErD,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;AC1CO,IAAM,mBAAN,cAA+B,SAAS;AAAA,EAC7C,cAAc;AACZ,UAAM,QAAQ;AAAA,EAChB;AAAA,EAEA,iBAAiB,OAA0B,aAAiC;AAC1E,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM,IAAI,eAAe,OAAO,EAAE,IAAI,MAAM,EAAE;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,OAAO,SAAoC;AACzC,UAAM,EAAE,UAAU,OAAO,UAAU,MAAM,IAAI;AAC7C,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,UAAM,UAAU,MAAM;AACpB,UAAI,UAAU;AACZ,eAAO;AAAA,UACL,OAAO,cAAc,eAAe,QAAQ;AAAA,UAC5C,QAAQ,cAAc,IAAI,QAAQ;AAAA,QACpC;AAAA,MACF,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,GAAG;AAEH,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,OAAO,QAAQ,SAAS,KAAK;AAAA,MACtD,MAAM,KAAK,UAAU;AAAA,QACnB,IAAI;AAAA,QACJ,OAAO,SAAS;AAAA,QAChB;AAAA,QACA,OAAO,SAAS,MAAM,SAAS,QAAQ,OAAO,GAAG;AAAA,QACjD,OAAO,QAAQ,OAAO,SAClB,QAAQ,QACR;AAAA,UACE,EAAE,MAAM,MAAM,MAAM,WAAW,UAAU,MAAM,MAAM,KAAK;AAAA,UAC1D,GAAI,SACA;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,MAAM,OAAO,MAAM;AAAA,cACnB,cAAc;AAAA,cACd,MAAM;AAAA,cACN,UAAU;AAAA,cACV,UAAU;AAAA,cACV,MAAM,OAAO,OAAO;AAAA,YACtB;AAAA,UACF,IACA,CAAC;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,WAAW;AAAA,UACb;AAAA,QACF;AAAA,QACJ,SAAS,CAAC,GAAI,QAAQ,WAAW,CAAC,CAAE;AAAA,QACpC,SAAS,QAAQ,WAAW;AAAA,UAC1B,GAAI,WACA,CAAC,IACD;AAAA,YACE,GAAG,CAAC,MAAM,YAAY;AAAA,UACxB;AAAA,QACN;AAAA,QACA,OAAO,QAAQ,SAAS;AAAA,UACtB,GAAI,WACA,CAAC,IACD;AAAA,YACE,CAAC,GAAG,MAAM,OAAO,SAAS,GAAG;AAAA,cAC3B,WAAW;AAAA,YACb;AAAA,YACA,CAAC,GAAG,MAAM,OAAO,aAAa,GAAG,EAAE,IAAI,KAAK;AAAA,UAC9C;AAAA,QACN;AAAA,MACF,CAAC,EAAE,KAAK;AAAA,MACR,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;ACvFA,OAAOG,iBAAgB;AACvB,OAAOH,QAAO;AACd,SAAS,KAAAF,UAAS;AAOX,IAAM,sBAAN,cAAkC,SAAS;AAAA,EAChD,cAAc;AACZ,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,OACE,MACA,KACA,aAAsB,MACtB,YAAoB,IACpB;AACA,WAAO,oBAAoB,GAAG,IAAI,aAAa,gBAAgB,EAAE,GAC/D,YAAY,iBAAiB,SAAS,QAAQ,EAChD,IAAI,IAAI;AAAA,EACV;AAAA,EAEA,aACE,UACA,KACA,OACA,YAAoB,OACpB,cAAuB,OACf;AACR,UAAM,UAAU,cAAc,GAAG,SAAS,KAAK,GAAG,SAAS,IAAI,IAAI,IAAI;AAEvE,YAAQ,IAAI,YAAY;AAAA,MACtB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,MAAM,OAAO;AAAA,MACtB,KAAK;AACH,cAAM,YAAY;AAAA,UAChB;AAAA,UACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,QAC5B;AACA,eAAO,KAAK,UAAU,IAAI,KAAK,OAAO;AAAA,MACxC,KAAK;AACH,eAAO,MACL,IAAI,WAAW,GAAG,OAAO,SAAS,EACpC,aAAa,OAAO;AAAA,MACtB,KAAK;AACH,YAAI,IAAI,UAAU;AAChB,iBAAO,gCAAgC,OAAO,2BAA2B,OAAO;AAAA,QAClF,OAAO;AACL,iBAAO,sCAAsC,OAAO;AAAA,QACtD;AAAA,MACF,KAAK;AACH,eAAO,MAAM,OAAO;AAAA,MACtB,KAAK;AACH,cAAM,EAAE,IAAI,OAAO,IAAI,uBAAuB,UAAU,IAAI,IAAI;AAChE,eAAO,MACL,IAAI,WAAW,GAAG,OAAO,SAAS,EACpC,GAAG,MAAM,SAAS,OAAO;AAAA,MAC3B,KAAK;AACH,eAAO,OAAO,OAAO,aACnB,IAAI,WAAW,UAAU,EAC3B;AAAA,MACF,KAAK;AACH,eAAO,MAAM,IAAI,WAAW,GAAG,OAAO,SAAS,EAAE,QAAQ,OAAO;AAAA,MAClE,KAAK;AACH,eAAO,gBAAgB,OAAO;AAAA,MAChC,KAAK;AACH,cAAM,cAAc,IAAI,SAAU;AAAA,UAChC,CAAC,UAAU,MAAM,SAAS,IAAI,QAAQ;AAAA,QACxC;AACA,YAAI,CAAC,aAAa;AAChB,gBAAM,IAAI,MAAM,oEAA4B,IAAI,IAAI,GAAG;AAAA,QACzD;AACA,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG,OAAO,GAAG,IAAI,WAAW,MAAM,EAAE;AAAA,QACtC;AAAA,MACF,KAAK;AACH,eAAO,gBAAgB,OAAO;AAAA,MAChC;AACE,cAAM,IAAI,MAAM,0CAAY,IAAI,UAAU,EAAE;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,mBACE,UACA,KACA,OACmB;AACnB,QAAI,IAAI,eAAe,SAAS;AAC9B,YAAM,EAAE,IAAI,OAAO,IAAI,uBAAuB,MAAM,SAAS,IAAI,IAAI;AACrE,aAAO;AAAA,QACL,YAAY,MAAM;AAAA,MACpB;AAAA,IACF,WAAW,IAAI,eAAe,UAAU;AACtC,UAAI;AACF,cAAM,UAAU,2BAA2B,UAAU,IAAI,IAAI;AAC7D,cAAM,SAAS,IAAI,SAAU,IAAI,CAAC,UAAU;AAC1C,qBAAW,QAAQ;AACnB,kBAAQ,cAAc,eAAe,QAAQ,IAAI;AACjD,iBAAO,KAAK,mBAAmB,UAAU,OAAO,KAAK;AAAA,QACvD,CAAC;AACD,eAAOE,GAAE,YAAY,MAAM;AAAA,MAC7B,QAAQ;AACN,eAAO,CAAC,IAAI;AAAA,MACd;AAAA,IACF,WAAW,IAAI,eAAe,SAAS;AACrC,aAAO,KAAK,mBAAmB,UAAU,IAAI,SAAU,KAAK;AAAA,IAC9D;AAEA,WAAO,CAAC,IAAI;AAAA,EACd;AAAA,EAEA,mBACE,UACA,KACA,OACA;AACA,QAAI,IAAI,SAAS,UAAU;AACzB,aAAO,YAAY,MAAM,OAAO,sCAAsC,MAAM,EAAE,IAAI,MAAM,OAAO;AAAA,IACjG,WAAW,IAAI,eAAe,SAAS;AACrC,UAAI,IAAI,SAAS,WAAW;AAC1B,cAAM,cAAc,GAAG,MAAM,OAAO,GAAGG,YAAW,SAAS,IAAI,IAAI,CAAC;AACpE,eAAO,YAAY,WAAW,2BAA2B,MAAM,EAAE,IAAI,WAAW;AAAA,MAClF,OAAO;AACL,YAAI;AACF,gBAAM,EAAE,IAAI,mBAAmB,cAAc,IAC3C,uBAAuB,UAAU,IAAI,IAAI;AAC3C,gBAAM,cAAc,GAAG,EAAE;AACzB,iBAAO,YAAY,WAAW,2BAA2B,cAAc,EAAE,IAAI,WAAW;AAAA,QAC1F,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,WAAW,IAAI,eAAe,gBAAgB;AAC5C,UAAI;AACF,cAAM,UAAU;AAAA,UACd;AAAA,UACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,QAC5B;AACA,cAAM,cAAc,cAAc,eAAe,QAAQ,IAAI;AAC7D,cAAM,cAAc,GAAG,QAAQ,IAAI;AACnC,eAAO,YAAY,WAAW,2BAA2B,YAAY,EAAE,IAAI,WAAW;AAAA,MACxF,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,YAAM,IAAI;AAAA,QACR,yEAAkB,IAAI,IAAI,IAAI,IAAI,UAAU;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAa,UAAkB,KAAoB,OAA0B;AAC3E,QAAI,IAAI,SAAS,UAAU;AACzB,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,IAAI,aAAa,QAAQ,IAAI,SAAS;AAC1D,QAAI;AACJ,QAAI,IAAI,eAAe,SAAS;AAC9B,UAAI,IAAI,SAAS,WAAW;AAC1B,sBAAc,GAAG,MAAM,OAAO,GAAGA,YAAW,SAAS,IAAI,IAAI,CAAC;AAAA,MAChE,OAAO;AACL,YAAI;AACF,gBAAM,EAAE,GAAG,IAAI,uBAAuB,UAAU,IAAI,IAAI;AACxD,wBAAc,GAAG,EAAE;AAAA,QACrB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO,IAAI,WAAW,kBAAkB,IAAI,IAAI,OAC9C,cAAc,cAAc,EAC9B;AAAA,IACF,WAAW,IAAI,eAAe,gBAAgB;AAC5C,UAAI;AACF,cAAM,UAAU;AAAA,UACd;AAAA,UACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,QAC5B;AACA,sBAAc,GAAG,QAAQ,IAAI;AAC7B,eAAO,IAAI,WAAW,kBAAkB,IAAI,IAAI,OAC9C,cAAc,cAAc,EAC9B;AAAA,MACF,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,YAAM,IAAI;AAAA,QACR,yEAAkB,IAAI,IAAI,IAAI,IAAI,UAAU;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,SAGT;AACA,UAAM,MAAM;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AACA,UAAM,iBAAiB,QAAQ;AAAA,MAC7B,CAAC,QAAQ,IAAI,SAAS;AAAA,IACxB,GAAG;AACH,QAAI,kBAAkB,0BAA0BL,GAAE,SAAS;AACzD,UAAI,UAAU,OAAO,KAAK,eAAe,IAAI,EAAE,CAAC;AAAA,IAClD;AACA,UAAM,gBAAgB,QAAQ,KAAK,CAAC,QAAQ,IAAI,SAAS,QAAQ,GAAG;AACpE,QAAI,iBAAiB,yBAAyBA,GAAE,SAAS;AACvD,UAAI,SAAS,OAAO,KAAK,cAAc,IAAI,EAAE,CAAC;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OACE,EAAE,SAAS,GACX,aACA,gBACA;AACA,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,SAAS,cAAc,IAAI,QAAQ;AAGzC,UAAM,UAAW,YAAY,SAC1B,OAAO,CAAC,QAAQ,IAAI,SAAS,IAAI,EACjC,IAAI,CAAC,QAAQ;AACZ,YAAM,gBAAgB,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI;AAClE,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,OAAO,eAAe,QAAQ,IAAI;AAAA,QAClC,IAAI,YAAY,KAAK,aAAa,UAAU,KAAK,KAAK,CAAC;AAAA,MACzD;AAAA,IACF,CAAC;AAGH,UAAM,gBAAiB,eAAe,SACnC;AAAA,MACC,CAAC,QACC,IAAI,SAAS,QACb,IAAI,SAAS,gBACZ,CAAC,SAAS,WAAW,EAAE,SAAS,IAAI,UAAU,KAC7C,IAAI,KAAK,SAAS,KAAK;AAAA,IAC7B,EAEC,KAAK,CAAC,MAAM;AACX,aAAO,EAAE,QAAQ,YAAY,IAAI;AAAA,IACnC,CAAC;AAGH,UAAM,eAAiD,CAAC;AACxD,aAAS,OAAO,eAAe;AAC7B,UAAI;AACJ,UAAI,iBAAiB;AACrB,UAAI;AAEJ,UAAI,IAAI,eAAe,SAAS;AAC9B,YAAI,IAAI,SAAS,UAAU;AACzB,gBAAM;AACN,mBAAS,GAAG,MAAM,OAAO;AACzB,2BAAiB,MAAM;AAAA,QACzB,OAAO;AACL,gBAAM;AACN,cAAI;AACF,kBAAM,EAAE,mBAAmB,GAAG,IAAI;AAAA,cAChC;AAAA,cACA,IAAI;AAAA,YACN;AACA,6BAAiB,kBAAkB;AACnC,qBAAS;AAAA,UACX,QAAQ;AACN;AAAA,UACF;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM;AACN,YAAI;AACF,gBAAM,UAAU;AAAA,YACd;AAAA,YACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,UAC5B;AACA,2BAAiB,QAAQ;AAAA,QAC3B,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAEA,mBAAa,KAAK;AAAA,QAChB;AAAA,QACA,SAAS;AAAA,UACP,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAGA,UAAM,gBAAgBE,GAAE;AAAA,MACtB,YACG,SAAU,IAAI,CAAC,QAAQ;AACtB,eAAO,KAAK,mBAAmB,UAAU,KAAK,KAAK;AAAA,MACrD,CAAC,EACA,KAAK,EACL,OAAO,CAAC,QAAQ,QAAQ,IAAI;AAAA,IACjC,EAAE,KAAK,IAAI;AAGX,iBAAc,KAAK;AAAA,MACjB,KAAK;AAAA,MACL,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,MAAM,KAAK,WAAW,aAAa;AAEzC,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAmBD,MAAM,OAAO;AAAA,WACb,MAAM,OAAO,gCAAgC,MAAM,EAAE,IACxD,MAAM,EACR;AAAA,WACK,MAAM,OAAO,mCAAmC,MAAM,EAAE,IAC3D,MAAM,EACR;AAAA,EACJ,aAAa;AAAA,EACb,cACC,IAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,mBAAmB,UAAU,KAAK,KAAK;AAAA,MACrD,CAAC,EACA,KAAK,IAAI,CAAC;AAAA;AAAA,OAEN,MAAM,OAAO;AAAA,0BACM,MAAM,OAAO,YAAY,MAAM,OAAO;AAAA;AAAA,mDAEb,MAAM,OAAO;AAAA;AAAA;AAAA,gBAGhD,IAAI,OAAO;AAAA,eACZ,IAAI,MAAM;AAAA;AAAA;AAAA;AAAA,+CAIsB,MAAM,OAAO,cACxD,MAAM,aACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUI,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYb,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAOE,MAAM,QAAQ;AAAA,cACrB,OAAO,SAAS,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAef,MAAM,OAAO,iBAAiB,QACrD,IAAI,CAAC,QAAQ;AACZ,eAAO;AAAA,UACL,aAAa,IAAI,KAAK;AAAA,UACtB,OAAO,IAAI,EAAE;AAAA,UACb,eAAe,CAAC,SAAS,MAAM,EAAE,SAAS,IAAI,KAAK,MAAM,KAAK;AAAA,QAChE,EAAE,KAAK,IAAI;AAAA,MACb,CAAC,EACA,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,2BAGW,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAO5B,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMd,cACC,IAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,aAAa,UAAU,KAAK,KAAK;AAAA,MAC/C,CAAC,EACA,KAAK,UAAU,CAAC;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,QAsGrB,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,uBACd,UACA,SAMA;AACA,QAAM,aAAa,cAAc,IAAI,QAAQ;AAC7C,QAAM,OAAO,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAC5D,MAAI,QAAQ,WAAW,IAAI,GAAG;AAC5B,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,gBAAgB;AAAA,MAChB,mBAAmB,cAAc,eAAe,QAAQ;AAAA,MACxD,OAAO,KAAK,QAAQ,KAAK;AAAA,IAC3B;AAAA,EACF,OAAO;AACL,UAAM,cAAcG,YAAW;AAAA,MAC7BA,YAAW,WAAW,QAAQ,IAAI,MAAMA,YAAW,WAAW,OAAO;AAAA,MACrE;AAAA,IACF;AACA,QAAI;AACF,YAAM,oBAAoB,cAAc,eAAe,QAAQ;AAC/D,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,gBAAgB;AAAA,QAChB;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAAC;AACT,UAAM,IAAI,MAAM,6CAAoB,OAAO,EAAE;AAAA,EAC/C;AACF;AAEO,SAAS,2BACd,UACA,SACc;AACd,QAAM,aAAa,cAAc,IAAI,QAAQ;AAC7C,QAAM,UAAU,WAAW,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,OAAO;AACrE,MAAI,eAAe,OAAO,GAAG;AAC3B,UAAM,YAAY,cAAc,IAAI,QAAQ,IAAI;AAChD,QAAI,UAAU,aAAa,QAAW;AACpC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,WAAO;AAAA,EACT,OAAO;AACL,UAAM,IAAI,MAAM,6CAAoB,OAAO,EAAE;AAAA,EAC/C;AACF;;;ACnmBA,OAAOC,WAAU;;;ACAjB,OAAOJ,QAAO;AAEd,OAAOS,WAAoB;;;ACF3B,OAAO,UAAoB;;;ACSpB,SAAS,QAAW,OAAqB;AAC9C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,WAAO,CAAC,KAAU;AAAA,EACpB;AACF;AAEO,SAAS,SAAY,KAAyB;AACnD,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,MAAI,KAAK,MAAM,CAAC,QAAQ,SAAS,GAAG,EAAE,SAAS,MAAM,GAAG,GAAG;AACzD,WAAO,IAAI,IAAe,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AAAA,EACxE,OAAO;AACL,WAAO,IAAI,IAAe,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC/C;AACF;;;ACxBA,OAAOT,QAAO;AACd,OAAO,cAAc;AACrB,OAAOG,iBAAgB;AACvB,OAAOG,YAAW;;;ACHlB,OAAON,QAAO;AACd,OAAO,WAAW;AAGX,IAAM,gBAAN,MAAoB;AAAA,EACzB,kBACE,eACA,WACA;AACA,UAAM,YAAY;AAAA,MAChB,KAAK,CAAC;AAAA,MACN,MAAM,CAAC;AAAA,MACP,OAAO,CAAC;AAAA,IACV;AAGA,UAAM,eAAe;AAAA,MACnB,IAAIA,GAAE,aAAa,WAAW,eAAe,CAAC,QAAQ,IAAI,IAAI;AAAA,MAC9D,QAAQA,GAAE,aAAa,eAAe,WAAW,CAAC,QAAQ,IAAI,IAAI;AAAA,IACpE;AACA,QAAI,aAAa,OAAO,SAAS,GAAG;AAClC,gBAAU,MAAM,UAAU,IAAI,OAAO,aAAa,MAAM;AAAA,IAC1D;AACA,QAAI,aAAa,GAAG,SAAS,GAAG;AAC9B,gBAAU,OAAO,UAAU,KAAK,OAAO,aAAa,EAAE;AAAA,IACxD;AAGA,UAAM,gBAAgBA,GAAE;AAAA,MACtB;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,IAAI;AAAA,IACf;AACA,UAAM,gBAAgBA,GAAE;AAAA,MACtB;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,IAAI;AAAA,IACf;AACA,cAAU,QAAQA,GAAE;AAAA,MAAe;AAAA,MAAe;AAAA,MAAe,CAAC,GAAG,MACnE,MAAM,GAAG,CAAC;AAAA,IACZ;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,kBACE,eACA,WACA;AAEA,QAAI,YAAY;AAAA,MACd,KAAK,CAAC;AAAA,MACN,MAAM,CAAC;AAAA,IACT;AACA,UAAM,eAAe;AAAA,MACnB,IAAIA,GAAE;AAAA,QAAa;AAAA,QAAW;AAAA,QAAe,CAAC,QAC5C,CAAC,IAAI,MAAM,IAAI,QAAQ,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI;AAAA,MAC7C;AAAA,MACA,QAAQA,GAAE;AAAA,QAAa;AAAA,QAAe;AAAA,QAAW,CAAC,QAChD,CAAC,IAAI,MAAM,IAAI,QAAQ,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI;AAAA,MAC7C;AAAA,IACF;AACA,QAAI,aAAa,OAAO,SAAS,GAAG;AAClC,gBAAU,MAAM,UAAU,IAAI,OAAO,aAAa,MAAM;AAAA,IAC1D;AACA,QAAI,aAAa,GAAG,SAAS,GAAG;AAC9B,gBAAU,OAAO,UAAU,KAAK,OAAO,aAAa,EAAE;AAAA,IACxD;AAEA,WAAO;AAAA,EACT;AACF;;;AD1DO,IAAM,gBAAN,cAA4B,cAAc;AAAA,EAC/C,MAAM,oCACJ,OACA,SACA,SAC2B;AAE3B,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,mCAAmC,KAAK;AAAA,MACxC;AAAA,MACA,GAAG,KAAK,qBAAqB,OAAO;AAAA,MACpC;AAAA,MACA;AAAA,MACA,GAAG,KAAK,oBAAoB,OAAO;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,OAAO,WAAW,KAAK;AAAA,MACvB,WAAW,MAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,QACjD,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2BACJ,OACA,UAC6B;AAC7B,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,EAAE,IAAI,KAAK,IAAI,KAAK,sBAAsB,OAAO,QAAQ;AAC/D,QAAI,GAAG,WAAW,KAAK,KAAK,WAAW,GAAG;AACxC,cAAQ,IAAI,iDAAc;AAC1B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC;AAAA,MACA,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC;AAAA,MACA,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAEA,UAAM,oBAAoB,SACvB,IAAI,CAAC,YAAY,QAAQ,QAAQ,KAAK,GAAG,CAAC,EAC1C,KAAK,GAAG;AACX,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,MAAM;AAAA,QACN,OAAO,YAAY,KAAK,KAAK,iBAAiB;AAAA,QAC9C,WAAW,MAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,UACjD,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mCACJ,OACA,eACA,eACA,WACA,WAC6B;AAc7B,UAAM,iBAAiB,KAAK,kBAAkB,eAAe,SAAS;AAGtE,UAAM,qBAAqB,KAAK;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,kBAAkB,eAAe,SAAS;AAGtE,UAAM,oBAAoB,KAAK;AAAA,MAC7B;AAAA,MACA;AAAA,IACF;AAEA,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC,GAAI,eAAe,IAAI,SAAS,IAAI,mBAAmB,IAAI,KAAK,CAAC;AAAA,MACjE,GAAI,eAAe,KAAK,SAAS,IAAI,mBAAmB,KAAK,KAAK,CAAC;AAAA,MACnE,GAAI,eAAe,MAAM,SAAS,IAAI,mBAAmB,MAAM,KAAK,CAAC;AAAA,MACrE,GAAI,eAAe,IAAI,SAAS,IAAI,kBAAkB,IAAI,KAAK,CAAC;AAAA,MAChE,GAAI,eAAe,KAAK,SAAS,IAAI,kBAAkB,KAAK,KAAK,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC,GAAI,eAAe,IAAI,SAAS,IAAI,mBAAmB,IAAI,OAAO,CAAC;AAAA,MACnE,GAAI,eAAe,KAAK,SAAS,IAAI,mBAAmB,KAAK,OAAO,CAAC;AAAA,MACrE,GAAI,eAAe,MAAM,SAAS,IAAI,mBAAmB,MAAM,OAAO,CAAC;AAAA,MACvE,GAAI,kBAAkB,IAAI,KAAK,SAAS,IACpC,kBAAkB,IAAI,OACtB,CAAC;AAAA,MACL,GAAI,kBAAkB,KAAK,KAAK,SAAS,IACrC,kBAAkB,KAAK,OACvB,CAAC;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,MACxD,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,GAAI,CAAC,OAAO,QAAQ,OAAO,EACxB,IAAI,CAAC,WAAW;AACf,cAAM,MAAM,eAAe,MAAM,EAAE;AACnC,YAAI,MAAM,GAAG;AACX,iBAAO,SAAS;AAAA,QAClB;AACA,eAAO;AAAA,MACT,CAAC,EACA,OAAO,CAAC,SAAS,SAAS,IAAI;AAAA,IACnC,EAAE,KAAK,GAAG;AAEV,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,2BACJ,OACA,gBACA,YAC6B;AAC7B,UAAM,SAAS,CAAC,OAAiC;AAC/C,aAAO,CAAC,GAAG,QAAQ,KAAK,GAAG,GAAG,GAAG,EAAE,EAAE,KAAK,KAAK;AAAA,IACjD;AACA,UAAM,OAAO,eAAe;AAAA,MAC1B,CAAC,QAAQ,YAAY;AACnB,cAAM,cAAc,WAAW;AAAA,UAC7B,CAAC,QAAQ,OAAO,OAAO,MAAM,OAAO,GAAG;AAAA,QACzC;AACA,YAAI,CAAC,aAAa;AAChB,iBAAO,IAAI,KAAK,OAAO;AACvB,iBAAO;AAAA,QACT;AAEA,YAAIM,OAAM,SAAS,WAAW,MAAM,OAAO;AACzC,iBAAO,SAAS,KAAK,WAAW;AAChC,iBAAO,SAAS,KAAK,OAAO;AAC5B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,KAAK,CAAC;AAAA,QACN,UAAU,CAAC;AAAA,QACX,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,KAAK,KAAK,sBAAsB,OAAO,KAAK,GAAG;AAAA,MAC/C,UAAU,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAAA,MACzD,UAAU,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAAA,IAC3D;AAEA,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC,GAAG,QAAQ,IAAI;AAAA,MACf,GAAG,QAAQ,SAAS;AAAA,MACpB,GAAG,QAAQ,SAAS;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kCAAkC,KAAK;AAAA,MACvC,GAAG,QAAQ,IAAI;AAAA,MACf,GAAG,QAAQ,SAAS;AAAA,MACpB,GAAG,QAAQ,SAAS;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,MACxD,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,IAEF,EAAE,KAAK,GAAG;AAEV,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,sBACE,UACA,KACA;AACA,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,SAAS,cAAc,IAAI,QAAQ;AAEzC,WAAO;AAAA;AAAA;AAAA;AAAA,IAIP,QAAQ;AAAA,IACR,QAAQ;AAAA;AAAA;AAAA,IAGR,MAAM,KAAK;AAAA;AAAA,WAEJ,QAAQ,eAAe,QAAQ,wBAAwB,MAAM,EAAE;AAAA;AAAA;AAAA,IAGtE,QAAQ;AAAA;AAAA,QAEJ,QAAQ;AAAA,iBACC,QAAQ;AAAA;AAAA,wEAE+C,QAAQ;AAAA,6BACnD,QAAQ;AAAA;AAAA;AAAA,eAGtB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4EAOuB,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAM/B,QAAQ;AAAA;AAAA,kBAElB,QAAQ;AAAA,eACX,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wEAUiD,MAAM,aAAa;AAAA,6BAC9D,QAAQ;AAAA;AAAA,cAEvB,QAAQ;AAAA,0BACI,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKjB,IAAI,MAAM;AAAA,kBACT,IAAI,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAQR,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,wBAIR,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMZ,OAAO,KAAK;AAAA;AAAA;AAAA,2BAGT,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAaf,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAgBzB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAOE,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,0CAKS,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAYlC,OAAO,KAAK,eAAe,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAO5C,QAAQ,eAAe,QAAQ;AAAA,QACtC,KAAK;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,SAAsC;AACjE,WAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,YAAM,SAAmB,CAAC;AAC1B,UAAI,OAAO,SAAS,MAAM;AACxB,eAAO;AAAA,MACT;AAGA,UAAI,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW;AACxD,eAAO;AAAA,UACL,GAAG,OAAO,IAAI,KAAK,OAAO,IAAI,MAAM,OAAO,SAAS,KAAK,OAAO,KAAK;AAAA,QACvE;AAAA,MACF,OAAO;AACL,YAAI,aAAa,OAAO;AACxB,YAAI;AACJ,YAAI,WAAW,SAAS,MAAM,KAAK,eAAe,QAAQ;AACxD,sBAAY;AACZ,uBAAa;AAAA,QACf;AACA,eAAO;AAAA,UACL,GAAG,OAAO,IAAI,KAAK,OAAO,IAAI,IAC5B,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EACzC,GAAG,YAAY,MAAM,SAAS,MAAM,EAAE;AAAA,QACxC;AAAA,MACF;AACA,UAAI,OAAO,UAAU;AACnB,eAAO,KAAK,YAAY;AAAA,MAC1B;AAEA,aAAO,KAAK,OAAO,WAAW,eAAe,eAAe;AAE5D,UAAI,OAAO,cAAc,QAAW;AAClC,YACE,OAAO,OAAO,cAAc,YAC5B,OAAO,UAAU,WAAW,GAAG,GAC/B;AACA,iBAAO,KAAK,aAAa,OAAO,SAAS,GAAG;AAAA,QAC9C,OAAO;AACL,iBAAO,KAAK,uBAAuB,OAAO,SAAS,KAAK;AAAA,QAC1D;AAAA,MACF;AAEA,aAAO,SAAS,OAAO,KAAK,GAAG,CAAC;AAAA,IAClC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,SAAqC;AAC/D,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC;AAAA,IACV;AACA,UAAM,QAAQN,GAAE;AAAA,MACd,QAAQ,OAAO,CAAC,GAAG,UAAU;AAC3B,UAAE;AAAA,UACA,SAAS,MAAM,IAAI,KAAK,MAAM,QAC3B,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EACvB,KAAK,GAAG,CAAC;AAAA,QACd;AACA,eAAO;AAAA,MACT,GAAG,CAAC,CAAa;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBACN,WACA,eACA;AACA,QAAI,UAAU;AAAA,MACZ,KAAK;AAAA,QACH,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,OAAO;AAAA,QACL,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAEA,YAAQ,MAAM;AAAA,MACZ,IAAI,CAAC,UAAU,GAAG,KAAK,qBAAqB,UAAU,GAAG,CAAC;AAAA,MAC1D,MAAM;AAAA,QACJ;AAAA,QACA,qBAAqB,UAAU,IAC5B,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,GAAG,EAC5B,KAAK,IAAI,CAAC;AAAA,MACf;AAAA,IACF;AACA,YAAQ,OAAO;AAAA,MACb,IAAI;AAAA,QACF;AAAA,QACA,qBAAqB,UAAU,KAC5B,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,GAAG,EAC5B,KAAK,IAAI,CAAC;AAAA,MACf;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,qBAAqB,UAAU,IAAI;AAAA,MAC7C;AAAA,IACF;AACA,YAAQ,QAAQ,UAAU,MAAM;AAAA,MAC9B,CAAC,GAAG,aAAa;AACf,cAAM,eAAe,cAAc;AAAA,UACjC,CAAC,QAAQ,IAAI,QAAQ,SAAS;AAAA,QAChC;AACA,YAAI,iBAAiB,QAAW;AAC9B,iBAAO;AAAA,QACT;AAGA,cAAM,eAAeA,GAAE;AAAA,UACrB,KAAK,qBAAqB,CAAC,YAAY,CAAC;AAAA,UACxC,KAAK,qBAAqB,CAAC,QAAQ,CAAC;AAAA,QACtC;AACA,cAAM,iBAAiBA,GAAE;AAAA,UACvB,KAAK,qBAAqB,CAAC,QAAQ,CAAC;AAAA,UACpC,KAAK,qBAAqB,CAAC,YAAY,CAAC;AAAA,QAC1C;AACA,YAAI,aAAa,SAAS,GAAG;AAC3B,YAAE,KAAK;AAAA,YACL,GAAG,EAAE;AAAA,YACL;AAAA,YACA,GAAG,aAAa,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,EAAE,IAAI,WAAW;AAAA,UAC7D;AACA,YAAE,OAAO;AAAA,YACP,GAAG,EAAE;AAAA,YACL;AAAA,YACA,GAAG,eAAe,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,EAAE,IAAI,WAAW;AAAA,UAC/D;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,qBACN,WACA,WACA;AACA,QAAI,UAAU;AAAA,MACZ,KAAK;AAAA,QACH,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAGA,YAAQ,MAAM;AAAA,MACZ,IAAI,CAAC,kBAAkB,GAAG,KAAK,oBAAoB,UAAU,GAAG,CAAC;AAAA,MACjE,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,UAAU,IACV;AAAA,UACC,CAAC,UACC,MAAM,QAAQ;AAAA,YAAM,CAAC,YACnB,UAAU,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,SAAS,OAAO;AAAA,UACvD,MAAM;AAAA,QACV,EACC;AAAA,UACC,CAAC,UACC,aAAaG,YAAW,WAAW,MAAM,IAAI,CAAC,KAAK,MAAM,QACtD,IAAI,CAAC,eAAe,IAAI,UAAU,GAAG,EACrC,KAAK,GAAG,CAAC;AAAA,QAChB;AAAA,MACJ;AAAA,IACF;AAEA,YAAQ,OAAO;AAAA,MACb,IAAI;AAAA,QACF,GAAG,UAAU,KACV;AAAA,UACC,CAAC,UACC,MAAM,QAAQ;AAAA,YAAM,CAAC,YACnB,UAAU,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,SAAS,OAAO;AAAA,UACxD,MAAM;AAAA,QACV,EACC;AAAA,UACC,CAAC,UACC,aAAaA,YAAW,WAAW,MAAM,IAAI,CAAC,KAAK,MAAM,QACtD,IAAI,CAAC,eAAe,IAAI,UAAU,GAAG,EACrC,KAAK,GAAG,CAAC;AAAA,QAChB;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,oBAAoB,UAAU,IAAI;AAAA,MAC5C;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,OACA,UACkC;AAClC,WAAO,SAAS;AAAA,MACd,CAAC,GAAG,YAAY;AACd,cAAM,qBAAqB,QAAQ,QAChC,IAAI,CAAC,QAAQ,IAAI,IAAI,QAAQ,GAAG,KAAK,KAAK,EAAE,CAAC,GAAG,EAChD,KAAK,GAAG;AACX,UAAE,GAAG;AAAA,UACH,kBAAkB,QAAQ,QAAQ,KAAK,GAAG,CAAC;AAAA,2BAC1B,QAAQ,EAAE;AAAA,yBACZ,QAAQ,QAAQ;AAAA,yBAChB,QAAQ,QAAQ;AAAA,QACjC;AACA,UAAE,KAAK,KAAK,sBAAsB,kBAAkB,IAAI;AACxD,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;;;AFzoBO,IAAM,aAAN,MAAM,YAA6C;AAAA,EA6BxD,YACU,QACR,OACA;AAFQ;AAGR,SAAK,OAAO,SAAS,KAAK,KAAK,MAAM;AAAA,EACvC;AAAA,EAjCQ;AAAA,EACR,YAA2B,IAAI,cAAc;AAAA,EAE7C,IAAI,iBAAiB;AACnB,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,OAAO,OAAO,YAAY,QAAQ;AAAA,MAClD,MAAM,KAAK,KAAK,OAAO,OAAO,YAAY,QAAQ;AAAA,MAClD,UAAU,KAAK,KAAK,OAAO,OAAO,YAAY,YAAY;AAAA,MAC1D,MAAM,KAAK,KAAK,OAAO,OAAO,YAAY,QAAQ;AAAA,MAClD,UAAU,KAAK,KAAK,OAAO,OAAO,YAAY,YAAY;AAAA,IAC5D;AAAA,EACF;AAAA,EAEQ;AAAA,EACR,IAAI,GAAG,IAAuB;AAC5B,SAAK,MAAM;AAAA,EACb;AAAA,EACA,IAAI,KAAK;AACP,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM;AACR,WAAO,KAAK,GAAG,QAAQ;AAAA,EACzB;AAAA,EASA,KAAK,OAA2B;AAC9B,SAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAAe,IAAY,IAAY;AAC/C,SAAK,KAAK,KAAK,GAAG,UAAU,OAAO,IAAI,EAAE;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAe,IAAY,IAAY;AAC9C,SAAK,KAAK,KAAK,GAAG,SAAS,OAAO,IAAI,EAAE;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc;AACZ,SAAK,KAAK,KAAK,GAAG,YAAY;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAA4B;AACjC,SAAK,KAAK,KAAK,GAAG,OAAO,QAAQ,OAAO,CAAC;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,YAAY;AACV,SAAK,KAAK,KAAK,GAAG,OAAO,GAAG;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAkC;AACtC,QAAI,OAAO,IAAI,CAAC,MAAM,UAAU;AAC9B,YAAM,CAAC,GAAkB;AAAA,IAC3B;AACA,eAAW,CAAC,KAAK,IAAI,GAAG,KAAK,QAAQ,GAAG,GAAG;AACzC,WAAK,KAAK,KAAK,GAAG,MAAM,KAAK,IAAI,GAAG;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,KAAkC;AACxC,SAAK,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO;AAChC,iBAAW,CAAC,KAAK,IAAI,GAAG,KAAK,QAAQ,GAAG,GAAG;AACzC,WAAG,SAAS,KAAK,IAAI,GAAG;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,OAAe,MAAa;AACvC,UAAM,KAAK,KAAK,KAAK,EAAE,OAAO,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,OAAO,OAAe,MAAa;AACvC,UAAM,IAAI,KAAK,KAAK,KAAK,EAAE,OAAO,IAAI;AACtC,UAAM,eAAe,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC,IAAI;AAClE,UAAM,EAAE,kBAAkB,MAAM,GAAG,YAAY;AAAA,EACjD;AAAA,EAEA,MAAM,OAAe;AACnB,SAAK,KAAK,KAAK,GAAG,MAAM,KAAK;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAgB;AACrB,SAAK,KAAK,KAAK,GAAG,OAAO,MAAM;AAC/B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAgB,OAAgB;AACpC,SAAK,KAAK,KAAK,GAAG,MAAM,QAAQ,GAAG,MAAM,OAAO,KAAK,KAAK,MAAM;AAChE,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,QAAgB;AACvB,SAAK,KAAK,KAAK,GAAG,SAAS,MAAM;AACjC,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,SAAK,KAAK,KAAK,GAAG,MAAM,CAAC;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,KAAuC;AACnD,QAAI,KAAK;AACP,aAAO,KAAK,GAAG,YAAY,GAAG;AAAA,IAChC;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,MAAM,QAAgC;AAC1C,WAAO,KAAK,GAAG,MAAM,MAAM;AAAA,EAC7B;AAAA,EAEA,eAAe,OAAe,UAAkB;AAC9C,QAAI,UAAU,QAAQ;AACpB,aAAO,KAAK,KAAK,IAAI,OAAO,QAAQ,EAAE,QAAQ;AAAA,IAChD;AACA,WAAO,KAAK,KAAK,IAAI,KAAK,EAAE,QAAQ;AAAA,EACtC;AAAA,EAEA,MAAM,IAAO,OAAe,UAAgC;AAC1D,QAAI,UAAU,QAAQ;AACpB,cAAQ,MAAM,KAAK,KAAK,IAAI,OAAO,QAAQ,GAAG,CAAC;AAAA,IACjD;AACA,YAAQ,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EACvC;AAAA,EAEA,MAAM,SAAS,OAAe;AAC5B,UAAM,KAAK,KAAK,KAAK,EAAE,SAAS;AAAA,EAClC;AAAA,EAEA,IAAI,UAA6C;AAC/C,WAAO,KAAK,KAAK;AAAA,MAAY,CAAC,QAC5B,SAAS,IAAI,YAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA,EAEA,gBAAgB,OAAyC;AACvD,SAAK,KAAK,MAAM,OAAO,CAAC,KAAK,SAAS,IAAI,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AACtE,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,UAAM,SAAS,IAAI,YAAW,KAAK,MAAM;AACzC,WAAO,KAAK,KAAK,GAAG,MAAM;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,gBAAgB;AACpB,UAAM,CAAC,EAAE,MAAM,IAAK,MAAM,KAAK,KAAK,QAAQ,KAAK;AAQjD,WAAO,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,QAAQ,OAAO,EAAE,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,SAAS;AACb,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,UAAU;AACd,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,WAAW;AACf,WAAO,KAAK,KAAK,QAAQ,SAAS;AAAA,EACpC;AAAA,EAEA,MAAM,cAAc;AAClB,WAAO,KAAK,KAAK,QAAQ,SAAS,QAAW,IAAI;AAAA,EACnD;AACF;;;AI/MA,SAAS,UAAAO,eAAc;AACvB,OAAON,WAAU;;;ACFjB;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAUP,SAAS,kBAAkB;AASpB,IAAM,eAAN,MAAM,cAAiD;AAAA,EAwC5D,YACU,QACR,QACA;AAFQ;AAGR,UAAM,EAAE,oBAAoB,WAAW,GAAG,KAAK,IAAI,KAAK;AAExD,SAAK,SACH,UACA,IAAI,OAAO;AAAA,MACT,SAAS,IAAI,aAAa;AAAA,QACxB;AAAA,QACA,MAAM,WAAW,IAAI;AAAA,MACvB,CAAC;AAAA,IACH,CAAC;AAEH,SAAK,WAAW,IAAI,SAAS;AAAA,MAC3B,IAAI,KAAK;AAAA,MACT,UAAU,IAAI,sBAAsB,SAAgB;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EA1DQ;AAAA,EAER,IAAI,iBAAiB;AACnB,WAAO;AAAA,MACL,MAAM,KAAK,OAAO;AAAA,MAClB,MAAM,KAAK,OAAO;AAAA,MAClB,UAAU,KAAK,OAAO;AAAA,MACtB,MAAM,KAAK,OAAO;AAAA,MAClB,UAAU,KAAK,OAAO;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ;AAAA,EACR,IAAI,GAAG,IAA0C;AAC/C,SAAK,MAAM;AAAA,EACb;AAAA,EACA,IAAI,KAAK;AACP,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ;AAAA,EACR,IAAI,SAAS,UAAoB;AAC/B,SAAK,YAAY;AAAA,EACnB;AAAA,EACA,IAAI,WAAW;AACb,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM;AACR,UAAM,WAAW,KAAK,GAAG,QAAQ,EAAE,WAAW,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAC1E,WAAO,KAAK,GAAG,QAAQ,EAAE,IAAI,QAAQ,OAAO,MAAM,SAAS,MAAM,CAAE;AAAA,EACrE;AAAA,EAuBA,KAAK,OAAe;AAClB,SAAK,KAAK,KAAK,OAAO,WAAW,KAAW;AAC5C,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAAe,IAAY,IAAY;AAC/C,SAAK,KAAK,KAAK,GAAG,UAAU,OAAa,IAAU,EAAQ;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAe,IAAY,IAAY;AAC9C,SAAK,KAAK,KAAK,GAAG,SAAS,OAAa,IAAU,EAAQ;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,cAAc;AACZ,SAAK,KAAK,KAAK,GAAG,YAAY;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAA4B;AACjC,SAAK,KAAK,KAAK,GAAG,OAAO,QAAQ,OAAO,CAAS;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,YAAY;AACV,SAAK,KAAK,KAAK,GAAG,UAAU;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAkC;AACtC,QAAI,OAAO,IAAI,CAAC,MAAM,UAAU;AAC9B,YAAM,CAAC,GAAkB;AAAA,IAC3B;AACA,eAAW,CAAC,KAAK,IAAI,GAAG,KAAK,QAAQ,GAAG,GAAG;AACzC,WAAK,KAAK,KAAK,GAAG;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,KAAkC;AACxC,SAAK,KAAK,KAAK,GAAG;AAAA,MAAM,CAAC,OACvB,GAAG;AAAA,QACD,IAAI;AAAA,UAAI,CAAC,CAAC,KAAK,IAAI,GAAG,MACpB,GAAG,KAAY,IAAoC,GAAG;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,OAAe,MAAa;AACvC,UAAM,KAAK,OACR,WAAW,KAAW,EACtB,OAAO,IAAI,EACX,QAAQ;AAAA,EACb;AAAA,EAEA,MAAM,OAAO,OAAe,MAAa;AACvC,UAAM,IAAI,KAAK,OACZ,WAAW,KAAW,EACtB,OAAO,IAAI,EACX,qBAAqB,MAAM;AAC1B,YAAM,UAA+B,CAAC;AAEtC,aAAO,KAAK,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACpC,gBAAQ,GAAG,IAAI,aAAa,IAAI,IAAI,GAAG,CAAC;AAAA,MAC1C,CAAC;AACD,aAAO;AAAA,IACT,CAAC;AACH,UAAM,EAAE,QAAQ;AAAA,EAClB;AAAA,EAEA,MAAM,OAAe;AACnB,SAAK,KAAK,KAAK,GAAG,MAAM,KAAK;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAgB;AACrB,SAAK,KAAK,KAAK,GAAG,OAAO,MAAM;AAC/B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAgB,OAAgB;AACpC,SAAK,KAAK,KAAK,GAAG;AAAA,MAAO,CAAC,OACxB,GAAG,GAAG,MAAM,MAAa,EAAE,GAAG,SAAS,MAAM;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,QAAgB;AACvB,SAAK,KAAK,KAAK,GAAG,WAAW,MAAa;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,SAAK,KAAK,KAAK,GAAG,MAAM,CAAC;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,KAAyC;AACrD,QAAI,KAAK;AACP,YAAM,EAAE,KAAK,IAAI,MAAM,IAAI,aAAa,KAAK,GAAG,QAAQ,CAAC;AACzD,aAAO;AAAA,IACT;AACA,WAAO,KAAK,GAAG,QAAQ;AAAA,EACzB;AAAA,EAEA,MAAM,MAAM,QAAgC;AAC1C,UAAM,SAAS,MAAM,KAAK,QAAQ;AAClC,WAAO,OAAO,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;AAAA,EACxC;AAAA,EAEA,eAAe,OAAe,UAAkB;AAC9C,QAAI,UAAU,QAAQ;AACpB,cAAQ,MAAM;AAAA,QACZ;AAAA,QACA,MAAM,IAAI,IAAI,SAAS,MAAM,CAAC,EAAE,QAAQ,KAAK,MAAM,EAAE;AAAA,MACvD;AAAA,IACF;AACA,WAAO,IAAI,IAAI,KAAK,EAAE,QAAQ,KAAK,MAAM,EAAE;AAAA,EAC7C;AAAA,EAEA,MAAM,IAAO,OAAe,UAAgC;AAC1D,QAAI,UAAU,QAAQ;AACpB,cAAQ,MAAM;AAAA,QACZ;AAAA,QACA,MAAM,IAAI,IAAI,SAAS,MAAM,CAAC,EAAE,QAAQ,KAAK,MAAM,EAAE;AAAA,MACvD;AAAA,IACF;AACA,UAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK,EAAE,QAAQ,KAAK,MAAM;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,OAAe;AAC5B,UAAM,qBAAqB,IAAI,MAAM,KAAK,CAAC,GAAG,QAAQ,KAAK,MAAM;AAAA,EACnE;AAAA,EAEA,IAAO,UAA6C;AAClD,WAAO,KAAK,OACT,YAAY,EACZ,QAAQ,OAAO,QAAQ,SAAS,IAAI,cAAa,KAAK,QAAQ,GAAG,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,OAAO,QAAQ;AAAA,EAC7B;AAAA,EAEA,gBAAgB,OAAyC;AACvD,eAAW,QAAQ,OAAO;AACxB,cAAQ,MAAM;AAAA,QACZ,KAAK;AACH,eAAK,KAAK,KAAK,GAAG,aAAa;AAC/B;AAAA,QACF,KAAK;AACH,eAAK,KAAK,KAAK,GAAG,YAAY;AAC9B;AAAA,QACF,KAAK;AACH,eAAK,KAAK,KAAK,GAAG,WAAW;AAC7B;AAAA,MACJ;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,UAAM,SAAS,IAAI,cAAa,KAAK,MAAM;AAC3C,WAAO,KAAK,KAAK;AACjB,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,gBAAgB;AACpB,UAAM,SAAS,MAAM,KAAK,SAAS,cAAc;AACjD,WAAO,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAC9D;AAAA,EAEA,MAAM,SAAS;AACb,UAAM,WAAW,MAAM,KAAK,cAAc;AAC1C,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,MAAM,UAAU;AACd,UAAM,EAAE,SAAS,MAAM,IAAI,MAAM,KAAK,SAAS,gBAAgB;AAC/D,QAAI,OAAO;AACT,YAAM;AAAA,IACR;AAEA,WAAO,CAAC,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EACjD;AAAA,EAEA,MAAM,WAAW;AACf,UAAM,EAAE,SAAS,MAAM,IAAI,MAAM,KAAK,SAAS,YAAY;AAC3D,QAAI,OAAO;AACT,YAAM;AAAA,IACR;AAEA,WAAO,CAAC,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EACjD;AAAA,EAEA,MAAM,cAAc;AAClB,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,QAAQ,IAAI,MAAM,KAAK,SAAS,YAAY;AAE3D,UAAI,OAAO;AACT,gBAAQ,MAAM,4BAA4B,KAAK;AAC/C,cAAM;AAAA,MACR;AAEA,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,gBAAQ,IAAI,uBAAuB;AACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ADrSO,IAAe,UAAf,MAAuB;AAAA,EACrB;AAAA,EACP,IAAI,WAAW,QAAwB;AACrC,SAAK,cAAc;AAAA,EACrB;AAAA,EACA,IAAI,aAAa;AACf,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAUA,MAAM,cAAc,UAA+C;AACjE,UAAM,iBAAiBA,MAAK,KAAK,UAAU,qBAAqB;AAChE,UAAM,SAAS,MAAM,OAAO;AAC5B,UAAM,SAAS,OAAO,SAAS,WAAW,OAAO,WAAW;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,OAAkB;AACjC,YAAQ,QAAQ,IAAI,YAAY,eAAe;AAAA,MAC7C,KAAK;AAAA,MACL,KAAK;AACH,eAAO,UAAU,MACb,KAAK,WAAW,oBAAoB,IACpC,KAAK,WAAW,mBAAmB,KACjC,KAAK,WAAW,oBAAoB;AAC1C;AAAA,MACF,KAAK;AACH,eAAO,UAAU,MACb,KAAK,WAAW,mBAAmB,IACnC,KAAK,WAAW,kBAAkB,KAChC,KAAK,WAAW,mBAAmB;AACzC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,WAAW,MAAM;AAC7B;AAAA,MACF;AACE,cAAM,IAAI;AAAA,UACR,oBAAU,QAAQ,IAAI,QAAQ;AAAA,QAChC;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,SAAS,IAAwD;AAC/D,QAAI,cAAcM,SAAQ;AACxB,aAAO,IAAI,aAAa,KAAK,iBAAiB,GAAG,EAAE;AAAA,IACrD,OAAO;AACL,aAAO,IAAI,WAAW,KAAK,iBAAiB,GAAiB,EAAE;AAAA,IACjE;AAAA,EACF;AACF;;;AE1EA,OAAOD,WAAU;AAEV,SAAS,0BAA0B;AACxC,MAAI;AACF,IAAAA,MAAK,aAAa,OAAO,qBAAqB,YAAa,SAAS;AAClE,UAAI,QAAQ,WAAW,GAAG;AAExB,cAAM,EAAE,KAAKE,cAAa,UAAUC,kBAAiB,IAAI,KAAK,MAAM;AACpE,eAAO,KAAK,OAAO,IAAID,cAAaC,iBAAgB;AAAA,MACtD;AAEA,YAAM,EAAE,cAAc,SAAS,IAAI,QAAQ;AAAA,QACzC,CAAC,QAAQ,WAAW;AAClB,cAAI,OAAO,WAAW,UAAU;AAC9B,mBAAO,aAAa,KAAK,iBAAiB;AAC1C,mBAAO,SAAS,KAAK,QAAQ,MAAM;AAAA,UACrC,WAAW,UAAU,OAAO,WAAW,UAAU;AAC/C,mBAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,QAAQ;AACnC,qBAAO,aAAa,KAAK,QAAQ;AACjC,qBAAO,SAAS,KAAK,KAAK,OAAO,GAAG,CAAC;AAAA,YACvC,CAAC;AAAA,UACH,OAAO;AACL,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF;AAEA,iBAAO;AAAA,QACT;AAAA,QACA,EAAE,cAAc,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,MACnC;AAEA,YAAM,EAAE,KAAK,aAAa,UAAU,iBAAiB,IAAI,KAAK,MAAM;AAEpE,YAAM,cAAc,CAAC,GAAG,kBAAkB,GAAG,QAAQ;AAErD,aAAO,KAAK,OAAO;AAAA,QACjB,GAAG,WAAW,4BAA4B,aAAa,KAAK,IAAI,CAAC;AAAA,QACjE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;APpCO,IAAM,cAAN,cAA0B,QAAQ;AAAA,EAChC,iBAAiB;AAAA,EACjB,YAA2B,IAAI,cAAc;AAAA,EAC7C;AAAA,EAGP,IAAI,WAAW,QAA4B;AACzC,SAAK,cAAc;AAAA,EACrB;AAAA,EACA,IAAI,aAAa;AACf,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ;AAAA,EACA;AAAA,EAEA,OAA0B;AAAA,EAClC,IAAI,IAAI,KAAiB;AACvB,SAAK,OAAO;AAAA,EACd;AAAA,EACA,IAAI,MAAkB;AACpB,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,OAA0B;AAAA,EAClC,IAAI,IAAI,KAAiB;AACvB,SAAK,OAAO;AAAA,EACd;AAAA,EACA,IAAI,MAAkB;AACpB,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,iBAAiB;AACnB,WAAOZ,GAAE,UAAU,KAAK,YAAY,CAAC,EAAE,WAAW,OAAO;AAAA,MACvD,MAAM,WAAW,QAAQ;AAAA,MACzB,MAAM,WAAW,QAAQ;AAAA,MACzB,UAAU,WAAW;AAAA,MACrB,MAAM,WAAW;AAAA,MACjB,UAAU,WAAW;AAAA,IACvB,EAAE;AAAA,EACJ;AAAA,EAEA,cAAc;AACZ,UAAM;AACN,4BAAwB;AAAA,EAC1B;AAAA,EAEA,KAAK,QAAwB;AAC3B,SAAK,aAAa;AAClB,SAAK,aAAa,KAAK,iBAAiB,MAAM;AAAA,EAChD;AAAA,EAEA,MAAM,WAAW;AACf,QAAI,KAAK,SAAS,MAAM;AACtB;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,QAAQ,KAAK,WAAW,mBAAmB;AAC7D,YAAM,QAAQ,KAAK,eAAe;AAClC,YAAM,QAAQ,KAAK,eAAe;AAElC,UACE,GAAG,MAAM,QAAQ,WAAW,IAAI,MAAM,QAAQ,IAAI,IAChD,MAAM,QACR,OACA,GAAG,MAAM,QAAQ,WAAW,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,QAAQ,IACpE;AACA,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,WAAW,KAAK,WAAW,IAAI;AAC9C,SAAK,MAAM,IAAI,WAAW,KAAK,WAAW,aAAa;AAAA,EACzD;AAAA,EAEA,MAAM,OAAiB;AACrB,UAAM,eAAe,UAAU,MAAM,QAAQ;AAE7C,QAAI,CAAC,KAAK,YAAY,GAAG;AACvB,YAAM,SAAS,KAAK,iBAAiB,KAAK;AAC1C,WAAK,YAAY,IAAIS,MAAK,MAAM;AAAA,IAClC;AAEA,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,UAAU,MAAgC;AACxC,WAAO,IAAI,WAAW,KAAK,WAAW,IAAI,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,QAAQ,QAAW;AAC1B,YAAM,KAAK,IAAI,QAAQ;AACvB,WAAK,MAAM;AAAA,IACb;AACA,QAAI,KAAK,QAAQ,QAAW;AAC1B,YAAM,KAAK,IAAI,QAAQ;AACvB,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,cAAc;AAClB,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,QAAQ;AACxB,WAAK,OAAO;AAAA,IACd;AACA,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,QAAQ;AACxB,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,IAAI,IAAU,OAAe;AAC3B,WAAO,GAAG,IAAI,KAAK;AAAA,EACrB;AAAA,EAEQ,iBAAiB,QAA4C;AACnE,UAAM,oBAAoBT,GAAE;AAAA,MAC1B;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,QACA,YAAY;AAAA,UACV,WAAW;AAAA,UACX,WAAW;AAAA,QACb;AAAA,QACA,YAAY;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU,OAAO;AAAA,QACnB;AAAA,MACF;AAAA,MACA,OAAO;AAAA,IACT;AAGA,UAAM,OAAOA,GAAE,MAAM,CAAC,GAAG,mBAAmB;AAAA,MAC1C,YAAY;AAAA,QACV,UAAU,GAAG,OAAO,QAAQ;AAAA,MAC9B;AAAA,IACF,CAAC;AAED,UAAM,gBAAgBA,GAAE,MAAM,CAAC,GAAG,mBAAmB;AAAA,MACnD,YAAY;AAAA,QACV,UAAU,GAAG,OAAO,QAAQ;AAAA,MAC9B;AAAA,IACF,CAAC;AAGD,UAAM,mBAAmB,OAAO,cAAc;AAC9C,UAAM,kBAAkB,OAAO,cAAc;AAC7C,UAAM,qBAAqBA,GAAE,MAAM,CAAC,GAAG,mBAAmB,gBAAgB;AAC1E,UAAM,oBAAoBA,GAAE;AAAA,MAC1B,CAAC;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,iBAAiBA,GAAE,MAAM,CAAC,GAAG,mBAAmB,kBAAkB;AAAA,MACtE,YAAY;AAAA,QACV,UAAU,GAAG,OAAO,QAAQ;AAAA,MAC9B;AAAA,IACF,CAAC;AAGD,UAAM,oBAAoB,OAAO,cAAc,cAAc,CAAC;AAC9D,UAAM,mBAAmB,OAAO,cAAc,oBAAoB,CAAC;AACnE,UAAM,oBAAoBA,GAAE,MAAM,CAAC,GAAG,mBAAmB,iBAAiB;AAC1E,UAAM,mBAAmBA,GAAE;AAAA,MACzB,CAAC;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,MAAoC;AACnD,UAAM,UAAU,KAAK,IAAI,CAAC,SAAS;AAAA,MACjC,SAAS;AAAA,MACT,SAAS,KAAK,WAAW,GAA+B;AAAA,IAC1D,EAAE;AAEF,WAAOA,GAAE,OAAO,SAAS,CAAC,EAAE,QAAQ,MAAM;AACxC,YAAM,OAAO,QAAQ;AAIrB,aAAO,GAAG,KAAK,QAAQ,WAAW,IAAI,KAAK,QAAQ,IAAI,IACrD,KAAK,QACP;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AQlOA,OAAOA,QAAO;AACd,SAAS,gBAAgB;AACzB,OAAOI,WAAU;AACjB,SAAS,cAAAS,mBAAkB;AAQ3B,SAAqC,UAAAH,SAAQ,gBAAAI,eAAc,OAAAC,YAAW;;;ACXtE,OAAOf,QAAO;AACd,OAAOgB,eAAc;AACrB,OAAOV,YAAW;AAUX,IAAM,kBAAN,cAA8B,cAAc;AAAA,EACjD,MAAM,oCACJ,OACA,SACA,SAC2B;AAE3B,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gCAAgC,KAAK;AAAA,MACrC,GAAG,KAAK,qBAAqB,OAAO;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,KAAK,oBAAoB,OAAO,OAAO;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA,+BAA+B,KAAK;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,OAAO,WAAW,KAAK;AAAA,MACvB,WAAW,MAAMU,UAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,QACjD,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2BACJ,OACA,UAC6B;AAC7B,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,EAAE,IAAI,KAAK,IAAI,KAAK,sBAAsB,OAAO,QAAQ;AAC/D,QAAI,GAAG,WAAW,KAAK,KAAK,WAAW,GAAG;AACxC,cAAQ,IAAI,iDAAc;AAC1B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH;AAAA,IACF;AAEA,UAAM,oBAAoB,SACvB,IAAI,CAAC,YAAY,QAAQ,QAAQ,KAAK,GAAG,CAAC,EAC1C,KAAK,GAAG;AACX,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,MAAM;AAAA,QACN,OAAO,YAAY,KAAK,KAAK,iBAAiB;AAAA,QAC9C,WAAW,MAAMA,UAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,UACjD,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mCACJ,OACA,eACA,eACA,WACA,WAC6B;AAc7B,UAAM,iBAAiB,KAAK,kBAAkB,eAAe,SAAS;AAGtE,UAAM,qBAAqB,KAAK;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,kBAAkB,eAAe,SAAS;AAGtE,UAAM,oBAAoB,KAAK;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,sBACJhB,GAAE,MAAM,OAAO,OAAO,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI;AAC5D,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,sBACA;AAAA,QACE,+BAA+B,KAAK;AAAA,QACpC,GAAI,eAAe,IAAI,SAAS,IAAI,mBAAmB,IAAI,KAAK,CAAC;AAAA,QACjE,GAAI,eAAe,KAAK,SAAS,IAC7B,mBAAmB,KAAK,KACxB,CAAC;AAAA,QACL,GAAI,eAAe,MAAM,SAAS,IAC9B,mBAAmB,MAAM,KACzB,CAAC;AAAA,QACL;AAAA,MACF,IACA,CAAC;AAAA,MACL,GAAI,eAAe,IAAI,SAAS,IAAI,kBAAkB,IAAI,KAAK,CAAC;AAAA,MAChE,GAAI,eAAe,KAAK,SAAS,IAAI,kBAAkB,KAAK,KAAK,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,sBACA;AAAA,QACE,+BAA+B,KAAK;AAAA,QACpC,GAAI,eAAe,IAAI,SAAS,IAC5B,mBAAmB,IAAI,OACvB,CAAC;AAAA,QACL,GAAI,eAAe,KAAK,SAAS,IAC7B,mBAAmB,KAAK,OACxB,CAAC;AAAA,QACL,GAAI,eAAe,MAAM,SAAS,IAC9B,mBAAmB,MAAM,OACzB,CAAC;AAAA,QACL;AAAA,MACF,IACA,CAAC;AAAA,MACL,GAAI,kBAAkB,IAAI,KAAK,SAAS,IACpC,kBAAkB,IAAI,OACtB,CAAC;AAAA,MACL,GAAI,kBAAkB,KAAK,KAAK,SAAS,IACrC,kBAAkB,KAAK,OACvB,CAAC;AAAA,MACL;AAAA,IACF;AAEA,UAAM,YAAY,MAAMgB,UAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,MACxD,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,GAAI,CAAC,OAAO,QAAQ,OAAO,EACxB,IAAI,CAAC,WAAW;AACf,cAAM,MAAM,eAAe,MAAM,EAAE;AACnC,YAAI,MAAM,GAAG;AACX,iBAAO,SAAS;AAAA,QAClB;AACA,eAAO;AAAA,MACT,CAAC,EACA,OAAO,CAAC,SAAS,SAAS,IAAI;AAAA,IACnC,EAAE,KAAK,GAAG;AAEV,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,2BACJ,OACA,gBACA,YAC6B;AAC7B,UAAM,SAAS,CAAC,OAAiC;AAC/C,aAAO,CAAC,GAAG,QAAQ,KAAK,GAAG,GAAG,GAAG,EAAE,EAAE,KAAK,KAAK;AAAA,IACjD;AACA,UAAM,OAAO,eAAe;AAAA,MAC1B,CAAC,QAAQ,YAAY;AACnB,cAAM,cAAc,WAAW;AAAA,UAC7B,CAAC,QAAQ,OAAO,OAAO,MAAM,OAAO,GAAG;AAAA,QACzC;AACA,YAAI,CAAC,aAAa;AAChB,iBAAO,IAAI,KAAK,OAAO;AACvB,iBAAO;AAAA,QACT;AAEA,YAAIV,OAAM,SAAS,WAAW,MAAM,OAAO;AACzC,iBAAO,SAAS,KAAK,WAAW;AAChC,iBAAO,SAAS,KAAK,OAAO;AAC5B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,KAAK,CAAC;AAAA,QACN,UAAU,CAAC;AAAA,QACX,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,KAAK,KAAK,sBAAsB,OAAO,KAAK,GAAG;AAAA,MAC/C,UAAU,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAAA,MACzD,UAAU,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAAA,IAC3D;AAEA,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,QAAQ,IAAI;AAAA,MACf,GAAG,QAAQ,SAAS;AAAA,MACpB,GAAG,QAAQ,SAAS;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,QAAQ,IAAI;AAAA,MACf,GAAG,QAAQ,SAAS;AAAA,MACpB,GAAG,QAAQ,SAAS;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,YAAY,MAAMU,UAAS,OAAO,MAAM,KAAK,IAAI,GAAG;AAAA,MACxD,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,IAEF,EAAE,KAAK,GAAG;AAEV,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,sBACE,UACA,KACA;AACA,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,SAAS,cAAc,IAAI,QAAQ;AAEzC,WAAO;AAAA;AAAA;AAAA;AAAA,IAIP,QAAQ;AAAA,IACR,QAAQ;AAAA;AAAA;AAAA,IAGR,MAAM,KAAK;AAAA;AAAA,WAEJ,QAAQ,eAAe,QAAQ,wBAAwB,MAAM,EAAE;AAAA;AAAA;AAAA,IAGtE,QAAQ;AAAA;AAAA,QAEJ,QAAQ;AAAA,iBACC,QAAQ;AAAA;AAAA,wEAE+C,QAAQ;AAAA,6BACnD,QAAQ;AAAA;AAAA;AAAA,eAGtB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4EAOuB,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAM/B,QAAQ;AAAA;AAAA,kBAElB,QAAQ;AAAA,eACX,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wEAUiD,MAAM,aAAa;AAAA,6BAC9D,QAAQ;AAAA;AAAA,cAEvB,QAAQ;AAAA,0BACI,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKjB,IAAI,MAAM;AAAA,kBACT,IAAI,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAQR,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,2BAIL,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAMV,OAAO,KAAK;AAAA;AAAA;AAAA,gCAGT,OAAO,KAAK;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,WA+BjC,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAOE,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,0CAKS,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAYvB,OAAO,KAAK,aAAa,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAOrD,QAAQ,eAAe,QAAQ;AAAA,QACtC,KAAK;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,SAAsC;AACjE,WAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,UAAI,MAAM;AACV,YAAM,SAAmB,CAAC;AAC1B,UAAI,OAAO,SAAS,MAAM;AACxB,eAAO;AAAA,MACT;AAEA,UAAI,OAAO,SAAS,WAAW;AAC7B,cAAM,eAAe,OAAO,IAAI,OAAO,OAAO,IAAI,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK;AAAA,MACzF,WAAW,OAAO,KAAK,SAAS,MAAM,GAAG;AACvC,cAAM,eAAe,OAAO,IAAI,WAAW,OAAO,KAAK,YAAY,CAAC;AAAA,MACtE,OAAO;AACL,YAAI,aAAqB,OAAO;AAEhC,YAAI,eAAe,SAAS;AAC1B,uBAAa;AAAA,QACf,WAAW,eAAe,QAAQ;AAChC,uBAAa;AAAA,QACf,WAAW,eAAe,UAAU;AAClC,uBAAa;AAAA,QACf;AACA,cAAM,eAAe,OAAO,IAAI,OAAO,UAAU,GAAG,OAAO,SAAS,IAAI,OAAO,MAAM,MAAM,EAAE;AAAA,MAC/F;AACA,UAAI,OAAO,UAAU;AACnB,eAAO,KAAK,YAAY;AAAA,MAC1B;AAEA,UAAI,CAAC,OAAO,UAAU;AACpB,eAAO,KAAK,WAAW;AAAA,MACzB;AAEA,UAAI,OAAO,cAAc,QAAW;AAClC,YACE,OAAO,OAAO,cAAc,YAC5B,OAAO,UAAU,WAAW,GAAG,GAC/B;AACA,iBAAO,KAAK,aAAa,OAAO,SAAS,GAAG;AAAA,QAC9C,OAAO;AACL,iBAAO,KAAK,kBAAkB,OAAO,SAAS,KAAK;AAAA,QACrD;AAAA,MACF;AACA,UAAI,OAAO,SAAS,QAAQ;AAC1B,eAAO,KAAK,wBAAwB;AAAA,MACtC;AAEA,cACG,OAAO,SAAS,IAAI,GAAG,GAAG,kBAAkB,OAAO,KAAK,GAAG,CAAC,KAAK,OAClE;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,oBACN,OACA,SACU;AACV,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAAQhB,GAAE;AAAA,MACd,QAAQ,OAAO,CAAC,GAAG,UAAU;AAC3B,UAAE;AAAA,UACA,gCAAgC,KAAK,gBAAgB,OAAO,MAAM,SAAS,MAAM,IAAI,CAAC;AAAA,iBAC/E,KAAK;AAAA,sBACA,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,GAAG,CAAC,KAAK,MAAM,SAAS,WAAW,cAAc,EAAE;AAAA;AAAA,QAE7G;AACA,eAAO;AAAA,MACT,GAAG,CAAC,CAAa;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,OACA,UACkC;AAClC,WAAO,SAAS;AAAA,MACd,CAAC,GAAG,YAAY;AACd,cAAM,CAAC,SAAS,QAAQ,IAAI,QAAQ,GAAG,MAAM,GAAG;AAChD,cAAM,OAAO,GAAG,KAAK,IAAI,QAAQ,QAAQ,KAAK,GAAG,CAAC;AAClD,cAAM,qBAAqB,QAAQ,QAChC,IAAI,CAAC,QAAQ,IAAI,IAAI,QAAQ,GAAG,KAAK,KAAK,EAAE,CAAC,GAAG,EAChD,KAAK,GAAG;AAEX,UAAE,GAAG;AAAA,UACH;AAAA,UACA,+BAA+B,KAAK;AAAA,UACpC,6BAA6B,IAAI,OAAO,kBAAkB,OAAO,OAAO,QAAQ,QAAQ;AAAA,UACxF,cAAc,QAAQ,SAAS,YAAY,CAAC;AAAA,UAC5C,cAAc,QAAQ,SAAS,YAAY,CAAC;AAAA,UAC5C;AAAA,QACF;AACA,UAAE,KAAK;AAAA,UACL;AAAA,UACA,+BAA+B,KAAK;AAAA,UACpC,oBAAoB,IAAI;AAAA,UACxB;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,sBACN,WACA,eACA;AACA,QAAI,UAAU;AAAA,MACZ,KAAK;AAAA,QACH,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,OAAO;AAAA,QACL,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAEA,YAAQ,MAAM;AAAA,MACZ,IAAI,CAAC,UAAU,GAAG,KAAK,qBAAqB,UAAU,GAAG,CAAC;AAAA,MAC1D,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,UAAU,IAAI,IAAI,CAAC,QAAQ,gBAAgB,IAAI,IAAI,IAAI;AAAA,MAC5D;AAAA,IACF;AACA,YAAQ,OAAO;AAAA,MACb,IAAI;AAAA,QACF;AAAA,QACA,GAAG,UAAU,KAAK,IAAI,CAAC,QAAQ,gBAAgB,IAAI,IAAI,IAAI;AAAA,MAC7D;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,qBAAqB,UAAU,IAAI;AAAA,MAC7C;AAAA,IACF;AACA,YAAQ,QAAQ,UAAU,MAAM;AAAA,MAC9B,CAAC,GAAG,aAAa;AACf,cAAM,eAAe,cAAc;AAAA,UACjC,CAAC,QAAQ,IAAI,QAAQ,SAAS;AAAA,QAChC;AACA,YAAI,iBAAiB,QAAW;AAC9B,iBAAO;AAAA,QACT;AAGA,cAAM,eAAeA,GAAE;AAAA,UACrB,KAAK,qBAAqB,CAAC,YAAY,CAAC;AAAA,UACxC,KAAK,qBAAqB,CAAC,QAAQ,CAAC;AAAA,QACtC;AACA,cAAM,iBAAiBA,GAAE;AAAA,UACvB,KAAK,qBAAqB,CAAC,QAAQ,CAAC;AAAA,UACpC,KAAK,qBAAqB,CAAC,YAAY,CAAC;AAAA,QAC1C;AACA,YAAI,aAAa,SAAS,GAAG;AAC3B,YAAE,KAAK;AAAA,YACL,GAAG,EAAE;AAAA,YACL;AAAA,YACA,GAAG,aAAa;AAAA,cAAI,CAAC,MACnB,EAAE,QAAQ,cAAc,eAAe;AAAA,YACzC;AAAA,UACF;AACA,YAAE,OAAO;AAAA,YACP,GAAG,EAAE;AAAA,YACL;AAAA,YACA,GAAG,eAAe;AAAA,cAAI,CAAC,MACrB,EAAE,QAAQ,cAAc,eAAe;AAAA,YACzC;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,qBACN,OACA,WACA,WACA;AACA,QAAI,UAAU;AAAA,MACZ,KAAK;AAAA,QACH,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,CAAC;AAAA,QACL,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAGA,YAAQ,MAAM;AAAA,MACZ,IAAI,CAAC,kBAAkB,GAAG,KAAK,oBAAoB,OAAO,UAAU,GAAG,CAAC;AAAA,MACxE,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,UAAU,IACV;AAAA,UACC,CAAC,UACC,MAAM,QAAQ;AAAA,YAAM,CAAC,YACnB,UAAU,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,SAAS,OAAO;AAAA,UACvD,MAAM;AAAA,QACV,EACC;AAAA,UACC,CAAC,UAAU,+BAA+B,KAAK;AAAA,0BACjC,KAAK,gBAAgB,OAAO,MAAM,SAAS,MAAM,IAAI,CAAC;AAAA;AAAA,QAEtE;AAAA,MACJ;AAAA,IACF;AAEA,YAAQ,OAAO;AAAA,MACb,IAAI;AAAA,QACF,GAAG,UAAU,KACV;AAAA,UACC,CAAC,UACC,MAAM,QAAQ;AAAA,YAAM,CAAC,YACnB,UAAU,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,SAAS,OAAO;AAAA,UACxD,MAAM;AAAA,QACV,EACC;AAAA,UACC,CAAC,UAAU,+BAA+B,KAAK;AAAA,0BACjC,KAAK,gBAAgB,OAAO,MAAM,SAAS,MAAM,IAAI,CAAC;AAAA;AAAA,QAEtE;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,oBAAoB,OAAO,UAAU,IAAI;AAAA,MACnD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,gBACN,OACA,SACA,MACQ;AACR,QAAI,QAAQ,CAAC,EAAE,MAAM,GAAG,EAAE,SAAS,GAAG;AACpC,cAAQ,QAAQ,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAC/B,gBAAU,QAAQ,IAAI,CAAC,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,IAClD;AAEA,WAAO,GAAG,KAAK,IAAI,QAAQ,KAAK,GAAG,CAAC,IAAI,IAAI;AAAA,EAC9C;AACF;;;ADxrBO,IAAM,gBAAN,cAA4B,QAAQ;AAAA,EAClC,iBAAiB;AAAA,EACjB,YAA6B,IAAI,gBAAgB;AAAA,EACjD;AAAA,EAGP,IAAI,WAAW,QAA8B;AAC3C,SAAK,cAAc;AAAA,EACrB;AAAA,EACA,IAAI,aAAa;AACf,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ;AAAA,EACA;AAAA,EAEA,OAA4B;AAAA,EACpC,IAAI,IAAI,KAAmB;AACzB,SAAK,OAAO;AAAA,EACd;AAAA,EACA,IAAI,MAAoB;AACtB,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,OAA4B;AAAA,EACpC,IAAI,IAAI,KAAmB;AACzB,SAAK,OAAO;AAAA,EACd;AAAA,EACA,IAAI,MAAoB;AACtB,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,iBAAiB;AACnB,WAAOA,GAAE,UAAU,KAAK,YAAY,CAAC,YAAY;AAAA,MAC/C,MAAM,OAAO,QAAQ;AAAA,MACrB,MAAM,OAAO,QAAQ;AAAA,MACrB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,UAAU,OAAO;AAAA,IACnB,EAAE;AAAA,EACJ;AAAA,EAEA,cAAc;AACZ,UAAM;AAAA,EACR;AAAA,EAEA,KAAK,QAA0B;AAC7B,SAAK,aAAa;AAClB,SAAK,aAAa,KAAK,iBAAiB,MAAM;AAAA,EAChD;AAAA,EAEA,MAAM,WAAW;AACf,QAAI,KAAK,SAAS,MAAM;AACtB;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,QAAQ,KAAK,WAAW,mBAAmB;AAC7D,YAAM,YAAY,KAAK,WAAW;AAClC,YAAM,YAAY,KAAK,WAAW;AAElC,UACE,GAAG,UAAU,QAAQ,WAAW,IAAI,UAAU,QAAQ,IAAI,IACxD,UAAU,QACZ,OACA,GAAG,UAAU,QAAQ,WAAW,IAAI,UAAU,QAAQ,IAAI,IAAI,UAAU,QAAQ,IAChF;AACA,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,aAAa,KAAK,WAAW,IAAI;AAChD,SAAK,MAAM,IAAI,aAAa,KAAK,WAAW,aAAa;AAAA,EAC3D;AAAA,EAEA,IAAI,SAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,OAAiB;AACrB,UAAM,eAAe,UAAU,MAAM,QAAQ;AAE7C,QAAI,CAAC,KAAK,YAAY,GAAG;AACvB,YAAM,UAAwB,KAAK,iBAAiB,KAAK;AACzD,YAAM,EAAE,oBAAoB,WAAW,GAAG,OAAO,IAAI;AAErD,WAAK,YAAY,IAAI,IAAIU,QAAiB;AAAA,QACxC,SAAS,IAAII,cAAa;AAAA,UACxB;AAAA,UACA,MAAMD,YAAW,MAAM;AAAA,QACzB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,UAAU,MAAkC;AAC1C,WAAO,IAAI,aAAa,KAAK,WAAW,IAAI,CAAC;AAAA,EAC/C;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,QAAQ,QAAW;AAC1B,YAAM,KAAK,IAAI,QAAQ;AACvB,WAAK,MAAM;AAAA,IACb;AACA,QAAI,KAAK,QAAQ,QAAW;AAC1B,YAAM,KAAK,IAAI,QAAQ;AACvB,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,cAAc;AAClB,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,QAAQ;AACxB,WAAK,OAAO;AAAA,IACd;AACA,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,QAAQ;AACxB,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,IAAI,IAAsB,OAAe;AACvC,WAAOE,OAAM,KAAK,GAAG,QAAQ,EAAE;AAAA,EACjC;AAAA,EAEQ,iBAAiB,QAAgD;AACvE,UAAM,sBAAsBf,GAAE;AAAA,MAC5B;AAAA,QACE,WAAW;AAAA,UACT,IAAI;AAAA,UACJ,MAAAI;AAAA,UACA,iBAAiBA,MAAK,KAAK,OAAO,aAAa,kBAAkB;AAAA,QACnE;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU,OAAO;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,IACT;AAGA,UAAM,OAAOJ,GAAE,MAAM,CAAC,GAAG,qBAAqB;AAAA,MAC5C,UAAU,GAAG,OAAO,QAAQ;AAAA,IAC9B,CAAC;AAED,UAAM,gBAAgBA,GAAE,MAAM,CAAC,GAAG,qBAAqB;AAAA,MACrD,UAAU,GAAG,OAAO,QAAQ;AAAA,IAC9B,CAAC;AAGD,UAAM,mBAAmB,OAAO,cAAc;AAC9C,UAAM,kBAAkB,OAAO,cAAc;AAC7C,UAAM,qBAAqBA,GAAE;AAAA,MAC3B,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AACA,UAAM,oBAAoBA,GAAE;AAAA,MAC1B,CAAC;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,iBAAiBA,GAAE,MAAM,CAAC,GAAG,qBAAqB,kBAAkB;AAAA,MACxE,UAAU,GAAG,OAAO,QAAQ;AAAA,IAC9B,CAAC;AAGD,UAAM,oBAAoB,OAAO,cAAc,cAAc,CAAC;AAC9D,UAAM,mBAAmB,OAAO,cAAc,oBAAoB,CAAC;AACnE,UAAM,oBAAoBA,GAAE;AAAA,MAC1B,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AACA,UAAM,mBAAmBA,GAAE;AAAA,MACzB,CAAC;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,MAAsC;AACrD,UAAM,UAAU,KAAK,IAAI,CAAC,SAAS;AAAA,MACjC,SAAS;AAAA,MACT,SAAS,KAAK,WAAW,GAAiC;AAAA,IAC5D,EAAE;AAEF,WAAOA,GAAE;AAAA,MACP;AAAA,MACA,CAAC,EAAE,QAAQ,MACT,GAAG,QAAQ,QAAQ,WAAW,IAAI,QAAQ,QAAQ,IAAI,IAAI,QAAQ,QAAQ;AAAA,IAC9E;AAAA,EACF;AACF;;;ATvOA,IAAM,eAAuBI,MAAK;AAAA,EAChC,gBAAgB;AAAA,EAChB;AACF;AACA,IAAM,iBAAiB,UAAQ,YAAY;AAEpC,IAAM,MAAM,MAAM;AACvB,QAAM,SAAU,eAAe,SAAS,WACtC,eAAe,WACf;AACF,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,IAAI,YAAY;AAAA,EACzB,WAAW,OAAO,WAAW,UAAU;AACrC,WAAO,IAAI,cAAc;AAAA,EAC3B;AACA,QAAM,IAAI,MAAM,4FAAsB;AACxC,GAAG;;;AWfI,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,cAAc;AACZ,UAAM,OAAO;AAAA,EACf;AAAA,EAEA,iBAAiB,OAA0B;AACzC,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OACE,EAAE,SAAS,GACX,cACA,gBACA;AACA,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,UAAM,QAAQ,IAAI,oBAAoB;AACtC,QAAI,gBAAgB,aAAa,QAAW;AAC1C,YAAM,IAAI,MAAM,kDAAyB,QAAQ,EAAE;AAAA,IACrD;AACA,UAAM,MAAM,MAAM,WAAW,eAAe,QAAQ;AAEpD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM,GAAG,UAAU,sBAAsB,UAAU,GAAG;AAAA,MACtD,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;ACnCO,IAAM,uBAAN,cAAmC,SAAS;AAAA,EACjD,cAAc;AACZ,UAAM,YAAY;AAAA,EACpB;AAAA,EAEA,iBAAiB,OAA0B;AACzC,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,GAAkC;AAClD,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAKjB,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;ACtCA,OAAOD,iBAAgB;AACvB,OAAOH,QAAO;AAaP,IAAM,oBAAN,cAAgC,SAAS;AAAA,EAC9C,cAAc;AACZ,UAAM,SAAS;AAAA,EACjB;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,GAA+B,MAAqB;AACpE,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAGnD,UAAM,EAAE,OAAO,WAAW,IAAI,KAAK,cAAc,IAAI;AAGrD,UAAM,wBAAwB,KAAK;AAAA,MAAK,CAACD,UACtCA,KAAI,QAAQ,WAAW,CAAC,GAAG,SAAS,iBAAiB;AAAA,IACxD;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,YAAY,WAAW;AAAA,QACrB,CAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM;AAAA,MAC5C;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,wBACA,CAAC,6CAA6C,IAC9C,CAAC;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,MAGZ;AACA,UAAM,aAAuB,CAAC;AAG9B,QAAI,iBAA2B,CAAC;AAEhC,UAAM,SAASC,GAAE,QAAQ,MAAM,CAACD,SAAQA,KAAI,SAAS;AACrD,UAAM,OAAO,OAAO,KAAK,MAAM,EAC5B,IAAI,CAAC,cAAc;AAClB,YAAM,UAAU,OAAO,SAAS;AAChC,YAAM,cAAc,QACjB,IAAI,CAACA,SAAQ;AAEZ,cAAM,uBAAuBA,KAAI,WAAW;AAAA,UAC1C,CAAC,UACC,CAAC,aAAa,UAAU,MAAM,IAAI,KAClC,CAAC,aAAa,UAAU,MAAM,IAAI,KAClC,CAAC,aAAa,YAAY,MAAM,IAAI,KACpC,EAAE,MAAM,aAAa,QAAQ,MAAM,KAAK,WAAW,GAAG;AAAA;AAAA,QAC1D;AAGA,cAAM,gBAAgBA,KAAI,eACvB,IAAI,CAAC,cAAc;AAClB,iBAAO,qBAAqB,WAAW,UAAU;AAAA,QACnD,CAAC,EACA,KAAK,IAAI;AACZ,yBAAiB,eAAe;AAAA,UAC9BA,KAAI,eAAe,IAAI,CAAC,cAAc,UAAU,EAAE;AAAA,QACpD;AAGA,cAAM,YAAY;AAAA,UAChB;AAAA,UACA;AAAA,QACF;AAGA,cAAM,gBAAgB;AAAA,UACpB,kBAAkBA,KAAI,UAAU;AAAA,UAChC;AAAA,QACF;AAGA,cAAM,aAAa,KAAK,qBACrB,IAAI,CAAC,UAAU,MAAM,IAAI,EACzB,KAAK,IAAI,CAAC;AAEb,eAAOC,GAAE;AAAA,UAAOD,KAAI,QAAQ;AAAA,UAAS,CAAC,WACpC,WAAW,QAAQ,IAAI;AAAA,QACzB,EACG,IAAI,CAAC,WAAW;AACf,gBAAM,aAAa,GAAG,OAAO,OAAO,MAAM,MAAM,GAAGA,KAAI,IAAI;AAC3D,kBAAQ,QAAQ;AAAA,YACd,KAAK;AACH,qBAAO,KAAK;AAAA,gBACVA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,KAAK;AACH,qBAAO,KAAK;AAAA,gBACVA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,KAAK;AACH,qBAAO,KAAK;AAAA,gBACVA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,KAAK;AACH,qBAAO,KAAK;AAAA,gBACVA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,KAAK;AAAA,YACL;AACE,qBAAO,oBAAoBI,YAAW,SAAS,QAAQ,IAAI,CAAC;AAAA,UAChE;AAAA,QACF,CAAC,EACA,KAAK,IAAI;AAAA,MACd,CAAC,EACA,KAAK,MAAM;AAEd,aAAO,oBAAoB,UAAU,QAAQ,UAAU,SAAS,CAAC;AAAA,EACvE,WAAW;AAAA;AAAA,IAEP,CAAC,EACA,KAAK,MAAM;AAEd,WAAO;AAAA,MACL,OAAO,CAAC,IAAI;AAAA,MACZ,YAAYH,GAAE,WAAWA,GAAE,KAAK,UAAU,GAAG,cAAc;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,YACED,MACA,YACA,eACA,WACA,eACA,YACA;AACA,UAAM,kBAAkBA,KAAI,QAAQ,eAChC,QAAQI,YAAW,SAASJ,KAAI,QAAQ,YAAY,IACpDA,KAAI;AAER,QAAIA,KAAI,QAAQ,eAAe,OAAO;AACpC,aAAO;AAAA,wBACW,eAAe,GAAG,aAAa,IAAI,SAAS,cAAc,aAAa;AAAA;AAAA;AAAA,eAGhF,UAAU,oBAAoB,UAAU;AAAA;AAAA;AAAA,MAGjD,KAAK;AAAA,IACP,OAAO;AACL,aAAO;AAAA,wBACW,eAAe,GAAG,aAAa,IAAI,SAAS,cAAc,aAAa;AAAA;AAAA,iBAE9EA,KAAI,QAAQ,UAAU;AAAA,eACxB,UAAU;AAAA,cACX,UAAU;AAAA;AAAA;AAAA,QAGhB,KAAK;AAAA,IACT;AAAA,EACF;AAAA,EAEA,qBACEA,MACA,YACA,eACA,WACA,eACA,sBACA;AACA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,GAAG,qBAAqB;AAAA,QACtB,CAAC,UAAU,oBAAoB,MAAM,IAAI,aAAa,MAAM,IAAI;AAAA,MAClE;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,iBAAiB,cAAc,KAAK,OAAO;AACjD,WAAO;AAAA,wBACaA,KAAI,UAAU,GAAG,aAAa;AAAA,IAClD,SAAS,GAAG,cAAc;AAAA;AAAA;AAAA,eAGf,aAAa;AAAA;AAAA,MAEtB,WAAW;AAAA;AAAA;AAAA,eAGF,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQrB,KAAK;AAAA,EACP;AAAA,EAEA,UACEA,MACA,YACA,eACA,WACA,eACA,YACA;AACA,UAAM,gBAAgBA,KAAI,QAAQ,eAC9B,QAAQI,YAAW,SAASJ,KAAI,QAAQ,YAAY,IACpD,QAAQI,YAAW,SAASJ,KAAI,UAAU;AAC9C,WAAO,qBAAqBI,YAAW;AAAA,MACrC;AAAA,MACA;AAAA,IACF,CAAC,GAAG,aAAa,IAAI,CAAC,WAAW,yBAAyB,EACvD,OAAO,CAAC,MAAM,MAAM,EAAE,EACtB,KAAK,GAAG,CAAC,oBAAoB,aAAa;AAAA;AAAA,UAEvC,UAAU;AAAA,QACZ,UAAU;AAAA,iCAEZJ,KAAI,QAAQ,eAAe,SAAS,qBAAqB,EAC3D;AAAA;AAAA,EAEF;AAAA,EAEA,kBACEA,MACA,YACA,eACA,WACA,YACA;AACA,WAAO;AAAA,wBACaA,KAAI,UAAU,GAAG,aAAa,IAAI,SAAS;AAAA,4BACvC,UAAU,oBAAoB,UAAU;AAAA;AAAA,MAE9D,KAAK;AAAA,EACT;AACF;;;ACtRA,OAAOI,iBAAgB;AACvB,SAAS,KAAAL,UAAS;AASlB,OAAOE,SAAO;AAEP,IAAM,sBAAN,cAAkC,SAAS;AAAA,EAChD,cAAc;AACZ,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,OAAO,MAAc,OAAwB;AAC3C,WAAO;AAAA,MACL,eAAe,QAAQ;AAAA,YAAe,KAAK,aAAa,EAAE;AAAA,MAC1D;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAAA,EACA,OAAO,MAAc,OAAwB;AAC3C,WAAO;AAAA,MACL;AAAA,MACA,KAAK,OAAO,MAAM,KAAK;AAAA,MACvB;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAAA,EAEA,mBAAmB,UAAkB,KAAoB;AACvD,QAAI,IAAI,eAAe,SAAS;AAC9B,YAAM,EAAE,IAAI,kBAAkB,IAAI;AAAA,QAChC;AAAA,QACA,IAAI;AAAA,MACN;AACA,YAAM,cAAc,GAAG,EAAE;AACzB,aAAO,YAAY,WAAW,2BAA2B,kBAAkB,EAAE,IAAI,WAAW;AAAA,IAC9F,WAAW,IAAI,eAAe,gBAAgB;AAC5C,UAAI;AACF,cAAM,UAAU;AAAA,UACd;AAAA,UACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,QAC5B;AACA,cAAM,cAAc,cAAc,eAAe,QAAQ,IAAI;AAC7D,cAAM,cAAc,GAAG,QAAQ,IAAI;AACnC,eAAO,YAAY,WAAW,2BAA2B,YAAY,EAAE,IAAI,WAAW;AAAA,MACxF,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,4DAAe,IAAI,IAAI,IAAI,IAAI,UAAU,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,aACE,UACA,KACA,OACA,SAAiB,IACT;AACR,QAAI,UAAkB;AACtB,cAAU,kBAAkB,MAAM,GAAG,IAAI,IAAI;AAE7C,YAAQ,IAAI,YAAY;AAAA,MACtB,KAAK;AACH,YACE,IAAI,mBAAmBF,GAAE,cACxB,IAAI,QAAQ,aAAa,MAAM,KAChC;AACA,iBAAO,uBAAuB,IAAI,KAAK,KAAK,OAAO;AAAA,QACrD,OAAO;AACL,iBAAO,mCAAmC,IAAI,KAAK,KAAK,OAAO;AAAA,QACjE;AAAA,MACF,KAAK;AACH,eAAO,qBAAqB,OAAO;AAAA,MACrC,KAAK;AACH,eAAO,iBAAiB,OAAO;AAAA,MACjC,KAAK;AACH,eAAO,wBAAwB,OAAO;AAAA,MACxC,KAAK;AACH,eAAO,6BAA6B,IAAI,KAAK,KAAK,OAAO;AAAA,MAC3D,KAAK;AACH,eAAO,kBAAkB,OAAO;AAAA,MAClC,KAAK;AACH,eAAO,mCAAmC,OAAO;AAAA,MACnD,KAAK;AACH,eAAO,kCAAkC,OAAO;AAAA,MAClD,KAAK;AACH,YAAI;AACF,cAAI;AACJ,cAAI,IAAI,SAAS,WAAW;AAC1B,qBAAS,GAAG,MAAM,OAAO,GAAGK,YAAW,SAAS,IAAI,IAAI,CAAC;AAAA,UAC3D,OAAO;AACL,kBAAM,EAAE,GAAG,IAAI,uBAAuB,UAAU,IAAI,IAAI;AACxD,qBAAS,GAAG,EAAE;AAAA,UAChB;AACA,iBAAO,IAAI,MAAM,IAAI,OAAO,IAC1B,IAAI,YAAY,IAAI,WAAW,cAAc,EAC/C;AAAA,QACF,QAAQ;AACN,iBAAO,2CAAkB,IAAI,IAAI;AAAA,QACnC;AAAA,MACF,KAAK;AACH,YAAI;AACF,gBAAM,UAAU;AAAA,YACd;AAAA,YACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,UAC5B;AACA,gBAAM,OAAO,GAAG,QAAQ,IAAI;AAC5B,iBAAO,IAAI,IAAI,kBAAkB,IAAI,IAAI,OACvC,IAAI,YAAY,IAAI,WAAW,cAAc,EAC/C;AAAA,QACF,QAAQ;AACN,iBAAO,UAAU,OAAO;AAAA,QAC1B;AAAA,MACF,KAAK;AACH,eAAO,KAAK,IAAI,IAAI;AAAA,MACtB,KAAK;AACH,eAAO,KAAK,IAAI,IAAI;AAAA,MACtB;AACE,cAAM,IAAI;AAAA,UACR,mEAAiB,IAAI,UAAU,OAAO,IAAI,IAAI;AAAA,QAChD;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,oBAAoB,SAAkC;AACpD,WAAO,QAAQ;AAAA,MACb,CAAC,QAAQ,QAAQ;AACf,YAAI,IAAI,UAAU;AAChB,iBAAO;AAAA,QACT;AAEA,YAAI;AACJ,YAAI,IAAI,aAAa,MAAM;AACzB,kBAAQ;AAAA,QACV,WAAW,IAAI,mBAAmBL,GAAE,WAAW;AAC7C,kBAAQ;AAAA,QACV,WAAW,IAAI,mBAAmBA,GAAE,SAAS;AAC3C,kBAAQ,OAAO,KAAK,IAAI,QAAQ,IAAI,EAAE,CAAC;AAAA,QACzC,WAAW,IAAI,mBAAmBA,GAAE,YAAY;AAC9C,kBAAQ;AAAA,QACV,WAAW,IAAI,mBAAmBA,GAAE,WAAW;AAC7C,cAAI,IAAI,eAAe,mBAAmB;AACxC,oBAAQ;AAAA,UACV,OAAO;AACL,oBAAQ;AAAA,UACV;AAAA,QACF,WAAW,IAAI,mBAAmBA,GAAE,UAAU;AAC5C,kBAAQ,CAAC;AAAA,QACX,WAAW,IAAI,mBAAmBA,GAAE,WAAW;AAC7C,kBAAQ,CAAC;AAAA,QACX;AAEA,eAAO,IAAI,IAAI,IAAI;AACnB,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OACE,EAAE,SAAS,GACX,gBACA;AACA,UAAM,SAAS,cAAc,IAAI,QAAQ;AACzC,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,UAAW,eAAe,SAC7B,OAAO,CAAC,QAAQ,IAAI,SAAS,IAAI,EACjC,IAAI,CAAC,QAAQ;AACZ,YAAM,gBAAgB,OAAO,MAAM;AAAA,QACjC,CAAC,SAAS,KAAK,SAAS,IAAI;AAAA,MAC9B;AACA,UAAI,QAAQ,eAAe,QAAQ,IAAI;AACvC,aAAO;AAAA,IACT,CAAC;AAEH,UAAM,eAAe,KAAK,oBAAoB,OAAO;AAGrD,UAAM,eACJ,QAEC,OAAO,CAAC,QAAQ;AACf,UAAI,IAAI,SAAS,MAAM;AACrB,eAAO;AAAA,MACT,WAAW,IAAI,KAAK,SAAS,KAAK,KAAK,IAAI,eAAe,aAAa;AACrE,YAAI;AACF,qCAA2B,UAAU,IAAI,KAAK,QAAQ,OAAO,EAAE,CAAC;AAChE,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,WAAW,IAAI,eAAe,SAAS;AACrC,YAAI;AACF,iCAAuB,UAAU,IAAI,IAAI;AACzC,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC,EACA,IAAI,CAAC,QAAQ;AACZ,UAAI;AACJ,UAAI,aAAa;AACjB,UAAI;AACJ,UAAI,IAAI,eAAe,SAAS;AAC9B,cAAM;AACN,cAAM,EAAE,mBAAmB,eAAe,GAAG,IAC3C,uBAAuB,UAAU,IAAI,IAAI;AAC3C,qBAAa,cAAc;AAC3B,iBAAS;AAAA,MACX,OAAO;AACL,cAAM;AACN,cAAM,UAAU;AAAA,UACd;AAAA,UACA,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,QAC5B;AACA,qBAAa,QAAQ;AAAA,MACvB;AAEA,aAAO;AAAA,QACL;AAAA,QACA,SAAS;AAAA,UACP,UAAU;AAAA,UACV,MAAM;AAAA,UACN;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC,EACA,OAAO,CAAC,gBAAgB;AACvB,UAAI,YAAY,QAAQ,wBAAwB;AAC9C,YAAI;AACF,wBAAc,IAAI,YAAY,QAAQ,QAAQ;AAC9C,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AAEH,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAoBD,MAAM,OAAO,mCAAmC,MAAM,EAAE,IAC3D,MAAM,EACR;AAAA,WACK,MAAM,OAAO,gCAAgC,MAAM,EAAE,IACxD,MAAM,EACR;AAAA,WACK,MAAM,OAAO;AAAA,EACtBE,IAAE;AAAA,QACF,QACG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,OAAO,EAAE,SAAS,IAAI,UAAU,CAAC,EAClE,IAAI,CAAC,QAAQ;AACZ,iBAAO,KAAK,mBAAmB,UAAU,GAAG;AAAA,QAC9C,CAAC;AAAA,MACL,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,0BAEc,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAQzC,MAAM,aACR;AAAA;AAAA,OAEK,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA,kBAIR,MAAM,aAAa,sBAC7B,MAAM,aACR;AAAA;AAAA,mCAE6B,MAAM,OAAO;AAAA;AAAA,OAEzC,MAAM,OAAO;AAAA,oDAEhB,MAAM,OACR,eAAe,KAAK,UAAU,YAAY,EAAE;AAAA,QAC1C;AAAA,QACA;AAAA,MACF,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAKK,MAAM,OAAO,cAAc,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,YAIpC,QACC,OAAO,CAAC,QAAQ,IAAI,eAAe,cAAc,EACjD,IAAI,CAAC,QAAQ;AACZ,YAAI,IAAI,UAAU;AAChB,iBAAO,GAAG,IAAI,IAAI,SAAS,IAAI,KAAK;AAAA,YAClC;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,GAAG,IAAI,IAAI,SAAS,IAAI,KAAK,QAAQ,OAAO,KAAK,CAAC;AAAA,QAC3D;AAAA,MACF,CAAC,EACA,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYlB,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,yBAIM,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAQjC,OAAO,SAAS,MAAM,OACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yDAaY,MAAM,QACR;AAAA;AAAA;AAAA;AAAA,cAIA,QACC,IAAI,CAAC,QAAQ;AACZ,YAAI,IAAI,SAAS,cAAc;AAC7B,iBAAO,gBAAgB,KAAK;AAAA,YAC1B,gCAAgC,IAAI,IAAI;AAAA,YACxC;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,KAAK;AAAA,YACV,KAAK,aAAa,UAAU,KAAK,KAAK;AAAA,aACrC,MAAM;AACL,kBAAI,IAAI,MAAM,SAAS,IAAI,GAAG;AAC5B,oBAAI;AACF,wBAAMQ,UAAS,cAAc;AAAA,oBAC3B,IAAI,MAAM,QAAQ,MAAM,EAAE;AAAA,kBAC5B;AACA,yBAAOA,QAAO,SAAS,IAAI;AAAA,gBAC7B,QAAQ;AACN,yBAAO,IAAI;AAAA,gBACb;AAAA,cACF;AACA,qBAAO,IAAI;AAAA,YACb,GAAG;AAAA,UACL;AAAA,QACF;AAAA,MACF,CAAC,EACA,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUjB,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ArBrWA,OAAOQ,eAAc;;;AsB7Dd,IAAM,+BAAN,cAA2C,SAAS;AAAA,EACzD,cAAc;AACZ,UAAM,oBAAoB;AAAA,EAC5B;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,GAA0C;AAC1D,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA,EAGV,KAAK,UAAU;AAAA,QACf,KAAK,KAAK;AAAA,QACV,SAAS;AAAA,MACX,CAAC,CAAC;AAAA;AAAA,QAEM,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;AC7BO,IAAM,iCAAN,cAA6C,SAAS;AAAA,EAC3D,cAAc;AACZ,UAAM,sBAAsB;AAAA,EAC9B;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,UAAU,UAAU,GAA4C;AACvE,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,UAAM,SAAS,cAAc,IAAI,QAAQ;AACzC,QAAI,CAAC,WAAW;AACd,YAAM,aAAa,OAAO,MAAM;AAAA,QAAK,CAAC,SACpC,CAAC,QAAQ,OAAO,EAAE,SAAS,KAAK,IAAI;AAAA,MACtC;AACA,UAAI,YAAY;AACd,oBAAY,WAAW;AAAA,MACzB,OAAO;AACL,cAAM,gBAAgB,OAAO,MAAM;AAAA,UACjC,CAAC,SAAS,KAAK,SAAS;AAAA,QAC1B;AACA,YAAI,eAAe;AACjB,sBAAY,cAAc;AAAA,QAC5B,OAAO;AACL,kBAAQ,IAAI,4CAAmB;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA,WAGD,MAAM,OAAO,cAChB,MAAM,OACR;AAAA,WACK,MAAM,OAAO,gCAAgC,MAAM,EAAE,IACxD,MAAM,EACR;AAAA,WACK,MAAM,OAAO,mCAAmC,MAAM,EAAE,IAC3D,MAAM,EACR;AAAA;AAAA,kBAEY,MAAM,OAAO,2BACvB,MAAM,OACR;AAAA;AAAA;AAAA,uBAGiB,MAAM,OAAO;AAAA,eACrB,YAAY,MAAM,EAAE,WAAW,MAAM,OAAO;AAAA,yBAClC,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,iDAIW,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,4BAIlC,MAAM,OAAO,cACrC,MAAM,aACR;AAAA,kBACgB,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,SAI1B,MAAM,WAAW,gBAAgB,MAAM,KAAK;AAAA;AAAA,iBAEpC,MAAM,KAAK;AAAA,mBACT,MAAM,KAAK;AAAA,yBACL,MAAM,KAAK,aACxB,YAAY,QAAQ,SAAS,MAAM,EACrC;AAAA;AAAA;AAAA;AAAA,QAIF,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAqBJ,OAAO,SAAS,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA,mBAIhC,MAAM,WAAW;AAAA,kBAClB,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAM3B,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;ACtHA,OAAOb,iBAAgB;AAEhB,IAAM,gCAAN,cAA4C,SAAS;AAAA,EAC1D,cAAc;AACZ,UAAM,qBAAqB;AAAA,EAC7B;AAAA,EAEA,iBAAiB,OAA0B,QAAgB;AACzD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,UAAU,OAAO,GAA2C;AACnE,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,QAAQ,SAAS,UAAU,MAAM;AAEvC,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,OAAO,MAAM;AAAA,MACtC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAOD,MAAM;AAAA;AAAA,kBAEC,MAAM;AAAA,mCACW,MAAM;AAAA;AAAA;AAAA;AAAA,eAI1B,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAWZ,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;AAEO,SAAS,SAAS,UAAkB,QAAwB;AACjE,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,WAAO;AAAA,EACT,WAAW,OAAO,SAAS,aAAa,GAAG;AACzC,WAAO;AAAA,EACT,OAAO;AACL,UAAM,WAAW,cAAc,IAAI,QAAQ,EAAE,MAAM;AAAA,MACjD,CAAC,SAAS,GAAG,QAAQ,GAAGA,YAAW,SAAS,KAAK,IAAI,CAAC,OAAO;AAAA,IAC/D;AACA,QAAI,YAAY,SAAS,MAAM;AAC7B,aAAO,SAAS;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AACF;;;AC/DO,IAAM,8BAAN,cAA0C,SAAS;AAAA,EACxD,cAAc;AACZ,UAAM,mBAAmB;AAAA,EAC3B;AAAA,EAEA,iBAAiB,OAA0B,QAAgB;AACzD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,UAAU,OAAO,GAAyC;AACjE,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,QAAQ,SAAS,UAAU,MAAM;AAEvC,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,OAAO,MAAM;AAAA,MACtC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAOD,MAAM,KAAK,MAAM;AAAA;AAAA,cAEd,MAAM;AAAA;AAAA;AAAA;AAAA,kBAIF,MAAM,+CAA+C,MAAM;AAAA,wBACrD,MAAM;AAAA;AAAA;AAAA,4BAGF,KAAK,UAAU,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,qCAKZ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQlC,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;ACrDO,IAAM,iCAAN,cAA6C,SAAS;AAAA,EAC3D,cAAc;AACZ,UAAM,sBAAsB;AAAA,EAC9B;AAAA,EAEA,iBAAiB,OAA0B,aAAqB;AAC9D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,WAAW;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,UAAU,OAAO,GAA4C;AACpE,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,OAAO,MAAM;AAAA,MACtC,MAAM;AAAA;AAAA;AAAA,EAGV,KAAK,UAAU;AAAA,QACf,KAAK,KAAK;AAAA,QACV,SAAS;AAAA,MACX,CAAC,CAAC;AAAA;AAAA,QAEM,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;AC7BO,IAAM,8BAAN,cAA0C,SAAS;AAAA,EACxD,cAAc;AACZ,UAAM,mBAAmB;AAAA,EAC3B;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,GAAyC;AACzD,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA;AAAA,WAID,MAAM,OAAO,8CAA8C,MAAM,EAAE,IAAI,MAAM,OAAO;AAAA;AAAA,kBAE7E,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAsBf,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAarB,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;AC9DO,IAAM,8BAAN,cAA0C,SAAS;AAAA,EACxD,cAAc;AACZ,UAAM,mBAAmB;AAAA,EAC3B;AAAA,EAEA,iBAAiB,OAA0B;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,GAAG,MAAM,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA;AAAA,EAGA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAyC;AACvC,UAAM,QAAQ,cAAc,eAAe,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB,KAAK;AAAA,MAC9B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAWD,MAAM,OAAO,gCAAgC,MAAM,EAAE,IACxD,MAAM,EACR;AAAA,EACJ,aAAa;AAAA;AAAA,yCAGP,MAAM,OACR,6BAA6B,MAAM,OAAO,iBAAiB,QACxD,IAAI,CAAC,QAAQ;AACZ,eAAO;AAAA,UACL,GAAG,IAAI,IAAI,eAAe,IAAI,KAAK;AAAA,UACnC,OAAO,IAAI,EAAE;AAAA,UACb,eAAe,CAAC,SAAS,MAAM,EAAE,SAAS,IAAI,KAAK,MAAM,KAAK;AAAA,QAChE,EAAE,KAAK,IAAI;AAAA,MACb,CAAC,EACA,KAAK,KAAK,CAAC;AAAA;AAAA,QAEZ,KAAK;AAAA,MACP,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;;;AC1DA,OAAO,QAAQ;AACf,SAAS,KAAAL,UAAS;AAKlB,OAAOkB,eAAc;AAGd,IAAM,2BAAN,cAAuC,SAAS;AAAA,EACrD,cAAc;AACZ,UAAM,gBAAgB;AAAA,EACxB;AAAA,EAEA,mBAAmB;AACjB,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,CAAC,GAAsC;AAClD,UAAM;AAAA,MACJ,QAAQ,EAAE,OAAO,KAAK;AAAA,MACtB,QAAQ;AAAA,QACN,OAAO,EAAE,OAAO;AAAA,MAClB;AAAA,IACF,IAAI;AAEJ,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B,KAAK,IAAI,OAAOjB,SAAQ;AACtB,cAAM,YAAY,KAAK,iBAAiBA,MAAK,KAAK;AAElD,cAAM,YAAY,OAAO,YAAY;AACnC,eAAKA,KAAI,QAAQ,cAAc,WAAW,OAAO;AAC/C,mBAAO;AAAA,cACL,aAAa;AAAA,gBACX,GACG,UAAU,WAAW,EAAE,QAAQ,MAAM,CAAC,EACtC,MAAM,GAAG,EACT,KAAK,MAAO;AAAA,cACjB;AAAA,cACA,MAAM,CAAC;AAAA,YACT;AAAA,UACF,OAAO;AACL,mBAAO;AAAA,cACL,aAAa,CAAC;AAAA,cACd,MAAM;AAAA,gBACJ;AAAA,gBACA,MAAMiB,UAAS,OAAO,KAAK,UAAU,SAAS,GAAG;AAAA,kBAC/C,QAAQ;AAAA,gBACV,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF,GAAG;AAEH,eAAO;AAAA,UACL;AAAA,YACE,GAAGjB,KAAI,QAAQ,cAAc,KAAK,eAAe,MAAM,GAAGA,KAAI,IAAI;AAAA,YAClE,GAAG,UAAU;AAAA,UACf,EAAE,KAAK,MAAO;AAAA,UACd,iBAAiBA,KAAI,QAAQ,eAAe,kBAAkB;AAAA,UAC9D,GAAG,UAAU;AAAA,QACf,EAAE,KAAK,IAAI;AAAA,MACb,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB;AAAA,MACzB,MAAM,MAAM,KAAK,aAAa;AAAA,MAC9B,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EAEA,oBAAoB,SAA6B,MAAuB;AACtE,QAAI,mBAAmBD,GAAE,WAAW;AAClC,aAAO,OAAO;AAAA,QACZ,OAAO,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC,QAAQ;AAAA,UACtC;AAAA,UACA,KAAK,oBAAoB,QAAQ,MAAM,GAAG,GAAG,GAAG;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,IACF,WAAW,mBAAmBA,GAAE,UAAU;AACxC,aAAO,CAAC,KAAK,oBAAoB,QAAQ,SAAS,IAAI,CAAC;AAAA,IACzD,WAAW,mBAAmBA,GAAE,WAAW;AACzC,UAAI,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,OAAO,KAAK,SAAS,SAAS;AACtE,eAAO;AAAA,MACT,OAAO;AACL,eAAO,KAAK,YAAY;AAAA,MAC1B;AAAA,IACF,WAAW,mBAAmBA,GAAE,WAAW;AACzC,UAAI,SAAS,OAAO;AAClB,eAAO;AAAA,MACT;AACA,aAAO,QAAQ,YAAY;AAAA,IAC7B,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,SAAS;AACvC,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B,WAAW,mBAAmBA,GAAE,aAAa;AAC3C,aAAO,KAAK,oBAAoB,QAAQ,KAAK,WAAW,IAAI;AAAA,IAC9D,WAAW,mBAAmBA,GAAE,aAAa;AAC3C,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,UAAU;AACxC,aAAO,KAAK,oBAAoB,QAAQ,KAAK,QAAQ,CAAC,GAAG,IAAI;AAAA,IAC/D,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,UAAU;AACxC,aAAO,QAAQ,KAAK,MAAM;AAAA,QAAI,CAAC,SAC7B,KAAK,oBAAoB,MAAM,IAAI;AAAA,MACrC;AAAA,IACF,WAAW,mBAAmBA,GAAE,SAAS;AACvC,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO,QAAQ;AAAA,IACjB,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO,KAAK,oBAAoB,QAAQ,KAAK,QAAQ,IAAI;AAAA,IAC3D,WAAW,mBAAmBA,GAAE,aAAa,mBAAmBA,GAAE,QAAQ;AACxE,YAAM,MAAM,KAAK,oBAAoB,QAAQ,KAAK,SAAS,IAAI;AAC/D,YAAM,QAAQ,KAAK,oBAAoB,QAAQ,KAAK,WAAW,IAAI;AACnE,aAAO,EAAE,CAAC,GAAG,GAAG,MAAM;AAAA,IACxB,WAAW,mBAAmBA,GAAE,QAAQ;AACtC,aAAO,CAAC,KAAK,oBAAoB,QAAQ,KAAK,WAAW,IAAI,CAAC;AAAA,IAChE,WAAW,mBAAmBA,GAAE,iBAAiB;AAC/C,aAAO,KAAK,oBAAoB,QAAQ,KAAK,OAAO,IAAI;AAAA,IAC1D,OAAO;AAEL,aAAO,WAAW,QAAQ,KAAK;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,iBACEC,MACA,YAC4B;AAC5B,UAAM,UAAU,oBAAoBA,MAAK,UAAU;AACnD,WAAO,KAAK,oBAAoB,SAAS,aAAa;AAAA,EAGxD;AACF;;;A7BpEA,SAAS,gBAAgB;;;A8BxEzB,OAAOI,iBAAgB;AAEvB,OAAOH,SAAO;AAIP,IAAM,0BAAN,cAAsC,SAAS;AAAA,EACpD,cAAc;AACZ,UAAM,eAAe;AAAA,EACvB;AAAA,EAEA,mBAAmB;AACjB,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAE9B,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG;AAAA,MACd,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,OAAO,CAAC,GAAqC;AAC3C,UAAM,YAAY,cAAc,UAAU;AAC1C,UAAM,WAAW,UAAU,IAAI,CAAC,OAAO,cAAc,IAAI,EAAE,CAAC;AAE5D,UAAM,cAA4B,SAC/B,IAAI,CAAC,WAAW;AACf,UACE,OAAO,aAAa,UACpB,OAAO,KAAK,OAAO,OAAO,EAAE,WAAW,GACvC;AACA,eAAO;AAAA,MACT;AACA,YAAM,aAAa,OAAO,KAAK,OAAO,OAAO;AAC7C,YAAM,oBAAoB,WAAW;AAAA,QACnC,CAAC,GAAG,cAAc;AAChB,gBAAM,cAAc,OAAO,eAAe,SAAS;AACnD,YAAE,SAAS,IAAI;AACf,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MAGH;AAEA,YAAM,oBAAoB,GAAG,OAAO,MAAM,MAAM;AAChD,aAAO;AAAA,QACL,OAAO,gBAAgB,OAAO,EAAE;AAAA,QAChC,OAAO;AAAA,UACL,gBAAgBG,YAAW;AAAA,YACzB,OAAO;AAAA,YACP;AAAA,UACF,CAAC,2BAA2B,iBAAiB,qBAAqB,KAAK;AAAA,YACrE;AAAA,UACF,CAAC;AAAA,UACD;AAAA,QACF;AAAA,QACA,YAAY,CAAC,iBAAiB;AAAA,MAChC;AAAA,IACF,CAAC,EACA,OAAO,WAAW;AAErB,UAAM,aAAa,YAAY;AAAA,MAC7B,CAAC,QAAQI,QAAO;AACd,YAAIA,QAAO,MAAM;AACf,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,UACL,OAAO,CAAC,GAAG,OAAQ,OAAO,MAAMA,IAAG,KAAK,IAAI,GAAGA,IAAG,OAAO,EAAE;AAAA,UAC3D,YAAYP,IAAE,KAAK,CAAC,GAAG,OAAQ,YAAY,GAAGO,IAAG,UAAU,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO,CAAC;AAAA,QACR,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB;AAAA,MACzB,MAAM,WAAW,MAAM,KAAK,IAAI;AAAA,MAChC,YAAY,WAAW;AAAA,MACvB,eAAe,CAAC,uCAAuC;AAAA,IACzD;AAAA,EACF;AACF;;;AC/DA,OAAOP,SAAO;AAId,OAAOG,iBAAgB;AAIhB,IAAM,6BAAN,cAAyC,SAAS;AAAA,EACvD,cAAc;AACZ,UAAM,kBAAkB;AAAA,EAC1B;AAAA,EAEA,mBAAmB;AACjB,UAAM,EAAE,IAAI,IAAI,OAAO,OAAO;AAC9B,UAAM,EAAE,MAAM,IAAI,GAAG;AACrB,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,WAAW,OAAO,YAAY;AAEpC,WAAO;AAAA,MACL,QAAQ,GAAG,GAAG,IAAI,MAAM;AAAA,MACxB,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,SAAS;AACP,UAAM,YAAY,cAAc,UAAU;AAC1C,UAAM,WAAW,UAAU,IAAI,CAAC,OAAO,cAAc,IAAI,EAAE,CAAC;AAC5D,UAAM,QAAQH,IAAE,MAAM,CAAC,GAAG,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAEzD,UAAM,mBAAmBA,IAAE;AAAA,MACzB,SAAS;AAAA,QAAQ,CAAC,MAChB,EAAE,MACC,IAAI,CAAC,MAAM;AACV,cAAI,eAAe,CAAC,KAAK,EAAE,iBAAiB,cAAc;AACxD,mBAAO,EAAE;AAAA,UACX;AACA,iBAAO;AAAA,QACT,CAAC,EACA,OAAO,WAAW;AAAA,MACvB;AAAA,IACF,EAAE,IAAI,CAAC,UAAU;AACf,YAAM,CAAC,WAAW,OAAO,IAAI,MAAM,MAAM,IAAI;AAC7C,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe,GAAGG,YAAW,SAAS,SAAS,CAAC,GAAGA,YAAW,SAAS,OAAO,CAAC;AAAA,MACjF;AAAA,IACF,CAAC;AAED,UAAM,cAA2C,SAAS,IAAI,CAAC,WAAW;AACxE,YAAM,UAAU,OAAO,MAAM;AAAA,QAAI,CAAC,SAChC,KAAK,cAAc,MAAM,KAAK;AAAA,MAChC;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,UACL,aAAa,OAAO,EAAE;AAAA,gBAChB,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA,UAExB;AAAA,QACF;AAAA,QACA,YAAY,CAAC;AAAA,MACf;AAAA,IACF,CAAC;AAED,gBAAY;AAAA,MACV,GAAG,iBAAiB,IAAI,CAAC,EAAE,WAAW,SAAS,cAAc,MAAM;AACjE,eAAO;AAAA,UACL,OAAO;AAAA,YACL,aAAa,aAAa;AAAA;AAAA,cAExBA,YAAW,YAAY,SAAS,CAAC;AAAA,cACjCA,YAAW,YAAY,OAAO,CAAC;AAAA;AAAA,YAEjC;AAAA,UACF;AAAA,UACA,YAAY,CAAC;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,aAAa,YAAY;AAAA,MAC7B,CAAC,QAAQI,QAAO;AACd,YAAIA,QAAO,MAAM;AACf,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,UACL,OAAO,CAAC,GAAG,OAAQ,OAAO,GAAGA,IAAG,OAAO,EAAE;AAAA,UACzC,YAAYP,IAAE,KAAK,CAAC,GAAG,OAAQ,YAAY,GAAGO,IAAG,UAAU,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO,CAAC;AAAA,QACR,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG,KAAK,iBAAiB;AAAA,MACzB,MAAM,WAAW,MAAM,KAAK,IAAI;AAAA,MAChC,YAAY,WAAW;AAAA,MACvB,eAAe;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,YACI,SAAS,IAAI,CAAC,WAAW,GAAG,OAAO,KAAK,KAAK,OAAO,EAAE,OAAO,EAAE,KAAK,KAAK,CAAC;AAAA,YAC1E,iBAAiB,IAAI,CAAC,EAAE,OAAO,cAAc,MAAM,GAAG,KAAK,KAAK,aAAa,EAAE,EAAE,KAAK,KAAK,CAAC;AAAA;AAAA,QAEhG;AAAA,QACA;AAAA;AAAA;AAAA,MAGF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,cAAc,MAAkB,OAAwB;AAC9D,QAAI,cAAc,IAAI,GAAG;AACvB,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,SAAS,MAAM;AACtB,aAAO;AAAA,IACT;AAEA,QAAI,eAAe,IAAI,GAAG;AACxB,UAAI,2BAA2B,IAAI,GAAG;AACpC,eAAO,GAAG,KAAK,IAAI,QAAQ,KAAK,WAAW,kBAAkB,QAAQ;AAAA,MACvE;AACA,aAAO;AAAA,IACT;AAEA,QAAI;AAEJ,QAAI,cAAc,IAAI,GAAG;AACvB,aAAO;AAAA,IACT,WAAW,iBAAiB,IAAI,GAAG;AACjC,aAAO;AAAA,IACT,WAAW,aAAa,IAAI,KAAK,WAAW,IAAI,GAAG;AACjD,aAAO;AAAA,IACT,WAAW,WAAW,IAAI,GAAG;AAC3B,YAAM,aAAa,MAAM,KAAK,EAAE;AAChC,UAAI,CAAC,YAAY;AACf,gBAAQ,KAAK,6BAA6B,KAAK,EAAE,EAAE;AACnD,eAAO;AAAA,MACT;AACA,aAAO,OAAO,KAAK,WAAW,MAAM,EACjC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EACnB,KAAK,KAAK;AAAA,IACf,WAAW,YAAY,IAAI,KAAK,aAAa,IAAI,KAAK,cAAc,IAAI,GAAG;AACzE,aAAO;AAAA,IACT,WAAW,cAAc,IAAI,GAAG;AAC9B,aAAO;AAAA,IACT,WACE,WAAW,IAAI,KACf,eAAe,IAAI,KACnB,WAAW,IAAI,KACf,gBAAgB,IAAI,GACpB;AACA,aAAO;AAAA,IACT,WAAW,WAAW,IAAI,GAAG;AAC3B,aAAO;AAAA,IACT,WAAW,WAAW,IAAI,GAAG;AAC3B,aAAO;AAAA,IACT,OAAO;AACL,cAAQ,KAAK,sBAAuB,KAAa,IAAI,EAAE;AACvD,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,UAAU;AACjB,aAAO,GAAG,IAAI;AAAA,IAChB;AACA,QAAI,KAAK,WAAW;AAClB,aAAO,cAAc,IAAI,KAAK,IAAI,iBAAiB,IAAI;AAAA,IACzD;AAEA,WAAO,GAAG,KAAK,IAAI,KAAK,IAAI;AAAA,EAC9B;AACF;;;A/B7HA,SAAS,cAAc,0BAA0B;AAyB1C,IAAM,SAAN,MAAa;AAAA,EAClB,OAQM,CAAC;AAAA,EACP,QAAkD,CAAC;AAAA,EACnD,SAA2C,CAAC;AAAA,EAC5C,YAAqB;AAAA,EAErB,IAAI,gBAAwB;AAC1B,WAAOH,MAAK,KAAK,OAAO,aAAa,eAAe;AAAA,EACtD;AAAA,EACO,cAAc;AAAA,EAAC;AAAA,EAEtB,MAAM,OAAsB;AAC1B,UAAM,EAAE,QAAQ,IAAI,OAAO,OAAO;AAGlC,UAAM,QAAQ;AAAA,MACZ,QAAQ,IAAI,OAAO,WAAW;AAC5B,cAAM,cAAcA,MACjB,KAAK,WAAW,aAAa,MAAM,gBAAgB,EACnD,QAAQ,UAAU,OAAO;AAC5B,YAAI,CAACC,IAAG,WAAW,WAAW,GAAG;AAC/B;AAAA,QACF;AAEA,cAAM,cAAcD,MAAK;AAAA,UACvB,OAAO;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAEA,cAAM,cAAc,MAAM,KAAK,kBAAkB,WAAW;AAC5D,cAAM,cAAc,OAAO,YAAY;AACrC,cAAIC,IAAG,WAAW,WAAW,MAAM,OAAO;AACxC,mBAAO;AAAA,UACT;AACA,iBAAO,KAAK,kBAAkB,WAAW;AAAA,QAC3C,GAAG;AAEH,YAAI,gBAAgB,aAAa;AAC/B;AAAA,QACF;AACA,QAAAA,IAAG,cAAc,aAAaA,IAAG,aAAa,WAAW,CAAC;AAAA,MAC5D,CAAC;AAAA,IACH;AAGA,QAAI,mBAAmB,MAAM,KAAK,oBAAoB;AAEtD,UAAM,oBAAoB,MAAM,KAAK,qBAAqB;AAG1D,UAAM,SAASC,OAAM,kBAAkB,iBAAiB;AACxD,QAAI,QAAQ;AACV,YAAM,MAAM;AACZ,YAAM,UAAU,QAAQ,OAAO,UAAU,IAAI,UAAU;AACvD,cAAQ;AAAA,QACN,MAAM,MAAM,QAAQ,IAAI,OAAO,MAAM,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC;AAAA,MACnE;AACA;AAAA,IACF;AAEA,UAAM,MAAM,IAAI,gBAAgB;AAChC,SAAK,YAAY;AACjB,UAAM,YAAY,YAAY;AAC5B,UAAI,KAAK,cAAc,OAAO;AAC5B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,cAAQ,IAAI,MAAM,cAAc,2BAA2B,CAAC;AAG5D,UAAI;AACF,cAAM,mBAAmB,KAAO,gBAAgB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,MACxE,QAAQ;AAAA,MAAC;AACT,cAAQ,IAAI,MAAM,cAAc,eAAe,CAAC;AAChD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,GAAG,WAAW,SAAS;AAG/B,UAAM,OAAON,IAAE;AAAA,MACb;AAAA,MACA;AAAA,MACAA,IAAE;AAAA,IACJ;AACA,UAAM,YAAY,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI;AACxC,YAAQ,IAAI,mBAAmB,SAAS;AAGxC,UAAM,aAAaA,IAAE,QAAQ,WAAW,CAAC,MAAM;AAC7C,YAAM,UAAU,EAAE;AAAA,QAChB;AAAA,MACF;AACA,aAAO,QAAS,CAAC;AAAA,IACnB,CAAC;AAGD,UAAM,YAAY,OAAO,KAAK,UAAU;AAIxC,QAAI,UAAU,SAAS,QAAQ,KAAK,UAAU,SAAS,OAAO,GAAG;AAC/D,cAAQ,IAAI,kDAAe;AAC3B,YAAM,KAAK,sBAAsB;AAEjC,UACE,GAAG,YAAY,WAAW,YAC1B,GAAG,WAAW,OAAO,YAAY,OACjC;AACA,gBAAQ,IAAI,qEAAwB;AACpC,cAAM,KAAK;AAAA,UACT;AAAA,UACA,CAAC;AAAA,UACD,EAAE,WAAW,KAAK;AAAA,QACpB;AAAA,MACF;AAGA,iBAAW,WAAW,IAAIA,IAAE,KAAK;AAAA,QAC/B,GAAI,WAAW,WAAW,KAAK,CAAC;AAAA,QAChC;AAAA,MACF,CAAC;AACD,gBAAU,KAAK,WAAW;AAC1B,yBAAmB,MAAM,KAAK,oBAAoB;AAAA,IACpD;AAIA,QACE,UAAU,SAAS,OAAO,KAC1B,UAAU,SAAS,WAAW,KAC9B,UAAU,SAAS,WAAW,GAC9B;AACA,cAAQ,IAAI,0EAA4C;AAExD,YAAM,UAAUA,IAAE;AAAA,QAChB;AAAA,UACE,GAAI,WAAW,OAAO,KAAK,CAAC;AAAA,UAC5B,GAAI,WAAW,WAAW,KAAK,CAAC;AAAA,UAChC,GAAI,WAAW,WAAW,KAAK,CAAC;AAAA,QAClC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,UAAU,OAAO,EAAE,QAAQ,OAAO,KAAK,CAAC;AAAA,MACjE;AACA,YAAM,KAAK,yBAAyB,OAAO;AAAA,IAC7C;AAGA,QAAI,UAAU,SAAS,OAAO,GAAG;AAC/B,YAAM,YAAY,KAAK,oBAAoB,WAAW,OAAO,CAAC;AAC9D,cAAQ,IAAI,kDAAe;AAC3B,YAAM,KAAK,uBAAuB,SAAS;AAC3C,cAAQ,IAAI,gDAAkB;AAC9B,YAAM,KAAK,oBAAoB,SAAS;AAAA,IAC1C;AAGA,UAAM,KAAK,cAAc,gBAAgB;AAGzC,SAAK,YAAY;AACjB,QAAI,MAAM;AACV,YAAQ,IAAI,WAAW,SAAS;AAAA,EAClC;AAAA,EAEA,oBAAoB,WAA+B;AACjD,WAAOA,IAAE;AAAA,MACP,UAAU,IAAI,CAAC,MAAM;AACnB,cAAM,UAAU,EAAE,MAAM,qBAAqB;AAC7C,eAAOG,YAAW,SAAS,QAAS,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,wBAA2C;AAC/C,YACE,MAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,iBAAiB,iBAAiB,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,MAC9D,KAAK,iBAAiB,aAAa,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,IAC5D,CAAC,GAEA,KAAK,EACL,KAAK;AAAA,EACV;AAAA,EAEA,MAAM,uBAAuB,WAAwC;AACnE,YACE,MAAM,QAAQ;AAAA,MACZ,UAAU;AAAA,QAAI,OAAO,aACnB,KAAK;AAAA,UACH;AAAA,UACA;AAAA,YACE;AAAA,UACF;AAAA,UACA;AAAA,YACE,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAEC,KAAK,EACL,KAAK;AAAA,EACV;AAAA,EAEA,MAAM,oBAAoB,WAAwC;AAChE,UAAM,CAAC,GAAG,IAAI,MAAM,KAAK;AAAA,MACvB;AAAA,MACA,EAAE,UAAU,UAAU,CAAC,EAAE;AAAA,MACzB,EAAE,WAAW,KAAK;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gCAAgC,UAAkB,QAAgB;AACtE,QAAI,CAACE,IAAG,WAAW,QAAQ,GAAG;AAC5B;AAAA,IACF;AAEA,UAAM,iBAAiBA,IAAG,aAAa,QAAQ,EAAE,SAAS;AAE1D,UAAM,kBAAkB,MAAM;AAC5B,YAAM,MAAM,eAAe;AAAA,QACzB;AAAA,QACA;AAAA,MACF;AAEA,UAAI,OAAO,SAAS,OAAO,GAAG;AAC5B,eAAO,IAAI,QAAQ,mBAAmB,mBAAmB;AAAA,MAC3D,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,GAAG;AACH,WAAOA,IAAG,UAAU,QAAQ,cAAc;AAAA,EAC5C;AAAA,EAEA,MAAM,yBAAyB,SAAsC;AACnE,UAAM,EAAE,QAAQ,IAAI,OAAO,OAAO;AAClC,UAAM,EAAE,KAAK,OAAO,IAAI,OAAO,OAAO;AACtC,UAAM,EAAE,YAAY,IAAI;AAExB,YACE,MAAM,QAAQ;AAAA,MACZ,QAAQ;AAAA,QAAI,OAAO,WACjB,QAAQ;AAAA,UACN,QAAQ,IAAI,OAAO,QAAQ;AACzB,kBAAM,UAAU,OAAO,cAAc;AACrC,kBAAM,MAAM,QACT,QAAQ,IAAI,MAAM,KAAK,IAAI,MAAM,GAAG,EACpC,QAAQ,iBAAiB,YAAY;AACxC,kBAAM,MAAM,QAAQ,GAAG;AACvB,gBAAI,CAACA,IAAG,WAAW,GAAG,GAAG;AACvB,cAAAA,IAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,YACvC;AACA,oBAAQ;AAAA,cACN;AAAA,cACA,MAAM,KAAK,IAAI,QAAQ,cAAc,KAAK,EAAE,CAAC;AAAA,YAC/C;AACA,kBAAM,KAAK,gCAAgC,SAAS,GAAG;AACvD,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,GACA,KAAK;AAAA,EACT;AAAA,EAEA,MAAM,sBAAkD;AACtD,UAAM,eAA4B;AAAA;AAAA,MAEhC,QAAQ,OAAO,cAAc;AAAA,MAC7B,OAAO,OAAO,cAAc;AAAA,MAC5B,WAAW,OAAO,cAAc;AAAA,MAChC,WAAW,OAAO,cAAc;AAAA;AAAA,MAEhC,OAAO,OAAO,cAAc;AAAA,IAC9B;AAEA,UAAM,aACJ,MAAM,QAAQ;AAAA,MACZ,OAAO,QAAQ,YAAY,EAAE,IAAI,OAAO,CAAC,WAAW,OAAO,MAAM;AAC/D,eAAO,UAAU,OAAO;AAAA,MAC1B,CAAC;AAAA,IACH,GAEC,KAAK,EACL,KAAK;AAER,UAAM,gBAGA,MAAM,QAAQ;AAAA,MAClB,UAAU,IAAI,OAAO,aAAa;AAChC,eAAO;AAAA,UACL,MAAM,SAAS,UAAU,OAAO,YAAY,MAAM;AAAA,UAClD,UAAU,MAAM,KAAK,kBAAkB,QAAQ;AAAA,QACjD;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,uBAAmD;AACvD,QAAIA,IAAG,WAAW,KAAK,aAAa,MAAM,OAAO;AAC/C,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,oBAAqB,MAAMA,IAAG;AAAA,MAClC,KAAK;AAAA,IACP;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,WAA6C;AAC/D,UAAMA,IAAG,UAAU,KAAK,eAAe,WAAW;AAAA,MAChD,QAAQ;AAAA,IACV,CAAC;AACD,YAAQ,IAAI,kBAAkB,KAAK,aAAa;AAAA,EAClD;AAAA,EAEA,MAAM,kBAAkB,UAAmC;AACzD,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,YAAM,OAAO,OAAO,WAAW,MAAM;AACrC,YAAM,QAAQA,IAAG,iBAAiB,QAAQ;AAC1C,YAAM,GAAG,SAAS,MAAM;AACxB,YAAM,GAAG,QAAQ,SAAU,OAAY;AACrC,aAAK,OAAO,KAAK;AAAA,MACnB,CAAC;AACD,YAAM,GAAG,SAAS,WAAY;AAC5B,gBAAQ,KAAK,OAAO,KAAK,CAAC;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,UAAkB;AACvC,UAAM,aAAa,GAAG;AAAA,MACpB;AAAA,MACAA,IAAG,aAAa,QAAQ,EAAE,SAAS;AAAA,MACnC,GAAG,aAAa;AAAA,IAClB;AAEA,UAAM,UAAmD,CAAC;AAC1D,QAAI,YAAoB;AACxB,QAAI,aAAqB;AACzB,UAAM,UAAU,CAAC,SAAkB;AACjC,UAAI,GAAG,mBAAmB,IAAI,GAAG;AAC/B,YAAI,KAAK,QAAQ,GAAG,aAAa,KAAK,IAAI,GAAG;AAC3C,sBAAY,KAAK,KAAK,YAAY,SAAS,EAAE,QAAQ,UAAU,EAAE;AAAA,QACnE;AAAA,MACF;AACA,UAAI,GAAG,oBAAoB,IAAI,GAAG;AAChC,YAAI,GAAG,aAAa,KAAK,IAAI,GAAG;AAC9B,uBAAa,KAAK,KAAK,YAAY,SAAS;AAAA,QAC9C;AAEA,cAAM,kBACJ,KAAK,kBAAkB,CAAC,GACxB,IAAI,CAAC,cAAc;AACnB,gBAAM,KAAK;AAEX,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,IAAI,GAAG,KAAK,YAAY,SAAS;AAAA,YACjC,YAAY,GAAG,aACX,KAAK,gBAAgB,GAAG,UAAU,IAClC;AAAA,UACN;AAAA,QACF,CAAC;AACD,cAAM,aAAyB,KAAK,WAAW;AAAA,UAC7C,CAAC,UAAU,UAAU;AACnB,kBAAM,aAAa,KAAK,UAAU,SAAS,aAAa,UAAU;AAIlE,mBAAO,KAAK;AAAA,cACV;AAAA,gBACE,MAAM,SAAS;AAAA,gBACf,MAAM,SAAS;AAAA,gBACf,UACE,SAAS,kBAAkB,UAC3B,SAAS,gBAAgB;AAAA,gBAC3B;AAAA,cACF;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,YAAI,KAAK,SAAS,QAAW;AAC3B,gBAAM,IAAI;AAAA,YACR,4FAAsB,SAAS,IAAI,UAAU;AAAA,UAC/C;AAAA,QACF;AACA,cAAM,aAAa,KAAK,gBAAgB,KAAK,IAAK;AAElD,gBAAQ,KAAK;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,SAAG,aAAa,MAAM,OAAO;AAAA,IAC/B;AACA,YAAQ,UAAU;AAElB,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC;AAAA,IACV;AAGA,UAAM,mBAAmB,eAAe,OAAO,CAACN,SAAQ;AACtD,aAAO,QAAQ;AAAA,QACb,CAAC,WACC,OAAO,cAAcA,KAAI,aACzB,OAAO,eAAeA,KAAI;AAAA,MAC9B;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,iBAAiB,IAAI,CAACA,SAAQ;AACjD,YAAM,cAAc,QAAQ;AAAA,QAC1B,CAAC,WACC,OAAO,cAAcA,KAAI,aACzB,OAAO,eAAeA,KAAI;AAAA,MAC9B;AACA,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,gBAAgB,YAAa;AAAA,QAC7B,YAAY,YAAa;AAAA,QACzB,YAAY,YAAa;AAAA,MAC3B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,UAAqC;AACnD,YAAQ,UAAU,MAAM;AAAA,MACtB,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,GAAG,WAAW;AACjB,cAAM,UAAW,SAAgC;AACjD,YAAI,GAAG,gBAAgB,OAAO,GAAG;AAC/B,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,QAAQ;AAAA,UACjB;AAAA,QACF,WAAW,GAAG,iBAAiB,OAAO,GAAG;AACvC,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,OAAO,QAAQ,IAAI;AAAA,UAC5B;AAAA,QACF,OAAO;AACL,cAAI,QAAQ,SAAS,GAAG,WAAW,aAAa;AAC9C,mBAAO;AAAA,UACT,WAAW,QAAQ,SAAS,GAAG,WAAW,kBAAkB;AAC1D,mBAAO;AAAA,UACT,WAAW,QAAQ,SAAS,GAAG,WAAW,aAAa;AACrD,mBAAO;AAAA,UACT,WAAW,QAAQ,SAAS,GAAG,WAAW,cAAc;AACtD,mBAAO;AAAA,UACT;AACA,gBAAM,IAAI,MAAM,+CAAY;AAAA,QAC9B;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,cAAM,UAAU;AAChB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,cAAc,KAAK,gBAAgB,QAAQ,WAAW;AAAA,QACxD;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,cAAM,cAAc;AACpB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,OAAO,YAAY,QAAQ,IAAI,CAAC,WAAW;AACzC,gBAAI,GAAG,4BAA4B,MAAM,GAAG;AAC1C,oBAAM,MAAM,KAAK,gBAAgB;AAAA,gBAC/B,MAAM,OAAO,WAAW,CAAC,EAAE;AAAA,gBAC3B,MAAM,OAAO,WAAW,CAAC,EAAE;AAAA,cAC7B,CAAC;AAED,qBAAO,KAAK,gBAAgB;AAAA,gBAC1B,MAAM;AAAA,kBACJ,aAAa,IAAI,IAAI,IAAI,GAAG,IAAI,WAAW,MAAM,EAAE,KACjD,IAAI,IACN;AAAA,gBACF;AAAA,gBACA,MAAM,OAAO;AAAA,cACf,CAAC;AAAA,YACH,OAAO;AACL,qBAAO,KAAK,gBAAgB;AAAA,gBAC1B,MAAO,OAAgC;AAAA,gBACvC,MAAO,OAAgC;AAAA,gBACvC,UACG,OAAgC,kBAAkB;AAAA,cACvD,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,IACG,SAAkC,SACnC,YAAY,SAAS;AAAA,UACvB,MAAO,SAAkC,eAAe;AAAA,YACtD,CAAC,YAAY,KAAK,gBAAgB,OAAO;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,OAAQ,SAA8B,MAAM;AAAA,YAAI,CAAC,SAC/C,KAAK,gBAAgB,IAAI;AAAA,UAC3B;AAAA,QACF;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,OAAQ,SAAqC,MAAM;AAAA,YAAI,CAAC,SACtD,KAAK,gBAAgB,IAAI;AAAA,UAC3B;AAAA,QACF;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ,KAAK;AAAA,YACV,SAAsC;AAAA,UACzC;AAAA,UACA,OAAO,KAAK;AAAA,YACT,SAAsC;AAAA,UACzC;AAAA,QACF;AAAA,MACF,KAAK,GAAG,WAAW;AACjB,YAAI,GAAG,gBAAgB,QAAQ,GAAG;AAChC,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,UAAU,SAAS,SAAS;AAAA,cAAI,CAAC,SAC/B,KAAK,gBAAgB,IAAI;AAAA,YAC3B;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,cAAM,IAAI,MAAM,oBAAoB;AAAA,IACxC;AAEA,YAAQ,MAAM,QAAQ;AACtB,UAAM,IAAI,MAAM,yCAAqB,SAAS,IAAI,EAAE;AAAA,EACtD;AAAA,EAEA,kBAAkB,CAChB,UAMA,QAAgB,MACH;AACb,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,KAAK,gBAAgB,SAAS,IAAI;AAE/C,QAAI,SAAS,QAAW;AACtB,cAAQ,MAAM,EAAE,MAAM,MAAM,SAAS,CAAC;AAAA,IACxC;AAEA,UAAM,SAAmB;AAAA,MACvB,MAAM,KAAK,cAAc,KAAK,YAAY,SAAS,IAAI,WAAW,KAAK;AAAA,MACvE;AAAA,MACA,UAAU,SAAS,aAAa;AAAA,MAChC,YAAY,UAAU;AAAA,IACxB;AAGA,QACE,GAAG,uBAAuB,IAAI,KAC9B,GAAG,oBAAoB,SAAS,IAAI,KACpC,GAAG,aAAa,SAAS,KAAK,QAAQ,GACtC;AACA,aAAO,OAAOI,YAAW,SAAS,SAAS,KAAK,SAAS,MAAM,IAAI;AAAA,IACrE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UACE,MACA,YACoB;AACpB,QAAI,SAAS,QAAW;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,GAAG,cAAc,EAAE,SAAS,GAAG,YAAY,SAAS,CAAC;AACrE,WAAO,QAAQ,UAAU,GAAG,SAAS,aAAa,MAAM,UAAU;AAAA,EACpE;AAAA,EAEA,MAAM,eAAe;AACnB,UAAM,cAAcC,MAAK;AAAA,MACvB,OAAO;AAAA,MACP;AAAA,IACF;AAGA,UAAM,YAAY,MAAM,UAAU,WAAW;AAC7C,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,UAAU,IAAI,CAAC,aAAa,KAAK,iBAAiB,QAAQ,CAAC;AAAA,IAC7D;AACA,SAAK,OAAO,OAAO,KAAK;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,iBAA4D;AAChE,UAAM,cAAcA,MAAK;AAAA,MACvB,OAAO;AAAA,MACP;AAAA,IACF;AAGA,UAAM,aAAa,MAAM,UAAU,WAAW,GAAG,OAAO,CAACA,UAAS;AAGhE,YAAM,UAAUA,MAAK,QAAQ,UAAU,OAAO,EAAE,QAAQ,OAAO,KAAK;AACpE,aAAOC,IAAG,WAAW,OAAO;AAAA,IAC9B,CAAC;AACD,UAAM,UAAU,MAAM,eAAe,SAAS;AAC9C,UAAM,YAAY,QACf,IAAI,CAAC,EAAE,SAAS,MAAM,OAAO,QAAQ,QAAQ,CAAC,EAC9C,KAAK;AACR,SAAK,SAAS,OAAO;AAAA,MACnB,UAAU,OAAO,CAAC,CAAC,IAAI,MAAM,KAAK,SAAS,OAAO,CAAC;AAAA,IACrD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,cACJ,YAAqB,OAC8B;AACnD,QAAI,CAAC,aAAa,OAAO,KAAK,KAAK,KAAK,EAAE,SAAS,GAAG;AACpD,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,eAAe;AAAA,MACnBD,MAAK,KAAK,OAAO,aAAa,iCAAiC;AAAA,MAC/DA,MAAK,KAAK,OAAO,aAAa,qCAAqC;AAAA,IACrE;AAGA,UAAM,aACJ,MAAM,QAAQ,IAAI,aAAa,IAAI,CAAC,YAAY,UAAU,OAAO,CAAC,CAAC,GAElE,KAAK,EACL,OAAO,CAACA,UAAS;AAGhB,YAAM,UAAUA,MAAK,QAAQ,UAAU,OAAO,EAAE,QAAQ,OAAO,KAAK;AACpE,aAAOC,IAAG,WAAW,OAAO;AAAA,IAC9B,CAAC;AACH,UAAM,UAAU,MAAM,eAAe,WAAW,SAAS;AACzD,UAAM,YAAY,QACf,IAAI,CAAC,EAAE,SAAS,MAAM,OAAO,QAAQ,QAAQ,CAAC,EAC9C,KAAK;AACR,SAAK,QAAQ,OAAO;AAAA,MAClB,UAAU,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,aAAaP,GAAE,OAAO;AAAA,IACpD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,KAA4B;AACtC,QAAI,QAAQ,UAAU;AACpB,aAAO,IAAI,iBAAiB;AAAA,IAC9B,WAAW,QAAQ,cAAc;AAC/B,aAAO,IAAI,qBAAqB;AAAA,IAClC,WAAW,QAAQ,aAAa;AAC9B,aAAO,IAAI,oBAAoB;AAAA,IACjC,WAAW,QAAQ,iBAAiB;AAClC,aAAO,IAAI,wBAAwB;AAAA,IACrC,WAAW,QAAQ,kBAAkB;AACnC,aAAO,IAAI,yBAAyB;AAAA,IACtC,WAAW,QAAQ,SAAS;AAC1B,aAAO,IAAI,gBAAgB;AAAA,IAC7B,WAAW,QAAQ,cAAc;AAC/B,aAAO,IAAI,qBAAqB;AAAA,IAClC,WAAW,QAAQ,WAAW;AAC5B,aAAO,IAAI,kBAAkB;AAAA,IAC/B,WAAW,QAAQ,aAAa;AAC9B,aAAO,IAAI,oBAAoB;AAAA,IACjC,WAAW,QAAQ,qBAAqB;AACtC,aAAO,IAAI,4BAA4B;AAAA,IACzC,WAAW,QAAQ,qBAAqB;AACtC,aAAO,IAAI,4BAA4B;AAAA,IACzC,WAAW,QAAQ,aAAa;AAC9B,aAAO,IAAI,oBAAoB;AAAA,IACjC,WAAW,QAAQ,sBAAsB;AACvC,aAAO,IAAI,6BAA6B;AAAA,IAC1C,WAAW,QAAQ,wBAAwB;AACzC,aAAO,IAAI,+BAA+B;AAAA,IAC5C,WAAW,QAAQ,qBAAqB;AACtC,aAAO,IAAI,4BAA4B;AAAA,IACzC,WAAW,QAAQ,uBAAuB;AACxC,aAAO,IAAI,8BAA8B;AAAA,IAC3C,WAAW,QAAQ,wBAAwB;AACzC,aAAO,IAAI,+BAA+B;AAAA,IAC5C,WAAW,QAAQ,oBAAoB;AACrC,aAAO,IAAI,2BAA2B;AAAA,IACxC,OAAO;AACL,YAAM,IAAI,oBAAoB,gDAAa,GAAG,EAAE;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,KACA,SACwB;AACxB,UAAM,WAAqB,KAAK,YAAY,GAAG;AAE/C,QAAI,QAAmB,CAAC;AACxB,QACE,CAAC,WAAW,kBAAkB,SAAS,aAAa,WAAW,EAAE;AAAA,MAC/D;AAAA,IACF,GACA;AACA,YAAM,WAAY,QAAuC;AAEzD,UAAI,QAAQ,aAAa,QAAQ,kBAAkB;AAEjD,cAAM,SAAS,cAAc,IAAI,QAAS;AAC1C,cAAM,cAAc,GAAGM,MAAK;AAAA,UAC1B,OAAO;AAAA,UACP;AAAA,QACF,CAAC,IAAI,OAAO,MAAM,EAAE,IAAI,OAAO,MAAM,EAAE;AACvC,gBAAQ,CAAC,MAAM,KAAK,iBAAiB,WAAW,CAAC;AAAA,MACnD,WAAW,QAAQ,eAAe,QAAQ,SAAS;AAEjD,cAAM,cAAc,MAAM,KAAK,eAAe,UAAU,GAAG;AAC3D,cAAM,oBAAoB,MAAM,KAAK;AAAA,UACnC,GAAG,QAAQ;AAAA,QACb;AACA,cAAM,iBAAiB,KAAK,uBAAuB,iBAAiB;AACpE,gBAAQ,CAAC,aAAa,cAAc;AAAA,MACtC,WAAW,QAAQ,aAAa;AAE9B,cAAM,oBAAoB,MAAM,KAAK;AAAA,UACnC,GAAG,QAAQ;AAAA,QACb;AACA,cAAM,iBAAiB,KAAK,uBAAuB,iBAAiB;AACpE,gBAAQ,CAAC,cAAc;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,SAAS,OAAO,SAAS,GAAG,KAAK;AACxD,UAAM,WAAW,MAAM,KAAK,wBAAwB,KAAK,QAAQ;AAEjE,QAAI,sBAAqC,CAAC;AAC1C,QAAI,SAAS,cAAc;AACzB,6BACE,MAAM,QAAQ;AAAA,QACZ,SAAS,aAAa,IAAI,CAAC,EAAE,KAAAa,MAAK,SAAAC,SAAQ,MAAM;AAC9C,iBAAO,KAAK,eAAeD,MAAKC,QAAO;AAAA,QACzC,CAAC;AAAA,MACH,GACA,KAAK;AAAA,IACT;AAEA,WAAO,CAAC,UAAU,GAAG,mBAAmB;AAAA,EAC1C;AAAA,EAEA,MAAM,wBACJ,KACA,QACsB;AACtB,UAAM,EAAE,QAAQ,MAAM,UAAU,MAAM,YAAY,cAAc,IAAI;AAGpE,UAAM,aAAa,WAChB;AAAA,MACC,CAAC,GAAG,cAAc;AAChB,cAAM,aAAa,cAAc,cAAc,SAAS;AACxD,YAAI,aAAa;AACjB,YAAI,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;AACxD,uBAAa;AAAA,YACXd,MAAK,SAASA,MAAK,QAAQ,QAAQ,GAAG,UAAU;AAAA,YAChD,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,OAAO,OAAO,CAAC;AAAA,UAC/C;AAAA,QACF;AAGA,cAAM,YAAY,EAAE;AAAA,UAClB,CAAC,cAAc,UAAU,SAAS;AAAA,QACpC;AACA,YAAI,WAAW;AACb,oBAAU,OAAOJ,IAAE,KAAK,UAAU,KAAK,OAAO,SAAS,CAAC;AAAA,QAC1D,OAAO;AACL,YAAE,KAAK;AAAA,YACL,MAAM,CAAC,SAAS;AAAA,YAChB,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IAIH,EAEC;AAAA,MACC,CAAC,cACC,SAAS,SAAS,UAAU,KAAK,QAAQ,MAAM,EAAE,IAAI,KAAK,MAAM;AAAA,IACpE;AAGF,UAAM,SAAS;AAAA,MACb,GAAI,iBAAiB,CAAC;AAAA,MACtB,GAAG,WAAW;AAAA,QACZ,CAAC,cACC,YAAY,UAAU,KAAK,KAAK,IAAI,CAAC,YAAY,UAAU,IAAI;AAAA,MACnE;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,YAAY,OAAO,YAAY;AACnC,UAAI,QAAQ,kBAAkB;AAC5B,eAAO,CAAC,QAAQ,IAAI,EAAE,KAAK,MAAM;AAAA,MACnC,OAAO;AACL,eAAOgB,UAAS,OAAO,CAAC,QAAQ,IAAI,EAAE,KAAK,MAAM,GAAG;AAAA,UAClD,QAAQ,QAAQ,WAAW,SAAS;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AAEH,WAAO;AAAA,MACL,MAAM,SAAS,MAAM;AAAA,MACrB,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,aAA6C;AACjE,UAAM,EAAE,QAAQ,IAAI,OAAO,OAAO;AAClC,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,WAAW,GAAG,OAAO,WAAW,IAAI,YAAY,IAAI;AAE1D,UAAM,eAAehB,IAAE;AAAA,MACrB,QAAQ,IAAI,CAAC,WAAW,SAAS,QAAQ,aAAa,IAAI,MAAM,GAAG,CAAC;AAAA,IACtE;AACA,WAAO,MAAM,QAAQ;AAAA,MACnB,aAAa,IAAI,OAAO,gBAAgB;AACtC,cAAM,MAAMI,MAAK,QAAQ,WAAW;AACpC,YAAIC,IAAG,WAAW,GAAG,MAAM,OAAO;AAChC,UAAAA,IAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,QACvC;AACA,QAAAA,IAAG,cAAc,aAAa,YAAY,IAAI;AAC9C,gBAAQ;AAAA,UACN;AAAA,UACA,MAAM,KAAK,YAAY,QAAQ,cAAc,KAAK,EAAE,CAAC;AAAA,QACvD;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,KACA,iBACA,kBACA;AACA,UAAM,kBAAkB;AAAA,MACtB,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAGA,UAAM,OAAsB,CAAC,GAAG;AAGhC,UAAM,gBACJ,MAAM,QAAQ;AAAA,MACZ,KAAK,IAAI,OAAOY,SAAQ;AACtB,eAAO,MAAM,KAAK,eAAeA,MAAK,eAAe;AAAA,MACvD,CAAC;AAAA,IACH,GACA,KAAK;AAEP,UAAM,wBAAuC,MAAM;AACjD,UAAI,gBAAgB,cAAc,MAAM;AACtC,eAAO;AAAA,MACT,OAAO;AACL,eAAO,aAAa,OAAO,CAAC,gBAAgB;AAC1C,gBAAM,EAAE,QAAQ,IAAI,OAAO,OAAO;AAClC,gBAAM,WAAW,GAAG,OAAO,WAAW,IAAI,YAAY,IAAI;AAC1D,gBAAM,eAAe,QAAQ;AAAA,YAAI,CAAC,WAChC,SAAS,QAAQ,aAAa,IAAI,MAAM,GAAG;AAAA,UAC7C;AACA,iBAAO,aAAa;AAAA,YAClB,CAAC,YAAYZ,IAAG,WAAW,OAAO,MAAM;AAAA,UAC1C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AACH,QAAI,qBAAqB,WAAW,GAAG;AACrC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO,QAAQ;AAAA,MACb,qBAAqB;AAAA,QAAI,CAAC,gBACxB,KAAK,gBAAgB,WAAW;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBACE,UACA,aACA,QAC0D;AAC1D,UAAM,EAAE,QAAQ,MAAM,QAAQ,IAAI,KAAK;AAAA,MACrC;AAAA,IACF,EAAE,iBAAiB,cAAc,eAAe,QAAQ,GAAG,MAAM;AAEjE,UAAM,WAAWD,MAAK,KAAK,OAAO,aAAa,QAAQ,OAAO;AAC9D,UAAM,UAAUA,MAAK,KAAK,QAAQ,OAAO;AACzC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAUC,IAAG,WAAW,QAAQ;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,YACE,UACA,OAG4C;AAC5C,UAAM,OAAsB,YAAY;AACxC,UAAM,QAAQ,cAAc,eAAe,QAAQ;AACnD,UAAM,YAAY,OAAO,KAAK,KAAK,EAAE;AAAA,MACnC,CAAC,SAAS,SAAS,MAAM;AAAA,IAC3B;AAEA,WAAO,KAAK;AAAA,MACV,CAAC,QAAQ,QAAQ;AACf,cAAM,MAAM,KAAK,YAAY,GAAG;AAChC,YAAI,IAAI,WAAW,YAAY,GAAG;AAChC,oBAAU,IAAI,CAAC,gBAAgB;AAC7B,kBAAM,EAAE,QAAAc,SAAQ,MAAMC,GAAE,IAAI,IAAI;AAAA,cAC9B;AAAA,cACA;AAAA,YACF;AACA,mBAAO,GAAG,GAAG,KAAK,WAAW,EAAE,IAAIf,IAAG;AAAA,cACpCD,MAAK,KAAK,OAAO,aAAae,SAAQC,EAAC;AAAA,YACzC;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAEA,cAAM,EAAE,QAAQ,MAAM,EAAE,IAAI,IAAI,iBAAiB,KAAK;AACtD,cAAM,EAAE,QAAQ,IAAI,OAAO,OAAO;AAClC,YAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,kBAAQ,IAAI,CAAC,MAAM;AACjB,mBAAO,GAAG,GAAG,KAAK,CAAC,EAAE,IAAIf,IAAG;AAAA,cAC1BD,MAAK,KAAK,OAAO,aAAa,OAAO,QAAQ,WAAW,CAAC,GAAG,CAAC;AAAA,YAC/D;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,GAAG,IAAIC,IAAG,WAAWD,MAAK,KAAK,OAAO,aAAa,QAAQ,CAAC,CAAC;AAAA,QACtE;AAEA,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,WAA0C;AAC7D,UAAM,aAAa,cAAc,cAAc,SAAS;AACxD,UAAM,gBAAgBA,MAAK;AAAA,MACzB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IACf;AACA,UAAM,aAAa,OAAOA,MAAK,SAAS,WAAW,aAAa;AAChE,UAAM,WAAW,MAAM,OAAO;AAE9B,QAAI,CAAC,SAAS,SAAS,GAAG;AACxB,YAAM,IAAI,MAAM,mDAAqB,SAAS,EAAE;AAAA,IAClD;AACA,WAAO,SAAS,SAAS,EAAE,SAAS,SAAS;AAAA,EAC/C;AAAA,EAEA,MAAM,kBAAkB,UAAiD;AACvE,QAAI,SAAS,aAAa,SAAS;AACjC,aAAO,KAAK,cAAc,SAAS,IAAI;AAAA,IACzC,WAAW,SAAS,aAAa,SAAS;AACxC,UAAI,SAAS,SAAS,QAAW;AAC/B,cAAM,IAAI,MAAM;AAAA,MAClB,WAAW,SAAS,SAAS,SAAS,GAAG;AACvC,gBACE,MAAM,KAAK,kBAAkB;AAAA,UAC3B,GAAG;AAAA,UACH,UAAU;AAAA,QACZ,CAAC,GACD,MAAM;AAAA,MACV,OAAO;AACL,cAAM,YAAY,MAAM,KAAK,cAAc,SAAS,IAAI;AACxD,YAAI,SAAS,KAAK,aAAa,MAAM;AACnC,iBAAON,GAAE,MAAM,SAAS,EAAE,SAAS;AAAA,QACrC,OAAO;AACL,iBAAOA,GAAE,MAAM,SAAS;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,WAAW,SAAS,aAAa,UAAU;AACzC,YAAM,MAAM,MAAM,SAAS,SAAS;AAAA,QAClC,OAAO,SAAS,kBAAkB;AAChC,gBAAM,SAAS,MAAM;AACrB,iBAAO,cAAc,KAAM,IAAI,IAC7B,MAAM,KAAK,kBAAkB,aAAa;AAC5C,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MACH;AAEA,UAAI,SAAS,MAAM,aAAa,MAAM;AACpC,eAAOA,GAAE,OAAO,GAAG,EAAE,SAAS;AAAA,MAChC,OAAO;AACL,eAAOA,GAAE,OAAO,GAAG;AAAA,MACrB;AAAA,IACF,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM,cAAc,MAAyC;AAC3D,QAAI,UAAwBA,GAAE,QAAQ;AACtC,QAAI,cAAc,IAAI,GAAG;AACvB,gBAAUA,GAAE,OAAO,EAAE,IAAI;AAAA,IAC3B,WAAW,iBAAiB,IAAI,GAAG;AACjC,gBAAUA,GAAE,OAAO;AAAA,IACrB,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAUA,GAAE,OAAO,EAAE,IAAI,kBAAkB,KAAK,QAAQ,CAAC;AAAA,IAC3D,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAU,MAAM,KAAK,eAAe,KAAK,EAAE;AAAA,IAC7C,WAAW,aAAa,IAAI,GAAG;AAC7B,gBAAUA,GAAE,OAAO,EAAE,IAAI,KAAK,MAAM;AAAA,IACtC,WAAW,YAAY,IAAI,KAAK,aAAa,IAAI,GAAG;AAClD,gBAAUA,GAAE,OAAO;AAAA,IACrB,WAAW,cAAc,IAAI,GAAG;AAC9B,gBAAUA,GAAE,OAAO;AAAA,IACrB,WAAW,cAAc,IAAI,GAAG;AAC9B,gBAAUA,GAAE,QAAQ;AAAA,IACtB,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAUA,GAAE,OAAO,EAAE,OAAO,EAAE;AAAA,IAChC,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAUA,GAAE,OAAO,EAAE,OAAO,CAAC;AAAA,IAC/B,WAAW,eAAe,IAAI,GAAG;AAC/B,gBAAU;AAAA,IACZ,WAAW,gBAAgB,IAAI,GAAG;AAChC,gBAAU;AAAA,IACZ,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAU,MAAM,KAAK,eAAe,KAAK,EAAE;AAAA,IAC7C,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAUA,GAAE,OAAO,EAAE,KAAK;AAAA,IAC5B,WAAW,cAAc,IAAI,GAAG;AAC9B,gBAAU,MAAM,KAAK,eAAe,KAAK,EAAE;AAAA,IAC7C,WAAW,eAAe,IAAI,GAAG;AAC/B,UACE,2BAA2B,IAAI,KAC9B,uBAAuB,IAAI,KAAK,KAAK,eACtC;AACA,kBAAUA,GAAE,OAAO,EAAE,IAAI;AAAA,MAC3B;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,8EAA4B,IAAI,GAAG;AAAA,IACrD;AAEA,QAAK,KAAgC,UAAU;AAC7C,gBAAW,QAAwB,YAAY;AAAA,IACjD;AACA,QAAI,KAAK,UAAU;AACjB,gBAAU,QAAQ,SAAS;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,kBACE,KACA,SAC6B;AAC7B,QAAI,mBAAmBA,GAAE,WAAW;AAClC,UAAI,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,OAAO,GAAG;AAChD,eAAO;AAAA,MACT,WAAW,QAAQ,gBAAgB,qBAAqB;AACtD,eAAO;AAAA,MACT,WAAW,IAAI,SAAS,MAAM,GAAG;AAC/B,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,WAAW,mBAAmBA,GAAE,WAAW;AACzC,UAAI,QAAQ,MAAM;AAChB,eAAO;AAAA,MACT,WAAW,IAAI,SAAS,KAAK,GAAG;AAC9B,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,SAAS;AACvC,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,WAAW;AACzC,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,UAAU,mBAAmBA,GAAE,YAAY;AACzE,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,UAAU;AACxC,aAAO;AAAA,IACT,WAAW,mBAAmBA,GAAE,YAAY;AAC1C,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,0CAAY,GAAG,IAAI,QAAQ,KAAK,QAAQ,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,uBACE,SACA,UAAkB,QACH;AACf,UAAM,MAAM;AAAA,MACV,MAAM;AAAA,MACN,OAAOK,YAAW,SAAS,SAAS,KAAK;AAAA,MACzC;AAAA,IACF;AACA,QAAI,mBAAmBL,GAAE,WAAW;AAClC,YAAM,aAAa,OAAO,KAAK,QAAQ,KAAK;AAC5C,YAAM,WAAW,WAAW,IAAI,CAAC,QAAQ;AACvC,cAAM,YAAY,QAAQ,MAAM,GAAG;AACnC,eAAO,KAAK,uBAAuB,WAAW,GAAG;AAAA,MACnD,CAAC;AACD,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,QACZ;AAAA,MACF;AAAA,IACF,WAAW,mBAAmBA,GAAE,UAAU;AACxC,YAAM,YAAY,QAAQ,KAAK;AAC/B,UAAI,qBAAqBA,GAAE,aAAa,QAAQ,SAAS,QAAQ,GAAG;AAClE,eAAO;AAAA,UACL,GAAG;AAAA,UACH,YAAY;AAAA,QACd;AAAA,MACF;AACA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,QACZ,SAAS,KAAK,uBAAuB,WAAW,OAAO;AAAA,MACzD;AAAA,IACF,WAAW,mBAAmBA,GAAE,UAAU;AACxC,YAAM,cAAc,QAAQ,KAAK,QAAQ;AAAA,QAAI,CAAC,QAC5C,KAAK,uBAAuB,KAAK,OAAO;AAAA,MAC1C;AAEA,aAAO,YAAY,CAAC;AAAA,IACtB,WAAW,mBAAmBA,GAAE,aAAa;AAC3C,aAAO;AAAA,QACL,GAAG,KAAK,uBAAuB,QAAQ,KAAK,WAAW,OAAO;AAAA,QAC9D,UAAU;AAAA,MACZ;AAAA,IACF,WAAW,mBAAmBA,GAAE,aAAa;AAC3C,aAAO;AAAA,QACL,GAAG,KAAK,uBAAuB,QAAQ,KAAK,WAAW,OAAO;AAAA,QAC9D,UAAU;AAAA,MACZ;AAAA,IACF,OAAO;AACL,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY,KAAK,kBAAkB,SAAS,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,UACA,WACwB;AACxB,UAAM,SAAS,MAAM,cAAc,IAAI,QAAQ;AAC/C,UAAM,UAAU,OAAO,QAAQ,SAAS;AACxC,QAAI,YAAY,QAAW;AACzB,YAAM,IAAI,4BAA4B,0CAAiB;AAAA,IACzD;AACA,UAAM,YAAY,OAAO,sBAAsB,OAAO;AACtD,UAAM,eAA+B;AAAA,MACnC,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAEA,UAAM,iBAAkB,MAAM,KAAK;AAAA,MACjC;AAAA,IACF;AAEA,UAAM,cAAc,KAAK,uBAAuB,cAAc;AAC9D,gBAAY,WAAW,YAAY,SAAU,IAAI,CAAC,UAAU;AAC1D,UAAI,MAAM,eAAe,UAAU;AACjC,cAAM,YAAY,MAAM,SAAU;AAAA,UAAK,CAAC,OACtC,CAAC,SAAS,MAAM,EAAE,SAAS,GAAG,IAAI;AAAA,QACpC;AACA,YAAI,WAAW;AACb,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,YAAY;AAAA,YACZ,QAAQ;AAAA,cACN,QAAQ,UAAU;AAAA,YACpB;AAAA,UACF;AAAA,QACF,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF,WACE,MAAM,eAAe,WACrB,MAAM,WACN,MAAM,QAAQ,eAAe,UAC7B;AACA,cAAM,YAAY,MAAM,QAAS,SAAU;AAAA,UAAK,CAAC,OAC/C,CAAC,SAAS,MAAM,EAAE,SAAS,GAAG,IAAI;AAAA,QACpC;AACA,YAAI,WAAW;AACb,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,SAAS;AAAA,cACP,GAAG,MAAM;AAAA,cACT,YAAY;AAAA,cACZ,QAAQ;AAAA,gBACN,QAAQ,UAAU;AAAA,cACpB;AAAA,YACF;AAAA,UACF;AAAA,QACF,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,MACA;AACA,QAAI,CAAC,sBAAsB,KAAK,KAAK,QAAQ,GAAG;AAC9C,YAAM,IAAI,oBAAoB,6EAAgC;AAAA,IAChE;AAEA,UAAM,KAAK,iBAAiB,UAAU,IAAI;AAG1C,UAAM,cAAc,OAAO;AAG3B,UAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,sBAAsB;AAAA,MAC3B,GAAI,KAAK,aAAa,SAClB;AAAA,QACE,KAAK,iBAAiB,cAAc;AAAA,UAClC,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,UAAmD;AACjE,UAAM,SAAS,cAAc,IAAI,QAAQ;AAEzC,UAAM,YAAY,MAAM;AACtB,UAAI,OAAO,UAAU;AACnB,eAAO;AAAA,UACL,GAAG,OAAO,WAAW,oBAAoB,OAAO,MAAM,QAAQ,IAAI,OAAO,MAAM,EAAE;AAAA,QACnF;AAAA,MACF,OAAO;AACL,eAAO;AAAA,UACL,GAAG,OAAO,WAAW,oBAAoB,OAAO,MAAM,EAAE;AAAA,UACxD,GAAG,OAAO,WAAW,qBAAqB,OAAO,MAAM,EAAE;AAAA,UACzD,GAAG,OAAO,OAAO,KAAK,QACnB,IAAI,CAAC,WAAW;AAAA,YACf,GAAG,OAAO,WAAW,IAAI,MAAM,iBAAiB,OAAO,MAAM,EAAE;AAAA,UACjE,CAAC,EACA,KAAK;AAAA,QACV;AAAA,MACF;AAAA,IACF,GAAG;AAEH,qBAAiB,WAAW,UAAU;AACpC,UAAIO,IAAG,WAAW,OAAO,GAAG;AAC1B,gBAAQ,IAAI,MAAM,IAAI,UAAU,OAAO,EAAE,CAAC;AAC1C,iBAAS,UAAU,OAAO,EAAE;AAAA,MAC9B,OAAO;AACL,gBAAQ,IAAI,MAAM,OAAO,cAAc,OAAO,EAAE,CAAC;AAAA,MACnD;AAAA,IACF;AAGA,UAAM,cAAc,OAAO;AAE3B,WAAO,EAAE,SAAS;AAAA,EACpB;AACF;;;AgCt5CO,SAAS,UAAmB;AACjC,SAAO,QAAQ,IAAI,OAAO,UAAa,QAAQ,IAAI,OAAO;AAC5D;AACO,SAAS,WAAoB;AAClC,SAAO,QAAQ,IAAI,OAAO;AAC5B;AACO,SAAS,aAAsB;AACpC,SAAO,QAAQ,IAAI,OAAO;AAC5B;AACO,SAAS,iBAA0B;AACxC,SAAO,QAAQ,IAAI,cAAc;AACnC;AACO,SAAS,gBAAyB;AACvC,SAAO,SAAS,KAAK,QAAQ,IAAI,aAAa;AAChD;AACO,SAAS,YAAqB;AACnC,SAAO,SAAS,KAAK,QAAQ,IAAI,aAAa;AAChD;AACO,SAAS,eAAwB;AACtC,SAAO,SAAS,KAAK,QAAQ,IAAI,aAAa;AAChD;AACO,SAAS,SAAkB;AAChC,SAAO,QAAQ,KAAK,QAAQ,IAAI,aAAa;AAC/C;;;ACvBA,SAAS,KAAAP,UAAS;AAOX,SAAS,iBAAiB,OAAsC;AACrE,SAAO,MAAM,OAAO,IAAI,CAAC,UAAU;AACjC,UAAM,gBAAgB,MAAM,KAAK,IAAI,MAAM;AAC3C,UAAMM,QAAO,MAAM,KAAK,OAAO,CAAC,KAAK,KAAK,MAAM;AAC9C,UAAI,OAAO,QAAQ,UAAU;AAC3B,eAAO,GAAG,GAAG,IAAI,GAAG;AAAA,MACtB;AACA,aAAO,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG;AAAA,IACtC,GAAG,EAAE;AAEL,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,gBAAgB,MAAM,QAAQ,cAAc,MAAM,QAAQ;AAAA,QAC5E;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,wBAAwBM,KAAI,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,QACjE;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,2CAA2C,MAAM,YAC9D,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EACpD,KAAK,MAAM,CAAC;AAAA,QACjB;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,oBAAoB,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC9D;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,+BAA+B,MAAM,eAAe,OAC1D,IAAI,CAAC,MAAM,EAAE,OAAO,EACpB,KAAK,IAAI,CAAC;AAAA,QACf;AAAA,MAEF,KAAKA,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iCAAiC,MAAM,gBAAgB,OAC7D,IAAI,CAAC,MAAM,EAAE,OAAO,EACpB,KAAK,IAAI,CAAC;AAAA,QACf;AAAA,MAEF,KAAKA,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI;AAAA,QAClB;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,cAAM,iBAAiB,MAAM;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,oBAAoB,cAAc;AAAA,QACpD;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,IAAI,kBAAkB,KAAK,CAAC;AAAA,QAC9C;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,IAAI,kBAAkB,KAAK,CAAC;AAAA,QAC9C;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,GAAGM,KAAI,0BAA0B,MAAM,WAAW,SAAS,CAAC;AAAA,QACvE;AAAA,MAEF,KAAKN,GAAE,aAAa;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,MAAM,WAAW,GAAGM,KAAI;AAAA,QACnC;AAAA,MAEF;AACE,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,MAAM;AAAA,QACjB;AAAA,IACJ;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBACP,OACA;AACA,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,WACL,MAAM,QAAQ,YAAY,MAAM,YAAY,aAAa,WAC3D,IAAI,MAAM,OAAO,aAAa,MAAM,YAAY,IAAI,KAAK,GAAG;AAAA,IAE9D,KAAK;AACH,aAAO,WACL,MAAM,QACF,YACA,MAAM,YACJ,6BACA,cACR,IAAI,MAAM,QAAQ,SAAS,CAAC;AAAA,IAE9B,KAAK;AAAA,IACL,KAAK;AACH,aAAO,gBACL,MAAM,QAAQ,YAAY,MAAM,YAAY,aAAa,WAC3D,IAAI,MAAM,OAAO,QAAQ,MAAM,YAAY,IAAI,KAAK,GAAG;AAAA,IAEzD,KAAK;AACH,aAAO,WACL,MAAM,QAAQ,YAAY,MAAM,YAAY,gBAAgB,OAC9D,IAAI,qBAAqB,MAAM,OAAO,CAAC;AAAA,IAEzC;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,kBACP,OACA;AACA,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,WACL,MAAM,QAAQ,YAAY,MAAM,YAAY,YAAY,WAC1D,IAAI,MAAM,OAAO,aAAa,MAAM,YAAY,IAAI,KAAK,GAAG;AAAA,IAE9D,KAAK;AACH,aAAO,WACL,MAAM,QACF,YACA,MAAM,YACJ,0BACA,WACR,IAAI,MAAM,QAAQ,SAAS,CAAC;AAAA,IAE9B,KAAK;AAAA,IACL,KAAK;AACH,aAAO,gBACL,MAAM,QAAQ,YAAY,MAAM,YAAY,YAAY,YAC1D,IAAI,MAAM,OAAO,QAAQ,MAAM,YAAY,IAAI,KAAK,GAAG;AAAA,IAEzD,KAAK;AACH,aAAO,WACL,MAAM,QAAQ,YAAY,MAAM,YAAY,iBAAiB,QAC/D,IAAI,qBAAqB,MAAM,OAAO,CAAC;AAAA,IAEzC;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,qBAAqB,OAAgC;AAC5D,MAAI;AACF,QAAI,OAAO,UAAU,UAAU;AAC7B,UACE,QAAQ,OAAO,OAAO,gBAAgB,KACtC,QAAQ,OAAO,OAAO,gBAAgB,GACtC;AACA,eAAO,MAAM,SAAS;AAAA,MACxB;AAAA,IACF;AACA,WAAO,IAAI,KAAK,OAAO,KAAK,CAAC,EAAE,YAAY;AAAA,EAC7C,QAAQ;AACN,WAAO,MAAM,SAAS;AAAA,EACxB;AACF;;;AnCnHA,IAAM,cAAN,MAAkB;AAAA,EACT,gBAAyB;AAAA,EAExB,eAA8B;AAAA,EACtC,IAAI,YAAY,aAAqB;AACnC,SAAK,eAAe;AAAA,EACtB;AAAA,EACA,IAAI,cAAsB;AACxB,QAAI,KAAK,iBAAiB,MAAM;AAC9B,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,cAAsB;AACxB,WAAO,KAAK,YAAY,MAAMA,MAAK,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAKA,MAAK,GAAG;AAAA,EACpE;AAAA,EAEQ,YAAmC;AAAA,EAC3C,IAAI,SAAS,UAA0B;AACrC,SAAK,YAAY;AAAA,EACnB;AAAA,EACA,IAAI,WAAW;AACb,QAAI,KAAK,cAAc,MAAM;AAC3B,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,YAAmC;AAAA,EAC3C,IAAI,SAAS,WAA2B;AACtC,SAAK,YAAY;AAAA,EACnB;AAAA,EACA,IAAI,WAAW;AACb,QAAI,KAAK,cAAc,MAAM;AAC3B,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,UAAyB;AAAA,EACjC,IAAI,OAAO,QAAgB;AACzB,SAAK,UAAU;AAAA,EACjB;AAAA,EACA,IAAI,SAAiB;AACnB,QAAI,KAAK,YAAY,MAAM;AACzB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,UAA+B;AAAA,EACvC,IAAI,OAAO,QAAsB;AAC/B,SAAK,UAAU;AAAA,EACjB;AAAA,EACA,IAAI,SAAuB;AACzB,QAAI,KAAK,YAAY,MAAM;AACzB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,WAAiC;AAAA,EACzC,IAAI,QAAQ,SAAwB;AAClC,SAAK,WAAW;AAAA,EAClB;AAAA,EACA,IAAI,UAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,iBAAiB;AACrB,UAAM,KAAK,KAAK,MAAM,OAAO,QAAW,IAAI;AAAA,EAC9C;AAAA,EAEA,MAAM,KACJ,WAAoB,OACpB,aAAsB,MACtB,aACA,aAAsB,OACtB;AACA,QAAI,KAAK,eAAe;AACtB;AAAA,IACF;AACA,KAAC,YACC,QAAQ;AAAA,MACNH,OAAM,KAAK,cAAc,aAAa,iBAAiB,EAAE,EAAE;AAAA,IAC7D;AAGF,SAAK,cAAc,eAAgB,MAAM,gBAAgB;AACzD,UAAM,aAAaG,MAAK,KAAK,KAAK,aAAa,oBAAoB;AACnE,UAAM,cAAcA,MAAK,KAAK,KAAK,aAAa,qBAAqB;AACrE,QAAIC,IAAG,WAAW,UAAU,MAAM,OAAO;AACvC,YAAM,IAAI,MAAM,qCAAqC,UAAU,EAAE;AAAA,IACnE;AACA,SAAK,SAAS,KAAK;AAAA,MACjBA,IAAG,aAAa,UAAU,EAAE,SAAS;AAAA,IACvC;AACA,QAAIA,IAAG,WAAW,WAAW,GAAG;AAC9B,WAAK,UAAU,KAAK;AAAA,QAClBA,IAAG,aAAa,WAAW,EAAE,SAAS;AAAA,MACxC;AAAA,IACF;AAGA,UAAM,aAAa,MAAM,GAAG,cAAc,KAAK,WAAW;AAC1D,SAAK,WAAW,WAAW;AAC3B,OAAG,KAAK,UAAiB;AACzB,SAAK,WAAW,GAAG;AAGnB,QAAI,YAAY;AACd,WAAK,gBAAgB;AACrB;AAAA,IACF;AAGA,UAAM,cAAc,SAAS,QAAQ;AAGrC,SAAK,SAAS,IAAI,OAAO;AAGzB,UAAM,KAAK,OAAO,eAAe;AACjC,UAAM,KAAK,OAAO,cAAc;AAChC,UAAM,KAAK,OAAO,aAAa;AAE/B,QAAI,QAAQ,KAAK,CAAC,OAAO,KAAK,YAAY;AACxC,YAAM,KAAK,OAAO,KAAK;AAEvB,YAAM,qCAAqC;AAAA,QACzC,QAAQ;AAAA,MACV,CAAC,EAAE;AAAA,QAAM,CAAC,MACR,QAAQ,IAAIJ,OAAM,IAAI,+BAA+B,EAAE,OAAO,EAAE,CAAC;AAAA,MACnE;AAAA,IACF;AAEA,SAAK,gBAAgB;AACrB,KAAC,YAAY,QAAQ,QAAQA,OAAM,KAAK,aAAa,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,YACJ,QACA,QACA,SACA;AACA,QAAI,KAAK,kBAAkB,OAAO;AAChC,YAAM,KAAK,KAAK,SAAS,UAAU,SAAS,UAAU;AAAA,IACxD;AAGA,WAAO;AAAA,MACL,GAAG,KAAK,OAAO,MAAM,MAAM;AAAA,MAC3B,OAAO,UAAU,WAAyB;AACxC,eAAO,KAAK,OAAO;AAAA,MACrB;AAAA,IACF;AAGA,WAAO;AAAA,MACL,GAAG,KAAK,OAAO,MAAM,MAAM;AAAA,MAC3B,OAAO,UAAU,WAA4B;AAC3C,eAAO;AAAA,MACT;AAAA,IACF;AAGA,SAAK,OAAO,KAAK,IAAI,CAACF,SAAQ;AAE5B,UAAI,KAAK,OAAO,OAAOA,KAAI,SAAS,MAAM,QAAW;AACnD,cAAM,IAAI,MAAM,yEAAkBA,KAAI,SAAS,EAAE;AAAA,MACnD;AACA,YAAM,QAAQ,KAAK,OAAO,OAAOA,KAAI,SAAS;AAG9C,YAAM,UAAU,oBAAoBA,MAAK,KAAK,OAAO,KAAK;AAG1D,aAAO,MAAM;AAAA,QACX,QAAQA,KAAI,QAAQ;AAAA,QACpB,KAAK,KAAK,OAAO,MAAM,SAASA,KAAI;AAAA,QACpC,SAAS,OAAO,SAAS,UAA4B;AACnD,WAACA,KAAI,QAAQ,UAAU,CAAC,GAAG;AAAA,YAAM,CAAC,UAChC,OAAO,aAAa,OAAO,SAASA,IAAG;AAAA,UACzC;AAGA,gBAAM,QAAQA,KAAI,QAAQ,eAAe,QAAQ,UAAU;AAC3D,cAAI;AAGJ,cAAI;AACF,sBAAU,cAAc,OAAO,EAAE,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC;AAAA,UAC7D,SAAS,GAAG;AACV,gBAAI,aAAa,UAAU;AACzB,oBAAM,WAAW,iBAAiB,CAAC,EAChC,IAAI,CAAC,UAAU,MAAM,OAAO,EAC5B,KAAK,GAAG;AACX,oBAAM,IAAI,oBAAoB,QAAQ;AAAA,YACxC,OAAO;AACL,oBAAM;AAAA,YACR;AAAA,UACF;AAGA,gBAAM,KAAKA,KAAI,QAAQ,eAAe,kBAAkB;AAGxD,gBAAM,EAAE,UAAU,UAAU,WAAW,IAAI,OAAO,YAAY;AAC5D,gBAAI,OAAO,OAAO;AAChB,kBAAI;AACF,sBAAM,cAAc,OAAO,MAAM,WAAWA,KAAI,MAAM,OAAO;AAC7D,oBAAI,YAAY,UAAU,OAAO;AAC/B,yBAAO,EAAE,UAAU,MAAM,YAAY,KAAK;AAAA,gBAC5C;AAEA,sBAAMsB,YAAW,YAAY;AAC7B,sBAAMC,YAAW,YAAY;AAC7B,sBAAMC,cAAa,MAAM,OAAO,MAAM,IAAIF,SAAQ;AAClD,uBAAO,EAAE,UAAAA,WAAU,UAAAC,WAAU,YAAAC,YAAW;AAAA,cAC1C,SAAS,GAAG;AACV,wBAAQ,MAAM,CAAC;AAAA,cACjB;AACA,qBAAO,EAAE,UAAU,MAAM,YAAY,KAAK;AAAA,YAC5C;AACA,mBAAO,EAAE,UAAU,MAAM,YAAY,KAAK;AAAA,UAC5C,GAAG;AACH,cAAI,eAAe,MAAM;AACvB,mBAAO;AAAA,UACT;AAGA,gBAAM,SAAS,MAAO,MAAcxB,KAAI,UAAU,EAAE;AAAA,YAClD;AAAA,YACAA,KAAI,WAAW,IAAI,CAAC,UAAU;AAE5B,kBAAI,aAAa,UAAU,MAAM,IAAI,GAAG;AACtC,uBAAO,OAAO;AAAA,kBACZ;AAAA,oBACE,SAAS,QAAQ;AAAA,oBACjB;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,OAAO;AACL,uBAAO,QAAQ,MAAM,IAAI;AAAA,cAC3B;AAAA,YACF,CAAC;AAAA,UACH;AACA,gBAAM,KAAKA,KAAI,QAAQ,eAAe,kBAAkB;AAGxD,cAAI,OAAO,SAAS,UAAU;AAC5B,kBAAM,OAAO,MAAM,IAAI,UAAU,QAAQ,QAAQ;AAAA,UACnD;AACA,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAyB;AAC7B,UAAM,GAAG,QAAQ;AAAA,EACnB;AACF;AACO,IAAM,SAAS,IAAI,YAAY;;;AD1UtC,OAAOM,SAAQ;AAiBf,IAAM,qBAAN,MAAyB;AAAA,EACf,WAAgC,oBAAI,IAAI;AAAA,EACzC,cAAmC,oBAAI,IAAI;AAAA,EAC1C,aAAqC,oBAAI,IAAI;AAAA,EAC9C,eAAwB;AAAA;AAAA,EAG/B,MAAM,SAAS,WAAoB,OAAO;AACxC,QAAI,KAAK,cAAc;AACrB;AAAA,IACF;AACA,UAAM,cAAcD,MAAK;AAAA,MACvB,OAAO;AAAA,MACP;AAAA,IACF;AACA,KAAC,YAAY,QAAQ,IAAIH,OAAM,OAAO,YAAY,WAAW,EAAE,CAAC;AAEhE,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,MAAAC,MAAK,KAAKE,MAAK,QAAQ,WAAY,GAAG,CAAC,MAAM,UAAU;AACrD,gBAAQ;AAAA,UACN,MAAM,IAAI,OAAO,SAAS;AACxB,kBAAM,KAAK,SAAS,KAAK,MAAMC,IAAG,aAAa,IAAI,EAAE,SAAS,CAAC,CAAC;AAAA,UAClE,CAAC;AAAA,QACH,EAAE,KAAK,MAAM;AACX,kBAAQ,IAAI;AACZ,eAAK,eAAe;AAAA,QACtB,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,WAAoB,OAAO;AACtC,YAAQ,IAAI,QAAQ;AACpB,SAAK,SAAS,MAAM;AACpB,SAAK,YAAY,MAAM;AACvB,SAAK,WAAW,MAAM;AACtB,SAAK,eAAe;AAEpB,UAAM,aAAaD,MAAK;AAAA,MACtB,OAAO;AAAA,MACP,0CAA0C,KAAK,IAAI,CAAC;AAAA,IACtD;AAEA,QAAI,WAAS,SAAS,UAAQ,MAAM,UAAU,GAAG;AAC/C,aAAO,UAAQ,MAAM,UAAU;AAAA,IACjC;AAEA,WAAO,MAAM,KAAK,SAAS,QAAQ;AAAA,EACrC;AAAA,EAEA,MAAM,SAAS,MAAiC;AAC9C,UAAM,SAAS,IAAI,OAAO,IAAI;AAC9B,UAAM,OAAO,oBAAoB;AACjC,WAAO,mBAAmB;AAC1B,SAAK,SAAS,IAAI,KAAK,IAAI,MAAM;AAAA,EAEnC;AAAA,EAEA,IAAI,UAA0B;AAC5B,UAAM,SAAS,KAAK,SAAS,IAAI,QAAQ;AACzC,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,MAAM,6DAAqB,QAAQ,EAAE;AAAA,IACjD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,UAA2B;AAChC,UAAM,SAAS,KAAK,SAAS,IAAI,QAAQ;AACzC,WAAO,WAAW;AAAA,EACpB;AAAA,EAEA,YAAsB;AACpB,WAAO,MAAM,KAAK,cAAc,SAAS,KAAK,CAAC;AAAA,EACjD;AAAA,EAEA,kBAA4B;AAC1B,WAAO,KAAK,UAAU,EAAE,OAAO,CAAC,aAAa;AAC3C,YAAM,SAAS,KAAK,IAAI,QAAQ;AAChC,aAAO,OAAO,aAAa;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,UAA4B;AACzC,WAAO,KAAK,UAAU,EAAE,OAAO,CAAC,aAAa;AAC3C,YAAM,SAAS,KAAK,IAAI,QAAQ;AAChC,aAAO,OAAO,aAAa;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,KAAa,YAA0B;AAEnD,SAAK,YAAY,IAAI,KAAK,UAAU;AAAA,EACtC;AAAA,EAEA,cAAc,KAAqB;AACjC,UAAM,aAAa,KAAK,YAAY,IAAI,GAAG;AAC3C,QAAI,eAAe,QAAW;AAC5B,YAAM,IAAI,MAAM,gFAAoB,GAAG,EAAE;AAAA,IAC3C;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,WAAsB;AACjC,SAAK,WAAW,IAAI,UAAU,MAAM,SAAS;AAAA,EAC/C;AAAA,EAEA,aAAa,KAAwB;AACnC,UAAM,YAAY,KAAK,WAAW,IAAI,GAAG;AACzC,QAAI,cAAc,QAAW;AAC3B,YAAM,IAAI,MAAM,sFAAqB,GAAG,EAAE;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,UAAqC;AAElD,UAAM,aACJD,aAAW,UAAU,QAAQ,MAAM,WAC/B,GAAG,QAAQ,SACXA,aAAW,UAAU,QAAQ;AAEnC,WAAO;AAAA,MACL,IAAIA,aAAW,UAAUA,aAAW,WAAW,QAAQ,CAAC,EAAE,YAAY;AAAA,MACtE,UAAUA,aACP,UAAUA,aAAW,WAAW,UAAU,CAAC,EAC3C,YAAY;AAAA,MACf,OAAOA,aAAW,SAAS,UAAU,IAAI;AAAA,MACzC,aAAaA,aAAW,SAAS,YAAY,IAAI;AAAA,MACjD,SAAS;AAAA,MACT,eAAe;AAAA,MACf,OAAO,SAAS,YAAY;AAAA,MAC5B,UAAUA,aAAW,WAAW,QAAQ,EAAE,YAAY;AAAA,IACxD;AAAA,EACF;AACF;AAEO,IAAM,gBAAgB,IAAI,mBAAmB;;;ADjJpD,OAAOA,kBAAgB;AACvB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,SAAS,KAAAP,UAAS;AAElB,OAAOkB,eAAc;AAGd,IAAM,SAAN,MAAa;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAKA;AAAA,EACA;AAAA,EAGA;AAAA,EAGA;AAAA,EACA;AAAA,EAGA,QAEI,CAAC;AAAA,EACL,QAEI,CAAC;AAAA,EACL,aAII,CAAC;AAAA,EAEL,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAe;AAEb,SAAK,KAAK;AACV,SAAK,WAAW;AAChB,SAAK,QAAQ,SAAS,KAAK;AAC3B,SAAK,QAAQ,SAASb,aAAW,WAAWA,aAAW,UAAU,EAAE,CAAC;AAGpE,QAAI,OAAO;AACT,WAAK,QAAQ,MAAM,IAAI,CAAC,SAAS;AAC/B,YAAI,WAAW,IAAI,GAAG;AACpB,cAAI,KAAK,GAAG,SAAS,QAAQ,GAAG;AAC9B,iBAAK,KAAK,KAAK,GAAG,QAAQ,UAAU,EAAE;AAAA,UACxC;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AACD,WAAK,YAAY,MAAM,OAAO,CAAC,QAAQ,SAAS;AAC9C,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,KAAK,IAAI,GAAG;AAAA,QACf;AAAA,MACF,GAAG,CAAC,CAAC;AAGL,WAAK,YAAY,MACd,OAAO,CAAC,SAAS,eAAe,IAAI,CAAC,EACrC,OAAO,CAAC,QAAQ,SAAS;AACxB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,KAAK,IAAI,GAAG;AAAA,QACf;AAAA,MACF,GAAG,CAAC,CAAC;AAAA,IACT,OAAO;AACL,WAAK,QAAQ,CAAC;AACd,WAAK,YAAY,CAAC;AAClB,WAAK,YAAY,CAAC;AAAA,IACpB;AAGA,SAAK,UAAU,WAAW,CAAC;AAG3B,SAAK,UAAU,WAAW,CAAC;AAG3B,SAAK,aAAa,SAAS,CAAC;AAC5B,SAAK,QAAQ,OAAO;AAAA,MAClB,OAAO,QAAQ,KAAK,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,SAAS,MAAM;AACxD,eAAO;AAAA,UACL;AAAA,UACAL,GAAE;AAAA,YACA,OAAO,KAAK,SAAS;AAAA,UACvB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAGA,SAAK,QAAQ;AAAA,MACX,UAAUK,aACP,UAAUA,aAAW,WAAW,YAAY,EAAE,CAAC,EAC/C,YAAY;AAAA,MACf,IAAIA,aAAW,UAAUA,aAAW,WAAW,EAAE,CAAC,EAAE,YAAY;AAAA,MAChE,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,WAAgC;AAC7C,UAAM,SAAS,KAAK,QAAQ,SAAS;AAErC,UAAM,SAAsB,KAAK,mBAAmB,IAAI,MAAM;AAC9D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,mBACE,QACA,QACA,uBAAgC,OACnB;AAEb,aAAS,OAAO,QAAQ,OAAO,IAAI;AAGnC,UAAM,cAAcH,IAAE,QAAQ,QAAQ,CAAC,UAAU;AAC/C,UAAI,MAAM,SAAS,GAAG,GAAG;AACvB,cAAM,CAAC,GAAG,IAAI,MAAM,MAAM,GAAG;AAC7B,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,UAAM,SAAS,OAAO,KAAK,WAAW,EAAE;AAAA,MACtC,CAAC,GAAG,aAAa;AACf,cAAMwB,UAAS,YAAY,QAAQ;AAEnC,YAAI,aAAa,IAAI;AACnB,gBAAM,aAAaA,QAAO;AAAA,YACxB,CAAC,UAAU,CAAC,cAAc,KAAK,UAAU,KAAK,CAAC;AAAA,UACjD;AACA,gBAAM,gBAAgBA,QAAO;AAAA,YAAO,CAAC,UACnC,cAAc,KAAK,UAAU,KAAK,CAAC;AAAA,UACrC;AAEA,cAAI,WAAW,IAAI;AAEjB,cAAE,SAAS,EAAE,OAAO;AAAA,cAClB,WAAW,IAAI,CAAC,UAAU,GAAG,KAAK,KAAK,IAAI,KAAK,EAAE;AAAA,YACpD;AACA,cAAE,UAAU,EAAE,QAAQ,OAAO,aAAa;AAAA,UAC5C,OAAO;AAEL,cAAE,SAAS,EAAE,OAAO;AAAA,cAClB,WAAW;AAAA,gBACT,CAAC,UAAU,GAAG,MAAM,IAAI,KAAK,OAAO,MAAM,KAAK,KAAK;AAAA,cACtD;AAAA,YACF;AAAA,UACF;AAEA,iBAAO;AAAA,QACT;AAEA,cAAM,WAAW,KAAK,UAAU,QAAQ;AACxC,YAAI,aAAa,QAAW;AAC1B,gBAAM,IAAI,MAAM,+DAAuB,QAAQ,EAAE;AAAA,QACnD;AACA,cAAM,YAAY,cAAc,IAAI,SAAS,IAAI;AAEjD,YACE,uBAAuB,QAAQ,KAC/B,2BAA2B,QAAQ,GACnC;AAEA,gBAAM,YAAYA,QAAO;AAAA,YAAI,CAAC,UAC5B,MAAM,MAAM,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,UACpC;AAGA,cAAI,UAAU,WAAW,KAAK,UAAU,CAAC,MAAM,MAAM;AACnD,gBAAI,WAAW,IAAI;AACjB,gBAAE,SAAS,EAAE,OAAO,OAAO,GAAG,KAAK,KAAK,IAAI,QAAQ,KAAK;AAAA,YAC3D,OAAO;AACL,gBAAE,SAAS,EAAE,OAAO;AAAA,gBAClB,GAAG,MAAM,IAAI,QAAQ,UAAU,MAAM,KAAK,QAAQ;AAAA,cACpD;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAGA,gBAAM,gBAAgB,MAAM;AAC1B,gBAAI,sBAAsB;AACxB,qBAAO;AAAA,YACT;AAEA,gBAAI,uBAAuB,QAAQ,GAAG;AACpC,kBACE,SAAS,kBAAkB,SAC1B,SAAS,YAAY,WAAW,OACjC;AACA,uBAAO;AAAA,cACT,OAAO;AACL,uBAAO;AAAA,cACT;AAAA,YACF,OAAO;AACL,kBAAI,SAAS,UAAU;AACrB,uBAAO;AAAA,cACT,OAAO;AACL,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,GAAG;AACH,gBAAM,iBAAiB,UAAU;AAAA,YAC/B,GAAG,WAAW,KAAK,SAAS,MAAM,EAAE,GAAG,QAAQ;AAAA,YAC/C;AAAA,YACA,iBAAiB;AAAA,UACnB;AACA,YAAE,SAAS,EAAE,OAAO,OAAO,eAAe,MAAM;AAChD,YAAE,UAAU,EAAE,QAAQ,OAAO,eAAe,OAAO;AAEnD,gBAAM,SAAS,WAAW,KAAK,WAAW,SAAS,OAAO;AAC1D,gBAAM,YAAY,WAAW,KAAK,KAAK,QAAQ;AAE/C,cAAI;AACJ,cAAI,SAAS,kBAAkB;AAC7B,yBAAa;AAAA,cACX,QAAQ,SAAS;AAAA,YACnB;AAAA,UACF,OAAO;AACL,gBAAI,MAAM;AACV,gBAAI,uBAAuB,QAAQ,GAAG;AACpC,kBAAI,SAAS,eAAe;AAC1B,uBAAO,GAAG,SAAS,IAAI,SAAS,IAAI;AACpC,qBAAK,GAAG,MAAM;AAAA,cAChB,OAAO;AACL,uBAAO,GAAG,SAAS;AACnB,qBAAK,GAAG,MAAM,IAAIrB,aAAW;AAAA,kBAC3B,KAAK,MAAM,GAAG,QAAQ,OAAO,GAAG;AAAA,gBAClC,CAAC;AAAA,cACH;AAAA,YACF,OAAO;AACL,qBAAO,GAAG,SAAS,IAAI,SAAS,IAAI;AACpC,mBAAK,GAAG,MAAM;AAAA,YAChB;AACA,yBAAa;AAAA,cACX;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAEA,YAAE,MAAM,KAAK;AAAA,YACX,IAAI;AAAA,YACJ,MAAM;AAAA,YACN,OAAO,UAAU;AAAA,YACjB,GAAG;AAAA,UACL,CAAC;AAGD,cAAI,eAAe,QAAQ,SAAS,GAAG;AACrC,kBAAM,mBAAmB,eAAe,QAAQ,IAAI,CAAC,WAAW;AAC9D,oBAAM,QAAQ,CAAC,UAAU,OAAO,EAAE,EAAE,KAAK,IAAI;AAC7C,qBAAO;AAAA,gBACL,IAAI;AAAA,gBACJ,OAAO,OAAO;AAAA,gBACd,UAAU,OAAO;AAAA,gBACjB,UAAU,OAAO;AAAA,gBACjB,QAAQ,OAAO;AAAA,gBACf,SAAS,OAAO;AAAA,cAClB;AAAA,YACF,CAAC;AAED,cAAE,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,gBAAgB;AAAA,UAChD;AAEA,YAAE,QAAQ,EAAE,MAAM,OAAO,eAAe,KAAK;AAAA,QAC/C,WACE,sBAAsB,QAAQ,KAC9B,yBAAyB,QAAQ,GACjC;AAEA,gBAAM,YAAYqB,QAAO;AAAA,YAAI,CAAC,UAC5B,MAAM,MAAM,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,UACpC;AACA,gBAAM,iBAAiB,UAAU,mBAAmB,IAAI,SAAS;AAEjE,cAAI;AACJ,cAAI,sBAAsB,QAAQ,GAAG;AACnC,kBAAM,UAAU,UAAU,cAAc;AACxC,uBAAW;AAAA,cACT,WAAW,KAAK;AAAA,cAChB;AAAA,cACA,SAAS,WAAW,KAAK,GAAG,OAAO,KAAK,GAAG,MAAM,KAAK,OAAO;AAAA,cAC7D,SAAS,UAAU;AAAA,cACnB,OAAO,SAAS;AAAA,YAClB;AAAA,UACF,WAAW,yBAAyB,QAAQ,GAAG;AAC7C,kBAAM,CAAC,QAAQ,MAAM,IAAI,SAAS,UAAU,MAAM,IAAI;AACtD,kBAAM,iBAAiB,MAAM;AAE3B,kBAAI,KAAK,UAAU,UAAU,OAAO;AAClC,oBAAI,WAAW,KAAK,OAAO;AACzB,yBAAO;AAAA,oBACL,SAAS,GAAGrB,aAAW,YAAY,MAAM,CAAC;AAAA,oBAC1C,OAAO,GAAGA,aAAW,YAAY,MAAM,CAAC;AAAA,kBAC1C;AAAA,gBACF,OAAO;AACL,yBAAO;AAAA,oBACL,SAAS,GAAGA,aAAW,YAAY,MAAM,CAAC;AAAA,oBAC1C,OAAO,GAAGA,aAAW,YAAY,MAAM,CAAC;AAAA,kBAC1C;AAAA,gBACF;AAAA,cACF,OAAO;AAEL,uBAAO;AAAA,kBACL,SAAS,GAAGA,aAAW,YAAY,KAAK,KAAK,CAAC;AAAA,kBAC9C,OAAO,GAAGA,aAAW,YAAY,UAAU,KAAK,CAAC;AAAA,gBACnD;AAAA,cACF;AAAA,YACF,GAAG;AAEH,uBAAW;AAAA,cACT,WAAW,KAAK;AAAA,cAChB,SAAS;AAAA,cACT,SAAS,WAAW,KAAK,OAAO,GAAG,MAAM;AAAA,cACzC,SAAS;AAAA,gBACP,OAAO,SAAS;AAAA,gBAChB,GAAG;AAAA,cACL;AAAA,cACA,SAAS,UAAU;AAAA,cACnB,OAAO;AAAA,YACT;AAAA,UACF,OAAO;AACL,kBAAM,IAAI,MAAM;AAAA,UAClB;AAEA,YAAE,QAAQ,KAAK;AAAA,YACb,IAAI;AAAA,YACJ,OAAO,UAAU;AAAA,YACjB;AAAA,YACA,UAAU,eAAe;AAAA,YACzB,QAAQ,eAAe;AAAA,YACvB,SAAS,eAAe;AAAA,UAC1B,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC;AAAA,QACV,OAAO,CAAC;AAAA,QACR,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBACE,YACA,SAAiB,MACC;AAClB,UAAM,SAAS,WAAW;AAAA,MACxB,CAAC,QAAQ,cAAc;AACrB,YAAI,KAAK,OAAO;AAChB,YAAI,UAAU,SAAS,GAAG,GAAG;AAC3B,WAAC,KAAK,GAAG,QAAQ,IAAI,UAAU,MAAM,GAAG;AACxC,kBAAQ,SAAS,KAAK,GAAG;AAAA,QAC3B,OAAO;AACL,gBAAM;AACN,kBAAQ;AAAA,QACV;AACA,eAAO,GAAG,KAAK,OAAO,GAAG,KAAK,CAAC,GAAG,OAAO,KAAK;AAE9C,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IAGH;AAEA,WAAO,OAAO,KAAK,MAAM,EACtB,IAAI,CAAC,QAAQ;AACZ,YAAM,QAAQ,OAAO,GAAG;AAGxB,UAAI,QAAQ,IAAI;AACd,eAAO,MAAM,IAAI,CAAC,aAAa;AAE7B,cAAI,aAAa,QAAQ;AACvB,mBAAO;AAAA,cACL,UAAU;AAAA,cACV,MAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,QAAQ;AAAA,cACV;AAAA,cACA,UAAU,CAAC;AAAA,YACb;AAAA,UACF;AAEA,gBAAMsB,QAAO,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AACzD,cAAIA,UAAS,QAAW;AACtB,oBAAQ,IAAI,EAAE,UAAU,OAAO,CAAC;AAChC,kBAAM,IAAI,MAAM,GAAG,OAAO,EAAE,oCAAqB,QAAQ,EAAE;AAAA,UAC7D;AACA,iBAAO;AAAA,YACL,UAAU;AAAA,YACV,MAAAA;AAAA,YACA,UAAU,CAAC;AAAA,UACb;AAAA,QACF,CAAC;AAAA,MACH;AAGA,YAAM,OAAO,OAAO,UAAU,GAAG;AACjC,UAAI,CAAC,eAAe,IAAI,GAAG;AACzB,cAAM,IAAI,MAAM,gCAAiB,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE;AAAA,MACpD;AACA,YAAM,YAAY,cAAc,IAAI,KAAK,IAAI;AAG7C,UAAI,2BAA2B,IAAI,KAAK,uBAAuB,IAAI,GAAG;AACpE,YAAI,MAAM,UAAU,MAAM,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,KAAK,QAAQ;AAEjE,gBAAM,SAAS,UAAU,UAAU;AACnC,iBAAO;AAAA,YACL,UAAU;AAAA,YACV,MAAM;AAAA,cACJ,GAAG;AAAA,cACH,MAAM,MAAM;AAAA,cACZ,UAAU,KAAK;AAAA,YACjB;AAAA,YACA,UAAU,CAAC;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAKA,YAAM,WAAW,KAAK,sBAAsB,OAAO,SAAS;AAC5D,YAAM,WACJ,2BAA2B,IAAI,KAAK,uBAAuB,IAAI,IAC1D,WACA;AAEP,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC,EACA,KAAK;AAAA,EACV;AAAA,EAEA,cACE,SAAS,IACT,WAAmB,GACnB,QAAkB,CAAC,GACT;AACV,WAAO,KAAK,MACT,IAAI,CAAC,SAAS;AACb,YAAM,WAAW,CAAC,QAAQ,KAAK,IAAI,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,GAAG;AACrE,UAAI,aAAa,QAAQ;AACvB,eAAO;AAAA,MACT;AACA,UAAI,eAAe,IAAI,GAAG;AACxB,YAAI,WAAW,GAAG;AAChB,iBAAO;AAAA,QACT;AACA,YAAI,MAAM,SAAS,KAAK,IAAI,GAAG;AAE7B,iBAAO;AAAA,QACT;AAEA,cAAM,QAAQ,cAAc,IAAI,KAAK,IAAI;AACzC,eAAO,MAAM,cAAc,UAAU,WAAW,GAAG;AAAA,UACjD,GAAG;AAAA,UACH,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,EACL,OAAO,CAAC,MAAM,MAAM,IAAI;AAAA,EAC7B;AAAA,EAEA,kBAA4B;AAC1B,WAAO,KAAK,MACT,IAAI,CAAC,SAAS;AACb,UAAI,KAAK,SAAS,YAAY;AAC5B,YACE,KAAK,iBAAiB,kBACrB,KAAK,iBAAiB,cAAc,KAAK,kBAAkB,MAC5D;AACA,iBAAO,GAAG,KAAK,IAAI;AAAA,QACrB,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO,KAAK;AAAA,IACd,CAAC,EACA,OAAO,WAAW;AAAA,EACvB;AAAA,EAEA,MAAM,sBAAsB;AAC1B,UAAM,WAAW,GAAG,KAAK,MAAM,QAAQ;AAGvC,kBAAc,cAAc,GAAG,KAAK,EAAE,cAAc,kBAAkB;AAGtE,QAAI,OAAO,KAAK,KAAK,OAAO,EAAE,SAAS,GAAG;AACxC,oBAAc,cAAc,GAAG,KAAK,EAAE,aAAa,kBAAkB;AACrE,oBAAc;AAAA,QACZ,GAAG,KAAK,EAAE;AAAA,QACV;AAAA,MACF;AACA,aAAO,KAAK,KAAK,OAAO,EAAE,IAAI,CAAC,cAAc;AAC3C,sBAAc;AAAA,UACZ,GAAG,KAAK,EAAE,SAAS,UAAU,YAAY,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAGA,WAAO,KAAK,KAAK,UAAU,EAAE,IAAI,CAAC,WAAW;AAC3C,oBAAc,cAAc,QAAQ,kBAAkB;AAAA,IACxD,CAAC;AAGD,UAAM,kBAAkB,GAAG,QAAQ,IAAI,KAAK,MAAM,QAAQ;AAC1D,UAAM,oBAAoBrB,MAAK;AAAA,MAC7B,OAAO;AAAA,MACP,oBAAoB,eAAe;AAAA,IACrC;AAEA,QAAIC,IAAG,WAAW,iBAAiB,GAAG;AACpC,YAAM,aAAaD,MAAK,SAAS,WAAW,iBAAiB;AAC7D,YAAM,IAAI,MAAM,OAAO;AACvB,WAAK,QAAQ,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,QAAQ;AAClD,sBAAc,cAAc,KAAK,eAAe;AAChD,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,EAAE,GAAG;AAAA,QACd;AAAA,MACF,GAAG,CAAC,CAAC;AAAA,IACP;AAAA,EACF;AAAA,EAEA,qBAA2B;AACzB,UAAM,gBAAgB,KAAK,QAAQ,OAAO,CAAC,QAAQ,IAAI,SAAS,QAAQ;AAExE,kBAAc,aAAa;AAAA,MACzB,MAAM,KAAK;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,SAAqB;AACnB,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,EAEA,MAAM,OAAsB;AAE1B,UAAM,aAAa,KAAK,cAAc;AACtC,SAAK,UAAU,OAAO;AAAA,MACpB,OAAO,QAAQ,KAAK,OAAO,EAAE,IAAI,CAAC,CAAC,SAAS,MAAM;AAChD,eAAO;AAAA,UACL;AAAA,UACA,KAAK,yBAAyB,YAAY,SAAS;AAAA,QACrD;AAAA,MACF,CAAC;AAAA,IACH;AAGA,UAAM,WAAWA,MAAK;AAAA,MACpB,OAAO;AAAA,MACP,mBAAmB,KAAK,MAAM,QAAQ,IAAI,KAAK,MAAM,EAAE;AAAA,IACzD;AACA,UAAM,OAAO,KAAK,OAAO;AACzB,IAAAC,IAAG;AAAA,MACD;AAAA,MACA,MAAMW,UAAS,OAAO,KAAK,UAAU,IAAI,GAAG;AAAA,QAC1C,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,UAAM,cAAc,SAAS,IAAI;AAAA,EACnC;AAAA,EAEA,cACE,UACA,WAAqB,CAAC,GACH;AACnB,QAAI,SAAS,SAAS,IAAI;AACxB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,UAAU,YAAY,KAAK;AACjC,UAAM,aAAa,OAAO,KAAK,OAAO;AACtC,UAAM,YAAYhB,IAAE,KAAK,WAAW,IAAI,CAAC,QAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC;AAErE,WAAO,KAAK,MAAM,IAAI,CAAC,SAAS;AAC9B,UACE,KAAK,SAAS,cACd,UAAU;AAAA,QAAK,CAAC,MACd,EAAE,WAAW,CAAC,GAAG,UAAU,KAAK,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG;AAAA,MACvD,GACA;AACA,cAAM,YAAY,cAAc,IAAI,KAAK,IAAI;AAC7C,cAAM,WAAW,UAAU,cAAc,SAAS;AAAA,UAChD,GAAG;AAAA,UACH,GAAG,KAAK,IAAI;AAAA,QACd,CAAC;AAED,eAAO;AAAA,UACL,OAAO,KAAK;AAAA,UACZ;AAAA,UACA,gBAAgB,KAAK;AAAA,UACrB;AAAA,UACA,QAAQ,SAAS,SAAS;AAAA,UAC1B,KAAK,OAAO;AAAA,YACV,WAAW,IAAI,CAAC,cAAc;AAC5B,qBAAO;AAAA,gBACL;AAAA,gBACA,SAAS,MAAM,CAAC,UAAU,MAAM,IAAI,SAAS,MAAM,IAAI;AAAA,cACzD;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,OAAO,KAAK;AAAA,QACZ,UAAU,CAAC;AAAA,QACX,gBAAgB,KAAK,SAAS,aAAa,KAAK,OAAO;AAAA,QACvD;AAAA,QACA,KAAK,OAAO;AAAA,UACV,WAAW,IAAI,CAAC,cAAc;AAC5B,kBAAM,eAAe,QAAQ,SAAS;AACtC,kBAAM,MAAM,aAAa,KAAK,CAAC,MAAM;AACnC,oBAAM,QAAQ,CAAC,GAAG,UAAU,KAAK,IAAI,EAAE,KAAK,GAAG;AAC/C,qBAAO,MAAM,SAAS,EAAE,WAAW,QAAQ,GAAG;AAAA,YAChD,CAAC;AACD,mBAAO,CAAC,WAAW,GAAG;AAAA,UACxB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,yBACE,YACA,WACU;AACV,WAAO,WACJ,IAAI,CAAC,cAAc;AAClB,UAAI,UAAU,SAAS,SAAS,GAAG;AACjC,eAAO,KAAK,yBAAyB,UAAU,UAAU,SAAS;AAAA,MACpE,WAAW,UAAU,IAAI,SAAS,GAAG;AACnC,eAAO,UAAU,SAAS,OAAO,UAAU,KAAK,EAAE,KAAK,GAAG;AAAA,MAC5D,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF,CAAC,EACA,OAAO,WAAW,EAClB,KAAK;AAAA,EACV;AAAA,EAEA,MAAM,WAAW,MAAkB,IAA4B;AAC7D,QAAI,CAAC,IAAI;AACP,WAAK,MAAM,KAAK,IAAI;AAAA,IACtB,OAAO;AACL,WAAK,MAAM,OAAO,IAAI,GAAG,IAAI;AAAA,IAC/B;AACA,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,mBAAmB,aAGf;AACF,UAAM,MAAM,YAAY,MAAM,GAAG;AAEjC,QAAI,WAAW,KAAK;AACpB,UAAM,SAGA,CAAC;AACP,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,WAAW,IAAI,CAAC;AACtB,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,MACF,CAAC;AAED,YAAM,OAAO,cAAc,IAAI,QAAQ,EAAE,MAAM;AAAA,QAC7C,CAAC,MAAM,EAAE,SAAS;AAAA,MACpB;AACA,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,GAAG,QAAQ,sDAAc,WAAW,EAAE;AAAA,MACxD;AACA,UAAI,eAAe,IAAI,GAAG;AACxB,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,SAAqB,IAA2B;AAE/D,UAAM,UAAU,KAAK,MAAM,EAAE,EAAE;AAG/B,UAAM,WAAqB,CAAC,IAAI;AAGhC,QAAI,YAAY,QAAQ,MAAM;AAE5B,YAAM,eAAe,cAAc,UAAU;AAC7C,iBAAW,eAAe,cAAc;AACtC,cAAM,YAAY,cAAc,IAAI,WAAW;AAC/C,cAAM,sBAAsB,OAAO,KAAK,UAAU,OAAO;AACzD,mBAAW,aAAa,qBAAqB;AAC3C,gBAAM,SAAS,UAAU,QAAQ,SAAS;AAG1C,gBAAM,uBAAuB,OAAO,IAAI,CAAC,gBAAgB;AACvD,kBAAM,WAAW,UAAU,mBAAmB,WAAW;AACzD,kBAAM,WAAW,SAAS;AAAA,cAAI,CAAC,MAC7B,EAAE,aAAa,WAAW,EAAE,aAAa,KAAK,KAC1C;AAAA,gBACE,GAAG;AAAA,gBACH,UAAU,QAAQ;AAAA,cACpB,IACA;AAAA,YACN;AAEA,mBAAO,SAAS,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG;AAAA,UACjD,CAAC;AAED,cAAI,OAAO,KAAK,GAAG,MAAM,qBAAqB,KAAK,GAAG,GAAG;AACvD,sBAAU,QAAQ,SAAS,IAAI;AAC/B,qBAAS,KAAK,SAAS;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,SAAK,MAAM,EAAE,IAAI;AAEjB,UAAM,QAAQ,IAAI,SAAS,IAAI,OAAO,WAAW,OAAO,KAAK,CAAC,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,QAAQ,IAA2B;AAEvC,UAAM,UAAU,KAAK,MAAM,EAAE,EAAE;AAG/B,UAAM,WAAqB,CAAC,IAAI;AAGhC,UAAM,eAAe,cAAc,UAAU;AAC7C,eAAW,eAAe,cAAc;AACtC,YAAM,YAAY,cAAc,IAAI,WAAW;AAC/C,YAAM,sBAAsB,OAAO,KAAK,UAAU,OAAO;AACzD,iBAAW,aAAa,qBAAqB;AAC3C,cAAM,SAAS,UAAU,QAAQ,SAAS;AAE1C,cAAM,uBAAuB,OAC1B,IAAI,CAAC,gBAAgB;AACpB,gBAAM,WAAW,UAAU,mBAAmB,WAAW;AACzD,cACE,SAAS;AAAA,YACP,CAAC,MAAM,EAAE,aAAa,WAAW,EAAE,aAAa,KAAK;AAAA,UACvD,GACA;AACA,mBAAO;AAAA,UACT,OAAO;AACL,mBAAO;AAAA,UACT;AAAA,QACF,CAAC,EACA,OAAO,WAAW;AAErB,YAAI,OAAO,KAAK,GAAG,MAAM,qBAAqB,KAAK,GAAG,GAAG;AACvD,oBAAU,QAAQ,SAAS,IAAI;AAC/B,mBAAS,KAAK,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAGA,kBAAc,IAAI,KAAK,EAAE,EAAE,QAAQ,IAAI,CAAC,UAAU;AAChD,YAAM,UAAU,MAAM,QAAQ,OAAO,CAAC,QAAQ,QAAQ,OAAO;AAAA,IAC/D,CAAC;AAGD,SAAK,MAAM,OAAO,IAAI,CAAC;AAEvB,UAAM,QAAQ,IAAI,SAAS,IAAI,OAAO,WAAW,OAAO,KAAK,CAAC,CAAC;AAAA,EACjE;AAAA,EAEA,2BAA2B,aAA6B;AACtD,QAAI,YAAY,SAAS,GAAG,MAAM,OAAO;AACvC,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,MAAM,YAAY,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE;AAG9C,UAAM,eAAe,IAAI,OAAO,CAAC,UAAU,UAAU;AACnD,YAAM,UAAU,cAAc,IAAI,QAAQ,EAAE,MAAM;AAAA,QAChD,CAAC,MAAM,EAAE,SAAS;AAAA,MACpB;AACA,UAAI,CAAC,WAAW,QAAQ,SAAS,YAAY;AAC3C,gBAAQ,MAAM,EAAE,KAAK,QAAQ,KAAK,IAAI,UAAU,MAAM,CAAC;AACvD,cAAM,IAAI,MAAM,+CAAY,WAAW,EAAE;AAAA,MAC3C;AACA,aAAO,QAAQ;AAAA,IACjB,GAAG,KAAK,EAAE;AACV,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,IAAY,IAA2B;AACpD,UAAM,OAAO,KAAK,MAAM,EAAE;AAC1B,UAAM,WAAW,CAAC,GAAG,KAAK,KAAK;AAC/B,aAAS,OAAO,IAAI,GAAG,IAAI;AAC3B,aAAS,OAAO,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AACxC,SAAK,QAAQ;AAEb,UAAM,KAAK,KAAK;AAAA,EAClB;AACF","sourcesContent":["import { z } from \"zod\";\n\n/* \n Enums\n*/\nexport type EnumsLabel<T extends string, L extends \"ko\" | \"en\"> = {\n [key in T]: { [lang in L]: string };\n};\nexport type EnumsLabelKo<T extends string> = EnumsLabel<T, \"ko\">;\n\n/*\n Custom Scalars\n*/\nexport const SQLDateTimeString = z\n .string()\n .regex(/([0-9]{4}-[0-9]{2}-[0-9]{2}( [0-9]{2}:[0-9]{2}:[0-9]{2})*)$/, {\n message: \"잘못된 SQLDate 타입\",\n })\n .min(10)\n .max(19)\n .describe(\"SQLDateTimeString\");\nexport type SQLDateTimeString = z.infer<typeof SQLDateTimeString>;\n\n/*\n Utility Types\n*/\nexport function zArrayable<T extends z.ZodTypeAny>(\n shape: T\n): z.ZodUnion<[T, z.ZodArray<T, \"many\">]> {\n return z.union([shape, shape.array()]);\n}\nexport type DistributiveOmit<T, K extends keyof any> = T extends any\n ? Omit<T, K>\n : never;\n\n/*\n Model-Defintion\n*/\nexport type CommonProp = {\n name: string;\n nullable?: boolean;\n toFilter?: true;\n desc?: string;\n dbDefault?: string;\n};\nexport type IntegerProp = CommonProp & {\n type: \"integer\";\n unsigned?: true;\n};\nexport type BigIntegerProp = CommonProp & {\n type: \"bigInteger\";\n unsigned?: true;\n};\nexport type TextProp = CommonProp & {\n type: \"text\";\n textType: \"text\" | \"mediumtext\" | \"longtext\";\n};\nexport type StringProp = CommonProp & {\n type: \"string\";\n length: number;\n};\nexport type EnumProp = CommonProp & {\n type: \"enum\";\n length: number;\n id: string;\n};\nexport type FloatProp = CommonProp & {\n type: \"float\";\n unsigned?: true;\n precision: number;\n scale: number;\n};\nexport type DoubleProp = CommonProp & {\n type: \"double\";\n unsigned?: true;\n precision: number;\n scale: number;\n};\nexport type DecimalProp = CommonProp & {\n type: \"decimal\";\n unsigned?: true;\n precision: number;\n scale: number;\n};\nexport type BooleanProp = CommonProp & {\n type: \"boolean\";\n};\nexport type DateProp = CommonProp & {\n type: \"date\";\n};\nexport type DateTimeProp = CommonProp & {\n type: \"datetime\";\n};\nexport type TimeProp = CommonProp & {\n type: \"time\";\n};\nexport type TimestampProp = CommonProp & {\n type: \"timestamp\";\n};\nexport type JsonProp = CommonProp & {\n type: \"json\";\n id: string;\n};\nexport type UuidProp = CommonProp & {\n type: \"uuid\";\n};\nexport type VirtualProp = CommonProp & {\n type: \"virtual\";\n id: string;\n};\n\nexport type RelationType =\n | \"HasMany\"\n | \"BelongsToOne\"\n | \"ManyToMany\"\n | \"OneToOne\";\nexport type RelationOn =\n | \"CASCADE\"\n | \"SET NULL\"\n | \"NO ACTION\"\n | \"SET DEFAULT\"\n | \"RESTRICT\";\ntype _RelationProp = {\n type: \"relation\";\n name: string;\n with: string;\n nullable?: boolean;\n toFilter?: true;\n desc?: string;\n};\nexport type OneToOneRelationProp = _RelationProp & {\n relationType: \"OneToOne\";\n customJoinClause?: string;\n} & (\n | {\n hasJoinColumn: true;\n onUpdate: RelationOn;\n onDelete: RelationOn;\n }\n | {\n hasJoinColumn: false;\n }\n );\nexport type BelongsToOneRelationProp = _RelationProp & {\n relationType: \"BelongsToOne\";\n customJoinClause?: string;\n onUpdate: RelationOn;\n onDelete: RelationOn;\n};\nexport type HasManyRelationProp = _RelationProp & {\n relationType: \"HasMany\";\n joinColumn: string;\n fromColumn?: string;\n};\nexport type ManyToManyRelationProp = _RelationProp & {\n relationType: \"ManyToMany\";\n joinTable: `${string}__${string}`;\n onUpdate: RelationOn;\n onDelete: RelationOn;\n};\nexport type RelationProp =\n | OneToOneRelationProp\n | BelongsToOneRelationProp\n | HasManyRelationProp\n | ManyToManyRelationProp;\n\nexport type EntityProp =\n | IntegerProp\n | BigIntegerProp\n | TextProp\n | StringProp\n | FloatProp\n | DoubleProp\n | DecimalProp\n | BooleanProp\n | DateProp\n | DateTimeProp\n | TimeProp\n | TimestampProp\n | JsonProp\n | UuidProp\n | EnumProp\n | VirtualProp\n | RelationProp;\n\nexport type EntityIndex = {\n type: \"index\" | \"unique\";\n columns: string[];\n name?: string;\n};\nexport type EntityJson = {\n id: string;\n parentId?: string;\n table: string;\n title?: string;\n props: EntityProp[];\n indexes: EntityIndex[];\n subsets: {\n [subset: string]: string[];\n };\n enums: {\n [enumId: string]: {\n [key: string]: string;\n };\n };\n};\nexport type EntitySubsetRow = {\n field: string;\n has: {\n [key: string]: boolean;\n };\n children: EntitySubsetRow[];\n prefixes: string[];\n relationEntity?: string;\n isOpen?: boolean;\n};\nexport type FlattenSubsetRow = Omit<EntitySubsetRow, \"children\">;\n\n// SMD Legacy\nexport type SMDInput<T extends string> = {\n id: string;\n parentId?: string;\n table?: string;\n title?: string;\n props?: EntityProp[];\n indexes?: EntityIndex[];\n subsets?: {\n [subset: string]: T[];\n };\n};\n\n/*\n PropNode\n*/\n\nexport type EntityPropNode =\n | {\n nodeType: \"plain\";\n prop: EntityProp;\n }\n | {\n nodeType: \"object\" | \"array\";\n prop?: EntityProp;\n children: EntityPropNode[];\n };\n\n/*\n Prop Type Guards\n*/\nexport function isIntegerProp(p: any): p is IntegerProp {\n return p?.type === \"integer\";\n}\nexport function isBigIntegerProp(p: any): p is BigIntegerProp {\n return p?.type === \"bigInteger\";\n}\nexport function isTextProp(p: any): p is TextProp {\n return p?.type === \"text\";\n}\nexport function isStringProp(p: any): p is StringProp {\n return p?.type === \"string\";\n}\nexport function isEnumProp(p: any): p is EnumProp {\n return p?.type === \"enum\";\n}\nexport function isFloatProp(p: any): p is FloatProp {\n return p?.type === \"float\";\n}\nexport function isDoubleProp(p: any): p is DoubleProp {\n return p?.type === \"double\";\n}\nexport function isDecimalProp(p: any): p is DecimalProp {\n return p?.type === \"decimal\";\n}\nexport function isBooleanProp(p: any): p is BooleanProp {\n return p?.type === \"boolean\";\n}\nexport function isDateProp(p: any): p is DateProp {\n return p?.type === \"date\";\n}\nexport function isDateTimeProp(p: any): p is DateTimeProp {\n return p?.type === \"datetime\";\n}\nexport function isTimeProp(p: any): p is TimeProp {\n return p?.type === \"time\";\n}\nexport function isTimestampProp(p: any): p is TimestampProp {\n return p?.type === \"timestamp\";\n}\nexport function isJsonProp(p: any): p is JsonProp {\n return p?.type === \"json\";\n}\nexport function isUuidProp(p: any): p is UuidProp {\n return p?.type === \"uuid\";\n}\nexport function isVirtualProp(p: any): p is VirtualProp {\n return p?.type === \"virtual\";\n}\nexport function isRelationProp(p: any): p is RelationProp {\n return p?.type === \"relation\";\n}\nexport function isOneToOneRelationProp(p: any): p is OneToOneRelationProp {\n return p?.relationType === \"OneToOne\";\n}\nexport function isBelongsToOneRelationProp(\n p: any\n): p is BelongsToOneRelationProp {\n return p?.relationType === \"BelongsToOne\";\n}\nexport function isHasManyRelationProp(p: any): p is HasManyRelationProp {\n return p?.relationType === \"HasMany\";\n}\nexport function isManyToManyRelationProp(p: any): p is ManyToManyRelationProp {\n return p?.relationType === \"ManyToMany\";\n}\n\ntype JoinClause =\n | {\n from: string;\n to: string;\n }\n | {\n custom: string;\n };\nexport function isCustomJoinClause(p: any): p is { custom: string } {\n return p?.custom;\n}\n\n/* 서브셋 */\n// type SubsetLoader = {\n// as: string;\n// table: string;\n// manyJoin: {\n// fromTable: string;\n// fromCol: string;\n// idField: string;\n// toTable: string;\n// toCol: string;\n// through?: {\n// table: string;\n// fromCol: string;\n// toCol: string;\n// };\n// };\n// oneJoins: ({\n// as: string;\n// join: \"inner\" | \"outer\";\n// table: string;\n// } & JoinClause)[];\n// select: (string | Knex.Raw)[];\n// loaders?: SubsetLoader[];\n// };\n// export type SubsetQuery = {\n// select: (string | Knex.Raw)[];\n// virtual: string[];\n// joins: ({\n// as: string;\n// join: \"inner\" | \"outer\";\n// table: string;\n// } & JoinClause)[];\n// loaders: SubsetLoader[];\n// };\n\ntype SubsetLoader = {\n as: string;\n table: string;\n manyJoin: {\n fromTable: string;\n fromCol: string;\n idField: string;\n toTable: string;\n toCol: string;\n through?: {\n table: string;\n fromCol: string;\n toCol: string;\n };\n };\n oneJoins: ({\n as: string;\n join: \"inner\" | \"outer\";\n table: string;\n } & JoinClause)[];\n select: string[];\n loaders?: SubsetLoader[];\n};\n\nexport type SubsetQuery = {\n select: string[];\n virtual: string[];\n joins: ({\n as: string;\n join: \"inner\" | \"outer\";\n table: string;\n } & JoinClause)[];\n loaders: SubsetLoader[];\n};\n\n/* BaseModel */\nexport const SonamuQueryMode = z.enum([\"both\", \"list\", \"count\"]);\nexport type SonamuQueryMode = z.infer<typeof SonamuQueryMode>;\n\n/* Knex Migration */\nexport type KnexError = {\n code: string;\n errno: number;\n sql: string;\n sqlMessage: string;\n sqlState: string;\n};\nexport function isKnexError(e: any): e is KnexError {\n return e.code && e.sqlMessage && e.sqlState;\n}\nexport function isKyselyError(e: any): e is KnexError {\n return e.code && e.sqlMessage && e.sqlState;\n}\n\nexport type KnexColumnType =\n | \"string\"\n | \"text\"\n | \"smalltext\"\n | \"mediumtext\"\n | \"longtext\"\n | \"integer\"\n | \"bigInteger\"\n | \"decimal\"\n | \"timestamp\"\n | \"boolean\"\n | \"foreign\"\n | \"uuid\"\n | \"json\"\n | \"float\"\n | \"date\"\n | \"time\"\n | \"datetime\";\nexport type MigrationColumn = {\n name: string;\n type: KnexColumnType;\n nullable: boolean;\n unsigned?: boolean;\n length?: number;\n defaultTo?: string;\n precision?: number;\n scale?: number;\n};\nexport type MigrationIndex = {\n columns: string[];\n type: \"unique\" | \"index\";\n};\nexport type MigrationForeign = {\n columns: string[];\n to: string;\n onUpdate: RelationOn;\n onDelete: RelationOn;\n};\nexport type MigrationJoinTable = {\n table: string;\n indexes: MigrationIndex[];\n columns: MigrationColumn[];\n foreigns: MigrationForeign[];\n};\nexport type MigrationSet = {\n table: string;\n columns: MigrationColumn[];\n indexes: MigrationIndex[];\n foreigns: MigrationForeign[];\n};\nexport type MigrationSetAndJoinTable = MigrationSet & {\n joinTables: MigrationJoinTable[];\n};\nexport type GenMigrationCode = {\n title: string;\n table: string;\n type: \"normal\" | \"foreign\";\n formatted: string | null;\n};\n\n/* Api */\nexport type ApiParam = {\n name: string;\n type: ApiParamType;\n optional: boolean;\n defaultDef?: string;\n};\nexport namespace ApiParamType {\n export type Object = {\n t: \"object\";\n props: ApiParam[];\n };\n export type Union = {\n t: \"union\";\n types: ApiParamType[];\n };\n export type Intersection = {\n t: \"intersection\";\n types: ApiParamType[];\n };\n export type StringLiteral = {\n t: \"string-literal\";\n value: string;\n };\n export type NumericLiteral = {\n t: \"numeric-literal\";\n value: number;\n };\n export type Array = {\n t: \"array\";\n elementsType: ApiParamType;\n };\n export type Ref = {\n t: \"ref\";\n id: string;\n args?: ApiParamType[];\n };\n export type IndexedAccess = {\n t: \"indexed-access\";\n object: ApiParamType;\n index: ApiParamType;\n };\n export type TupleType = {\n t: \"tuple-type\";\n elements: ApiParamType[];\n };\n export type Pick = Ref & {\n t: \"ref\";\n id: \"Pick\";\n };\n export type Omit = Ref & {\n t: \"ref\";\n id: \"Omit\";\n };\n export type Partial = Ref & {\n t: \"ref\";\n id: \"Partial\";\n };\n export type Promise = Ref & {\n t: \"ref\";\n id: \"Promise\";\n };\n export type Context = Ref & {\n t: \"ref\";\n id: \"Context\";\n };\n export type TypeParam = {\n t: \"type-param\";\n id: string;\n constraint?: ApiParamType;\n };\n\n export function isObject(v: any): v is ApiParamType.Object {\n return v?.t === \"object\";\n }\n export function isUnion(v: any): v is ApiParamType.Union {\n return v?.t === \"union\";\n }\n export function isIntersection(v: any): v is ApiParamType.Intersection {\n return v?.t === \"intersection\";\n }\n export function isStringLiteral(v: any): v is ApiParamType.StringLiteral {\n return v?.t === \"string-literal\";\n }\n export function isNumericLiteral(v: any): v is ApiParamType.NumericLiteral {\n return v?.t === \"numeric-literal\";\n }\n export function isArray(v: any): v is ApiParamType.Array {\n return v?.t === \"array\";\n }\n export function isRef(v: any): v is ApiParamType.Ref {\n return v?.t === \"ref\";\n }\n export function isIndexedAccess(v: any): v is ApiParamType.IndexedAccess {\n return v?.t === \"indexed-access\";\n }\n export function isTupleType(v: any): v is ApiParamType.TupleType {\n return v?.t === \"tuple-type\";\n }\n export function isPick(v: any): v is ApiParamType.Pick {\n return v?.t === \"ref\" && v.id === \"Pick\";\n }\n export function isOmit(v: any): v is ApiParamType.Omit {\n return v?.t === \"ref\" && v.id === \"Omit\";\n }\n export function isPartial(v: any): v is ApiParamType.Partial {\n return v?.t === \"ref\" && v.id === \"Partial\";\n }\n export function isPromise(v: any): v is ApiParamType.Promise {\n return v?.t === \"ref\" && v.id === \"Promise\";\n }\n export function isContext(v: any): v is ApiParamType.Context {\n return v?.t === \"ref\" && v.id === \"Context\";\n }\n export function isRefKnex(v: any): v is ApiParamType.Ref {\n return v?.t === \"ref\" && v.id === \"Knex\";\n }\n export function isRefKysely(v: any): v is ApiParamType.Ref {\n return (\n v?.t === \"ref\" && (v.id === \"Kysely\" || v.id.startsWith(\"Transaction\"))\n );\n }\n export function isTypeParam(v: any): v is ApiParamType.TypeParam {\n return v?.t === \"type-param\";\n }\n}\nexport type ApiParamType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"null\"\n | \"undefined\"\n | \"void\"\n | \"any\"\n | \"unknown\"\n | \"true\"\n | \"false\"\n | ApiParamType.StringLiteral\n | ApiParamType.NumericLiteral\n | ApiParamType.Object\n | ApiParamType.Union\n | ApiParamType.Intersection\n | ApiParamType.Array\n | ApiParamType.Ref\n | ApiParamType.IndexedAccess\n | ApiParamType.TypeParam\n | ApiParamType.TupleType;\n\n/* Template */\n// 셀프 참조 타입이므로 Zod 생략하고 직접 정의\nexport const RenderingNode = z.any();\nexport type RenderingNode = {\n name: string;\n label: string;\n renderType:\n | \"string-plain\"\n | \"string-image\"\n | \"string-datetime\"\n | \"string-date\"\n | \"number-plain\"\n | \"number-id\"\n | \"number-fk_id\"\n | \"boolean\"\n | \"enums\"\n | \"array\"\n | \"array-images\"\n | \"object\"\n | \"object-pick\"\n | \"record\";\n zodType: z.ZodTypeAny;\n element?: RenderingNode;\n children?: RenderingNode[];\n config?: {\n picked: string;\n };\n optional?: boolean;\n nullable?: boolean;\n};\n\nexport const TemplateOptions = z.object({\n entity: z.object({\n entityId: z.string(),\n parentId: z.string().optional(),\n title: z.string(),\n table: z.string().optional(),\n props: z.array(z.object({})).optional(),\n indexes: z.array(z.object({})).optional(),\n subsets: z.object({}).optional(),\n enums: z.object({}).optional(),\n }),\n init_types: z.object({\n entityId: z.string(),\n }),\n generated: z.object({}),\n generated_sso: z.object({}),\n generated_http: z.object({\n entityId: z.string(),\n }),\n model: z.object({\n entityId: z.string(),\n defaultSearchField: z.string(),\n defaultOrderBy: z.string(),\n }),\n model_test: z.object({\n entityId: z.string(),\n }),\n bridge: z.object({\n entityId: z.string(),\n }),\n service: z.object({\n entityId: z.string(),\n }),\n view_list: z.object({\n entityId: z.string(),\n extra: z.unknown(),\n }),\n view_list_columns: z.object({\n entityId: z.string(),\n columns: z\n .object({\n name: z.string(),\n label: z.string(),\n tc: z.string(),\n })\n .array(),\n columnImports: z.string(),\n }),\n view_search_input: z.object({\n entityId: z.string(),\n }),\n view_form: z.object({\n entityId: z.string(),\n }),\n view_id_all_select: z.object({\n entityId: z.string(),\n }),\n view_id_async_select: z.object({\n entityId: z.string(),\n textField: z.string(),\n }),\n view_enums_select: z.object({\n entityId: z.string(),\n enumId: z.string(),\n }),\n view_enums_dropdown: z.object({\n entityId: z.string(),\n enumId: z.string(),\n }),\n view_enums_buttonset: z.object({\n entityId: z.string(),\n enumId: z.string(),\n }),\n kysely_interface: z.object({}),\n});\nexport type TemplateOptions = z.infer<typeof TemplateOptions>;\n\nexport const TemplateKey = z.enum([\n \"entity\",\n \"init_types\",\n \"generated\",\n \"generated_sso\",\n \"generated_http\",\n \"model\",\n \"model_test\",\n \"bridge\",\n \"service\",\n \"view_list\",\n \"view_list_columns\",\n \"view_search_input\",\n \"view_form\",\n \"view_id_all_select\",\n \"view_id_async_select\",\n \"view_enums_select\",\n \"view_enums_dropdown\",\n \"view_enums_buttonset\",\n \"kysely_interface\",\n]);\nexport type TemplateKey = z.infer<typeof TemplateKey>;\n\nexport const GenerateOptions = z.object({\n overwrite: z.boolean().optional(),\n});\nexport type GenerateOptions = z.infer<typeof GenerateOptions>;\n\nexport const PathAndCode = z.object({\n path: z.string(),\n code: z.string(),\n});\nexport type PathAndCode = z.infer<typeof PathAndCode>;\n\nexport type FixtureSearchOptions = {\n entityId: string;\n field: string;\n value: string;\n searchType: \"equals\" | \"like\";\n};\n\nexport type FixtureRecord = {\n fixtureId: string;\n entityId: string;\n id: number;\n columns: {\n [key: string]: {\n prop: EntityProp;\n value: any;\n };\n };\n fetchedRecords: string[];\n belongsRecords: string[];\n target?: FixtureRecord; // Import 대상 DB 레코드(id가 같은)\n unique?: FixtureRecord; // Import 대상 DB 레코드(unique key가 같은)\n override?: boolean;\n};\n\nexport type FixtureImportResult = {\n entityId: string;\n data: {\n [key: string]: any;\n };\n};\n\nexport type RelationNode = {\n fixtureId: string;\n entityId: string;\n related: Set<string>;\n};\n","import { z, ZodRecord } from \"zod\";\nimport {\n ApiParam,\n ApiParamType,\n isBelongsToOneRelationProp,\n isBigIntegerProp,\n isBooleanProp,\n isDateProp,\n isDateTimeProp,\n isDecimalProp,\n isDoubleProp,\n isEnumProp,\n isFloatProp,\n isIntegerProp,\n isJsonProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isTimeProp,\n isTimestampProp,\n isUuidProp,\n isVirtualProp,\n EntityProp,\n EntityPropNode,\n TextProp,\n} from \"../types/types\";\nimport { ExtendedApi } from \"./decorators\";\n\n/*\n ExtendedApi 에서 ZodObject 리턴\n*/\nexport function getZodObjectFromApi(\n api: ExtendedApi,\n references: {\n [id: string]: z.ZodObject<any>;\n } = {}\n) {\n if (api.typeParameters?.length > 0) {\n api.typeParameters.map((typeParam) => {\n if (typeParam.constraint) {\n let zodType = getZodTypeFromApiParamType(\n typeParam.constraint,\n references\n );\n (references[typeParam.id] as any) = zodType;\n }\n });\n }\n\n const ReqType = getZodObjectFromApiParams(\n api.parameters.filter(\n (param) =>\n !ApiParamType.isContext(param.type) &&\n !ApiParamType.isRefKnex(param.type) &&\n !ApiParamType.isRefKysely(param.type) &&\n !(param.optional === true && param.name.startsWith(\"_\")) // _로 시작하는 파라미터는 제외\n ),\n references\n );\n return ReqType;\n}\n\n/*\n ZodObject를 통해 ApiParam 리턴\n*/\nexport function getZodObjectFromApiParams(\n apiParams: ApiParam[],\n references: {\n [id: string]: z.ZodObject<any>;\n } = {}\n): z.ZodObject<{}, \"strip\", z.ZodTypeAny, {}, {}> {\n return z.object(\n apiParams.reduce((r, param) => {\n let zodType = getZodTypeFromApiParamType(param.type, references);\n if (param.optional) {\n zodType = zodType.optional();\n }\n return {\n ...r,\n [param.name]: zodType,\n };\n }, {})\n );\n}\n\n/*\n ApiParamType으로 ZodType 컨버팅\n*/\nexport function getZodTypeFromApiParamType(\n paramType: ApiParamType,\n references: {\n [id: string]: z.ZodObject<any>;\n }\n): z.ZodType<unknown> {\n switch (paramType) {\n case \"string\":\n return z.string();\n case \"number\":\n return z.number();\n case \"boolean\":\n return z.boolean();\n default:\n const advType = paramType as { t: string };\n switch (advType.t) {\n case \"string-literal\":\n case \"numeric-literal\":\n return z.literal((advType as any).value);\n case \"object\":\n const objType = paramType as { t: string; props: ApiParam[] };\n return getZodObjectFromApiParams(objType.props);\n case \"array\":\n const arrType = paramType as {\n t: string;\n elementsType: ApiParamType;\n };\n return z.array(\n getZodTypeFromApiParamType(arrType.elementsType, references)\n );\n case \"ref\":\n const refType = paramType as {\n t: string;\n id: string;\n args?: ApiParamType[];\n };\n\n // 객체 키 관리 유틸리티\n if ([\"Pick\", \"Omit\"].includes(refType.id)) {\n if (refType.args?.length !== 2) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const [obj, literalOrUnion] = refType.args!.map((arg) =>\n getZodTypeFromApiParamType(arg, references)\n ) as [z.ZodObject<any>, z.ZodUnion<any> | z.ZodLiteral<string>];\n let keys: string[] = [];\n if (literalOrUnion instanceof z.ZodUnion) {\n keys = literalOrUnion._def.options.map(\n (option: { _def: { value: string } }) => option._def.value\n );\n } else {\n keys = [(literalOrUnion as z.ZodLiteral<string>)._def.value];\n }\n const keyRecord = keys.reduce((result, key) => {\n return {\n ...result,\n [key]: true,\n };\n }, {} as any);\n\n if (refType.id === \"Pick\") {\n if (obj.pick) {\n return obj.pick(keyRecord);\n }\n } else {\n if (obj.omit) {\n return obj.omit(keyRecord);\n }\n }\n }\n if ([\"Partial\"].includes(refType.id)) {\n if (refType.args?.length !== 1) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const obj = getZodTypeFromApiParamType(refType.args[0], references);\n return (obj as any).partial();\n }\n\n const reference = references[refType.id];\n if (reference === undefined) {\n return z.string();\n // throw new Error(`ref 참조 불가 ${refType.id}`);\n }\n return reference;\n case \"union\":\n const unionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n // nullable 유니온\n if (\n unionType.types.length === 2 &&\n unionType.types.some((type) => type === \"null\")\n ) {\n if (unionType.types[0] === \"null\") {\n return getZodTypeFromApiParamType(\n unionType.types[1],\n references\n ).nullable();\n } else {\n return getZodTypeFromApiParamType(\n unionType.types[0],\n references\n ).nullable();\n }\n }\n\n // 일반 유니온\n return z.union(\n unionType.types.map((type) =>\n getZodTypeFromApiParamType(type, references)\n ) as any\n );\n case \"intersection\":\n const intersectionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n return intersectionType.types.reduce((result, type, index) => {\n const resolvedType = getZodTypeFromApiParamType(type, references);\n if (index === 0) {\n return resolvedType;\n } else {\n return z.intersection(result as any, resolvedType);\n }\n }, z.unknown() as any) as any;\n case \"tuple-type\":\n const tupleType = paramType as ApiParamType.TupleType;\n return z.tuple(\n tupleType.elements.map((elem) =>\n getZodTypeFromApiParamType(elem, references)\n ) as any\n );\n }\n return z.unknown();\n }\n}\n\nexport function propNodeToZodTypeDef(\n propNode: EntityPropNode,\n injectImportKeys: string[]\n): string {\n if (propNode.nodeType === \"plain\") {\n return propToZodTypeDef(propNode.prop, injectImportKeys);\n } else if (propNode.nodeType === \"array\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.array(z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n \"})),\",\n ].join(\"\\n\");\n } else if (propNode.nodeType === \"object\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n `})${propNode.prop && propNode.prop.nullable ? \".nullable()\" : \"\"},`,\n ].join(\"\\n\");\n } else {\n throw Error;\n }\n}\n\nexport function getTextTypeLength(textType: TextProp[\"textType\"]): number {\n switch (textType) {\n case \"text\":\n return 1024 * 64 - 1;\n case \"mediumtext\":\n return 1024 * 1024 * 16 - 1;\n case \"longtext\":\n return 1024 * 1024 * 1024 * 4 - 1;\n }\n}\n\nexport function propToZodTypeDef(\n prop: EntityProp,\n injectImportKeys: string[]\n): string {\n let stmt: string;\n if (isIntegerProp(prop)) {\n stmt = `${prop.name}: z.number().int()`;\n } else if (isBigIntegerProp(prop)) {\n stmt = `${prop.name}: z.bigint()`;\n } else if (isTextProp(prop)) {\n stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;\n } else if (isEnumProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isStringProp(prop)) {\n stmt = `${prop.name}: z.string().max(${prop.length})`;\n } else if (isDecimalProp(prop)) {\n stmt = `${prop.name}: z.string()`;\n } else if (isFloatProp(prop) || isDoubleProp(prop)) {\n stmt = `${prop.name}: z.number()`;\n } else if (isBooleanProp(prop)) {\n stmt = `${prop.name}: z.boolean()`;\n } else if (isDateProp(prop)) {\n stmt = `${prop.name}: z.string().length(10)`;\n } else if (isTimeProp(prop)) {\n stmt = `${prop.name}: z.string().length(8)`;\n } else if (isDateTimeProp(prop)) {\n stmt = `${prop.name}: SQLDateTimeString`;\n } else if (isTimestampProp(prop)) {\n stmt = `${prop.name}: SQLDateTimeString`;\n } else if (isJsonProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isUuidProp(prop)) {\n stmt = `${prop.name}: z.string().uuid()`;\n } else if (isVirtualProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isRelationProp(prop)) {\n if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n stmt = `${prop.name}_id: z.number().int()`;\n } else {\n // 그외 relation 케이스 제외\n return `// ${prop.name}: ${prop.relationType} ${prop.with}`;\n }\n } else {\n return \"// unable to resolve\";\n }\n\n if ((prop as { unsigned?: boolean }).unsigned) {\n stmt += \".nonnegative()\";\n }\n if (prop.nullable) {\n stmt += \".nullable()\";\n }\n\n return stmt + \",\";\n}\n\nexport function zodTypeToZodCode(\n zt: z.ZodFirstPartySchemaTypes | z.ZodObject<any>\n): string {\n switch (zt._def.typeName) {\n case \"ZodString\":\n return \"z.string()\";\n case \"ZodNumber\":\n return \"z.number()\";\n case \"ZodBoolean\":\n return \"z.boolean()\";\n case \"ZodBigInt\":\n return \"z.bigint()\";\n case \"ZodDate\":\n return \"z.date()\";\n case \"ZodNull\":\n return \"z.null()\";\n case \"ZodUndefined\":\n return \"z.undefined()\";\n case \"ZodAny\":\n return \"z.any()\";\n case \"ZodUnknown\":\n return \"z.unknown()\";\n case \"ZodNever\":\n return \"z.never()\";\n case \"ZodNullable\":\n return zodTypeToZodCode(zt._def.innerType) + \".nullable()\";\n case \"ZodDefault\":\n return (\n zodTypeToZodCode(zt._def.innerType) +\n `.default(${zt._def.defaultValue()})`\n );\n case \"ZodRecord\":\n return `z.record(${zodTypeToZodCode(zt._def.keyType)}, ${zodTypeToZodCode(\n zt._def.valueType\n )})`;\n case \"ZodLiteral\":\n if (typeof zt._def.value === \"string\") {\n return `z.literal(\"${zt._def.value}\")`;\n } else {\n return `z.literal(${zt._def.value})`;\n }\n case \"ZodUnion\":\n return `z.union([${zt._def.options\n .map((option: z.ZodTypeAny) => zodTypeToZodCode(option))\n .join(\",\")}])`;\n case \"ZodEnum\":\n return `z.enum([${zt._def.values\n .map((val: string) => `\"${val}\"`)\n .join(\", \")}])`;\n case \"ZodArray\":\n return `z.array(${zodTypeToZodCode(zt._def.type)})`;\n case \"ZodObject\":\n const shape = (zt as any).shape;\n return [\n \"z.object({\",\n ...Object.keys(shape).map(\n (key) => `${key}: ${zodTypeToZodCode(shape[key])},`\n ),\n \"})\",\n ].join(\"\\n\");\n case \"ZodOptional\":\n return zodTypeToZodCode(zt._def.innerType) + \".optional()\";\n default:\n throw new Error(`처리되지 않은 ZodType ${zt._def.typeName}`);\n }\n}\n\nexport function apiParamToTsCode(\n params: ApiParam[],\n injectImportKeys: string[]\n): string {\n return params\n .map((param) => {\n return `${param.name}${\n param.optional && !param.defaultDef ? \"?\" : \"\"\n }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${\n param.defaultDef ? `= ${param.defaultDef}` : \"\"\n }`;\n })\n .join(\", \");\n}\n\nexport function apiParamTypeToTsType(\n paramType: ApiParamType,\n injectImportKeys: string[]\n): string {\n if (\n [\n \"string\",\n \"number\",\n \"boolean\",\n \"true\",\n \"false\",\n \"null\",\n \"undefined\",\n \"void\",\n \"any\",\n \"unknown\",\n ].includes(paramType as string)\n ) {\n return paramType as string;\n } else if (ApiParamType.isObject(paramType)) {\n return `{ ${apiParamToTsCode(paramType.props, injectImportKeys)} }`;\n } else if (ApiParamType.isStringLiteral(paramType)) {\n return `\"${paramType.value}\"`;\n } else if (ApiParamType.isNumericLiteral(paramType)) {\n return String(paramType.value);\n } else if (ApiParamType.isUnion(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" | \");\n } else if (ApiParamType.isIntersection(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" & \");\n } else if (ApiParamType.isArray(paramType)) {\n return (\n apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + \"[]\"\n );\n } else if (ApiParamType.isRef(paramType)) {\n if (\n [\"Pick\", \"Omit\", \"Promise\", \"Partial\"].includes(paramType.id) === false\n ) {\n // importKeys 인젝션\n injectImportKeys.push(paramType.id);\n }\n if (paramType.args === undefined || paramType.args.length === 0) {\n return paramType.id;\n } else {\n return `${paramType.id}<${paramType.args\n .map((arg) => apiParamTypeToTsType(arg, injectImportKeys))\n .join(\",\")}>`;\n }\n } else if (ApiParamType.isIndexedAccess(paramType)) {\n return `${apiParamTypeToTsType(\n paramType.object,\n injectImportKeys\n )}[${apiParamTypeToTsType(paramType.index, injectImportKeys)}]`;\n } else if (ApiParamType.isTupleType(paramType)) {\n return `[ ${paramType.elements.map((elem) =>\n apiParamTypeToTsType(elem, injectImportKeys)\n )} ]`;\n } else if (ApiParamType.isTypeParam(paramType)) {\n return `<${paramType.id}${\n paramType.constraint\n ? ` extends ${apiParamTypeToTsType(\n paramType.constraint,\n injectImportKeys\n )}`\n : \"\"\n }>`;\n } else {\n throw new Error(`resolve 불가 ApiParamType ${paramType}`);\n }\n}\n\nexport function unwrapPromiseOnce(paramType: ApiParamType) {\n if (ApiParamType.isPromise(paramType)) {\n return paramType.args![0];\n } else {\n return paramType;\n }\n}\n\nexport function serializeZodType(zt: z.ZodTypeAny): any {\n switch (zt._def.typeName) {\n case \"ZodObject\":\n return {\n type: \"object\",\n shape: Object.keys((zt as z.ZodObject<any>).shape).reduce(\n (result, key) => {\n return {\n ...result,\n [key]: serializeZodType((zt as z.ZodObject<any>).shape[key]),\n };\n },\n {}\n ),\n };\n case \"ZodArray\":\n return {\n type: \"array\",\n element: serializeZodType(zt._def.type),\n };\n case \"ZodEnum\":\n return {\n type: \"enum\",\n values: zt._def.values,\n };\n case \"ZodString\":\n return {\n type: \"string\",\n checks: zt._def.checks,\n };\n case \"ZodNumber\":\n return {\n type: \"number\",\n checks: zt._def.checks,\n };\n case \"ZodBoolean\":\n return {\n type: \"boolean\",\n };\n case \"ZodNullable\":\n return {\n ...serializeZodType(zt._def.innerType),\n nullable: true,\n };\n case \"ZodOptional\":\n return {\n ...serializeZodType(zt._def.innerType),\n optional: true,\n };\n case \"ZodAny\":\n return {\n type: \"any\",\n };\n case \"ZodRecord\":\n return {\n type: \"record\",\n keyType: serializeZodType((zt as ZodRecord)._def.keyType),\n valueType: serializeZodType((zt as ZodRecord)._def.valueType),\n };\n case \"ZodUnion\":\n return {\n type: \"union\",\n options: (zt._def as z.ZodUnionDef).options.map((option) =>\n serializeZodType(option)\n ),\n };\n default:\n throw new Error(\n `Serialize 로직이 정의되지 않은 ZodType: ${zt._def.typeName}`\n );\n }\n}\n\nexport function zodTypeToTsTypeDef(\n zt: z.ZodFirstPartySchemaTypes | z.ZodObject<any>\n): string {\n if (zt._def.description) {\n return zt._def.description;\n }\n\n switch (zt._def.typeName) {\n case \"ZodString\":\n return \"string\";\n case \"ZodNumber\":\n return \"number\";\n case \"ZodBoolean\":\n return \"boolean\";\n case \"ZodBigInt\":\n return \"bigint\";\n case \"ZodDate\":\n return \"date\";\n case \"ZodNull\":\n return \"null\";\n case \"ZodUndefined\":\n return \"undefined\";\n case \"ZodAny\":\n return \"any\";\n case \"ZodUnknown\":\n return \"unknown\";\n case \"ZodNever\":\n return \"never\";\n case \"ZodNullable\":\n return zodTypeToTsTypeDef(zt._def.innerType) + \" | null\";\n case \"ZodDefault\":\n return zodTypeToTsTypeDef(zt._def.innerType);\n case \"ZodRecord\":\n return `{ [ key: ${zodTypeToTsTypeDef(\n zt._def.keyType\n )} ]: ${zodTypeToTsTypeDef(zt._def.valueType)}}`;\n case \"ZodLiteral\":\n if (typeof zt._def.value === \"string\") {\n return `\"${zt._def.value}\"`;\n } else {\n return `${zt._def.value}`;\n }\n case \"ZodUnion\":\n return `${zt._def.options\n .map((option: z.ZodTypeAny) => zodTypeToTsTypeDef(option))\n .join(\" | \")}`;\n case \"ZodEnum\":\n return `${zt._def.values.map((val: string) => `\"${val}\"`).join(\" | \")}`;\n case \"ZodArray\":\n return `${zodTypeToTsTypeDef(zt._def.type)}[]`;\n case \"ZodObject\":\n const shape = (zt as any).shape;\n return [\n \"{\",\n ...Object.keys(shape).map((key) => {\n if (shape[key]._def.typeName === \"ZodOptional\") {\n return `${key}?: ${zodTypeToTsTypeDef(shape[key]._def.innerType)},`;\n } else {\n return `${key}: ${zodTypeToTsTypeDef(shape[key])},`;\n }\n }),\n \"}\",\n ].join(\"\\n\");\n case \"ZodOptional\":\n return zodTypeToTsTypeDef(zt._def.innerType) + \" | undefined\";\n default:\n throw new Error(`처리되지 않은 ZodType ${zt._def.typeName}`);\n }\n}\n","import { HTTPMethods } from \"fastify\";\nimport inflection from \"inflection\";\nimport { ApiParam, ApiParamType } from \"../types/types\";\n\nexport type ServiceClient =\n | \"axios\"\n | \"axios-multipart\"\n | \"swr\"\n | \"socketio\"\n | \"window-fetch\";\nexport type ApiDecoratorOptions = {\n httpMethod?: HTTPMethods;\n contentType?:\n | \"text/plain\"\n | \"text/html\"\n | \"text/xml\"\n | \"application/json\"\n | \"application/octet-stream\";\n clients?: ServiceClient[];\n path?: string;\n resourceName?: string;\n guards?: string[];\n description?: string;\n};\nexport const registeredApis: {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n}[] = [];\nexport type ExtendedApi = {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n typeParameters: ApiParamType.TypeParam[];\n parameters: ApiParam[];\n returnType: ApiParamType;\n};\n\nexport function api(options: ApiDecoratorOptions = {}) {\n options = {\n httpMethod: \"GET\",\n contentType: \"application/json\",\n clients: [\"axios\"],\n ...options,\n };\n\n return function (target: Object, propertyKey: string) {\n const modelName = target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = propertyKey;\n const defaultPath = `/${inflection.camelize(\n modelName.replace(/Model$/, \"\"),\n true\n )}/${inflection.camelize(propertyKey, true)}`;\n\n const api = {\n modelName,\n methodName,\n path: options.path ?? defaultPath,\n options,\n };\n registeredApis.push(api);\n };\n}\n","export abstract class SoException extends Error {\n constructor(\n public readonly statusCode: number,\n public message: string,\n public payload?: unknown\n ) {\n super(message);\n }\n}\n\nexport function isSoException(err: any): err is SoException {\n return err.statusCode !== undefined;\n}\n\n/*\n\t잘못된 매개변수 등 요청사항에 문제가 있는 경우\n*/\nexport class BadRequestException extends SoException {\n constructor(\n public message = \"Bad Request\",\n public payload?: unknown\n ) {\n super(400, message, payload);\n }\n}\n\n/*\n\t로그인이 반드시 필요한 케이스에 로그아웃 상태인 경우 / 접근 권한이 없는 요청시\n*/\nexport class UnauthorizedException extends SoException {\n constructor(\n public message = \"Unauthorized\",\n public payload?: unknown\n ) {\n super(401, message, payload);\n }\n}\n\n/*\n\t존재하지 않는 레코드에 접근시\n*/\nexport class NotFoundException extends SoException {\n constructor(\n public message = \"Not Found\",\n public payload?: unknown\n ) {\n super(404, message, payload);\n }\n}\n\n/*\n\t현재 상태에서 처리가 불가능한 케이스\n*/\nexport class ServiceUnavailableException extends SoException {\n constructor(\n public message = \"Service Unavailable\",\n public payload?: unknown\n ) {\n super(503, message, payload);\n }\n}\n\n/*\n\t내부 처리 로직 (외부 API 콜 포함) 오류 발생시\n*/\nexport class InternalServerErrorException extends SoException {\n constructor(\n public message = \"Internal Server Error\",\n public payload?: unknown\n ) {\n super(500, message, payload);\n }\n}\n\n/*\n\t이미 처리함\n*/\nexport class AlreadyProcessedException extends SoException {\n constructor(\n public message = \"Already Processed\",\n public payload?: unknown\n ) {\n super(541, message, payload);\n }\n}\n\n/*\n\t중복 허용하지 않는 케이스에 중복 요청\n*/\nexport class DuplicateRowException extends SoException {\n constructor(\n public message = \"Duplicate Row\",\n public payload?: unknown\n ) {\n super(542, message, payload);\n }\n}\n\n/*\n\t뭔가를 하려고 했으나 대상이 없음\n*/\nexport class TargetNotFoundException extends SoException {\n constructor(\n public message = \"Target Not Found\",\n public payload?: unknown\n ) {\n super(520, message, payload);\n }\n}\n","import path from \"path\";\nimport glob from \"glob\";\nimport fs from \"fs-extra\";\nimport _ from \"lodash\";\n\nexport function globAsync(pathPattern: string): Promise<string[]> {\n return new Promise((resolve, reject) => {\n glob(path.resolve(pathPattern), (err, files) => {\n if (err) {\n reject(err);\n } else {\n resolve(files);\n }\n });\n });\n}\nexport async function importMultiple(\n filePaths: string[],\n doRefresh: boolean = false\n): Promise<{ filePath: string; imported: any }[]> {\n const results: { filePath: string; imported: any }[] = [];\n\n for (const filePath of filePaths) {\n let importPath = \"./\" + path.relative(__dirname, filePath);\n\n if (doRefresh) {\n if (require.resolve) {\n delete require.cache[require.resolve(importPath)];\n } else {\n importPath += `?t=${Date.now()}`;\n }\n }\n\n const imported = await import(importPath);\n results.push({\n filePath,\n imported,\n });\n }\n\n return results;\n}\nexport async function findAppRootPath() {\n const apiRootPath = findApiRootPath();\n return apiRootPath.split(path.sep).slice(0, -1).join(path.sep);\n}\n\nexport function findApiRootPath() {\n const basePath = require.main?.path ?? __dirname;\n let dir = path.dirname(basePath);\n if (dir.includes(\"/.yarn/\")) {\n dir = dir.split(\"/.yarn/\")[0];\n }\n do {\n if (fs.existsSync(path.join(dir, \"/package.json\"))) {\n return dir.split(path.sep).join(path.sep);\n }\n dir = dir.split(path.sep).slice(0, -1).join(path.sep);\n } while (dir.split(path.sep).length > 1);\n throw new Error(\"Cannot find AppRoot using Sonamu -2\");\n}\n\nexport function nonNullable<T>(value: T): value is NonNullable<T> {\n return value !== null && value !== undefined;\n}\n\nexport function hydrate<T>(rows: T[]): T[] {\n return rows.map((row: any) => {\n // nullable relation인 경우 관련된 필드가 전부 null로 생성되는 것 방지하는 코드\n const nestedKeys = Object.keys(row).filter((key) => key.includes(\"__\"));\n const groups = _.groupBy(nestedKeys, (key) => key.split(\"__\")[0]);\n const nullKeys = Object.keys(groups).filter(\n (key) =>\n groups[key].length > 1 &&\n groups[key].every((field) => row[field] === null)\n );\n\n const hydrated = Object.keys(row).reduce((r, field) => {\n if (!field.includes(\"__\")) {\n if (Array.isArray(row[field]) && _.isObject(row[field][0])) {\n r[field] = hydrate(row[field]);\n return r;\n } else {\n r[field] = row[field];\n return r;\n }\n }\n\n const parts = field.split(\"__\");\n const objPath =\n parts[0] +\n parts\n .slice(1)\n .map((part) => `[${part}]`)\n .join(\"\");\n _.set(\n r,\n objPath,\n row[field] && Array.isArray(row[field]) && _.isObject(row[field][0])\n ? hydrate(row[field])\n : row[field]\n );\n\n return r;\n }, {} as any);\n nullKeys.map((nullKey) => (hydrated[nullKey] = null));\n\n return hydrated;\n });\n}\n","import _ from \"lodash\";\nimport { EntityManager as EntityManager } from \"./entity-manager\";\nimport {\n EntityProp,\n RelationProp,\n isRelationProp,\n SubsetQuery,\n isVirtualProp,\n isBelongsToOneRelationProp,\n isOneToOneRelationProp,\n isHasManyRelationProp,\n isManyToManyRelationProp,\n EntityPropNode,\n isEnumProp,\n StringProp,\n EntityIndex,\n EntityJson,\n EntitySubsetRow,\n} from \"../types/types\";\nimport inflection from \"inflection\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { z } from \"zod\";\nimport { Sonamu } from \"../api/sonamu\";\nimport prettier from \"prettier\";\nimport { nonNullable } from \"../utils/utils\";\n\nexport class Entity {\n id: string;\n parentId?: string;\n table: string;\n title: string;\n names: {\n parentFs: string;\n fs: string;\n module: string;\n };\n props: EntityProp[];\n propsDict: {\n [key: string]: EntityProp;\n };\n relations: {\n [key: string]: RelationProp;\n };\n indexes: EntityIndex[];\n subsets: {\n [key: string]: string[];\n };\n types: {\n [name: string]: z.ZodTypeAny;\n } = {};\n enums: {\n [enumId: string]: z.ZodEnum<any>;\n } = {};\n enumLabels: {\n [enumId: string]: {\n [key: string]: string;\n };\n } = {};\n\n constructor({\n id,\n parentId,\n table,\n title,\n props,\n indexes,\n subsets,\n enums,\n }: EntityJson) {\n // id\n this.id = id;\n this.parentId = parentId;\n this.title = title ?? this.id;\n this.table = table ?? inflection.underscore(inflection.pluralize(id));\n\n // props\n if (props) {\n this.props = props.map((prop) => {\n if (isEnumProp(prop)) {\n if (prop.id.includes(\"$Model\")) {\n prop.id = prop.id.replace(\"$Model\", id);\n }\n }\n return prop;\n });\n this.propsDict = props.reduce((result, prop) => {\n return {\n ...result,\n [prop.name]: prop,\n };\n }, {});\n\n // relations\n this.relations = props\n .filter((prop) => isRelationProp(prop))\n .reduce((result, prop) => {\n return {\n ...result,\n [prop.name]: prop,\n };\n }, {});\n } else {\n this.props = [];\n this.propsDict = {};\n this.relations = {};\n }\n\n // indexes\n this.indexes = indexes ?? [];\n\n // subsets\n this.subsets = subsets ?? {};\n\n // enums\n this.enumLabels = enums ?? {};\n this.enums = Object.fromEntries(\n Object.entries(this.enumLabels).map(([key, enumLabel]) => {\n return [\n key,\n z.enum(\n Object.keys(enumLabel) as unknown as readonly [string, ...string[]]\n ),\n ];\n })\n );\n\n // names\n this.names = {\n parentFs: inflection\n .dasherize(inflection.underscore(parentId ?? id))\n .toLowerCase(),\n fs: inflection.dasherize(inflection.underscore(id)).toLowerCase(),\n module: id,\n };\n }\n\n /*\n subset SELECT/JOIN/LOADER 결과 리턴\n */\n getSubsetQuery(subsetKey: string): SubsetQuery {\n const subset = this.subsets[subsetKey];\n\n const result: SubsetQuery = this.resolveSubsetQuery(\"\", subset);\n return result;\n }\n\n /*\n */\n resolveSubsetQuery(\n prefix: string,\n fields: string[],\n isAlreadyOuterJoined: boolean = false\n ): SubsetQuery {\n // prefix 치환 (prefix는 ToOneRelation이 복수로 붙은 경우 모두 __로 변경됨)\n prefix = prefix.replace(/\\./g, \"__\");\n\n // 서브셋을 1뎁스만 분리하여 그룹핑\n const subsetGroup = _.groupBy(fields, (field) => {\n if (field.includes(\".\")) {\n const [rel] = field.split(\".\");\n return rel;\n } else {\n return \"\";\n }\n });\n\n const result = Object.keys(subsetGroup).reduce(\n (r, groupKey) => {\n const fields = subsetGroup[groupKey];\n // 현재 테이블 필드셋은 select, virtual에 추가하고 리턴\n if (groupKey === \"\") {\n const realFields = fields.filter(\n (field) => !isVirtualProp(this.propsDict[field])\n );\n const virtualFields = fields.filter((field) =>\n isVirtualProp(this.propsDict[field])\n );\n\n if (prefix === \"\") {\n // 현재 테이블인 경우\n r.select = r.select.concat(\n realFields.map((field) => `${this.table}.${field}`)\n );\n r.virtual = r.virtual.concat(virtualFields);\n } else {\n // 넘어온 테이블인 경우\n r.select = r.select.concat(\n realFields.map(\n (field) => `${prefix}.${field} as ${prefix}__${field}`\n )\n );\n }\n\n return r;\n }\n\n const relation = this.relations[groupKey];\n if (relation === undefined) {\n throw new Error(`존재하지 않는 relation 참조 ${groupKey}`);\n }\n const relEntity = EntityManager.get(relation.with);\n\n if (\n isOneToOneRelationProp(relation) ||\n isBelongsToOneRelationProp(relation)\n ) {\n // -One Relation: JOIN 으로 처리\n const relFields = fields.map((field) =>\n field.split(\".\").slice(1).join(\".\")\n );\n\n // -One Relation에서 id 필드만 참조하는 경우 릴레이션 넘기지 않고 리턴\n if (relFields.length === 1 && relFields[0] === \"id\") {\n if (prefix === \"\") {\n r.select = r.select.concat(`${this.table}.${groupKey}_id`);\n } else {\n r.select = r.select.concat(\n `${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`\n );\n }\n return r;\n }\n\n // innerOrOuter\n const innerOrOuter = (() => {\n if (isAlreadyOuterJoined) {\n return \"outer\";\n }\n\n if (isOneToOneRelationProp(relation)) {\n if (\n relation.hasJoinColumn === true &&\n (relation.nullable ?? false) === false\n ) {\n return \"inner\";\n } else {\n return \"outer\";\n }\n } else {\n if (relation.nullable) {\n return \"outer\";\n } else {\n return \"inner\";\n }\n }\n })();\n const relSubsetQuery = relEntity.resolveSubsetQuery(\n `${prefix !== \"\" ? prefix + \".\" : \"\"}${groupKey}`,\n relFields,\n innerOrOuter === \"outer\"\n );\n r.select = r.select.concat(relSubsetQuery.select);\n r.virtual = r.virtual.concat(relSubsetQuery.virtual);\n\n const joinAs = prefix === \"\" ? groupKey : prefix + \"__\" + groupKey;\n const fromTable = prefix === \"\" ? this.table : prefix;\n\n let joinClause;\n if (relation.customJoinClause) {\n joinClause = {\n custom: relation.customJoinClause,\n };\n } else {\n let from, to;\n if (isOneToOneRelationProp(relation)) {\n if (relation.hasJoinColumn) {\n from = `${fromTable}.${relation.name}_id`;\n to = `${joinAs}.id`;\n } else {\n from = `${fromTable}.id`;\n to = `${joinAs}.${inflection.underscore(\n this.names.fs.replace(/\\-/g, \"_\")\n )}_id`;\n }\n } else {\n from = `${fromTable}.${relation.name}_id`;\n to = `${joinAs}.id`;\n }\n joinClause = {\n from,\n to,\n };\n }\n\n r.joins.push({\n as: joinAs,\n join: innerOrOuter,\n table: relEntity.table,\n ...joinClause,\n });\n\n // BelongsToOne 밑에 HasMany가 붙은 경우\n if (relSubsetQuery.loaders.length > 0) {\n const convertedLoaders = relSubsetQuery.loaders.map((loader) => {\n const newAs = [groupKey, loader.as].join(\"__\");\n return {\n as: newAs,\n table: loader.table,\n manyJoin: loader.manyJoin,\n oneJoins: loader.oneJoins,\n select: loader.select,\n loaders: loader.loaders,\n };\n });\n\n r.loaders = [...r.loaders, ...convertedLoaders];\n }\n\n r.joins = r.joins.concat(relSubsetQuery.joins);\n } else if (\n isHasManyRelationProp(relation) ||\n isManyToManyRelationProp(relation)\n ) {\n // -Many Relation: Loader 로 처리\n const relFields = fields.map((field) =>\n field.split(\".\").slice(1).join(\".\")\n );\n const relSubsetQuery = relEntity.resolveSubsetQuery(\"\", relFields);\n\n let manyJoin: SubsetQuery[\"loaders\"][number][\"manyJoin\"];\n if (isHasManyRelationProp(relation)) {\n const fromCol = relation?.fromColumn ?? \"id\";\n manyJoin = {\n fromTable: this.table,\n fromCol,\n idField: prefix === \"\" ? `${fromCol}` : `${prefix}__${fromCol}`,\n toTable: relEntity.table,\n toCol: relation.joinColumn,\n };\n } else if (isManyToManyRelationProp(relation)) {\n const [table1, table2] = relation.joinTable.split(\"__\");\n const throughTables = (() => {\n // 동일 테이블 릴레이션인 경우\n if (this.table === relEntity.table) {\n if (table1 === this.table) {\n return {\n fromCol: `${inflection.singularize(table1)}_id`,\n toCol: `${inflection.singularize(table2)}_id`,\n };\n } else {\n return {\n fromCol: `${inflection.singularize(table2)}_id`,\n toCol: `${inflection.singularize(table1)}_id`,\n };\n }\n } else {\n // 서로 다른 테이블인 경우 릴레이션 테이블 유지\n return {\n fromCol: `${inflection.singularize(this.table)}_id`,\n toCol: `${inflection.singularize(relEntity.table)}_id`,\n };\n }\n })();\n\n manyJoin = {\n fromTable: this.table,\n fromCol: \"id\",\n idField: prefix === \"\" ? `id` : `${prefix}__id`,\n through: {\n table: relation.joinTable,\n ...throughTables,\n },\n toTable: relEntity.table,\n toCol: \"id\",\n };\n } else {\n throw new Error();\n }\n\n r.loaders.push({\n as: groupKey,\n table: relEntity.table,\n manyJoin,\n oneJoins: relSubsetQuery.joins,\n select: relSubsetQuery.select,\n loaders: relSubsetQuery.loaders,\n });\n }\n\n return r;\n },\n {\n select: [],\n virtual: [],\n joins: [],\n loaders: [],\n } as SubsetQuery\n );\n return result;\n }\n\n /*\n FieldExpr[] 을 EntityPropNode[] 로 변환\n */\n fieldExprsToPropNodes(\n fieldExprs: string[],\n entity: Entity = this\n ): EntityPropNode[] {\n const groups = fieldExprs.reduce(\n (result, fieldExpr) => {\n let key, value, elseExpr;\n if (fieldExpr.includes(\".\")) {\n [key, ...elseExpr] = fieldExpr.split(\".\");\n value = elseExpr.join(\".\");\n } else {\n key = \"\";\n value = fieldExpr;\n }\n result[key] = (result[key] ?? []).concat(value);\n\n return result;\n },\n {} as {\n [k: string]: string[];\n }\n );\n\n return Object.keys(groups)\n .map((key) => {\n const group = groups[key];\n\n // 일반 prop 처리\n if (key === \"\") {\n return group.map((propName) => {\n // uuid 개별 처리\n if (propName === \"uuid\") {\n return {\n nodeType: \"plain\" as const,\n prop: {\n type: \"string\",\n name: \"uuid\",\n length: 128,\n } as StringProp,\n children: [],\n };\n }\n\n const prop = entity.props.find((p) => p.name === propName);\n if (prop === undefined) {\n console.log({ propName, groups });\n throw new Error(`${entity.id} -- 잘못된 FieldExpr ${propName}`);\n }\n return {\n nodeType: \"plain\" as const,\n prop,\n children: [],\n };\n });\n }\n\n // relation prop 처리\n const prop = entity.propsDict[key];\n if (!isRelationProp(prop)) {\n throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);\n }\n const relEntity = EntityManager.get(prop.with);\n\n // relation -One 에 id 필드 하나인 경우\n if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {\n if (group.length == 1 && (group[0] === \"id\" || group[0] == \"id?\")) {\n // id 하나만 있는지 체크해서, 하나만 있으면 상위 prop으로 id를 리턴\n const idProp = relEntity.propsDict.id;\n return {\n nodeType: \"plain\" as const,\n prop: {\n ...idProp,\n name: key + \"_id\",\n nullable: prop.nullable,\n },\n children: [],\n };\n }\n }\n\n // -One 그외의 경우 object로 리턴\n // -Many의 경우 array로 리턴\n // Recursive 로 뎁스 처리\n const children = this.fieldExprsToPropNodes(group, relEntity);\n const nodeType =\n isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)\n ? (\"object\" as const)\n : (\"array\" as const);\n\n return {\n prop,\n children,\n nodeType,\n };\n })\n .flat();\n }\n\n getFieldExprs(\n prefix = \"\",\n maxDepth: number = 3,\n froms: string[] = []\n ): string[] {\n return this.props\n .map((prop) => {\n const propName = [prefix, prop.name].filter((v) => v !== \"\").join(\".\");\n if (propName === prefix) {\n return null;\n }\n if (isRelationProp(prop)) {\n if (maxDepth < 0) {\n return null;\n }\n if (froms.includes(prop.with)) {\n // 역방향 relation인 경우 제외\n return null;\n }\n // 정방향 relation인 경우 recursive 콜\n const relMd = EntityManager.get(prop.with);\n return relMd.getFieldExprs(propName, maxDepth - 1, [\n ...froms,\n this.id,\n ]);\n }\n return propName;\n })\n .flat()\n .filter((f) => f !== null) as string[];\n }\n\n getTableColumns(): string[] {\n return this.props\n .map((prop) => {\n if (prop.type === \"relation\") {\n if (\n prop.relationType === \"BelongsToOne\" ||\n (prop.relationType === \"OneToOne\" && prop.hasJoinColumn === true)\n ) {\n return `${prop.name}_id`;\n } else {\n return null;\n }\n }\n return prop.name;\n })\n .filter(nonNullable);\n }\n\n async registerModulePaths() {\n const basePath = `${this.names.parentFs}`;\n\n // base-scheme\n EntityManager.setModulePath(`${this.id}BaseSchema`, `sonamu.generated`);\n\n // subset\n if (Object.keys(this.subsets).length > 0) {\n EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);\n EntityManager.setModulePath(\n `${this.id}SubsetMapping`,\n `sonamu.generated`\n );\n Object.keys(this.subsets).map((subsetKey) => {\n EntityManager.setModulePath(\n `${this.id}Subset${subsetKey.toUpperCase()}`,\n `sonamu.generated`\n );\n });\n }\n\n // enums\n Object.keys(this.enumLabels).map((enumId) => {\n EntityManager.setModulePath(enumId, `sonamu.generated`);\n });\n\n // types\n const typesModulePath = `${basePath}/${this.names.parentFs}.types`;\n const typesFileDistPath = path.join(\n Sonamu.apiRootPath,\n `dist/application/${typesModulePath}.js`\n );\n\n if (fs.existsSync(typesFileDistPath)) {\n const importPath = path.relative(__dirname, typesFileDistPath);\n const t = await import(importPath);\n this.types = Object.keys(t).reduce((result, key) => {\n EntityManager.setModulePath(key, typesModulePath);\n return {\n ...result,\n [key]: t[key],\n };\n }, {});\n }\n }\n\n registerTableSpecs(): void {\n const uniqueIndexes = this.indexes.filter((idx) => idx.type === \"unique\");\n\n EntityManager.setTableSpec({\n name: this.table,\n uniqueIndexes,\n });\n }\n\n toJson(): EntityJson {\n return {\n id: this.id,\n parentId: this.parentId,\n table: this.table,\n title: this.title,\n props: this.props,\n indexes: this.indexes,\n subsets: this.subsets,\n enums: this.enumLabels,\n };\n }\n\n async save(): Promise<void> {\n // sort: subsets\n const subsetRows = this.getSubsetRows();\n this.subsets = Object.fromEntries(\n Object.entries(this.subsets).map(([subsetKey]) => {\n return [\n subsetKey,\n this.subsetRowsToSubsetFields(subsetRows, subsetKey),\n ];\n })\n );\n\n // save\n const jsonPath = path.join(\n Sonamu.apiRootPath,\n `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`\n );\n const json = this.toJson();\n fs.writeFileSync(\n jsonPath,\n await prettier.format(JSON.stringify(json), {\n parser: \"json\",\n })\n );\n\n // reload\n await EntityManager.register(json);\n }\n\n getSubsetRows(\n _subsets?: { [key: string]: string[] },\n prefixes: string[] = []\n ): EntitySubsetRow[] {\n if (prefixes.length > 10) {\n return [];\n }\n\n const subsets = _subsets ?? this.subsets;\n const subsetKeys = Object.keys(subsets);\n const allFields = _.uniq(subsetKeys.map((key) => subsets[key]).flat());\n\n return this.props.map((prop) => {\n if (\n prop.type === \"relation\" &&\n allFields.find((f) =>\n f.startsWith([...prefixes, prop.name].join(\".\") + \".\")\n )\n ) {\n const relEntity = EntityManager.get(prop.with);\n const children = relEntity.getSubsetRows(subsets, [\n ...prefixes,\n `${prop.name}`,\n ]);\n\n return {\n field: prop.name,\n children,\n relationEntity: prop.with,\n prefixes,\n isOpen: children.length > 0,\n has: Object.fromEntries(\n subsetKeys.map((subsetKey) => {\n return [\n subsetKey,\n children.every((child) => child.has[subsetKey] === true),\n ];\n })\n ),\n };\n }\n\n return {\n field: prop.name,\n children: [],\n relationEntity: prop.type === \"relation\" ? prop.with : undefined,\n prefixes,\n has: Object.fromEntries(\n subsetKeys.map((subsetKey) => {\n const subsetFields = subsets[subsetKey];\n const has = subsetFields.some((f) => {\n const field = [...prefixes, prop.name].join(\".\");\n return f === field || f.startsWith(field + \".\");\n });\n return [subsetKey, has];\n })\n ),\n };\n });\n }\n\n subsetRowsToSubsetFields(\n subsetRows: EntitySubsetRow[],\n subsetKey: string\n ): string[] {\n return subsetRows\n .map((subsetRow) => {\n if (subsetRow.children.length > 0) {\n return this.subsetRowsToSubsetFields(subsetRow.children, subsetKey);\n } else if (subsetRow.has[subsetKey]) {\n return subsetRow.prefixes.concat(subsetRow.field).join(\".\");\n } else {\n return null;\n }\n })\n .filter(nonNullable)\n .flat();\n }\n\n async createProp(prop: EntityProp, at?: number): Promise<void> {\n if (!at) {\n this.props.push(prop);\n } else {\n this.props.splice(at, 0, prop);\n }\n await this.save();\n }\n\n analyzeSubsetField(subsetField: string): {\n entityId: string;\n propName: string;\n }[] {\n const arr = subsetField.split(\".\");\n\n let entityId = this.id;\n const result: {\n entityId: string;\n propName: string;\n }[] = [];\n for (let i = 0; i < arr.length; i++) {\n const propName = arr[i];\n result.push({\n entityId,\n propName,\n });\n\n const prop = EntityManager.get(entityId).props.find(\n (p) => p.name === propName\n );\n if (!prop) {\n throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);\n }\n if (isRelationProp(prop)) {\n entityId = prop.with;\n }\n }\n return result;\n }\n\n async modifyProp(newProp: EntityProp, at: number): Promise<void> {\n // 이전 프롭 이름 저장\n const oldName = this.props[at].name;\n\n // 저장할 엔티티\n const entities: Entity[] = [this];\n\n // 이름이 바뀐 경우\n if (oldName !== newProp.name) {\n // 전체 엔티티에서 현재 수정된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 수정\n const allEntityIds = EntityManager.getAllIds();\n for (const relEntityId of allEntityIds) {\n const relEntity = EntityManager.get(relEntityId);\n const relEntitySubsetKeys = Object.keys(relEntity.subsets);\n for (const subsetKey of relEntitySubsetKeys) {\n const subset = relEntity.subsets[subsetKey];\n\n // 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 수정 처리\n const modifiedSubsetFields = subset.map((subsetField) => {\n const analyzed = relEntity.analyzeSubsetField(subsetField);\n const modified = analyzed.map((a) =>\n a.propName === oldName && a.entityId === this.id\n ? {\n ...a,\n propName: newProp.name,\n }\n : a\n );\n // 분석한 필드를 다시 서브셋 필드로 복구\n return modified.map((a) => a.propName).join(\".\");\n });\n\n if (subset.join(\",\") !== modifiedSubsetFields.join(\",\")) {\n relEntity.subsets[subsetKey] = modifiedSubsetFields;\n entities.push(relEntity);\n }\n }\n }\n }\n\n // 프롭 수정\n this.props[at] = newProp;\n\n await Promise.all(entities.map(async (entity) => entity.save()));\n }\n\n async delProp(at: number): Promise<void> {\n // 이전 프롭 이름 저장\n const oldName = this.props[at].name;\n\n // 저장할 엔티티\n const entities: Entity[] = [this];\n\n // 전체 엔티티에서 현재 삭제된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 제외\n const allEntityIds = EntityManager.getAllIds();\n for (const relEntityId of allEntityIds) {\n const relEntity = EntityManager.get(relEntityId);\n const relEntitySubsetKeys = Object.keys(relEntity.subsets);\n for (const subsetKey of relEntitySubsetKeys) {\n const subset = relEntity.subsets[subsetKey];\n // 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 이후의 필드를 제외\n const modifiedSubsetFields = subset\n .map((subsetField) => {\n const analyzed = relEntity.analyzeSubsetField(subsetField);\n if (\n analyzed.find(\n (a) => a.propName === oldName && a.entityId === this.id\n )\n ) {\n return null;\n } else {\n return subsetField;\n }\n })\n .filter(nonNullable);\n\n if (subset.join(\",\") !== modifiedSubsetFields.join(\",\")) {\n relEntity.subsets[subsetKey] = modifiedSubsetFields;\n entities.push(relEntity);\n }\n }\n }\n\n // 현재 엔티티의 인덱스에서 제외\n EntityManager.get(this.id).indexes.map((index) => {\n index.columns = index.columns.filter((col) => col !== oldName);\n });\n\n // 프롭 삭제\n this.props.splice(at, 1);\n\n await Promise.all(entities.map(async (entity) => entity.save()));\n }\n\n getEntityIdFromSubsetField(subsetField: string): string {\n if (subsetField.includes(\".\") === false) {\n return this.id;\n }\n\n // 서브셋 필드의 마지막은 프롭이므로 제외\n const arr = subsetField.split(\".\").slice(0, -1);\n\n // 서브셋 필드를 내려가면서 마지막으로 relation된 엔티티를 찾음\n const lastEntityId = arr.reduce((entityId, field) => {\n const relProp = EntityManager.get(entityId).props.find(\n (p) => p.name === field\n );\n if (!relProp || relProp.type !== \"relation\") {\n console.debug({ arr, thisId: this.id, entityId, field });\n throw new Error(`잘못된 서브셋키 ${subsetField}`);\n }\n return relProp.with;\n }, this.id);\n return lastEntityId;\n }\n\n async moveProp(at: number, to: number): Promise<void> {\n const prop = this.props[at];\n const newProps = [...this.props];\n newProps.splice(to, 0, prop);\n newProps.splice(at < to ? at : at + 1, 1);\n this.props = newProps;\n\n await this.save();\n }\n}\n","import chalk from \"chalk\";\nimport glob from \"glob\";\nimport inflection from \"inflection\";\nimport _ from \"lodash\";\nimport path from \"path\";\nimport { Entity } from \"./entity\";\nimport { EntityJson } from \"../types/types\";\nimport { Sonamu } from \"../api/sonamu\";\nimport fs from \"fs-extra\";\n\nexport type EntityNamesRecord = Record<\n | \"fs\"\n | \"fsPlural\"\n | \"camel\"\n | \"camelPlural\"\n | \"capital\"\n | \"capitalPlural\"\n | \"upper\"\n | \"constant\",\n string\n>;\ntype TableSpec = {\n name: string;\n uniqueIndexes: { name?: string; columns: string[] }[];\n};\nclass EntityManagerClass {\n private entities: Map<string, Entity> = new Map();\n public modulePaths: Map<string, string> = new Map();\n private tableSpecs: Map<string, TableSpec> = new Map();\n public isAutoloaded: boolean = false;\n\n // 경로 전달받아 모든 entity.json 파일 로드\n async autoload(doSilent: boolean = false) {\n if (this.isAutoloaded) {\n return;\n }\n const pathPattern = path.join(\n Sonamu.apiRootPath,\n \"/src/application/**/*.entity.json\"\n );\n !doSilent && console.log(chalk.yellow(`autoload ${pathPattern}`));\n\n return new Promise((resolve) => {\n glob.glob(path.resolve(pathPattern!), (_err, files) => {\n Promise.all(\n files.map(async (file) => {\n await this.register(JSON.parse(fs.readFileSync(file).toString()));\n })\n ).then(() => {\n resolve(\"ok\");\n this.isAutoloaded = true;\n });\n });\n });\n }\n\n async reload(doSilent: boolean = false) {\n console.log(\"reload\");\n this.entities.clear();\n this.modulePaths.clear();\n this.tableSpecs.clear();\n this.isAutoloaded = false;\n\n const sonamuPath = path.join(\n Sonamu.apiRootPath,\n `dist/application/sonamu.generated.js?t=${Date.now()}`\n );\n // CJS\n if (require?.cache && require.cache[sonamuPath]) {\n delete require.cache[sonamuPath];\n }\n\n return await this.autoload(doSilent);\n }\n\n async register(json: EntityJson): Promise<void> {\n const entity = new Entity(json);\n await entity.registerModulePaths();\n entity.registerTableSpecs();\n this.entities.set(json.id, entity);\n // console.debug(chalk.cyan(`register :: ${entity.id}`));\n }\n\n get(entityId: string): Entity {\n const entity = this.entities.get(entityId);\n if (entity === undefined) {\n throw new Error(`존재하지 않는 Entity 요청 ${entityId}`);\n }\n\n return entity;\n }\n\n exists(entityId: string): boolean {\n const entity = this.entities.get(entityId);\n return entity !== undefined;\n }\n\n getAllIds(): string[] {\n return Array.from(EntityManager.entities.keys());\n }\n\n getAllParentIds(): string[] {\n return this.getAllIds().filter((entityId) => {\n const entity = this.get(entityId);\n return entity.parentId === undefined;\n });\n }\n\n getChildrenIds(parentId: string): string[] {\n return this.getAllIds().filter((entityId) => {\n const entity = this.get(entityId);\n return entity.parentId === parentId;\n });\n }\n\n setModulePath(key: string, modulePath: string): void {\n // console.debug(chalk.cyan(`setModulePath :: ${key} :: ${modulePath}`));\n this.modulePaths.set(key, modulePath);\n }\n\n getModulePath(key: string): string {\n const modulePath = this.modulePaths.get(key);\n if (modulePath === undefined) {\n throw new Error(`존재하지 않는 모듈 패스 요청 ${key}`);\n }\n\n return modulePath;\n }\n\n setTableSpec(tableSpec: TableSpec) {\n this.tableSpecs.set(tableSpec.name, tableSpec);\n }\n\n getTableSpec(key: string): TableSpec {\n const tableSpec = this.tableSpecs.get(key);\n if (tableSpec === undefined) {\n throw new Error(`존재하지 않는 테이블 스펙 요청 ${key}`);\n }\n\n return tableSpec;\n }\n\n getNamesFromId(entityId: string): EntityNamesRecord {\n // entityId가 단복수 동형 단어인 경우 List 붙여서 생성\n const pluralized =\n inflection.pluralize(entityId) === entityId\n ? `${entityId}List`\n : inflection.pluralize(entityId);\n\n return {\n fs: inflection.dasherize(inflection.underscore(entityId)).toLowerCase(),\n fsPlural: inflection\n .dasherize(inflection.underscore(pluralized))\n .toLowerCase(),\n camel: inflection.camelize(entityId, true),\n camelPlural: inflection.camelize(pluralized, true),\n capital: entityId,\n capitalPlural: pluralized,\n upper: entityId.toUpperCase(),\n constant: inflection.underscore(entityId).toUpperCase(),\n };\n }\n}\n\nexport const EntityManager = new EntityManagerClass();\n","import chalk from \"chalk\";\nimport { FastifyInstance, FastifyReply, FastifyRequest } from \"fastify\";\nimport { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { ZodError } from \"zod\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { getZodObjectFromApi } from \"./code-converters\";\nimport { Context } from \"./context\";\nimport { BadRequestException } from \"../exceptions/so-exceptions\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { fastifyCaster } from \"./caster\";\nimport { ApiParam, ApiParamType } from \"../types/types\";\nimport { Syncer } from \"../syncer/syncer\";\nimport { isLocal, isTest } from \"../utils/controller\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { ApiDecoratorOptions } from \"./decorators\";\nimport { humanizeZodError } from \"../utils/zod-error\";\nimport { DatabaseDriver, SonamuDBConfig } from \"../database/types\";\nimport { DB } from \"../database/db\";\n\nexport type SonamuConfig = {\n projectName?: string;\n api: {\n dir: string;\n };\n sync: {\n targets: string[];\n };\n route: {\n prefix: string;\n };\n};\nexport type SonamuSecrets = {\n [key: string]: string;\n};\ntype SonamuFastifyConfig = {\n contextProvider: (\n defaultContext: Pick<Context, \"headers\" | \"reply\">,\n request: FastifyRequest,\n reply: FastifyReply\n ) => Context;\n guardHandler: (\n guard: string,\n request: FastifyRequest,\n api: {\n typeParameters: ApiParamType.TypeParam[];\n parameters: ApiParam[];\n returnType: ApiParamType;\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n }\n ) => void;\n cache?: {\n get: (key: string) => Promise<unknown | null>;\n put: (key: string, value: unknown, ttl?: number) => Promise<void>;\n resolveKey: (\n path: string,\n reqBody: {\n [key: string]: unknown;\n }\n ) =>\n | {\n cache: false;\n }\n | {\n cache: true;\n key: string;\n ttl?: number;\n };\n };\n};\nclass SonamuClass {\n public isInitialized: boolean = false;\n\n private _apiRootPath: string | null = null;\n set apiRootPath(apiRootPath: string) {\n this._apiRootPath = apiRootPath;\n }\n get apiRootPath(): string {\n if (this._apiRootPath === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._apiRootPath!;\n }\n get appRootPath(): string {\n return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);\n }\n\n private _dbConfig: SonamuDBConfig | null = null;\n set dbConfig(dbConfig: SonamuDBConfig) {\n this._dbConfig = dbConfig;\n }\n get dbConfig() {\n if (this._dbConfig === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._dbConfig!;\n }\n\n private _dbClient: DatabaseDriver | null = null;\n set dbClient(_dbClient: DatabaseDriver) {\n this._dbClient = _dbClient;\n }\n get dbClient() {\n if (this._dbClient === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._dbClient!;\n }\n\n private _syncer: Syncer | null = null;\n set syncer(syncer: Syncer) {\n this._syncer = syncer;\n }\n get syncer(): Syncer {\n if (this._syncer === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._syncer!;\n }\n\n private _config: SonamuConfig | null = null;\n set config(config: SonamuConfig) {\n this._config = config;\n }\n get config(): SonamuConfig {\n if (this._config === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._config;\n }\n\n private _secrets: SonamuSecrets | null = null;\n set secrets(secrets: SonamuSecrets) {\n this._secrets = secrets;\n }\n get secrets(): SonamuSecrets | null {\n return this._secrets;\n }\n\n async initForTesting() {\n await this.init(true, false, undefined, true);\n }\n\n async init(\n doSilent: boolean = false,\n enableSync: boolean = true,\n apiRootPath?: string,\n forTesting: boolean = false\n ) {\n if (this.isInitialized) {\n return;\n }\n !doSilent &&\n console.time(\n chalk.cyan(`Sonamu.init${forTesting ? \" for testing\" : \"\"}`)\n );\n\n // API 루트 패스\n this.apiRootPath = apiRootPath ?? (await findApiRootPath());\n const configPath = path.join(this.apiRootPath, \"sonamu.config.json\");\n const secretsPath = path.join(this.apiRootPath, \"sonamu.secrets.json\");\n if (fs.existsSync(configPath) === false) {\n throw new Error(`Cannot find sonamu.config.json in ${configPath}`);\n }\n this.config = JSON.parse(\n fs.readFileSync(configPath).toString()\n ) as SonamuConfig;\n if (fs.existsSync(secretsPath)) {\n this.secrets = JSON.parse(\n fs.readFileSync(secretsPath).toString()\n ) as SonamuSecrets;\n }\n\n // DB 로드\n const baseConfig = await DB.getBaseConfig(this.apiRootPath);\n this.dbClient = baseConfig.client;\n DB.init(baseConfig as any);\n this.dbConfig = DB.fullConfig;\n\n // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단\n if (forTesting) {\n this.isInitialized = true;\n return;\n }\n\n // Entity 로드\n await EntityManager.autoload(doSilent);\n\n // Syncer\n this.syncer = new Syncer();\n\n // Autoload: Models / Types / APIs\n await this.syncer.autoloadModels();\n await this.syncer.autoloadTypes();\n await this.syncer.autoloadApis();\n\n if (isLocal() && !isTest() && enableSync) {\n await this.syncer.sync();\n\n fetch(\"http://127.0.0.1:57001/api/reload\", {\n method: \"GET\",\n }).catch((e) =>\n console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`))\n );\n }\n\n this.isInitialized = true;\n !doSilent && console.timeEnd(chalk.cyan(\"Sonamu.init\"));\n }\n\n async withFastify(\n server: FastifyInstance<Server, IncomingMessage, ServerResponse>,\n config: SonamuFastifyConfig,\n options?: { enableSync?: boolean; doSilent?: boolean }\n ) {\n if (this.isInitialized === false) {\n await this.init(options?.doSilent, options?.enableSync);\n }\n\n // 전체 라우팅 리스트\n server.get(\n `${this.config.route.prefix}/routes`,\n async (_request, _reply): Promise<any> => {\n return this.syncer.apis;\n }\n );\n\n // Healthcheck API\n server.get(\n `${this.config.route.prefix}/healthcheck`,\n async (_request, _reply): Promise<string> => {\n return \"ok\";\n }\n );\n\n // API 라우팅 등록\n this.syncer.apis.map((api) => {\n // model\n if (this.syncer.models[api.modelName] === undefined) {\n throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);\n }\n const model = this.syncer.models[api.modelName];\n\n // 파라미터 정보로 zod 스키마 빌드\n const ReqType = getZodObjectFromApi(api, this.syncer.types);\n\n // route\n server.route({\n method: api.options.httpMethod!,\n url: this.config.route.prefix + api.path,\n handler: async (request, reply): Promise<unknown> => {\n (api.options.guards ?? []).every((guard) =>\n config.guardHandler(guard, request, api)\n );\n\n // request 파싱\n const which = api.options.httpMethod === \"GET\" ? \"query\" : \"body\";\n let reqBody: {\n [key: string]: unknown;\n };\n try {\n reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});\n } catch (e) {\n if (e instanceof ZodError) {\n const messages = humanizeZodError(e)\n .map((issue) => issue.message)\n .join(\" \");\n throw new BadRequestException(messages);\n } else {\n throw e;\n }\n }\n\n // Content-Type\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시\n const { cacheKey, cacheTtl, cachedData } = await (async () => {\n if (config.cache) {\n try {\n const cacheKeyRes = config.cache.resolveKey(api.path, reqBody);\n if (cacheKeyRes.cache === false) {\n return { cacheKey: null, cachedData: null };\n }\n\n const cacheKey = cacheKeyRes.key;\n const cacheTtl = cacheKeyRes.ttl;\n const cachedData = await config.cache.get(cacheKey);\n return { cacheKey, cacheTtl, cachedData };\n } catch (e) {\n console.error(e);\n }\n return { cacheKey: null, cachedData: null };\n }\n return { cacheKey: null, cachedData: null };\n })();\n if (cachedData !== null) {\n return cachedData;\n }\n\n // 결과\n const result = await (model as any)[api.methodName].apply(\n model,\n api.parameters.map((param) => {\n // Context 인젝션\n if (ApiParamType.isContext(param.type)) {\n return config.contextProvider(\n {\n headers: request.headers,\n reply,\n },\n request,\n reply\n );\n } else {\n return reqBody[param.name];\n }\n })\n );\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시 키 있는 경우 갱신 후 저장\n if (config.cache && cacheKey) {\n await config.cache.put(cacheKey, result, cacheTtl);\n }\n return result;\n },\n }); // END server.route\n });\n }\n\n async destroy(): Promise<void> {\n await DB.destroy();\n }\n}\nexport const Sonamu = new SonamuClass();\n","import { z } from \"zod\";\n\n// optional, nullable 무관하게 ZodNumber 체크\nfunction isZodNumberAnyway(zodType: z.ZodType<any>) {\n if (zodType instanceof z.ZodNumber) {\n return true;\n } else if (\n zodType instanceof z.ZodNullable &&\n zodType._def.innerType instanceof z.ZodNumber\n ) {\n return true;\n } else if (\n zodType instanceof z.ZodOptional &&\n zodType._def.innerType instanceof z.ZodNumber\n ) {\n } else if (\n zodType instanceof z.ZodOptional &&\n zodType._def.innerType instanceof z.ZodOptional &&\n zodType._type.def.innerType instanceof z.ZodNumber\n ) {\n return true;\n }\n\n return false;\n}\n\n// ZodType을 이용해 raw를 Type Coercing\nexport function caster(zodType: z.ZodType<any>, raw: any): any {\n if (isZodNumberAnyway(zodType) && typeof raw === \"string\") {\n // number\n return Number(raw);\n } else if (\n zodType instanceof z.ZodUnion &&\n zodType.options.some((opt: z.ZodType<any>) => isZodNumberAnyway(opt))\n ) {\n // zArrayable Number 케이스 처리\n if (Array.isArray(raw)) {\n const numType = zodType.options.find(\n (opt: z.ZodType<any>) => opt instanceof z.ZodNumber\n );\n return raw.map((elem: any) => caster(numType, elem));\n } else {\n return Number(raw);\n }\n } else if (\n zodType instanceof z.ZodBoolean &&\n (raw === \"true\" || raw === \"false\")\n ) {\n // boolean\n return raw === \"true\";\n } else if (\n raw !== null &&\n Array.isArray(raw) &&\n zodType instanceof z.ZodArray\n ) {\n // array\n return raw.map((elem: any) => caster(zodType.element, elem));\n } else if (\n zodType instanceof z.ZodObject &&\n typeof raw === \"object\" &&\n raw !== null\n ) {\n // object\n return Object.keys(raw).reduce((r, rawKey) => {\n r[rawKey] = caster(zodType.shape[rawKey], raw[rawKey]);\n return r;\n }, {} as any);\n } else if (zodType instanceof z.ZodOptional) {\n // optional\n return caster(zodType._def.innerType, raw);\n } else if (zodType instanceof z.ZodNullable) {\n // nullable\n return caster(zodType._def.innerType, raw);\n } else if (\n zodType instanceof z.ZodDate &&\n new Date(raw).toString() !== \"Invalid Date\"\n ) {\n // date\n return new Date(raw);\n } else {\n // 나머지는 처리 안함\n return raw;\n }\n}\n\nexport function fastifyCaster(schema: z.ZodObject<any>) {\n return z.preprocess((raw: any) => {\n return caster(schema, raw);\n }, schema);\n}\n","import path, { dirname } from \"path\";\nimport { globAsync, importMultiple } from \"../utils/utils\";\nimport fs from \"fs-extra\";\nimport crypto from \"crypto\";\nimport equal from \"fast-deep-equal\";\nimport _ from \"lodash\";\nimport inflection from \"inflection\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport ts from \"typescript\";\nimport {\n ApiParam,\n ApiParamType,\n isBelongsToOneRelationProp,\n isBigIntegerProp,\n isBooleanProp,\n isDateProp,\n isDateTimeProp,\n isDecimalProp,\n isDoubleProp,\n isEnumProp,\n isFloatProp,\n isIntegerProp,\n isJsonProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isTimeProp,\n isTimestampProp,\n isUuidProp,\n isVirtualProp,\n EntityProp,\n EntityPropNode,\n SQLDateTimeString,\n} from \"../types/types\";\nimport {\n ApiDecoratorOptions,\n registeredApis,\n ExtendedApi,\n} from \"../api/decorators\";\nimport { z } from \"zod\";\nimport chalk from \"chalk\";\nimport {\n TemplateKey,\n PathAndCode,\n TemplateOptions,\n GenerateOptions,\n RenderingNode,\n} from \"../types/types\";\nimport {\n AlreadyProcessedException,\n BadRequestException,\n ServiceUnavailableException,\n} from \"../exceptions/so-exceptions\";\nimport { wrapIf } from \"../utils/lodash-able\";\nimport { getTextTypeLength } from \"../api/code-converters\";\nimport { Template } from \"../templates/base-template\";\nimport { Template__generated } from \"../templates/generated.template\";\nimport { Template__init_types } from \"../templates/init_types.template\";\nimport { Template__entity } from \"../templates/entity.template\";\nimport { Template__model } from \"../templates/model.template\";\nimport { Template__model_test } from \"../templates/model_test.template\";\nimport { Template__service } from \"../templates/service.template\";\nimport { Template__view_form } from \"../templates/view_form.template\";\nimport { Template__view_list } from \"../templates/view_list.template\";\nimport prettier from \"prettier\";\nimport { Template__view_id_all_select } from \"../templates/view_id_all_select.template\";\nimport { Template__view_id_async_select } from \"../templates/view_id_async_select.template\";\nimport { Template__view_enums_dropdown } from \"../templates/view_enums_dropdown.template\";\nimport { Template__view_enums_select } from \"../templates/view_enums_select.template\";\nimport { Template__view_enums_buttonset } from \"../templates/view_enums_buttonset.template\";\nimport { Template__view_search_input } from \"../templates/view_search_input.template\";\nimport { Template__view_list_columns } from \"../templates/view_list_columns.template\";\nimport { Template__generated_http } from \"../templates/generated_http.template\";\nimport { Sonamu } from \"../api/sonamu\";\nimport { execSync } from \"child_process\";\nimport { Template__generated_sso } from \"../templates/generated_sso.template\";\nimport { Template__kysely_interface } from \"../templates/kysely_types.template\";\nimport { DB } from \"../database/db\";\nimport { setTimeout as setTimeoutPromises } from \"timers/promises\";\n\ntype FileType = \"model\" | \"types\" | \"functions\" | \"generated\" | \"entity\";\ntype GlobPattern = {\n [key in FileType]: string;\n};\ntype PathAndChecksum = {\n path: string;\n checksum: string;\n};\ntype DiffGroups = {\n [key in FileType]: string[];\n};\nexport type RenderedTemplate = {\n target: string;\n path: string;\n body: string;\n importKeys: string[];\n customHeaders?: string[];\n preTemplates?: {\n key: TemplateKey;\n options: TemplateOptions[TemplateKey];\n }[];\n};\n\nexport class Syncer {\n apis: {\n typeParameters: ApiParamType.TypeParam[];\n parameters: ApiParam[];\n returnType: ApiParamType;\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n }[] = [];\n types: { [typeName: string]: z.ZodObject<any> } = {};\n models: { [modelName: string]: unknown } = {};\n isSyncing: boolean = false;\n\n get checksumsPath(): string {\n return path.join(Sonamu.apiRootPath, \"/.so-checksum\");\n }\n public constructor() {}\n\n async sync(): Promise<void> {\n const { targets } = Sonamu.config.sync;\n\n // 트리거와 무관하게 shared 분배\n await Promise.all(\n targets.map(async (target) => {\n const srcCodePath = path\n .join(__dirname, `../shared/${target}.shared.ts.txt`)\n .replace(\"/dist/\", \"/src/\");\n if (!fs.existsSync(srcCodePath)) {\n return;\n }\n\n const dstCodePath = path.join(\n Sonamu.appRootPath,\n target,\n \"src/services/sonamu.shared.ts\"\n );\n\n const srcChecksum = await this.getChecksumOfFile(srcCodePath);\n const dstChecksum = await (async () => {\n if (fs.existsSync(dstCodePath) === false) {\n return \"\";\n }\n return this.getChecksumOfFile(dstCodePath);\n })();\n\n if (srcChecksum === dstChecksum) {\n return;\n }\n fs.writeFileSync(dstCodePath, fs.readFileSync(srcCodePath));\n })\n );\n\n // 현재 checksums\n let currentChecksums = await this.getCurrentChecksums();\n // 이전 checksums\n const previousChecksums = await this.getPreviousChecksums();\n\n // 비교\n const isSame = equal(currentChecksums, previousChecksums);\n if (isSame) {\n const msg = \"Every files are synced!\";\n const margin = (process.stdout.columns - msg.length) / 2;\n console.log(\n chalk.black.bgGreen(\" \".repeat(margin) + msg + \" \".repeat(margin))\n );\n return;\n }\n\n const abc = new AbortController();\n this.isSyncing = true;\n const onSIGUSR2 = async () => {\n if (this.isSyncing === false) {\n process.exit(0);\n }\n console.log(chalk.magentaBright(`wait for syncing done....`));\n\n // 싱크 완료 대기\n try {\n await setTimeoutPromises(20000, \"waiting-sync\", { signal: abc.signal });\n } catch {}\n console.log(chalk.magentaBright(`Syncing DONE!`));\n process.exit(0);\n };\n process.on(\"SIGUSR2\", onSIGUSR2);\n\n // 변경된 파일 찾기\n const diff = _.differenceWith(\n currentChecksums,\n previousChecksums,\n _.isEqual\n );\n const diffFiles = diff.map((r) => r.path);\n console.log(\"Changed Files: \", diffFiles);\n\n // 다른 부분 찾아 액션\n const diffGroups = _.groupBy(diffFiles, (r) => {\n const matched = r.match(\n /\\.(model|types|functions|entity|generated)\\.[tj]s/\n );\n return matched![1];\n }) as unknown as DiffGroups;\n\n // 변경된 파일들을 타입별로 분리하여 각 타입별 액션 처리\n const diffTypes = Object.keys(diffGroups);\n\n // 트리거: entity, types\n // 액션: 스키마 생성\n if (diffTypes.includes(\"entity\") || diffTypes.includes(\"types\")) {\n console.log(\"// 액션: 스키마 생성\");\n await this.actionGenerateSchemas();\n\n if (\n DB.baseConfig?.client === \"kysely\" &&\n DB.baseConfig.types?.enabled !== false\n ) {\n console.log(\"// 액션: kysely 인터페이스 생성\");\n await this.generateTemplate(\n \"kysely_interface\",\n {},\n { overwrite: true }\n );\n }\n\n // generated 싱크까지 동시에 처리 후 체크섬 갱신\n diffGroups[\"generated\"] = _.uniq([\n ...(diffGroups[\"generated\"] ?? []),\n \"/src/application/sonamu.generated.ts\",\n ]);\n diffTypes.push(\"generated\");\n currentChecksums = await this.getCurrentChecksums();\n }\n\n // 트리거: types, enums, generated 변경시\n // 액션: 파일 싱크 types, enums, generated\n if (\n diffTypes.includes(\"types\") ||\n diffTypes.includes(\"functions\") ||\n diffTypes.includes(\"generated\")\n ) {\n console.log(\"// 액션: 파일 싱크 types / functions / generated\");\n\n const tsPaths = _.uniq(\n [\n ...(diffGroups[\"types\"] ?? []),\n ...(diffGroups[\"functions\"] ?? []),\n ...(diffGroups[\"generated\"] ?? []),\n ].map((p) => p.replace(\"/dist/\", \"/src/\").replace(\".js\", \".ts\"))\n );\n await this.actionSyncFilesToTargets(tsPaths);\n }\n\n // 트리거: model\n if (diffTypes.includes(\"model\")) {\n const entityIds = this.getEntityIdFromPath(diffGroups[\"model\"]);\n console.log(\"// 액션: 서비스 생성\");\n await this.actionGenerateServices(entityIds);\n console.log(\"// 액션: HTTP파일 생성\");\n await this.actionGenerateHttps(entityIds);\n }\n\n // 저장\n await this.saveChecksums(currentChecksums);\n\n // 싱크 종료\n this.isSyncing = false;\n abc.abort();\n process.off(\"SIGUSR2\", onSIGUSR2);\n }\n\n getEntityIdFromPath(filePaths: string[]): string[] {\n return _.uniq(\n filePaths.map((p) => {\n const matched = p.match(/application\\/(.+)\\//);\n return inflection.camelize(matched![1].replace(/\\-/g, \"_\"));\n })\n );\n }\n\n async actionGenerateSchemas(): Promise<string[]> {\n return (\n await Promise.all([\n this.generateTemplate(\"generated_sso\", {}, { overwrite: true }),\n this.generateTemplate(\"generated\", {}, { overwrite: true }),\n ])\n )\n .flat()\n .flat();\n }\n\n async actionGenerateServices(entityIds: string[]): Promise<string[]> {\n return (\n await Promise.all(\n entityIds.map(async (entityId) =>\n this.generateTemplate(\n \"service\",\n {\n entityId,\n },\n {\n overwrite: true,\n }\n )\n )\n )\n )\n .flat()\n .flat();\n }\n\n async actionGenerateHttps(entityIds: string[]): Promise<string[]> {\n const [res] = await this.generateTemplate(\n \"generated_http\",\n { entityId: entityIds[0] },\n { overwrite: true }\n );\n return res;\n }\n\n async copyFileWithReplaceCoreToShared(fromPath: string, toPath: string) {\n if (!fs.existsSync(fromPath)) {\n return;\n }\n\n const oldFileContent = fs.readFileSync(fromPath).toString();\n\n const newFileContent = (() => {\n const nfc = oldFileContent.replace(\n /from \"sonamu\"/g,\n `from \"src/services/sonamu.shared\"`\n );\n\n if (toPath.includes(\"/web/\")) {\n return nfc.replace(/from \"lodash\";/g, `from \"lodash-es\";`);\n } else {\n return nfc;\n }\n })();\n return fs.writeFile(toPath, newFileContent);\n }\n\n async actionSyncFilesToTargets(tsPaths: string[]): Promise<string[]> {\n const { targets } = Sonamu.config.sync;\n const { dir: apiDir } = Sonamu.config.api;\n const { appRootPath } = Sonamu;\n\n return (\n await Promise.all(\n targets.map(async (target) =>\n Promise.all(\n tsPaths.map(async (src) => {\n const realSrc = Sonamu.apiRootPath + src;\n const dst = realSrc\n .replace(`/${apiDir}/`, `/${target}/`)\n .replace(\"/application/\", \"/services/\");\n const dir = dirname(dst);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n console.log(\n \"COPIED \",\n chalk.blue(dst.replace(appRootPath + \"/\", \"\"))\n );\n await this.copyFileWithReplaceCoreToShared(realSrc, dst);\n return dst;\n })\n )\n )\n )\n ).flat();\n }\n\n async getCurrentChecksums(): Promise<PathAndChecksum[]> {\n const PatternGroup: GlobPattern = {\n /* 원본 체크 */\n entity: Sonamu.apiRootPath + \"/src/application/**/*.entity.json\",\n types: Sonamu.apiRootPath + \"/src/application/**/*.types.ts\",\n generated: Sonamu.apiRootPath + \"/src/application/sonamu.generated.ts\",\n functions: Sonamu.apiRootPath + \"/src/application/**/*.functions.ts\",\n /* compiled-JS 체크 */\n model: Sonamu.apiRootPath + \"/dist/application/**/*.model.js\",\n };\n\n const filePaths = (\n await Promise.all(\n Object.entries(PatternGroup).map(async ([_fileType, pattern]) => {\n return globAsync(pattern);\n })\n )\n )\n .flat()\n .sort();\n\n const fileChecksums: {\n path: string;\n checksum: string;\n }[] = await Promise.all(\n filePaths.map(async (filePath) => {\n return {\n path: filePath.substring(Sonamu.apiRootPath.length),\n checksum: await this.getChecksumOfFile(filePath),\n };\n })\n );\n return fileChecksums;\n }\n\n async getPreviousChecksums(): Promise<PathAndChecksum[]> {\n if (fs.existsSync(this.checksumsPath) === false) {\n return [];\n }\n\n const previousChecksums = (await fs.readJSON(\n this.checksumsPath\n )) as PathAndChecksum[];\n return previousChecksums;\n }\n\n async saveChecksums(checksums: PathAndChecksum[]): Promise<void> {\n await fs.writeJSON(this.checksumsPath, checksums, {\n spaces: 2,\n });\n console.log(\"checksum saved\", this.checksumsPath);\n }\n\n async getChecksumOfFile(filePath: string): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const hash = crypto.createHash(\"sha1\");\n const input = fs.createReadStream(filePath);\n input.on(\"error\", reject);\n input.on(\"data\", function (chunk: any) {\n hash.update(chunk);\n });\n input.on(\"close\", function () {\n resolve(hash.digest(\"hex\"));\n });\n });\n }\n\n async readApisFromFile(filePath: string) {\n const sourceFile = ts.createSourceFile(\n filePath,\n fs.readFileSync(filePath).toString(),\n ts.ScriptTarget.Latest\n );\n\n const methods: Omit<ExtendedApi, \"path\" | \"options\">[] = [];\n let modelName: string = \"UnknownModel\";\n let methodName: string = \"unknownMethod\";\n const visitor = (node: ts.Node) => {\n if (ts.isClassDeclaration(node)) {\n if (node.name && ts.isIdentifier(node.name)) {\n modelName = node.name.escapedText.toString().replace(/Class$/, \"\");\n }\n }\n if (ts.isMethodDeclaration(node)) {\n if (ts.isIdentifier(node.name)) {\n methodName = node.name.escapedText.toString();\n }\n\n const typeParameters: ApiParamType.TypeParam[] = (\n node.typeParameters ?? []\n ).map((typeParam) => {\n const tp = typeParam as ts.TypeParameterDeclaration;\n\n return {\n t: \"type-param\",\n id: tp.name.escapedText.toString(),\n constraint: tp.constraint\n ? this.resolveTypeNode(tp.constraint)\n : undefined,\n };\n });\n const parameters: ApiParam[] = node.parameters.map(\n (paramDec, index) => {\n const defaultDef = this.printNode(paramDec.initializer, sourceFile);\n\n // 기본값이 있는 경우 paramDec.type가 undefined로 나옴\n\n return this.resolveParamDec(\n {\n name: paramDec.name,\n type: paramDec.type as ts.TypeNode,\n optional:\n paramDec.questionToken !== undefined ||\n paramDec.initializer !== undefined,\n defaultDef,\n },\n index\n );\n }\n );\n if (node.type === undefined) {\n throw new Error(\n `리턴 타입이 기재되지 않은 메소드 ${modelName}.${methodName}`\n );\n }\n const returnType = this.resolveTypeNode(node.type!);\n\n methods.push({\n modelName,\n methodName,\n typeParameters,\n parameters,\n returnType,\n });\n }\n ts.forEachChild(node, visitor);\n };\n visitor(sourceFile);\n\n if (methods.length === 0) {\n return [];\n }\n\n // 현재 파일의 등록된 API 필터\n const currentModelApis = registeredApis.filter((api) => {\n return methods.find(\n (method) =>\n method.modelName === api.modelName &&\n method.methodName === api.methodName\n );\n });\n\n // 등록된 API에 현재 메소드 타입 정보 확장\n const extendedApis = currentModelApis.map((api) => {\n const foundMethod = methods.find(\n (method) =>\n method.modelName === api.modelName &&\n method.methodName === api.methodName\n );\n return {\n ...api,\n typeParameters: foundMethod!.typeParameters,\n parameters: foundMethod!.parameters,\n returnType: foundMethod!.returnType,\n };\n });\n return extendedApis;\n }\n\n resolveTypeNode(typeNode: ts.TypeNode): ApiParamType {\n switch (typeNode?.kind) {\n case ts.SyntaxKind.AnyKeyword:\n return \"any\";\n case ts.SyntaxKind.UnknownKeyword:\n return \"unknown\";\n case ts.SyntaxKind.StringKeyword:\n return \"string\";\n case ts.SyntaxKind.NumberKeyword:\n return \"number\";\n case ts.SyntaxKind.BooleanKeyword:\n return \"boolean\";\n case ts.SyntaxKind.UndefinedKeyword:\n return \"undefined\";\n case ts.SyntaxKind.NullKeyword:\n return \"null\";\n case ts.SyntaxKind.VoidKeyword:\n return \"void\";\n case ts.SyntaxKind.LiteralType:\n const literal = (typeNode as ts.LiteralTypeNode).literal;\n if (ts.isStringLiteral(literal)) {\n return {\n t: \"string-literal\",\n value: literal.text,\n };\n } else if (ts.isNumericLiteral(literal)) {\n return {\n t: \"numeric-literal\",\n value: Number(literal.text),\n };\n } else {\n if (literal.kind === ts.SyntaxKind.NullKeyword) {\n return \"null\";\n } else if (literal.kind === ts.SyntaxKind.UndefinedKeyword) {\n return \"undefined\";\n } else if (literal.kind === ts.SyntaxKind.TrueKeyword) {\n return \"true\";\n } else if (literal.kind === ts.SyntaxKind.FalseKeyword) {\n return \"false\";\n }\n throw new Error(\"알 수 없는 리터럴\");\n }\n case ts.SyntaxKind.ArrayType:\n const arrNode = typeNode as ts.ArrayTypeNode;\n return {\n t: \"array\",\n elementsType: this.resolveTypeNode(arrNode.elementType),\n };\n case ts.SyntaxKind.TypeLiteral:\n const literalNode = typeNode as ts.TypeLiteralNode;\n return {\n t: \"object\",\n props: literalNode.members.map((member) => {\n if (ts.isIndexSignatureDeclaration(member)) {\n const res = this.resolveParamDec({\n name: member.parameters[0].name as ts.Identifier,\n type: member.parameters[0].type as ts.TypeNode,\n });\n\n return this.resolveParamDec({\n name: {\n escapedText: `[${res.name}${res.optional ? \"?\" : \"\"}: ${\n res.type\n }]`,\n } as ts.Identifier,\n type: member.type as ts.TypeNode,\n });\n } else {\n return this.resolveParamDec({\n name: (member as ts.PropertySignature).name as ts.Identifier,\n type: (member as ts.PropertySignature).type as ts.TypeNode,\n optional:\n (member as ts.PropertySignature).questionToken !== undefined,\n });\n }\n }),\n };\n case ts.SyntaxKind.TypeReference:\n return {\n t: \"ref\",\n id: (\n (typeNode as ts.TypeReferenceNode).typeName as ts.Identifier\n ).escapedText.toString(),\n args: (typeNode as ts.TypeReferenceNode).typeArguments?.map(\n (typeArg) => this.resolveTypeNode(typeArg)\n ),\n };\n case ts.SyntaxKind.UnionType:\n return {\n t: \"union\",\n types: (typeNode as ts.UnionTypeNode).types.map((type) =>\n this.resolveTypeNode(type)\n ),\n };\n case ts.SyntaxKind.IntersectionType:\n return {\n t: \"intersection\",\n types: (typeNode as ts.IntersectionTypeNode).types.map((type) =>\n this.resolveTypeNode(type)\n ),\n };\n case ts.SyntaxKind.IndexedAccessType:\n return {\n t: \"indexed-access\",\n object: this.resolveTypeNode(\n (typeNode as ts.IndexedAccessTypeNode).objectType\n ),\n index: this.resolveTypeNode(\n (typeNode as ts.IndexedAccessTypeNode).indexType\n ),\n };\n case ts.SyntaxKind.TupleType:\n if (ts.isTupleTypeNode(typeNode)) {\n return {\n t: \"tuple-type\",\n elements: typeNode.elements.map((elem) =>\n this.resolveTypeNode(elem)\n ),\n };\n }\n break;\n case undefined:\n throw new Error(`typeNode undefined`);\n }\n\n console.debug(typeNode);\n throw new Error(`알 수 없는 SyntaxKind ${typeNode.kind}`);\n }\n\n resolveParamDec = (\n paramDec: {\n name: ts.BindingName;\n type: ts.TypeNode;\n optional?: boolean;\n defaultDef?: string;\n },\n index: number = 0\n ): ApiParam => {\n const name = paramDec.name as ts.Identifier;\n const type = this.resolveTypeNode(paramDec.type);\n\n if (name === undefined) {\n console.debug({ name, type, paramDec });\n }\n\n const result: ApiParam = {\n name: name.escapedText ? name.escapedText.toString() : `nonameAt${index}`,\n type,\n optional: paramDec.optional === true,\n defaultDef: paramDec?.defaultDef,\n };\n\n // 구조분해할당의 경우 타입이름 사용\n if (\n ts.isObjectBindingPattern(name) &&\n ts.isTypeReferenceNode(paramDec.type) &&\n ts.isIdentifier(paramDec.type.typeName)\n ) {\n result.name = inflection.camelize(paramDec.type.typeName.text, true);\n }\n\n return result;\n };\n\n printNode(\n node: ts.Node | undefined,\n sourceFile: ts.SourceFile\n ): string | undefined {\n if (node === undefined) {\n return undefined;\n }\n\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);\n }\n\n async autoloadApis() {\n const pathPattern = path.join(\n Sonamu.apiRootPath,\n \"/src/application/**/*.model.ts\"\n );\n // console.debug(chalk.yellow(`autoload:APIs @ ${pathPattern}`));\n\n const filePaths = await globAsync(pathPattern);\n const result = await Promise.all(\n filePaths.map((filePath) => this.readApisFromFile(filePath))\n );\n this.apis = result.flat();\n return this.apis;\n }\n\n async autoloadModels(): Promise<{ [modelName: string]: unknown }> {\n const pathPattern = path.join(\n Sonamu.apiRootPath,\n \"dist/application/**/*.model.js\"\n );\n // console.debug(chalk.yellow(`autoload:models @ ${pathPattern}`));\n\n const filePaths = (await globAsync(pathPattern)).filter((path) => {\n // src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드\n // 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지\n const srcPath = path.replace(\"/dist/\", \"/src/\").replace(\".js\", \".ts\");\n return fs.existsSync(srcPath);\n });\n const modules = await importMultiple(filePaths);\n const functions = modules\n .map(({ imported }) => Object.entries(imported))\n .flat();\n this.models = Object.fromEntries(\n functions.filter(([name]) => name.endsWith(\"Model\"))\n );\n return this.models;\n }\n\n async autoloadTypes(\n doRefresh: boolean = false\n ): Promise<{ [typeName: string]: z.ZodObject<any> }> {\n if (!doRefresh && Object.keys(this.types).length > 0) {\n return this.types;\n }\n\n const pathPatterns = [\n path.join(Sonamu.apiRootPath, \"/dist/application/**/*.types.js\"),\n path.join(Sonamu.apiRootPath, \"/dist/application/**/*.generated.js\"),\n ];\n // console.debug(chalk.magenta(`autoload:types @ ${pathPatterns.join(\"\\n\")}`));\n\n const filePaths = (\n await Promise.all(pathPatterns.map((pattern) => globAsync(pattern)))\n )\n .flat()\n .filter((path) => {\n // src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드\n // 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지\n const srcPath = path.replace(\"/dist/\", \"/src/\").replace(\".js\", \".ts\");\n return fs.existsSync(srcPath);\n });\n const modules = await importMultiple(filePaths, doRefresh);\n const functions = modules\n .map(({ imported }) => Object.entries(imported))\n .flat();\n this.types = Object.fromEntries(\n functions.filter(([, f]) => f instanceof z.ZodType)\n ) as typeof this.types;\n return this.types;\n }\n\n getTemplate(key: TemplateKey): Template {\n if (key === \"entity\") {\n return new Template__entity();\n } else if (key === \"init_types\") {\n return new Template__init_types();\n } else if (key === \"generated\") {\n return new Template__generated();\n } else if (key === \"generated_sso\") {\n return new Template__generated_sso();\n } else if (key === \"generated_http\") {\n return new Template__generated_http();\n } else if (key === \"model\") {\n return new Template__model();\n } else if (key === \"model_test\") {\n return new Template__model_test();\n } else if (key === \"service\") {\n return new Template__service();\n } else if (key === \"view_list\") {\n return new Template__view_list();\n } else if (key === \"view_list_columns\") {\n return new Template__view_list_columns();\n } else if (key === \"view_search_input\") {\n return new Template__view_search_input();\n } else if (key === \"view_form\") {\n return new Template__view_form();\n } else if (key === \"view_id_all_select\") {\n return new Template__view_id_all_select();\n } else if (key === \"view_id_async_select\") {\n return new Template__view_id_async_select();\n } else if (key === \"view_enums_select\") {\n return new Template__view_enums_select();\n } else if (key === \"view_enums_dropdown\") {\n return new Template__view_enums_dropdown();\n } else if (key === \"view_enums_buttonset\") {\n return new Template__view_enums_buttonset();\n } else if (key === \"kysely_interface\") {\n return new Template__kysely_interface();\n } else {\n throw new BadRequestException(`잘못된 템플릿 키 ${key}`);\n }\n }\n\n async renderTemplate<T extends keyof TemplateOptions>(\n key: T,\n options: TemplateOptions[T]\n ): Promise<PathAndCode[]> {\n const template: Template = this.getTemplate(key);\n\n let extra: unknown[] = [];\n if (\n [\"service\", \"generated_http\", \"model\", \"view_list\", \"view_form\"].includes(\n key\n )\n ) {\n const entityId = (options as TemplateOptions[\"service\"]).entityId;\n\n if (key === \"service\" || key === \"generated_http\") {\n // service 필요 정보 (API 리스트)\n const entity = EntityManager.get(entityId!);\n const modelTsPath = `${path.join(\n Sonamu.apiRootPath,\n \"/src/application\"\n )}/${entity.names.fs}/${entity.names.fs}.model.ts`;\n extra = [await this.readApisFromFile(modelTsPath)];\n } else if (key === \"view_list\" || key === \"model\") {\n // view_list 필요 정보 (컬럼 노드, 리스트파라미터 노드)\n const columnsNode = await this.getColumnsNode(entityId, \"A\");\n const listParamsZodType = await this.getZodTypeById(\n `${entityId}ListParams`\n );\n const listParamsNode = this.zodTypeToRenderingNode(listParamsZodType);\n extra = [columnsNode, listParamsNode];\n } else if (key === \"view_form\") {\n // view_form 필요 정보 (세이브파라미터 노드)\n const saveParamsZodType = await this.getZodTypeById(\n `${entityId}SaveParams`\n );\n const saveParamsNode = this.zodTypeToRenderingNode(saveParamsZodType);\n extra = [saveParamsNode];\n }\n }\n\n const rendered = await template.render(options, ...extra);\n const resolved = await this.resolveRenderedTemplate(key, rendered);\n\n let preTemplateResolved: PathAndCode[] = [];\n if (rendered.preTemplates) {\n preTemplateResolved = (\n await Promise.all(\n rendered.preTemplates.map(({ key, options }) => {\n return this.renderTemplate(key, options);\n })\n )\n ).flat();\n }\n\n return [resolved, ...preTemplateResolved];\n }\n\n async resolveRenderedTemplate(\n key: TemplateKey,\n result: RenderedTemplate\n ): Promise<PathAndCode> {\n const { target, path: filePath, body, importKeys, customHeaders } = result;\n\n // import 할 대상의 대상 path 추출\n const importDefs = importKeys\n .reduce(\n (r, importKey) => {\n const modulePath = EntityManager.getModulePath(importKey);\n let importPath = modulePath;\n if (modulePath.includes(\"/\") || modulePath.includes(\".\")) {\n importPath = wrapIf(\n path.relative(path.dirname(filePath), modulePath),\n (p) => [p.startsWith(\".\") === false, \"./\" + p]\n );\n }\n\n // 같은 파일에서 import 하는 경우 keys 로 나열 처리\n const existsOne = r.find(\n (importDef) => importDef.from === importPath\n );\n if (existsOne) {\n existsOne.keys = _.uniq(existsOne.keys.concat(importKey));\n } else {\n r.push({\n keys: [importKey],\n from: importPath,\n });\n }\n return r;\n },\n [] as {\n keys: string[];\n from: string;\n }[]\n )\n // 셀프 참조 방지\n .filter(\n (importDef) =>\n filePath.endsWith(importDef.from.replace(\"./\", \"\") + \".ts\") === false\n );\n\n // 커스텀 헤더 포함하여 헤더 생성\n const header = [\n ...(customHeaders ?? []),\n ...importDefs.map(\n (importDef) =>\n `import { ${importDef.keys.join(\", \")} } from '${importDef.from}'`\n ),\n ].join(\"\\n\");\n\n const formatted = await (async () => {\n if (key === \"generated_http\") {\n return [header, body].join(\"\\n\\n\");\n } else {\n return prettier.format([header, body].join(\"\\n\\n\"), {\n parser: key === \"entity\" ? \"json\" : \"typescript\",\n });\n }\n })();\n\n return {\n path: target + \"/\" + filePath,\n code: formatted,\n };\n }\n\n async writeCodeToPath(pathAndCode: PathAndCode): Promise<string[]> {\n const { targets } = Sonamu.config.sync;\n const { appRootPath } = Sonamu;\n const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;\n\n const dstFilePaths = _.uniq(\n targets.map((target) => filePath.replace(\"/:target/\", `/${target}/`))\n );\n return await Promise.all(\n dstFilePaths.map(async (dstFilePath) => {\n const dir = path.dirname(dstFilePath);\n if (fs.existsSync(dir) === false) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(dstFilePath, pathAndCode.code);\n console.log(\n \"GENERATED \",\n chalk.blue(dstFilePath.replace(appRootPath + \"/\", \"\"))\n );\n return dstFilePath;\n })\n );\n }\n\n async generateTemplate(\n key: TemplateKey,\n templateOptions: any,\n _generateOptions?: GenerateOptions\n ) {\n const generateOptions = {\n overwrite: false,\n ..._generateOptions,\n };\n\n // 키 children\n const keys: TemplateKey[] = [key];\n\n // 템플릿 렌더\n const pathAndCodes = (\n await Promise.all(\n keys.map(async (key) => {\n return await this.renderTemplate(key, templateOptions);\n })\n )\n ).flat();\n\n const filteredPathAndCodes: PathAndCode[] = (() => {\n if (generateOptions.overwrite === true) {\n return pathAndCodes;\n } else {\n return pathAndCodes.filter((pathAndCode) => {\n const { targets } = Sonamu.config.sync;\n const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;\n const dstFilePaths = targets.map((target) =>\n filePath.replace(\"/:target/\", `/${target}/`)\n );\n return dstFilePaths.every(\n (dstPath) => fs.existsSync(dstPath) === false\n );\n });\n }\n })();\n if (filteredPathAndCodes.length === 0) {\n throw new AlreadyProcessedException(\n \"이미 경로에 모든 파일이 존재합니다.\"\n );\n }\n\n return Promise.all(\n filteredPathAndCodes.map((pathAndCode) =>\n this.writeCodeToPath(pathAndCode)\n )\n );\n }\n\n checkExistsGenCode(\n entityId: string,\n templateKey: TemplateKey,\n enumId?: string\n ): { subPath: string; fullPath: string; isExists: boolean } {\n const { target, path: genPath } = this.getTemplate(\n templateKey\n ).getTargetAndPath(EntityManager.getNamesFromId(entityId), enumId);\n\n const fullPath = path.join(Sonamu.appRootPath, target, genPath);\n const subPath = path.join(target, genPath);\n return {\n subPath,\n fullPath,\n isExists: fs.existsSync(fullPath),\n };\n }\n\n checkExists(\n entityId: string,\n enums: {\n [name: string]: z.ZodEnum<any>;\n }\n ): Record<`${TemplateKey}${string}`, boolean> {\n const keys: TemplateKey[] = TemplateKey.options;\n const names = EntityManager.getNamesFromId(entityId);\n const enumsKeys = Object.keys(enums).filter(\n (name) => name !== names.constant\n );\n\n return keys.reduce(\n (result, key) => {\n const tpl = this.getTemplate(key);\n if (key.startsWith(\"view_enums\")) {\n enumsKeys.map((componentId) => {\n const { target, path: p } = tpl.getTargetAndPath(\n names,\n componentId\n );\n result[`${key}__${componentId}`] = fs.existsSync(\n path.join(Sonamu.appRootPath, target, p)\n );\n });\n return result;\n }\n\n const { target, path: p } = tpl.getTargetAndPath(names);\n const { targets } = Sonamu.config.sync;\n if (target.includes(\":target\")) {\n targets.map((t) => {\n result[`${key}__${t}`] = fs.existsSync(\n path.join(Sonamu.appRootPath, target.replace(\":target\", t), p)\n );\n });\n } else {\n result[key] = fs.existsSync(path.join(Sonamu.appRootPath, target, p));\n }\n\n return result;\n },\n {} as Record<`${TemplateKey}${string}`, boolean>\n );\n }\n\n async getZodTypeById(zodTypeId: string): Promise<z.ZodTypeAny> {\n const modulePath = EntityManager.getModulePath(zodTypeId);\n const moduleAbsPath = path.join(\n Sonamu.apiRootPath,\n \"dist\",\n \"application\",\n modulePath + \".js\"\n );\n const importPath = \"./\" + path.relative(__dirname, moduleAbsPath);\n const imported = await import(importPath);\n\n if (!imported[zodTypeId]) {\n throw new Error(`존재하지 않는 zodTypeId ${zodTypeId}`);\n }\n return imported[zodTypeId].describe(zodTypeId);\n }\n\n async propNodeToZodType(propNode: EntityPropNode): Promise<z.ZodTypeAny> {\n if (propNode.nodeType === \"plain\") {\n return this.propToZodType(propNode.prop);\n } else if (propNode.nodeType === \"array\") {\n if (propNode.prop === undefined) {\n throw new Error();\n } else if (propNode.children.length > 0) {\n return (\n await this.propNodeToZodType({\n ...propNode,\n nodeType: \"object\",\n })\n ).array();\n } else {\n const innerType = await this.propToZodType(propNode.prop);\n if (propNode.prop.nullable === true) {\n return z.array(innerType).nullable();\n } else {\n return z.array(innerType);\n }\n }\n } else if (propNode.nodeType === \"object\") {\n const obj = await propNode.children.reduce(\n async (promise, childPropNode) => {\n const result = await promise;\n result[childPropNode.prop!.name] =\n await this.propNodeToZodType(childPropNode);\n return result;\n },\n {} as any\n );\n\n if (propNode.prop?.nullable === true) {\n return z.object(obj).nullable();\n } else {\n return z.object(obj);\n }\n } else {\n throw Error;\n }\n }\n async propToZodType(prop: EntityProp): Promise<z.ZodTypeAny> {\n let zodType: z.ZodTypeAny = z.unknown();\n if (isIntegerProp(prop)) {\n zodType = z.number().int();\n } else if (isBigIntegerProp(prop)) {\n zodType = z.bigint();\n } else if (isTextProp(prop)) {\n zodType = z.string().max(getTextTypeLength(prop.textType));\n } else if (isEnumProp(prop)) {\n zodType = await this.getZodTypeById(prop.id);\n } else if (isStringProp(prop)) {\n zodType = z.string().max(prop.length);\n } else if (isFloatProp(prop) || isDoubleProp(prop)) {\n zodType = z.number();\n } else if (isDecimalProp(prop)) {\n zodType = z.string();\n } else if (isBooleanProp(prop)) {\n zodType = z.boolean();\n } else if (isDateProp(prop)) {\n zodType = z.string().length(10);\n } else if (isTimeProp(prop)) {\n zodType = z.string().length(8);\n } else if (isDateTimeProp(prop)) {\n zodType = SQLDateTimeString;\n } else if (isTimestampProp(prop)) {\n zodType = SQLDateTimeString;\n } else if (isJsonProp(prop)) {\n zodType = await this.getZodTypeById(prop.id);\n } else if (isUuidProp(prop)) {\n zodType = z.string().uuid();\n } else if (isVirtualProp(prop)) {\n zodType = await this.getZodTypeById(prop.id);\n } else if (isRelationProp(prop)) {\n if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n zodType = z.number().int();\n }\n } else {\n throw new Error(`prop을 zodType으로 변환하는데 실패 ${prop}}`);\n }\n\n if ((prop as { unsigned?: boolean }).unsigned) {\n zodType = (zodType as z.ZodNumber).nonnegative();\n }\n if (prop.nullable) {\n zodType = zodType.nullable();\n }\n\n return zodType;\n }\n\n resolveRenderType(\n key: string,\n zodType: z.ZodTypeAny\n ): RenderingNode[\"renderType\"] {\n if (zodType instanceof z.ZodString) {\n if (key.includes(\"img\") || key.includes(\"image\")) {\n return \"string-image\";\n } else if (zodType.description === \"SQLDateTimeString\") {\n return \"string-datetime\";\n } else if (key.endsWith(\"date\")) {\n return \"string-date\";\n } else {\n return \"string-plain\";\n }\n } else if (zodType instanceof z.ZodNumber) {\n if (key === \"id\") {\n return \"number-id\";\n } else if (key.endsWith(\"_id\")) {\n return \"number-fk_id\";\n } else {\n return \"number-plain\";\n }\n } else if (zodType instanceof z.ZodBoolean) {\n return \"boolean\";\n } else if (zodType instanceof z.ZodEnum) {\n return \"enums\";\n } else if (zodType instanceof z.ZodRecord) {\n return \"record\";\n } else if (zodType instanceof z.ZodAny || zodType instanceof z.ZodUnknown) {\n return \"string-plain\";\n } else if (zodType instanceof z.ZodUnion) {\n return \"string-plain\";\n } else if (zodType instanceof z.ZodLiteral) {\n return \"string-plain\";\n } else {\n throw new Error(`타입 파싱 불가 ${key} ${zodType._def.typeName}`);\n }\n }\n zodTypeToRenderingNode(\n zodType: z.ZodTypeAny,\n baseKey: string = \"root\"\n ): RenderingNode {\n const def = {\n name: baseKey,\n label: inflection.camelize(baseKey, false),\n zodType,\n };\n if (zodType instanceof z.ZodObject) {\n const columnKeys = Object.keys(zodType.shape);\n const children = columnKeys.map((key) => {\n const innerType = zodType.shape[key];\n return this.zodTypeToRenderingNode(innerType, key);\n });\n return {\n ...def,\n renderType: \"object\",\n children,\n };\n } else if (zodType instanceof z.ZodArray) {\n const innerType = zodType._def.type;\n if (innerType instanceof z.ZodString && baseKey.includes(\"images\")) {\n return {\n ...def,\n renderType: \"array-images\",\n };\n }\n return {\n ...def,\n renderType: \"array\",\n element: this.zodTypeToRenderingNode(innerType, baseKey),\n };\n } else if (zodType instanceof z.ZodUnion) {\n const optionNodes = zodType._def.options.map((opt: z.ZodTypeAny) =>\n this.zodTypeToRenderingNode(opt, baseKey)\n );\n // TODO: ZodUnion이 들어있는 경우 핸들링\n return optionNodes[0];\n } else if (zodType instanceof z.ZodOptional) {\n return {\n ...this.zodTypeToRenderingNode(zodType._def.innerType, baseKey),\n optional: true,\n };\n } else if (zodType instanceof z.ZodNullable) {\n return {\n ...this.zodTypeToRenderingNode(zodType._def.innerType, baseKey),\n nullable: true,\n };\n } else {\n return {\n ...def,\n renderType: this.resolveRenderType(baseKey, zodType),\n };\n }\n }\n\n async getColumnsNode(\n entityId: string,\n subsetKey: string\n ): Promise<RenderingNode> {\n const entity = await EntityManager.get(entityId);\n const subsetA = entity.subsets[subsetKey];\n if (subsetA === undefined) {\n throw new ServiceUnavailableException(\"SubsetA 가 없습니다.\");\n }\n const propNodes = entity.fieldExprsToPropNodes(subsetA);\n const rootPropNode: EntityPropNode = {\n nodeType: \"object\",\n children: propNodes,\n };\n\n const columnsZodType = (await this.propNodeToZodType(\n rootPropNode\n )) as z.ZodObject<any>;\n\n const columnsNode = this.zodTypeToRenderingNode(columnsZodType);\n columnsNode.children = columnsNode.children!.map((child) => {\n if (child.renderType === \"object\") {\n const pickedCol = child.children!.find((cc) =>\n [\"title\", \"name\"].includes(cc.name)\n );\n if (pickedCol) {\n return {\n ...child,\n renderType: \"object-pick\",\n config: {\n picked: pickedCol.name,\n },\n };\n } else {\n return child;\n }\n } else if (\n child.renderType === \"array\" &&\n child.element &&\n child.element.renderType === \"object\"\n ) {\n const pickedCol = child.element!.children!.find((cc) =>\n [\"title\", \"name\"].includes(cc.name)\n );\n if (pickedCol) {\n return {\n ...child,\n element: {\n ...child.element,\n renderType: \"object-pick\",\n config: {\n picked: pickedCol.name,\n },\n },\n };\n } else {\n return child;\n }\n }\n return child;\n });\n\n return columnsNode;\n }\n\n async createEntity(\n form: Omit<TemplateOptions[\"entity\"], \"title\"> & { title?: string }\n ) {\n if (!/^[A-Z][a-zA-Z0-9]*$/.test(form.entityId)) {\n throw new BadRequestException(\"entityId는 CamelCase 형식이어야 합니다.\");\n }\n\n await this.generateTemplate(\"entity\", form);\n\n // reload entities\n await EntityManager.reload();\n\n // generate schemas, types\n await Promise.all([\n this.actionGenerateSchemas(),\n ...(form.entityId === undefined\n ? [\n this.generateTemplate(\"init_types\", {\n entityId: form.entityId,\n }),\n ]\n : []),\n ]);\n }\n\n async delEntity(entityId: string): Promise<{ delPaths: string[] }> {\n const entity = EntityManager.get(entityId);\n\n const delPaths = (() => {\n if (entity.parentId) {\n return [\n `${Sonamu.apiRootPath}/src/application/${entity.names.parentFs}/${entity.names.fs}.entity.json`,\n ];\n } else {\n return [\n `${Sonamu.apiRootPath}/src/application/${entity.names.fs}`,\n `${Sonamu.apiRootPath}/dist/application/${entity.names.fs}`,\n ...Sonamu.config.sync.targets\n .map((target) => [\n `${Sonamu.appRootPath}/${target}/src/services/${entity.names.fs}`,\n ])\n .flat(),\n ];\n }\n })(); // iife\n\n for await (const delPath of delPaths) {\n if (fs.existsSync(delPath)) {\n console.log(chalk.red(`DELETE ${delPath}`));\n execSync(`rm -rf ${delPath}`);\n } else {\n console.log(chalk.yellow(`NOT_EXISTS ${delPath}`));\n }\n }\n\n // reload entities\n await EntityManager.reload();\n\n return { delPaths };\n }\n}\n","export function wrapIf(\n source: string,\n predicate: (str: string) => [boolean, string]\n): string {\n const [ok, wrapped] = predicate(source);\n return ok ? wrapped : source;\n}\n","import _ from \"lodash\";\nimport { TemplateOptions } from \"../types/types\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Entity } from \"../entity/entity\";\nimport { EntityPropNode } from \"../types/types\";\nimport { propNodeToZodTypeDef, zodTypeToZodCode } from \"../api/code-converters\";\nimport { Template } from \"./base-template\";\nimport { nonNullable } from \"../utils/utils\";\nimport { Sonamu } from \"../api\";\n\nexport type SourceCode = {\n label: string;\n lines: string[];\n importKeys: string[];\n};\nexport class Template__generated extends Template {\n constructor() {\n super(\"generated\");\n }\n\n getTargetAndPath() {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `sonamu.generated.ts`,\n };\n }\n\n render({}: TemplateOptions[\"generated\"]) {\n const entityIds = EntityManager.getAllIds();\n const entities = entityIds.map((id) => EntityManager.get(id));\n\n // 전체 SourceCode 생성\n const sourceCodes = entities\n .map((entity) => {\n return [\n this.getEnumsSourceCode(entity),\n this.getBaseSchemaSourceCode(entity),\n this.getBaseListParamsSourceCode(entity),\n this.getSubsetSourceCode(entity),\n ].filter(nonNullable);\n })\n .flat();\n\n // Sort\n const LABEL_KEY_ORDER = [\n \"Enums\",\n \"BaseSchema\",\n \"BaseListParams\",\n \"Subsets\",\n \"SubsetQueries\",\n ];\n sourceCodes.sort((a, b) => {\n const [aKey] = a.label.split(\":\");\n const [bKey] = b.label.split(\":\");\n const aIndex = LABEL_KEY_ORDER.indexOf(aKey);\n const bIndex = LABEL_KEY_ORDER.indexOf(bKey);\n if (aIndex > bIndex) {\n return 1;\n } else if (aIndex < bIndex) {\n return -1;\n } else {\n return 0;\n }\n });\n\n const sourceCode = sourceCodes.reduce(\n (result, ts) => {\n if (ts === null) {\n return result;\n }\n return {\n lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, \"\"],\n importKeys: _.uniq([...result!.importKeys, ...ts.importKeys]),\n };\n },\n {\n lines: [],\n importKeys: [],\n } as Omit<SourceCode, \"label\">\n );\n\n // .types.ts의 타입을 참조하는 경우 순환참조(상호참조)가 발생하므로 타입을 가져와 인라인 처리\n const allTypeKeys = entities\n .map((entity) => Object.keys(entity.types))\n .flat();\n const cdImportKeys = sourceCode.importKeys.filter((importKey) =>\n allTypeKeys.includes(importKey)\n );\n if (cdImportKeys.length > 0) {\n const customScalarLines = cdImportKeys\n .map((importKey) => {\n const entity = entities.find((entity) => entity.types[importKey]);\n if (!entity) {\n throw new Error(`ZodType not found ${importKey}`);\n }\n const zodType = entity.types[importKey]!;\n\n return [\n `// CustomScalar: ${importKey}`,\n `const ${importKey} = ${zodTypeToZodCode(zodType)};`,\n `type ${importKey} = z.infer<typeof ${importKey}>`,\n \"\",\n ];\n })\n .flat();\n sourceCode.lines = [...customScalarLines, ...sourceCode.lines];\n sourceCode.importKeys = sourceCode.importKeys.filter(\n (importKey) => !cdImportKeys.includes(importKey)\n );\n }\n\n const body = sourceCode.lines.join(\"\\n\");\n\n // import\n const sonamuImports = [\n \"zArrayable\",\n \"SQLDateTimeString\",\n \"SubsetQuery\",\n \"SonamuQueryMode\",\n ].filter((mod) => body.includes(mod));\n\n return {\n ...this.getTargetAndPath(),\n body,\n importKeys: sourceCode.importKeys,\n customHeaders: [\n `import { z } from 'zod';`,\n `import { ${sonamuImports.join(\",\")} } from \"sonamu\";`,\n ],\n };\n }\n\n getEnumsSourceCode(entity: Entity): SourceCode | null {\n if (Object.keys(entity.enumLabels).length === 0) {\n return null;\n }\n return {\n label: `Enums: ${entity.id}`,\n lines: [\n ...Object.entries(entity.enumLabels)\n .filter(([_, enumLabel]) => Object.keys(enumLabel).length > 0)\n .map(([enumId, enumLabel]) => [\n `export const ${enumId} = z.enum([${Object.keys(enumLabel).map(\n (el) => `\"${el}\"`\n )}]).describe(\"${enumId}\");`,\n `export type ${enumId} = z.infer<typeof ${enumId}>`,\n `export const ${enumId}Label = ${JSON.stringify(enumLabel)}`,\n ])\n .flat(),\n ],\n importKeys: [],\n };\n }\n\n getBaseSchemaSourceCode(\n entity: Entity,\n importKeys: string[] = []\n ): SourceCode {\n const schemaName = `${entity.names.module}BaseSchema`;\n const propNode: EntityPropNode = {\n nodeType: \"object\",\n children: entity.props.map((prop) => {\n return {\n nodeType: \"plain\",\n prop,\n };\n }),\n };\n\n const schemaBody = propNodeToZodTypeDef(propNode, importKeys);\n\n const lines = [\n `export const ${schemaName} = ${schemaBody}`,\n `export type ${schemaName} = z.infer<typeof ${schemaName}>`,\n ];\n\n return {\n label: `BaseSchema: ${entity.id}`,\n importKeys,\n lines,\n };\n }\n\n getBaseListParamsSourceCode(entity: Entity): SourceCode | null {\n // Prop 없는 MD인 경우 생성 제외\n if (entity.props.length === 0) {\n return null;\n } else if (entity.parentId !== undefined) {\n return null;\n }\n\n const schemaName = `${entity.names.module}BaseListParams`;\n\n const filterProps = entity.props.filter((prop) => prop.toFilter === true);\n\n const propNodes: EntityPropNode[] = filterProps.map((prop) => {\n return {\n nodeType: \"plain\" as const,\n prop,\n children: [],\n };\n });\n\n const importKeys: string[] = [];\n const filterBody = propNodes\n .map((propNode) => propNodeToZodTypeDef(propNode, importKeys))\n .join(\"\\n\");\n\n const schemaBody = `\nz.object({\n num: z.number().int().nonnegative(),\n page: z.number().int().min(1),\n search: ${entity.id}SearchField,\n keyword: z.string(),\n orderBy: ${entity.id}OrderBy,\n queryMode: SonamuQueryMode,\n id: zArrayable(z.number().int().positive()),${filterBody}\n}).partial();\n`.trim();\n\n const lines = [\n `export const ${schemaName} = ${schemaBody}`,\n `export type ${schemaName} = z.infer<typeof ${schemaName}>`,\n ];\n\n return {\n label: `BaseListParams: ${entity.id}`,\n importKeys,\n lines,\n };\n }\n\n getSubsetSourceCode(entity: Entity): SourceCode | null {\n if (Object.keys(entity.subsets).length == 0) {\n return null;\n } else if (entity.parentId !== undefined) {\n return null;\n }\n\n const subsetKeys = Object.keys(entity.subsets);\n const importKeys: string[] = [];\n const lines: string[] = [\n ...subsetKeys\n .map((subsetKey) => {\n // 서브셋에서 FieldExpr[] 가져옴\n const fieldExprs = entity.subsets[subsetKey];\n\n // FieldExpr[]로 EntityPropNode[] 가져옴\n const propNodes = entity.fieldExprsToPropNodes(fieldExprs);\n const schemaName = `${entity.names.module}Subset${subsetKey}`;\n const propNode: EntityPropNode = {\n nodeType: \"object\",\n children: propNodes,\n };\n\n // EntityPropNode[]로 ZodTypeDef(string)을 가져옴\n const body = propNodeToZodTypeDef(propNode, importKeys);\n\n return [\n `export const ${schemaName} = ${body}`,\n `export type ${schemaName} = z.infer<typeof ${schemaName}>`,\n ];\n })\n .flat(),\n `export type ${entity.names.module}SubsetMapping = {`,\n ...subsetKeys.map(\n (subsetKey) =>\n ` ${subsetKey}: ${entity.names.module}Subset${subsetKey};`\n ),\n \"}\",\n `export const ${entity.names.module}SubsetKey = z.enum([${subsetKeys\n .map((k) => `\"${k}\"`)\n .join(\",\")}]);`,\n `export type ${entity.names.module}SubsetKey = z.infer<typeof ${entity.names.module}SubsetKey>`,\n \"\",\n ];\n\n return {\n label: `Subsets: ${entity.id}`,\n lines,\n importKeys: _.uniq(importKeys),\n };\n }\n}\n","import { TemplateKey, TemplateOptions } from \"../types/types\";\nimport { EntityNamesRecord } from \"../entity/entity-manager\";\nimport { RenderedTemplate } from \"../syncer/syncer\";\n\nexport abstract class Template {\n constructor(public key: TemplateKey) {}\n public abstract render(\n options: TemplateOptions[TemplateKey],\n ...extra: unknown[]\n ): RenderedTemplate | Promise<RenderedTemplate>;\n\n public abstract getTargetAndPath(\n names?: EntityNamesRecord,\n ...extra: unknown[]\n ): {\n target: string;\n path: string;\n };\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { Sonamu } from \"../api\";\n\nexport class Template__init_types extends Template {\n constructor() {\n super(\"init_types\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `${names.fs}/${names.fs}.types.ts`,\n };\n }\n\n render({ entityId }: TemplateOptions[\"init_types\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n const hasCreatedAt =\n EntityManager.get(entityId).props.find(\n (prop) => prop.name === \"created_at\"\n ) !== undefined;\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport { z } from \"zod\";\nimport { ${entityId}BaseSchema, ${entityId}BaseListParams } from \"../sonamu.generated\";\n\n// ${entityId} - ListParams\nexport const ${entityId}ListParams = ${entityId}BaseListParams;\nexport type ${entityId}ListParams = z.infer<typeof ${entityId}ListParams>;\n\n// ${entityId} - SaveParams\nexport const ${entityId}SaveParams = ${entityId}BaseSchema.partial({ id: true${\n hasCreatedAt ? \", created_at: true\" : \"\"\n } });\nexport type ${entityId}SaveParams = z.infer<typeof ${entityId}SaveParams>;\n\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { Sonamu } from \"../api\";\n\nexport class Template__entity extends Template {\n constructor() {\n super(\"entity\");\n }\n\n getTargetAndPath(names: EntityNamesRecord, parentNames?: EntityNamesRecord) {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `${(parentNames ?? names).fs}/${names.fs}.entity.json`,\n };\n }\n\n render(options: TemplateOptions[\"entity\"]) {\n const { entityId, title, parentId, table } = options;\n const names = EntityManager.getNamesFromId(entityId);\n\n const parent = (() => {\n if (parentId) {\n return {\n names: EntityManager.getNamesFromId(parentId),\n entity: EntityManager.get(parentId),\n };\n } else {\n return null;\n }\n })();\n\n return {\n ...this.getTargetAndPath(names, parent?.names ?? names),\n body: JSON.stringify({\n id: entityId,\n title: title ?? entityId,\n parentId,\n table: table ?? names.fsPlural.replace(/\\-/g, \"_\"),\n props: options.props?.length\n ? options.props\n : [\n { name: \"id\", type: \"integer\", unsigned: true, desc: \"ID\" },\n ...(parent\n ? [\n {\n type: \"relation\",\n name: parent.names.camel,\n relationType: \"BelongsToOne\",\n with: parentId,\n onUpdate: \"CASCADE\",\n onDelete: \"CASCADE\",\n desc: parent.entity.title,\n },\n ]\n : []),\n {\n name: \"created_at\",\n type: \"timestamp\",\n desc: \"등록일시\",\n dbDefault: \"CURRENT_TIMESTAMP\",\n },\n ],\n indexes: [...(options.indexes ?? [])],\n subsets: options.subsets ?? {\n ...(parentId\n ? {}\n : {\n A: [\"id\", \"created_at\"],\n }),\n },\n enums: options.enums ?? {\n ...(parentId\n ? {}\n : {\n [`${names.capital}OrderBy`]: {\n \"id-desc\": \"ID최신순\",\n },\n [`${names.capital}SearchField`]: { id: \"ID\" },\n }),\n },\n }).trim(),\n importKeys: [],\n };\n }\n}\n","import inflection from \"inflection\";\nimport _ from \"lodash\";\nimport { z } from \"zod\";\nimport { RenderingNode, TemplateKey, TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { isEnumProp, isRelationProp, RelationProp } from \"../types/types\";\nimport { RenderedTemplate } from \"../syncer/syncer\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_list extends Template {\n constructor() {\n super(\"view_list\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/pages/admin\",\n path: `${names.fsPlural}/index.tsx`,\n };\n }\n\n wrapTc(\n body: string,\n key: string,\n collapsing: boolean = true,\n className: string = \"\"\n ) {\n return `<Table.Cell key=\"${key}\"${collapsing ? \" collapsing\" : \"\"}${\n className ? ` className={\\`${className}\\`}` : \"\"\n }>${body}</Table.Cell>`;\n }\n\n renderColumn(\n entityId: string,\n col: RenderingNode,\n names: EntityNamesRecord,\n parentObj: string = \"row\",\n withoutName: boolean = false\n ): string {\n const colName = withoutName ? `${parentObj}` : `${parentObj}.${col.name}`;\n\n switch (col.renderType) {\n case \"string-plain\":\n case \"string-date\":\n case \"number-id\":\n return `<>{${colName}}</>`;\n case \"number-fk_id\":\n const relPropFk = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n return `<>${relPropFk.with}#{${colName}}</>`;\n case \"string-image\":\n return `<>{${\n col.nullable ? `${colName} && ` : \"\"\n }<img src={${colName}} />}</>`;\n case \"string-datetime\":\n if (col.nullable) {\n return `<span className=\"text-tiny\">{${colName} === null ? '-' : dateF(${colName})}</span>`;\n } else {\n return `<span className=\"text-tiny\">{dateF(${colName})}</span>`;\n }\n case \"boolean\":\n return `<>{${colName} ? <Label color='green' circular>O</Label> : <Label color='grey' circular>X</Label> }</>`;\n case \"enums\":\n const { id: enumId } = getEnumInfoFromColName(entityId, col.name);\n return `<>{${\n col.nullable ? `${colName} && ` : \"\"\n }${enumId}Label[${colName}]}</>`;\n case \"array-images\":\n return `<>{ ${colName}.map(r => ${\n col.nullable ? `r && ` : \"\"\n }<img src={r} />) }</>`;\n case \"number-plain\":\n return `<>{${col.nullable ? `${colName} && ` : \"\"}numF(${colName})}</>`;\n case \"object\":\n return `<>{/* object ${colName} */}</>`;\n case \"object-pick\":\n const pickedChild = col.children!.find(\n (child) => child.name === col.config?.picked\n );\n if (!pickedChild) {\n throw new Error(`object-pick 선택 실패 (오브젝트: ${col.name})`);\n }\n return this.renderColumn(\n entityId,\n pickedChild,\n names,\n `${colName}${col.nullable ? \"?\" : \"\"}`\n );\n case \"array\":\n return `<>{ /* array ${colName} */ }</>`;\n default:\n throw new Error(`렌더 불가 컬럼 ${col.renderType}`);\n }\n }\n\n renderColumnImport(\n entityId: string,\n col: RenderingNode,\n names: EntityNamesRecord\n ): (string | null)[] {\n if (col.renderType === \"enums\") {\n const { id: enumId } = getEnumInfoFromColName(names.capital, col.name);\n return [\n `import { ${enumId}Label } from 'src/services/sonamu.generated';`,\n ];\n } else if (col.renderType === \"object\") {\n try {\n const relProp = getRelationPropFromColName(entityId, col.name);\n const result = col.children!.map((child) => {\n entityId = relProp.with;\n names = EntityManager.getNamesFromId(relProp.with);\n return this.renderColumnImport(entityId, child, names);\n });\n return _.flattenDeep(result);\n } catch {\n return [null];\n }\n } else if (col.renderType === \"array\") {\n return this.renderColumnImport(entityId, col.element!, names);\n }\n\n return [null];\n }\n\n renderFilterImport(\n entityId: string,\n col: RenderingNode,\n names: EntityNamesRecord\n ) {\n if (col.name === \"search\") {\n return `import { ${names.capital}SearchInput } from \"src/components/${names.fs}/${names.capital}SearchInput\";`;\n } else if (col.renderType === \"enums\") {\n if (col.name === \"orderBy\") {\n const componentId = `${names.capital}${inflection.camelize(col.name)}Select`;\n return `import { ${componentId} } from \"src/components/${names.fs}/${componentId}\";`;\n } else {\n try {\n const { id, targetEntityNames: targetMDNames } =\n getEnumInfoFromColName(entityId, col.name);\n const componentId = `${id}Select`;\n return `import { ${componentId} } from \"src/components/${targetMDNames.fs}/${componentId}\";`;\n } catch {\n return \"\";\n }\n }\n } else if (col.renderType === \"number-fk_id\") {\n try {\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n const targetNames = EntityManager.getNamesFromId(relProp.with);\n const componentId = `${relProp.with}IdAsyncSelect`;\n return `import { ${componentId} } from \"src/components/${targetNames.fs}/${componentId}\";`;\n } catch {\n return \"\";\n }\n } else {\n throw new Error(\n `렌더 불가능한 필터 임포트 ${col.name} ${col.renderType}`\n );\n }\n }\n\n renderFilter(entityId: string, col: RenderingNode, names: EntityNamesRecord) {\n if (col.name === \"search\") {\n return \"\";\n }\n\n const isClearable = col.optional === true && col.name !== \"orderBy\";\n let componentId: string;\n if (col.renderType === \"enums\") {\n if (col.name === \"orderBy\") {\n componentId = `${names.capital}${inflection.camelize(col.name)}Select`;\n } else {\n try {\n const { id } = getEnumInfoFromColName(entityId, col.name);\n componentId = `${id}Select`;\n } catch {\n return \"\";\n }\n }\n return `<${componentId} {...register('${col.name}')} ${\n isClearable ? \"clearable\" : \"\"\n } />`;\n } else if (col.renderType === \"number-fk_id\") {\n try {\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n componentId = `${relProp.with}IdAsyncSelect`;\n return `<${componentId} {...register('${col.name}')} ${\n isClearable ? \"clearable\" : \"\"\n } subset=\"A\" />`;\n } catch {\n return \"\";\n }\n } else {\n throw new Error(\n `렌더 불가능한 필터 임포트 ${col.name} ${col.renderType}`\n );\n }\n }\n\n getDefault(columns: RenderingNode[]): {\n orderBy: string;\n search: string;\n } {\n const def = {\n orderBy: \"id-desc\",\n search: \"title\",\n };\n const orderByZodType = columns.find(\n (col) => col.name === \"orderBy\"\n )?.zodType;\n if (orderByZodType && orderByZodType instanceof z.ZodEnum) {\n def.orderBy = Object.keys(orderByZodType.Enum)[0];\n }\n const searchZodType = columns.find((col) => col.name === \"search\")?.zodType;\n if (searchZodType && searchZodType instanceof z.ZodEnum) {\n def.search = Object.keys(searchZodType.Enum)[0];\n }\n return def;\n }\n\n render(\n { entityId }: TemplateOptions[\"view_list\"],\n columnsNode: RenderingNode,\n listParamsNode: RenderingNode\n ) {\n const names = EntityManager.getNamesFromId(entityId);\n const entity = EntityManager.get(entityId);\n\n // 실제 리스트 컬럼\n const columns = (columnsNode.children as RenderingNode[])\n .filter((col) => col.name !== \"id\")\n .map((col) => {\n const propCandidate = entity.props.find((p) => p.name === col.name);\n return {\n name: col.name,\n label: propCandidate?.desc ?? col.label,\n tc: `(row) => ${this.renderColumn(entityId, col, names)}`,\n };\n });\n\n // 필터 컬럼\n const filterColumns = (listParamsNode.children as RenderingNode[])\n .filter(\n (col) =>\n col.name !== \"id\" &&\n col.name !== \"queryMode\" &&\n ([\"enums\", \"number-id\"].includes(col.renderType) ||\n col.name.endsWith(\"_id\"))\n )\n // orderBy가 가장 뒤로 오게 순서 조정\n .sort((a) => {\n return a.name == \"orderBy\" ? 1 : -1;\n });\n\n // 필터 컬럼을 프리 템플릿으로 설정\n const preTemplates: RenderedTemplate[\"preTemplates\"] = [];\n for (let col of filterColumns) {\n let key: TemplateKey;\n let targetEntityId = entityId;\n let enumId: string | undefined;\n\n if (col.renderType === \"enums\") {\n if (col.name === \"search\") {\n key = \"view_enums_dropdown\";\n enumId = `${names.capital}SearchField`;\n targetEntityId = names.capital;\n } else {\n key = \"view_enums_select\";\n try {\n const { targetEntityNames, id } = getEnumInfoFromColName(\n entityId,\n col.name\n );\n targetEntityId = targetEntityNames.capital;\n enumId = id;\n } catch {\n continue;\n }\n }\n } else {\n key = \"view_id_async_select\";\n try {\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n targetEntityId = relProp.with;\n } catch {\n continue;\n }\n }\n\n preTemplates.push({\n key,\n options: {\n entityId: targetEntityId,\n enumId,\n },\n });\n }\n\n // 리스트 컬럼\n const columnImports = _.uniq(\n columnsNode\n .children!.map((col) => {\n return this.renderColumnImport(entityId, col, names);\n })\n .flat()\n .filter((col) => col !== null)\n ).join(\"\\n\");\n\n // SearchInput\n preTemplates!.push({\n key: \"view_search_input\",\n options: {\n entityId,\n },\n });\n\n // 디폴트 파라미터\n const def = this.getDefault(filterColumns);\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n Breadcrumb,\n Checkbox,\n Pagination,\n Segment,\n Table,\n TableRow,\n Message,\n Transition,\n Button,\n Label,\n} from 'semantic-ui-react';\nimport classNames from 'classnames';\nimport { DateTime } from \"luxon\";\nimport { DelButton, EditButton, AppBreadcrumbs, AddButton, useSelection, useListParams, SonamuCol, numF, dateF, datetimeF } from '@sonamu-kit/react-sui';\n\nimport { ${names.capital}SubsetA } from \"src/services/sonamu.generated\";\nimport { ${names.capital}Service } from 'src/services/${names.fs}/${\n names.fs\n }.service';\nimport { ${names.capital}ListParams } from 'src/services/${names.fs}/${\n names.fs\n }.types';\n${columnImports}\n${filterColumns\n .map((col) => {\n return this.renderFilterImport(entityId, col, names);\n })\n .join(\"\\n\")}\n\ntype ${names.capital}ListProps = {};\nexport default function ${names.capital}List({}: ${names.capital}ListProps) {\n // 리스트 필터\n const { listParams, register } = useListParams(${names.capital}ListParams, {\n num: 12,\n page: 1,\n orderBy: '${def.orderBy}',\n search: '${def.search}',\n });\n\n // 리스트 쿼리\n const { data, mutate, error, isLoading } = ${names.capital}Service.use${\n names.capitalPlural\n }('A', listParams);\n const { rows, total } = data ?? {};\n\n // 삭제\n const confirmDel = (ids: number[]) => {\n const answer = confirm('삭제하시겠습니까?');\n if (!answer) {\n return;\n }\n\n ${names.capital}Service.del(ids).then(() => {\n mutate();\n });\n };\n\n // 일괄 삭제\n const confirmDelSelected = () => {\n const answer = confirm(\\`\\${selectedKeys.length}건을 일괄 삭제하시겠습니까?\\`);\n if (!answer) {\n return;\n }\n\n ${names.capital}Service.del(selectedKeys).then(() => {\n mutate();\n });\n };\n\n // 현재 경로와 타이틀\n const PAGE = {\n route: '/admin/${names.fsPlural}',\n title: '${entity.title ?? names.capital}',\n };\n\n // 선택\n const {\n getSelected,\n isAllSelected,\n selectedKeys,\n toggle,\n selectAll,\n deselectAll,\n handleCheckboxClick,\n } = useSelection((rows ?? []).map((row) => row.id));\n\n // 컬럼\n const columns:SonamuCol<${names.capital}SubsetA>[] = [${columns\n .map((col) => {\n return [\n `{ label: \"${col.label}\",`,\n `tc: ${col.tc}, `,\n `collapsing: ${[\"Title\", \"Name\"].includes(col.label) === false}, }`,\n ].join(\"\\n\");\n })\n .join(\",\\n\")}];\n\n return (\n <div className=\"list ${names.fsPlural}-index\">\n <div className=\"top-nav\">\n <div className=\"header-row\">\n <div className=\"header\">{PAGE.title}</div>\n <AppBreadcrumbs>\n <Breadcrumb.Section active>{PAGE.title}</Breadcrumb.Section>\n </AppBreadcrumbs>\n <${names.capital}SearchInput\n input={register('keyword')}\n dropdown={register('search')}\n />\n </div>\n <div className=\"filters-row\">\n ${filterColumns\n .map((col) => {\n return this.renderFilter(entityId, col, names);\n })\n .join(\" \\n\")}\n </div>\n </div>\n\n <Segment basic padded className=\"contents-segment\" loading={isLoading}>\n <div className=\"buttons-row\">\n <div className={classNames('count', { hidden: isLoading })}>\n {total} 건\n </div>\n <div className=\"buttons\">\n <AddButton currentRoute={PAGE.route} icon=\"write\" label=\"추가\" />\n </div>\n </div>\n\n <Table\n celled\n compact\n selectable\n className={classNames({ hidden: total === undefined || total === 0 })}\n >\n <Table.Header>\n <TableRow>\n <Table.HeaderCell collapsing>\n <Checkbox\n label=\"ID\"\n checked={isAllSelected}\n onChange={isAllSelected ? deselectAll : selectAll}\n />\n </Table.HeaderCell>\n {\n /* Header */\n columns.map((col, index) => col.th ?? <Table.HeaderCell key={index} collapsing={col.collapsing}>{ col.label }</Table.HeaderCell>)\n }\n <Table.HeaderCell>관리</Table.HeaderCell>\n </TableRow>\n </Table.Header>\n <Table.Body>\n {rows &&\n rows.map((row, rowIndex) => (\n <Table.Row key={row.id}>\n <Table.Cell>\n <Checkbox\n label={row.id}\n checked={getSelected(row.id)}\n onChange={() => toggle(row.id)}\n onClick={(e) =>\n handleCheckboxClick(e, rowIndex)\n }\n />\n </Table.Cell>\n {\n /* Body */\n columns.map((col, colIndex) => (\n <Table.Cell key={colIndex} collapsing={col.collapsing} className={col.className}>\n {col.tc(row, rowIndex)}\n </Table.Cell>\n ))\n }\n <Table.Cell collapsing>\n <EditButton\n as={Link}\n to={\\`\\${PAGE.route}/form?id=\\${row.id}\\`}\n state={{ from: PAGE.route }}\n />\n <DelButton onClick={() => confirmDel([row.id])} />\n </Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n <div\n className={classNames('pagination-row', {\n hidden: (total ?? 0) === 0,\n })}\n >\n <Pagination\n totalPages={Math.ceil((total ?? 0) / (listParams.num ?? 24))}\n {...register('page')}\n />\n </div>\n </Segment>\n\n <div className=\"fixed-menu\">\n <Transition\n visible={selectedKeys.length > 0}\n animation=\"slide left\"\n duration={500}\n >\n <Message size=\"small\" color=\"violet\" className=\"text-center\">\n <span className=\"px-4\">{selectedKeys.length}개 선택됨</span>\n <Button size=\"tiny\" color=\"violet\" onClick={() => deselectAll()}>\n 선택 해제\n </Button>\n <Button size=\"tiny\" color=\"red\" onClick={confirmDelSelected}>\n 일괄 삭제\n </Button>\n </Message>\n </Transition>\n </div>\n </div>\n );\n}\n `.trim(),\n importKeys: [],\n preTemplates,\n };\n }\n}\n\nexport function getEnumInfoFromColName(\n entityId: string,\n colName: string\n): {\n id: string;\n targetEntityNames: EntityNamesRecord;\n targetEntityId: string;\n title: string;\n} {\n const baseEntity = EntityManager.get(entityId);\n const prop = baseEntity.props.find((p) => p.name === colName);\n if (prop && isEnumProp(prop)) {\n return {\n id: prop.id,\n targetEntityId: entityId,\n targetEntityNames: EntityManager.getNamesFromId(entityId),\n title: prop.desc ?? prop.id,\n };\n } else {\n const idCandidate = inflection.camelize(\n inflection.underscore(entityId) + \"_\" + inflection.underscore(colName),\n false\n );\n try {\n const targetEntityNames = EntityManager.getNamesFromId(entityId);\n return {\n id: idCandidate,\n targetEntityId: entityId,\n targetEntityNames: targetEntityNames,\n title: idCandidate,\n };\n } catch {}\n throw new Error(`찾을 수 없는 EnumProp ${colName}`);\n }\n}\n\nexport function getRelationPropFromColName(\n entityId: string,\n colName: string\n): RelationProp {\n const baseEntity = EntityManager.get(entityId);\n const relProp = baseEntity.props.find((prop) => prop.name === colName);\n if (isRelationProp(relProp)) {\n const relEntity = EntityManager.get(relProp.with);\n if (relEntity.parentId !== undefined) {\n throw new Error(\"Only parent entities can be used as relation props\");\n }\n return relProp;\n } else {\n throw new Error(`찾을 수 없는 Relation ${colName}`);\n }\n}\n","import path from \"path\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { DBKnexClass } from \"./drivers/knex/db\";\nimport { DBKyselyClass } from \"./drivers/kysely/db\";\nimport { SonamuDBBaseConfig } from \"./types\";\n\nconst dbConfigPath: string = path.join(\n findApiRootPath(),\n \"/dist/configs/db.js\"\n);\nconst knexfileModule = require(dbConfigPath);\n\nexport const DB = (() => {\n const config = (knexfileModule.default?.default ??\n knexfileModule.default ??\n knexfileModule) as SonamuDBBaseConfig;\n if (config.client === \"knex\") {\n return new DBKnexClass();\n } else if (config.client === \"kysely\") {\n return new DBKyselyClass();\n }\n throw new Error(\"지원하지 않는 DB 클라이언트입니다.\");\n})();\n","import _ from \"lodash\";\nimport { DBPreset, KnexBaseConfig, SonamuKnexDBConfig } from \"../../types\";\nimport knex, { Knex } from \"knex\";\nimport { KnexClient } from \"./client\";\nimport { DBClass } from \"../../db.abstract\";\nimport { attachOnDuplicateUpdate } from \"./plugins/knex-on-duplicate-update\";\nimport { KnexGenerator } from \"./generator\";\n\nexport class DBKnexClass extends DBClass {\n public migrationTable = \"knex_migrations\";\n public generator: KnexGenerator = new KnexGenerator();\n public baseConfig?: KnexBaseConfig;\n\n public declare _fullConfig?: SonamuKnexDBConfig;\n set fullConfig(config: SonamuKnexDBConfig) {\n this._fullConfig = config;\n }\n get fullConfig() {\n if (!this._fullConfig) {\n throw new Error(\"DB Config has not been initialized\");\n }\n return this._fullConfig;\n }\n\n private wdb?: Knex;\n private rdb?: Knex;\n\n private _tdb: KnexClient | null = null;\n set tdb(tdb: KnexClient) {\n this._tdb = tdb;\n }\n get tdb(): KnexClient {\n if (this._tdb === null) {\n throw new Error(\"tdb has not been initialized\");\n }\n return this._tdb;\n }\n\n private _fdb: KnexClient | null = null;\n set fdb(fdb: KnexClient) {\n this._fdb = fdb;\n }\n get fdb(): KnexClient {\n if (this._fdb === null) {\n throw new Error(\"fdb has not been initialized\");\n }\n return this._fdb;\n }\n\n get connectionInfo() {\n return _.mapValues(this.fullConfig, ({ connection }) => ({\n host: connection.host ?? \"localhost\",\n port: connection.port ?? 3306,\n database: connection.database,\n user: connection.user,\n password: connection.password,\n }));\n }\n\n constructor() {\n super();\n attachOnDuplicateUpdate();\n }\n\n init(config: KnexBaseConfig) {\n this.baseConfig = config;\n this.fullConfig = this.generateDBConfig(config);\n }\n\n async testInit() {\n if (this._tdb !== null) {\n return;\n }\n\n if (this.fullConfig.test && this.fullConfig.production_master) {\n const tConn = this.connectionInfo.test;\n const pConn = this.connectionInfo.production_master;\n\n if (\n `${tConn.host ?? \"localhost\"}:${tConn.port ?? 3306}/${\n tConn.database\n }` ===\n `${pConn.host ?? \"localhost\"}:${pConn.port ?? 3306}/${pConn.database}`\n ) {\n throw new Error(\n `테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`\n );\n }\n }\n\n this.tdb = new KnexClient(this.fullConfig.test);\n this.fdb = new KnexClient(this.fullConfig.fixture_local);\n }\n\n getDB(which: DBPreset) {\n const instanceName = which === \"w\" ? \"wdb\" : \"rdb\";\n\n if (!this[instanceName]) {\n const config = this.getCurrentConfig(which);\n this[instanceName] = knex(config);\n }\n\n return this[instanceName]!;\n }\n\n getClient(mode: keyof SonamuKnexDBConfig) {\n return new KnexClient(this.fullConfig[mode]);\n }\n\n async destroy(): Promise<void> {\n if (this.wdb !== undefined) {\n await this.wdb.destroy();\n this.wdb = undefined;\n }\n if (this.rdb !== undefined) {\n await this.rdb.destroy();\n this.rdb = undefined;\n }\n }\n\n async testDestroy() {\n if (this._tdb) {\n await this._tdb.destroy();\n this._tdb = null;\n }\n if (this._fdb) {\n await this._fdb.destroy();\n this._fdb = null;\n }\n }\n\n raw(db: Knex, query: string) {\n return db.raw(query);\n }\n\n private generateDBConfig(config: KnexBaseConfig): SonamuKnexDBConfig {\n const defaultKnexConfig = _.merge(\n {\n client: \"mysql2\",\n pool: {\n min: 1,\n max: 5,\n },\n migrations: {\n extension: \"js\",\n directory: \"./dist/migrations\",\n },\n connection: {\n host: \"localhost\",\n port: 3306,\n database: config.database,\n },\n },\n config.defaultOptions\n );\n\n // 로컬 환경 설정\n const test = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_test`,\n },\n });\n\n const fixture_local = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_fixture`,\n },\n });\n\n // 개발 환경 설정\n const devMasterOptions = config.environments?.development;\n const devSlaveOptions = config.environments?.development_slave;\n const development_master = _.merge({}, defaultKnexConfig, devMasterOptions);\n const development_slave = _.merge(\n {},\n defaultKnexConfig,\n devMasterOptions,\n devSlaveOptions\n );\n const fixture_remote = _.merge({}, defaultKnexConfig, devMasterOptions, {\n connection: {\n database: `${config.database}_fixture`,\n },\n });\n\n // 프로덕션 환경 설정\n const prodMasterOptions = config.environments?.production ?? {};\n const prodSlaveOptions = config.environments?.production_slave ?? {};\n const production_master = _.merge({}, defaultKnexConfig, prodMasterOptions);\n const production_slave = _.merge(\n {},\n defaultKnexConfig,\n prodMasterOptions,\n prodSlaveOptions\n );\n\n return {\n test,\n fixture_local,\n fixture_remote,\n development_master,\n development_slave,\n production_master,\n production_slave,\n };\n }\n\n /**\n * keys에 해당하는 설정들을 중복없이 가져옵니다. (host/port/database가 같은 설정은 중복으로 처리합니다.)\n */\n getUniqueConfigs(keys: (keyof SonamuKnexDBConfig)[]) {\n const targets = keys.map((key) => ({\n connKey: key,\n options: this.fullConfig[key as keyof SonamuKnexDBConfig],\n }));\n\n return _.uniqBy(targets, ({ options }) => {\n const conn = options.connection as Knex.ConnectionConfig & {\n port?: number;\n };\n\n return `${conn.host ?? \"localhost\"}:${conn.port ?? 3306}/${\n conn.database\n }`;\n });\n }\n}\n","import knex, { Knex } from \"knex\";\nimport { DatabaseClient, KnexConfig, WhereClause } from \"../../types\";\nimport { asArray } from \"../../../utils/model\";\nimport _ from \"lodash\";\nimport { KnexGenerator } from \"./generator\";\n\n// 확장된 Transaction 타입 정의\nexport type ExtendedKnexTrx = Knex.Transaction & DatabaseClient<\"knex\">;\n\nexport class KnexClient implements DatabaseClient<\"knex\"> {\n private knex: Knex;\n generator: KnexGenerator = new KnexGenerator();\n\n get connectionInfo() {\n return {\n host: this.knex.client.config.connection?.host ?? \"localhost\",\n port: this.knex.client.config.connection?.port ?? 3306,\n database: this.knex.client.config.connection?.database ?? \"\",\n user: this.knex.client.config.connection?.user ?? \"\",\n password: this.knex.client.config.connection?.password ?? \"\",\n };\n }\n\n private _qb?: Knex.QueryBuilder;\n set qb(qb: Knex.QueryBuilder) {\n this._qb = qb;\n }\n get qb() {\n if (!this._qb) {\n throw new Error(\"QueryBuilder is not initialized\");\n }\n return this._qb;\n }\n\n get sql() {\n return this.qb.toQuery();\n }\n\n constructor(\n private config: KnexConfig,\n _knex?: Knex\n ) {\n this.knex = _knex ?? knex(this.config);\n }\n\n from(table: string): KnexClient {\n this.qb = this.knex.from(table);\n return this;\n }\n\n innerJoin(table: string, k1: string, k2: string) {\n this.qb = this.qb.innerJoin(table, k1, k2);\n return this;\n }\n\n leftJoin(table: string, k1: string, k2: string) {\n this.qb = this.qb.leftJoin(table, k1, k2);\n return this;\n }\n\n clearSelect() {\n this.qb = this.qb.clearSelect();\n return this;\n }\n\n select(columns: string | string[]) {\n this.qb = this.qb.select(asArray(columns));\n return this;\n }\n\n selectAll() {\n this.qb = this.qb.select(\"*\");\n return this;\n }\n\n where(ops: WhereClause | WhereClause[]) {\n if (typeof ops[0] === \"string\") {\n ops = [ops as WhereClause];\n }\n for (const [lhs, op, rhs] of asArray(ops)) {\n this.qb = this.qb.where(lhs, op, rhs);\n }\n return this;\n }\n\n orWhere(ops: WhereClause | WhereClause[]) {\n this.qb = this.qb.orWhere((qb) => {\n for (const [lhs, op, rhs] of asArray(ops)) {\n qb.andWhere(lhs, op, rhs);\n }\n });\n return this;\n }\n\n async insert(table: string, data: any[]) {\n await this.knex(table).insert(data);\n }\n\n async upsert(table: string, data: any[]) {\n const q = this.knex(table).insert(data);\n const updateFields = Array.isArray(data) ? Object.keys(data[0]) : data;\n await q.onDuplicateUpdate.apply(q, updateFields);\n }\n\n limit(limit: number) {\n this.qb = this.qb.limit(limit);\n return this;\n }\n\n offset(offset: number) {\n this.qb = this.qb.offset(offset);\n return this;\n }\n\n count(column: string, alias?: string) {\n this.qb = this.qb.count(alias ? `${column} as ${alias}` : column);\n return this;\n }\n\n distinct(column: string) {\n this.qb = this.qb.distinct(column);\n return this;\n }\n\n first() {\n this.qb = this.qb.limit(1);\n return this;\n }\n\n async execute(trx?: ExtendedKnexTrx): Promise<any[]> {\n if (trx) {\n return this.qb.transacting(trx);\n }\n return this.qb;\n }\n\n async pluck(column: string): Promise<any[]> {\n return this.qb.pluck(column);\n }\n\n createRawQuery(query: string, bindings?: any[]) {\n if (bindings?.length) {\n return this.knex.raw(query, bindings).toQuery();\n }\n return this.knex.raw(query).toQuery();\n }\n\n async raw<R>(query: string, bindings?: any[]): Promise<R[]> {\n if (bindings?.length) {\n return (await this.knex.raw(query, bindings))[0];\n }\n return (await this.knex.raw(query))[0];\n }\n\n async truncate(table: string) {\n await this.knex(table).truncate();\n }\n\n trx(callback: (trx: KnexClient) => Promise<any>) {\n return this.knex.transaction((trx) =>\n callback(new KnexClient(this.config, trx))\n );\n }\n\n destroy() {\n return this.knex.destroy();\n }\n\n clearQueryParts(parts: (\"order\" | \"offset\" | \"limit\")[]) {\n this.qb = parts.reduce((acc, part) => acc.clear(part), this.qb.clone());\n return this;\n }\n\n clone() {\n const client = new KnexClient(this.config);\n client.qb = this.qb.clone();\n return client;\n }\n\n // Migrator\n\n async getMigrations() {\n const [, result] = (await this.knex.migrate.list()) as [\n unknown,\n {\n file: string;\n directory: string;\n }[],\n ];\n\n return result.map((r) => r.file.replace(\".js\", \"\"));\n }\n\n async status() {\n return this.knex.migrate.status();\n }\n\n async migrate() {\n return this.knex.migrate.latest();\n }\n\n async rollback() {\n return this.knex.migrate.rollback();\n }\n\n async rollbackAll() {\n return this.knex.migrate.rollback(undefined, true);\n }\n}\n","import _ from \"lodash\";\n\nexport type ListResult<T> = {\n rows: T[];\n total?: number;\n};\n\nexport type ArrayOr<T> = T | T[];\n\nexport function asArray<T>(param: T | T[]): T[] {\n if (Array.isArray(param)) {\n return param;\n } else {\n return [param as T] as T[];\n }\n}\n\nexport function objToMap<T>(obj: { [k: string]: T }) {\n const keys = Object.keys(obj);\n if (keys.every((key) => parseInt(key).toString() === key)) {\n return new Map<number, T>(keys.map((key) => [parseInt(key), obj[key]]));\n } else {\n return new Map<string, T>(Object.entries(obj));\n }\n}\n\nexport interface BaseListParams {\n id?: number | number[];\n num?: number;\n page?: number;\n keyword?: string;\n queryMode?: \"list\" | \"count\" | \"both\";\n}\n","import _ from \"lodash\";\nimport prettier from \"prettier\";\nimport inflection from \"inflection\";\nimport equal from \"fast-deep-equal\";\nimport {\n GenMigrationCode,\n MigrationColumn,\n MigrationForeign,\n MigrationIndex,\n} from \"../../../types/types\";\nimport { CodeGenerator } from \"../../code-generator\";\nimport { EntityManager } from \"../../../entity/entity-manager\";\n\nexport class KnexGenerator extends CodeGenerator {\n async generateCreateCode_ColumnAndIndexes(\n table: string,\n columns: MigrationColumn[],\n indexes: MigrationIndex[]\n ): Promise<GenMigrationCode> {\n // 컬럼, 인덱스 처리\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.createTable(\"${table}\", (table) => {`,\n \"// columns\",\n ...this.genColumnDefinitions(columns),\n \"\",\n \"// indexes\",\n ...this.genIndexDefinitions(indexes),\n \"});\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n ` return knex.schema.dropTable(\"${table}\");`,\n \"}\",\n ];\n return {\n table,\n type: \"normal\",\n title: `create__${table}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n };\n }\n\n /*\n 테이블 생성하는 케이스 - FK 생성\n*/\n async generateCreateCode_Foreign(\n table: string,\n foreigns: MigrationForeign[]\n ): Promise<GenMigrationCode[]> {\n if (foreigns.length === 0) {\n return [];\n }\n\n const { up, down } = this.genForeignDefinitions(table, foreigns);\n if (up.length === 0 && down.length === 0) {\n console.log(\"fk 가 뭔가 다릅니다\");\n return [];\n }\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n \"// create fk\",\n ...up,\n \"});\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n \"// drop fk\",\n ...down,\n \"});\",\n \"}\",\n ];\n\n const foreignKeysString = foreigns\n .map((foreign) => foreign.columns.join(\"_\"))\n .join(\"_\");\n return [\n {\n table,\n type: \"foreign\",\n title: `foreign__${table}__${foreignKeysString}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n },\n ];\n }\n\n async generateAlterCode_ColumnAndIndexes(\n table: string,\n entityColumns: MigrationColumn[],\n entityIndexes: MigrationIndex[],\n dbColumns: MigrationColumn[],\n dbIndexes: MigrationIndex[]\n ): Promise<GenMigrationCode[]> {\n /*\n 세부 비교 후 다른점 찾아서 코드 생성\n\n 1. 컬럼갯수 다름: MD에 있으나, DB에 없다면 추가\n 2. 컬럼갯수 다름: MD에 없으나, DB에 있다면 삭제\n 3. 그외 컬럼(컬럼 갯수가 동일하거나, 다른 경우 동일한 컬럼끼리) => alter\n 4. 다른거 다 동일하고 index만 변경되는 경우\n\n ** 컬럼명을 변경하는 경우는 따로 핸들링하지 않음\n => drop/add 형태의 마이그레이션 코드가 생성되는데, 수동으로 rename 코드로 수정하여 처리\n */\n\n // 각 컬럼 이름 기준으로 add, drop, alter 여부 확인\n const alterColumnsTo = this.getAlterColumnsTo(entityColumns, dbColumns);\n\n // 추출된 컬럼들을 기준으로 각각 라인 생성\n const alterColumnLinesTo = this.getAlterColumnLinesTo(\n alterColumnsTo,\n entityColumns\n );\n\n // 인덱스의 add, drop 여부 확인\n const alterIndexesTo = this.getAlterIndexesTo(entityIndexes, dbIndexes);\n\n // 추출된 인덱스들을 기준으로 각각 라인 생성\n const alterIndexLinesTo = this.getAlterIndexLinesTo(\n alterIndexesTo,\n alterColumnsTo\n );\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...(alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.up : []),\n ...(alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.up : []),\n ...(alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.up : []),\n ...(alterIndexesTo.add.length > 0 ? alterIndexLinesTo.add.up : []),\n ...(alterIndexesTo.drop.length > 0 ? alterIndexLinesTo.drop.up : []),\n \"})\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...(alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.down : []),\n ...(alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.down : []),\n ...(alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.down : []),\n ...(alterIndexLinesTo.add.down.length > 0\n ? alterIndexLinesTo.add.down\n : []),\n ...(alterIndexLinesTo.drop.down.length > 0\n ? alterIndexLinesTo.drop.down\n : []),\n \"})\",\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n ...([\"add\", \"drop\", \"alter\"] as const)\n .map((action) => {\n const len = alterColumnsTo[action].length;\n if (len > 0) {\n return action + len;\n }\n return null;\n })\n .filter((part) => part !== null),\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n }\n\n async generateAlterCode_Foreigns(\n table: string,\n entityForeigns: MigrationForeign[],\n dbForeigns: MigrationForeign[]\n ): Promise<GenMigrationCode[]> {\n const getKey = (mf: MigrationForeign): string => {\n return [mf.columns.join(\"-\"), mf.to].join(\"///\");\n };\n const fkTo = entityForeigns.reduce(\n (result, entityF) => {\n const matchingDbF = dbForeigns.find(\n (dbF) => getKey(entityF) === getKey(dbF)\n );\n if (!matchingDbF) {\n result.add.push(entityF);\n return result;\n }\n\n if (equal(entityF, matchingDbF) === false) {\n result.alterSrc.push(matchingDbF);\n result.alterDst.push(entityF);\n return result;\n }\n return result;\n },\n {\n add: [] as MigrationForeign[],\n alterSrc: [] as MigrationForeign[],\n alterDst: [] as MigrationForeign[],\n }\n );\n\n const linesTo = {\n add: this.genForeignDefinitions(table, fkTo.add),\n alterSrc: this.genForeignDefinitions(table, fkTo.alterSrc),\n alterDst: this.genForeignDefinitions(table, fkTo.alterDst),\n };\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...linesTo.add.up,\n ...linesTo.alterSrc.down,\n ...linesTo.alterDst.up,\n \"})\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...linesTo.add.down,\n ...linesTo.alterDst.down,\n ...linesTo.alterSrc.up,\n \"})\",\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n \"foreigns\",\n // TODO 바뀌는 부분\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n }\n\n generateModelTemplate(\n entityId: string,\n def: { orderBy: string; search: string }\n ) {\n const names = EntityManager.getNamesFromId(entityId);\n const entity = EntityManager.get(entityId);\n\n return `\nimport { ListResult, asArray, NotFoundException, BadRequestException, api } from 'sonamu';\nimport { BaseModelClass } from 'sonamu/knex';\nimport {\n ${entityId}SubsetKey,\n ${entityId}SubsetMapping,\n} from \"../sonamu.generated\";\nimport {\n ${names.camel}SubsetQueries,\n} from \"../sonamu.generated.sso\";\nimport { ${entityId}ListParams, ${entityId}SaveParams } from \"./${names.fs}.types\";\n\n/*\n ${entityId} Model\n*/\nclass ${entityId}ModelClass extends BaseModelClass {\n modelName = \"${entityId}\";\n\n @api({ httpMethod: \"GET\", clients: [\"axios\", \"swr\"], resourceName: \"${entityId}\" })\n async findById<T extends ${entityId}SubsetKey>(\n subset: T,\n id: number\n ): Promise<${entityId}SubsetMapping[T]> {\n const { rows } = await this.findMany(subset, {\n id,\n num: 1,\n page: 1,\n });\n if (rows.length == 0) {\n throw new NotFoundException(\\`존재하지 않는 ${names.capital} ID \\${id}\\`);\n }\n\n return rows[0];\n }\n\n async findOne<T extends ${entityId}SubsetKey>(\n subset: T,\n listParams: ${entityId}ListParams\n ): Promise<${entityId}SubsetMapping[T] | null> {\n const { rows } = await this.findMany(subset, {\n ...listParams,\n num: 1,\n page: 1,\n });\n\n return rows[0] ?? null;\n }\n\n @api({ httpMethod: \"GET\", clients: [\"axios\", \"swr\"], resourceName: \"${names.capitalPlural}\" })\n async findMany<T extends ${entityId}SubsetKey>(\n subset: T,\n params: ${entityId}ListParams = {}\n ): Promise<ListResult<${entityId}SubsetMapping[T]>> {\n // params with defaults\n params = {\n num: 24,\n page: 1,\n search: \"${def.search}\",\n orderBy: \"${def.orderBy}\",\n ...params,\n };\n\n // build queries\n let { rows, total } = await this.runSubsetQuery({\n subset,\n params,\n subsetQuery: ${names.camel}SubsetQueries[subset],\n build: ({ qb }) => {\n // id\n if (params.id) {\n qb.whereIn(\"${entity.table}.id\", asArray(params.id));\n }\n\n // search-keyword\n if (params.search && params.keyword && params.keyword.length > 0) {\n if (params.search === \"id\") {\n qb.where(\"${entity.table}.id\", params.keyword);\n } \n // } else if (params.search === \"field\") {\n // qb.where(\"${entity.table}.field\", \"like\", \\`%\\${params.keyword}%\\`);\n // }\n else {\n throw new BadRequestException(\n \\`구현되지 않은 검색 필드 \\${params.search}\\`\n );\n }\n }\n\n // orderBy\n if (params.orderBy) {\n // default orderBy\n const [orderByField, orderByDirec] = params.orderBy.split(\"-\");\n qb.orderBy(\"${entity.table}.\" + orderByField, orderByDirec);\n }\n\n return qb;\n },\n debug: false,\n });\n\n return {\n rows,\n total,\n };\n }\n\n @api({ httpMethod: \"POST\" })\n async save(\n spa: ${entityId}SaveParams[]\n ): Promise<number[]> {\n const wdb = this.getDB(\"w\");\n const ub = this.getUpsertBuilder();\n\n // register\n spa.map((sp) => {\n ub.register(\"${entity.table}\", sp);\n });\n\n // transaction\n return wdb.transaction(async (trx) => {\n const ids = await ub.upsert(trx, \"${entity.table}\");\n\n return ids;\n });\n }\n\n @api({ httpMethod: \"POST\", guards: [ \"admin\" ] })\n async del(ids: number[]): Promise<number> {\n const wdb = this.getDB(\"w\");\n\n // transaction\n await wdb.transaction(async (trx) => {\n return trx(\"${entity.table}\").whereIn(\"${entity.table}.id\", ids).delete();\n });\n\n return ids.length;\n }\n}\n\nexport const ${entityId}Model = new ${entityId}ModelClass();\n `.trim();\n }\n\n /*\n MigrationColumn[] 읽어서 컬럼 정의하는 구문 생성\n*/\n private genColumnDefinitions(columns: MigrationColumn[]): string[] {\n return columns.map((column) => {\n const chains: string[] = [];\n if (column.name === \"id\") {\n return `table.increments().primary();`;\n }\n\n // FIXME: float(M,D) deprecated -> decimal(M,D) 이용하도록 하고, float/double 처리 추가\n if (column.type === \"float\" || column.type === \"decimal\") {\n chains.push(\n `${column.type}('${column.name}', ${column.precision}, ${column.scale})`\n );\n } else {\n let columnType = column.type;\n let extraType: string | undefined;\n if (columnType.includes(\"text\") && columnType !== \"text\") {\n extraType = columnType;\n columnType = \"text\";\n }\n chains.push(\n `${column.type}('${column.name}'${\n column.length ? `, ${column.length}` : \"\"\n }${extraType ? `, '${extraType}'` : \"\"})`\n );\n }\n if (column.unsigned) {\n chains.push(\"unsigned()\");\n }\n\n chains.push(column.nullable ? \"nullable()\" : \"notNullable()\");\n\n if (column.defaultTo !== undefined) {\n if (\n typeof column.defaultTo === \"string\" &&\n column.defaultTo.startsWith(`\"`)\n ) {\n chains.push(`defaultTo(${column.defaultTo})`);\n } else {\n chains.push(`defaultTo(knex.raw('${column.defaultTo}'))`);\n }\n }\n\n return `table.${chains.join(\".\")};`;\n });\n }\n\n /*\n MigrationIndex[] 읽어서 인덱스/유니크 정의하는 구문 생성\n*/\n private genIndexDefinitions(indexes: MigrationIndex[]): string[] {\n if (indexes.length === 0) {\n return [];\n }\n const lines = _.uniq(\n indexes.reduce((r, index) => {\n r.push(\n `table.${index.type}([${index.columns\n .map((col) => `'${col}'`)\n .join(\",\")}])`\n );\n return r;\n }, [] as string[])\n );\n return lines;\n }\n\n private getAlterColumnLinesTo(\n columnsTo: ReturnType<KnexGenerator[\"getAlterColumnsTo\"]>,\n entityColumns: MigrationColumn[]\n ) {\n let linesTo = {\n add: {\n up: [] as string[],\n down: [] as string[],\n },\n drop: {\n up: [] as string[],\n down: [] as string[],\n },\n alter: {\n up: [] as string[],\n down: [] as string[],\n },\n };\n\n linesTo.add = {\n up: [\"// add\", ...this.genColumnDefinitions(columnsTo.add)],\n down: [\n \"// rollback - add\",\n `table.dropColumns(${columnsTo.add\n .map((col) => `'${col.name}'`)\n .join(\", \")})`,\n ],\n };\n linesTo.drop = {\n up: [\n \"// drop\",\n `table.dropColumns(${columnsTo.drop\n .map((col) => `'${col.name}'`)\n .join(\", \")})`,\n ],\n down: [\n \"// rollback - drop\",\n ...this.genColumnDefinitions(columnsTo.drop),\n ],\n };\n linesTo.alter = columnsTo.alter.reduce(\n (r, dbColumn) => {\n const entityColumn = entityColumns.find(\n (col) => col.name == dbColumn.name\n );\n if (entityColumn === undefined) {\n return r;\n }\n\n // 컬럼 변경사항\n const columnDiffUp = _.difference(\n this.genColumnDefinitions([entityColumn]),\n this.genColumnDefinitions([dbColumn])\n );\n const columnDiffDown = _.difference(\n this.genColumnDefinitions([dbColumn]),\n this.genColumnDefinitions([entityColumn])\n );\n if (columnDiffUp.length > 0) {\n r.up = [\n ...r.up,\n \"// alter column\",\n ...columnDiffUp.map((l) => l.replace(\";\", \"\") + \".alter();\"),\n ];\n r.down = [\n ...r.down,\n \"// rollback - alter column\",\n ...columnDiffDown.map((l) => l.replace(\";\", \"\") + \".alter();\"),\n ];\n }\n\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n\n return linesTo;\n }\n\n private getAlterIndexLinesTo(\n indexesTo: ReturnType<KnexGenerator[\"getAlterIndexesTo\"]>,\n columnsTo: ReturnType<KnexGenerator[\"getAlterColumnsTo\"]>\n ) {\n let linesTo = {\n add: {\n up: [] as string[],\n down: [] as string[],\n },\n drop: {\n up: [] as string[],\n down: [] as string[],\n },\n };\n\n // 인덱스가 추가되는 경우, 컬럼과 같이 추가된 케이스에는 drop에서 제외해야함!\n linesTo.add = {\n up: [\"// add indexes\", ...this.genIndexDefinitions(indexesTo.add)],\n down: [\n \"// rollback - add indexes\",\n ...indexesTo.add\n .filter(\n (index) =>\n index.columns.every((colName) =>\n columnsTo.add.map((col) => col.name).includes(colName)\n ) === false\n )\n .map(\n (index) =>\n `table.drop${inflection.capitalize(index.type)}([${index.columns\n .map((columnName) => `'${columnName}'`)\n .join(\",\")}])`\n ),\n ],\n };\n // 인덱스가 삭제되는 경우, 컬럼과 같이 삭제된 케이스에는 drop에서 제외해야함!\n linesTo.drop = {\n up: [\n ...indexesTo.drop\n .filter(\n (index) =>\n index.columns.every((colName) =>\n columnsTo.drop.map((col) => col.name).includes(colName)\n ) === false\n )\n .map(\n (index) =>\n `table.drop${inflection.capitalize(index.type)}([${index.columns\n .map((columnName) => `'${columnName}'`)\n .join(\",\")}])`\n ),\n ],\n down: [\n \"// rollback - drop indexes\",\n ...this.genIndexDefinitions(indexesTo.drop),\n ],\n };\n\n return linesTo;\n }\n\n /*\n MigrationForeign[] 읽어서 외부키 constraint 정의하는 구문 생성\n */\n private genForeignDefinitions(\n table: string,\n foreigns: MigrationForeign[]\n ): { up: string[]; down: string[] } {\n return foreigns.reduce(\n (r, foreign) => {\n const columnsStringQuote = foreign.columns\n .map((col) => `'${col.replace(`${table}.`, \"\")}'`)\n .join(\",\");\n r.up.push(\n `table.foreign('${foreign.columns.join(\",\")}')\n .references('${foreign.to}')\n .onUpdate('${foreign.onUpdate}')\n .onDelete('${foreign.onDelete}')`\n );\n r.down.push(`table.dropForeign([${columnsStringQuote}])`);\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n }\n}\n","import _ from \"lodash\";\nimport equal from \"fast-deep-equal\";\nimport { MigrationColumn, MigrationIndex } from \"../types/types\";\n\nexport class CodeGenerator {\n getAlterColumnsTo(\n entityColumns: MigrationColumn[],\n dbColumns: MigrationColumn[]\n ) {\n const columnsTo = {\n add: [] as MigrationColumn[],\n drop: [] as MigrationColumn[],\n alter: [] as MigrationColumn[],\n };\n\n // 컬럼명 기준 비교\n const extraColumns = {\n db: _.differenceBy(dbColumns, entityColumns, (col) => col.name),\n entity: _.differenceBy(entityColumns, dbColumns, (col) => col.name),\n };\n if (extraColumns.entity.length > 0) {\n columnsTo.add = columnsTo.add.concat(extraColumns.entity);\n }\n if (extraColumns.db.length > 0) {\n columnsTo.drop = columnsTo.drop.concat(extraColumns.db);\n }\n\n // 동일 컬럼명의 세부 필드 비교\n const sameDbColumns = _.intersectionBy(\n dbColumns,\n entityColumns,\n (col) => col.name\n );\n const sameMdColumns = _.intersectionBy(\n entityColumns,\n dbColumns,\n (col) => col.name\n );\n columnsTo.alter = _.differenceWith(sameDbColumns, sameMdColumns, (a, b) =>\n equal(a, b)\n );\n\n return columnsTo;\n }\n\n getAlterIndexesTo(\n entityIndexes: MigrationIndex[],\n dbIndexes: MigrationIndex[]\n ) {\n // 인덱스 비교\n let indexesTo = {\n add: [] as MigrationIndex[],\n drop: [] as MigrationIndex[],\n };\n const extraIndexes = {\n db: _.differenceBy(dbIndexes, entityIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n entity: _.differenceBy(entityIndexes, dbIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n };\n if (extraIndexes.entity.length > 0) {\n indexesTo.add = indexesTo.add.concat(extraIndexes.entity);\n }\n if (extraIndexes.db.length > 0) {\n indexesTo.drop = indexesTo.drop.concat(extraIndexes.db);\n }\n\n return indexesTo;\n }\n}\n","import { Knex } from \"knex\";\nimport { Kysely } from \"kysely\";\nimport path from \"path\";\nimport { KnexClient } from \"./drivers/knex/client\";\nimport { KyselyClient } from \"./drivers/kysely/client\";\nimport {\n SonamuDBConfig,\n DBPreset,\n Database,\n SonamuDBBaseConfig,\n KnexConfig,\n} from \"./types\";\n\n// db.ts에 포함시킬 경우 순환참조 발생\n\nexport abstract class DBClass {\n public _fullConfig?: SonamuDBConfig;\n set fullConfig(config: SonamuDBConfig) {\n this._fullConfig = config;\n }\n get fullConfig() {\n if (!this._fullConfig) {\n throw new Error(\"FixtureManager has not been initialized\");\n }\n return this._fullConfig;\n }\n\n abstract tdb: KnexClient | KyselyClient;\n abstract fdb: KnexClient | KyselyClient;\n\n abstract testInit(): Promise<void>;\n abstract getDB(which: DBPreset): Knex | Kysely<Database>;\n abstract destroy(): Promise<void>;\n abstract raw(db: Knex | Kysely<Database>, query: string): any;\n\n async getBaseConfig(rootPath: string): Promise<SonamuDBBaseConfig> {\n const baseConfigPath = path.join(rootPath, \"/dist/configs/db.js\");\n const module = await import(baseConfigPath);\n const config = module.default?.default ?? module.default ?? module;\n return config;\n }\n\n getCurrentConfig(which?: DBPreset) {\n switch (process.env.NODE_ENV ?? \"development\") {\n case \"development\":\n case \"staging\":\n return which === \"w\"\n ? this.fullConfig[\"development_master\"]\n : this.fullConfig[\"development_slave\"] ??\n this.fullConfig[\"development_master\"];\n break;\n case \"production\":\n return which === \"w\"\n ? this.fullConfig[\"production_master\"]\n : this.fullConfig[\"production_slave\"] ??\n this.fullConfig[\"production_master\"];\n break;\n case \"test\":\n return this.fullConfig[\"test\"];\n break;\n default:\n throw new Error(\n `현재 ENV ${process.env.NODE_ENV}에는 설정 가능한 DB설정이 없습니다.`\n );\n }\n }\n\n toClient(db: Knex | Kysely<Database>): KnexClient | KyselyClient {\n if (db instanceof Kysely) {\n return new KyselyClient(this.getCurrentConfig(), db);\n } else {\n return new KnexClient(this.getCurrentConfig() as KnexConfig, db);\n }\n }\n}\n","import {\n ComparisonOperatorExpression,\n FileMigrationProvider,\n Kysely,\n Migrator,\n MysqlDialect,\n Transaction,\n sql,\n} from \"kysely\";\nimport {\n Database,\n DatabaseClient,\n DriverSpec,\n KyselyConfig,\n WhereClause,\n} from \"../../types\";\nimport _ from \"lodash\";\nimport { asArray } from \"../../../utils/model\";\nimport { createPool } from \"mysql2\";\n\ntype TB = keyof Database;\ntype TE = TB & string;\n\n// 확장된 Transaction 타입 정의\nexport type ExtendedKyselyTrx = Transaction<Database> &\n DatabaseClient<\"kysely\">;\n\nexport class KyselyClient implements DatabaseClient<\"kysely\"> {\n private kysely: Kysely<Database>;\n\n get connectionInfo() {\n return {\n host: this.config.host,\n port: this.config.port,\n database: this.config.database,\n user: this.config.user,\n password: this.config.password,\n };\n }\n\n private _qb?: DriverSpec[\"kysely\"][\"queryBuilder\"];\n set qb(qb: DriverSpec[\"kysely\"][\"queryBuilder\"]) {\n this._qb = qb;\n }\n get qb() {\n if (!this._qb) {\n throw new Error(\"QueryBuilder is not initialized\");\n }\n return this._qb;\n }\n\n private _migrator?: Migrator;\n set migrator(migrator: Migrator) {\n this._migrator = migrator;\n }\n get migrator() {\n if (!this._migrator) {\n throw new Error(\"Migrator is not initialized\");\n }\n return this._migrator;\n }\n\n get sql() {\n const bindings = this.qb.compile().parameters.map((p) => JSON.stringify(p));\n return this.qb.compile().sql.replace(/\\?/g, () => bindings.shift()!);\n }\n\n constructor(\n private config: KyselyConfig,\n kysely?: Kysely<Database>\n ) {\n const { onCreateConnection, migration, ...rest } = this.config;\n\n this.kysely =\n kysely ??\n new Kysely({\n dialect: new MysqlDialect({\n onCreateConnection,\n pool: createPool(rest),\n }),\n });\n\n this.migrator = new Migrator({\n db: this.kysely,\n provider: new FileMigrationProvider(migration as any),\n });\n }\n\n from(table: string) {\n this.qb = this.kysely.selectFrom(table as TB);\n return this;\n }\n\n innerJoin(table: string, k1: string, k2: string) {\n this.qb = this.qb.innerJoin(table as TB, k1 as TB, k2 as TB);\n return this;\n }\n\n leftJoin(table: string, k1: string, k2: string) {\n this.qb = this.qb.leftJoin(table as TB, k1 as TB, k2 as TB);\n return this;\n }\n\n clearSelect() {\n this.qb = this.qb.clearSelect();\n return this;\n }\n\n select(columns: string | string[]) {\n this.qb = this.qb.select(asArray(columns) as TE[]);\n return this;\n }\n\n selectAll() {\n this.qb = this.qb.selectAll();\n return this;\n }\n\n where(ops: WhereClause | WhereClause[]) {\n if (typeof ops[0] === \"string\") {\n ops = [ops as WhereClause];\n }\n for (const [lhs, op, rhs] of asArray(ops)) {\n this.qb = this.qb.where(\n lhs as any,\n op as ComparisonOperatorExpression,\n rhs\n );\n }\n return this;\n }\n\n orWhere(ops: WhereClause | WhereClause[]) {\n this.qb = this.qb.where((eb) =>\n eb.or(\n ops.map(([lhs, op, rhs]) =>\n eb(lhs as any, op as ComparisonOperatorExpression, rhs)\n )\n )\n );\n return this;\n }\n\n async insert(table: string, data: any[]) {\n await this.kysely\n .insertInto(table as TB)\n .values(data)\n .execute();\n }\n\n async upsert(table: string, data: any[]) {\n const q = this.kysely\n .insertInto(table as TB)\n .values(data)\n .onDuplicateKeyUpdate(() => {\n const updates: Record<string, any> = {};\n // 첫 번째 레코드의 키들을 기준으로 업데이트 설정\n Object.keys(data[0]).forEach((key) => {\n updates[key] = sql`VALUES(${sql.raw(key)})`; // VALUES 구문 사용\n });\n return updates;\n });\n await q.execute();\n }\n\n limit(limit: number) {\n this.qb = this.qb.limit(limit);\n return this;\n }\n\n offset(offset: number) {\n this.qb = this.qb.offset(offset);\n return this;\n }\n\n count(column: string, alias?: string) {\n this.qb = this.qb.select((eb) =>\n eb.fn.count(column as any).as(alias ?? column)\n );\n return this;\n }\n\n distinct(column: string) {\n this.qb = this.qb.distinctOn(column as any);\n return this;\n }\n\n first() {\n this.qb = this.qb.limit(1);\n return this;\n }\n\n async execute(trx?: ExtendedKyselyTrx): Promise<any[]> {\n if (trx) {\n const { rows } = await trx.executeQuery(this.qb.compile());\n return rows as any[];\n }\n return this.qb.execute();\n }\n\n async pluck(column: string): Promise<any[]> {\n const result = await this.execute();\n return result.map((row) => row[column]);\n }\n\n createRawQuery(query: string, bindings?: any[]) {\n if (bindings?.length) {\n query = query.replace(\n /\\?/g,\n () => sql.lit(bindings.shift()).compile(this.kysely).sql\n );\n }\n return sql.raw(query).compile(this.kysely).sql;\n }\n\n async raw<R>(query: string, bindings?: any[]): Promise<R[]> {\n if (bindings?.length) {\n query = query.replace(\n /\\?/g,\n () => sql.lit(bindings.shift()).compile(this.kysely).sql\n );\n }\n const { rows } = await sql.raw(query).execute(this.kysely);\n return rows as R[];\n }\n\n async truncate(table: string) {\n await sql`truncate table ${sql.table(table)}`.execute(this.kysely);\n }\n\n trx<T>(callback: (trx: KyselyClient) => Promise<T>) {\n return this.kysely\n .transaction()\n .execute(async (trx) => callback(new KyselyClient(this.config, trx)));\n }\n\n destroy() {\n return this.kysely.destroy();\n }\n\n clearQueryParts(parts: (\"order\" | \"offset\" | \"limit\")[]) {\n for (const part of parts) {\n switch (part) {\n case \"order\":\n this.qb = this.qb.clearOrderBy();\n break;\n case \"offset\":\n this.qb = this.qb.clearOffset();\n break;\n case \"limit\":\n this.qb = this.qb.clearLimit();\n break;\n }\n }\n return this;\n }\n\n clone() {\n const client = new KyselyClient(this.config);\n client.qb = this.qb;\n return client;\n }\n\n // Migrator\n\n async getMigrations() {\n const result = await this.migrator.getMigrations();\n return result.filter((r) => !r.executedAt).map((r) => r.name);\n }\n\n async status() {\n const pendings = await this.getMigrations();\n return 0 - pendings.length;\n }\n\n async migrate() {\n const { results, error } = await this.migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n\n return [0, results?.map((r) => r.migrationName)];\n }\n\n async rollback() {\n const { results, error } = await this.migrator.migrateDown();\n if (error) {\n throw error;\n }\n\n return [0, results?.map((r) => r.migrationName)];\n }\n\n async rollbackAll() {\n while (true) {\n const { error, results } = await this.migrator.migrateDown();\n\n if (error) {\n console.error(\"Error while rollbackAll:\", error);\n throw error;\n }\n\n if (!results || results.length === 0) {\n console.log(\"RollbackAll completed\");\n break;\n }\n }\n }\n}\n","import knex from \"knex\";\n\nexport function attachOnDuplicateUpdate() {\n try {\n knex.QueryBuilder.extend(\"onDuplicateUpdate\", function (...columns) {\n if (columns.length === 0) {\n // 업데이트 할 컬럼이 없으면 onDuplicateUpdate 구문 처리 패스\n const { sql: originalSQL, bindings: originalBindings } = this.toSQL();\n return this.client.raw(originalSQL, originalBindings);\n }\n\n const { placeholders, bindings } = columns.reduce(\n (result, column) => {\n if (typeof column === \"string\") {\n result.placeholders.push(`?? = Values(??)`);\n result.bindings.push(column, column);\n } else if (column && typeof column === \"object\") {\n Object.keys(column).forEach((key) => {\n result.placeholders.push(`?? = ?`);\n result.bindings.push(key, column[key]);\n });\n } else {\n throw new Error(\n \"onDuplicateUpdate error: expected column name to be string or object.\"\n );\n }\n\n return result;\n },\n { placeholders: [], bindings: [] }\n );\n\n const { sql: originalSQL, bindings: originalBindings } = this.toSQL();\n\n const newBindings = [...originalBindings, ...bindings];\n\n return this.client.raw(\n `${originalSQL} ON DUPLICATE KEY UPDATE ${placeholders.join(\", \")}`,\n newBindings\n );\n });\n } catch {\n // ignored\n }\n}\n","import _ from \"lodash\";\nimport { promises } from \"fs\";\nimport path from \"path\";\nimport { createPool } from \"mysql2\";\nimport {\n DBPreset,\n Database,\n KyselyBaseConfig,\n KyselyConfig,\n SonamuKyselyDBConfig,\n} from \"../../types\";\nimport { FileMigrationProviderProps, Kysely, MysqlDialect, sql } from \"kysely\";\nimport { KyselyClient } from \"./client\";\nimport { DBClass } from \"../../db.abstract\";\nimport { Sonamu } from \"../../../api\";\nimport { KyselyGenerator } from \"./generator\";\n\nexport class DBKyselyClass extends DBClass {\n public migrationTable = \"kysely_migration\";\n public generator: KyselyGenerator = new KyselyGenerator();\n public baseConfig?: KyselyBaseConfig;\n\n public declare _fullConfig?: SonamuKyselyDBConfig;\n set fullConfig(config: SonamuKyselyDBConfig) {\n this._fullConfig = config;\n }\n get fullConfig() {\n if (!this._fullConfig) {\n throw new Error(\"DB Config has not been initialized\");\n }\n return this._fullConfig;\n }\n\n private wdb?: Kysely<Database>;\n private rdb?: Kysely<Database>;\n\n private _tdb: KyselyClient | null = null;\n set tdb(tdb: KyselyClient) {\n this._tdb = tdb;\n }\n get tdb(): KyselyClient {\n if (this._tdb === null) {\n throw new Error(\"tdb has not been initialized\");\n }\n return this._tdb;\n }\n\n private _fdb: KyselyClient | null = null;\n set fdb(fdb: KyselyClient) {\n this._fdb = fdb;\n }\n get fdb(): KyselyClient {\n if (this._fdb === null) {\n throw new Error(\"fdb has not been initialized\");\n }\n return this._fdb;\n }\n\n get connectionInfo() {\n return _.mapValues(this.fullConfig, (config) => ({\n host: config.host ?? \"localhost\",\n port: config.port ?? 3306,\n database: config.database,\n user: config.user,\n password: config.password,\n }));\n }\n\n constructor() {\n super();\n }\n\n init(config: KyselyBaseConfig) {\n this.baseConfig = config;\n this.fullConfig = this.generateDBConfig(config);\n }\n\n async testInit() {\n if (this._tdb !== null) {\n return;\n }\n\n if (this.fullConfig.test && this.fullConfig.production_master) {\n const tConnInfo = this.fullConfig.test;\n const pConnInfo = this.fullConfig.production_master;\n\n if (\n `${tConnInfo.host ?? \"localhost\"}:${tConnInfo.port ?? 3306}/${\n tConnInfo.database\n }` ===\n `${pConnInfo.host ?? \"localhost\"}:${pConnInfo.port ?? 3306}/${pConnInfo.database}`\n ) {\n throw new Error(\n `테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`\n );\n }\n }\n\n this.tdb = new KyselyClient(this.fullConfig.test);\n this.fdb = new KyselyClient(this.fullConfig.fixture_local);\n }\n\n get config(): SonamuKyselyDBConfig {\n return this.fullConfig;\n }\n\n getDB(which: DBPreset) {\n const instanceName = which === \"w\" ? \"wdb\" : \"rdb\";\n\n if (!this[instanceName]) {\n const _config: KyselyConfig = this.getCurrentConfig(which);\n const { onCreateConnection, migration, ...config } = _config;\n\n this[instanceName] = new Kysely<Database>({\n dialect: new MysqlDialect({\n onCreateConnection,\n pool: createPool(config),\n }),\n });\n }\n\n return this[instanceName]!;\n }\n\n getClient(mode: keyof SonamuKyselyDBConfig) {\n return new KyselyClient(this.fullConfig[mode]);\n }\n\n async destroy(): Promise<void> {\n if (this.wdb !== undefined) {\n await this.wdb.destroy();\n this.wdb = undefined;\n }\n if (this.rdb !== undefined) {\n await this.rdb.destroy();\n this.rdb = undefined;\n }\n }\n\n async testDestroy() {\n if (this._tdb) {\n await this._tdb.destroy();\n this._tdb = null;\n }\n if (this._fdb) {\n await this._fdb.destroy();\n this._fdb = null;\n }\n }\n\n raw(db: Kysely<Database>, query: string) {\n return sql`${query}`.execute(db);\n }\n\n private generateDBConfig(config: KyselyBaseConfig): SonamuKyselyDBConfig {\n const defaultKyselyConfig = _.merge(\n {\n migration: {\n fs: promises,\n path,\n migrationFolder: path.join(Sonamu.apiRootPath, \"/dist/migrations\"),\n } as FileMigrationProviderProps,\n port: 3306,\n host: \"localhost\",\n database: config.database,\n },\n config.defaultOptions\n );\n\n // 로컬 환경 설정\n const test = _.merge({}, defaultKyselyConfig, {\n database: `${config.database}_test`,\n });\n\n const fixture_local = _.merge({}, defaultKyselyConfig, {\n database: `${config.database}_fixture`,\n });\n\n // 개발 환경 설정\n const devMasterOptions = config.environments?.development;\n const devSlaveOptions = config.environments?.development_slave;\n const development_master = _.merge(\n {},\n defaultKyselyConfig,\n devMasterOptions\n );\n const development_slave = _.merge(\n {},\n defaultKyselyConfig,\n devMasterOptions,\n devSlaveOptions\n );\n const fixture_remote = _.merge({}, defaultKyselyConfig, devMasterOptions, {\n database: `${config.database}_fixture`,\n });\n\n // 프로덕션 환경 설정\n const prodMasterOptions = config.environments?.production ?? {};\n const prodSlaveOptions = config.environments?.production_slave ?? {};\n const production_master = _.merge(\n {},\n defaultKyselyConfig,\n prodMasterOptions\n );\n const production_slave = _.merge(\n {},\n defaultKyselyConfig,\n prodMasterOptions,\n prodSlaveOptions\n );\n\n return {\n test,\n fixture_local,\n fixture_remote,\n development_master,\n development_slave,\n production_master,\n production_slave,\n };\n }\n\n /**\n * keys에 해당하는 설정들을 중복없이 가져옵니다. (host/port/database가 같은 설정은 중복으로 처리합니다.)\n */\n getUniqueConfigs(keys: (keyof SonamuKyselyDBConfig)[]) {\n const targets = keys.map((key) => ({\n connKey: key,\n options: this.fullConfig[key as keyof SonamuKyselyDBConfig],\n }));\n\n return _.uniqBy(\n targets,\n ({ options }) =>\n `${options.host ?? \"localhost\"}:${options.port ?? 3306}/${options.database}`\n );\n }\n}\n","import _ from \"lodash\";\nimport prettier from \"prettier\";\nimport equal from \"fast-deep-equal\";\nimport {\n GenMigrationCode,\n MigrationColumn,\n MigrationForeign,\n MigrationIndex,\n} from \"../../../types/types\";\nimport { CodeGenerator } from \"../../code-generator\";\nimport { EntityManager } from \"../../../entity/entity-manager\";\n\nexport class KyselyGenerator extends CodeGenerator {\n async generateCreateCode_ColumnAndIndexes(\n table: string,\n columns: MigrationColumn[],\n indexes: MigrationIndex[]\n ): Promise<GenMigrationCode> {\n // 컬럼, 인덱스 처리\n const lines: string[] = [\n \"// @ts-ignore\",\n 'import { Kysely, sql } from \"kysely\";',\n 'import { Database } from \"sonamu\";',\n \"\",\n \"export async function up(db: Kysely<Database>): Promise<void> {\",\n `await db.schema.createTable(\"${table}\")`,\n ...this.genColumnDefinitions(columns),\n \".execute();\",\n \"\",\n \"// indexes\",\n ...this.genIndexDefinitions(table, indexes),\n \"}\",\n \"\",\n \"export async function down(db: Kysely<Database>): Promise<void> {\",\n ` await db.schema.dropTable(\"${table}\").execute();`,\n \"}\",\n ];\n\n return {\n table,\n type: \"normal\",\n title: `create__${table}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n };\n }\n\n /*\n 테이블 생성하는 케이스 - FK 생성\n*/\n async generateCreateCode_Foreign(\n table: string,\n foreigns: MigrationForeign[]\n ): Promise<GenMigrationCode[]> {\n if (foreigns.length === 0) {\n return [];\n }\n\n const { up, down } = this.genForeignDefinitions(table, foreigns);\n if (up.length === 0 && down.length === 0) {\n console.log(\"fk 가 뭔가 다릅니다\");\n return [];\n }\n\n const lines: string[] = [\n \"// @ts-ignore\",\n 'import { Kysely, sql } from \"kysely\";',\n 'import { Database } from \"sonamu\";',\n \"\",\n \"export async function up(db: Kysely<Database>): Promise<void> {\",\n ...up,\n \"}\",\n \"\",\n \"export async function down(db: Kysely<Database>): Promise<void> {\",\n ...down,\n \"}\",\n ];\n\n const foreignKeysString = foreigns\n .map((foreign) => foreign.columns.join(\"_\"))\n .join(\"_\");\n return [\n {\n table,\n type: \"foreign\",\n title: `foreign__${table}__${foreignKeysString}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n },\n ];\n }\n\n async generateAlterCode_ColumnAndIndexes(\n table: string,\n entityColumns: MigrationColumn[],\n entityIndexes: MigrationIndex[],\n dbColumns: MigrationColumn[],\n dbIndexes: MigrationIndex[]\n ): Promise<GenMigrationCode[]> {\n /*\n 세부 비교 후 다른점 찾아서 코드 생성\n\n 1. 컬럼갯수 다름: MD에 있으나, DB에 없다면 추가\n 2. 컬럼갯수 다름: MD에 없으나, DB에 있다면 삭제\n 3. 그외 컬럼(컬럼 갯수가 동일하거나, 다른 경우 동일한 컬럼끼리) => alter\n 4. 다른거 다 동일하고 index만 변경되는 경우\n\n ** 컬럼명을 변경하는 경우는 따로 핸들링하지 않음\n => drop/add 형태의 마이그레이션 코드가 생성되는데, 수동으로 rename 코드로 수정하여 처리\n */\n\n // 각 컬럼 이름 기준으로 add, drop, alter 여부 확인\n const alterColumnsTo = this.getAlterColumnsTo(entityColumns, dbColumns);\n\n // 추출된 컬럼들을 기준으로 각각 라인 생성\n const alterColumnLinesTo = this.getAlterColumnLinesTo(\n alterColumnsTo,\n entityColumns\n );\n\n // 인덱스의 add, drop 여부 확인\n const alterIndexesTo = this.getAlterIndexesTo(entityIndexes, dbIndexes);\n\n // 추출된 인덱스들을 기준으로 각각 라인 생성\n const alterIndexLinesTo = this.getAlterIndexLinesTo(\n table,\n alterIndexesTo,\n alterColumnsTo\n );\n\n const alterColumnsToExist =\n _.sumBy(Object.values(alterColumnsTo), (v) => v.length) > 0;\n const lines: string[] = [\n \"// @ts-ignore\",\n 'import { Kysely, sql } from \"kysely\";',\n 'import { Database } from \"sonamu\";',\n \"\",\n \"export async function up(db: Kysely<Database>): Promise<void> {\",\n ...(alterColumnsToExist\n ? [\n `await db.schema.alterTable(\"${table}\")`,\n ...(alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.up : []),\n ...(alterColumnsTo.drop.length > 0\n ? alterColumnLinesTo.drop.up\n : []),\n ...(alterColumnsTo.alter.length > 0\n ? alterColumnLinesTo.alter.up\n : []),\n \".execute();\",\n ]\n : []),\n ...(alterIndexesTo.add.length > 0 ? alterIndexLinesTo.add.up : []),\n ...(alterIndexesTo.drop.length > 0 ? alterIndexLinesTo.drop.up : []),\n \"}\",\n \"\",\n \"export async function down(db: Kysely<Database>): Promise<void> {\",\n ...(alterColumnsToExist\n ? [\n `await db.schema.alterTable(\"${table}\")`,\n ...(alterColumnsTo.add.length > 0\n ? alterColumnLinesTo.add.down\n : []),\n ...(alterColumnsTo.drop.length > 0\n ? alterColumnLinesTo.drop.down\n : []),\n ...(alterColumnsTo.alter.length > 0\n ? alterColumnLinesTo.alter.down\n : []),\n \".execute();\",\n ]\n : []),\n ...(alterIndexLinesTo.add.down.length > 0\n ? alterIndexLinesTo.add.down\n : []),\n ...(alterIndexLinesTo.drop.down.length > 0\n ? alterIndexLinesTo.drop.down\n : []),\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n ...([\"add\", \"drop\", \"alter\"] as const)\n .map((action) => {\n const len = alterColumnsTo[action].length;\n if (len > 0) {\n return action + len;\n }\n return null;\n })\n .filter((part) => part !== null),\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n }\n\n async generateAlterCode_Foreigns(\n table: string,\n entityForeigns: MigrationForeign[],\n dbForeigns: MigrationForeign[]\n ): Promise<GenMigrationCode[]> {\n const getKey = (mf: MigrationForeign): string => {\n return [mf.columns.join(\"-\"), mf.to].join(\"///\");\n };\n const fkTo = entityForeigns.reduce(\n (result, entityF) => {\n const matchingDbF = dbForeigns.find(\n (dbF) => getKey(entityF) === getKey(dbF)\n );\n if (!matchingDbF) {\n result.add.push(entityF);\n return result;\n }\n\n if (equal(entityF, matchingDbF) === false) {\n result.alterSrc.push(matchingDbF);\n result.alterDst.push(entityF);\n return result;\n }\n return result;\n },\n {\n add: [] as MigrationForeign[],\n alterSrc: [] as MigrationForeign[],\n alterDst: [] as MigrationForeign[],\n }\n );\n\n const linesTo = {\n add: this.genForeignDefinitions(table, fkTo.add),\n alterSrc: this.genForeignDefinitions(table, fkTo.alterSrc),\n alterDst: this.genForeignDefinitions(table, fkTo.alterDst),\n };\n\n const lines: string[] = [\n \"// @ts-ignore\",\n 'import { Kysely, sql } from \"kysely\";',\n 'import { Database } from \"sonamu\";',\n \"\",\n \"export async function up(db: Kysely<Database>): Promise<void> {\",\n ...linesTo.add.up,\n ...linesTo.alterSrc.down,\n ...linesTo.alterDst.up,\n \"}\",\n \"\",\n \"export async function down(db: Kysely<Database>): Promise<void> {\",\n ...linesTo.add.down,\n ...linesTo.alterDst.down,\n ...linesTo.alterSrc.up,\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n \"foreigns\",\n // TODO 바뀌는 부분\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n }\n\n generateModelTemplate(\n entityId: string,\n def: { orderBy: string; search: string }\n ) {\n const names = EntityManager.getNamesFromId(entityId);\n const entity = EntityManager.get(entityId);\n\n return `\nimport { ListResult, asArray, NotFoundException, BadRequestException, api } from 'sonamu';\nimport { BaseModelClass } from 'sonamu/kysely';\nimport {\n ${entityId}SubsetKey,\n ${entityId}SubsetMapping,\n} from \"../sonamu.generated\";\nimport {\n ${names.camel}SubsetQueries,\n} from \"../sonamu.generated.sso\";\nimport { ${entityId}ListParams, ${entityId}SaveParams } from \"./${names.fs}.types\";\n\n/*\n ${entityId} Model\n*/\nclass ${entityId}ModelClass extends BaseModelClass {\n modelName = \"${entityId}\";\n\n @api({ httpMethod: \"GET\", clients: [\"axios\", \"swr\"], resourceName: \"${entityId}\" })\n async findById<T extends ${entityId}SubsetKey>(\n subset: T,\n id: number\n ): Promise<${entityId}SubsetMapping[T]> {\n const { rows } = await this.findMany(subset, {\n id,\n num: 1,\n page: 1,\n });\n if (rows.length == 0) {\n throw new NotFoundException(\\`존재하지 않는 ${names.capital} ID \\${id}\\`);\n }\n\n return rows[0];\n }\n\n async findOne<T extends ${entityId}SubsetKey>(\n subset: T,\n listParams: ${entityId}ListParams\n ): Promise<${entityId}SubsetMapping[T] | null> {\n const { rows } = await this.findMany(subset, {\n ...listParams,\n num: 1,\n page: 1,\n });\n\n return rows[0] ?? null;\n }\n\n @api({ httpMethod: \"GET\", clients: [\"axios\", \"swr\"], resourceName: \"${names.capitalPlural}\" })\n async findMany<T extends ${entityId}SubsetKey>(\n subset: T,\n params: ${entityId}ListParams = {}\n ): Promise<ListResult<${entityId}SubsetMapping[T]>> {\n // params with defaults\n params = {\n num: 24,\n page: 1,\n search: \"${def.search}\",\n orderBy: \"${def.orderBy}\",\n ...params,\n };\n\n // build queries\n let { rows, total } = await this.runSubsetQuery({\n subset,\n params,\n subsetQuery: ${names.camel}SubsetQueries[subset],\n build: ({ qb }) => {\n // id\n if (params.id) {\n qb = qb.where(\"${entity.table}.id\", \"in\", asArray(params.id));\n }\n\n // search-keyword\n if (params.search && params.keyword && params.keyword.length > 0) {\n if (params.search === \"id\") {\n qb = qb.where(\"${entity.table}.id\", \"=\", Number(params.keyword));\n }\n // } else if (params.search === \"field\") {\n // qb = qb.where(\"${entity.table}.field\", \"like\", \\`%\\${params.keyword}%\\`);\n // }\n else {\n throw new BadRequestException(\n \\`구현되지 않은 검색 필드 \\${params.search}\\`\n );\n }\n }\n\n // orderBy\n if (params.orderBy) {\n // default orderBy\n const [orderByField, orderByDirec] = this.parseOrderBy(\n params.orderBy\n );\n qb = qb.orderBy(orderByField, orderByDirec);\n }\n\n return qb;\n },\n debug: false,\n });\n\n return {\n rows,\n total,\n };\n }\n\n @api({ httpMethod: \"POST\" })\n async save(\n spa: ${entityId}SaveParams[]\n ): Promise<number[]> {\n const wdb = this.getDB(\"w\");\n const ub = this.getUpsertBuilder();\n\n // register\n spa.map((sp) => {\n ub.register(\"${entity.table}\", sp);\n });\n\n // transaction\n return wdb.transaction().execute(async (trx) => {\n const ids = await ub.upsert(trx, \"${entity.table}\");\n\n return ids;\n });\n }\n\n @api({ httpMethod: \"POST\", guards: [ \"admin\" ] })\n async del(ids: number[]): Promise<number> {\n const wdb = this.getDB(\"w\");\n\n // transaction\n await wdb.transaction().execute(async (trx) => {\n return trx.deleteFrom(\"${entity.table}\").where(\"${entity.table}.id\", \"in\", ids).execute();\n });\n\n return ids.length;\n }\n}\n\nexport const ${entityId}Model = new ${entityId}ModelClass();\n `.trim();\n }\n\n /*\n MigrationColumn[] 읽어서 컬럼 정의하는 구문 생성\n*/\n private genColumnDefinitions(columns: MigrationColumn[]): string[] {\n return columns.map((column) => {\n let str = \"\";\n const chains: string[] = [];\n if (column.name === \"id\") {\n return `.addColumn(\"id\", \"integer\", (col) => col.unsigned().autoIncrement().primaryKey())`;\n }\n\n if (column.type === \"decimal\") {\n str = `.addColumn(\"${column.name}\", \"${column.type}(${column.precision}, ${column.scale})\"`;\n } else if (column.type.includes(\"text\")) {\n str = `.addColumn(\"${column.name}\", sql\\`${column.type.toUpperCase()}\\``;\n } else {\n let columnType: string = column.type;\n // FIXME: add double\n if (columnType === \"float\") {\n columnType = \"float4\";\n } else if (columnType === \"uuid\") {\n columnType = \"char(36)\";\n } else if (columnType === \"string\") {\n columnType = \"varchar\";\n }\n str = `.addColumn(\"${column.name}\", \"${columnType}${column.length ? `(${column.length})` : \"\"}\"`;\n }\n if (column.unsigned) {\n chains.push(\"unsigned()\");\n }\n\n if (!column.nullable) {\n chains.push(\"notNull()\");\n }\n\n if (column.defaultTo !== undefined) {\n if (\n typeof column.defaultTo === \"string\" &&\n column.defaultTo.startsWith(`\"`)\n ) {\n chains.push(`defaultTo(${column.defaultTo})`);\n } else {\n chains.push(`defaultTo(sql\\`${column.defaultTo}\\`)`);\n }\n }\n if (column.type === \"uuid\") {\n chains.push(\"defaultTo(sql`UUID()`)\");\n }\n\n return (\n (chains.length > 0 ? `${str}, (col) => col.${chains.join(\".\")}` : str) +\n \")\"\n );\n });\n }\n\n /*\n MigrationIndex[] 읽어서 인덱스/유니크 정의하는 구문 생성\n*/\n private genIndexDefinitions(\n table: string,\n indexes: MigrationIndex[]\n ): string[] {\n if (indexes.length === 0) {\n return [];\n }\n\n const lines = _.uniq(\n indexes.reduce((r, index) => {\n r.push(\n `await db.schema.createIndex(\"${this.createIndexName(table, index.columns, index.type)}\")\n .on(\"${table}\")\n .columns([${index.columns.map((col) => `\"${col}\"`).join(\",\")}])${index.type === \"unique\" ? \".unique()\" : \"\"}\n .execute();`\n );\n return r;\n }, [] as string[])\n );\n return lines;\n }\n\n /*\n MigrationForeign[] 읽어서 외부키 constraint 정의하는 구문 생성\n */\n private genForeignDefinitions(\n table: string,\n foreigns: MigrationForeign[]\n ): { up: string[]; down: string[] } {\n return foreigns.reduce(\n (r, foreign) => {\n const [toTable, toColumn] = foreign.to.split(\".\");\n const name = `${table}_${foreign.columns.join(\"_\")}_foreign`;\n const columnsStringQuote = foreign.columns\n .map((col) => `'${col.replace(`${table}.`, \"\")}'`)\n .join(\",\");\n\n r.up.push(\n \"// create fk\",\n `await db.schema.alterTable(\"${table}\")`,\n `.addForeignKeyConstraint(\"${name}\", [${columnsStringQuote}], \"${toTable}\", [\"${toColumn}\"])`,\n `.onUpdate(\"${foreign.onUpdate.toLowerCase()}\")`,\n `.onDelete(\"${foreign.onDelete.toLowerCase()}\")`,\n `.execute();`\n );\n r.down.push(\n \"// drop fk\",\n `await db.schema.alterTable(\"${table}\")`,\n `.dropConstraint(\"${name}\")`,\n `.execute();`\n );\n\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n }\n\n private getAlterColumnLinesTo(\n columnsTo: ReturnType<KyselyGenerator[\"getAlterColumnsTo\"]>,\n entityColumns: MigrationColumn[]\n ) {\n let linesTo = {\n add: {\n up: [] as string[],\n down: [] as string[],\n },\n drop: {\n up: [] as string[],\n down: [] as string[],\n },\n alter: {\n up: [] as string[],\n down: [] as string[],\n },\n };\n\n linesTo.add = {\n up: [\"// add\", ...this.genColumnDefinitions(columnsTo.add)],\n down: [\n \"// rollback - add\",\n ...columnsTo.add.map((col) => `.dropColumn(\"${col.name}\")`),\n ],\n };\n linesTo.drop = {\n up: [\n \"// drop\",\n ...columnsTo.drop.map((col) => `.dropColumn(\"${col.name}\")`),\n ],\n down: [\n \"// rollback - drop\",\n ...this.genColumnDefinitions(columnsTo.drop),\n ],\n };\n linesTo.alter = columnsTo.alter.reduce(\n (r, dbColumn) => {\n const entityColumn = entityColumns.find(\n (col) => col.name == dbColumn.name\n );\n if (entityColumn === undefined) {\n return r;\n }\n\n // 컬럼 변경사항\n const columnDiffUp = _.difference(\n this.genColumnDefinitions([entityColumn]),\n this.genColumnDefinitions([dbColumn])\n );\n const columnDiffDown = _.difference(\n this.genColumnDefinitions([dbColumn]),\n this.genColumnDefinitions([entityColumn])\n );\n if (columnDiffUp.length > 0) {\n r.up = [\n ...r.up,\n \"// alter column\",\n ...columnDiffUp.map((l) =>\n l.replace(\".addColumn\", \".modifyColumn\")\n ),\n ];\n r.down = [\n ...r.down,\n \"// rollback - alter column\",\n ...columnDiffDown.map((l) =>\n l.replace(\".addColumn\", \".modifyColumn\")\n ),\n ];\n }\n\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n\n return linesTo;\n }\n\n private getAlterIndexLinesTo(\n table: string,\n indexesTo: ReturnType<KyselyGenerator[\"getAlterIndexesTo\"]>,\n columnsTo: ReturnType<KyselyGenerator[\"getAlterColumnsTo\"]>\n ) {\n let linesTo = {\n add: {\n up: [] as string[],\n down: [] as string[],\n },\n drop: {\n up: [] as string[],\n down: [] as string[],\n },\n };\n\n // 인덱스가 추가되는 경우, 컬럼과 같이 추가된 케이스에는 drop에서 제외해야함!\n linesTo.add = {\n up: [\"// add indexes\", ...this.genIndexDefinitions(table, indexesTo.add)],\n down: [\n \"// rollback - add indexes\",\n ...indexesTo.add\n .filter(\n (index) =>\n index.columns.every((colName) =>\n columnsTo.add.map((col) => col.name).includes(colName)\n ) === false\n )\n .map(\n (index) => `await db.schema.alterTable(\"${table}\")\n .dropIndex(\"${this.createIndexName(table, index.columns, index.type)}\")\n .execute();`\n ),\n ],\n };\n // 인덱스가 삭제되는 경우, 컬럼과 같이 삭제된 케이스에는 drop에서 제외해야함!\n linesTo.drop = {\n up: [\n ...indexesTo.drop\n .filter(\n (index) =>\n index.columns.every((colName) =>\n columnsTo.drop.map((col) => col.name).includes(colName)\n ) === false\n )\n .map(\n (index) => `await db.schema.alterTable(\"${table}\")\n .dropIndex(\"${this.createIndexName(table, index.columns, index.type)}\")\n .execute();`\n ),\n ],\n down: [\n \"// rollback - drop indexes\",\n ...this.genIndexDefinitions(table, indexesTo.drop),\n ],\n };\n\n return linesTo;\n }\n\n private createIndexName(\n table: string,\n columns: string[],\n type: string\n ): string {\n if (columns[0].split(\".\").length > 1) {\n table = columns[0].split(\".\")[0];\n columns = columns.map((col) => col.split(\".\")[1]);\n }\n\n return `${table}_${columns.join(\"_\")}_${type}`;\n }\n}\n","import { RenderingNode, TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { Template__view_list } from \"./view_list.template\";\nimport { Sonamu } from \"../api\";\nimport { DB } from \"../database/db\";\n\nexport class Template__model extends Template {\n constructor() {\n super(\"model\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `${names.fs}/${names.fs}.model.ts`,\n };\n }\n\n render(\n { entityId }: TemplateOptions[\"model\"],\n _columnsNode: RenderingNode,\n listParamsNode: RenderingNode\n ) {\n const names = EntityManager.getNamesFromId(entityId);\n\n const vlTpl = new Template__view_list();\n if (listParamsNode?.children === undefined) {\n throw new Error(`listParamsNode가 없습니다. ${entityId}`);\n }\n const def = vlTpl.getDefault(listParamsNode.children);\n\n return {\n ...this.getTargetAndPath(names),\n body: DB.generator.generateModelTemplate(entityId, def),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { Sonamu } from \"../api\";\n\nexport class Template__model_test extends Template {\n constructor() {\n super(\"model_test\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `${names.fs}/${names.fs}.model.test.ts`,\n };\n }\n\n render({ entityId }: TemplateOptions[\"model_test\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport { describe, test, expect } from \"vitest\";\nimport { bootstrap } from '../../testing/bootstrap';\n\nbootstrap([]);\ndescribe.skip(\"${entityId}ModelTest\", () => {\n test(\"Query\", async () => {\n expect(true).toBe(true);\n });\n});\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import inflection from \"inflection\";\nimport _ from \"lodash\";\nimport { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { ApiParamType, ApiParam } from \"../types/types\";\nimport {\n apiParamTypeToTsType,\n apiParamToTsCode,\n unwrapPromiseOnce,\n} from \"../api/code-converters\";\nimport { ExtendedApi } from \"../api/decorators\";\nimport { Template } from \"./base-template\";\nimport { Sonamu } from \"../api/sonamu\";\n\nexport class Template__service extends Template {\n constructor() {\n super(\"service\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \":target/src/services\",\n path: `${names.fs}/${names.fs}.service.ts`,\n };\n }\n\n render({ entityId }: TemplateOptions[\"service\"], apis: ExtendedApi[]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n // 서비스 TypeSource\n const { lines, importKeys } = this.getTypeSource(apis);\n\n // AxiosProgressEvent 있는지 확인\n const hasAxiosProgressEvent = apis.find((api) =>\n (api.options.clients ?? []).includes(\"axios-multipart\")\n );\n\n return {\n ...this.getTargetAndPath(names),\n body: lines.join(\"\\n\"),\n importKeys: importKeys.filter(\n (key) => [\"ListResult\"].includes(key) === false\n ),\n customHeaders: [\n `import { z } from 'zod';`,\n `import qs from \"qs\";`,\n `import useSWR, { SWRResponse } from \"swr\";`,\n `import { fetch, ListResult, SWRError, SwrOptions, handleConditional, swrPostFetcher } from '../sonamu.shared';`,\n ...(hasAxiosProgressEvent\n ? [`import { AxiosProgressEvent } from 'axios';`]\n : []),\n ],\n };\n }\n\n getTypeSource(apis: ExtendedApi[]): {\n lines: string[];\n importKeys: string[];\n } {\n const importKeys: string[] = [];\n\n // 제네릭에서 선언한 타입, importKeys에서 제외 필요\n let typeParamNames: string[] = [];\n\n const groups = _.groupBy(apis, (api) => api.modelName);\n const body = Object.keys(groups)\n .map((modelName) => {\n const methods = groups[modelName];\n const methodCodes = methods\n .map((api) => {\n // 컨텍스트 제외된 파라미터 리스트\n const paramsWithoutContext = api.parameters.filter(\n (param) =>\n !ApiParamType.isContext(param.type) &&\n !ApiParamType.isRefKnex(param.type) &&\n !ApiParamType.isRefKysely(param.type) &&\n !(param.optional === true && param.name.startsWith(\"_\")) // _로 시작하는 파라미터는 제외\n );\n\n // 파라미터 타입 정의\n const typeParamsDef = api.typeParameters\n .map((typeParam) => {\n return apiParamTypeToTsType(typeParam, importKeys);\n })\n .join(\", \");\n typeParamNames = typeParamNames.concat(\n api.typeParameters.map((typeParam) => typeParam.id)\n );\n\n // 파라미터 정의\n const paramsDef = apiParamToTsCode(\n paramsWithoutContext,\n importKeys\n );\n\n // 리턴 타입 정의\n const returnTypeDef = apiParamTypeToTsType(\n unwrapPromiseOnce(api.returnType),\n importKeys\n );\n\n // 페이로드 데이터 정의\n const payloadDef = `{ ${paramsWithoutContext\n .map((param) => param.name)\n .join(\", \")} }`;\n\n return _.sortBy(api.options.clients, (client) =>\n client === \"swr\" ? 0 : 1\n )\n .map((client) => {\n const apiBaseUrl = `${Sonamu.config.route.prefix}${api.path}`;\n switch (client) {\n case \"axios\":\n return this.renderAxios(\n api,\n apiBaseUrl,\n typeParamsDef,\n paramsDef,\n returnTypeDef,\n payloadDef\n );\n case \"axios-multipart\":\n return this.renderAxiosMultipart(\n api,\n apiBaseUrl,\n typeParamsDef,\n paramsDef,\n returnTypeDef,\n paramsWithoutContext\n );\n case \"swr\":\n return this.renderSwr(\n api,\n apiBaseUrl,\n typeParamsDef,\n paramsDef,\n returnTypeDef,\n payloadDef\n );\n case \"window-fetch\":\n return this.renderWindowFetch(\n api,\n apiBaseUrl,\n typeParamsDef,\n paramsDef,\n payloadDef\n );\n case \"socketio\":\n default:\n return `// Not supported ${inflection.camelize(client, true)} yet.`;\n }\n })\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return `export namespace ${modelName.replace(/Model$/, \"Service\")} {\n${methodCodes}\n}`;\n })\n .join(\"\\n\\n\");\n\n return {\n lines: [body],\n importKeys: _.difference(_.uniq(importKeys), typeParamNames),\n };\n }\n\n renderAxios(\n api: ExtendedApi,\n apiBaseUrl: string,\n typeParamsDef: string,\n paramsDef: string,\n returnTypeDef: string,\n payloadDef: string\n ) {\n const methodNameAxios = api.options.resourceName\n ? \"get\" + inflection.camelize(api.options.resourceName)\n : api.methodName;\n\n if (api.options.httpMethod === \"GET\") {\n return `\nexport async function ${methodNameAxios}${typeParamsDef}(${paramsDef}): Promise<${returnTypeDef}> {\n return fetch({\n method: \"GET\",\n url: \\`${apiBaseUrl}?\\${qs.stringify(${payloadDef})}\\`,\n });\n}\n `.trim();\n } else {\n return `\nexport async function ${methodNameAxios}${typeParamsDef}(${paramsDef}): Promise<${returnTypeDef}> {\n return fetch({\n method: '${api.options.httpMethod}',\n url: \\`${apiBaseUrl}\\`,\n data: ${payloadDef},\n });\n}\n `.trim();\n }\n }\n\n renderAxiosMultipart(\n api: ExtendedApi,\n apiBaseUrl: string,\n typeParamsDef: string,\n paramsDef: string,\n returnTypeDef: string,\n paramsWithoutContext: ApiParam[]\n ) {\n const formDataDef = [\n 'formData.append(\"file\", file);',\n ...paramsWithoutContext.map(\n (param) => `formData.append('${param.name}', String(${param.name}));`\n ),\n ].join(\"\\n\");\n\n const paramsDefComma = paramsDef !== \"\" ? \", \" : \"\";\n return `\nexport async function ${api.methodName}${typeParamsDef}(\n ${paramsDef}${paramsDefComma}\n file: File,\n onUploadProgress?: (pe:AxiosProgressEvent) => void\n ): Promise<${returnTypeDef}> {\n const formData = new FormData();\n ${formDataDef}\n return fetch({\n method: 'POST',\n url: \\`${apiBaseUrl}\\`,\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n onUploadProgress,\n data: formData,\n });\n }\n `.trim();\n }\n\n renderSwr(\n api: ExtendedApi,\n apiBaseUrl: string,\n typeParamsDef: string,\n paramsDef: string,\n returnTypeDef: string,\n payloadDef: string\n ) {\n const methodNameSwr = api.options.resourceName\n ? \"use\" + inflection.camelize(api.options.resourceName)\n : \"use\" + inflection.camelize(api.methodName);\n return ` export function ${inflection.camelize(\n methodNameSwr,\n true\n )}${typeParamsDef}(${[paramsDef, \"swrOptions?: SwrOptions\"]\n .filter((p) => p !== \"\")\n .join(\",\")}, ): SWRResponse<${returnTypeDef}, SWRError> {\n return useSWR(handleConditional([\n \\`${apiBaseUrl}\\`,\n ${payloadDef},\n ], swrOptions?.conditional)${\n api.options.httpMethod === \"POST\" ? \", swrPostFetcher\" : \"\"\n });\n }`;\n }\n\n renderWindowFetch(\n api: ExtendedApi,\n apiBaseUrl: string,\n typeParamsDef: string,\n paramsDef: string,\n payloadDef: string\n ) {\n return `\nexport async function ${api.methodName}${typeParamsDef}(${paramsDef}): Promise<Response> {\n return window.fetch(\\`${apiBaseUrl}?\\${qs.stringify(${payloadDef})}\\`);\n}\n `.trim();\n }\n}\n","import inflection from \"inflection\";\nimport { z } from \"zod\";\nimport { RenderingNode, TemplateKey, TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { RenderedTemplate } from \"../syncer/syncer\";\nimport { Template } from \"./base-template\";\nimport {\n getEnumInfoFromColName,\n getRelationPropFromColName,\n} from \"./view_list.template\";\nimport _ from \"lodash\";\n\nexport class Template__view_form extends Template {\n constructor() {\n super(\"view_form\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/pages/admin\",\n path: `${names.fsPlural}/form.tsx`,\n };\n }\n\n wrapFC(body: string, label?: string): string {\n return [\n `<Form.Field>${label ? `\\n <label>${label}</label>` : \"\"}`,\n body,\n `</Form.Field>`,\n ].join(\"\\n\");\n }\n wrapFG(body: string, label?: string): string {\n return [\n `<Form.Group widths=\"equal\">`,\n this.wrapFC(body, label),\n `</Form.Group>`,\n ].join(\"\\n\");\n }\n\n renderColumnImport(entityId: string, col: RenderingNode) {\n if (col.renderType === \"enums\") {\n const { id, targetEntityNames } = getEnumInfoFromColName(\n entityId,\n col.name\n );\n const componentId = `${id}Select`;\n return `import { ${componentId} } from \"src/components/${targetEntityNames.fs}/${componentId}\";`;\n } else if (col.renderType === \"number-fk_id\") {\n try {\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n const targetNames = EntityManager.getNamesFromId(relProp.with);\n const componentId = `${relProp.with}IdAsyncSelect`;\n return `import { ${componentId} } from \"src/components/${targetNames.fs}/${componentId}\";`;\n } catch {\n return \"\";\n }\n } else {\n throw new Error(`렌더 불가능한 임포트 ${col.name} ${col.renderType}`);\n }\n }\n\n renderColumn(\n entityId: string,\n col: RenderingNode,\n names: EntityNamesRecord,\n parent: string = \"\"\n ): string {\n let regExpr: string = \"\";\n regExpr = `{...register(\\`${parent}${col.name}\\`)}`;\n\n switch (col.renderType) {\n case \"string-plain\":\n if (\n col.zodType instanceof z.ZodString &&\n (col.zodType.maxLength ?? 0) <= 512\n ) {\n return `<Input placeholder=\"${col.label}\" ${regExpr} />`;\n } else {\n return `<TextArea rows={8} placeholder=\"${col.label}\" ${regExpr} />`;\n }\n case \"string-datetime\":\n return `<SQLDateTimeInput ${regExpr} />`;\n case \"string-date\":\n return `<SQLDateInput ${regExpr} />`;\n case \"number-id\":\n return `<input type=\"hidden\" ${regExpr} />`;\n case \"number-plain\":\n return `<NumberInput placeholder=\"${col.label}\" ${regExpr} />`;\n case \"boolean\":\n return `<BooleanToggle ${regExpr} />`;\n case \"string-image\":\n return `<ImageUploader multiple={false} ${regExpr} />`;\n case \"array-images\":\n return `<ImageUploader multiple={true} ${regExpr} maxSize={5} />`;\n case \"enums\":\n try {\n let enumId: string;\n if (col.name === \"orderBy\") {\n enumId = `${names.capital}${inflection.camelize(col.name)}Select`;\n } else {\n const { id } = getEnumInfoFromColName(entityId, col.name);\n enumId = `${id}Select`;\n }\n return `<${enumId} ${regExpr} ${\n col.optional || col.nullable ? \"clearable\" : \"\"\n } textPrefix=\"\" />`;\n } catch {\n return `<>찾을 수 없는 Enum ${col.name}</>`;\n }\n case \"number-fk_id\":\n try {\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n const fkId = `${relProp.with}IdAsyncSelect`;\n return `<${fkId} {...register('${col.name}')} ${\n col.optional || col.nullable ? \"clearable\" : \"\"\n } subset=\"A\" />`;\n } catch {\n return `<Input ${regExpr} />`;\n }\n case \"array\":\n return `<>${col.name} array</>`;\n case \"object\":\n return `<>${col.name} object</>`;\n default:\n throw new Error(\n `대응 불가능한 렌더 타입 ${col.renderType} on ${col.name}`\n );\n }\n }\n\n resolveDefaultValue(columns: RenderingNode[]): object {\n return columns.reduce(\n (result, col) => {\n if (col.optional) {\n return result;\n }\n\n let value: unknown;\n if (col.nullable === true) {\n value = null;\n } else if (col.zodType instanceof z.ZodNumber) {\n value = 0;\n } else if (col.zodType instanceof z.ZodEnum) {\n value = Object.keys(col.zodType.Enum)[0];\n } else if (col.zodType instanceof z.ZodBoolean) {\n value = false;\n } else if (col.zodType instanceof z.ZodString) {\n if (col.renderType === \"string-datetime\") {\n value = \"now()\";\n } else {\n value = \"\";\n }\n } else if (col.zodType instanceof z.ZodArray) {\n value = [];\n } else if (col.zodType instanceof z.ZodObject) {\n value = {};\n }\n\n result[col.name] = value;\n return result;\n },\n {} as { [key: string]: unknown }\n );\n }\n\n render(\n { entityId }: TemplateOptions[\"view_form\"],\n saveParamsNode: RenderingNode\n ) {\n const entity = EntityManager.get(entityId);\n const names = EntityManager.getNamesFromId(entityId);\n const columns = (saveParamsNode.children as RenderingNode[])\n .filter((col) => col.name !== \"id\")\n .map((col) => {\n const propCandidate = entity.props.find(\n (prop) => prop.name === col.name\n );\n col.label = propCandidate?.desc ?? col.label;\n return col;\n });\n\n const defaultValue = this.resolveDefaultValue(columns);\n\n // 프리 템플릿\n const preTemplates: RenderedTemplate[\"preTemplates\"] = (\n columns as RenderingNode[]\n )\n .filter((col) => {\n if (col.name === \"id\") {\n return false;\n } else if (col.name.endsWith(\"_id\") || col.renderType === \"number-id\") {\n try {\n getRelationPropFromColName(entityId, col.name.replace(\"_id\", \"\"));\n return true;\n } catch {\n return false;\n }\n } else if (col.renderType === \"enums\") {\n try {\n getEnumInfoFromColName(entityId, col.name);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n })\n .map((col) => {\n let key: TemplateKey;\n let targetMdId = entityId;\n let enumId: string | undefined;\n if (col.renderType === \"enums\") {\n key = \"view_enums_select\";\n const { targetEntityNames: targetMDNames, id } =\n getEnumInfoFromColName(entityId, col.name);\n targetMdId = targetMDNames.capital;\n enumId = id;\n } else {\n key = \"view_id_async_select\";\n const relProp = getRelationPropFromColName(\n entityId,\n col.name.replace(\"_id\", \"\")\n );\n targetMdId = relProp.with;\n }\n\n return {\n key: key as TemplateKey,\n options: {\n entityId: targetMdId,\n node: col,\n enumId,\n },\n };\n })\n .filter((preTemplate) => {\n if (preTemplate.key === \"view_id_async_select\") {\n try {\n EntityManager.get(preTemplate.options.entityId);\n return true;\n } catch {\n return false;\n }\n }\n return true;\n });\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport React, { useEffect, useState, Dispatch, SetStateAction, forwardRef, Ref, useImperativeHandle, useCallback } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n Button,\n Checkbox,\n Form,\n Header,\n Input,\n Segment,\n TextArea,\n Label,\n} from 'semantic-ui-react';\nimport { DateTime } from \"luxon\";\n\nimport { BackLink, LinkInput, NumberInput, BooleanToggle, SQLDateTimeInput, SQLDateInput, useTypeForm, useGoBack } from \"@sonamu-kit/react-sui\";\nimport { defaultCatch } from 'src/services/sonamu.shared';\nimport { ImageUploader } from 'src/admin-common/ImageUploader';\nimport { useCommonModal } from \"src/admin-common/CommonModal\";\n\nimport { ${names.capital}SaveParams } from 'src/services/${names.fs}/${\n names.fs\n }.types';\nimport { ${names.capital}Service } from 'src/services/${names.fs}/${\n names.fs\n }.service';\nimport { ${names.capital}SubsetA } from 'src/services/sonamu.generated';\n${_.uniq(\n columns\n .filter((col) => [\"number-fk_id\", \"enums\"].includes(col.renderType))\n .map((col) => {\n return this.renderColumnImport(entityId, col);\n })\n).join(\"\\n\")}\n\nexport default function ${names.capitalPlural}FormPage() {\n // 라우팅 searchParams\n const [searchParams] = useSearchParams();\n const query = {\n id: searchParams.get('id') ?? undefined,\n };\n\n return <${\n names.capitalPlural\n }Form id={query?.id ? Number(query.id) : undefined} />;\n}\ntype ${names.capitalPlural}FormProps = {\n id?: number;\n mode?: 'page' | 'modal';\n};\nexport function ${names.capitalPlural}Form({ id, mode }: ${\n names.capitalPlural\n }FormProps) {\n // 편집시 기존 row\n const [row, setRow] = useState<${names.capital}SubsetA | undefined>();\n\n // ${names.capital}SaveParams 폼\n const { form, setForm, register } = useTypeForm(${\n names.capital\n }SaveParams, ${JSON.stringify(defaultValue).replace(\n /\"now\\(\\)\"/g,\n \"DateTime.local().toSQL()!.slice(0, 19)\"\n )});\n\n // 수정일 때 기존 row 콜\n useEffect(() => {\n if (id) {\n ${names.capital}Service.get${names.capital}('A', id).then((row) => {\n setRow(row);\n setForm({\n ...row,\n ${columns\n .filter((col) => col.renderType === \"number-fk_id\")\n .map((col) => {\n if (col.nullable) {\n return `${col.name}: row.${col.name.replace(\n \"_id\",\n \"?.id\"\n )} ?? null`;\n } else {\n return `${col.name}: row.${col.name.replace(\"_id\", \".id\")}`;\n }\n })\n .join(\",\\n\")}\n });\n });\n }\n }, [id]);\n\n // CommonModal\n const { doneModal, closeModal } = useCommonModal();\n\n // 저장\n const { goBack } = useGoBack();\n const handleSubmit = useCallback(() => {\n ${names.capital}Service.save([form]).then(([id]) => {\n if( mode === 'modal' ) {\n doneModal();\n } else {\n goBack('/admin/${names.fsPlural}');\n }\n }).catch(defaultCatch);\n }, [ form, mode, id ]);\n\n // 페이지\n const PAGE = {\n title: \\`${\n entity.title ?? names.capital\n }\\${id ? \\`#\\${id} 수정\\` : ' 등록'}\\`,\n }\n\n return (\n <div className=\"form\">\n <Segment padded basic>\n <Segment padded color=\"grey\">\n <div className=\"header-row\">\n <Header>\n {PAGE.title}\n </Header>\n { mode !== 'modal' && <div className=\"buttons\">\n <BackLink primary size=\"tiny\" to=\"/admin/${\n names.fsPlural\n }\" content=\"목록\" icon=\"list\" />\n </div>}\n </div>\n <Form>\n ${columns\n .map((col) => {\n if (col.name === \"created_at\") {\n return `{form.id && (${this.wrapFG(\n `<div className=\"p-8px\">{form.${col.name}}</div>`,\n \"등록일시\"\n )})}`;\n } else {\n return this.wrapFG(\n this.renderColumn(entityId, col, names),\n (() => {\n if (col.label.endsWith(\"Id\")) {\n try {\n const entity = EntityManager.get(\n col.label.replace(\"Id\", \"\")\n );\n return entity.title ?? col.label;\n } catch {\n return col.label;\n }\n }\n return col.label;\n })()\n );\n }\n })\n .join(\"\\n\")}\n <Segment basic textAlign=\"center\">\n <Button type=\"submit\" primary onClick={handleSubmit} content=\"저장\" icon=\"save\" />\n </Segment>\n </Form>\n </Segment>\n </Segment>\n </div>\n );\n};\n `.trim(),\n importKeys: [],\n preTemplates,\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_id_all_select extends Template {\n constructor() {\n super(\"view_id_all_select\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${names.capital}IdAllSelect.tsx`,\n };\n }\n\n render({ entityId }: TemplateOptions[\"view_id_all_select\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n return {\n ...this.getTargetAndPath(names),\n body: `\n/*\nview_id_all_select\n${JSON.stringify({\n key: this.key,\n options: entityId,\n})}\n*/\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_id_async_select extends Template {\n constructor() {\n super(\"view_id_async_select\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${names.capital}IdAsyncSelect.tsx`,\n };\n }\n\n render({ entityId, textField }: TemplateOptions[\"view_id_async_select\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n const entity = EntityManager.get(entityId);\n if (!textField) {\n const pickedProp = entity.props.find((prop) =>\n [\"name\", \"title\"].includes(prop.name)\n );\n if (pickedProp) {\n textField = pickedProp.name;\n } else {\n const candidateProp = entity.props.find(\n (prop) => prop.type === \"string\"\n );\n if (candidateProp) {\n textField = candidateProp.name;\n } else {\n console.log(\"textField 찾을 수 없음\");\n }\n }\n }\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport React, { useState, useEffect, SyntheticEvent } from \"react\";\nimport { DropdownProps, DropdownItemProps, DropdownOnSearchChangeData, Dropdown } from \"semantic-ui-react\";\nimport { ${names.capital}SubsetKey, ${\n names.capital\n }SubsetMapping } from \"src/services/sonamu.generated\";\nimport { ${names.capital}Service } from \"src/services/${names.fs}/${\n names.fs\n }.service\";\nimport { ${names.capital}ListParams } from \"src/services/${names.fs}/${\n names.fs\n }.types\";\n\nexport function ${names.capital}IdAsyncSelect<T extends ${\n names.capital\n }SubsetKey>(\n { subset, baseListParams, textField, valueField, ...props }: DropdownProps & {\n subset: T;\n baseListParams?: ${names.capital}ListParams;\n textField${textField ? \"?\" : \"\"}: keyof ${names.capital}SubsetMapping[T];\n valueField?: keyof ${names.capital}SubsetMapping[T];\n },\n) {\n const [options, setOptions] = useState<DropdownItemProps[]>([]);\n const [listParams, setListParams] = useState<${names.capital}ListParams>(\n baseListParams ?? {},\n );\n\n const { data, error } = ${names.capital}Service.use${\n names.capitalPlural\n }(subset, listParams);\n const { rows: ${names.camelPlural}, total } = data ?? {};\n\n useEffect(() => {\n setOptions(\n (${names.camelPlural} ?? []).map((${names.camel}) => {\n return {\n key: ${names.camel}.id,\n value: ${names.camel}[valueField ?? 'id'] as string | number,\n text: String(${names.camel}[textField${\n textField ? ` ?? '${textField}'` : \"\"\n }]),\n };\n }),\n );\n }, [${names.camelPlural}]);\n\n useEffect(() => {\n setListParams({\n ...listParams,\n ...baseListParams,\n });\n }, [baseListParams]);\n\n const handleSearchChange = (\n e: SyntheticEvent<HTMLElement, Event>,\n data: DropdownOnSearchChangeData,\n ) => {\n setListParams({\n ...listParams,\n keyword: data.searchQuery,\n });\n };\n\n return (\n <Dropdown\n placeholder=\"${entity.title ?? names.constant}\"\n selection\n options={options}\n onSearchChange={handleSearchChange}\n disabled={!${names.camelPlural}}\n loading={!${names.camelPlural}}\n selectOnBlur={false}\n {...props}\n />\n );\n}\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport inflection from \"inflection\";\n\nexport class Template__view_enums_dropdown extends Template {\n constructor() {\n super(\"view_enums_dropdown\");\n }\n\n getTargetAndPath(names: EntityNamesRecord, enumId: string) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${enumId}Dropdown.tsx`,\n };\n }\n\n render({ entityId, enumId }: TemplateOptions[\"view_enums_dropdown\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n const label = getLabel(entityId, enumId);\n\n return {\n ...this.getTargetAndPath(names, enumId),\n body: `\nimport React from 'react';\nimport {\n Dropdown,\n DropdownProps,\n} from 'semantic-ui-react';\n\nimport { ${enumId}Label } from 'src/services/sonamu.generated';\n\nexport function ${enumId}Dropdown(props: DropdownProps) {\n const options = Object.entries(${enumId}Label).map(([key, label]) => {\n return {\n key,\n value: key,\n text: \"${label}: \" + label,\n };\n });\n return (\n <Dropdown\n className=\"label\"\n options={options}\n {...props}\n />\n );\n}\n `.trim(),\n importKeys: [],\n };\n }\n}\n\nexport function getLabel(entityId: string, enumId: string): string {\n if (enumId.endsWith(\"OrderBy\")) {\n return \"정렬\";\n } else if (enumId.endsWith(\"SearchField\")) {\n return \"검색\";\n } else {\n const enumProp = EntityManager.get(entityId).props.find(\n (prop) => `${entityId}${inflection.camelize(prop.name)}` === enumId\n );\n if (enumProp && enumProp.desc) {\n return enumProp.desc;\n }\n return enumId;\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { getLabel } from \"./view_enums_dropdown.template\";\n\nexport class Template__view_enums_select extends Template {\n constructor() {\n super(\"view_enums_select\");\n }\n\n getTargetAndPath(names: EntityNamesRecord, enumId: string) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${enumId}Select.tsx`,\n };\n }\n\n render({ entityId, enumId }: TemplateOptions[\"view_enums_select\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n const label = getLabel(entityId, enumId);\n\n return {\n ...this.getTargetAndPath(names, enumId),\n body: `\nimport React from 'react';\nimport {\n Dropdown,\n DropdownProps,\n} from 'semantic-ui-react';\n\nimport { ${enumId}, ${enumId}Label } from 'src/services/sonamu.generated';\n\nexport type ${enumId}SelectProps = {\n placeholder?: string;\n textPrefix?: string;\n} & DropdownProps;\nexport function ${enumId}Select({placeholder, textPrefix, ...props}: ${enumId}SelectProps) {\n const typeOptions = ${enumId}.options.map((key) => ({\n key,\n value: key,\n text: (textPrefix ?? '${label}: ') + ${enumId}Label[key],\n }));\n\n return (\n <Dropdown\n placeholder={placeholder ?? \"${label}\"}\n selection\n options={typeOptions}\n selectOnBlur={false}\n {...props}\n />\n );\n}\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_enums_buttonset extends Template {\n constructor() {\n super(\"view_enums_buttonset\");\n }\n\n getTargetAndPath(names: EntityNamesRecord, componentId: string) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${componentId}ButtonSet.tsx`,\n };\n }\n\n render({ entityId, enumId }: TemplateOptions[\"view_enums_buttonset\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n return {\n ...this.getTargetAndPath(names, enumId),\n body: `\n/*\nview_enums_buttonset\n${JSON.stringify({\n key: this.key,\n options: entityId,\n})}\n*/\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_search_input extends Template {\n constructor() {\n super(\"view_search_input\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/components\",\n path: `${names.fs}/${names.capital}SearchInput.tsx`,\n };\n }\n\n render({ entityId }: TemplateOptions[\"view_search_input\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport React from \"react\";\nimport { useState } from \"react\";\nimport { DropdownProps, Input, InputProps } from \"semantic-ui-react\";\nimport { ${names.capital}SearchFieldDropdown } from \"src/components/${names.fs}/${names.capital}SearchFieldDropdown\";\n\nexport function ${names.capital}SearchInput({\n input: { value: inputValue, onChange: inputOnChange, ...inputProps },\n dropdown: dropdownProps,\n}: {\n input: InputProps;\n dropdown: DropdownProps;\n}) {\n const [keyword, setKeyword] = useState<string>(inputValue ?? '');\n\n const handleKeyDown = (e: { key: string }) => {\n if (inputOnChange && e.key === 'Enter') {\n inputOnChange(e as any, {\n value: keyword,\n });\n }\n };\n\n return (\n <Input\n size=\"small\"\n placeholder=\"검색...\"\n style={{ margin: 0 }}\n label={<${names.capital}SearchFieldDropdown {...dropdownProps} />}\n labelPosition=\"left\"\n action={{\n icon: 'search',\n onClick: () => handleKeyDown({ key: 'Enter' }),\n }}\n {...inputProps}\n value={keyword}\n onChange={(e, { value }) => setKeyword(value)}\n onKeyDown={handleKeyDown}\n />\n );\n}\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import { TemplateOptions } from \"../types/types\";\nimport { EntityManager, EntityNamesRecord } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\n\nexport class Template__view_list_columns extends Template {\n constructor() {\n super(\"view_list_columns\");\n }\n\n getTargetAndPath(names: EntityNamesRecord) {\n return {\n target: \"web/src/pages/admin\",\n path: `${names.fsPlural}/_columns.tsx`,\n };\n }\n\n // 컬럼\n render({\n entityId,\n columns,\n columnImports,\n }: TemplateOptions[\"view_list_columns\"]) {\n const names = EntityManager.getNamesFromId(entityId);\n\n return {\n ...this.getTargetAndPath(names),\n body: `\nimport React from 'react';\nimport {\n Segment,\n Table,\n TableRow,\n Button,\n Label,\n} from 'semantic-ui-react';\nimport { DateTime } from \"luxon\";\nimport { TFColumn } from \"src/typeframe/iso-types\";\nimport { ${names.capital}SubsetA } from \"src/services/${names.fs}/${\n names.fs\n }.generated\";\n${columnImports}\n\nconst columns: { [key in Exclude<keyof ${\n names.capital\n }SubsetA, 'id'>]: TFColumn<${names.capital}SubsetA> } = {${columns\n .map((col) => {\n return [\n `${col.name}: { label: \"${col.label}\",`,\n `tc: ${col.tc}, `,\n `collapsing: ${[\"Title\", \"Name\"].includes(col.label) === false}, }`,\n ].join(\"\\n\");\n })\n .join(\",\\n\")}};\nexport default columns;\n `.trim(),\n importKeys: [],\n };\n }\n}\n","import qs from \"qs\";\nimport { z } from \"zod\";\nimport { TemplateOptions } from \"../types/types\";\nimport { getZodObjectFromApi } from \"../api/code-converters\";\nimport { ExtendedApi } from \"../api/decorators\";\nimport { Template } from \"./base-template\";\nimport prettier from \"prettier\";\nimport { Sonamu } from \"../api/sonamu\";\n\nexport class Template__generated_http extends Template {\n constructor() {\n super(\"generated_http\");\n }\n\n getTargetAndPath() {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `sonamu.generated.http`,\n };\n }\n\n async render({}: TemplateOptions[\"generated_http\"]) {\n const {\n syncer: { types, apis },\n config: {\n route: { prefix },\n },\n } = Sonamu;\n\n const lines = await Promise.all(\n apis.map(async (api) => {\n const reqObject = this.resolveApiParams(api, types);\n\n const dataLines = await (async () => {\n if ((api.options.httpMethod ?? \"GET\") === \"GET\") {\n return {\n querystring: [\n qs\n .stringify(reqObject, { encode: false })\n .split(\"&\")\n .join(\"\\n\\t&\"),\n ],\n body: [],\n };\n } else {\n return {\n querystring: [],\n body: [\n \"\",\n await prettier.format(JSON.stringify(reqObject), {\n parser: \"json\",\n }),\n ],\n };\n }\n })();\n\n return [\n [\n `${api.options.httpMethod ?? \"GET\"} {{baseUrl}}${prefix}${api.path}`,\n ...dataLines.querystring,\n ].join(\"\\n\\t?\"),\n `Content-Type: ${api.options.contentType ?? \"application/json\"}`,\n ...dataLines.body,\n ].join(\"\\n\");\n })\n );\n\n return {\n ...this.getTargetAndPath(),\n body: lines.join(\"\\n\\n###\\n\\n\"),\n importKeys: [],\n };\n }\n\n zodTypeToReqDefault(zodType: z.ZodType<unknown>, name: string): unknown {\n if (zodType instanceof z.ZodObject) {\n return Object.fromEntries(\n Object.keys(zodType.shape).map((key) => [\n key,\n this.zodTypeToReqDefault(zodType.shape[key], key),\n ])\n );\n } else if (zodType instanceof z.ZodArray) {\n return [this.zodTypeToReqDefault(zodType.element, name)];\n } else if (zodType instanceof z.ZodString) {\n if (name.endsWith(\"_at\") || name.endsWith(\"_date\") || name === \"range\") {\n return \"2000-01-01\";\n } else {\n return name.toUpperCase();\n }\n } else if (zodType instanceof z.ZodNumber) {\n if (name === \"num\") {\n return 24;\n }\n return zodType.minValue ?? 0;\n } else if (zodType instanceof z.ZodBoolean) {\n return false;\n } else if (zodType instanceof z.ZodEnum) {\n return zodType.options[0];\n } else if (zodType instanceof z.ZodOptional) {\n return this.zodTypeToReqDefault(zodType._def.innerType, name);\n } else if (zodType instanceof z.ZodNullable) {\n return null;\n } else if (zodType instanceof z.ZodUnion) {\n return this.zodTypeToReqDefault(zodType._def.options[0], name);\n } else if (zodType instanceof z.ZodUnknown) {\n return \"unknown\";\n } else if (zodType instanceof z.ZodTuple) {\n return zodType._def.items.map((item: any) =>\n this.zodTypeToReqDefault(item, name)\n );\n } else if (zodType instanceof z.ZodDate) {\n return \"2000-01-01\";\n } else if (zodType instanceof z.ZodLiteral) {\n return zodType.value;\n } else if (zodType instanceof z.ZodEffects) {\n return this.zodTypeToReqDefault(zodType._def.schema, name);\n } else if (zodType instanceof z.ZodRecord || zodType instanceof z.ZodMap) {\n const key = this.zodTypeToReqDefault(zodType._def.keyType, name) as any;\n const value = this.zodTypeToReqDefault(zodType._def.valueType, name);\n return { [key]: value };\n } else if (zodType instanceof z.ZodSet) {\n return [this.zodTypeToReqDefault(zodType._def.valueType, name)];\n } else if (zodType instanceof z.ZodIntersection) {\n return this.zodTypeToReqDefault(zodType._def.right, name);\n } else {\n // console.log(zodType);\n return `unknown-${zodType._type}`;\n }\n }\n\n resolveApiParams(\n api: ExtendedApi,\n references: { [typeName: string]: z.ZodObject<any> }\n ): { [key: string]: unknown } {\n const reqType = getZodObjectFromApi(api, references);\n return this.zodTypeToReqDefault(reqType, \"unknownName\") as {\n [key: string]: unknown;\n };\n }\n}\n","import { SubsetQuery, TemplateOptions } from \"../types/types\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport inflection from \"inflection\";\nimport { SourceCode } from \"./generated.template\";\nimport _ from \"lodash\";\nimport { nonNullable } from \"../utils/utils\";\nimport { Sonamu } from \"../api\";\n\nexport class Template__generated_sso extends Template {\n constructor() {\n super(\"generated_sso\");\n }\n\n getTargetAndPath() {\n const { dir } = Sonamu.config.api;\n\n return {\n target: `${dir}/src/application`,\n path: `sonamu.generated.sso.ts`,\n };\n }\n\n render({}: TemplateOptions[\"generated_sso\"]) {\n const entityIds = EntityManager.getAllIds();\n const entities = entityIds.map((id) => EntityManager.get(id));\n\n const sourceCodes: SourceCode[] = entities\n .map((entity) => {\n if (\n entity.parentId !== undefined ||\n Object.keys(entity.subsets).length === 0\n ) {\n return null;\n }\n const subsetKeys = Object.keys(entity.subsets);\n const subsetQueryObject = subsetKeys.reduce(\n (r, subsetKey) => {\n const subsetQuery = entity.getSubsetQuery(subsetKey);\n r[subsetKey] = subsetQuery;\n return r;\n },\n {} as {\n [key: string]: SubsetQuery;\n }\n );\n\n const subsetKeyTypeName = `${entity.names.module}SubsetKey`;\n return {\n label: `SubsetQuery: ${entity.id}`,\n lines: [\n `export const ${inflection.camelize(\n entity.id,\n true\n )}SubsetQueries:{ [key in ${subsetKeyTypeName}]: SubsetQuery} = ${JSON.stringify(\n subsetQueryObject\n )};`,\n \"\",\n ],\n importKeys: [subsetKeyTypeName],\n };\n })\n .filter(nonNullable);\n\n const sourceCode = sourceCodes.reduce(\n (result, ts) => {\n if (ts === null) {\n return result;\n }\n return {\n lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, \"\"],\n importKeys: _.uniq([...result!.importKeys, ...ts.importKeys]),\n };\n },\n {\n lines: [],\n importKeys: [],\n } as Omit<SourceCode, \"label\">\n );\n\n return {\n ...this.getTargetAndPath(),\n body: sourceCode.lines.join(\"\\n\"),\n importKeys: sourceCode.importKeys,\n customHeaders: [`import { SubsetQuery } from \"sonamu\";`],\n };\n }\n}\n","import {\n EntityProp,\n isBelongsToOneRelationProp,\n isBigIntegerProp,\n isBooleanProp,\n isDateProp,\n isDateTimeProp,\n isDecimalProp,\n isDoubleProp,\n isEnumProp,\n isFloatProp,\n isIntegerProp,\n isJsonProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isTimeProp,\n isTimestampProp,\n isUuidProp,\n isVirtualProp,\n} from \"../types/types\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Template } from \"./base-template\";\nimport { SourceCode } from \"./generated.template\";\nimport _ from \"lodash\";\nimport { nonNullable } from \"../utils/utils\";\nimport { Sonamu } from \"../api\";\nimport { Entity } from \"../entity/entity\";\nimport inflection from \"inflection\";\nimport { DB } from \"../database/db\";\nimport { KyselyBaseConfig } from \"../database/types\";\n\nexport class Template__kysely_interface extends Template {\n constructor() {\n super(\"kysely_interface\");\n }\n\n getTargetAndPath() {\n const { dir } = Sonamu.config.api;\n const { types } = DB.baseConfig as KyselyBaseConfig;\n const outDir = types?.outDir ?? \"src/typings\";\n const fileName = types?.fileName ?? \"database.types.ts\";\n\n return {\n target: `${dir}/${outDir}`,\n path: fileName,\n };\n }\n\n render() {\n const entityIds = EntityManager.getAllIds();\n const entities = entityIds.map((id) => EntityManager.get(id));\n const enums = _.merge({}, ...entities.map((e) => e.enums));\n\n const manyToManyTables = _.uniq(\n entities.flatMap((e) =>\n e.props\n .map((p) => {\n if (isRelationProp(p) && p.relationType === \"ManyToMany\") {\n return p.joinTable;\n }\n return null;\n })\n .filter(nonNullable)\n )\n ).map((table) => {\n const [fromTable, toTable] = table.split(\"__\");\n return {\n table,\n fromTable,\n toTable,\n interfaceName: `${inflection.classify(fromTable)}${inflection.classify(toTable)}Table`,\n };\n });\n\n const sourceCodes: Omit<SourceCode, \"label\">[] = entities.map((entity) => {\n const columns = entity.props.map((prop) =>\n this.resolveColumn(prop, enums)\n );\n\n return {\n lines: [\n `interface ${entity.id}Table {\n ${columns.join(\"\\n\")}\n }`,\n \"\",\n ],\n importKeys: [],\n };\n });\n\n sourceCodes.push(\n ...manyToManyTables.map(({ fromTable, toTable, interfaceName }) => {\n return {\n lines: [\n `interface ${interfaceName} {\n id: number;\n ${inflection.singularize(fromTable)}_id: number;\n ${inflection.singularize(toTable)}_id: number;\n }`,\n \"\",\n ],\n importKeys: [],\n };\n })\n );\n\n const sourceCode = sourceCodes.reduce(\n (result, ts) => {\n if (ts === null) {\n return result;\n }\n return {\n lines: [...result!.lines, ...ts.lines, \"\"],\n importKeys: _.uniq([...result!.importKeys, ...ts.importKeys]),\n };\n },\n {\n lines: [],\n importKeys: [],\n } as Omit<SourceCode, \"label\">\n );\n\n return {\n ...this.getTargetAndPath(),\n body: sourceCode.lines.join(\"\\n\"),\n importKeys: sourceCode.importKeys,\n customHeaders: [\n `import { Generated, ColumnType } from \"kysely\";`,\n \"\",\n `export interface KyselyDatabase {\n ${entities.map((entity) => `${entity.table}: ${entity.id}Table`).join(\",\\n\")}\n ${manyToManyTables.map(({ table, interfaceName }) => `${table}: ${interfaceName}`).join(\",\\n\")}\n }`,\n \"\",\n `declare module \"sonamu\" {\n export interface DatabaseExtend extends KyselyDatabase {}\n }`,\n ],\n };\n }\n\n private resolveColumn(prop: EntityProp, enums: Entity[\"enums\"]) {\n if (isVirtualProp(prop)) {\n return null;\n }\n\n if (prop.name === \"id\") {\n return \"id: Generated<number>\";\n }\n\n if (isRelationProp(prop)) {\n if (isBelongsToOneRelationProp(prop)) {\n return `${prop.name}_id: ${prop.nullable ? \"number | null\" : \"number\"}`;\n }\n return null;\n }\n\n let type: string;\n\n if (isIntegerProp(prop)) {\n type = \"number\";\n } else if (isBigIntegerProp(prop)) {\n type = \"string\";\n } else if (isStringProp(prop) || isTextProp(prop)) {\n type = \"string\";\n } else if (isEnumProp(prop)) {\n const enumValues = enums[prop.id];\n if (!enumValues) {\n console.warn(`Enum values not found for ${prop.id}`);\n return null;\n }\n type = Object.keys(enumValues.Values)\n .map((e) => `\"${e}\"`)\n .join(\" | \");\n } else if (isFloatProp(prop) || isDoubleProp(prop) || isDecimalProp(prop)) {\n type = \"number\";\n } else if (isBooleanProp(prop)) {\n type = \"boolean\";\n } else if (\n isDateProp(prop) ||\n isDateTimeProp(prop) ||\n isTimeProp(prop) ||\n isTimestampProp(prop)\n ) {\n type = \"string\";\n } else if (isJsonProp(prop)) {\n type = \"string\";\n } else if (isUuidProp(prop)) {\n type = \"string\";\n } else {\n console.warn(`Unknown prop type: ${(prop as any).type}`);\n type = \"unknown\";\n }\n\n if (prop.nullable) {\n type = `${type} | null`;\n }\n if (prop.dbDefault) {\n type = `ColumnType<${type}, ${type} | undefined, ${type}>`;\n }\n\n return `${prop.name}: ${type};`;\n }\n}\n","export function isLocal(): boolean {\n return process.env.LR === undefined || process.env.LR === \"local\";\n}\nexport function isRemote(): boolean {\n return process.env.LR === \"remote\";\n}\nexport function isInDocker(): boolean {\n return process.env.LR !== undefined;\n}\nexport function isDaemonServer(): boolean {\n return process.env.NODE_TYPE === \"daemon\";\n}\nexport function isDevelopment(): boolean {\n return isRemote() && process.env.NODE_ENV === \"development\";\n}\nexport function isStaging(): boolean {\n return isRemote() && process.env.NODE_ENV === \"staging\";\n}\nexport function isProduction(): boolean {\n return isRemote() && process.env.NODE_ENV === \"production\";\n}\nexport function isTest(): boolean {\n return isLocal() && process.env.NODE_ENV === \"test\";\n}\n","import { z } from \"zod\";\n\ntype ValidationError = {\n path: string[];\n message: string;\n};\n\nexport function humanizeZodError(error: z.ZodError): ValidationError[] {\n return error.issues.map((issue) => {\n const pathAsStrings = issue.path.map(String);\n const path = issue.path.reduce((acc, cur, i) => {\n if (typeof cur === \"number\") {\n return `${acc}[${cur}]`;\n }\n return i === 0 ? cur : `${acc}.${cur}`;\n }, \"\");\n\n switch (issue.code) {\n case z.ZodIssueCode.invalid_type:\n return {\n path: pathAsStrings,\n message: `${path} should be a ${issue.expected}, received ${issue.received}.`,\n };\n\n case z.ZodIssueCode.unrecognized_keys:\n return {\n path: pathAsStrings,\n message: `Unrecognized keys in ${path}: ${issue.keys.join(\", \")}.`,\n };\n\n case z.ZodIssueCode.invalid_union:\n return {\n path: pathAsStrings,\n message: `${path} failed union validation. Inner errors: ${issue.unionErrors\n .map((e) => e.issues.map((i) => i.message).join(\"; \"))\n .join(\" OR \")}.`,\n };\n\n case z.ZodIssueCode.invalid_enum_value:\n return {\n path: pathAsStrings,\n message: `${path} must be one of: ${issue.options.join(\", \")}.`,\n };\n\n case z.ZodIssueCode.invalid_arguments:\n return {\n path: pathAsStrings,\n message: `Invalid function arguments: ${issue.argumentsError.issues\n .map((i) => i.message)\n .join(\"; \")}.`,\n };\n\n case z.ZodIssueCode.invalid_return_type:\n return {\n path: pathAsStrings,\n message: `Invalid function return type: ${issue.returnTypeError.issues\n .map((i) => i.message)\n .join(\"; \")}.`,\n };\n\n case z.ZodIssueCode.invalid_date:\n return {\n path: pathAsStrings,\n message: `${path} must be a valid date.`,\n };\n\n case z.ZodIssueCode.invalid_string:\n const validationType = issue.validation;\n return {\n path: pathAsStrings,\n message: `${path} must be a valid ${validationType}.`,\n };\n\n case z.ZodIssueCode.too_small:\n return {\n path: pathAsStrings,\n message: `${path} ${getMinimumMessage(issue)}.`,\n };\n\n case z.ZodIssueCode.too_big:\n return {\n path: pathAsStrings,\n message: `${path} ${getMaximumMessage(issue)}`,\n };\n\n case z.ZodIssueCode.not_multiple_of:\n return {\n path: pathAsStrings,\n message: `${path} must be a multiple of ${issue.multipleOf.toString()}.`,\n };\n\n case z.ZodIssueCode.custom:\n return {\n path: pathAsStrings,\n message: issue.message || `${path} failed custom validation.`,\n };\n\n default:\n return {\n path: pathAsStrings,\n message: issue.message,\n };\n }\n });\n}\n\nfunction getMinimumMessage(\n issue: z.ZodIssue & { code: typeof z.ZodIssueCode.too_small }\n) {\n switch (issue.type) {\n case \"string\":\n return `must be ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at least\" : \"more than\"\n } ${issue.minimum} character${issue.minimum === 1 ? \"\" : \"s\"}`;\n\n case \"number\":\n return `must be ${\n issue.exact\n ? \"exactly\"\n : issue.inclusive\n ? \"greater than or equal to\"\n : \"greater than\"\n } ${issue.minimum.toString()}`;\n\n case \"array\":\n case \"set\":\n return `must contain ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at least\" : \"more than\"\n } ${issue.minimum} item${issue.minimum === 1 ? \"\" : \"s\"}`;\n\n case \"date\":\n return `must be ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at or after\" : \"after\"\n } ${formatDateConstraint(issue.minimum)}`;\n\n default:\n return \"is too small\";\n }\n}\n\nfunction getMaximumMessage(\n issue: z.ZodIssue & { code: typeof z.ZodIssueCode.too_big }\n) {\n switch (issue.type) {\n case \"string\":\n return `must be ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at most\" : \"less than\"\n } ${issue.maximum} character${issue.maximum === 1 ? \"\" : \"s\"}`;\n\n case \"number\":\n return `must be ${\n issue.exact\n ? \"exactly\"\n : issue.inclusive\n ? \"less than or equal to\"\n : \"less than\"\n } ${issue.maximum.toString()}`;\n\n case \"array\":\n case \"set\":\n return `must contain ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at most\" : \"fewer than\"\n } ${issue.maximum} item${issue.maximum === 1 ? \"\" : \"s\"}`;\n\n case \"date\":\n return `must be ${\n issue.exact ? \"exactly\" : issue.inclusive ? \"at or before\" : \"before\"\n } ${formatDateConstraint(issue.maximum)}`;\n\n default:\n return \"is too big\";\n }\n}\n\nfunction formatDateConstraint(value: number | bigint): string {\n try {\n if (typeof value === \"bigint\") {\n if (\n value > BigInt(Number.MAX_SAFE_INTEGER) ||\n value < BigInt(Number.MIN_SAFE_INTEGER)\n ) {\n return value.toString();\n }\n }\n return new Date(Number(value)).toISOString();\n } catch {\n return value.toString();\n }\n}\n"]}
|