@jeffjassky/oauth-host 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/models.ts","../src/server/config.ts","../src/server/errors.ts","../src/server/routes/discovery.ts","../src/server/crypto.ts","../src/server/redirect-uris.ts","../src/server/services/tokens.ts","../src/server/protect.ts","../src/server/rate-limit.ts","../src/server/keys.ts","../src/server/services/admin.ts","../src/server/services/cimd.ts","../src/server/services/scopes.ts","../src/server/services/authorize.ts","../src/server/services/consent.ts","../src/server/services/oidc.ts","../src/server/routes/oauth.ts","../src/server/index.ts"],"names":["mongoose","express","randomBytes","createHash","nodeTimingSafeEqual","challenge","createHmac","createPrivateKey","createPublicKey","generateKeyPairSync","assertRedirectUris","sign"],"mappings":";;;;;;;;;;;;AAgCA,IAAM,aAAA,GAAsC;AAAA,EAC1C,MAAA,EAAQ,aAAA;AAAA,EACR,KAAA,EAAO,YAAA;AAAA,EACP,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO,YAAA;AAAA,EACP,OAAA,EAAS,cAAA;AAAA,EACT,GAAA,EAAK,UAAA;AAAA,EACL,KAAA,EAAO;AACT,CAAA;AAEA,SAAS,OAAA,CACP,UAAA,EACA,IAAA,EACA,KAAA,EACA,UAAA,EACU;AACV,EAAA,MAAM,QAAA,GAAW,UAAA,CAAW,MAAA,GAAS,IAAI,CAAA;AACzC,EAAA,IAAI,UAAU,OAAO,QAAA;AAIrB,EAAA,OAAO,UAAA,CAAW,KAAA,CAAM,IAAA,EAAM,KAAA,IAAkB,UAAU,CAAA;AAC5D;AAIA,SAAS,YAAA,GAAuC;AAC9C,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,UAAU,EAAE,IAAA,EAAM,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,MACvD,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA;AAAA;AAAA;AAAA,MAIrC,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,cAAA,EAAgB,QAAQ,CAAA,EAAG,OAAA,EAAS,cAAA,EAAe;AAAA;AAAA;AAAA;AAAA,MAIhF,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,QAAA,EAAU,MAAM,CAAA,EAAG,OAAA,EAAS,QAAA,EAAS;AAAA,MAC1E,WAAA,EAAa,MAAA;AAAA,MACb,iBAAA,EAAmB,IAAA;AAAA,MACnB,YAAA,EAAc,MAAA;AAAA,MACd,OAAA,EAAS,EAAE,IAAA,EAAM,OAAA,EAAS,SAAS,KAAA,EAAM;AAAA;AAAA;AAAA,MAGzC,OAAA,EAAS;AAAA,QACP;AAAA,UACE,GAAA,EAAK,KAAA;AAAA,UACL,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,UACrC,KAAA,EAAO,MAAA;AAAA,UACP,WAAW,EAAE,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,KAAK,GAAA,EAAI;AAAA,UAC3C,UAAA,EAAY,IAAA;AAAA,UACZ,SAAA,EAAW;AAAA;AACb,OACF;AAAA,MACA,YAAA,EAAc,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MAC5C,aAAA,EAAe,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MAC7C,gBAAA,EAAkB,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MAChD,QAAA,EAAU;AAAA,QACR,GAAA,EAAK,KAAA;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAW,MAAA;AAAA,QACX,WAAA,EAAa,MAAA;AAAA,QACb,MAAA,EAAQ,MAAA;AAAA,QACR,UAAA,EAAY;AAAA,OACd;AAAA,MACA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,QAAA,EAAU,UAAU,CAAA,EAAG,OAAA,EAAS,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA,MAIxE,gBAAA,EAAkB,EAAE,IAAA,EAAM,GAAA,EAAK,IAAI,MAAA;AAAO,KAC5C;AAAA,IACA,EAAE,YAAY,IAAA;AAAK,GACrB;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,WAAA,GAAqC;AAC5C,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,MAAA,EAAQ,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA,MAC5D,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA;AAAA;AAAA;AAAA,MAIzC,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACtC,SAAA,EAAW,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACzC,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA,EAAE;AAAA,MACpC,UAAA,EAAY,IAAA;AAAA,MACZ,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACvC,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,QAAQ,CAAA;AAAE,KACzE;AAAA,IACA,EAAE,YAAY,IAAA;AAAK,GACrB;AAMA,EAAA,MAAA,CAAO,KAAA;AAAA,IACL,EAAE,QAAA,EAAU,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,WAAW,CAAA,EAAE;AAAA,IACvC,EAAE,MAAA,EAAQ,IAAA,EAAM,yBAAyB,EAAE,SAAA,EAAW,MAAK;AAAE,GAC/D;AACA,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,MAAA,EAAQ,CAAA,EAAG,CAAA;AAC1B,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,QAAA,EAAU,CAAA,EAAG,CAAA;AAE5B,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,UAAA,GAAmC;AAC1C,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,UAAU,EAAE,IAAA,EAAM,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,MACvD,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA,MAC5D,OAAA,EAAS,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,MAChE,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACtC,SAAA,EAAW,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACzC,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MAC5C,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MAC9C,mBAAA,EAAqB,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,MAAA,EAAO;AAAA,MACrE,KAAA,EAAO,MAAA;AAAA,MACP,QAAA,EAAU,IAAA;AAAA;AAAA;AAAA,MAGV,UAAA,EAAY,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACxC,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,IAAA;AAAK,KAC1C;AAAA,IACA,EAAE,UAAA,EAAY,EAAE,WAAW,IAAA,EAAM,SAAA,EAAW,OAAM;AAAE,GACtD;AAEA,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,SAAA,EAAW,CAAA,IAAK,EAAE,kBAAA,EAAoB,GAAG,CAAA;AACxD,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,WAAA,GAAqC;AAC5C,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,QAAA,EAAU,SAAS,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK;AAAA,MAClE,WAAW,EAAE,IAAA,EAAM,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,MACxD,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA,MAC5D,OAAA,EAAS,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,MAChE,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACtC,QAAA,EAAU,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACxC,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MACzC,QAAA,EAAU,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,IAAA,EAAK;AAAA,MAChE,UAAA,EAAY,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACxC,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACvC,eAAA,EAAiB,IAAA;AAAA,MACjB,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,IAAA;AAAK,KAC1C;AAAA,IACA,EAAE,UAAA,EAAY,EAAE,WAAW,IAAA,EAAM,SAAA,EAAW,OAAM;AAAE,GACtD;AAKA,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,SAAA,EAAW,CAAA,IAAK,EAAE,kBAAA,EAAoB,GAAG,CAAA;AACxD,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,QAAA,EAAU,CAAA,EAAG,CAAA;AAC5B,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,OAAA,EAAS,CAAA,EAAG,CAAA;AAC3B,EAAA,MAAA,CAAO,MAAM,EAAE,MAAA,EAAQ,CAAA,EAAG,QAAA,EAAU,GAAG,CAAA;AAEvC,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,aAAA,GAAyC;AAChD,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,WAAW,EAAE,IAAA,EAAM,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,MACxD,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MACzC,MAAA,EAAQ,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA,MAC5D,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MAC5C,MAAA,EAAQ,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACtC,SAAA,EAAW,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,MACzC,KAAA,EAAO,MAAA;AAAA,MACP,KAAA,EAAO,MAAA;AAAA,MACP,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MAC9C,mBAAA,EAAqB,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,MAAM,CAAA,EAAG,OAAA,EAAS,MAAA,EAAO;AAAA,MACrE,MAAA,EAAQ,MAAA;AAAA,MACR,MAAA,EAAQ,MAAA;AAAA,MACR,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,UAAA,EAAY,QAAQ,CAAA,EAAE;AAAA,MACvD,SAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,IAAA;AAAK,KAC1C;AAAA,IACA,EAAE,UAAA,EAAY,EAAE,WAAW,IAAA,EAAM,SAAA,EAAW,OAAM;AAAE,GACtD;AAEA,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,SAAA,EAAW,CAAA,IAAK,EAAE,kBAAA,EAAoB,GAAG,CAAA;AACxD,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,SAAA,GAAiC;AACxC,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,KAAK,EAAE,IAAA,EAAM,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,MAClD,GAAA,EAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,OAAO,CAAA,EAAG,OAAA,EAAS,OAAA,EAAQ;AAAA,MACvD,SAAA,EAAW,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA;AAAA;AAAA,MAG/D,UAAA,EAAY,EAAE,IAAA,EAAMA,yBAAA,CAAS,OAAO,KAAA,CAAM,KAAA,EAAO,UAAU,IAAA,EAAK;AAAA,MAChE,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,QAAA,EAAU,UAAU,CAAA,EAAG,OAAA,EAAS,QAAA;AAAS,KAC1E;AAAA,IACA,EAAE,UAAA,EAAY,EAAE,WAAW,IAAA,EAAM,SAAA,EAAW,OAAM;AAAE,GACtD;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,YAAY,aAAA,EAA8C;AACjE,EAAA,MAAM,MAAA,GAAS,IAAIA,yBAAA,CAAS,MAAA;AAAA,IAC1B;AAAA,MACE,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,MACrC,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAC,MAAA,EAAQ,QAAA,EAAU,OAAA,EAAS,QAAQ,CAAA,EAAE;AAAA,MACnE,QAAA,EAAU,MAAA;AAAA,MACV,MAAA,EAAQA,yBAAA,CAAS,MAAA,CAAO,KAAA,CAAM,KAAA;AAAA,MAC9B,OAAA,EAASA,yBAAA,CAAS,MAAA,CAAO,KAAA,CAAM,QAAA;AAAA,MAC/B,EAAA,EAAI,MAAA;AAAA,MACJ,IAAA,EAAMA,yBAAA,CAAS,MAAA,CAAO,KAAA,CAAM;AAAA,KAC9B;AAAA,IACA,EAAE,UAAA,EAAY,EAAE,WAAW,IAAA,EAAM,SAAA,EAAW,OAAM;AAAE,GACtD;AAKA,EAAA,MAAA,CAAO,KAAA,CAAM,EAAE,SAAA,EAAW,CAAA,IAAK,EAAE,kBAAA,EAAoB,aAAA,GAAgB,KAAA,EAAQ,CAAA;AAC7E,EAAA,MAAA,CAAO,MAAM,EAAE,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,IAAI,CAAA;AAC3C,EAAA,MAAA,CAAO,MAAM,EAAE,MAAA,EAAQ,CAAA,EAAG,SAAA,EAAW,IAAI,CAAA;AAEzC,EAAA,OAAO,MAAA;AACT;AAWO,SAAS,YAAA,CAAa;AAAA,EAC3B,UAAA,GAAaA,yBAAA;AAAA,EACb,aAAa,EAAC;AAAA,EACd,gBAAA,GAAmB,QAAA;AAAA,EACnB,kBAAA,GAAqB;AACvB,CAAA,GAAyB,EAAC,EAAgB;AACxC,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,aAAA,EAAe,GAAG,UAAA,EAAW;AAChD,EAAA,MAAM,IAAI,CAAC,MAAA,KAAmB,CAAA,EAAG,gBAAgB,GAAG,MAAM,CAAA,CAAA;AAE1D,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,QAAwB,UAAA,EAAY,KAAA,CAAM,QAAQ,YAAA,EAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAAA,IACpF,KAAA,EAAO,QAAuB,UAAA,EAAY,KAAA,CAAM,OAAO,WAAA,EAAa,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,IAC/E,IAAA,EAAM,QAAsB,UAAA,EAAY,KAAA,CAAM,MAAM,UAAA,EAAY,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,IAC1E,KAAA,EAAO,QAAuB,UAAA,EAAY,KAAA,CAAM,OAAO,WAAA,EAAa,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,IAC/E,OAAA,EAAS,QAAyB,UAAA,EAAY,KAAA,CAAM,SAAS,aAAA,EAAe,CAAA,CAAE,UAAU,CAAC,CAAA;AAAA,IACzF,GAAA,EAAK,QAAqB,UAAA,EAAY,KAAA,CAAM,KAAK,SAAA,EAAW,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,IACrE,KAAA,EAAO,OAAA;AAAA,MACL,UAAA;AAAA,MACA,KAAA,CAAM,KAAA;AAAA,MACN,MAAM,YAAY,kBAAkB,CAAA;AAAA,MACpC,EAAE,OAAO;AAAA;AACX,GACF;AACF;AAUA,eAAsB,iBAAiB,MAAA,EAAoC;AACzE,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAC9D;;;ACrRA,IAAM,WAAA,GAAsB;AAAA,EAC1B,KAAA,GAAQ;AAAA,EAAC,CAAA;AAAA,EACT,IAAA,GAAO;AAAA,EAAC,CAAA;AAAA,EACR,IAAA,GAAO;AAAA,EAAC,CAAA;AAAA,EACR,KAAA,GAAQ;AAAA,EAAC;AACX,CAAA;AAEO,IAAM,WAAA,GAAmC;AAAA,EAC9C,IAAA,EAAM,EAAA;AAAA,EACN,WAAA,EAAa,IAAA;AAAA,EACb,cAAc,EAAA,GAAK,KAAA;AAAA,EACnB,iBAAiB,GAAA,GAAM,KAAA;AAAA,EACvB,oBAAA,EAAsB;AACxB,CAAA;AAGO,IAAM,8BAAc,IAAI,GAAA,CAAI,CAAC,QAAA,EAAU,SAAA,EAAW,OAAO,CAAC,CAAA;AAiI1D,SAAS,mBAAmB,GAAA,EAAkC;AACnE,EAAA,MAAM,EAAE,UAAA,EAAY,IAAA,EAAK,GAAI,GAAA;AAC7B,EAAA,MAAM,EAAA,GAAK,IAAA,EAAM,GAAA,IAAO,IAAA,EAAM,EAAA,IAAM,UAAA;AACpC,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAChB,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,OAAO,IAAA,EAAM,KAAA;AAAA,IACb,WAAA,EAAa,MAAM,WAAA,IAAe,IAAA;AAAA,IAClC,SAAA,EAAW,MAAM,SAAA,IAAa,IAAA;AAAA,IAC9B,UAAU,IAAA,EAAM,QAAA;AAAA,IAChB,OAAA,EAAS,OAAA,CAAQ,IAAA,EAAM,OAAO;AAAA,GAChC;AACF;AAmBO,SAAS,kBACd,EAAE,WAAA,GAAc,oBAAoB,QAAA,EAAS,GAAwD,EAAC,EACzF;AACb,EAAA,IAAI,OAAO,gBAAgB,UAAA,EAAY;AACrC,IAAA,MAAM,IAAI,UAAU,2DAA2D,CAAA;AAAA,EACjF;AACA,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,OAAO,QAAA,KAAa,UAAA,EAAY;AAC5D,IAAA,MAAM,IAAI,UAAU,wDAAwD,CAAA;AAAA,EAC9E;AACA,EAAA,OAAO,EAAE,aAAa,GAAI,QAAA,GAAW,EAAE,QAAA,EAAS,GAAI,EAAC,EAAG;AAC1D;AAEA,SAAS,gBAAgB,KAAA,EAAqD;AAC5E,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,UAAU,gDAAgD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AACtB,IAAA,MAAM,IAAA,GAAkB,OAAO,CAAA,KAAM,QAAA,GAAW,EAAE,IAAI,CAAA,EAAE,GAAI,EAAE,GAAG,CAAA,EAAE;AACnE,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,IAAM,OAAO,IAAA,CAAK,OAAO,QAAA,EAAU;AAC3C,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,mDAAA,EAAsD,KAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IAChG;AAGA,IAAA,IAAI,SAAA,CAAU,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,6DAAA,EAAgE,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IAChG;AACA,IAAA,OAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,EAAA;AAAA,MAC1B,MAAM,IAAA,CAAK,IAAA,IAAQ,WAAA,CAAY,GAAA,CAAI,KAAK,EAAE;AAAA,KAC5C;AAAA,EACF,CAAC,CAAA;AACH;AAWA,SAAS,sBAAA,CACP,OACA,UAAA,EACsB;AACtB,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,MAAA;AAChC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,oCAAA,EAAuC,MAAA,CAAO,EAAE,CAAC,CAAA,+CAAA;AAAA,OAEnD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAG,KAAK,CAAA;AAClB;AAEA,SAAS,mBAAmB,KAAA,EAA2D;AACrF,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AACtB,IAAA,MAAM,IAAA,GAAqB,OAAO,CAAA,KAAM,QAAA,GAAW,EAAE,IAAI,CAAA,EAAE,GAAI,EAAE,GAAG,CAAA,EAAE;AACtE,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAAA,IACvB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,kDAAA,EAAqD,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACrF;AAIA,IAAA,IAAI,IAAI,IAAA,EAAM;AACZ,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,sDAAA,EAAyD,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,IAAS,KAAK,EAAA,EAAG;AAAA,EACjD,CAAC,CAAA;AACH;AAQA,SAAS,WAAA,GAAiD;AACxD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAgD;AACpE,EAAA,OAAO;AAAA,IACL,MAAM,GAAA,CAAI,GAAA,EAAa,QAAA,EAAkB;AACvC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC7B,MAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,OAAA,IAAW,GAAA,EAAK;AAClC,QAAA,MAAM,QAAQ,EAAE,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,MAAM,QAAA,EAAS;AAClD,QAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAGtB,QAAA,IAAI,OAAA,CAAQ,OAAO,GAAA,EAAQ;AACzB,UAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,OAAA,EAAS,IAAI,CAAA,CAAE,OAAA,IAAW,GAAA,EAAK,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA;AAAA,QACtE;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,KAAA,CAAM,KAAA,IAAS,CAAA;AACf,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACF;AACF;AASA,SAAS,cAAc,GAAA,EAA4B;AACjD,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,GAAA,CAAI,MAAK,EAAG;AAC1C,IAAA,MAAM,IAAI,SAAA;AAAA,MACR,CAAA,iFAAA,EAAoF,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA,CAAA;AAAA,KACzG;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AACrC,EAAA,IAAI,aAAa,IAAA,CAAK,KAAK,KAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,EAAG;AACrD,IAAA,MAAM,IAAI,SAAA;AAAA,MACR,uEAAuE,GAAG,CAAA,kFAAA;AAAA,KAE5E;AAAA,EACF;AACA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,UAAA,GAAa,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,IAAA,CAAK,IAAI,CAAA;AAC9C,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,oEAAA,EAAuE,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,EACnG;AAIA,EAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,SAAA;AAAA,MACR,yEAAyE,GAAG,CAAA,oEAAA;AAAA,KAE9E;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG,MAAM,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA,EAAI,UAAA,EAAW;AAC5D;AAUA,SAAS,WAAA,CACP,OACA,UAAA,EACc;AACd,EAAA,MAAM,GAAA,GAAoB;AAAA,IACxB,OAAA,EAAS,KAAA;AAAA,IACT,cAAc,EAAC;AAAA,IACf,UAAA,EAAY,IAAA;AAAA,IACZ,cAAA,EAAgB,GAAA;AAAA,IAChB,QAAA,EAAU,KAAA;AAAA,IACV,eAAe,EAAC;AAAA,IAChB,QAAA,sBAAc,GAAA;AAAI,GACpB;AACA,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,SAAS,OAAO,GAAA;AAErC,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA,IAAK,KAAA,CAAM,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AACzE,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KAGF;AAAA,EACF;AAEA,EAAA,MAAM,gBAAgB,KAAA,CAAM,aAAA,IAAiB,CAAC,GAAG,UAAA,CAAW,MAAM,CAAA;AAClE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,aAAa,CAAA,IAAK,aAAA,CAAc,WAAW,CAAA,EAAG;AAC/D,IAAA,MAAM,IAAI,UAAU,6EAA6E,CAAA;AAAA,EACnG;AACA,EAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,IAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,qDAAA,EAAwD,MAAA,CAAO,EAAE,CAAC,CAAA,+CAAA;AAAA,OAEpE;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,EAAgB,GAAA,EAAa,QAAA,KAA6B;AAC1E,IAAA,IAAI,KAAA,KAAU,QAAW,OAAO,QAAA;AAChC,IAAA,IAAI,OAAO,UAAU,QAAA,IAAY,CAAC,OAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA,EAAG;AACtE,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,+BAAA,EAAkC,GAAG,CAAA,4BAAA,CAA8B,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,YAAA,EAAc,KAAA,CAAM,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA;AAAA,IAClD,UAAA,EAAY,QAAA,CAAS,KAAA,CAAM,UAAA,EAAY,cAAc,IAAS,CAAA;AAAA,IAC9D,cAAA,EAAgB,QAAA,CAAS,KAAA,CAAM,cAAA,EAAgB,kBAAkB,GAAK,CAAA;AAAA,IACtE,QAAA,EAAU,QAAA,CAAS,KAAA,CAAM,QAAA,EAAU,YAAY,KAAM,CAAA;AAAA,IACrD,aAAA,EAAe,CAAC,GAAG,aAAa,CAAA;AAAA,IAChC,QAAA,sBAAc,GAAA;AAAI,GACpB;AACF;AAEO,SAAS,cAAc,MAAA,EAAgD;AAC5E,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,MAAM,IAAI,UAAU,8DAA8D,CAAA;AAAA,EACpF;AAEA,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA,GAAY,QAAA;AAAA,IACZ,UAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,MAAA;AAAA,IACd,WAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA,GAAc,QAAA;AAAA,IACd,YAAA;AAAA,IACA,UAAU,EAAC;AAAA,IACX,aAAa,EAAC;AAAA,IACd,aAAa,EAAC;AAAA,IACd,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,QAAQ,EAAC;AAAA,IACT,OAAO,EAAC;AAAA,IACR,WAAA,GAAc,CAAA;AAAA,IACd,gBAAA;AAAA,IACA,MAAA,GAAS,WAAA;AAAA,IACT,QAAQ,MAAM;AAAA,IAAC;AAAA,GACjB,GAAI,MAAA;AAEJ,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,CAAC,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA,EAAG;AAC9D,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,4DAAA,EAA+D,KAAK,SAAA,CAAU,MAAM,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,EAC9G;AAGA,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,mDAAA,EAAsD,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EACrF;AACA,EAAA,IAAI,CAAC,UAAA,IAAc,OAAO,UAAA,KAAe,QAAA,EAAU;AACjD,IAAA,MAAM,IAAI,UAAU,mFAA8E,CAAA;AAAA,EACpG;AACA,EAAA,IAAI,WAAA,KAAgB,UAAA,IAAc,CAAC,YAAA,EAAc;AAC/C,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,IAAI,WAAA,KAAgB,eAAe,QAAA,CAAA,EAAW;AAC5C,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,IAAA,MAAM,IAAI,UAAU,wCAAwC,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,YAAA,KAAiB,OAAO,YAAA,CAAa,IAAA,KAAS,cAAc,OAAO,YAAA,CAAa,WAAW,UAAA,CAAA,EAAa;AAC1G,IAAA,MAAM,IAAI,UAAU,+DAA+D,CAAA;AAAA,EACrF;AAEA,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,MAAA,CAAO,MAAM,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,MAAA,CAAO,SAAS,CAAA;AAIrD,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AACvD,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,MAAA,IAAU,EAAC,EAAG;AAC9B,MAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,EAAG;AACtB,QAAA,MAAM,IAAI,SAAA,CAAU,CAAA,sBAAA,EAAyB,EAAE,EAAE,CAAA,eAAA,EAAkB,CAAC,CAAA,6BAAA,CAA+B,CAAA;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAgB,sBAAA,CAAuB,MAAA,CAAO,aAAA,EAAe,UAAU,CAAA;AAE7E,EAAA,MAAM,SAAS,YAAA,CAAa;AAAA,IAC1B,UAAA;AAAA,IACA,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA,EAAoB,MAAM,aAAA,IAAiB;AAAA,GAC5C,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,cACZ,iBAAA,CAAkB,WAAW,IAC7B,iBAAA,CAAkB,EAAE,WAAA,EAAa,QAAA,EAAU,CAAA;AAE/C,EAAA,IAAI,CAAC,QAAQ,QAAA,EAAU;AAIrB,IAAA,MAAA,CAAO,IAAA;AAAA,MACL;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,IAAS,WAAA,EAAY;AAK9C,EAAA,MAAM,eAAA,GAAkB,IAAI,MAAA,CAAO,SAAS,EAAE,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAC,CAAA,CAAA;AAEvE,EAAA,MAAM,GAAA,GAAuB;AAAA,IAC3B,MAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA,EAAW,eAAA,KAAoB,GAAA,GAAM,EAAA,GAAK,eAAA;AAAA,IAC1C,SAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,MAAM,SAAS,MAAA,EAAQ;AACrB,MAAA,OAAQ,MAAM,OAAA,CAAQ,QAAA,GAAW,MAAM,CAAA,IAAM,EAAE,IAAI,MAAA,EAAO;AAAA,IAC5D,CAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAK,EAAE,GAAG,WAAA,EAAa,GAAG,OAAO,GAAA,EAAI;AAAA,IACrC,WAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,OAAO,UAAA,CAAW,KAAA,IAAS,EAAE,GAAA,EAAK,EAAA,EAAI,UAAU,GAAA,EAAO;AAAA,MACvD,WAAW,UAAA,CAAW,SAAA,IAAa,EAAE,GAAA,EAAK,EAAA,EAAI,UAAU,GAAA,EAAO;AAAA,MAC/D,SAAS,UAAA,CAAW,OAAA,IAAW,EAAE,GAAA,EAAK,EAAA,EAAI,UAAU,GAAA,EAAO;AAAA,MAC3D,KAAK,CAAC,GAAA,EAAK,aAAa,KAAA,CAAM,GAAA,CAAI,KAAK,QAAQ;AAAA,KACjD;AAAA,IACA,eAAA,EAAiB,WAAW,KAAA,IAAS,CAAA;AAAA,IACrC,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,CAAK,aAAA,IAAiB,OAAO,OAAA,EAAS,IAAA,CAAK,OAAA,IAAW,EAAC,EAAE;AAAA,IAChF,WAAA;AAAA,IACA,IAAA,EAAM,WAAA,CAAY,gBAAA,EAAkB,UAAU,CAAA;AAAA,IAC9C,MAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAM,MAAM,KAAA,EAAO;AACjB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA;AAAA,MACjC,SAAS,GAAA,EAAK;AAGZ,QAAA,MAAA,CAAO,KAAA,GAAQ,EAAE,GAAA,EAAK,KAAA,IAAS,gCAAgC,CAAA;AAAA,MACjE;AAAA,IACF;AAAA,GACF;AAEA,EAAA,OAAO,GAAA;AACT;;;ACrjBO,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EACpC,MAAA;AAAA,EAEA,IAAA;AAAA,EAEA,WAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EAEA,WAAA,CACE,MAAA,EACA,IAAA,EACA,WAAA,EACA,IAAA,EACA;AACA,IAAA,KAAA,CAAM,cAAc,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,WAAW,KAAK,IAAI,CAAA;AACpD,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,EAAM,OAAA;AAAA,EACvB;AAAA,EAEA,MAAA,GAAwD;AACtD,IAAA,OAAO;AAAA,MACL,OAAO,IAAA,CAAK,IAAA;AAAA,MACZ,GAAI,KAAK,WAAA,GAAc,EAAE,mBAAmB,IAAA,CAAK,WAAA,KAAgB;AAAC,KACpE;AAAA,EACF;AACF;AAIO,IAAM,iBAAiB,CAAC,CAAA,KAAe,IAAI,UAAA,CAAW,GAAA,EAAK,mBAAmB,CAAC,CAAA;AAC/E,IAAM,eAAe,CAAC,CAAA,KAAe,IAAI,UAAA,CAAW,GAAA,EAAK,iBAAiB,CAAC,CAAA;AAC3E,IAAM,eAAe,CAAC,CAAA,KAAe,IAAI,UAAA,CAAW,GAAA,EAAK,iBAAiB,CAAC,CAAA;AAC3E,IAAM,uBAAuB,CAAC,CAAA,KACnC,IAAI,UAAA,CAAW,GAAA,EAAK,0BAA0B,CAAC,CAAA;AAC1C,IAAM,eAAe,CAAC,CAAA,KAAe,IAAI,UAAA,CAAW,GAAA,EAAK,iBAAiB,CAAC,CAAA;AAW3E,IAAM,mBAAA,GAAN,cAAkC,UAAA,CAAW;AAAA,EAClD,WAAA,CAAY,MAAc,WAAA,EAAsB;AAC9C,IAAA,KAAA,CAAM,GAAA,EAAK,MAAM,WAAW,CAAA;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAQO,IAAM,qBAAA,GAAN,cAAoC,UAAA,CAAW;AAAA,EACpD,WAAA;AAAA,EAEA,KAAA;AAAA,EAEA,WAAA,CAAY,IAAA,EAAc,WAAA,EAAiC,WAAA,EAAqB,KAAA,EAAgB;AAC9F,IAAA,KAAA,CAAM,GAAA,EAAK,MAAM,WAAW,CAAA;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AACZ,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AACnB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA;AAAA,EAGA,WAAW,MAAA,EAAwB;AACjC,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,WAAW,CAAA;AACpC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA;AACvC,IAAA,IAAI,KAAK,WAAA,EAAa,GAAA,CAAI,aAAa,GAAA,CAAI,mBAAA,EAAqB,KAAK,WAAW,CAAA;AAChF,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAW,GAAA,CAAI,aAAa,GAAA,CAAI,OAAA,EAAS,KAAK,KAAK,CAAA;AACtE,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,MAAM,CAAA;AAClC,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AACF;AAiBO,SAAS,IAAA,CAAK,QAAgB,OAAA,EAAqC;AACxE,EAAA,OAAO,OAAO,GAAA,EAAK,GAAA,EAAK,IAAA,KAAS;AAC/B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,GAAA,EAAK,GAAA,EAAK,IAAI,CAAA;AAAA,IAC9B,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,eAAe,UAAA,EAAY;AAG7B,QAAA,IAAI,GAAA,CAAI,WAAA,EAAa,OAAO,IAAA,CAAK,GAAG,CAAA;AACpC,QAAA,IAAI,GAAA,CAAI,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,IAAI,OAAO,CAAA;AACpC,QAAA,OAAO,GAAA,CAAI,OAAO,GAAA,CAAI,MAAM,EAAE,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA;AAAA,MACjD;AACA,MAAA,MAAA,CAAO,QAAQ,EAAE,GAAA,EAAK,MAAM,GAAA,CAAI,WAAA,IAAe,4BAA4B,CAAA;AAC3E,MAAA,IAAI,GAAA,CAAI,WAAA,EAAa,OAAO,IAAA,CAAK,GAAG,CAAA;AACpC,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,gBAAgB,CAAA;AAAA,IAChD;AAAA,EACF,CAAA;AACF;ACjHA,IAAM,SAAA,GAAiE;AAAA,EACrE,CAAC,0BAA0B,YAAY,CAAA;AAAA,EACvC,CAAC,kBAAkB,QAAQ,CAAA;AAAA,EAC3B,CAAC,uBAAuB,SAAS,CAAA;AAAA,EACjC,CAAC,qBAAqB,WAAW,CAAA;AAAA,EACjC,CAAC,YAAY,OAAO;AACtB,CAAA;AAEA,IAAM,aAAA,GAAgB,yCAAA;AACtB,IAAM,eAAA,GAAkB,mCAAA;AACxB,IAAM,mBAAA,GAAsB,uCAAA;AAarB,SAAS,4BAAA,CAA6B,QAAgB,UAAA,EAA4B;AACvF,EAAA,OAAO,GAAG,MAAM,CAAA,EAAG,mBAAmB,CAAA,EAAG,cAAA,CAAe,UAAU,CAAC,CAAA,CAAA;AACrE;AASA,SAAS,eAAe,UAAA,EAA4B;AAClD,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,IAAI,IAAI,UAAU,CAAA;AACvC,EAAA,OAAO,aAAa,GAAA,GAAM,EAAA,GAAK,QAAA,CAAS,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC5D;AAGA,SAAS,SAAS,OAAA,EAAyB;AACzC,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AACtD;AASA,SAAS,iBAAiB,SAAA,EAA2B;AACnD,EAAA,OAAO,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,QAAA,CAAS,SAAS,CAAC,CAAA,SAAA,CAAW,CAAA;AACtD;AAgBA,SAAS,gBAAA,CACP,GAAA,EACA,SAAA,EACA,IAAA,EACA,UACA,YAAA,EACgB;AAChB,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,CAAC,KAAK,GAAA,KAAQ;AAIpC,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACtF,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,GAAA,CAAI,KAAK,IAAI,CAAA;AACjC,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAC/B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,WAAA,EAAa,iBAAA,EAAmB,YAAA,CAAa,MAAM,CAAA,EAAG,CAAA;AAAA,IAC7F;AACA,IAAA,OAAO,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACrB,CAAC,CAAA;AACH;AAEA,SAAS,2BAAA,CAA4B,KAAsB,SAAA,EAA4C;AACrG,EAAA,MAAM,IAAA,GAAO,GAAG,GAAA,CAAI,MAAM,GAAG,SAAA,KAAc,GAAA,GAAM,KAAK,SAAS,CAAA,CAAA;AAC/D,EAAA,MAAM,YAAY,MAAA,CAAO,WAAA,CAAY,UAAU,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,IAAI,CAAA,KAAM,CAAC,KAAK,CAAA,EAAG,IAAI,GAAG,IAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAE5F,EAAA,OAAO;AAAA,IACL,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,GAAG,SAAA;AAAA,IACH,kBAAkB,GAAA,CAAI,MAAA,CAAO,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IAC5C,wBAAA,EAA0B,CAAC,MAAM,CAAA;AAAA,IACjC,qBAAA,EAAuB,CAAC,oBAAA,EAAsB,eAAe,CAAA;AAAA;AAAA;AAAA,IAG7D,gCAAA,EAAkC,CAAC,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKzC,qCAAA,EAAuC;AAAA,MACrC,qBAAA;AAAA,MACA,oBAAA;AAAA,MACA,GAAI,GAAA,CAAI,IAAA,CAAK,UAAU,CAAC,MAAM,IAAI;AAAC,KACrC;AAAA;AAAA;AAAA,IAGA,GAAI,IAAI,IAAA,CAAK,OAAA,GAAU,EAAE,qCAAA,EAAuC,IAAA,KAAS,EAAC;AAAA,IAC1E,uBAAA,EAAyB,CAAC,GAAA,CAAI,WAAW,CAAA;AAAA,IACzC,qCAAA,EAAuC,CAAC,OAAO,CAAA;AAAA;AAAA;AAAA,IAG/C,8CAAA,EAAgD;AAAA,GAClD;AACF;AAEA,SAAS,yBAAA,CAA0B,KAAsB,QAAA,EAAiD;AACxG,EAAA,OAAO;AAAA,IACL,UAAU,QAAA,CAAS,EAAA;AAAA,IACnB,qBAAA,EAAuB,CAAC,GAAA,CAAI,MAAM,CAAA;AAAA,IAClC,gBAAA,EAAkB,SAAS,MAAA,IAAU,GAAA,CAAI,OAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA;AAAA,IAC/D,wBAAA,EAA0B,CAAC,QAAQ;AAAA,GACrC;AACF;AAOO,SAAS,qBAAA,CAAsB,GAAA,EAAsB,SAAA,GAAY,QAAA,EAAkB;AACxF,EAAA,MAAM,MAAA,GAASC,0BAAQ,MAAA,EAAO;AAE9B,EAAA,MAAM,UAAA,GAAa,2BAAA,CAA4B,GAAA,EAAK,SAAS,CAAA;AAS7D,EAAA,MAAM,eAAe,cAAA,CAAe,GAAA,CAAI,MAAM,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AACjE,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,YAAA,GAAe,CAAC,CAAC,YAAA,EAAc,UAAU,CAAC,CAAA,GAAI,EAAE,CAAA;AAC3E,EAAA,MAAM,gBAAgB,CAAC,MAAA,KACrB,0CAA0C,GAAA,CAAI,MAAM,iCAAiC,MAAM,CAAA,CAAA,CAAA;AAK7F,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,CAAC,MAAM,GAAA,KAAQ,GAAA,CAAI,IAAA,CAAK,UAAU,CAAC,CAAA;AACpE,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,iBAAiB,aAAa,CAAA;AAAA,IAC9B,gBAAA,CAAiB,GAAA,EAAK,aAAA,EAAe,UAAA,EAAY,YAAY,aAAa;AAAA,GAC5E;AACA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,iBAAiB,eAAe,CAAA;AAAA,IAChC,gBAAA,CAAiB,GAAA,EAAK,eAAA,EAAiB,UAAA,EAAY,YAAY,aAAa;AAAA,GAC9E;AAYA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAA,CAAO,GAAA,CAAI,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,QAAA,CAAS,CAAA,CAAA,EAAI,YAAY,CAAA,EAAG,eAAe,CAAA,CAAE,CAAC,CAAA,GAAA,CAAK,GAAG,OAAO,CAAA;AAAA,EACzF;AAKA,EAAA,MAAM,WAAW,IAAI,GAAA;AAAA,IACnB,IAAI,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,eAAe,CAAA,CAAE,EAAE,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA,EAAG,0BAA0B,GAAA,EAAK,CAAC,CAAC,CAAC;AAAA,GACvG;AAGA,EAAA,MAAM,gBAAgB,yBAAA,CAA0B,GAAA,EAAK,GAAA,CAAI,SAAA,CAAU,CAAC,CAAE,CAAA;AACtE,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,iBAAiB,mBAAmB,CAAA;AAAA,IACpC,gBAAA;AAAA,MACE,GAAA;AAAA,MACA,mBAAA;AAAA,MACA,aAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,MAAA,KAAW,CAAA,8BAAA,EAAiC,MAAM,CAAA,CAAA;AAAA;AACrD,GACF;AAEA,EAAA,OAAO,MAAA;AACT;AC5MO,SAAS,WAAA,CAAY,QAAQ,EAAA,EAAY;AAC9C,EAAA,OAAOC,kBAAA,CAAY,KAAK,CAAA,CAAE,QAAA,CAAS,WAAW,CAAA;AAChD;AAEO,SAAS,OAAO,KAAA,EAAuB;AAC5C,EAAA,OAAOC,kBAAW,QAAQ,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,OAAO,WAAW,CAAA;AAC9D;AAUO,SAAS,SAAA,CAAU,GAAW,CAAA,EAAoB;AACvD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAClC,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAClC,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,CAAK,MAAA,EAAQ,OAAO,KAAA;AACxC,EAAA,OAAOC,sBAAA,CAAoB,MAAM,IAAI,CAAA;AACvC;AAGO,SAAS,UAAA,CAAW,UAAkBC,UAAAA,EAA4B;AAEvE,EAAA,IAAI,SAAS,MAAA,GAAS,EAAA,IAAM,QAAA,CAAS,MAAA,GAAS,KAAK,OAAO,KAAA;AAC1D,EAAA,IAAI,CAAC,qBAAA,CAAsB,IAAA,CAAK,QAAQ,GAAG,OAAO,KAAA;AAClD,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA,EAAGA,UAAS,CAAA;AAC9C;AASO,SAAS,eAAA,CAAgB,MAAA,EAAgB,QAAA,EAAkB,IAAA,EAAsB;AACtF,EAAA,OAAOC,iBAAA,CAAW,QAAA,EAAU,IAAI,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA,CAAE,MAAA,CAAO,WAAW,CAAA;AACtF;AAGO,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,YAAY,EAAE,CAAA;AACvB;AAGO,SAAS,oBAAA,GAA+B;AAC7C,EAAA,OAAO,YAAY,EAAE,CAAA;AACvB;;;ACzCA,IAAM,iCAAiB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,WAAA,EAAa,OAAO,CAAC,CAAA;AAmB3D,SAAS,kBAAA,CAAmB,YAAoB,SAAA,EAA4B;AAEjF,EAAA,IAAI,UAAA,KAAe,WAAW,OAAO,IAAA;AAErC,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI;AACF,IAAA,CAAA,GAAI,IAAI,IAAI,UAAU,CAAA;AACtB,IAAA,CAAA,GAAI,IAAI,IAAI,SAAS,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AAIN,IAAA,OAAO,KAAA;AAAA,EACT;AAKA,EAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,CAAA,CAAE,QAAQ,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,CAAA,CAAE,QAAQ,CAAA,EAAG,OAAO,KAAA;AAK/E,EAAA,OACE,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,QAAA,IACd,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,QAAA,IACjB,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,QAAA,IACjB,CAAA,CAAE,aAAa,CAAA,CAAE,QAAA,IACjB,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,QAAA,IACjB,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,IACf,CAAA,CAAE,IAAA,KAAS,CAAA,CAAE,IAAA;AAEpB;AAGO,SAAS,qBAAA,CAAsB,YAA+B,SAAA,EAA4B;AAC/F,EAAA,OAAO,WAAW,IAAA,CAAK,CAAC,UAAU,kBAAA,CAAmB,KAAA,EAAO,SAAS,CAAC,CAAA;AACxE;;;AClCA,SAAS,UAAU,QAAA,EAA0B;AAC3C,EAAA,OAAO,MAAA,CAAO,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAE,CAAA;AACpC;AAEA,IAAM,WAAA,GAAc,CAAC,KAAA,KAAA,CAClB,KAAA,IAAS,IAAI,KAAA,CAAM,KAAK,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AAG3C,IAAM,gBAAgB,CAAC,CAAA,KAAc,IAAI,UAAA,CAAW,GAAA,EAAK,kBAAkB,CAAC,CAAA;AAE5E,eAAe,SAAA,CACb,KACA,OAAA,EACwB;AACxB,EAAA,MAAM,QAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,SAAS,OAAO,CAAA;AACrD,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,SAAA,EAAW;AAC7B,IAAA,MAAM,aAAa,sDAAsD,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,KAAA;AACT;AAWA,eAAsB,WAAA,CACpB,GAAA,EACA,OAAA,EACA,IAAA,EACuB;AACvB,EAAA,MAAM,QAAA,GAAW,OAAO,OAAO,CAAA;AAC/B,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AAErB,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,gBAAA;AAAA,IACjC,EAAE,QAAA,EAAU,UAAA,EAAY,IAAA,EAAK;AAAA,IAC7B,EAAE,IAAA,EAAM,EAAE,UAAA,EAAY,KAAI,EAAE;AAAA,IAC5B,EAAE,gBAAgB,OAAA;AAAQ,GAC5B;AAEA,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,MAAA,CAAO,KAAK,OAAA,CAAQ,EAAE,UAAU,CAAA;AAC3D,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,QAAA,GAAW,UAAU,QAAQ,CAAA;AACnC,MAAA,MAAM,OAAA,GAAU,MAAM,YAAA,CAAa,GAAA,EAAK,UAAU,aAAa,CAAA;AAC/D,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,SAAS,QAAA,CAAS,OAAA;AAAA,QAClB,IAAA,EAAM,EAAE,QAAA,EAAU,aAAA,EAAe,OAAA;AAAQ,OAC1C,CAAA;AACD,MAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,QACT,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,QAAA,EAAS;AAAA,QACpC;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,aAAa,yDAAyD,CAAA;AAAA,EAC9E;AAEA,EAAA,IAAI,KAAK,SAAA,CAAU,OAAA,EAAQ,IAAK,GAAA,CAAI,SAAQ,EAAG;AAC7C,IAAA,MAAM,aAAa,gCAAgC,CAAA;AAAA,EACrD;AACA,EAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,QAAA,EAAU;AACnC,IAAA,MAAM,aAAa,qDAAqD,CAAA;AAAA,EAC1E;AAKA,EAAA,IAAI,CAAC,kBAAA,CAAmB,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,WAAW,CAAA,EAAG;AAC3D,IAAA,MAAM,aAAa,6DAA6D,CAAA;AAAA,EAClF;AACA,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,gBAAgB,EAAA,EAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AAC5D,IAAA,MAAM,aAAa,0BAA0B,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,eAAe,QAAA,CACb,KACA,IAAA,EAWuB;AACvB,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,cAAc,WAAA,EAAY;AAChC,EAAA,MAAM,eAAe,WAAA,EAAY;AACjC,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,OAAA,EAAS,KAAK,KAAA,CAAM,GAAA;AAAA,IACpB,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,UAAU,IAAA,CAAK;AAAA,GACjB;AAEA,EAAA,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO;AAAA,IAC5B,GAAG,MAAA;AAAA,IACH,IAAA,EAAM,QAAA;AAAA,IACN,SAAA,EAAW,OAAO,WAAW,CAAA;AAAA,IAC7B,WAAW,IAAI,IAAA,CAAK,MAAM,GAAA,CAAI,GAAA,CAAI,cAAc,GAAI;AAAA,GACrD,CAAA;AACD,EAAA,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO;AAAA,IAC5B,GAAG,MAAA;AAAA,IACH,IAAA,EAAM,SAAA;AAAA,IACN,SAAA,EAAW,OAAO,YAAY,CAAA;AAAA,IAC9B,QAAA,EAAU,KAAK,QAAA,IAAY,IAAA;AAAA;AAAA;AAAA;AAAA,IAI3B,WAAW,IAAI,IAAA,CAAK,MAAM,GAAA,CAAI,GAAA,CAAI,eAAe,GAAI,CAAA;AAAA,IACrD,iBAAiB,IAAA,CAAK;AAAA,GACvB,CAAA;AAED,EAAA,MAAM,IAAI,MAAA,CAAO,KAAA,CAAM,UAAU,EAAE,GAAA,EAAK,KAAK,KAAA,CAAM,GAAA,IAAO,EAAE,IAAA,EAAM,EAAE,UAAA,EAAY,IAAI,KAAK,GAAG,CAAA,IAAK,CAAA;AAEjG,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA,EAAW,IAAI,GAAA,CAAI,WAAA;AAAA,IACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAAA,IAC9B,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK;AAAA,GAClB;AACF;AAEA,eAAsB,YAAA,CACpB,KACA,IAAA,EACuB;AACvB,EAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,GAAA,EAAK,KAAK,OAAO,CAAA;AAC/C,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,GAAA,EAAK;AAAA,IACjC,KAAA;AAAA,IACA,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,QAAQ,IAAA,CAAK,MAAA;AAAA;AAAA;AAAA,IAGb,UAAU,IAAA,CAAK,SAAA;AAAA,IACf,QAAA,EAAU,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAA;AAAA,IACjC,eAAA,EAAiB,IAAI,IAAA,CAAK,IAAA,CAAK,KAAI,GAAI,GAAA,CAAI,GAAA,CAAI,eAAA,GAAkB,GAAI;AAAA,GACtE,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM;AAAA,IACR,IAAA,EAAM,oBAAA;AAAA,IACN,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,SAAA,EAAW,OAAO,SAAA,IAAa,MAAA;AAAA,IAC/B,QAAQ,MAAA,CAAO;AAAA,GAChB,CAAA;AACD,EAAA,MAAM,IAAI,KAAA,CAAM;AAAA,IACd,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO,QAAA;AAAA,IACP,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,SAAS,KAAA,CAAM,GAAA;AAAA,IACf,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,QAAQ,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU,MAAA,CAAO,QAAA;AAAS,GACrF,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAUA,eAAsB,aAAA,CACpB,GAAA,EACA,UAAA,EACA,IAAA,EACuB;AACvB,EAAA,MAAM,SAAA,GAAY,OAAO,UAAU,CAAA;AACnC,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AAErB,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,gBAAA;AAAA,IACnC,EAAE,SAAA,EAAW,IAAA,EAAM,WAAW,UAAA,EAAY,IAAA,EAAM,WAAW,IAAA,EAAK;AAAA,IAChE,EAAE,IAAA,EAAM,EAAE,UAAA,EAAY,KAAI,EAAE;AAAA,IAC5B,EAAE,gBAAgB,OAAA;AAAQ,GAC5B;AAEA,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,QAAQ,EAAE,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,CAAA;AAC3E,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,MAAM,UAAU,MAAM,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,UAAU,wBAAwB,CAAA;AAChF,MAAA,GAAA,CAAI,KAAA,CAAM;AAAA,QACR,IAAA,EAAM,8BAAA;AAAA,QACN,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA;AAAA,QAC7B,SAAA,EAAW,MAAM,SAAA,IAAa,MAAA;AAAA,QAC9B,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,MAAM,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,eAAe,OAAA;AAAQ,OAC1D,CAAA;AACD,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,wBAAA;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,MAAM,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,eAAe,OAAA;AAAQ,OAC1D,CAAA;AACD,MAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,QACT,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,MAAM,QAAA,EAAS;AAAA,QACrD;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,aAAa,oDAAoD,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,KAAA,CAAM,QAAA,KAAa,IAAA,CAAK,QAAA,EAAU;AAGpC,IAAA,MAAM,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,QAAA,EAAU,sBAAsB,CAAA;AAC9D,IAAA,MAAM,IAAI,KAAA,CAAM;AAAA,MACd,IAAA,EAAM,sBAAA;AAAA,MACN,KAAA,EAAO,QAAA;AAAA,MACP,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,MAAM,EAAE,QAAA,EAAU,MAAM,QAAA,EAAU,QAAA,EAAU,MAAM,QAAA;AAAS,KAC5D,CAAA;AACD,IAAA,MAAM,aAAa,gDAAgD,CAAA;AAAA,EACrE;AACA,EAAA,IAAI,MAAM,SAAA,CAAU,OAAA,EAAQ,IAAK,GAAA,CAAI,SAAQ,EAAG;AAC9C,IAAA,MAAM,aAAa,2BAA2B,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,KAAA,CAAM,mBAAmB,KAAA,CAAM,eAAA,CAAgB,SAAQ,IAAK,GAAA,CAAI,SAAQ,EAAG;AAG7E,IAAA,MAAM,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,QAAA,EAAU,wBAAwB,CAAA;AAChE,IAAA,MAAM,aAAa,sFAAsF,CAAA;AAAA,EAC3G;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,GAAA,EAAK,MAAM,OAAO,CAAA;AAahD,EAAA,IAAI,GAAA,CAAI,YAAA,IAAgB,KAAA,CAAM,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,YAAA,CAAa,MAAA;AAAA,MAC1C,MAAM,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA;AAAA,MAC/B,KAAA,CAAM;AAAA,KACR;AACA,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,GAAA,CAAI,OAAO,KAAA,CAAM,SAAA;AAAA,QACrB,EAAE,GAAA,EAAK,KAAA,CAAM,GAAA,EAAK,WAAW,IAAA,EAAK;AAAA,QAClC,EAAE,IAAA,EAAM,EAAE,WAAW,GAAA,EAAK,SAAA,EAAW,UAAS;AAAE,OAClD;AACA,MAAA,MAAM,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,QAAA,EAAU,0BAA0B,CAAA;AAClE,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,eAAA;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,MAAM,EAAE,MAAA,EAAQ,0BAAA,EAA4B,SAAA,EAAW,MAAM,SAAA;AAAU,OACxE,CAAA;AACD,MAAA,MAAM,aAAa,uEAAuE,CAAA;AAAA,IAC5F;AAAA,EACF;AAKA,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,CAAC,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,CAAA;AACnE,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,MAAA,GAAS,SAAA,GAAY,OAAA;AAC9C,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAA,EAAG;AACxB,MAAA,MAAM,YAAA,CAAa,CAAA,OAAA,EAAU,CAAC,CAAA,0DAAA,CAA4D,CAAA;AAAA,IAC5F;AAAA,EACF;AAEA,EAAA,MAAM,WAAW,IAAA,CAAK,SAAA,EAAW,MAAA,GAAS,IAAA,CAAK,YAAY,KAAA,CAAM,QAAA;AACjE,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,QAAA,CAAS,CAAC,CAAA,EAAG;AAC/B,MAAA,MAAM,aAAA,CAAc,CAAA,UAAA,EAAa,CAAC,CAAA,2CAAA,CAA6C,CAAA;AAAA,IACjF;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,GAAA,EAAK;AAAA,IACjC,KAAA;AAAA,IACA,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,MAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,eAAA,EAAiB,KAAA,CAAM,eAAA,IAAmB,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,EAAQ,GAAI,GAAA,CAAI,GAAA,CAAI,eAAA,GAAkB,GAAI,CAAA;AAAA,IACjG,UAAU,KAAA,CAAM;AAAA,GACjB,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM;AAAA,IACR,IAAA,EAAM,uBAAA;AAAA,IACN,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,SAAA,EAAW,OAAO,SAAA,IAAa,MAAA;AAAA,IAC/B,QAAQ,MAAA,CAAO;AAAA,GAChB,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAGA,eAAsB,YAAA,CACpB,GAAA,EACA,QAAA,EACA,MAAA,EACiB;AACjB,EAAA,MAAM,EAAE,aAAA,GAAgB,CAAA,KAAM,MAAM,GAAA,CAAI,OAAO,KAAA,CAAM,UAAA;AAAA,IACnD,EAAE,QAAA,EAAU,SAAA,EAAW,IAAA,EAAK;AAAA,IAC5B,EAAE,IAAA,EAAM,EAAE,2BAAW,IAAI,IAAA,IAAO;AAAE,GACpC;AACA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,GAAA,CAAI,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,QAAQ,aAAA,EAAe,aAAA,IAAiB,kCAAkC,CAAA;AAAA,EAC1G;AACA,EAAA,OAAO,aAAA;AACT;AA+BA,IAAM,iBAAA,GAAoB,GAAA;AAC1B,IAAM,kBAAA,uBAAyB,GAAA,EAAmD;AAElF,SAAS,QAAA,CAAS,KAAsB,IAAA,EAAoC;AAC1E,EAAA,IAAI,GAAA,CAAI,eAAA,IAAmB,CAAA,EAAG,OAAO,IAAA;AACrC,EAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,GAAA,CAAI,IAAI,CAAA;AACvC,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,IAAI,GAAA,CAAI,KAAA,IAAS,IAAA,CAAK,GAAA,EAAI,EAAG;AAC3B,IAAA,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,GAAA,CAAI,GAAA;AACb;AAEA,SAAS,QAAA,CAAS,GAAA,EAAsB,IAAA,EAAc,GAAA,EAA0B;AAC9E,EAAA,IAAI,GAAA,CAAI,mBAAmB,CAAA,EAAG;AAC9B,EAAA,IAAI,kBAAA,CAAmB,QAAQ,iBAAA,EAAmB;AAGhD,IAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAChD,IAAA,IAAI,MAAA,KAAW,MAAA,EAAW,kBAAA,CAAmB,MAAA,CAAO,MAAM,CAAA;AAAA,EAC5D;AAGA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,EAAI,GAAI,GAAA,CAAI,eAAA,EAAiB,GAAA,CAAI,SAAA,CAAU,OAAA,EAAS,CAAA;AAChF,EAAA,kBAAA,CAAmB,GAAA,CAAI,IAAA,EAAM,EAAE,GAAA,EAAK,OAAO,CAAA;AAC7C;AAGO,SAAS,kBAAkB,SAAA,EAAyB;AACzD,EAAA,kBAAA,CAAmB,OAAO,SAAS,CAAA;AACrC;AAEA,eAAsB,qBAAA,CACpB,KACA,GAAA,EAC+B;AAC/B,EAAA,MAAM,IAAA,GAAO,OAAO,GAAG,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,EAAK,IAAI,CAAA;AACjC,EAAA,IAAI,QAAQ,OAAO,MAAA;AAEnB,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,EAAE,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,QAAA,EAAU,CAAA;AAChF,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,IAAI,KAAA,CAAM,WAAW,OAAO,IAAA;AAC5B,EAAA,IAAI,MAAM,SAAA,CAAU,OAAA,MAAa,IAAA,CAAK,GAAA,IAAO,OAAO,IAAA;AAIpD,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,CAAA,EAAG,CAAA;AAC7E,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,SAAA,EAAW,OAAO,IAAA;AAEtC,EAAA,QAAA,CAAS,GAAA,EAAK,MAAM,KAAK,CAAA;AACzB,EAAA,OAAO,KAAA;AACT;AASA,eAAsB,WAAA,CACpB,GAAA,EACA,GAAA,EACA,QAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,EAAE,SAAA,EAAW,MAAA,CAAO,GAAG,CAAA,EAAG,CAAA;AACvE,EAAA,IAAI,CAAC,KAAA,EAAO;AACZ,EAAA,iBAAA,CAAkB,MAAM,SAAS,CAAA;AAGjC,EAAA,IAAI,KAAA,CAAM,aAAa,QAAA,EAAU;AAEjC,EAAA,IAAI,KAAA,CAAM,SAAS,SAAA,EAAW;AAC5B,IAAA,MAAM,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,QAAA,EAAU,mBAAmB,CAAA;AAAA,EAC7D,CAAA,MAAO;AACL,IAAA,MAAM,GAAA,CAAI,OAAO,KAAA,CAAM,SAAA;AAAA,MACrB,EAAE,GAAA,EAAK,KAAA,CAAM,GAAA,EAAK,WAAW,IAAA,EAAK;AAAA,MAClC,EAAE,IAAA,EAAM,EAAE,2BAAW,IAAI,IAAA,IAAO;AAAE,KACpC;AAAA,EACF;AACA,EAAA,MAAM,IAAI,KAAA,CAAM;AAAA,IACd,IAAA,EAAM,eAAA;AAAA,IACN,KAAA,EAAO,QAAA;AAAA,IACP,QAAA;AAAA,IACA,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,MAAM,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA;AAAS,GACpD,CAAA;AACH;;;ACjfO,SAAS,cAAc,GAAA,EAAoD;AAChF,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAEvD,EAAA,OAAO,SAAS,OAAA,CAAQ,MAAA,EAA4B,IAAA,GAAuB,EAAC,EAAmB;AAC7F,IAAA,MAAM,QAAA,GAAW,MAAA,KAAW,MAAA,GAAY,EAAC,GAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,GAAS,CAAC,MAAM,CAAA;AACrF,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA,IAAY,GAAA,CAAI,SAAA,CAAU,CAAC,CAAA,CAAG,EAAA;AACpD,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,KAAA;AAK1B,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,iCAAA,EAAoC,QAAQ,CAAA,6CAAA,EACtC,CAAC,GAAG,QAAQ,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,OAChC;AAAA,IACF;AACA,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,EAAG;AAC1B,QAAA,MAAM,IAAI,SAAA,CAAU,CAAA,sCAAA,EAAyC,CAAC,CAAA,oCAAA,CAAsC,CAAA;AAAA,MACtG;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,4BAAA,CAA6B,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAErE,IAAA,OAAO,KAAK,GAAA,CAAI,MAAA,EAAQ,OAAO,GAAA,EAAK,KAAK,IAAA,KAAS;AAChD,MAAA,MAAM,GAAA,GAAM,iBAAiB,GAAG,CAAA;AAGhC,MAAA,IAAI,CAAC,GAAA,EAAK,OAAO,SAAA,CAAU,GAAA,EAAK,KAAK,WAAW,CAAA;AAEhD,MAAA,MAAM,KAAA,GAAQ,MAAM,qBAAA,CAAsB,GAAA,EAAK,GAAG,CAAA;AAClD,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,OAAO,SAAA,CAAU,GAAA,EAAK,GAAA,EAAK,WAAA,EAAa;AAAA,UACtC,KAAA,EAAO,eAAA;AAAA,UACP,iBAAA,EAAmB;AAAA,SACpB,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AAKtC,QAAA,OAAO,SAAA,CAAU,GAAA,EAAK,GAAA,EAAK,WAAA,EAAa;AAAA,UACtC,KAAA,EAAO,eAAA;AAAA,UACP,iBAAA,EAAmB;AAAA,SACpB,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACjC,MAAA,MAAM,EAAA,GAAK,SAAS,KAAA,GAChB,QAAA,CAAS,WAAW,CAAA,IAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,CAAC,CAAC,IACzD,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AACrC,MAAA,IAAI,CAAC,EAAA,EAAI;AACP,QAAA,OAAO,SAAA,CAAU,GAAA,EAAK,GAAA,EAAK,WAAA,EAAa;AAAA,UACtC,KAAA,EAAO,oBAAA;AAAA,UACP,iBAAA,EAAmB,CAAA,SAAA,EAAY,IAAA,KAAS,KAAA,GAAQ,QAAA,GAAW,QAAQ,CAAA,EAAA,EAAK,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAAA,UAC1F,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,GAAG;AAAA,SACzB,CAAA;AAAA,MACH;AAIA,MAAA,GAAA,CAAI,KAAA,GAAQ;AAAA,QACV,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,SAAA,EAAW,MAAM,SAAA,IAAa,IAAA;AAAA,QAC9B,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA;AAAA,QAC7B,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,QACzB,UAAU,KAAA,CAAM;AAAA,OAClB;AACA,MAAA,OAAO,IAAA,EAAK;AAAA,IACd,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAUA,SAAS,iBAAiB,GAAA,EAA6B;AACrD,EAAA,MAAM,MAAA,GAAS,IAAI,OAAA,CAAQ,aAAA;AAC3B,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,IAAA,CAAK,MAAM,CAAA;AAC/C,EAAA,OAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAK,IAAA;AAC7B;AAEA,SAAS,UACP,GAAA,EACA,MAAA,EACA,WAAA,EACA,MAAA,GAAyE,EAAC,EAChE;AACV,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,GAAG,OAAO,OAAA,CAAQ,MAAM,EAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,CAAC,EAAE,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACjF,sBAAsB,WAAW,CAAA,CAAA;AAAA,GACnC;AACA,EAAA,GAAA,CAAI,IAAI,kBAAA,EAAoB,CAAA,OAAA,EAAU,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAGxD,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,IAC7B,KAAA,EAAO,OAAO,KAAA,IAAS,iBAAA;AAAA,IACvB,iBAAA,EAAmB,OAAO,iBAAA,IAAqB;AAAA,GAChD,CAAA;AACH;;;ACxHO,SAAS,SAAA,CACd,GAAA,EACA,MAAA,EACA,KAAA,EACgB;AAChB,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA;AAClC,EAAA,IAAI,SAAS,KAAA,EAAO,OAAO,CAAC,IAAA,EAAM,IAAA,EAAM,SAAS,IAAA,EAAK;AAEtD,EAAA,OAAO,CAAC,GAAA,EAAK,GAAA,EAAK,IAAA,KAAS;AACzB,IAAA,KAAA,CAAM,YAAY;AAChB,MAAA,IAAI,GAAA;AACJ,MAAA,IAAI;AACF,QAAA,GAAA,GAAM,MAAM,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,QAAQ,CAAA;AAAA,MACzE,SAAS,GAAA,EAAK;AAKZ,QAAA,GAAA,CAAI,OAAO,KAAA,GAAQ,EAAE,GAAA,EAAK,MAAA,IAAU,uDAAuD,CAAA;AAC3F,QAAA,IAAA,EAAK;AACL,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,GAAA,CAAI,KAAA,IAAS,IAAA,CAAK,GAAA,EAAK;AACzB,QAAA,IAAA,EAAK;AACL,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAA,CAAM,GAAA,CAAI,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,IAAK,GAAI,CAAC,CAAA;AAC3E,MAAA,GAAA,CAAI,GAAA,CAAI,aAAA,EAAe,MAAA,CAAO,UAAU,CAAC,CAAA;AAIzC,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,QACnB,KAAA,EAAO,mBAAA;AAAA,QACP,iBAAA,EAAmB,CAAA,wBAAA,EAA2B,MAAM,CAAA,WAAA,EAAc,UAAU,CAAA,EAAA;AAAA,OAC7E,CAAA;AAAA,IACH,CAAA,GAAG;AAAA,EACL,CAAA;AACF;ACAA,SAAS,WAAW,GAAA,EAAsC;AACxD,EAAA,OAAO,OAAO,IAAA,CAAK,SAAA,CAAU,EAAE,GAAA,EAAK,IAAI,GAAA,EAAK,GAAA,EAAK,GAAA,CAAI,GAAA,EAAK,GAAG,GAAA,CAAI,CAAA,EAAG,GAAG,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAClF;AAEA,SAAS,MAAM,GAAA,EAAyC;AACtD,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,EAAE,MAAA,EAAQ,OAAO,CAAA;AACrC;AAGA,SAAS,UAAA,CAAW,KAA8B,GAAA,EAAsC;AACtF,EAAA,MAAM,EAAE,CAAA,EAAG,GAAG,IAAA,EAAK,GAAI,GAAA;AAEvB,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,KAAK,GAAA,EAAK,OAAA,EAAS,KAAK,KAAA,EAAM;AAClD;AAEA,SAAS,oBAAoB,KAAA,EAAsD;AACjF,EAAA,IAAI,CAAC,KAAA,EAAO,MAAA,EAAQ,OAAO,EAAC;AAC5B,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACzB,IAAA,IAAI,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,GAAA,KAAQ,OAAA,EAAS;AACpC,MAAA,MAAM,IAAI,UAAU,CAAA,yBAAA,EAA4B,IAAA,CAAK,GAAG,CAAA,WAAA,EAAc,IAAA,CAAK,GAAG,CAAA,0BAAA,CAA4B,CAAA;AAAA,IAC5G;AACA,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AACF,MAAA,UAAA,GAAaC,uBAAA,CAAiB,KAAK,aAAa,CAAA;AAAA,IAClD,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,yBAAA,EAA4B,IAAA,CAAK,GAAG,CAAA,gCAAA,EAAoC,IAAc,OAAO,CAAA,CAAA;AAAA,OAC/F;AAAA,IACF;AACA,IAAA,IAAI,UAAA,CAAW,sBAAsB,IAAA,EAAM;AACzC,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,yBAAA,EAA4B,IAAA,CAAK,GAAG,CAAA,2BAAA,CAA6B,CAAA;AAAA,IACvF;AACA,IAAA,MAAM,GAAA,GAAM,KAAA,CAAMC,sBAAA,CAAgB,UAAU,CAAC,CAAA;AAC7C,IAAA,IAAI,GAAA,CAAI,QAAQ,OAAA,EAAS;AACvB,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,yBAAA,EAA4B,IAAA,CAAK,GAAG,gBAAgB,MAAA,CAAO,GAAA,CAAI,GAAG,CAAC,CAAA,sBAAA,CAAwB,CAAA;AAAA,IACjH;AAGA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,UAAA,CAAW,GAAG,CAAA;AACtC,IAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,IAAU,QAAA,EAAU,UAAA,EAAY,SAAA,EAAW,UAAA,CAAW,GAAA,EAAK,GAAG,CAAA,EAAE;AAAA,EAC7F,CAAC,CAAA;AACH;AAEA,IAAM,WAAA,GAAc,oOAAA;AAIb,SAAS,iBAAiB,GAAA,EAAkC;AAGjE,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAKvD,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAuB;AAC5C,EAAA,IAAI,UAAA,GAA0C,IAAA;AAE9C,EAAA,SAAS,aAAA,CAAc,KAAa,GAAA,EAAyC;AAC3E,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,IAAA,MAAM,MAAMD,uBAAA,CAAiB,EAAE,KAAK,GAAA,EAAc,MAAA,EAAQ,OAAO,CAAA;AACjE,IAAA,QAAA,CAAS,GAAA,CAAI,KAAK,GAAG,CAAA;AACrB,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,eAAe,kBAAA,GAA2C;AACxD,IAAA,MAAM,EAAE,YAAW,GAAIE,0BAAA,CAAoB,MAAM,EAAE,UAAA,EAAY,cAAc,CAAA;AAC7E,IAAA,MAAM,UAAA,GAAa,MAAM,UAAU,CAAA;AACnC,IAAA,MAAM,GAAA,GAAM,WAAW,UAAU,CAAA;AACjC,IAAA,MAAM,GAAA,GAAM;AAAA,MACV,GAAA;AAAA,MACA,GAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAW,UAAA,CAAW,UAAA,EAAY,GAAG,CAAA;AAAA,MACrC,UAAA;AAAA,MACA,MAAA,EAAQ;AAAA,KACV;AACA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,OAAO,GAAG,CAAA;AAAA,IACxC,SAAS,GAAA,EAAK;AAKZ,MAAA,IAAK,GAAA,CAA0B,IAAA,KAAS,IAAA,EAAO,MAAM,GAAA;AACrD,MAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,MAAA,CAAO,IAAI,OAAA,CAAQ,EAAE,KAAK,CAAA;AACrD,MAAA,IAAI,CAAC,UAAU,MAAM,GAAA;AACrB,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,aAAA,GAAgB;AACpB,MAAA,MAAM,SAAS,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,QAAQ,CAAA;AAC3D,MAAA,IAAI,MAAA,EAAQ,OAAO,EAAE,GAAA,EAAK,MAAA,CAAO,KAAK,GAAA,EAAK,OAAA,EAAS,UAAA,EAAY,MAAA,CAAO,UAAA,EAAW;AAClF,MAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,QAAA,MAAM,IAAI,MAAM,2FAA2F,CAAA;AAAA,MAC7G;AACA,MAAA,IAAI,CAAC,GAAA,CAAI,OAAA,CAAQ,cAAc,MAAM,IAAI,MAAM,WAAW,CAAA;AAI1D,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,QAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,CAAA,CAAE,IAAA,CAAK,EAAE,SAAA,EAAW,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,CAAA,IACvF,OAAO,UAAA,KAAe,kBAAA,EAAmB,CAAE,OAAA,CAAQ,MAAM;AAAE,QAAA,UAAA,GAAa,IAAA;AAAA,MAAM,CAAC,CAAA,CAAA;AACpF,MAAA,OAAO,EAAE,GAAA,EAAK,GAAA,CAAI,GAAA,EAAK,GAAA,EAAK,OAAA,EAAS,UAAA,EAAY,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,GAAA,CAAI,UAAU,CAAA,EAAE;AAAA,IAC1F,CAAA;AAAA,IAEA,MAAM,IAAA,GAAO;AACX,MAAA,IAAI,WAAW,MAAA,EAAQ;AAGrB,QAAA,OAAO,EAAE,MAAM,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA,EAAE;AAAA,MACpD;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,MAAA,CAAO,IAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,EAAE,GAAA,EAAK,CAAC,UAAU,UAAU,CAAA,EAAE,EAAG,CAAA,CAC/E,IAAA,CAAK,EAAE,SAAA,EAAW,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,CAAA;AAChC,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,IAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,CAAE,WAAW,GAAA,EAAK,CAAA,CAAE,KAAK,GAAA,EAAK,CAAA,CAAE,KAAK,GAAA,EAAK,KAAA,GAAQ,CAAA,EAAE;AAAA,IAC3F;AAAA,GACF;AACF;;;ACxHA,IAAM,QAAA,GAAW,GAAA;AACjB,IAAM,YAAA,GAAe,EAAA;AAErB,SAAS,WAAW,SAAA,EAA4B;AAC9C,EAAA,MAAM,CAAA,GAAI,OAAO,SAAA,KAAc,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,GAAI,YAAA;AAChG,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,CAAA;AAClB,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA;AAC7B;AAEA,SAAS,UAAU,SAAA,EAA4B;AAC7C,EAAA,MAAM,CAAA,GAAI,OAAO,SAAA,KAAc,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA;AAChG,EAAA,OAAO,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA;AACrB;AASA,SAAS,SAAS,QAAA,EAAyB;AACzC,EAAA,OAAO,IAAI,KAAA,CAAM,CAAA,gDAAA,EAAmD,QAAQ,CAAA,CAAA,CAAG,CAAA;AACjF;AAOO,SAAS,eAAe,GAAA,EAAmC;AAChE,EAAA,OAAO;AAAA,IACL,UAAU,GAAA,CAAI,QAAA;AAAA,IACd,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,MAAM,GAAA,CAAI,IAAA;AAAA;AAAA;AAAA;AAAA,IAIV,YAAA,EAAc,IAAI,YAAA,IAAgB,QAAA;AAAA,IAClC,GAAI,IAAI,WAAA,GAAc,EAAE,aAAa,GAAA,CAAI,WAAA,KAAgB,EAAC;AAAA,IAC1D,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA;AAAA,IAC5B,cAAc,CAAC,GAAI,GAAA,CAAI,YAAA,IAAgB,EAAG,CAAA;AAAA,IAC1C,eAAe,CAAC,GAAI,GAAA,CAAI,aAAA,IAAiB,EAAG,CAAA;AAAA,IAC5C,kBAAkB,CAAC,GAAI,GAAA,CAAI,gBAAA,IAAoB,EAAG,CAAA;AAAA,IAClD,UAAU,EAAE,GAAK,GAAA,CAAI,QAAA,IAAY,EAAC,EAAsB;AAAA,IACxD,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,WAAW,GAAA,CAAI;AAAA,GACjB;AACF;AAoBA,SAAS,kBAAkB,KAAA,EAAwB;AACjD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,EAAO;AACvC,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,oDAAA,EAAuD,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,EACrG;AACA,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,IAAI,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,kDAAA,EAAqD,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EACnF;AACA,EAAA,MAAM,QAAA,GAAW,IAAI,QAAA,KAAa,WAAA,IAAe,IAAI,QAAA,KAAa,WAAA,IAAe,IAAI,QAAA,KAAa,OAAA;AAClG,EAAA,IAAI,IAAI,QAAA,KAAa,QAAA,IAAY,EAAE,GAAA,CAAI,QAAA,KAAa,WAAW,QAAA,CAAA,EAAW;AACxE,IAAA,MAAM,IAAI,SAAA;AAAA,MACR,yFAAyF,KAAK,CAAA,CAAA;AAAA,KAChG;AAAA,EACF;AAIA,EAAA,IAAI,IAAI,IAAA,EAAM;AACZ,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,sDAAA,EAAyD,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EACvF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,mBAAmB,KAAA,EAA0B;AACpD,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,UAAU,qDAAqD,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,KAAA,CAAM,IAAI,iBAAiB,CAAA;AACpC;AAUA,SAAS,YAAA,CAAa,KAAsB,KAAA,EAA0B;AACpE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,UAAU,gEAAgE,CAAA;AAAA,EACtF;AACA,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,IAAI,OAAO,OAAO,QAAA,IAAY,CAAC,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACrD,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,oCAAA,EAAuC,MAAA,CAAO,EAAE,CAAC,CAAA,+CAAA;AAAA,OACnD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAI,KAAkB,CAAA;AAChC;AAGA,SAAS,eAAA,CAAgB,KAAsB,KAAA,EAA0B;AACvE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACvD,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,GAAA,CAAI,UAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA;AAC7D,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,UAAU,2EAA2E,CAAA;AAAA,EACjG;AACA,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA,EAAG;AAC/C,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,uCAAA,EAA0C,MAAA,CAAO,EAAE,CAAC,CAAA,qCAAA;AAAA,OACtD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAI,KAAkB,CAAA;AAChC;AAEA,SAAS,WAAW,KAAA,EAAwB;AAC1C,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,MAAK,EAAG;AAC9C,IAAA,MAAM,IAAI,UAAU,0FAAqF,CAAA;AAAA,EAC3G;AACA,EAAA,OAAO,MAAM,IAAA,EAAK;AACpB;AAMA,eAAe,oBAAA,CACb,GAAA,EACA,MAAA,EACA,EAAA,EACoC;AACpC,EAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,UAAA;AAAA,IACjC,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAK;AAAA,IAC7B,EAAE,MAAM,EAAE,SAAA,sBAAe,IAAA,EAAK,EAAG,SAAA,EAAW,EAAA,EAAG;AAAE,GACnD;AACA,EAAA,OAAO,EAAE,aAAA,EAAe,GAAA,CAAI,aAAA,IAAiB,CAAA,EAAE;AACjD;AAMA,eAAe,oBAAA,CACb,KACA,MAAA,EACiB;AACjB,EAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,UAAA;AAAA,IACjC,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAK;AAAA,IAC7B,EAAE,IAAA,EAAM,EAAE,2BAAW,IAAI,IAAA,IAAO;AAAE,GACpC;AACA,EAAA,OAAO,IAAI,aAAA,IAAiB,CAAA;AAC9B;AAMO,SAAS,iBAAiB,GAAA,EAAkC;AACjE,EAAA,OAAO;AAAA,IACL,MAAM,OAAO,IAAA,EAAgD;AAC3D,MAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACrC,QAAA,MAAM,IAAI,UAAU,yDAAyD,CAAA;AAAA,MAC/E;AACA,MAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA;AACjC,MAAA,MAAM,YAAA,GAAe,kBAAA,CAAmB,IAAA,CAAK,YAAY,CAAA;AACzD,MAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,GAAA,EAAK,IAAA,CAAK,aAAa,CAAA;AAC1D,MAAA,MAAM,gBAAA,GAAmB,eAAA,CAAgB,GAAA,EAAK,IAAA,CAAK,gBAAgB,CAAA;AAEnE,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,gBAAA,EAAiB;AACnD,MAAA,MAAM,eAAe,oBAAA,EAAqB;AAE1C,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,MAAA,CAAO;AAAA,QACzC,QAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA,EAAM,cAAA;AAAA,QACN,YAAA,EAAc,QAAA;AAAA,QACd,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA;AAAA;AAAA;AAAA,QAG7B,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,CAAO,YAAY,CAAA,EAAG,KAAA,EAAO,SAAA,EAAW,SAAA,kBAAW,IAAI,IAAA,IAAQ,CAAA;AAAA,QACjF,YAAA;AAAA,QACA,aAAA;AAAA,QACA,gBAAA;AAAA,QACA,QAAA,EAAU,IAAA,CAAK,QAAA,IAAY,EAAC;AAAA,QAC5B,MAAA,EAAQ;AAAA,OACT,CAAA;AAED,MAAA,MAAM,GAAA,CAAI,MAAM,EAAE,IAAA,EAAM,wBAAwB,KAAA,EAAO,OAAA,EAAS,UAAU,CAAA;AAE1E,MAAA,OAAO,EAAE,MAAA,EAAQ,cAAA,CAAe,GAAG,CAAA,EAAG,UAAU,YAAA,EAAa;AAAA,IAC/D,CAAA;AAAA,IAEA,MAAM,YAAA,CAAa,QAAA,EAAU,IAAA,GAAO,EAAC,EAA2B;AAC9D,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,OAAA,CAAQ,EAAE,UAAU,CAAA;AACxD,MAAA,IAAI,CAAC,GAAA,EAAK,MAAM,QAAA,CAAS,QAAQ,CAAA;AAMjC,MAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AACzB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,uBAAuB,QAAQ,CAAA,sGAAA;AAAA,SAEjC;AAAA,MACF;AAEA,MAAA,MAAM,WAAA,GAAa,OAAO,IAAA,CAAK,WAAA,KAAgB,YAAY,IAAA,CAAK,WAAA,GAAc,CAAA,GAAI,IAAA,CAAK,WAAA,GAAc,CAAA;AACrG,MAAA,MAAM,YAAY,IAAI,IAAA,CAAK,IAAA,CAAK,GAAA,KAAQ,WAAW,CAAA;AAOnD,MAAA,KAAA,MAAW,MAAA,IAAU,IAAI,OAAA,EAAS;AAChC,QAAA,MAAA,CAAO,YAAY,MAAA,CAAO,SAAA,IAAa,OAAO,SAAA,GAAY,SAAA,GAAY,OAAO,SAAA,GAAY,SAAA;AAAA,MAC3F;AAEA,MAAA,MAAM,eAAe,oBAAA,EAAqB;AAC1C,MAAA,GAAA,CAAI,QAAQ,IAAA,CAAK;AAAA,QACf,IAAA,EAAM,OAAO,YAAY,CAAA;AAAA,QACzB,KAAA,EAAO,KAAK,KAAA,IAAS,CAAA,QAAA,EAAA,qBAAe,IAAA,EAAK,EAAE,aAAa,CAAA,CAAA;AAAA,QACxD,SAAA,sBAAe,IAAA;AAAK,OACrB,CAAA;AACD,MAAA,GAAA,CAAI,aAAa,SAAS,CAAA;AAC1B,MAAA,MAAM,IAAI,IAAA,EAAK;AAEf,MAAA,GAAA,CAAI,KAAA,CAAM,EAAE,IAAA,EAAM,6BAAA,EAA+B,UAAU,CAAA;AAC3D,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,6BAAA;AAAA,QACN,KAAA,EAAO,OAAA;AAAA,QACP,QAAA;AAAA,QACA,IAAA,EAAM,EAAE,WAAA,EAAa,SAAA;AAAU,OAChC,CAAA;AAED,MAAA,OAAO,EAAE,MAAA,EAAQ,cAAA,CAAe,GAAG,CAAA,EAAG,UAAU,YAAA,EAAa;AAAA,IAC/D,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,QAAA,EAAU,KAAA,EAA8B;AACnD,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,OAAA,CAAQ,EAAE,UAAU,CAAA;AACxD,MAAA,IAAI,CAAC,GAAA,EAAK,MAAM,QAAA,CAAS,QAAQ,CAAA;AAIjC,MAAA,IAAI,MAAM,IAAA,KAAS,MAAA,MAAe,IAAA,GAAO,UAAA,CAAW,MAAM,IAAI,CAAA;AAC9D,MAAA,IAAI,MAAM,YAAA,KAAiB,MAAA,MAAe,YAAA,GAAe,kBAAA,CAAmB,MAAM,YAAY,CAAA;AAC9F,MAAA,IAAI,KAAA,CAAM,kBAAkB,MAAA,EAAW,GAAA,CAAI,gBAAgB,YAAA,CAAa,GAAA,EAAK,MAAM,aAAa,CAAA;AAChG,MAAA,IAAI,KAAA,CAAM,qBAAqB,MAAA,EAAW;AACxC,QAAA,GAAA,CAAI,gBAAA,GAAmB,eAAA,CAAgB,GAAA,EAAK,KAAA,CAAM,gBAAgB,CAAA;AAAA,MACpE;AACA,MAAA,IAAI,KAAA,CAAM,QAAA,KAAa,MAAA,EAAW,GAAA,CAAI,WAAW,KAAA,CAAM,QAAA;AACvD,MAAA,IAAI,MAAM,OAAA,KAAY,MAAA,MAAe,OAAA,GAAU,OAAA,CAAQ,MAAM,OAAO,CAAA;AAEpE,MAAA,MAAM,IAAI,IAAA,EAAK;AACf,MAAA,MAAM,GAAA,CAAI,MAAM,EAAE,IAAA,EAAM,wBAAwB,KAAA,EAAO,OAAA,EAAS,UAAU,CAAA;AAC1E,MAAA,OAAO,eAAe,GAAG,CAAA;AAAA,IAC3B,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,KAAA,GAAQ,EAAC,EAAG;AAGrB,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,KAAK,CAAA;AACpC,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA;AACjC,MAAA,MAAM,SAAiB,EAAC;AACxB,MAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,MAAA,CAAO,MAAA,GAAS,KAAA,CAAM,MAAA;AAExC,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,IAAA,CAAK,MAAM,EAC7C,IAAA,CAAK,EAAE,WAAW,EAAA,EAAI,EACtB,IAAA,CAAK,IAAI,EACT,KAAA,CAAM,KAAK,EACX,IAAA,EAAuB;AAE1B,MAAA,OAAO,EAAE,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,cAAc,GAAG,KAAA,EAAM;AAAA,IAClD,CAAA;AAAA,IAEA,MAAM,IAAI,QAAA,EAAU;AAClB,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,QAAA,EAAU,CAAA,CAAE,IAAA,EAA4B;AACtF,MAAA,OAAO,GAAA,GAAM,cAAA,CAAe,GAAG,CAAA,GAAI,IAAA;AAAA,IACrC,CAAA;AAAA,IAEA,MAAM,QAAQ,QAAA,EAAU;AACtB,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,OAAA,CAAQ,EAAE,UAAU,CAAA;AACxD,MAAA,IAAI,CAAC,GAAA,EAAK,MAAM,QAAA,CAAS,QAAQ,CAAA;AAEjC,MAAA,GAAA,CAAI,MAAA,GAAS,UAAA;AACb,MAAA,MAAM,IAAI,IAAA,EAAK;AAIf,MAAA,MAAM,EAAE,eAAc,GAAI,MAAM,qBAAqB,GAAA,EAAK,EAAE,QAAA,EAAS,EAAG,OAAO,CAAA;AAC/E,MAAA,MAAM,gBAAgB,MAAM,oBAAA,CAAqB,GAAA,EAAK,EAAE,UAAU,CAAA;AAGlE,MAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,EAAE,UAAU,CAAA;AAC7C,MAAA,MAAM,IAAI,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,EAAE,UAAU,CAAA;AAIhD,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,uBAAA;AAAA,QACN,KAAA,EAAO,OAAA;AAAA,QACP,QAAA;AAAA,QACA,IAAA,EAAM,EAAE,aAAA,EAAe,aAAA;AAAc,OACtC,CAAA;AAED,MAAA,OAAO,EAAE,eAAe,aAAA,EAAc;AAAA,IACxC;AAAA,GACF;AACF;AAaA,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,IAAI;AACF,IAAA,OAAO,kBAAA,CAAmB,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA;AAAA,EACrD,CAAA,CAAA,MAAQ;AAGN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AASA,SAAS,gBAAgB,GAAA,EAAwC;AAC/D,EAAA,MAAM,MAAA,GAAS,IAAI,OAAA,EAAS,aAAA;AAC5B,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA,EAAG;AACzD,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,EAAG,QAAQ,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA;AAE7E,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,MAAM,QAAA,GAAW,cAAc,GAAA,GAAM,CAAA,GAAI,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AACxE,IAAA,MAAM,MAAA,GAAS,MAAM,CAAA,GAAI,EAAA,GAAK,cAAc,OAAA,CAAQ,KAAA,CAAM,GAAA,GAAM,CAAC,CAAC,CAAA;AAGlE,IAAA,OAAO,EAAE,UAAU,YAAA,EAAc,MAAA,KAAW,KAAK,IAAA,GAAO,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,EACjF;AAEA,EAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,EAAA,IAAI,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,IAAY,KAAK,SAAA,EAAW;AACxD,IAAA,OAAO;AAAA,MACL,UAAU,IAAA,CAAK,SAAA;AAAA,MACf,YAAA,EAAc,OAAO,IAAA,CAAK,aAAA,KAAkB,YAAY,IAAA,CAAK,aAAA,GACzD,KAAK,aAAA,GACL,IAAA;AAAA,MACJ,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAUA,SAAS,YAAY,QAAA,EAA+B;AAClD,EAAA,OAAO,IAAI,UAAA,CAAW,GAAA,EAAK,gBAAA,EAAkB,8BAAA,EAAgC;AAAA;AAAA,IAE3E,SAAS,QAAA,GAAW,EAAE,kBAAA,EAAoB,sCAAA,KAA2C;AAAC,GACvF,CAAA;AACH;AAqBA,eAAsB,kBAAA,CACpB,KACA,GAAA,EACyB;AACzB,EAAA,MAAM,KAAA,GAAQ,gBAAgB,GAAG,CAAA;AACjC,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,QAAA,QAAgB,WAAA,CAAY,OAAA,CAAQ,KAAA,EAAO,QAAQ,CAAC,CAAA;AAEzE,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,CAAA;AAC3E,EAAA,IAAI,CAAC,UAAU,MAAA,CAAO,MAAA,KAAW,UAAU,MAAM,WAAA,CAAY,MAAM,QAAQ,CAAA;AAE3E,EAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAK5B,IAAA,IAAI,MAAM,YAAA,KAAiB,IAAA,EAAM,MAAM,WAAA,CAAY,MAAM,QAAQ,CAAA;AACjE,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAM,YAAA,KAAiB,IAAA,EAAM,MAAM,WAAA,CAAY,MAAM,QAAQ,CAAA;AAEjE,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,IAAI,OAAA;AACJ,EAAA,KAAA,MAAW,MAAA,IAAU,OAAO,OAAA,EAAS;AAInC,IAAA,IAAI,OAAO,SAAA,IAAa,MAAA,CAAO,SAAA,CAAU,OAAA,MAAa,GAAA,EAAK;AAG3D,IAAA,IAAI,SAAA,CAAU,OAAO,KAAA,CAAM,YAAY,GAAG,MAAA,CAAO,IAAI,GAAG,OAAA,GAAU,MAAA;AAAA,EACpE;AACA,EAAA,IAAI,CAAC,OAAA,EAAS,MAAM,WAAA,CAAY,MAAM,QAAQ,CAAA;AAK9C,EAAA,MAAM,MAAA,uBAAa,IAAA,EAAK;AACxB,EAAA,OAAA,CAAQ,UAAA,GAAa,MAAA;AACrB,EAAA,MAAM,GAAA,CAAI,OAAO,MAAA,CAAO,SAAA;AAAA,IACtB,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,cAAA,EAAgB,QAAQ,IAAA,EAAK;AAAA,IAC1D,EAAE,IAAA,EAAM,EAAE,sBAAA,EAAwB,QAAO;AAAE,GAC7C;AAEA,EAAA,OAAO,MAAA;AACT;AAOA,SAAS,mBAAA,CAAoB,KAAsB,GAAA,EAA4B;AAI7E,EAAA,OAAO,GAAA,CAAI,GAAA,CAAI,CAAC,EAAA,KAAO,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,IAAK,EAAE,EAAA,EAAI,KAAA,EAAO,IAAI,CAAA;AACpE;AAEO,SAAS,gBAAgB,GAAA,EAAiC;AAC/D,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,KAAA,EAAO;AAChB,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,EAAO,KAAK,CAAA;AACrC,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AAElC,MAAA,MAAM,MAAA,GAAiB,EAAE,SAAA,EAAW,IAAA,EAAK;AACzC,MAAA,IAAI,KAAA,EAAO,MAAA,KAAW,MAAA,EAAW,MAAA,CAAO,SAAS,KAAA,CAAM,MAAA;AACvD,MAAA,IAAI,KAAA,EAAO,QAAA,KAAa,MAAA,EAAW,MAAA,CAAO,WAAW,KAAA,CAAM,QAAA;AAE3D,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAM,IAAA,CAAK,MAAM,EAC9C,IAAA,CAAK,EAAE,WAAW,EAAA,EAAI,EACtB,IAAA,CAAK,IAAI,EACT,KAAA,CAAM,KAAK,EACX,IAAA,EAAsB;AAEzB,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,IAAI,KAAA,EAAM;AAInD,MAAA,MAAM,SAAA,GAAY,CAAC,GAAG,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,CAAC,CAAC,CAAA;AAC5D,MAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,MAAA,CAAO,OAAO,IAAA,CAAK,EAAE,QAAA,EAAU,EAAE,GAAA,EAAK,SAAA,EAAU,EAAG,EAC1E,IAAA,EAAuB;AAC1B,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,QAAA,EAAU,cAAA,CAAe,CAAC,CAAC,CAAC,CAAC,CAAA;AAIxE,MAAA,MAAM,YAAA,uBAAmB,GAAA,EAA4B;AACrD,MAAA,MAAM,QAAwB,EAAC;AAE/B,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AACtC,QAAA,MAAM,OAAA,GAAwB;AAAA,UAC5B,EAAA,EAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,UACpB,MAAA,EAAQ,SACJ,EAAE,QAAA,EAAU,OAAO,QAAA,EAAU,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,QAAA,EAAU,MAAA,CAAO,UAAS,GAG1E,EAAE,UAAU,KAAA,CAAM,QAAA,EAAU,MAAM,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,EAAC,EAAE;AAAA,UACnE,QAAQ,mBAAA,CAAoB,GAAA,EAAK,KAAA,CAAM,MAAA,IAAU,EAAE,CAAA;AAAA,UACnD,WAAW,KAAA,CAAM,SAAA;AAAA,UACjB,GAAI,MAAM,UAAA,GAAa,EAAE,YAAY,KAAA,CAAM,UAAA,KAAe;AAAC,SAC7D;AAIA,QAAA,IAAI,GAAA,CAAI,YAAA,IAAgB,KAAA,CAAM,SAAA,EAAW;AACvC,UAAA,MAAM,QAAA,GAAW,GAAG,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA,EAAI,MAAM,QAAQ,CAAA,CAAA;AAC1D,UAAA,IAAI,SAAA,GAAY,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA;AACzC,UAAA,IAAI,CAAC,SAAA,EAAW;AAId,YAAA,MAAM,IAAA,GAAO,EAAE,EAAA,EAAI,KAAA,CAAM,MAAA,EAAO;AAChC,YAAA,SAAA,GAAY,MAAA,GACR,MAAM,GAAA,CAAI,YAAA,CAAa,KAAK,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,MAAM,MAAA,IAAU,EAAC,EAAG,IACxE,EAAC;AACL,YAAA,YAAA,CAAa,GAAA,CAAI,UAAU,SAAS,CAAA;AAAA,UACtC;AACA,UAAA,OAAA,CAAQ,UAAU,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,KAAA,CAAM,SAAS,CAAA,IAG3D,EAAE,EAAA,EAAI,KAAA,CAAM,SAAA,EAAW,KAAA,EAAO,MAAM,SAAA,EAAU;AAAA,QACrD;AAEA,QAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAAA,MACpB;AAEA,MAAA,OAAO,EAAE,OAAO,KAAA,EAAM;AAAA,IACxB,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,OAAA,EAAS,IAAA,GAAO,EAAC,EAAG;AAC/B,MAAA,MAAM,EAAA,GAAK,KAAK,EAAA,IAAM,OAAA;AACtB,MAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,SAAS,OAAO,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAIvE,MAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAE,eAAe,CAAA,EAAE;AAEtC,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA;AAC9C,MAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,QAAA,KAAA,CAAM,SAAA,uBAAgB,IAAA,EAAK;AAC3B,QAAA,KAAA,CAAM,SAAA,GAAY,EAAA;AAClB,QAAA,MAAM,MAAM,IAAA,EAAK;AAAA,MACnB;AAIA,MAAA,MAAM,aAAA,GAAgB,MAAM,oBAAA,CAAqB,GAAA,EAAK,EAAE,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA;AAE5E,MAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,QAAA,GAAA,CAAI,KAAA,CAAM;AAAA,UACR,IAAA,EAAM,qBAAA;AAAA,UACN,QAAQ,KAAA,CAAM,MAAA;AAAA,UACd,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,UACzB,GAAI,MAAM,SAAA,GAAY,EAAE,WAAW,KAAA,CAAM,SAAA,KAAc,EAAC;AAAA,UACxD,QAAQ,KAAA,CAAM;AAAA,SACf,CAAA;AACD,QAAA,MAAM,IAAI,KAAA,CAAM;AAAA,UACd,IAAA,EAAM,qBAAA;AAAA,UACN,KAAA,EAAO,EAAA;AAAA,UACP,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,UACd,SAAS,KAAA,CAAM,GAAA;AAAA,UACf,IAAA,EAAM,EAAE,aAAA;AAAc,SACvB,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,aAAA,EAAc;AAAA,IACzB;AAAA,GACF;AACF;AAYA,SAAS,YAAY,MAAA,EAA+B;AAClD,EAAA,MAAM,GAAA,GAAM,OAAO,MAAM,CAAA;AACzB,EAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,QAAA,CAAS,GAAG,KAAK,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,IAAA;AAC7D,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,eAAe,GAAA,EAAgC;AAC7D,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYL,MAAM,OAAO,MAAA,EAAQ;AACnB,MAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,MAAA,CAAO,MAAM,UAAA,CAAW,EAAE,QAAQ,CAAA;AACjE,MAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,MAAA,CAAO,MAAM,UAAA,CAAW,EAAE,QAAQ,CAAA;AACjE,MAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,EAAE,QAAQ,CAAA;AAC3C,MAAA,MAAM,IAAI,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,EAAE,QAAQ,CAAA;AAK9C,MAAA,MAAM,GAAA,GAAM,YAAY,MAAM,CAAA;AAC9B,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,MAAM,GAAA,CAAI,OAAO,MAAA,CAAO,UAAA;AAAA,UACtB,EAAE,CAAC,CAAA,iBAAA,EAAoB,GAAG,EAAE,GAAG,EAAE,OAAA,EAAS,IAAA,EAAK,EAAE;AAAA,UACjD,EAAE,QAAQ,EAAE,CAAC,oBAAoB,GAAG,CAAA,CAAE,GAAG,EAAA,EAAG;AAAE,SAChD;AAAA,MACF;AAEA,MAAA,MAAM,IAAI,MAAA,CAAO,KAAA,CAAM,UAAA,CAAW,EAAE,QAAQ,CAAA;AAE5C,MAAA,MAAM,MAAA,GAAS,aAAa,YAAA,IAAgB,CAAA;AAC5C,MAAA,MAAM,MAAA,GAAS,aAAa,YAAA,IAAgB,CAAA;AAK5C,MAAA,MAAM,GAAA,CAAI,KAAA,CAAM,EAAE,IAAA,EAAM,sBAAA,EAAwB,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,EAAG,CAAA;AAE3F,MAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAAA,IAC1B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,MAAM,SAAA,CAAU,MAAA,EAAQ,IAAA,GAAO,EAAC,EAAG;AAIjC,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,MAAA,CAAO,MAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,MAAM,CAAA,CACjE,KAAA,CAAM,QAAQ,EACd,IAAA,EAAsB;AAEzB,MAAA,MAAM,EAAE,eAAc,GAAI,MAAM,qBAAqB,GAAA,EAAK,EAAE,MAAA,EAAO,EAAG,QAAQ,CAAA;AAC9E,MAAA,MAAM,gBAAgB,MAAM,oBAAA,CAAqB,GAAA,EAAK,EAAE,QAAQ,CAAA;AAEhE,MAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,EAAE,QAAQ,CAAA;AAC3C,MAAA,MAAM,IAAI,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,EAAE,QAAQ,CAAA;AAE9C,MAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,QAAA,GAAA,CAAI,KAAA,CAAM;AAAA,UACR,IAAA,EAAM,qBAAA;AAAA,UACN,MAAA;AAAA,UACA,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,UACzB,GAAI,MAAM,SAAA,GAAY,EAAE,WAAW,KAAA,CAAM,SAAA,KAAc,EAAC;AAAA,UACxD,QAAQ,KAAA,CAAM;AAAA,SACf,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,IAAI,KAAA,CAAM;AAAA,QACd,IAAA,EAAM,2BAAA;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,MAAA;AAAA,QACA,IAAA,EAAM,EAAE,aAAA,EAAe,aAAA,EAAe,GAAI,IAAA,CAAK,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,EAAC;AAAG,OACvF,CAAA;AAED,MAAA,OAAO,EAAE,eAAe,aAAA,EAAc;AAAA,IACxC;AAAA,GACF;AACF;AAMO,SAAS,kBAAkB,GAAA,EAAmC;AACnE,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASL,MAAM,OAAA,CAAQ,MAAA,EAAQ,SAAA,EAAW;AAC/B,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAW,MAAM,CAAA,CAC5E,KAAA,CAAM,QAAQ,EACd,IAAA,EAAsB;AAEzB,MAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,oBAAA,CAAqB,KAAK,EAAE,MAAA,EAAQ,SAAA,EAAU,EAAG,QAAQ,CAAA;AAGzF,MAAA,MAAM,gBAAgB,MAAM,oBAAA,CAAqB,KAAK,EAAE,MAAA,EAAQ,WAAW,CAAA;AAC3E,MAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,WAAW,EAAE,MAAA,EAAQ,WAAW,CAAA;AAEtD,MAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,QAAA,GAAA,CAAI,KAAA,CAAM;AAAA,UACR,IAAA,EAAM,qBAAA;AAAA,UACN,MAAA;AAAA,UACA,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,UACzB,SAAA;AAAA,UACA,QAAQ,KAAA,CAAM;AAAA,SACf,CAAA;AACD,QAAA,MAAM,IAAI,KAAA,CAAM;AAAA,UACd,IAAA,EAAM,qBAAA;AAAA,UACN,KAAA,EAAO,QAAA;AAAA,UACP,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,MAAA;AAAA,UACA,SAAS,KAAA,CAAM,GAAA;AAAA,UACf,IAAA,EAAM,EAAE,SAAA,EAAW,MAAA,EAAQ,0BAAA;AAA2B,SACvD,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,eAAe,aAAA,EAAc;AAAA,IACxC;AAAA,GACF;AACF;;;ACvvBA,IAAM,eAAA,GAAkB,GAAA;AAGxB,IAAM,uBAAA,GAA0B,GAAA;AAQhC,SAAS,OAAO,WAAA,EAA0C;AACxD,EAAA,OAAO,IAAI,mBAAA,CAAoB,gBAAA,EAAkB,WAAW,CAAA;AAC9D;AAGO,SAAS,cAAc,QAAA,EAA2B;AACvD,EAAA,OAAO,cAAA,CAAe,KAAK,QAAQ,CAAA;AACrC;AAMA,SAAS,WAAA,CAAY,OAAuB,GAAA,EAAmB;AAC7D,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,QAAA,CAAS,WAAA,EAAY;AAC1C,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS;AAG1B,IAAA,IAAI,GAAA,CAAI,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,OAAO,KAAA;AACnC,IAAA,IAAI,QAAA,KAAa,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA;AACnC,IAAA,OAAO,KAAK,UAAA,IAAc,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAAA,EAC7D,CAAC,CAAA;AACH;AAQO,SAAS,kBAAA,CAAmB,KAAsB,QAAA,EAAuB;AAC9E,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,IAAI,QAAQ,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,MAAA,CAAO,CAAA,+BAAA,EAAkC,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,GAAA,CAAI,aAAa,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAA,CAAO,CAAA,mDAAA,EAAsD,GAAA,CAAI,QAAQ,CAAA,EAAA,CAAI,CAAA;AAAA,EACrF;AAIA,EAAA,IAAI,GAAA,CAAI,QAAA,IAAY,GAAA,CAAI,QAAA,EAAU;AAChC,IAAA,MAAM,OAAO,4CAA4C,CAAA;AAAA,EAC3D;AAIA,EAAA,IAAI,IAAI,IAAA,EAAM;AACZ,IAAA,MAAM,OAAO,uCAAuC,CAAA;AAAA,EACtD;AACA,EAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,YAAA,EAAc,GAAG,CAAA,EAAG;AAC5C,IAAA,MAAM,MAAA,CAAO,CAAA,gBAAA,EAAmB,GAAA,CAAI,IAAI,CAAA,yCAAA,CAA2C,CAAA;AAAA,EACrF;AACA,EAAA,OAAO,GAAA;AACT;AAOA,IAAM,iBAAA,GAAoB,8CAAA;AAS1B,eAAe,UAAA,CAAW,KAAe,QAAA,EAAmC;AAC1E,EAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,MAAA,CAAO,uCAAuC,CAAA;AAE/D,EAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,WAAS;AACP,IAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,IAAA,IAAI,IAAA,EAAM;AACV,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,KAAA,IAAS,KAAA,CAAM,UAAA;AACf,IAAA,IAAI,QAAQ,QAAA,EAAU;AAGpB,MAAA,KAAK,OAAO,MAAA,EAAO;AACnB,MAAA,MAAM,MAAA,CAAO,CAAA,oCAAA,EAAuC,QAAQ,CAAA,MAAA,CAAQ,CAAA;AAAA,IACtE;AACA,IAAA,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,SAAS,MAAM,CAAA;AAC9C;AAQA,eAAe,aAAA,CACb,GAAA,EACA,GAAA,EACA,IAAA,EACuB;AACvB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,CAAI,QAAA,EAAS,EAAG;AAAA,MAChC,MAAA,EAAQ,KAAA;AAAA;AAAA;AAAA;AAAA,MAIR,QAAA,EAAU,QAAA;AAAA,MACV,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,kBAAA;AAAA,QACR,GAAI,IAAA,GAAO,EAAE,eAAA,EAAiB,IAAA,KAAS;AAAC,OAC1C;AAAA,MACA,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,KAAK,cAAc;AAAA,KACpD,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAQ,GAAA,EAA2B,IAAA;AACzC,IAAA,IAAI,IAAA,KAAS,cAAA,IAAkB,IAAA,KAAS,YAAA,EAAc;AACpD,MAAA,MAAM,MAAA,CAAO,CAAA,yCAAA,EAA4C,GAAA,CAAI,IAAA,CAAK,cAAc,CAAA,EAAA,CAAI,CAAA;AAAA,IACtF;AACA,IAAA,MAAM,MAAA,CAAO,CAAA,yCAAA,EAA6C,GAAA,EAAe,OAAA,IAAW,eAAe,CAAA,CAAE,CAAA;AAAA,EACvG;AAIA,EAAA,IAAI,IAAI,MAAA,KAAW,GAAA,EAAK,OAAO,EAAE,UAAU,IAAA,EAAK;AAEhD,EAAA,IAAI,GAAA,CAAI,MAAA,IAAU,GAAA,IAAO,GAAA,CAAI,SAAS,GAAA,EAAK;AACzC,IAAA,MAAM,MAAA;AAAA,MACJ,CAAA,8BAAA,EAAiC,IAAI,MAAM,CAAA,sFAAA;AAAA,KAE7C;AAAA,EACF;AACA,EAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,IAAA,MAAM,MAAA,CAAO,CAAA,iCAAA,EAAoC,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/D;AAEA,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AACvD,EAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,CAAK,WAAW,CAAA,EAAG;AACxC,IAAA,MAAM,MAAA,CAAO,CAAA,mDAAA,EAAsD,WAAA,IAAe,MAAM,CAAA,EAAA,CAAI,CAAA;AAAA,EAC9F;AAEA,EAAA,MAAM,OAAO,MAAM,UAAA,CAAW,GAAA,EAAK,GAAA,CAAI,KAAK,QAAQ,CAAA;AACpD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,OAAO,+CAA+C,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA,KAAW,YAAY,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClE,IAAA,MAAM,OAAO,mDAAmD,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,MAAA;AAAA,IACV,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,GAAI,EAAE,IAAA,EAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,KAAgB;AAAC,GAC/E;AACF;AAaA,SAAS,aAAA,CAAc,KAA8B,KAAA,EAAuB;AAC1E,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAK,CAAA;AACvB,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,MAAK,EAAG;AAC9C,IAAA,MAAM,MAAA,CAAO,CAAA,0BAAA,EAA6B,KAAK,CAAA,4BAAA,CAA8B,CAAA;AAAA,EAC/E;AACA,EAAA,OAAO,MAAM,IAAA,EAAK;AACpB;AASA,SAAS,gBAAA,CAAiB,KAA8B,KAAA,EAAmC;AACzF,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAK,CAAA;AACvB,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM,OAAO,MAAA;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,MAAK,EAAG;AAC9C,IAAA,MAAM,MAAA,CAAO,CAAA,0BAAA,EAA6B,KAAK,CAAA,kBAAA,CAAoB,CAAA;AAAA,EACrE;AACA,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,IAAI,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,MAAA,CAAO,CAAA,0BAAA,EAA6B,KAAK,CAAA,4BAAA,EAA+B,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EACxF;AACA,EAAA,IAAI,GAAA,CAAI,aAAa,QAAA,EAAU;AAC7B,IAAA,MAAM,OAAO,CAAA,0BAAA,EAA6B,KAAK,CAAA,sBAAA,EAAyB,GAAA,CAAI,QAAQ,CAAA,EAAA,CAAI,CAAA;AAAA,EAC1F;AACA,EAAA,OAAO,KAAA;AACT;AAOA,SAASC,oBAAmB,GAAA,EAAwC;AAClE,EAAA,MAAM,QAAQ,GAAA,CAAI,aAAA;AAClB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,OAAO,oEAAoE,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,EAAO;AACvC,MAAA,MAAM,OAAO,CAAA,gEAAA,EAAmE,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IAC1G;AACA,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,IAAI,IAAI,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,MAAA,CAAO,CAAA,mEAAA,EAAsE,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,IAC7F;AACA,IAAA,MAAM,QAAA,GAAW,IAAI,QAAA,KAAa,WAAA,IAAe,IAAI,QAAA,KAAa,WAAA,IAAe,IAAI,QAAA,KAAa,OAAA;AAClG,IAAA,IAAI,IAAI,QAAA,KAAa,QAAA,IAAY,EAAE,GAAA,CAAI,QAAA,KAAa,WAAW,QAAA,CAAA,EAAW;AACxE,MAAA,MAAM,MAAA;AAAA,QACJ,0GACqD,KAAK,CAAA,CAAA;AAAA,OAC5D;AAAA,IACF;AAGA,IAAA,IAAI,IAAI,IAAA,EAAM;AACZ,MAAA,MAAM,MAAA,CAAO,CAAA,uEAAA,EAA0E,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,IACjG;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;AASO,SAAS,wBAAA,CACd,GAAA,EACA,GAAA,EACA,GAAA,EACkB;AAClB,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,EAAK,WAAW,CAAA;AAC/C,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI;AACF,IAAA,WAAA,GAAc,IAAI,IAAI,QAAQ,CAAA;AAAA,EAChC,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,MAAA,CAAO,CAAA,oDAAA,EAAuD,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EACjF;AACA,EAAA,IAAI,WAAA,CAAY,IAAA,KAAS,GAAA,CAAI,IAAA,EAAM;AACjC,IAAA,MAAM,MAAA;AAAA,MACJ,CAAA,yCAAA,EAA4C,QAAQ,CAAA,8CAAA,EAChC,GAAA,CAAI,IAAI,CAAA,EAAA;AAAA,KAC9B;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,GAAA,CAAI,0BAAA;AACnB,EAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,MAAA,EAAQ;AAC7C,IAAA,MAAM,MAAA;AAAA,MACJ,CAAA,0EAAA,EACU,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAA,sCAAA;AAAA,KAClC;AAAA,EACF;AAKA,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,GAAA,EAAK,aAAa,CAAA;AAC7C,EAAA,MAAM,YAAA,GAAeA,oBAAmB,GAAG,CAAA;AAK3C,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,GAAA,CAAI,KAAK,aAAA,CAAc,MAAA,CAAO,CAAC,EAAA,KAAO,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAC,CAAC,CAAA;AACvF,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI,GAAA,CAAI,KAAA,KAAU,MAAA,IAAa,GAAA,CAAI,UAAU,IAAA,EAAM;AACjD,IAAA,aAAA,GAAgB,CAAC,GAAG,SAAS,CAAA;AAAA,EAC/B,CAAA,MAAO;AACL,IAAA,IAAI,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,EAAU;AACjC,MAAA,MAAM,OAAO,mEAAmE,CAAA;AAAA,IAClF;AACA,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,MAAM,KAAK,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAA;AAChE,IAAA,aAAA,GAAgB,CAAC,GAAG,SAAS,CAAA,CAAE,MAAA,CAAO,CAAC,EAAA,KAAO,SAAA,CAAU,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,MAAM,MAAA;AAAA,MACJ;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,GAAA,EAAK,UAAU,CAAA;AAChD,EAAA,MAAM,WAAA,GAAc,gBAAA,CAAiB,GAAA,EAAK,YAAY,CAAA;AACtD,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,EAAK,SAAS,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,EAAK,YAAY,CAAA;AACrD,EAAA,IAAI,OAAA,WAAkB,OAAA,GAAU,OAAA;AAChC,EAAA,IAAI,WAAA,WAAsB,WAAA,GAAc,WAAA;AACxC,EAAA,IAAI,MAAA,WAAiB,MAAA,GAAS,MAAA;AAC9B,EAAA,IAAI,UAAA,WAAqB,UAAA,GAAa,UAAA;AAEtC,EAAA,OAAO,EAAE,IAAA,EAAM,YAAA,EAAc,aAAA,EAAe,QAAA,EAAS;AACvD;AAMA,SAAS,eAAA,CAAgB,GAAA,EAAsB,GAAA,EAAa,OAAA,EAAuB;AACjF,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,GAAA,CAAI,IAAA;AAGzB,EAAA,IAAI,QAAA,CAAS,QAAQ,uBAAA,EAAyB;AAC5C,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,EAAK,CAAE,IAAA,EAAK;AACpC,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAM,QAAA,CAAS,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,EAChD;AACA,EAAA,QAAA,CAAS,GAAA,CAAI,KAAK,EAAE,KAAA,EAAO,KAAK,GAAA,EAAI,GAAI,eAAA,EAAiB,OAAA,EAAS,CAAA;AACpE;AAEA,SAAS,iBAAA,CAAkB,KAAsB,GAAA,EAA4B;AAC3E,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,IAAI,GAAG,CAAA;AACvC,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,IAAI,KAAA,CAAM,KAAA,IAAS,IAAA,CAAK,GAAA,EAAI,EAAG;AAC7B,IAAA,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA,CAAM,OAAA;AACf;AAEA,SAAS,OAAA,CAAQ,KAAsB,MAAA,EAAiC;AACtE,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,iBAAA,EAAmB,OAAA,EAAQ;AACpD,EAAA,IAAI,SAAA,KAAc,QAAW,OAAO,KAAA;AACpC,EAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA,GAAY,IAAI,IAAA,CAAK,UAAA;AAC3C;AAUA,eAAe,OAAA,CACb,GAAA,EACA,QAAA,EACA,GAAA,EACA,cACA,IAAA,EACyB;AACzB,EAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,gBAAA;AAAA,IAClC,EAAE,QAAA,EAAS;AAAA,IACX;AAAA,MACE,IAAA,EAAM;AAAA,QACJ,MAAM,YAAA,CAAa,IAAA;AAAA,QACnB,cAAc,YAAA,CAAa,YAAA;AAAA,QAC3B,eAAe,YAAA,CAAa,aAAA;AAAA;AAAA;AAAA,QAG5B,kBAAkB,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,QAC/C,UAAU,YAAA,CAAa,QAAA;AAAA,QACvB,aAAa,GAAA,CAAI,IAAA;AAAA,QACjB,iBAAA,sBAAuB,IAAA,EAAK;AAAA,QAC5B,GAAI,IAAA,GAAO,EAAE,YAAA,EAAc,IAAA,KAAS;AAAC,OACvC;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,QAAA;AAAA,QACN,YAAA,EAAc,MAAA;AAAA,QACd,OAAA,EAAS,KAAA;AAAA,QACT,SAAS,EAAC;AAAA,QACV,MAAA,EAAQ;AAAA;AACV,KACF;AAAA,IACA,EAAE,MAAA,EAAQ,IAAA,EAAM,cAAA,EAAgB,OAAA,EAAS,qBAAqB,KAAA;AAAM,IACpE,IAAA,EAAK;AAEP,EAAA,OAAO,GAAA;AACT;AAYA,eAAsB,iBAAA,CACpB,KACA,QAAA,EACyB;AACzB,EAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,GAAA,EAAK,QAAQ,CAAA;AAE5C,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,QAAA,EAAU,CAAA,CAAE,IAAA,EAAK;AACpE,EAAA,IAAI,QAAA,EAAU;AAIZ,IAAA,IAAI,QAAA,CAAS,WAAW,QAAA,EAAU;AAChC,MAAA,MAAM,MAAA,CAAO,CAAA,QAAA,EAAW,QAAQ,CAAA,aAAA,CAAe,CAAA;AAAA,IACjD;AAGA,IAAA,IAAI,QAAA,CAAS,YAAA,KAAiB,MAAA,EAAQ,OAAO,QAAA;AAC7C,IAAA,IAAI,OAAA,CAAQ,GAAA,EAAK,QAAQ,CAAA,EAAG,OAAO,QAAA;AAAA,EACrC;AAEA,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,GAAA,EAAK,GAAA,CAAI,IAAI,CAAA;AAClD,EAAA,IAAI,UAAA,EAAY,MAAM,MAAA,CAAO,UAAU,CAAA;AAEvC,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,UAAU,IAAA,EAAK,GAAI,MAAM,aAAA,CAAc,GAAA,EAAK,GAAA,EAAK,QAAA,EAAU,YAAY,CAAA;AAC/E,IAAA,IAAI,CAAC,QAAA,EAAU;AAGb,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,iBAAA,uBAAwB,IAAA,EAAK;AACtC,QAAA,MAAM,SAAS,IAAA,EAAK;AACpB,QAAA,OAAO,QAAA;AAAA,MACT;AACA,MAAA,MAAM,OAAO,oEAAoE,CAAA;AAAA,IACnF;AACA,IAAA,MAAM,YAAA,GAAe,wBAAA,CAAyB,GAAA,EAAK,GAAA,EAAK,QAAQ,CAAA;AAChE,IAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,KAAK,QAAA,EAAU,GAAA,EAAK,cAAc,IAAI,CAAA;AACnE,IAAA,GAAA,CAAI,MAAA,CAAO,KAAA,GAAQ,EAAE,QAAA,IAAY,kDAAkD,CAAA;AACnF,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAA,GAAU,GAAA,YAAe,mBAAA,GAC1B,GAAA,CAAI,eAAe,0CAAA,GACpB,0CAAA;AAIJ,IAAA,eAAA,CAAgB,GAAA,EAAK,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AACtC,IAAA,GAAA,CAAI,OAAO,IAAA,GAAO,EAAE,QAAA,EAAU,GAAA,IAAO,kDAAkD,CAAA;AACvF,IAAA,MAAM,GAAA,YAAe,mBAAA,GAAsB,GAAA,GAAM,MAAA,CAAO,OAAO,CAAA;AAAA,EACjE;AACF;;;ACjeO,SAAS,WAAW,GAAA,EAAmC;AAC5D,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,EAAC;AACrC,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,EAAA,IAAM,IAAI,KAAA,CAAM,KAAK,GAAG,IAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACtD,EAAA,OAAO,CAAC,GAAG,IAAI,CAAA;AACjB;AAUO,SAAS,cAAA,CACd,GAAA,EACA,SAAA,EACA,MAAA,EACU;AACV,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,MAAA,CAAO,aAAa,CAAA;AAC5C,EAAA,KAAA,MAAW,MAAM,SAAA,EAAW;AAC1B,IAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AAC3B,MAAA,MAAM,YAAA,CAAa,CAAA,eAAA,EAAkB,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IAC5C;AACA,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACpB,MAAA,MAAM,aAAa,CAAA,QAAA,EAAW,MAAA,CAAO,QAAQ,CAAA,4BAAA,EAA+B,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACnF;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAG,SAAS,CAAA;AACtB;AAqBO,SAAS,oBAAA,CAAqB,KAAsB,MAAA,EAAkC;AAC3F,EAAA,IAAI,CAAC,IAAI,aAAA,EAAe;AACtB,IAAA,MAAM,YAAA;AAAA,MACJ;AAAA,KAGF;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,MAAA,CAAO,aAAa,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAc,MAAA,CAAO,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAC,CAAA;AAChE,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,YAAA;AAAA,MACJ,CAAA,uCAAA,EAA0C,OAAO,QAAQ,CAAA,mDAAA,EAC1B,IAAI,aAAA,CAAc,IAAA,CAAK,GAAG,CAAC,CAAA,uFAAA;AAAA,KAE5D;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AASO,SAAS,cAAA,CACd,GAAA,EACA,GAAA,EACA,IAAA,GAAyC,EAAC,EACuD;AACjG,EAAA,MAAM,UAAU,IAAI,GAAA,CAAI,IAAA,CAAK,iBAAA,IAAqB,EAAE,CAAA;AACpD,EAAA,OAAO,GAAA,CAAI,GAAA,CAAI,CAAC,EAAA,KAAO;AAIrB,IAAA,MAAM,IAAA,GAAkB,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,IAAK,EAAM,KAAA,EAAO,EAAA,EAAG;AAClE,IAAA,OAAO;AAAA,MACL,EAAA;AAAA,MACA,KAAA,EAAO,KAAK,KAAA,IAAS,EAAA;AAAA,MACrB,GAAI,KAAK,WAAA,GAAc,EAAE,aAAa,IAAA,CAAK,WAAA,KAAgB,EAAC;AAAA,MAC5D,GAAI,IAAA,CAAK,SAAA,GAAY,EAAE,SAAA,EAAW,IAAA,KAAS,EAAC;AAAA,MAC5C,KAAA,EAAO,CAAC,OAAA,CAAQ,GAAA,CAAI,EAAE;AAAA,KACxB;AAAA,EACF,CAAC,CAAA;AACH;AAaO,SAAS,iBAAA,CACd,GAAA,EACA,SAAA,EACA,MAAA,EACU;AACV,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAGvD,EAAA,MAAM,OAAA,GAAU,OAAO,gBAAA,CAAiB,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,gBAAgB,CAAA,GAAI,QAAA;AAEpF,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,QAAA,GAAW,OAAO,gBAAA,CAAiB,CAAC,KAAK,GAAA,CAAI,SAAA,CAAU,CAAC,CAAA,EAAG,EAAA;AACjE,IAAA,OAAO,QAAA,GAAW,CAAC,QAAQ,CAAA,GAAI,EAAC;AAAA,EAClC;AAEA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,MAAM,SAAA,EAAW;AAC1B,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA,EAAG;AAErB,MAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,gBAAA,EAAkB,CAAA,kBAAA,EAAqB,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACxE;AACA,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACpB,MAAA,MAAM,IAAI,UAAA;AAAA,QACR,GAAA;AAAA,QACA,gBAAA;AAAA,QACA,CAAA,QAAA,EAAW,MAAA,CAAO,QAAQ,CAAA,+BAAA,EAAkC,EAAE,CAAA,CAAA;AAAA,OAChE;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,EACb;AACA,EAAA,OAAO,CAAC,GAAG,IAAI,CAAA;AACjB;;;AC5HA,SAAS,GAAA,CAAI,OAAgC,IAAA,EAAkC;AAC7E,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,CAAA;AACxB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAA,GAAS,IAAI,KAAA,GAAQ,MAAA;AACjE;AAGA,SAAS,IAAA,CAAK,OAAgC,IAAA,EAAwB;AACpE,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,CAAA;AACxB,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU,OAAO,QAAQ,CAAC,KAAK,IAAI,EAAC;AACzD,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,SAAU,EAAC;AACnC,EAAA,OAAO,KAAA,CAAM,OAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AAC/E;AAeA,eAAe,aAAA,CAAc,KAAsB,QAAA,EAA2C;AAC5F,EAAA,IAAI,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,aAAA,CAAc,QAAQ,CAAA,EAAG;AAC/C,IAAA,OAAO,iBAAA,CAAkB,KAAK,QAAQ,CAAA;AAAA,EACxC;AACA,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,QAAA,EAAU,CAAA,CAAE,IAAA,EAAK;AAClE,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,mBAAA,CAAoB,gBAAA,EAAkB,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,4BAAA,CACpB,KACA,KAAA,EAC+B;AAE/B,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,EAAO,WAAW,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,mBAAA,CAAoB,iBAAA,EAAmB,yBAAyB,CAAA;AAAA,EAC5E;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,GAAA,EAAK,QAAQ,CAAA;AAChD,EAAA,IAAI,MAAA,CAAO,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAM,IAAI,mBAAA,CAAoB,gBAAA,EAAkB,CAAA,QAAA,EAAW,QAAQ,CAAA,aAAA,CAAe,CAAA;AAAA,EACpF;AAEA,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,KAAA,EAAO,cAAc,CAAA;AAC7C,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,MAAM,IAAI,mBAAA,CAAoB,iBAAA,EAAmB,4BAA4B,CAAA;AAAA,EAC/E;AAOA,EAAA,IAAI,CAAC,qBAAA,CAAsB,MAAA,CAAO,YAAA,EAAc,WAAW,CAAA,EAAG;AAC5D,IAAA,MAAM,IAAI,mBAAA;AAAA,MACR,iBAAA;AAAA,MACA,8CAA8C,QAAQ,CAAA,CAAA;AAAA,KACxD;AAAA,EACF;AAGA,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAChC,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAc,WAAA,KAC1B,IAAI,qBAAA,CAAsB,IAAA,EAAM,WAAA,EAAa,WAAA,EAAa,KAAK,CAAA;AAEjE,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,EAAO,eAAe,CAAA;AAC/C,EAAA,IAAI,iBAAiB,MAAA,EAAQ;AAC3B,IAAA,MAAM,IAAI,qBAAA;AAAA,MACR,2BAAA;AAAA,MACA,wCAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAKA,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,KAAA,EAAO,gBAAgB,CAAA;AACjD,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,MAAM,IAAA,CAAK,mBAAmB,+CAA+C,CAAA;AAAA,EAC/E;AAIA,EAAA,IAAI,GAAA,CAAI,KAAA,EAAO,uBAAuB,CAAA,KAAM,MAAA,EAAQ;AAClD,IAAA,MAAM,IAAA,CAAK,mBAAmB,wCAAwC,CAAA;AAAA,EACxE;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI;AAIF,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,KAAA,EAAO,OAAO,CAAC,CAAA;AAChD,IAAA,MAAA,GAAS,SAAA,CAAU,SACf,cAAA,CAAe,GAAA,EAAK,WAAW,MAAM,CAAA,GACrC,oBAAA,CAAqB,GAAA,EAAK,MAAM,CAAA;AACpC,IAAA,SAAA,GAAY,kBAAkB,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,UAAU,GAAG,MAAM,CAAA;AAAA,EACpE,SAAS,GAAA,EAAK;AAGZ,IAAA,IAAI,GAAA,YAAe,YAAY,MAAM,IAAA,CAAK,IAAI,IAAA,EAAM,GAAA,CAAI,WAAA,IAAe,GAAA,CAAI,IAAI,CAAA;AAC/E,IAAA,MAAM,GAAA;AAAA,EACR;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,KAAA,EAAO,SAAS,CAAA;AACtC,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,MAAM,MAAA,GAAS,OAAO,SAAS,CAAA;AAC/B,IAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,IAAK,SAAS,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAA,CAAK,mBAAmB,0CAA0C,CAAA;AAAA,IAC1E;AACA,IAAA,MAAA,GAAS,MAAA;AAAA,EACX;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,IACvC,GAAI,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA,GAAI,EAAE,KAAA,EAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA,EAAE,GAAI,EAAC;AAAA,IAC5D,aAAA;AAAA,IACA,GAAI,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA,GAAI,EAAE,MAAA,EAAQ,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA,EAAE,GAAI,EAAC;AAAA,IAC/D,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW;AAAC,GAC3C;AACF;AAUA,eAAsB,0BAAA,CACpB,GAAA,EACA,SAAA,EACA,IAAA,EAC0B;AAC1B,EAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,MAAA,CAAO,QAAQ,MAAA,CAAO;AAAA,IAC1C,WAAW,WAAA,EAAY;AAAA,IACvB,QAAA,EAAU,UAAU,MAAA,CAAO,QAAA;AAAA,IAC3B,QAAQ,IAAA,CAAK,EAAA;AAAA,IACb,aAAa,SAAA,CAAU,WAAA;AAAA,IACvB,QAAQ,SAAA,CAAU,MAAA;AAAA,IAClB,WAAW,SAAA,CAAU,SAAA;AAAA,IACrB,OAAO,SAAA,CAAU,KAAA;AAAA,IACjB,OAAO,SAAA,CAAU,KAAA;AAAA,IACjB,eAAe,SAAA,CAAU,aAAA;AAAA,IACzB,mBAAA,EAAqB,MAAA;AAAA,IACrB,QAAQ,SAAA,CAAU,MAAA;AAAA,IAClB,QAAQ,SAAA,CAAU,MAAA;AAAA,IAClB,SAAA,EAAW,IAAI,IAAA,CAAK,IAAA,CAAK,KAAI,GAAI,GAAA,CAAI,GAAA,CAAI,oBAAA,GAAuB,GAAI;AAAA,GACrE,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM;AAAA,IACR,IAAA,EAAM,+BAAA;AAAA,IACN,QAAQ,IAAA,CAAK,EAAA;AAAA,IACb,QAAA,EAAU,UAAU,MAAA,CAAO,QAAA;AAAA,IAC3B,QAAQ,SAAA,CAAU,MAAA;AAAA,IAClB,IAAA,EAAM,EAAE,SAAA,EAAW,SAAA,CAAU,SAAA;AAAU,GACxC,CAAA;AAED,EAAA,OAAO,GAAA;AACT;AAUA,SAAS,SAAA,CAAU,UAAA,EAAoB,IAAA,EAAc,KAAA,EAAuB;AAC1E,EAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,IAAA,CAAK,UAAU,CAAA;AAChD,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,UAAA,EAAY,2BAA2B,CAAA;AAC3D,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAChC,EAAA,OAAO,QAAA,GAAW,GAAA,CAAI,QAAA,EAAS,GAAI,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,CAAA;AAC5E;AAGO,SAAS,kBAAA,CAAmB,KAAsB,SAAA,EAA2B;AAClF,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,UAAA,EAAY,YAAA,EAAc,SAAS,CAAA;AAC1D;AAUO,SAAS,gBAAA,CAAiB,KAAsB,QAAA,EAAiC;AACtF,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,EAAU,OAAO,IAAA;AAC1B,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,aAAa,QAAQ,CAAA;AAC1D;;;AC3LO,IAAM,qBAAA,GAAwB,EAAA;AAGrC,SAAS,QAAA,CAAS,GAAsB,CAAA,EAA+B;AACrE,EAAA,OAAO,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAO,CAAC,CAAA;AAC/B;AAQA,eAAe,WAAA,CAAY,GAAA,EAAsB,SAAA,EAAmB,IAAA,EAAmB;AACrF,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,QAAQ,EAAE,SAAA,EAAW,CAAA,CAAE,IAAA,EAAK;AACrE,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,SAAA,CAAU,OAAA,MAAa,IAAA,CAAK,GAAA,EAAI,IAAK,OAAA,CAAQ,QAAA,EAAU;AAC7E,IAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,iBAAA,EAAmB,0CAA0C,CAAA;AAAA,EACzF;AAIA,EAAA,IAAI,CAAC,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,IAAA,CAAK,EAAE,CAAA,EAAG;AACtC,IAAA,MAAM,aAAa,oDAAoD,CAAA;AAAA,EACzE;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,CAAA,CAAE,IAAA,EAAK;AACpF,EAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,iBAAA,EAAmB,0CAA0C,CAAA;AAAA,EACzF;AAEA,EAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAC3B;AASA,eAAe,cAAA,CACb,GAAA,EACA,QAAA,EACA,MAAA,EACmB;AACnB,EAAA,MAAM,SAAS,MAAM,GAAA,CAAI,OAAO,KAAA,CAAM,IAAA,CAAK,EAAE,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,CAAA,CAC7E,MAAA,CAAO,QAAQ,CAAA,CACf,IAAA,GACA,IAAA,EAAK;AACR,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAC,CAAA;AACrD;AAEA,eAAsB,iBAAA,CACpB,GAAA,EACA,SAAA,EACA,IAAA,EACyB;AACzB,EAAA,MAAM,EAAE,SAAS,MAAA,EAAO,GAAI,MAAM,WAAA,CAAY,GAAA,EAAK,WAAW,IAAI,CAAA;AAClE,EAAA,MAAM,oBAAoB,MAAM,cAAA,CAAe,KAAK,OAAA,CAAQ,QAAA,EAAU,QAAQ,MAAM,CAAA;AAEpF,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,EAAC;AACrC,EAAA,MAAM,OAAA,GAA0B;AAAA,IAC9B,MAAA,EAAQ;AAAA,MACN,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,GAAI,SAAS,OAAA,GAAU,EAAE,SAAS,QAAA,CAAS,OAAA,KAAY,EAAC;AAAA,MACxD,GAAI,SAAS,SAAA,GAAY,EAAE,WAAW,QAAA,CAAS,SAAA,KAAc,EAAC;AAAA,MAC9D,GAAI,SAAS,WAAA,GAAc,EAAE,aAAa,QAAA,CAAS,WAAA,KAAgB,EAAC;AAAA,MACpE,GAAI,SAAS,MAAA,GAAS,EAAE,QAAQ,QAAA,CAAS,MAAA,KAAW,EAAC;AAAA,MACrD,GAAI,SAAS,UAAA,GAAa,EAAE,YAAY,QAAA,CAAS,UAAA,KAAe;AAAC,KACnE;AAAA,IACA,QAAQ,cAAA,CAAe,GAAA,EAAK,QAAQ,MAAA,EAAQ,EAAE,mBAAmB,CAAA;AAAA,IACjE,IAAA,EAAM;AAAA,MACJ,WAAA,EAAa,KAAK,WAAA,IAAe,IAAA;AAAA,MACjC,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU;AAAC,KAC5C;AAAA,IACA,WAAW,OAAA,CAAQ;AAAA,GACrB;AAOA,EAAA,IAAI,IAAI,YAAA,EAAc;AACpB,IAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,YAAA,CAAa,KAAK,IAAA,EAAM;AAAA,MAC5C,MAAA,EAAQ,eAAe,MAAM,CAAA;AAAA,MAC7B,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AACD,IAAA,OAAA,CAAQ,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,qBAAqB,CAAA;AACrD,IAAA,OAAA,CAAQ,eAAA,GAAkB,IAAI,MAAA,GAAS,qBAAA;AAAA,EACzC;AAEA,EAAA,OAAO,OAAA;AACT;AAWA,SAAS,qBAAA,CACP,GAAA,EACA,WAAA,EACA,KAAA,EACA,MAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,WAAW,CAAA;AAC/B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAClF,EAAA,IAAI,UAAU,MAAA,EAAW,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,SAAS,KAAK,CAAA;AAC5D,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,GAAA,CAAI,MAAM,CAAA;AACtC,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAEA,eAAsB,aAAA,CACpB,GAAA,EACA,SAAA,EACA,IAAA,EACA,QAAA,EACiC;AACjC,EAAA,MAAM,EAAE,SAAS,MAAA,EAAO,GAAI,MAAM,WAAA,CAAY,GAAA,EAAK,WAAW,IAAI,CAAA;AAIlE,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,OAAA,GAC5B,CAAC,GAAG,IAAI,GAAA,CAAI,QAAA,CAAS,MAAA,IAAU,OAAA,CAAQ,MAAM,CAAC,IAC9C,EAAC;AACL,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAG/B,IAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,EAAG;AAChC,MAAA,MAAM,cAAA,CAAe,CAAA,OAAA,EAAU,EAAE,CAAA,4CAAA,CAA8C,CAAA;AAAA,IACjF;AAAA,EACF;AAEA,EAAA,IAAI,SAAA,GAA2B,IAAA;AAC/B,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,IAAI,IAAI,YAAA,EAAc;AACpB,MAAA,IAAI,CAAC,SAAS,SAAA,EAAW;AACvB,QAAA,MAAM,eAAe,qEAAgE,CAAA;AAAA,MACvF;AACA,MAAA,IAAI,CAAE,MAAM,GAAA,CAAI,YAAA,CAAa,OAAO,IAAA,EAAM,QAAA,CAAS,SAAS,CAAA,EAAI;AAC9D,QAAA,MAAM,YAAA,CAAa,CAAA,yBAAA,EAA4B,QAAA,CAAS,SAAS,CAAA,CAAA,CAAG,CAAA;AAAA,MACtE;AACA,MAAA,SAAA,GAAY,QAAA,CAAS,SAAA;AAAA,IACvB,CAAA,MAAA,IAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,MAAM,eAAe,mEAA8D,CAAA;AAAA,IACrF;AAAA,EACF;AAKA,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,gBAAA;AAAA,IACvC,EAAE,SAAA,EAAW,QAAA,EAAU,IAAA,EAAK;AAAA,IAC5B,EAAE,IAAA,EAAM,EAAE,QAAA,EAAU,QAAA,CAAS,OAAA,GAAU,UAAA,GAAa,QAAA,EAAU,SAAA,kBAAW,IAAI,IAAA,EAAK,EAAE,EAAE;AAAA,IACtF,EAAE,gBAAgB,OAAA;AAAQ,IAC1B,IAAA,EAAK;AACP,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,eAAe,qDAAqD,CAAA;AAAA,EAC5E;AAEA,EAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,IAAA,GAAA,CAAI,KAAA,CAAM;AAAA,MACR,IAAA,EAAM,sBAAA;AAAA,MACN,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AACD,IAAA,MAAM,IAAI,KAAA,CAAM;AAAA,MACd,IAAA,EAAM,sBAAA;AAAA,MACN,KAAA,EAAO,MAAA;AAAA,MACP,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,QAAQ,IAAA,CAAK;AAAA,KACd,CAAA;AACD,IAAA,OAAO;AAAA,MACL,YAAY,qBAAA,CAAsB,GAAA,EAAK,OAAA,CAAQ,WAAA,EAAa,QAAQ,KAAA,EAAO;AAAA,QACzE,KAAA,EAAO,eAAA;AAAA,QACP,iBAAA,EAAmB;AAAA,OACpB;AAAA,KACH;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,MAAA,CAAO,MAAM,OAAA,CAAQ;AAAA,IAC9C,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,SAAA;AAAA,IACA,SAAA,EAAW;AAAA,GACZ,EAAE,IAAA,EAAK;AAKR,EAAA,MAAM,MAAA,GAAS,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAI,QAAA,EAAU,MAAA,IAAU,EAAC,EAAI,GAAG,cAAc,CAAC,CAAC,CAAA;AAC5E,EAAA,MAAM,SAAA,GAAY,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAI,QAAA,EAAU,SAAA,IAAa,EAAC,EAAI,GAAG,OAAA,CAAQ,SAAS,CAAC,CAAC,CAAA;AAGrF,EAAA,MAAM,IAAA,GAAO,QAAQ,QAAQ,CAAA,IAAK,OAAO,MAAA,IAAU,QAAA,EAAU,OAAO,MAAA,IAAU,CAAA,CAAA;AAE9E,EAAA,MAAM,KAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,gBAAA;AAAA,IACpC,EAAE,UAAU,OAAA,CAAQ,QAAA,EAAU,QAAQ,OAAA,CAAQ,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAW,IAAA,EAAK;AAAA,IACjF;AAAA,MACE,IAAA,EAAM,EAAE,MAAA,EAAQ,SAAA,EAAW,YAAY,GAAA,EAAI;AAAA;AAAA;AAAA;AAAA,MAI3C,GAAI,IAAA,GAAO,EAAE,IAAA,EAAM,EAAE,OAAA,EAAS,CAAA,EAAE,EAAE,GAAI,EAAE,YAAA,EAAc,EAAE,OAAA,EAAS,GAAE;AAAE,KACvE;AAAA,IACA,EAAE,cAAA,EAAgB,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAM,qBAAqB,IAAA;AAAK,IACnE,IAAA,EAAK;AAIP,EAAA,MAAM,OAAO,WAAA,EAAY;AACzB,EAAA,MAAM,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO;AAAA,IAC3B,QAAA,EAAU,OAAO,IAAI,CAAA;AAAA,IACrB,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,SAAS,KAAA,CAAM,GAAA;AAAA,IACf,SAAA;AAAA;AAAA;AAAA,IAGA,MAAA,EAAQ,cAAA;AAAA,IACR,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,eAAe,OAAA,CAAQ,aAAA;AAAA,IACvB,mBAAA,EAAqB,MAAA;AAAA,IACrB,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,SAAA,EAAW,IAAI,IAAA,CAAK,GAAA,CAAI,SAAQ,GAAI,GAAA,CAAI,GAAA,CAAI,IAAA,GAAO,GAAI;AAAA,GACxD,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM;AAAA,IACR,IAAA,EAAM,uBAAA;AAAA,IACN,QAAQ,IAAA,CAAK,EAAA;AAAA,IACb,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAAA,IACzB,GAAI,SAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,IACjC,MAAA,EAAQ;AAAA,GACT,CAAA;AACD,EAAA,MAAM,IAAI,KAAA,CAAM;AAAA,IACd,IAAA,EAAM,uBAAA;AAAA,IACN,KAAA,EAAO,MAAA;AAAA,IACP,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,QAAQ,IAAA,CAAK,EAAA;AAAA,IACb,SAAS,KAAA,CAAM,GAAA;AAAA,IACf,MAAM,EAAE,MAAA,EAAQ,gBAAgB,SAAA,EAAW,OAAA,EAAS,MAAM,OAAA;AAAQ,GACnE,CAAA;AAED,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,sBAAsB,GAAA,EAAK,OAAA,CAAQ,aAAa,OAAA,CAAQ,KAAA,EAAO,EAAE,IAAA,EAAM;AAAA,GACrF;AACF;ACvSA,IAAM,IAAA,GAAO,CAAC,KAAA,KACZ,MAAA,CAAO,KAAK,KAAc,CAAA,CAAE,SAAS,WAAW,CAAA;AAUlD,IAAM,wBAAA,mBAA2B,IAAI,GAAA,CAAI,CAAC,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,SAAS,CAAC,CAAA;AAEhG,SAAS,OAAA,CAAQ,KAAiB,OAAA,EAA0C;AAC1E,EAAA,MAAM,MAAA,GAAS,EAAE,GAAA,EAAK,GAAA,CAAI,KAAK,GAAA,EAAK,KAAA,EAAO,GAAA,EAAK,GAAA,CAAI,GAAA,EAAI;AACxD,EAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,UAAU,MAAM,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAC,CAAA,CAAA;AAC7E,EAAA,MAAM,YAAYC,WAAA,CAAK,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AAAA,IAClD,KAAK,GAAA,CAAI,UAAA;AAAA,IACT,WAAA,EAAa;AAAA,GACd,CAAA;AACD,EAAA,OAAO,GAAG,IAAI,CAAA,CAAA,EAAI,SAAA,CAAU,QAAA,CAAS,WAAW,CAAC,CAAA,CAAA;AACnD;AAOA,SAAS,OAAO,WAAA,EAA6B;AAC3C,EAAA,MAAM,MAAA,GAASR,kBAAW,QAAQ,CAAA,CAAE,OAAO,WAAA,EAAa,OAAO,EAAE,MAAA,EAAO;AACxE,EAAA,OAAO,MAAA,CAAO,SAAS,CAAA,EAAG,MAAA,CAAO,SAAS,CAAC,CAAA,CAAE,SAAS,WAAW,CAAA;AACnE;AAOA,IAAM,YAAA,GAAe,cAAA;AAMrB,SAAS,aAAA,CAAc,QAAwB,GAAA,EAAiC;AAC9E,EAAA,MAAM,MAAM,MAAA,CAAO,gBAAA;AACnB,EAAA,IAAI,GAAA,YAAe,GAAA,EAAK,OAAO,GAAA,CAAI,IAAI,GAAG,CAAA;AAC1C,EAAA,IAAI,OAAO,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAQ,IAA+B,GAAG,CAAA;AAC9E,EAAA,OAAO,MAAA;AACT;AAWA,eAAsB,UAAA,CACpB,GAAA,EACA,MAAA,EACA,MAAA,EACiB;AACjB,EAAA,MAAM,GAAA,GAAM,OAAO,MAAM,CAAA;AACzB,EAAA,IAAI,GAAA,CAAI,WAAA,KAAgB,UAAA,EAAY,OAAO,GAAA;AAC3C,EAAA,IAAI,CAAC,IAAI,YAAA,EAAc;AACrB,IAAA,MAAM,IAAI,MAAM,2EAA2E,CAAA;AAAA,EAC7F;AAEA,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,MAAA,EAAQ,GAAG,CAAA;AAC1C,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,UAAU,eAAA,CAAgB,GAAA,EAAK,MAAA,CAAO,QAAA,EAAU,IAAI,YAAY,CAAA;AAGtE,EAAA,MAAM,GAAA,CAAI,OAAO,MAAA,CAAO,SAAA;AAAA,IACtB,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,CAAC,CAAA,iBAAA,EAAoB,GAAG,CAAA,CAAE,GAAG,EAAE,OAAA,EAAS,KAAA,EAAM,EAAE;AAAA,IAC7E,EAAE,MAAM,EAAE,CAAC,oBAAoB,GAAG,CAAA,CAAE,GAAG,OAAA,EAAQ;AAAE,GACnD;AACA,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,OAAA;AAAA,IACrC,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAAA,IAC5B,EAAE,kBAAkB,CAAA;AAAE,GACxB;AACA,EAAA,OAAQ,MAAA,IAAU,aAAA,CAAc,MAAA,EAAQ,GAAG,CAAA,IAAM,OAAA;AACnD;AAGA,SAAS,cAAA,CAAe,MAAmB,MAAA,EAA2C;AACpF,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,MAAM,CAAA;AAC9B,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA,EAAG;AAC1B,IAAA,IAAI,IAAA,CAAK,WAAA,EAAa,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,WAAA;AACtC,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,GAAA,CAAI,OAAA,GAAU,IAAA,CAAK,SAAA;AAAA,EACzC;AAGA,EAAA,IAAI,OAAA,CAAQ,IAAI,OAAO,CAAA,IAAK,KAAK,KAAA,EAAO,GAAA,CAAI,QAAQ,IAAA,CAAK,KAAA;AACzD,EAAA,OAAO,GAAA;AACT;AAEA,eAAe,UAAA,CACb,KACA,IAAA,EACkC;AAClC,EAAA,IAAI,CAAC,GAAA,CAAI,MAAA,EAAQ,OAAO,EAAC;AACzB,EAAA,OAAO,MAAM,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM;AAAA,IACjC,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,SAAA,EAAW,KAAK,SAAA,IAAa,MAAA;AAAA,IAC7B,MAAA,EAAQ,YAAA,CAAa,IAAA,CAAK,MAAM;AAAA,GACjC,CAAA;AACH;AAEA,eAAsB,YAAA,CACpB,GAAA,EACA,IAAA,EACA,IAAA,EASiB;AACjB,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,aAAA,EAAc;AACrC,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,OAAO,GAAA,CAAI,WAAA;AAKjB,EAAA,MAAM,OAAA,GAAmC;AAAA,IACvC,GAAG,cAAA,CAAe,IAAA,CAAK,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,IACxC,GAAG,MAAM,UAAA,CAAW,GAAA,EAAK,IAAI;AAAA,GAC/B;AACA,EAAA,KAAA,MAAW,KAAA,IAAS,wBAAA,EAA0B,OAAO,OAAA,CAAQ,KAAK,CAAA;AAElE,EAAA,OAAA,CAAQ,MAAM,GAAA,CAAI,MAAA;AAClB,EAAA,OAAA,CAAQ,GAAA,GAAM,MAAM,UAAA,CAAW,GAAA,EAAK,KAAK,MAAA,EAAQ,IAAA,CAAK,KAAK,EAAE,CAAA;AAC7D,EAAA,OAAA,CAAQ,GAAA,GAAM,KAAK,MAAA,CAAO,QAAA;AAC1B,EAAA,OAAA,CAAQ,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,GAAI,CAAA;AACnC,EAAA,OAAA,CAAQ,GAAA,GAAM,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,QAAQ,GAAI,CAAA;AAC5C,EAAA,OAAA,CAAQ,GAAA,GAAM,KAAK,KAAA,CAAA,CAAO,GAAA,GAAM,IAAI,GAAA,CAAI,WAAA,GAAc,GAAA,GAAO,IAAA,IAAQ,GAAI,CAAA;AAEzE,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,QAAA;AAC5C,EAAA,IAAI,QAAA,UAAkB,SAAA,GAAY,IAAA,CAAK,MAAM,QAAA,CAAS,OAAA,KAAY,GAAI,CAAA;AACtE,EAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAA,CAAQ,KAAA,GAAQ,IAAA,CAAK,KAAA;AACrC,EAAA,IAAI,KAAK,WAAA,EAAa,OAAA,CAAQ,OAAA,GAAU,MAAA,CAAO,KAAK,WAAW,CAAA;AAE/D,EAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAC7B;AAQA,eAAsB,aAAA,CACpB,KACA,IAAA,EAMkC;AAClC,EAAA,MAAM,MAAA,GAAkC;AAAA,IACtC,GAAG,cAAA,CAAe,IAAA,CAAK,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,IACxC,GAAG,MAAM,UAAA,CAAW,GAAA,EAAK,IAAI;AAAA,GAC/B;AAGA,EAAA,OAAO,MAAA,CAAO,GAAA;AACd,EAAA,OAAO,EAAE,GAAA,EAAK,MAAM,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG,GAAG,MAAA,EAAO;AAC5E;;;AChKO,SAAS,kBAAkB,GAAA,EAA8B;AAC9D,EAAA,MAAM,MAAA,GAASF,0BAAQ,MAAA,EAAO;AAC9B,EAAA,MAAM,IAAI,CAAC,CAAA,KAAkD,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAC,CAAA;AAC/E,EAAA,MAAM,IAAA,GAAO,iBAAiB,GAAG,CAAA;AAcjC,EAAA,MAAM,IAAA,GAAOA,0BAAQ,UAAA,CAAW,EAAE,UAAU,KAAA,EAAO,KAAA,EAAO,QAAQ,CAAA;AAElE,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAA,KAAyB,GAAA,CAAI,EAAA,IAAM,SAAA;AAClD,EAAA,MAAM,YAAY,CAAC,GAAA,KAAyB,oBAAoB,GAAG,CAAA,IAAK,MAAM,GAAG,CAAA;AACjF,EAAA,MAAM,IAAA,GAAO,eAAe,GAAG,CAAA;AAY/B,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,YAAA;AAAA,IACA,SAAA,CAAU,GAAA,EAAK,WAAA,EAAa,KAAK,CAAA;AAAA,IACjC,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI;AACF,QAAA,SAAA,GAAY,MAAM,4BAAA,CAA6B,GAAA,EAAK,GAAA,CAAI,KAAgC,CAAA;AAAA,MAC1F,SAAS,GAAA,EAAK;AAOZ,QAAA,IAAI,eAAe,qBAAA,EAAuB;AACxC,UAAA,OAAO,IAAI,QAAA,CAAS,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,QACrD;AACA,QAAA,MAAM,GAAA;AAAA,MACR;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACtC,MAAA,IAAI,CAAC,IAAA,EAAM;AAGT,QAAA,MAAM,EAAA,GAAK,iBAAiB,GAAA,EAAK,CAAA,EAAG,IAAI,MAAM,CAAA,EAAG,GAAA,CAAI,WAAW,CAAA,CAAE,CAAA;AAClE,QAAA,IAAI,CAAC,EAAA,EAAI;AAGP,UAAA,MAAM,IAAI,UAAA;AAAA,YACR,GAAA;AAAA,YACA,gBAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF;AACA,QAAA,OAAO,GAAA,CAAI,QAAA,CAAS,GAAA,EAAK,EAAE,CAAA;AAAA,MAC7B;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,0BAAA,CAA2B,GAAA,EAAK,WAAW,IAAI,CAAA;AACrE,MAAA,OAAO,IAAI,QAAA,CAAS,GAAA,EAAK,mBAAmB,GAAA,EAAK,OAAA,CAAQ,SAAS,CAAC,CAAA;AAAA,IACrE,CAAC;AAAA,GACH;AAEA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,YAAA;AAAA,IACA,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,CAAY,GAAA,EAAK,GAAG,CAAA;AAIvC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,IAAK,EAAA,EAAI,CAAC,GAAG,GAAG,CAAA;AACtE,MAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,MAAA,CAAO,IAAI,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA,EAAG,CAAC,CAAA;AAEpD,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAC7B,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,CAAK,EAAA,EAAI,SAAA,EAAW,IAAA,EAAM,EACzC,IAAA,CAAK,EAAE,SAAA,EAAW,EAAA,EAAI,CAAA,CACtB,IAAA,CAAK,IAAI,CAAA,CACT,KAAA,CAAM,KAAK,CAAA,CACX,IAAA,EAAK;AAER,MAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,MAAA,CAAO,OAC9B,IAAA,CAAK,EAAE,UAAU,EAAE,GAAA,EAAK,OAAO,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,QAAQ,GAAE,EAAG,EACzD,IAAA,EAAK;AACR,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,QAAA,EAAU,CAAC,CAAC,CAAC,CAAA;AAExD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,KAAA;AAAA,QACA,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA;AAAA;AAAA,UAGxB,EAAA,EAAI,MAAA,CAAO,CAAA,CAAE,GAAG,CAAA;AAAA,UAChB,MAAA,EAAQ;AAAA,YACN,UAAU,CAAA,CAAE,QAAA;AAAA,YACZ,MAAM,IAAA,CAAK,GAAA,CAAI,EAAE,QAAQ,CAAA,EAAG,QAAQ,CAAA,CAAE,QAAA;AAAA,YACtC,UAAU,IAAA,CAAK,GAAA,CAAI,EAAE,QAAQ,CAAA,EAAG,YAAY;AAAC,WAC/C;AAAA,UACA,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,GAAA,CAAI,CAAC,EAAA,KAAO,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,IAAK,EAAE,EAAA,EAAI,KAAA,EAAO,IAAI,CAAA;AAAA,UACxE,GAAI,EAAE,SAAA,GAAY,EAAE,WAAW,CAAA,CAAE,SAAA,KAAc,EAAC;AAAA,UAChD,WAAW,CAAA,CAAE,SAAA;AAAA,UACb,YAAY,CAAA,CAAE;AAAA,SAChB,CAAE;AAAA,OACH,CAAA;AAAA,IACH,CAAC;AAAA,GACH;AAIA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,QAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA,CAAU,GAAA,EAAK,OAAA,EAAS,SAAS,CAAA;AAAA,IACjC,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AAGpB,MAAA,GAAA,CAAI,GAAA,CAAI,iBAAiB,UAAU,CAAA;AACnC,MAAA,GAAA,CAAI,GAAA,CAAI,UAAU,UAAU,CAAA;AAE5B,MAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,CAAmB,GAAA,EAAK,GAAG,CAAA;AAChD,MAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,MAAA,MAAM,SAAA,GAAY,GAAA,CAAI,IAAA,CAAK,UAAU,CAAA;AAErC,MAAA,IAAI,cAAc,oBAAA,EAAsB;AACtC,QAAA,MAAM,OAAO,MAAM,WAAA,CAAY,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG;AAAA,UAClD,UAAU,MAAA,CAAO,QAAA;AAAA,UACjB,WAAA,EAAa,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA;AAAA,UAClC,YAAA,EAAc,GAAA,CAAI,IAAA,CAAK,aAAa;AAAA,SACrC,CAAA;AACD,QAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa,GAAA,EAAK,IAAI,CAAA;AAC3C,QAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,GAC3C,MAAM,YAAA,CAAa,GAAA,EAAK,IAAA,EAAM;AAAA,UAC9B,MAAA;AAAA,UACA,IAAA,EAAM,MAAM,GAAA,CAAI,QAAA,CAAS,OAAO,MAAM,CAAA;AAAA,UACtC,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,aAAa,MAAA,CAAO;AAAA,SACrB,CAAA,GACC,MAAA;AACJ,QAAA,OAAO,GAAA,CAAI,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,MAChD;AAEA,MAAA,IAAI,cAAc,eAAA,EAAiB;AACjC,QAAA,MAAM,SAAS,MAAM,aAAA,CAAc,KAAK,GAAA,CAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AAAA,UAC/D,UAAU,MAAA,CAAO,QAAA;AAAA,UACjB,OAAO,IAAA,CAAK,KAAA,KAAU,SAAY,MAAA,GAAY,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,UAC5D,SAAA,EAAW,IAAA,CAAK,IAAA,CAAK,QAAQ;AAAA,SAC9B,CAAA;AAID,QAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,GAC3C,MAAM,YAAA,CAAa,GAAA,EAAK,IAAA,EAAM;AAAA,UAC9B,MAAA;AAAA,UACA,IAAA,EAAM,MAAM,GAAA,CAAI,QAAA,CAAS,OAAO,MAAM,CAAA;AAAA,UACtC,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,aAAa,MAAA,CAAO;AAAA,SACrB,CAAA,GACC,MAAA;AACJ,QAAA,OAAO,GAAA,CAAI,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,MAChD;AAEA,MAAA,MAAM,oBAAA;AAAA,QACJ,IAAI,SAAS,CAAA,iFAAA;AAAA,OACf;AAAA,IACF,CAAC;AAAA,GACH;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,SAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA,CAAU,GAAA,EAAK,OAAA,EAAS,SAAS,CAAA;AAAA,IACjC,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,GAAA,CAAI,GAAA,CAAI,iBAAiB,UAAU,CAAA;AACnC,MAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,CAAmB,GAAA,EAAK,GAAG,CAAA;AAChD,MAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,MAAA,MAAM,YAAY,GAAA,EAAK,GAAA,CAAI,KAAK,KAAK,CAAA,EAAG,OAAO,QAAQ,CAAA;AAIvD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAAA,IACzB,CAAC;AAAA,GACH;AAIA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,WAAA;AAAA,IACA,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,MAAM,GAAA,GAAM,sBAAsB,IAAA,CAAK,GAAA,CAAI,QAAQ,aAAA,IAAiB,EAAE,IAAI,CAAC,CAAA;AAC3E,MAAA,IAAI,CAAC,GAAA,EAAK,MAAM,eAAA,CAAgB,mBAAmB,mCAAmC,CAAA;AAEtF,MAAA,MAAM,KAAA,GAAQ,MAAM,qBAAA,CAAsB,GAAA,EAAK,GAAG,CAAA;AAClD,MAAA,IAAI,CAAC,KAAA,EAAO,MAAM,eAAA,CAAgB,iBAAiB,iDAAiD,CAAA;AACpG,MAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,EAAG;AACpC,QAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,oBAAA,EAAsB,gCAAA,EAAkC;AAAA,UAChF,OAAA,EAAS,EAAE,kBAAA,EAAoB,mDAAA;AAAoD,SACpF,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,CAAA;AAC3E,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,eAAA,CAAgB,iBAAiB,sDAAsD,CAAA;AAE1G,MAAA,GAAA,CAAI,GAAA,CAAI,iBAAiB,UAAU,CAAA;AACnC,MAAA,GAAA,CAAI,IAAA,CAAK,MAAM,aAAA,CAAc,GAAA,EAAK;AAAA,QAChC,MAAA;AAAA,QACA,IAAA,EAAM,MAAM,GAAA,CAAI,QAAA,CAAS,MAAM,MAAM,CAAA;AAAA,QACrC,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,WAAW,KAAA,CAAM;AAAA,OAClB,CAAC,CAAA;AAAA,IACJ,CAAC;AAAA,GACH;AAIA,EAAA,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,CAAA,CAAE,OAAO,MAAM,GAAA,KAAQ;AAGzC,IAAA,GAAA,CAAI,GAAA,CAAI,iBAAiB,qBAAqB,CAAA;AAC9C,IAAA,GAAA,CAAI,IAAA,CAAK,MAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AAAA,EAC5B,CAAC,CAAC,CAAA;AAEF,EAAA,IAAI,GAAA,CAAI,KAAK,aAAA,EAAe;AAC1B,IAAA,MAAA,CAAO,OAAA,CAAQ,QAAA,EAAU,IAAA,EAAM,CAAC,MAAM,GAAA,KAAQ;AAAE,MAAA,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,IAAG,CAAC,CAAA;AACtE,IAAA,MAAA,CAAO,OAAA,CAAQ,SAAA,EAAW,IAAA,EAAM,CAAC,MAAM,GAAA,KAAQ;AAAE,MAAA,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,IAAG,CAAC,CAAA;AAAA,EACzE;AAIA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,qBAAA;AAAA,IACA,SAAA,CAAU,GAAA,EAAK,SAAA,EAAW,KAAK,CAAA;AAAA,IAC/B,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,CAAY,GAAA,EAAK,GAAG,CAAA;AACvC,MAAA,GAAA,CAAI,IAAA,CAAK,MAAM,iBAAA,CAAkB,GAAA,EAAK,UAAU,GAAA,EAAK,WAAW,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,IAC1E,CAAC;AAAA,GACH;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,qBAAA;AAAA,IACA,SAAA,CAAU,GAAA,EAAK,SAAA,EAAW,KAAK,CAAA;AAAA,IAC/B,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,CAAY,GAAA,EAAK,GAAG,CAAA;AAGvC,MAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,MAAA,IAAI,OAAO,IAAA,CAAK,OAAA,KAAY,SAAA,EAAW;AACrC,QAAA,MAAM,eAAe,6BAA6B,CAAA;AAAA,MACpD;AACA,MAAA,GAAA,CAAI,IAAA,CAAK,MAAM,aAAA,CAAc,GAAA,EAAK,UAAU,GAAA,EAAK,WAAW,GAAG,IAAA,EAAM;AAAA,QACnE,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,IAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,GAAI,MAAA;AAAA,QAC/D,WAAW,IAAA,CAAK,SAAA,KAAc,SAAY,MAAA,GAAY,MAAA,CAAO,KAAK,SAAS;AAAA,OAC5E,CAAC,CAAA;AAAA,IACJ,CAAC;AAAA,GACH;AAEA,EAAA,MAAA,CAAO,MAAA;AAAA,IACL,gBAAA;AAAA,IACA,CAAA,CAAE,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,CAAY,GAAA,EAAK,GAAG,CAAA;AACvC,MAAA,MAAM,EAAA,GAAK,SAAA,CAAU,GAAA,EAAK,IAAI,CAAA;AAG9B,MAAA,IAAI,CAACD,yBAAAA,CAAS,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,EAAE,CAAA,EAAG;AACxC,QAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,WAAA,EAAa,eAAe,CAAA;AAAA,MACxD;AAIA,MAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,gBAAA;AAAA,QACnC,EAAE,GAAA,EAAK,EAAA,EAAI,QAAQ,IAAA,CAAK,EAAA,EAAI,WAAW,IAAA,EAAK;AAAA,QAC5C,EAAE,MAAM,EAAE,SAAA,sBAAe,IAAA,EAAK,EAAG,SAAA,EAAW,MAAA,EAAO;AAAE,OACvD;AACA,MAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,aAAa,eAAe,CAAA;AAElE,MAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,GAAA,CAAI,OAAO,KAAA,CAAM,UAAA;AAAA,QAC/C,EAAE,OAAA,EAAS,KAAA,CAAM,GAAA,EAAK,WAAW,IAAA,EAAK;AAAA,QACtC,EAAE,IAAA,EAAM,EAAE,2BAAW,IAAI,IAAA,IAAO;AAAE,OACpC;AACA,MAAA,GAAA,CAAI,KAAA,CAAM,EAAE,IAAA,EAAM,qBAAA,EAAuB,QAAQ,IAAA,CAAK,EAAA,EAAI,QAAA,EAAU,KAAA,CAAM,UAAU,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,GAAG,GAAG,CAAA;AAChH,MAAA,KAAK,IAAI,KAAA,CAAM,EAAE,IAAA,EAAM,qBAAA,EAAuB,OAAO,MAAA,EAAQ,MAAA,EAAQ,IAAA,CAAK,EAAA,EAAI,UAAU,KAAA,CAAM,QAAA,EAAU,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA;AAC5H,MAAA,GAAA,CAAI,KAAK,EAAE,OAAA,EAAS,MAAM,aAAA,EAAe,aAAA,IAAiB,GAAG,CAAA;AAAA,IAC/D,CAAC;AAAA,GACH;AAEA,EAAA,OAAO,MAAA;AACT;AAIA,eAAe,WAAA,CAAY,KAAsB,GAAA,EAAoC;AACnF,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACtC,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,UAAA,CAAW,GAAA,EAAK,gBAAA,EAAkB,uCAAuC,CAAA;AAAA,EACrF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,eAAA,CAAgB,MAAc,WAAA,EAAiC;AACtE,EAAA,OAAO,IAAI,UAAA,CAAW,GAAA,EAAK,IAAA,EAAM,WAAA,EAAa;AAAA,IAC5C,SAAS,EAAE,kBAAA,EAAoB,iBAAiB,IAAI,CAAA,sBAAA,EAAyB,WAAW,CAAA,CAAA,CAAA;AAAI,GAC7F,CAAA;AACH;AASA,SAAS,aAAA,CAAc,QAAoB,OAAA,EAA2C;AACpF,EAAA,OAAO;AAAA,IACL,cAAc,MAAA,CAAO,WAAA;AAAA,IACrB,UAAA,EAAY,QAAA;AAAA,IACZ,YAAY,MAAA,CAAO,SAAA;AAAA,IACnB,GAAI,OAAO,YAAA,GAAe,EAAE,eAAe,MAAA,CAAO,YAAA,KAAiB,EAAC;AAAA,IACpE,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAAA;AAAA;AAAA,IAG7B,GAAI,OAAA,GAAU,EAAE,QAAA,EAAU,OAAA,KAAY;AAAC,GACzC;AACF;AASA,SAAS,SAAA,CAAU,KAAc,IAAA,EAAsB;AACrD,EAAA,MAAM,KAAA,GAAS,GAAA,CAAI,MAAA,CAAyD,IAAI,CAAA;AAChF,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA,GAAK,MAAM,CAAC,CAAA,IAAK,KAAO,KAAA,IAAS,EAAA;AAC7D;AAGA,SAAS,IAAI,KAAA,EAAwB;AACnC,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,EAAA;AAC7C;AAGA,SAAS,KAAK,KAAA,EAAsC;AAClD,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,MAAA;AAChC,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,GAAI,CAAC,MAAA,CAAO,KAAK,CAAC,CAAA;AAClE;AAGA,SAAS,oBAAoB,GAAA,EAA6B;AACxD,EAAA,MAAM,MAAA,GAAS,IAAI,OAAA,CAAQ,aAAA;AAC3B,EAAA,IAAI,MAAA,EAAQ,UAAA,CAAW,QAAQ,CAAA,EAAG;AAChC,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,EAAG,QAAQ,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA;AACtE,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC/B,IAAA,IAAI,EAAA,EAAI,OAAO,kBAAA,CAAmB,EAAE,CAAA;AAAA,EACtC;AACA,EAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,EAAA,OAAO,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,GAAW,KAAK,SAAA,GAAY,IAAA;AAC/D;AAUA,SAAS,eAAe,GAAA,EAAsC;AAC5D,EAAA,IAAI,CAAC,IAAI,IAAA,CAAK,aAAA,SAAsB,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,KAAS,IAAA,EAAK;AAE/D,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,GAAA,CAAI,KAAK,OAAO,CAAA;AACxC,EAAA,OAAO,CAAC,GAAA,EAAc,GAAA,EAAe,IAAA,KAAuB;AAC1D,IAAA,MAAM,MAAA,GAAS,IAAI,OAAA,CAAQ,MAAA;AAC3B,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,GAAA,CAAI,GAAA,CAAI,+BAA+B,GAAG,CAAA;AAAA,IAC5C,CAAA,MAAA,IAAW,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAG;AACxC,MAAA,GAAA,CAAI,GAAA,CAAI,+BAA+B,MAAM,CAAA;AAE7C,MAAA,GAAA,CAAI,GAAA,CAAI,QAAQ,QAAQ,CAAA;AAAA,IAC1B;AACA,IAAA,GAAA,CAAI,GAAA,CAAI,gCAAgC,6BAA6B,CAAA;AACrE,IAAA,GAAA,CAAI,GAAA,CAAI,gCAAgC,eAAe,CAAA;AACvD,IAAA,GAAA,CAAI,GAAA,CAAI,0BAA0B,KAAK,CAAA;AACvC,IAAA,IAAA,EAAK;AAAA,EACP,CAAA;AACF;;;ACtZO,SAAS,gBAAgB,MAAA,EAAkD;AAChF,EAAA,MAAM,GAAA,GAAM,cAAc,MAAM,CAAA;AAEhC,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA;AAAA;AAAA;AAAA,MAIN,SAAA,EAAW,qBAAA,CAAsB,GAAA,EAAK,GAAA,CAAI,SAAS,CAAA;AAAA,MACnD,KAAA,EAAO,kBAAkB,GAAG;AAAA,KAC9B;AAAA,IAEA,OAAA,EAAS,cAAc,GAAG,CAAA;AAAA,IAE1B,OAAA,EAAS,iBAAiB,GAAG,CAAA;AAAA,IAC7B,MAAA,EAAQ,gBAAgB,GAAG,CAAA;AAAA,IAC3B,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,IACzB,QAAA,EAAU,kBAAkB,GAAG,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU/B,WAAA,EAAa,MAAM,gBAAA,CAAiB,GAAA,CAAI,MAAM,CAAA;AAAA;AAAA,IAG9C,QAAQ,GAAA,CAAI;AAAA,GACd;AACF","file":"index.cjs","sourcesContent":["import mongoose from 'mongoose';\nimport type { Connection, Model, Mongoose, Schema } from 'mongoose';\n// Document shapes live in the PUBLISHED declarations, not here. Hosts type\n// their own queries against them, so `types/index.d.ts` is the single source of\n// truth and the source imports it — not the other way round. See traps #9.\nimport type {\n ModelNames,\n OAuthAuditDoc,\n OAuthClientDoc,\n OAuthCodeDoc,\n OAuthGrantDoc,\n OAuthKeyDoc,\n OAuthModels,\n OAuthRequestDoc,\n OAuthTokenDoc,\n} from '../../types/index.js';\n\n/**\n * Seven collections, one factory each.\n *\n * Mongoose keeps compiled models in a registry on the connection, so calling\n * `connection.model(name, schema)` twice for the same name throws\n * OverwriteModelError. A library cannot own seven global names unconditionally\n * — the host may already have a `Grant`, or the package may be loaded twice\n * through a hoisting mismatch. So: reuse an already-compiled model when the\n * name is taken, and let the host rename any of them via `modelNames`.\n *\n * The tradeoff, which belongs in the docs: if the existing model isn't ours,\n * queries fail confusingly. Tell hosts to set `modelNames` when a collision is\n * plausible. See standards/traps.md #2.\n */\n\nconst DEFAULT_NAMES: Required<ModelNames> = {\n client: 'OAuthClient',\n grant: 'OAuthGrant',\n code: 'OAuthCode',\n token: 'OAuthToken',\n request: 'OAuthRequest',\n key: 'OAuthKey',\n audit: 'OAuthAudit',\n};\n\nfunction compile<T>(\n connection: Mongoose | Connection,\n name: string,\n build: () => Schema<T>,\n collection: string,\n): Model<T> {\n const existing = connection.models?.[name] as Model<T> | undefined;\n if (existing) return existing;\n // Cast rather than a generic argument: mongoose's `model()` overloads infer\n // a hydrated-document type from the schema, and pinning the doc type through\n // the generic slot fights that inference instead of describing it.\n return connection.model(name, build() as never, collection) as unknown as Model<T>;\n}\n\n// ---------------------------------------------------------------------------\n\nfunction clientSchema(): Schema<OAuthClientDoc> {\n const schema = new mongoose.Schema<OAuthClientDoc>(\n {\n clientId: { type: String, required: true, unique: true },\n name: { type: String, required: true },\n // `public` exists for CIMD clients, which hold no secret and are bound by\n // PKCE instead. The enum was written with this widening in mind, so it\n // was one member rather than a migration.\n type: { type: String, enum: ['confidential', 'public'], default: 'confidential' },\n // How the row got here. A `cimd` row is re-derived from the client's own\n // metadata document, so this is what tells the re-fetch path which fields\n // it owns — and `status` is deliberately not one of them.\n registration: { type: String, enum: ['manual', 'cimd'], default: 'manual' },\n metadataUrl: String,\n metadataFetchedAt: Date,\n metadataEtag: String,\n trusted: { type: Boolean, default: false },\n // An array, not a string: rotation needs two live secrets at once or it\n // cannot be deployed without downtime.\n secrets: [\n {\n _id: false,\n hash: { type: String, required: true },\n label: String,\n createdAt: { type: Date, default: Date.now },\n lastUsedAt: Date,\n retiresAt: Date,\n },\n ],\n redirectUris: { type: [String], default: [] },\n allowedScopes: { type: [String], default: [] },\n allowedResources: { type: [String], default: [] },\n branding: {\n _id: false,\n logoUrl: String,\n publisher: String,\n homepageUrl: String,\n tosUrl: String,\n privacyUrl: String,\n },\n status: { type: String, enum: ['active', 'disabled'], default: 'active' },\n // Pairwise subjects live on the client, not in a collection of their own:\n // they are per-(client, user) and are read on every token issuance for\n // that client. A Map keyed by user id keeps that a single document read.\n pairwiseSubjects: { type: Map, of: String },\n },\n { timestamps: true },\n );\n\n return schema;\n}\n\nfunction grantSchema(): Schema<OAuthGrantDoc> {\n const schema = new mongoose.Schema<OAuthGrantDoc>(\n {\n userId: { type: mongoose.Schema.Types.Mixed, required: true },\n clientId: { type: String, required: true },\n // `null`, never absent. A missing field and a null field index\n // differently, and the unique index below has to see one consistent\n // value for single-subject mode.\n contextId: { type: String, default: null },\n scopes: { type: [String], default: [] },\n resources: { type: [String], default: [] },\n version: { type: Number, default: 1 },\n lastUsedAt: Date,\n revokedAt: { type: Date, default: null },\n revokedBy: { type: String, enum: ['user', 'admin', 'system', 'client'] },\n },\n { timestamps: true },\n );\n\n // One LIVE grant per (client, user, context). Partial on `revokedAt: null`\n // so a revoked grant does not block re-consent — the alternative is either\n // deleting revocation history or hitting a duplicate key on the second\n // connect, and both are worse.\n schema.index(\n { clientId: 1, userId: 1, contextId: 1 },\n { unique: true, partialFilterExpression: { revokedAt: null } },\n );\n schema.index({ userId: 1 });\n schema.index({ clientId: 1 });\n\n return schema;\n}\n\nfunction codeSchema(): Schema<OAuthCodeDoc> {\n const schema = new mongoose.Schema<OAuthCodeDoc>(\n {\n codeHash: { type: String, required: true, unique: true },\n clientId: { type: String, required: true },\n userId: { type: mongoose.Schema.Types.Mixed, required: true },\n grantId: { type: mongoose.Schema.Types.ObjectId, required: true },\n contextId: { type: String, default: null },\n scopes: { type: [String], default: [] },\n resources: { type: [String], default: [] },\n redirectUri: { type: String, required: true },\n codeChallenge: { type: String, required: true },\n codeChallengeMethod: { type: String, enum: ['S256'], default: 'S256' },\n nonce: String,\n authTime: Date,\n // Set, not deleted, on redemption. A consumed code has to stay readable\n // long enough to detect the replay — see `tokens.ts`.\n consumedAt: { type: Date, default: null },\n expiresAt: { type: Date, required: true },\n },\n { timestamps: { createdAt: true, updatedAt: false } },\n );\n\n schema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });\n return schema;\n}\n\nfunction tokenSchema(): Schema<OAuthTokenDoc> {\n const schema = new mongoose.Schema<OAuthTokenDoc>(\n {\n kind: { type: String, enum: ['access', 'refresh'], required: true },\n tokenHash: { type: String, required: true, unique: true },\n clientId: { type: String, required: true },\n userId: { type: mongoose.Schema.Types.Mixed, required: true },\n grantId: { type: mongoose.Schema.Types.ObjectId, required: true },\n contextId: { type: String, default: null },\n scopes: { type: [String], default: [] },\n audience: { type: [String], default: [] },\n familyId: { type: String, required: true },\n parentId: { type: mongoose.Schema.Types.ObjectId, default: null },\n consumedAt: { type: Date, default: null },\n revokedAt: { type: Date, default: null },\n familyExpiresAt: Date,\n expiresAt: { type: Date, required: true },\n },\n { timestamps: { createdAt: true, updatedAt: false } },\n );\n\n // The TTL reaps expired tokens, which is why `expiresAt` on a refresh token\n // is the SLIDING window and `familyExpiresAt` carries the absolute ceiling:\n // letting Mongo delete the row is only safe if nothing downstream needed it.\n schema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });\n schema.index({ familyId: 1 });\n schema.index({ grantId: 1 });\n schema.index({ userId: 1, clientId: 1 });\n\n return schema;\n}\n\nfunction requestSchema(): Schema<OAuthRequestDoc> {\n const schema = new mongoose.Schema<OAuthRequestDoc>(\n {\n requestId: { type: String, required: true, unique: true },\n clientId: { type: String, required: true },\n userId: { type: mongoose.Schema.Types.Mixed, required: true },\n redirectUri: { type: String, required: true },\n scopes: { type: [String], default: [] },\n resources: { type: [String], default: [] },\n state: String,\n nonce: String,\n codeChallenge: { type: String, required: true },\n codeChallengeMethod: { type: String, enum: ['S256'], default: 'S256' },\n prompt: String,\n maxAge: Number,\n decision: { type: String, enum: ['approved', 'denied'] },\n decidedAt: Date,\n expiresAt: { type: Date, required: true },\n },\n { timestamps: { createdAt: true, updatedAt: false } },\n );\n\n schema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });\n return schema;\n}\n\nfunction keySchema(): Schema<OAuthKeyDoc> {\n const schema = new mongoose.Schema<OAuthKeyDoc>(\n {\n kid: { type: String, required: true, unique: true },\n alg: { type: String, enum: ['ES256'], default: 'ES256' },\n publicJwk: { type: mongoose.Schema.Types.Mixed, required: true },\n // Retiring keys stay published in JWKS so tokens signed by them still\n // validate; only `active` is used to sign.\n privateJwk: { type: mongoose.Schema.Types.Mixed, required: true },\n status: { type: String, enum: ['active', 'retiring'], default: 'active' },\n },\n { timestamps: { createdAt: true, updatedAt: false } },\n );\n\n return schema;\n}\n\nfunction auditSchema(retentionDays: number): Schema<OAuthAuditDoc> {\n const schema = new mongoose.Schema<OAuthAuditDoc>(\n {\n type: { type: String, required: true },\n actor: { type: String, enum: ['user', 'client', 'admin', 'system'] },\n clientId: String,\n userId: mongoose.Schema.Types.Mixed,\n grantId: mongoose.Schema.Types.ObjectId,\n ip: String,\n meta: mongoose.Schema.Types.Mixed,\n },\n { timestamps: { createdAt: true, updatedAt: false } },\n );\n\n // A log nothing prunes is an outage waiting. Not a time-series collection:\n // erasure needs `deleteMany`, and time-series does not support it.\n // See standards/traps.md #17.\n schema.index({ createdAt: 1 }, { expireAfterSeconds: retentionDays * 86_400 });\n schema.index({ clientId: 1, createdAt: -1 });\n schema.index({ userId: 1, createdAt: -1 });\n\n return schema;\n}\n\n// ---------------------------------------------------------------------------\n\nexport interface CreateModelsOptions {\n connection?: Mongoose | Connection;\n modelNames?: ModelNames;\n collectionPrefix?: string;\n auditRetentionDays?: number;\n}\n\nexport function createModels({\n connection = mongoose,\n modelNames = {},\n collectionPrefix = 'oauth_',\n auditRetentionDays = 400,\n}: CreateModelsOptions = {}): OAuthModels {\n const names = { ...DEFAULT_NAMES, ...modelNames };\n const c = (suffix: string) => `${collectionPrefix}${suffix}`;\n\n return {\n Client: compile<OAuthClientDoc>(connection, names.client, clientSchema, c('clients')),\n Grant: compile<OAuthGrantDoc>(connection, names.grant, grantSchema, c('grants')),\n Code: compile<OAuthCodeDoc>(connection, names.code, codeSchema, c('codes')),\n Token: compile<OAuthTokenDoc>(connection, names.token, tokenSchema, c('tokens')),\n Request: compile<OAuthRequestDoc>(connection, names.request, requestSchema, c('requests')),\n Key: compile<OAuthKeyDoc>(connection, names.key, keySchema, c('keys')),\n Audit: compile<OAuthAuditDoc>(\n connection,\n names.audit,\n () => auditSchema(auditRetentionDays),\n c('audit'),\n ),\n };\n}\n\n/**\n * Build every index before the first write.\n *\n * Mongoose builds indexes in the background, so a cold database can serve a\n * write before its unique index exists — which is exactly long enough for two\n * grants to be created for one (client, user, context). Await this at boot.\n * See standards/traps.md #3.\n */\nexport async function syncModelIndexes(models: OAuthModels): Promise<void> {\n await Promise.all(Object.values(models).map((m) => m.init()));\n}\n","import type { Request } from 'express';\nimport { createModels, syncModelIndexes } from './models.js';\nimport type {\n ClaimsAdapter,\n ClientIdMetadataConfig,\n CreateOAuthHostConfig,\n GrantContextAdapter,\n Logger,\n OAuthAuditDoc,\n OAuthEvent,\n OAuthModels,\n PackageUser,\n RateLimitConfig,\n LoadUser,\n ResolveUser,\n ResourceSpec,\n ScopeSpec,\n SigningConfig,\n TtlConfig,\n UserAdapter,\n} from '../../types/index.js';\n\n/**\n * Config normalization — the single place raw host config becomes the shape\n * every route and service consumes. Nothing downstream re-implements a default.\n *\n * Validation here is deliberately fatal and specific. This package's failure\n * mode is a partner integration that half-works six weeks later, so a bad\n * `issuer` or an unknown scope in a client's `allowedScopes` has to be a boot\n * error with the offending value in the message.\n *\n * If you rename this file, note it is called `config.ts` on purpose and that a\n * bare `config.js`/`config.ts` in a global gitignore silently deletes it from\n * the repo. Run `npm run check-tracked` before the first push — traps #1.\n */\n\nconst NOOP_LOGGER: Logger = {\n debug() {},\n info() {},\n warn() {},\n error() {},\n};\n\nexport const DEFAULT_TTL: Required<TtlConfig> = {\n code: 60,\n accessToken: 3600,\n refreshToken: 60 * 86_400,\n refreshAbsolute: 180 * 86_400,\n authorizationRequest: 600,\n};\n\n/** OIDC scopes the package understands without a `claims` adapter. */\nexport const OIDC_SCOPES = new Set(['openid', 'profile', 'email']);\n\nexport interface ResolvedRateLimits {\n token: { max: number; windowMs: number } | false;\n authorize: { max: number; windowMs: number } | false;\n consent: { max: number; windowMs: number } | false;\n hit(key: string, windowMs: number): Promise<{ count: number; resetAt: number }>;\n}\n\n/**\n * One parsed `allowedHosts` entry.\n *\n * Kept as structure rather than a string so the match is an equality test, not\n * a suffix test: `evilclaude.ai`.endsWith(`claude.ai`) is true, and that is the\n * bug this shape exists to make unwritable.\n */\nexport interface CimdHostRule {\n /** Lowercased hostname, no leading dot. */\n host: string;\n /** Matched against `URL.port` — `''` means \"the scheme default, and only that\". */\n port: string;\n /** Entry was written as `.example.com`, so subdomains are admitted too. */\n subdomains: boolean;\n}\n\nexport interface ResolvedCimd {\n enabled: boolean;\n allowedHosts: CimdHostRule[];\n cacheTtlMs: number;\n fetchTimeoutMs: number;\n maxBytes: number;\n allowedScopes: string[];\n /**\n * Negative cache: URL → why it failed and until when.\n *\n * State on a config object is unusual, and it lives here for a reason — it\n * has to be per-instance so two hosts in one process cannot poison each\n * other, and a module-level map would do exactly that. Bounded, because the\n * key is a request parameter an attacker chooses.\n */\n failures: Map<string, { until: number; message: string }>;\n}\n\n/**\n * Whether `syncIndexes()` has resolved, shared by reference.\n *\n * A mutable cell rather than a boolean field because the routers close over the\n * context at mount time and have to observe a flip that happens afterwards —\n * which is the whole point, since the reported failure is a host calling\n * `syncIndexes()` inside its `app.listen` callback, after mounting.\n */\nexport interface IndexState {\n ready: boolean;\n}\n\nexport interface ResolvedContext {\n models: OAuthModels;\n issuer: string;\n /** Mount path of `routes.oauth`, normalized to a leading slash and no trailing one. */\n mountPath: string;\n resources: ResourceSpec[];\n scopes: ScopeSpec[];\n /** `id` → spec. Every scope lookup goes through this, never a linear scan. */\n scopeIndex: Map<string, ScopeSpec>;\n /**\n * What a `scope`-less `/authorize` falls back to. Undefined means no\n * fallback was configured, which is an error at request time rather than an\n * empty grant — see `resolveDefaultScopes`.\n */\n defaultScopes?: string[];\n consentUrl: string;\n loginUrl?: string;\n returnParam: string;\n\n resolveUser: ResolveUser;\n /**\n * Resolve a user the package only has an id for. Always returns something:\n * with no `loadUser` adapter the caller still gets `{ id }`, so `/userinfo`\n * answers a valid (if bare) document rather than 500ing.\n */\n loadUser(userId: PackageUser['id']): Promise<PackageUser>;\n grantContext?: GrantContextAdapter;\n claims?: ClaimsAdapter;\n\n ttl: Required<TtlConfig>;\n subjectMode: 'public' | 'pairwise';\n pairwiseSalt?: string;\n signing: SigningConfig;\n rateLimits: ResolvedRateLimits;\n tokenCacheTtlMs: number;\n cors: { tokenEndpoint: boolean; origins: string[] };\n clockSkewMs: number;\n cimd: ResolvedCimd;\n\n logger: Logger;\n track: (event: OAuthEvent) => void;\n /** Append-only. Never throws into a request — an audit failure is logged. */\n audit(entry: Partial<OAuthAuditDoc> & { type: string }): Promise<void>;\n}\n\n/**\n * Default user resolution.\n *\n * Reads the conventional spots an upstream auth middleware leaves things:\n * `req.user` (passport) then `req.authUserId`. Hosts using another convention\n * pass their own `resolveUser`.\n *\n * Pure read. Never verify a token in here — it runs on every request through\n * `/authorize` and `/consent`, and a throw becomes a 500 where the host wanted\n * a clean redirect to the login page.\n *\n * The properties read off `req` are written by the HOST's middleware, so they\n * are not on Express's `Request` type. Narrow through a local shape rather than\n * augmenting the global namespace — a library that declares into the host's\n * types leaks its assumptions into the host's own typechecks.\n */\ninterface AuthedRequestish {\n authUserId?: PackageUser['id'];\n user?: {\n _id?: PackageUser['id'];\n id?: PackageUser['id'];\n email?: string;\n displayName?: string | null;\n avatarUrl?: string | null;\n authTime?: Date;\n isAdmin?: boolean;\n };\n}\n\nexport function defaultResolveUser(req: Request): PackageUser | null {\n const { authUserId, user } = req as Request & AuthedRequestish;\n const id = user?._id ?? user?.id ?? authUserId;\n if (!id) return null;\n return {\n id,\n email: user?.email,\n displayName: user?.displayName ?? null,\n avatarUrl: user?.avatarUrl ?? null,\n authTime: user?.authTime,\n isAdmin: Boolean(user?.isAdmin),\n };\n}\n\n/**\n * The user adapter: the seam between the host's user system and this package.\n *\n * inbound resolveUser(req) \"who is making this request?\"\n * outbound oauth.users.forget(id) \"this user is gone, drop their data\"\n * oauth.users.revokeAll(id) \"kill their live access\"\n *\n * The package never queries the user collection, never joins against it, and\n * never writes to it.\n *\n * `isAdmin` gates nothing. It cannot: the package cannot know what admin means\n * here, and there is no admin router to guard — the admin surface is a plain\n * module export. See standards/adapters.md.\n *\n * The `typeof` check is not redundant with the types: hosts on plain JS reach\n * this at runtime with no compiler in front of them.\n */\nexport function createUserAdapter(\n { resolveUser = defaultResolveUser, loadUser }: { resolveUser?: ResolveUser; loadUser?: LoadUser } = {},\n): UserAdapter {\n if (typeof resolveUser !== 'function') {\n throw new TypeError('oauth-host: user adapter `resolveUser` must be a function');\n }\n if (loadUser !== undefined && typeof loadUser !== 'function') {\n throw new TypeError('oauth-host: user adapter `loadUser` must be a function');\n }\n return { resolveUser, ...(loadUser ? { loadUser } : {}) };\n}\n\nfunction normalizeScopes(input: CreateOAuthHostConfig['scopes']): ScopeSpec[] {\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError('oauth-host: `scopes` must be a non-empty array');\n }\n return input.map((s) => {\n const spec: ScopeSpec = typeof s === 'string' ? { id: s } : { ...s };\n if (!spec.id || typeof spec.id !== 'string') {\n throw new TypeError(`oauth-host: every scope needs a string \\`id\\` (got ${JSON.stringify(s)})`);\n }\n // RFC 6749 §3.3 — scope tokens are space-delimited, so a space in one makes\n // the whole parameter ambiguous and no error would point back here.\n if (/[\\s\"\\\\]/.test(spec.id)) {\n throw new TypeError(`oauth-host: scope id must not contain whitespace or quotes: '${spec.id}'`);\n }\n return {\n ...spec,\n label: spec.label ?? spec.id,\n oidc: spec.oidc ?? OIDC_SCOPES.has(spec.id),\n };\n });\n}\n\n/**\n * `defaultScopes`, checked against the catalog at boot.\n *\n * Undefined and empty are different things and only one of them is legal.\n * Undefined means \"no default\", which makes a `scope`-less `/authorize` a loud\n * error. An empty array would mean \"default to nothing\", which is the dead end\n * this key exists to remove — so it is refused here by name rather than\n * discovered as a token that can do nothing.\n */\nfunction normalizeDefaultScopes(\n input: CreateOAuthHostConfig['defaultScopes'],\n scopeIndex: Map<string, ScopeSpec>,\n): string[] | undefined {\n if (input === undefined) return undefined;\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError(\n 'oauth-host: `defaultScopes`, when given, must be a non-empty array of catalog scope ids. '\n + 'Omit the key entirely to require every client to send `scope`.',\n );\n }\n for (const id of input) {\n if (typeof id !== 'string' || !scopeIndex.has(id)) {\n throw new TypeError(\n `oauth-host: defaultScopes contains '${String(id)}', `\n + 'which is not in the configured scope catalog',\n );\n }\n }\n return [...input];\n}\n\nfunction normalizeResources(input: CreateOAuthHostConfig['resources']): ResourceSpec[] {\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError(\n 'oauth-host: `resources` must list at least one API. MCP clients send `resource` '\n + 'on every request (RFC 8707) and tokens are audience-bound to it.',\n );\n }\n return input.map((r) => {\n const spec: ResourceSpec = typeof r === 'string' ? { id: r } : { ...r };\n let url: URL;\n try {\n url = new URL(spec.id);\n } catch {\n throw new TypeError(`oauth-host: resource id must be an absolute URI: '${spec.id}'`);\n }\n // RFC 8707 §2 — the resource indicator carries no fragment, and comparison\n // is exact. Normalizing here means the comparison downstream can stay a\n // string equality rather than a URL parse on every token request.\n if (url.hash) {\n throw new TypeError(`oauth-host: resource id must not contain a fragment: '${spec.id}'`);\n }\n return { ...spec, label: spec.label ?? spec.id };\n });\n}\n\n/**\n * In-memory fixed-window counter.\n *\n * Per-process, so on N instances the effective limit is `max × N`. That is\n * stated rather than hidden, and `rateLimits.store` is how it becomes Redis.\n */\nfunction memoryStore(): RateLimitConfig['store'] & object {\n const buckets = new Map<string, { count: number; resetAt: number }>();\n return {\n async hit(key: string, windowMs: number) {\n const now = Date.now();\n const found = buckets.get(key);\n if (!found || found.resetAt <= now) {\n const fresh = { count: 1, resetAt: now + windowMs };\n buckets.set(key, fresh);\n // Opportunistic sweep: without it the map is an unbounded leak keyed by\n // client id and IP, which is attacker-controlled.\n if (buckets.size > 10_000) {\n for (const [k, v] of buckets) if (v.resetAt <= now) buckets.delete(k);\n }\n return fresh;\n }\n found.count += 1;\n return found;\n },\n };\n}\n\n/**\n * Parse one `allowedHosts` entry.\n *\n * The entry is a host, never a URL: accepting `https://claude.ai/` here would\n * invite a path, and a path in an allowlist reads like it constrains something\n * it does not. Reject the shapes that look permissive but are not.\n */\nfunction parseCimdHost(raw: unknown): CimdHostRule {\n if (typeof raw !== 'string' || !raw.trim()) {\n throw new TypeError(\n `oauth-host: clientIdMetadata.allowedHosts entries must be non-empty strings (got ${JSON.stringify(raw)})`,\n );\n }\n const entry = raw.trim().toLowerCase();\n if (/[/\\\\?#@\\s]/.test(entry) || entry.includes('://')) {\n throw new TypeError(\n `oauth-host: clientIdMetadata.allowedHosts takes a host, not a URL: '${raw}'. `\n + \"Write 'claude.ai' for that host exactly, or '.claude.ai' to include subdomains.\",\n );\n }\n const subdomains = entry.startsWith('.');\n const bare = subdomains ? entry.slice(1) : entry;\n const parts = /^([^:]+)(?::(\\d+))?$/.exec(bare);\n if (!parts || !parts[1]) {\n throw new TypeError(`oauth-host: clientIdMetadata.allowedHosts entry is not a hostname: '${raw}'`);\n }\n // A bare `*` reads as \"any host\", which is precisely the configuration this\n // key exists to prevent. Refuse it by name rather than letting it match\n // nothing and look like a typo.\n if (parts[1].includes('*')) {\n throw new TypeError(\n `oauth-host: clientIdMetadata.allowedHosts does not accept wildcards: '${raw}'. `\n + \"Use a leading dot ('.claude.ai') to admit subdomains of one host.\",\n );\n }\n return { host: parts[1], port: parts[2] ?? '', subdomains };\n}\n\n/**\n * CIMD config, resolved and validated fatally.\n *\n * The one rule worth restating: `allowedHosts` is required when `enabled`. An\n * authorization server that fetches arbitrary URLs on an unauthenticated\n * request parameter is an SSRF proxy, and defaulting this key to \"any\" would\n * ship that behaviour to whoever flipped `enabled` without reading the page.\n */\nfunction resolveCimd(\n input: ClientIdMetadataConfig | undefined,\n scopeIndex: Map<string, ScopeSpec>,\n): ResolvedCimd {\n const off: ResolvedCimd = {\n enabled: false,\n allowedHosts: [],\n cacheTtlMs: 3_600_000,\n fetchTimeoutMs: 5_000,\n maxBytes: 65_536,\n allowedScopes: [],\n failures: new Map(),\n };\n if (!input || !input.enabled) return off;\n\n if (!Array.isArray(input.allowedHosts) || input.allowedHosts.length === 0) {\n throw new TypeError(\n 'oauth-host: `clientIdMetadata.allowedHosts` must list at least one host when '\n + 'clientIdMetadata is enabled. There is no implicit \"any host\": the server fetches '\n + 'these URLs itself, on an unauthenticated request parameter.',\n );\n }\n\n const allowedScopes = input.allowedScopes ?? [...scopeIndex.keys()];\n if (!Array.isArray(allowedScopes) || allowedScopes.length === 0) {\n throw new TypeError('oauth-host: `clientIdMetadata.allowedScopes`, when given, must be non-empty');\n }\n for (const id of allowedScopes) {\n if (typeof id !== 'string' || !scopeIndex.has(id)) {\n throw new TypeError(\n `oauth-host: clientIdMetadata.allowedScopes contains '${String(id)}', `\n + 'which is not in the configured scope catalog',\n );\n }\n }\n\n const positive = (value: unknown, key: string, fallback: number): number => {\n if (value === undefined) return fallback;\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n throw new TypeError(`oauth-host: \\`clientIdMetadata.${key}\\` must be a positive number`);\n }\n return value;\n };\n\n return {\n enabled: true,\n allowedHosts: input.allowedHosts.map(parseCimdHost),\n cacheTtlMs: positive(input.cacheTtlMs, 'cacheTtlMs', 3_600_000),\n fetchTimeoutMs: positive(input.fetchTimeoutMs, 'fetchTimeoutMs', 5_000),\n maxBytes: positive(input.maxBytes, 'maxBytes', 65_536),\n allowedScopes: [...allowedScopes],\n failures: new Map(),\n };\n}\n\nexport function resolveConfig(config: CreateOAuthHostConfig): ResolvedContext {\n if (!config || typeof config !== 'object') {\n throw new TypeError('oauth-host: createOAuthHost(config) requires a config object');\n }\n\n const {\n connection,\n issuer,\n mountPath = '/oauth',\n consentUrl,\n loginUrl,\n returnParam = 'next',\n userAdapter,\n resolveUser,\n loadUser,\n grantContext,\n claims,\n subjectMode = 'public',\n pairwiseSalt,\n signing = {},\n rateLimits = {},\n tokenCache = {},\n modelNames,\n collectionPrefix,\n audit = {},\n cors = {},\n clockSkewMs = 0,\n clientIdMetadata,\n logger = NOOP_LOGGER,\n track = () => {},\n } = config;\n\n if (typeof issuer !== 'string' || !/^https?:\\/\\//.test(issuer)) {\n throw new TypeError(`oauth-host: \\`issuer\\` must be an absolute http(s) URL (got ${JSON.stringify(issuer)})`);\n }\n // Every metadata URL is built by concatenation. A trailing slash here yields\n // `https://x.com//token`, which some clients treat as a different origin.\n if (issuer.endsWith('/')) {\n throw new TypeError(`oauth-host: \\`issuer\\` must not end with a slash: '${issuer}'`);\n }\n if (!consentUrl || typeof consentUrl !== 'string') {\n throw new TypeError('oauth-host: `consentUrl` is required — it is where /authorize sends the user');\n }\n if (subjectMode === 'pairwise' && !pairwiseSalt) {\n throw new TypeError(\n 'oauth-host: `pairwiseSalt` is required when subjectMode is \"pairwise\". '\n + 'It is permanent: changing it changes every `sub` a partner has stored.',\n );\n }\n if (userAdapter && (resolveUser || loadUser)) {\n throw new TypeError(\n 'oauth-host: pass either `userAdapter` or the `resolveUser`/`loadUser` shorthands, not both',\n );\n }\n if (typeof track !== 'function') {\n throw new TypeError('oauth-host: `track` must be a function');\n }\n if (grantContext && (typeof grantContext.list !== 'function' || typeof grantContext.verify !== 'function')) {\n throw new TypeError('oauth-host: `grantContext` needs both `list()` and `verify()`');\n }\n\n const scopes = normalizeScopes(config.scopes);\n const resources = normalizeResources(config.resources);\n\n // A resource may narrow the catalog but cannot invent a scope — otherwise a\n // client could be granted something the consent screen has no label for.\n const scopeIndex = new Map(scopes.map((s) => [s.id, s]));\n for (const r of resources) {\n for (const s of r.scopes ?? []) {\n if (!scopeIndex.has(s)) {\n throw new TypeError(`oauth-host: resource '${r.id}' lists scope '${s}' which is not in the catalog`);\n }\n }\n }\n\n const defaultScopes = normalizeDefaultScopes(config.defaultScopes, scopeIndex);\n\n const models = createModels({\n connection,\n modelNames,\n collectionPrefix,\n auditRetentionDays: audit.retentionDays ?? 400,\n });\n\n const adapter = userAdapter\n ? createUserAdapter(userAdapter)\n : createUserAdapter({ resolveUser, loadUser });\n\n if (!adapter.loadUser) {\n // Not fatal — a host that never grants `profile`/`email` has nothing to\n // load. But it IS the reason those claims come back empty, and finding\n // that out from an empty /userinfo response costs an afternoon.\n logger.warn?.(\n 'oauth-host: no `loadUser` adapter — `profile`/`email` claims on /userinfo and '\n + 'the id_token will be empty, because those endpoints have no host session to read.',\n );\n }\n\n const store = rateLimits.store ?? memoryStore();\n\n // `/oauth`, `oauth/` and `/oauth/` must all produce the same metadata. This\n // is string concatenation downstream, so normalize once here rather than\n // defending against a double slash in nine endpoint URLs.\n const normalizedMount = `/${String(mountPath).replace(/^\\/+|\\/+$/g, '')}`;\n\n const ctx: ResolvedContext = {\n models,\n issuer,\n mountPath: normalizedMount === '/' ? '' : normalizedMount,\n resources,\n scopes,\n scopeIndex,\n defaultScopes,\n consentUrl,\n loginUrl,\n returnParam,\n resolveUser: adapter.resolveUser,\n async loadUser(userId) {\n return (await adapter.loadUser?.(userId)) ?? { id: userId };\n },\n grantContext,\n claims,\n ttl: { ...DEFAULT_TTL, ...config.ttl },\n subjectMode,\n pairwiseSalt,\n signing,\n rateLimits: {\n token: rateLimits.token ?? { max: 60, windowMs: 60_000 },\n authorize: rateLimits.authorize ?? { max: 60, windowMs: 60_000 },\n consent: rateLimits.consent ?? { max: 60, windowMs: 60_000 },\n hit: (key, windowMs) => store.hit(key, windowMs),\n },\n tokenCacheTtlMs: tokenCache.ttlMs ?? 0,\n cors: { tokenEndpoint: cors.tokenEndpoint ?? false, origins: cors.origins ?? [] },\n clockSkewMs,\n cimd: resolveCimd(clientIdMetadata, scopeIndex),\n logger,\n track,\n async audit(entry) {\n try {\n await models.Audit.create(entry);\n } catch (err) {\n // The audit log must never be the reason a token request fails. It is\n // evidence, not control flow.\n logger.error?.({ err, entry }, 'oauth-host: audit write failed');\n }\n },\n };\n\n return ctx;\n}\n","import type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport type { Logger } from '../../types/index.js';\n\n/**\n * Errors here are spec-shaped and loud — the opposite of the \"reject junk\n * quietly\" rule that governs a public ingest path.\n *\n * An authorization server that swallows bad input teaches an integrator\n * nothing and hides an attack. Every failure answers `{ error,\n * error_description }` with the RFC-mandated token, because clients switch on\n * `error` and a made-up code is indistinguishable from a broken server.\n * Volume is absorbed by rate limiting, not by silent drops.\n *\n * See standards/traps.md §19 (inverted for this package) and #6 — JSON on\n * throw, never Express's default HTML.\n */\nexport class OAuthError extends Error {\n status: number;\n\n code: string;\n\n description?: string;\n\n /** e.g. `WWW-Authenticate` on a 401 from the resource server. */\n headers?: Record<string, string>;\n\n constructor(\n status: number,\n code: string,\n description?: string,\n opts?: { headers?: Record<string, string> },\n ) {\n super(description ? `${code}: ${description}` : code);\n this.name = 'OAuthError';\n this.status = status;\n this.code = code;\n this.description = description;\n this.headers = opts?.headers;\n }\n\n toBody(): { error: string; error_description?: string } {\n return {\n error: this.code,\n ...(this.description ? { error_description: this.description } : {}),\n };\n }\n}\n\n/** RFC 6749 §5.2 — `invalid_client` is a 401 and carries no redirect. */\nexport const invalidClient = (d?: string) => new OAuthError(401, 'invalid_client', d);\nexport const invalidRequest = (d?: string) => new OAuthError(400, 'invalid_request', d);\nexport const invalidGrant = (d?: string) => new OAuthError(400, 'invalid_grant', d);\nexport const invalidScope = (d?: string) => new OAuthError(400, 'invalid_scope', d);\nexport const unsupportedGrantType = (d?: string) =>\n new OAuthError(400, 'unsupported_grant_type', d);\nexport const accessDenied = (d?: string) => new OAuthError(403, 'access_denied', d);\nexport const serverError = (d?: string) => new OAuthError(500, 'server_error', d);\n\n/**\n * An authorization-endpoint failure that must NOT be redirected back.\n *\n * The redirect-vs-render split is a security boundary, not a formatting\n * choice: an unrecognised `client_id` or an unregistered `redirect_uri` means\n * we have no proven-safe place to send the user, and redirecting anyway is the\n * open-redirect hole. Everything else redirects with `state` and `iss` intact.\n */\nexport class UnredirectableError extends OAuthError {\n constructor(code: string, description?: string) {\n super(400, code, description);\n this.name = 'UnredirectableError';\n }\n}\n\n/**\n * An authorization-endpoint failure the client IS allowed to be told about,\n * because `client_id` and `redirect_uri` have both already been validated\n * against the registration. RFC 6749 §4.1.2.1 — return it to `redirect_uri`\n * with `state` and, per RFC 9207, `iss`.\n */\nexport class RedirectableAuthError extends OAuthError {\n redirectUri: string;\n\n state?: string;\n\n constructor(code: string, description: string | undefined, redirectUri: string, state?: string) {\n super(400, code, description);\n this.name = 'RedirectableAuthError';\n this.redirectUri = redirectUri;\n this.state = state;\n }\n\n /** The full `redirect_uri` to 302 to, error parameters attached. */\n toRedirect(issuer: string): string {\n const url = new URL(this.redirectUri);\n url.searchParams.set('error', this.code);\n if (this.description) url.searchParams.set('error_description', this.description);\n if (this.state !== undefined) url.searchParams.set('state', this.state);\n url.searchParams.set('iss', issuer);\n return url.toString();\n }\n}\n\nexport type RawHandler = (\n req: Request,\n res: Response,\n next: NextFunction,\n) => unknown | Promise<unknown>;\n\n/**\n * Async handler wrapper.\n *\n * Without it a rejected promise reaches Express's default error handler, which\n * answers HTML. Every route in this package answers JSON, including on failure,\n * so a client that only knows how to parse `{ error }` never has to\n * special-case a 500. Test it by injecting a model whose method throws.\n * See standards/traps.md #6.\n */\nexport function wrap(logger: Logger, handler: RawHandler): RequestHandler {\n return async (req, res, next) => {\n try {\n await handler(req, res, next);\n } catch (err) {\n if (err instanceof OAuthError) {\n // Headers already flushed means we're mid-response — nothing useful\n // left to say, hand it to the host's handler to close out.\n if (res.headersSent) return next(err);\n if (err.headers) res.set(err.headers);\n return res.status(err.status).json(err.toBody());\n }\n logger.error?.({ err, path: req.originalUrl }, 'oauth-host: request failed');\n if (res.headersSent) return next(err);\n res.status(500).json({ error: 'server_error' });\n }\n };\n}\n","import express from 'express';\nimport type { RequestHandler, Router } from 'express';\nimport { wrap } from '../errors.js';\nimport type { ResolvedContext } from '../config.js';\nimport type { ResourceSpec } from '../../../types/index.js';\n\n/**\n * Discovery metadata — RFC 8414 (authorization server), OpenID Connect\n * Discovery, and RFC 9728 (protected resource).\n *\n * This router is mounted at the ORIGIN ROOT, not under `/oauth`: `/.well-known`\n * paths are defined relative to the issuer's origin and are not relocatable. It\n * is the one router in this package the host cannot choose a mount path for.\n *\n * Everything a client can reach is generated from ONE table below. Adding an\n * endpoint later (`introspection_endpoint`, `registration_endpoint`) is one row\n * in `ENDPOINTS`, not an edit in three documents that drift apart — which is\n * how a server ends up advertising a token endpoint it moved a year ago.\n */\n\n/** `metadata key` → path under the oauth router's mount. */\nconst ENDPOINTS: ReadonlyArray<readonly [key: string, path: string]> = [\n ['authorization_endpoint', '/authorize'],\n ['token_endpoint', '/token'],\n ['revocation_endpoint', '/revoke'],\n ['userinfo_endpoint', '/userinfo'],\n ['jwks_uri', '/jwks'],\n];\n\nconst WELL_KNOWN_AS = '/.well-known/oauth-authorization-server';\nconst WELL_KNOWN_OIDC = '/.well-known/openid-configuration';\nconst WELL_KNOWN_RESOURCE = '/.well-known/oauth-protected-resource';\n\n/**\n * Where a resource's RFC 9728 metadata lives.\n *\n * RFC 9728 §3.1: insert `/.well-known/oauth-protected-resource` between the\n * host and the path of the resource identifier. `https://api.example.com/mcp`\n * therefore publishes at `…/.well-known/oauth-protected-resource/mcp`, and a\n * resource that is a bare origin publishes at the unsuffixed path.\n *\n * `protect()` puts this exact URL in its `WWW-Authenticate` challenge, so the\n * two must agree — hence one function rather than two format strings.\n */\nexport function protectedResourceMetadataUrl(issuer: string, resourceId: string): string {\n return `${issuer}${WELL_KNOWN_RESOURCE}${identifierPath(resourceId)}`;\n}\n\n/**\n * The path component of an absolute identifier, `''` for a bare origin.\n *\n * Shared by the resource identifier (RFC 9728 §3.1) and the issuer identifier\n * (RFC 8414 §3.1) because both specs mandate the same transformation, and both\n * require the terminating `/` be removed before the segments are joined.\n */\nfunction identifierPath(identifier: string): string {\n const { pathname } = new URL(identifier);\n return pathname === '/' ? '' : pathname.replace(/\\/+$/, '');\n}\n\n/** Literal path → RegExp, so a path carrying `.` or `(` cannot become a pattern. */\nfunction escapeRe(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Match `/.well-known/<suffix>` and everything under it.\n *\n * A RegExp path, not `/*`: Express 4 and Express 5 disagree about wildcard\n * syntax (v5's path-to-regexp requires a name), and this package claims both in\n * its peer range. A RegExp means the same route works on either.\n */\nfunction wellKnownPattern(wellKnown: string): RegExp {\n return new RegExp(`^${escapeRe(wellKnown)}(?:/.*)?$`);\n}\n\n/**\n * One handler for every well-known endpoint that carries an inserted path.\n *\n * RFC 8414 §3.1 (issuer) and RFC 9728 §3.1 (resource) specify the *same*\n * transformation — the well-known segment goes BETWEEN the host and the\n * identifier's path — so they match the same way. Sharing the matcher is what\n * stops the two drifting: the failure this package already had was one endpoint\n * implementing the insertion and the other assuming a fixed path.\n *\n * `bare` answers the unsuffixed path, which is what an identifier with no path\n * component publishes at and what a client that ignores the transformation\n * asks for. Anything else is a 404 in JSON — serving `bare` for an arbitrary\n * suffix would hand a client the metadata of a server it did not ask about.\n */\nfunction wellKnownHandler(\n ctx: ResolvedContext,\n wellKnown: string,\n bare: Record<string, unknown>,\n bySuffix: Map<string, Record<string, unknown>>,\n describeMiss: (suffix: string) => string,\n): RequestHandler {\n return wrap(ctx.logger, (req, res) => {\n // Read the suffix off the path rather than a capture group: Express 4 and 5\n // expose RegExp captures differently, and `req.path` is the same string in\n // both.\n const suffix = req.path.slice(wellKnown.length).replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!suffix) return res.json(bare);\n const doc = bySuffix.get(suffix);\n if (!doc) {\n return res.status(404).json({ error: 'not_found', error_description: describeMiss(suffix) });\n }\n return res.json(doc);\n });\n}\n\nfunction authorizationServerMetadata(ctx: ResolvedContext, mountPath: string): Record<string, unknown> {\n const base = `${ctx.issuer}${mountPath === '/' ? '' : mountPath}`;\n const endpoints = Object.fromEntries(ENDPOINTS.map(([key, path]) => [key, `${base}${path}`]));\n\n return {\n issuer: ctx.issuer,\n ...endpoints,\n scopes_supported: ctx.scopes.map((s) => s.id),\n response_types_supported: ['code'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n // S256 only. `plain` is not implemented anywhere in this package, so\n // advertising it would be a lie a client would discover at redemption.\n code_challenge_methods_supported: ['S256'],\n // `none` is advertised only when CIMD is on. Listing it unconditionally\n // would tell every client that secretless authentication is available here,\n // and the only clients that can use it are the ones this server would then\n // refuse to register.\n token_endpoint_auth_methods_supported: [\n 'client_secret_basic',\n 'client_secret_post',\n ...(ctx.cimd.enabled ? ['none'] : []),\n ],\n // What tells Claude and ChatGPT to skip registration entirely and send\n // their metadata document URL as `client_id`.\n ...(ctx.cimd.enabled ? { client_id_metadata_document_supported: true } : {}),\n subject_types_supported: [ctx.subjectMode],\n id_token_signing_alg_values_supported: ['ES256'],\n // RFC 9207. Advertising it is what lets a client REQUIRE `iss` on the\n // authorization response and so refuse a mix-up attack.\n authorization_response_iss_parameter_supported: true,\n };\n}\n\nfunction protectedResourceMetadata(ctx: ResolvedContext, resource: ResourceSpec): Record<string, unknown> {\n return {\n resource: resource.id,\n authorization_servers: [ctx.issuer],\n scopes_supported: resource.scopes ?? ctx.scopes.map((s) => s.id),\n bearer_methods_supported: ['header'],\n };\n}\n\n/**\n * @param mountPath where the host mounts `createOAuthRouter`. The endpoint URLs\n * this document advertises are `issuer + mountPath + path`, and the host — not\n * the package — chooses that mount, so it has to be told. Default `/oauth`.\n */\nexport function createDiscoveryRouter(ctx: ResolvedContext, mountPath = '/oauth'): Router {\n const router = express.Router();\n\n const asMetadata = authorizationServerMetadata(ctx, mountPath);\n\n // RFC 8414 §3.1 — for an issuer WITH a path component the metadata lives at\n // `/.well-known/oauth-authorization-server/{path}`: the well-known segment is\n // inserted between the host and the issuer's path, never appended to it. An\n // issuer of `https://example.com/api` therefore publishes at\n // `…/.well-known/oauth-authorization-server/api`, and a bare-origin issuer at\n // the unsuffixed path. A host that only served the fixed path would be\n // undiscoverable to a spec-following client.\n const issuerSuffix = identifierPath(ctx.issuer).replace(/^\\//, '');\n const asBySuffix = new Map(issuerSuffix ? [[issuerSuffix, asMetadata]] : []);\n const notThisIssuer = (suffix: string) =>\n `This authorization server's issuer is '${ctx.issuer}', which does not publish at '${suffix}'`;\n\n // RFC 8414 and OIDC Discovery are the same document for this server: one\n // grant type, one signing alg, one set of endpoints. Serving one object from\n // every path is what keeps them from diverging.\n const serveAs = wrap(ctx.logger, (_req, res) => res.json(asMetadata));\n router.get(\n wellKnownPattern(WELL_KNOWN_AS),\n wellKnownHandler(ctx, WELL_KNOWN_AS, asMetadata, asBySuffix, notThisIssuer),\n );\n router.get(\n wellKnownPattern(WELL_KNOWN_OIDC),\n wellKnownHandler(ctx, WELL_KNOWN_OIDC, asMetadata, asBySuffix, notThisIssuer),\n );\n\n // The counterintuitive one. OpenID Connect Discovery 1.0 §4.1 APPENDS\n // `/.well-known/openid-configuration` to the issuer, so an issuer of\n // `https://example.com/api` publishes at `https://example.com/api/.well-known/\n // openid-configuration` — the opposite placement to RFC 8414 §3.1 above, for\n // the byte-identical document. RFC 8414 §5 names the disagreement and says a\n // deployment may have to answer both during the transition, so we answer both\n // rather than pick a winner and be undiscoverable to half the clients.\n //\n // Only registered when the issuer has a path: without one this collapses onto\n // the fixed path the route above already owns.\n if (issuerSuffix) {\n router.get(new RegExp(`^${escapeRe(`/${issuerSuffix}${WELL_KNOWN_OIDC}`)}/?$`), serveAs);\n }\n\n // Resource metadata keyed by the path suffix a request carries. Built once:\n // the catalog is fixed at boot and these are the hottest unauthenticated\n // reads in the package.\n const bySuffix = new Map(\n ctx.resources.map((r) => [identifierPath(r.id).replace(/^\\//, ''), protectedResourceMetadata(ctx, r)]),\n );\n // The bare path serves the first configured resource — the degenerate\n // single-API host never has to know suffixes exist.\n const firstResource = protectedResourceMetadata(ctx, ctx.resources[0]!);\n router.get(\n wellKnownPattern(WELL_KNOWN_RESOURCE),\n wellKnownHandler(\n ctx,\n WELL_KNOWN_RESOURCE,\n firstResource,\n bySuffix,\n (suffix) => `No resource is registered at '${suffix}'`,\n ),\n );\n\n return router;\n}\n","import {\n createHash,\n createHmac,\n randomBytes,\n timingSafeEqual as nodeTimingSafeEqual,\n} from 'node:crypto';\n\n/**\n * Every credential this package hands out is generated here, and nothing is\n * ever stored in a form that can be replayed.\n *\n * Codes, tokens and client secrets are 256 bits of CSPRNG output, so a plain\n * SHA-256 is the right digest and bcrypt would be a throughput bug with no\n * security gain — password hashing is slow to defend against low-entropy\n * inputs, and there are none here. Lookup is by hash; comparison of anything\n * secret-derived is constant-time.\n */\n\n/** 32 bytes, base64url, no padding. ~43 chars. */\nexport function randomToken(bytes = 32): string {\n return randomBytes(bytes).toString('base64url');\n}\n\nexport function sha256(value: string): string {\n return createHash('sha256').update(value).digest('base64url');\n}\n\n/**\n * Constant-time compare of two strings.\n *\n * Length is compared first and leaks — that is fine here, every input is a\n * fixed-width digest or a fixed-width token. Comparing digests rather than the\n * raw values keeps the buffers equal-length for `timingSafeEqual`, which throws\n * on a length mismatch.\n */\nexport function safeEqual(a: string, b: string): boolean {\n const bufA = Buffer.from(sha256(a));\n const bufB = Buffer.from(sha256(b));\n if (bufA.length !== bufB.length) return false;\n return nodeTimingSafeEqual(bufA, bufB);\n}\n\n/** RFC 7636 §4.6 — S256 only. `plain` is not accepted anywhere in this package. */\nexport function verifyPkce(verifier: string, challenge: string): boolean {\n // RFC 7636 §4.1 bounds the verifier; an unbounded one is a hashing DoS.\n if (verifier.length < 43 || verifier.length > 128) return false;\n if (!/^[A-Za-z0-9\\-._~]+$/.test(verifier)) return false;\n return safeEqual(sha256(verifier), challenge);\n}\n\n/**\n * Pairwise `sub` (OIDC Core §8.1).\n *\n * Deterministic so it survives a database restore, and salted so one client\n * cannot correlate its users with another's. The value is permanent for a\n * (user, client) pair — partners store it as their primary key.\n */\nexport function pairwiseSubject(userId: string, clientId: string, salt: string): string {\n return createHmac('sha256', salt).update(`${clientId}:${userId}`).digest('base64url');\n}\n\n/** A client identifier. Opaque, URL-safe, and not guessable from the name. */\nexport function generateClientId(): string {\n return randomToken(16);\n}\n\n/** A client secret. Returned once at creation; only its digest is stored. */\nexport function generateClientSecret(): string {\n return randomToken(32);\n}\n","/**\n * The one place a `redirect_uri` is compared.\n *\n * Everything here is byte-exact except one carve-out, and the carve-out is\n * mandated: RFC 8252 §7.3 requires an authorization server to allow the PORT of\n * a **loopback** redirect URI to vary, because a native client binds an\n * ephemeral port per session and cannot know it at registration time. Claude\n * Code registers `http://127.0.0.1/callback` and then connects from\n * `http://127.0.0.1:54321/callback`; comparing those as strings fails every\n * authorization with an unredirectable `invalid_request` that looks like the\n * client's bug.\n *\n * Nothing else is relaxed, and the relaxation is confined to this file so that\n * it stays reviewable as a single rule. Scheme, host, path, query, fragment and\n * userinfo all still have to match exactly, and a non-loopback host never\n * matches a different port — a general \"ports don't count\" comparison is the\n * open-redirect hole the check ORDER in `services/authorize.ts` exists to\n * prevent, and that file's header says so.\n */\n\n/**\n * Hosts that are loopback, exhaustively.\n *\n * A name, not a range: `127.0.0.2` is loopback to the kernel but is not a value\n * any client is documented to use, and admitting a range widens the carve-out\n * for nothing. `[::1]` carries its brackets because that is what\n * `URL.hostname` returns for an IPv6 literal.\n */\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);\n\n/** Is this a loopback redirect URI — the only shape whose port may vary? */\nexport function isLoopbackRedirectUri(value: string): boolean {\n try {\n return LOOPBACK_HOSTS.has(new URL(value).hostname);\n } catch {\n return false;\n }\n}\n\n/**\n * Does a presented `redirect_uri` match a registered one?\n *\n * `registered` is the value on the client registration (or, at the token\n * endpoint, the value bound onto the authorization code); `presented` is what\n * arrived on this request. The order matters only for readability — the\n * relation is symmetric.\n */\nexport function redirectUriMatches(registered: string, presented: string): boolean {\n // The overwhelmingly common case, and the only one for a hosted client.\n if (registered === presented) return true;\n\n let a: URL;\n let b: URL;\n try {\n a = new URL(registered);\n b = new URL(presented);\n } catch {\n // An unparseable value cannot be proven safe, so it is not a match. It is\n // also already impossible on the registered side — `clients.create()`\n // parses every entry.\n return false;\n }\n\n // BOTH sides must be loopback. A registered loopback URI does not admit a\n // remote presented one, and a registered remote URI never admits anything but\n // itself.\n if (!LOOPBACK_HOSTS.has(a.hostname) || !LOOPBACK_HOSTS.has(b.hostname)) return false;\n\n // `localhost` and `127.0.0.1` are different registrations on purpose: a\n // client that wants both registers both (Claude Code does). Resolving one to\n // the other would mean this package deciding what the client's DNS says.\n return (\n a.protocol === b.protocol\n && a.hostname === b.hostname\n && a.username === b.username\n && a.password === b.password\n && a.pathname === b.pathname\n && a.search === b.search\n && a.hash === b.hash\n );\n}\n\n/** The list form — a client's registration is always a list. */\nexport function redirectUriRegistered(registered: readonly string[], presented: string): boolean {\n return registered.some((entry) => redirectUriMatches(entry, presented));\n}\n","import { OAuthError, invalidGrant, invalidScope } from '../errors.js';\nimport { randomToken, sha256, verifyPkce } from '../crypto.js';\nimport { redirectUriMatches } from '../redirect-uris.js';\nimport type { ResolvedContext } from '../config.js';\nimport type {\n OAuthCodeDoc,\n OAuthGrantDoc,\n OAuthTokenDoc,\n UserId,\n} from '../../../types/index.js';\n\n/**\n * The token core — the security surface of this package, and the reason it is\n * unit-tested before any HTTP exists (build plan §13 step 2).\n *\n * Three invariants everything here exists to hold:\n *\n * 1. **Nothing replayable is stored.** Codes and tokens are 256-bit CSPRNG\n * strings; only their SHA-256 is written, and every lookup is by hash. The\n * raw value exists in one place: the return value of the call that minted it.\n * 2. **Single use is enforced by the database, not by a read-then-write.**\n * `findOneAndUpdate({ consumedAt: null })` is atomic; an `if (doc.consumedAt)`\n * check is a race two concurrent redemptions win.\n * 3. **A replay is an attack signal, not a duplicate to dedupe.** This is the\n * one place the house \"idempotency\" rule inverts (traps §16): a second\n * redemption of a code, or a second use of a rotated refresh token, means\n * the credential leaked. The correct response is to revoke every token\n * descended from it and say so loudly — silently returning the same tokens\n * hands the attacker exactly what they asked for.\n */\n\nexport interface IssuedTokens {\n accessToken: string;\n refreshToken?: string;\n expiresIn: number;\n scopes: string[];\n audience: string[];\n grantId: string;\n familyId: string;\n userId: UserId;\n contextId: string | null;\n}\n\n/**\n * The family id is derived from the code, not random.\n *\n * A replayed code arrives with nothing but its own hash, and the family it\n * spawned has to be revocable from that alone. Deriving instead of storing a\n * back-reference means the link cannot go missing. It stays unguessable because\n * the input is a hash of 256 bits of CSPRNG output.\n */\nfunction familyFor(codeHash: string): string {\n return sha256(`family:${codeHash}`);\n}\n\nconst parseScopes = (scope?: string): string[] =>\n (scope ?? '').split(/\\s+/).filter(Boolean);\n\n/** RFC 8707 §2 — the code for a resource the token may not be bound to. */\nconst invalidTarget = (d: string) => new OAuthError(400, 'invalid_target', d);\n\nasync function liveGrant(\n ctx: ResolvedContext,\n grantId: OAuthCodeDoc['grantId'],\n): Promise<OAuthGrantDoc> {\n const grant = await ctx.models.Grant.findById(grantId);\n if (!grant || grant.revokedAt) {\n throw invalidGrant('the authorization behind this token has been revoked');\n }\n return grant;\n}\n\n/**\n * Atomically consume a code.\n *\n * Consumption happens BEFORE validation, deliberately. A code that fails its\n * `redirect_uri` or PKCE check has still been presented, and leaving it live\n * for a second attempt is what turns a failed injection into a retried one.\n * The cost is that a client bug burns the code — which is the behaviour the\n * spec asks for anyway.\n */\nexport async function consumeCode(\n ctx: ResolvedContext,\n rawCode: string,\n opts: { clientId: string; redirectUri: string; codeVerifier: string },\n): Promise<OAuthCodeDoc> {\n const codeHash = sha256(rawCode);\n const now = new Date();\n\n const code = await ctx.models.Code.findOneAndUpdate(\n { codeHash, consumedAt: null },\n { $set: { consumedAt: now } },\n { returnDocument: 'after' },\n );\n\n if (!code) {\n const replayed = await ctx.models.Code.findOne({ codeHash });\n if (replayed) {\n const familyId = familyFor(codeHash);\n const revoked = await revokeFamily(ctx, familyId, 'code_replay');\n await ctx.audit({\n type: 'code_replay',\n actor: 'client',\n clientId: opts.clientId,\n userId: replayed.userId,\n grantId: replayed.grantId,\n meta: { familyId, tokensRevoked: revoked },\n });\n ctx.logger.warn?.(\n { clientId: opts.clientId, familyId },\n 'oauth-host: authorization code replayed — family revoked',\n );\n }\n // Same answer either way: an attacker must not learn whether the code was\n // real-but-spent or never existed.\n throw invalidGrant('authorization code is invalid, expired, or already used');\n }\n\n if (code.expiresAt.getTime() <= now.getTime()) {\n throw invalidGrant('authorization code has expired');\n }\n if (code.clientId !== opts.clientId) {\n throw invalidGrant('authorization code was issued to a different client');\n }\n // RFC 6749 §4.1.3 — matched against the value bound at /authorize, through\n // the SAME comparison that bound it. A prefix or origin comparison here is\n // the classic redirect-hijack hole; two comparisons that disagree is the\n // subtler version of it, where a URI passes one endpoint and fails the other.\n if (!redirectUriMatches(code.redirectUri, opts.redirectUri)) {\n throw invalidGrant('redirect_uri does not match the one the code was issued for');\n }\n if (!verifyPkce(opts.codeVerifier ?? '', code.codeChallenge)) {\n throw invalidGrant('PKCE verification failed');\n }\n\n return code;\n}\n\nasync function mintPair(\n ctx: ResolvedContext,\n args: {\n grant: OAuthGrantDoc;\n clientId: string;\n userId: UserId;\n contextId: string | null;\n scopes: string[];\n audience: string[];\n familyId: string;\n familyExpiresAt: Date;\n parentId?: OAuthTokenDoc['_id'] | null;\n },\n): Promise<IssuedTokens> {\n const now = Date.now();\n const accessToken = randomToken();\n const refreshToken = randomToken();\n const common = {\n clientId: args.clientId,\n userId: args.userId,\n grantId: args.grant._id,\n contextId: args.contextId,\n scopes: args.scopes,\n audience: args.audience,\n familyId: args.familyId,\n };\n\n await ctx.models.Token.create({\n ...common,\n kind: 'access',\n tokenHash: sha256(accessToken),\n expiresAt: new Date(now + ctx.ttl.accessToken * 1000),\n });\n await ctx.models.Token.create({\n ...common,\n kind: 'refresh',\n tokenHash: sha256(refreshToken),\n parentId: args.parentId ?? null,\n // `expiresAt` is the SLIDING window and is what the TTL index reaps;\n // `familyExpiresAt` is the absolute ceiling and is copied unchanged onto\n // every rotation, so no amount of refreshing extends it.\n expiresAt: new Date(now + ctx.ttl.refreshToken * 1000),\n familyExpiresAt: args.familyExpiresAt,\n });\n\n await ctx.models.Grant.updateOne({ _id: args.grant._id }, { $set: { lastUsedAt: new Date(now) } });\n\n return {\n accessToken,\n refreshToken,\n expiresIn: ctx.ttl.accessToken,\n scopes: args.scopes,\n audience: args.audience,\n grantId: String(args.grant._id),\n familyId: args.familyId,\n userId: args.userId,\n contextId: args.contextId,\n };\n}\n\nexport async function issueForCode(\n ctx: ResolvedContext,\n code: OAuthCodeDoc,\n): Promise<IssuedTokens> {\n const grant = await liveGrant(ctx, code.grantId);\n const issued = await mintPair(ctx, {\n grant,\n clientId: code.clientId,\n userId: code.userId,\n contextId: code.contextId,\n scopes: code.scopes,\n // Audience comes from the resources bound at /authorize, which were already\n // checked against the client's registration. Never from the token request.\n audience: code.resources,\n familyId: familyFor(code.codeHash),\n familyExpiresAt: new Date(Date.now() + ctx.ttl.refreshAbsolute * 1000),\n });\n\n ctx.track({\n type: 'oauth.token_issued',\n userId: issued.userId,\n clientId: code.clientId,\n grantId: issued.grantId,\n contextId: issued.contextId ?? undefined,\n scopes: issued.scopes,\n });\n await ctx.audit({\n type: 'token_issued',\n actor: 'client',\n clientId: code.clientId,\n userId: code.userId,\n grantId: grant._id,\n meta: { familyId: issued.familyId, scopes: issued.scopes, audience: issued.audience },\n });\n return issued;\n}\n\n/**\n * Rotating refresh with reuse detection.\n *\n * Rotation is what makes theft detectable: because the old token is consumed\n * the instant a new one is minted, the *second* presentation can only come from\n * someone who is not the holder of the current one. Which of the two is the\n * attacker is unknowable, so both lose — the whole family dies.\n */\nexport async function rotateRefresh(\n ctx: ResolvedContext,\n rawRefresh: string,\n opts: { clientId: string; scope?: string; resources?: string[] },\n): Promise<IssuedTokens> {\n const tokenHash = sha256(rawRefresh);\n const now = new Date();\n\n const token = await ctx.models.Token.findOneAndUpdate(\n { tokenHash, kind: 'refresh', consumedAt: null, revokedAt: null },\n { $set: { consumedAt: now } },\n { returnDocument: 'after' },\n );\n\n if (!token) {\n const known = await ctx.models.Token.findOne({ tokenHash, kind: 'refresh' });\n if (known?.consumedAt) {\n const revoked = await revokeFamily(ctx, known.familyId, 'refresh_reuse_detected');\n ctx.track({\n type: 'oauth.refresh_reuse_detected',\n userId: known.userId,\n clientId: known.clientId,\n grantId: String(known.grantId),\n contextId: known.contextId ?? undefined,\n scopes: known.scopes,\n meta: { familyId: known.familyId, tokensRevoked: revoked },\n });\n await ctx.audit({\n type: 'refresh_reuse_detected',\n actor: 'client',\n clientId: known.clientId,\n userId: known.userId,\n grantId: known.grantId,\n meta: { familyId: known.familyId, tokensRevoked: revoked },\n });\n ctx.logger.warn?.(\n { clientId: known.clientId, familyId: known.familyId },\n 'oauth-host: rotated refresh token reused — family revoked',\n );\n }\n throw invalidGrant('refresh token is invalid, expired, or already used');\n }\n\n if (token.clientId !== opts.clientId) {\n // A refresh token presented by a client it was not issued to is theft, not\n // a mistake — there is no flow that produces it.\n await revokeFamily(ctx, token.familyId, 'refresh_wrong_client');\n await ctx.audit({\n type: 'refresh_wrong_client',\n actor: 'client',\n clientId: opts.clientId,\n userId: token.userId,\n grantId: token.grantId,\n meta: { familyId: token.familyId, issuedTo: token.clientId },\n });\n throw invalidGrant('refresh token was issued to a different client');\n }\n if (token.expiresAt.getTime() <= now.getTime()) {\n throw invalidGrant('refresh token has expired');\n }\n if (token.familyExpiresAt && token.familyExpiresAt.getTime() <= now.getTime()) {\n // The ceiling exists so a compromised-but-actively-refreshed token cannot\n // live forever. Past it, re-consent is the only way back.\n await revokeFamily(ctx, token.familyId, 'family_absolute_expiry');\n throw invalidGrant('refresh token family has reached its absolute lifetime; re-authorization is required');\n }\n\n const grant = await liveGrant(ctx, token.grantId);\n\n // Re-checked on EVERY refresh, not just at consent: a grant made as an\n // employee has to die when the employment does, and the only moment we are\n // guaranteed to be asked again is this one.\n //\n // `verify` gets the user through `loadUser`, not a bare `{ id }`. There is no\n // host session on this band, but there IS an adapter for exactly this — the\n // one `/userinfo` already uses — and a rule like \"a member of this account OR\n // an admin\" cannot be written against an id alone without the host re-reading\n // the same user on every single refresh. With no `loadUser` configured\n // `ctx.loadUser` still answers `{ id }`, so this costs nothing it did not\n // already cost.\n if (ctx.grantContext && token.contextId !== null) {\n const stillAllowed = await ctx.grantContext.verify(\n await ctx.loadUser(token.userId),\n token.contextId,\n );\n if (!stillAllowed) {\n await ctx.models.Grant.updateOne(\n { _id: grant._id, revokedAt: null },\n { $set: { revokedAt: now, revokedBy: 'system' } },\n );\n await revokeFamily(ctx, token.familyId, 'context_membership_ended');\n await ctx.audit({\n type: 'grant_revoked',\n actor: 'system',\n clientId: token.clientId,\n userId: token.userId,\n grantId: token.grantId,\n meta: { reason: 'context_membership_ended', contextId: token.contextId },\n });\n throw invalidGrant('the context this authorization was granted for is no longer available');\n }\n }\n\n // Downscoping only (RFC 6749 §6). The ceiling is the intersection of what\n // this token carries and what the grant still says — a grant narrowed after\n // issuance must not be widened back by a refresh.\n const ceiling = token.scopes.filter((s) => grant.scopes.includes(s));\n const requested = parseScopes(opts.scope);\n const scopes = requested.length ? requested : ceiling;\n for (const s of scopes) {\n if (!ceiling.includes(s)) {\n throw invalidScope(`scope '${s}' was not granted; a refresh may only narrow the scope set`);\n }\n }\n\n const audience = opts.resources?.length ? opts.resources : token.audience;\n for (const r of audience) {\n if (!token.audience.includes(r)) {\n throw invalidTarget(`resource '${r}' is not one this authorization is bound to`);\n }\n }\n\n const issued = await mintPair(ctx, {\n grant,\n clientId: token.clientId,\n userId: token.userId,\n contextId: token.contextId,\n scopes,\n audience,\n familyId: token.familyId,\n familyExpiresAt: token.familyExpiresAt ?? new Date(now.getTime() + ctx.ttl.refreshAbsolute * 1000),\n parentId: token._id,\n });\n\n ctx.track({\n type: 'oauth.token_refreshed',\n userId: issued.userId,\n clientId: token.clientId,\n grantId: issued.grantId,\n contextId: issued.contextId ?? undefined,\n scopes: issued.scopes,\n });\n return issued;\n}\n\n/** Kill every token descended from one authorization code. Returns the count. */\nexport async function revokeFamily(\n ctx: ResolvedContext,\n familyId: string,\n reason: string,\n): Promise<number> {\n const { modifiedCount = 0 } = await ctx.models.Token.updateMany(\n { familyId, revokedAt: null },\n { $set: { revokedAt: new Date() } },\n );\n if (modifiedCount) {\n ctx.logger.info?.({ familyId, reason, tokensRevoked: modifiedCount }, 'oauth-host: token family revoked');\n }\n return modifiedCount;\n}\n\n/**\n * Kill every token issued under a grant.\n *\n * The grant is the consent record and outlives its tokens, so revoking it has\n * to reach them explicitly — otherwise \"revoke access\" means \"expire in an\n * hour\". `introspectAccessToken` re-checks the grant for the same reason.\n */\nexport async function revokeGrantTokens(ctx: ResolvedContext, grantId: unknown): Promise<number> {\n const { modifiedCount = 0 } = await ctx.models.Token.updateMany(\n { grantId: grantId as never, revokedAt: null },\n { $set: { revokedAt: new Date() } },\n );\n return modifiedCount;\n}\n\n/**\n * Resource-server lookup. Null means \"do not serve this request\" — unknown,\n * expired, revoked, or belonging to a grant that has since been revoked.\n */\n/**\n * The opt-in introspection cache.\n *\n * Keyed by token hash, never by the raw token — a cache key is the easiest\n * thing in a process to end up in a heap dump or a log line. Disabled at\n * `tokenCacheTtlMs === 0`, which is the default, because every millisecond of\n * TTL is a millisecond in which a revoked token still opens the door. Sized\n * against the number of tokens in flight rather than left unbounded: the key\n * space is attacker-influenced.\n */\nconst CACHE_MAX_ENTRIES = 10_000;\nconst introspectionCache = new Map<string, { doc: OAuthTokenDoc; until: number }>();\n\nfunction cacheGet(ctx: ResolvedContext, hash: string): OAuthTokenDoc | null {\n if (ctx.tokenCacheTtlMs <= 0) return null;\n const hit = introspectionCache.get(hash);\n if (!hit) return null;\n if (hit.until <= Date.now()) {\n introspectionCache.delete(hash);\n return null;\n }\n return hit.doc;\n}\n\nfunction cachePut(ctx: ResolvedContext, hash: string, doc: OAuthTokenDoc): void {\n if (ctx.tokenCacheTtlMs <= 0) return;\n if (introspectionCache.size >= CACHE_MAX_ENTRIES) {\n // Cheapest bounded eviction that cannot be gamed into keeping a revoked\n // token alive: drop the oldest insertion. Map preserves insertion order.\n const oldest = introspectionCache.keys().next().value;\n if (oldest !== undefined) introspectionCache.delete(oldest);\n }\n // Never cache past the token's own expiry — a 60s cache on a token with 5s\n // left would extend it.\n const until = Math.min(Date.now() + ctx.tokenCacheTtlMs, doc.expiresAt.getTime());\n introspectionCache.set(hash, { doc, until });\n}\n\n/** Drop a token from the cache the moment it is revoked, so revocation stays instant. */\nexport function forgetCachedToken(tokenHash: string): void {\n introspectionCache.delete(tokenHash);\n}\n\nexport async function introspectAccessToken(\n ctx: ResolvedContext,\n raw: string,\n): Promise<OAuthTokenDoc | null> {\n const hash = sha256(raw);\n const cached = cacheGet(ctx, hash);\n if (cached) return cached;\n\n const token = await ctx.models.Token.findOne({ tokenHash: hash, kind: 'access' });\n if (!token) return null;\n if (token.revokedAt) return null;\n if (token.expiresAt.getTime() <= Date.now()) return null;\n\n // A live token whose grant died must not work. Skipping this read is how\n // \"revocation is instant\" quietly becomes \"revocation takes an hour\".\n const grant = await ctx.models.Grant.findById(token.grantId, { revokedAt: 1 });\n if (!grant || grant.revokedAt) return null;\n\n cachePut(ctx, hash, token);\n return token;\n}\n\n/**\n * RFC 7009 — revocation is the one genuinely idempotent operation here.\n *\n * An unknown token is a 200: the client's goal (this credential does not work)\n * is already true, and answering 404 turns the endpoint into an oracle for\n * which tokens exist.\n */\nexport async function revokeToken(\n ctx: ResolvedContext,\n raw: string,\n clientId: string,\n): Promise<void> {\n const token = await ctx.models.Token.findOne({ tokenHash: sha256(raw) });\n if (!token) return;\n forgetCachedToken(token.tokenHash);\n // RFC 7009 §2.1 — a client may not revoke another client's token. Still a\n // 200, still nothing revoked.\n if (token.clientId !== clientId) return;\n\n if (token.kind === 'refresh') {\n await revokeFamily(ctx, token.familyId, 'client_revocation');\n } else {\n await ctx.models.Token.updateOne(\n { _id: token._id, revokedAt: null },\n { $set: { revokedAt: new Date() } },\n );\n }\n await ctx.audit({\n type: 'token_revoked',\n actor: 'client',\n clientId,\n userId: token.userId,\n grantId: token.grantId,\n meta: { kind: token.kind, familyId: token.familyId },\n });\n}\n","import type { Request, RequestHandler, Response } from 'express';\nimport { wrap } from './errors.js';\nimport { protectedResourceMetadataUrl } from './routes/discovery.js';\nimport { introspectAccessToken } from './services/tokens.js';\nimport type { ResolvedContext } from './config.js';\nimport type { OAuthHostInstance, ProtectOptions } from '../../types/index.js';\n\n/**\n * The resource-server middleware.\n *\n * app.use('/mcp', oauth.protect('contacts.read'), mcpRouter)\n *\n * Two things in here are load-bearing beyond \"check a token\":\n *\n * 1. **The `WWW-Authenticate` challenge carries `resource_metadata`.** That is\n * how an MCP client that has never heard of this server discovers where to\n * authorize: it calls the API, gets a 401, reads the metadata URL out of the\n * challenge, and walks from there to the authorization server. Without that\n * parameter the whole discovery chain is a dead end and the only fix is\n * out-of-band configuration. It is the single most important line here.\n *\n * 2. **Audience is enforced, not merely recorded.** A token minted for another\n * resource is rejected even though it is perfectly valid — the confused-deputy\n * defense RFC 8707 and the MCP authorization spec both require. Skipping it\n * turns every resource behind one issuer into a proxy for all the others.\n */\nexport function createProtect(ctx: ResolvedContext): OAuthHostInstance['protect'] {\n const declared = new Set(ctx.resources.map((r) => r.id));\n\n return function protect(scopes?: string | string[], opts: ProtectOptions = {}): RequestHandler {\n const required = scopes === undefined ? [] : Array.isArray(scopes) ? scopes : [scopes];\n const resource = opts.resource ?? ctx.resources[0]!.id;\n const mode = opts.mode ?? 'all';\n\n // Fail at mount, not on the first request. A typo'd resource here means\n // every token is the wrong audience, and the symptom (universal 401s) does\n // not point at the guard that caused it.\n if (!declared.has(resource)) {\n throw new TypeError(\n `oauth-host: protect({ resource: '${resource}' }) is not one of the configured resources `\n + `(${[...declared].join(', ')})`,\n );\n }\n for (const s of required) {\n if (!ctx.scopeIndex.has(s)) {\n throw new TypeError(`oauth-host: protect() requires scope '${s}', which is not in the scope catalog`);\n }\n }\n\n const metadataUrl = protectedResourceMetadataUrl(ctx.issuer, resource);\n\n return wrap(ctx.logger, async (req, res, next) => {\n const raw = bearerFromHeader(req);\n // RFC 6750 §3.1: a request with no credentials at all gets the bare\n // challenge — no `error`, because nothing was wrong with what was sent.\n if (!raw) return challenge(res, 401, metadataUrl);\n\n const token = await introspectAccessToken(ctx, raw);\n if (!token) {\n return challenge(res, 401, metadataUrl, {\n error: 'invalid_token',\n error_description: 'The access token is expired, revoked or unknown',\n });\n }\n\n if (!token.audience.includes(resource)) {\n // Deliberately `invalid_token` and not `insufficient_scope`: from this\n // resource's point of view the token is not addressed to it at all, and\n // saying \"wrong audience\" out loud would confirm the token is otherwise\n // good to a caller who stole it for a different API.\n return challenge(res, 401, metadataUrl, {\n error: 'invalid_token',\n error_description: 'The access token was not issued for this resource',\n });\n }\n\n const held = new Set(token.scopes);\n const ok = mode === 'any'\n ? required.length === 0 || required.some((s) => held.has(s))\n : required.every((s) => held.has(s));\n if (!ok) {\n return challenge(res, 403, metadataUrl, {\n error: 'insufficient_scope',\n error_description: `Requires ${mode === 'any' ? 'one of' : 'all of'}: ${required.join(' ')}`,\n scope: required.join(' '),\n });\n }\n\n // The contract `mcp-server` consumes — fixed in the build plan §6. Ids are\n // stringified here so a consumer never has to know they were ObjectIds.\n req.oauth = {\n userId: token.userId,\n clientId: token.clientId,\n contextId: token.contextId ?? null,\n scopes: token.scopes,\n grantId: String(token.grantId),\n tokenId: String(token._id),\n audience: token.audience,\n };\n return next();\n });\n };\n}\n\n/**\n * The header, and only the header.\n *\n * RFC 6750 also describes a form body and a query parameter; both are\n * deliberately unsupported. A token in a query string lands in access logs,\n * `Referer` headers and browser history, and the protected-resource metadata\n * this package publishes says `bearer_methods_supported: [\"header\"]`.\n */\nfunction bearerFromHeader(req: Request): string | null {\n const header = req.headers.authorization;\n if (!header) return null;\n const match = /^Bearer +([^\\s]+)$/i.exec(header);\n return match ? match[1]! : null;\n}\n\nfunction challenge(\n res: Response,\n status: number,\n metadataUrl: string,\n params: { error?: string; error_description?: string; scope?: string } = {},\n): Response {\n const parts = [\n ...Object.entries(params).map(([k, v]) => `${k}=\"${String(v).replace(/\"/g, '')}\"`),\n `resource_metadata=\"${metadataUrl}\"`,\n ];\n res.set('WWW-Authenticate', `Bearer ${parts.join(', ')}`);\n // The challenge omits `error` when nothing was presented, but the body still\n // has to say something a JSON client can switch on.\n return res.status(status).json({\n error: params.error ?? 'invalid_request',\n error_description: params.error_description ?? 'Missing bearer token',\n });\n}\n","import type { Request, RequestHandler } from 'express';\nimport type { ResolvedContext } from './config.js';\n\n/**\n * A thin middleware over `ctx.rateLimits`.\n *\n * Brute force on `/token` is the classic authorization-server failure, and the\n * counter itself lives in config so a host can make it Redis. All this file\n * does is turn a rule into an HTTP answer — which is why `false` (the \"no limit\n * here\" value) short-circuits to a passthrough rather than to a rule with an\n * infinite `max`: a disabled bucket should cost nothing per request.\n *\n * The key is supplied by the caller because the useful key differs per bucket:\n * `/token` limits per client, `/authorize` per IP. A single built-in key would\n * mean one client's traffic throttles another's.\n */\nexport function rateLimit(\n ctx: ResolvedContext,\n bucket: 'token' | 'authorize' | 'consent',\n keyOf: (req: Request) => string,\n): RequestHandler {\n const rule = ctx.rateLimits[bucket];\n if (rule === false) return (_req, _res, next) => next();\n\n return (req, res, next) => {\n void (async () => {\n let hit: { count: number; resetAt: number };\n try {\n hit = await ctx.rateLimits.hit(`${bucket}:${keyOf(req)}`, rule.windowMs);\n } catch (err) {\n // Fail open, loudly. The store may be the host's Redis; a transient\n // failure there must not take every token exchange down with it. The\n // cost of the other choice — a total auth outage because a counter is\n // unreachable — is worse than a window with no limiting.\n ctx.logger.error?.({ err, bucket }, 'oauth-host: rate limit store failed, allowing request');\n next();\n return;\n }\n\n if (hit.count <= rule.max) {\n next();\n return;\n }\n\n const retryAfter = Math.max(1, Math.ceil((hit.resetAt - Date.now()) / 1000));\n res.set('Retry-After', String(retryAfter));\n // JSON, like every other failure in this package — a client that only\n // knows how to parse `{ error }` should not meet HTML at the one moment\n // it is being told to back off. See standards/traps.md #6.\n res.status(429).json({\n error: 'too_many_requests',\n error_description: `Rate limit exceeded for ${bucket}. Retry in ${retryAfter}s.`,\n });\n })();\n };\n}\n","import { createPrivateKey, createPublicKey, generateKeyPairSync } from 'node:crypto';\nimport type { KeyObject } from 'node:crypto';\nimport { sha256 } from './crypto.js';\nimport type { ResolvedContext } from './config.js';\nimport type { OAuthKeyDoc, SigningKeySpec } from '../../types/index.js';\n\n/**\n * Signing keys for the `id_token`, and the JWKS the client validates against.\n *\n * ES256 only. Not a limitation to remove later: one curve means one code path,\n * and P-256 is the intersection of \"every OIDC client supports it\" and \"Node\n * signs it without a dependency\". RS256 would add a second branch to every\n * verification story for no client that cannot already do ES256.\n *\n * Two sources, in order:\n * 1. `signing.keys[]` — PEM from the environment. The production answer: the\n * key is not in the same database as the tokens it signs.\n * 2. `signing.autoGenerate` — generate once, persist as JWK, reuse on the\n * next boot. A development convenience, and named as one, because it puts\n * the private key next to the data it authenticates.\n *\n * Neither is not a default. A server that silently invents a fresh key every\n * boot invalidates every `id_token` it ever issued on restart, and the symptom\n * shows up in the client, not here — so `getSigningKey()` throws instead.\n */\n\nexport interface SigningKey {\n kid: string;\n alg: 'ES256';\n privateKey: KeyObject;\n}\n\nexport interface KeyManager {\n /** The active key. Throws a clear error if none is configured and autoGenerate is off. */\n getSigningKey(): Promise<SigningKey>;\n /** RFC 7517 JWK Set — active AND retiring keys, public halves only. */\n jwks(): Promise<{ keys: Record<string, unknown>[] }>;\n}\n\ninterface ConfiguredKey {\n kid: string;\n status: 'active' | 'retiring';\n privateKey: KeyObject;\n publicJwk: Record<string, unknown>;\n}\n\n/**\n * RFC 7638 thumbprint, used as the `kid`.\n *\n * Deterministic in the key material, which is what makes the persist path\n * race-safe: two processes that generate concurrently produce different kids,\n * but a process that re-persists the SAME key collides on the unique index and\n * re-reads instead of writing a duplicate. Member order is lexicographic per\n * the RFC — crv, kty, x, y — and must not be \"tidied\".\n */\nfunction thumbprint(jwk: Record<string, unknown>): string {\n return sha256(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }));\n}\n\nfunction toJwk(key: KeyObject): Record<string, unknown> {\n return key.export({ format: 'jwk' }) as unknown as Record<string, unknown>;\n}\n\n/** The public half. `d` is the private scalar — publishing it publishes the key. */\nfunction publicHalf(jwk: Record<string, unknown>, kid: string): Record<string, unknown> {\n const { d, ...rest } = jwk;\n void d;\n return { ...rest, kid, alg: 'ES256', use: 'sig' };\n}\n\nfunction normalizeConfigured(specs: SigningKeySpec[] | undefined): ConfiguredKey[] {\n if (!specs?.length) return [];\n return specs.map((spec) => {\n if (spec.alg && spec.alg !== 'ES256') {\n throw new TypeError(`oauth-host: signing key '${spec.kid}' has alg '${spec.alg}'; only ES256 is supported`);\n }\n let privateKey: KeyObject;\n try {\n privateKey = createPrivateKey(spec.privateKeyPem);\n } catch (err) {\n throw new TypeError(\n `oauth-host: signing key '${spec.kid}' is not a readable PKCS#8 PEM (${(err as Error).message})`,\n );\n }\n if (privateKey.asymmetricKeyType !== 'ec') {\n throw new TypeError(`oauth-host: signing key '${spec.kid}' must be an EC (P-256) key`);\n }\n const jwk = toJwk(createPublicKey(privateKey));\n if (jwk.crv !== 'P-256') {\n throw new TypeError(`oauth-host: signing key '${spec.kid}' uses curve ${String(jwk.crv)}; ES256 requires P-256`);\n }\n // A host-supplied kid wins even when it differs from the thumbprint: it is\n // already in tokens the clients hold, and changing it orphans them.\n const kid = spec.kid || thumbprint(jwk);\n return { kid, status: spec.status ?? 'active', privateKey, publicJwk: publicHalf(jwk, kid) };\n });\n}\n\nconst MISSING_KEY = 'oauth-host: no signing key. Set `signing.keys` to a PKCS#8 ES256 PEM, '\n + 'or `signing.autoGenerate: true` to generate and persist one (development only — it '\n + 'stores the private key in the same database as the tokens it signs).';\n\nexport function createKeyManager(ctx: ResolvedContext): KeyManager {\n // Eager: a malformed PEM is a boot error with the offending kid in the\n // message, not a 500 on the first client that asks for an id_token.\n const configured = normalizeConfigured(ctx.signing.keys);\n\n // Importing a JWK is a parse plus a key derivation. The doc is re-read on\n // every call so a rotation lands without a restart; only the KeyObject is\n // cached, keyed by the kid that identifies the material.\n const imported = new Map<string, KeyObject>();\n let generating: Promise<OAuthKeyDoc> | null = null;\n\n function importPrivate(kid: string, jwk: Record<string, unknown>): KeyObject {\n const cached = imported.get(kid);\n if (cached) return cached;\n const key = createPrivateKey({ key: jwk as never, format: 'jwk' });\n imported.set(kid, key);\n return key;\n }\n\n async function generateAndPersist(): Promise<OAuthKeyDoc> {\n const { privateKey } = generateKeyPairSync('ec', { namedCurve: 'prime256v1' });\n const privateJwk = toJwk(privateKey);\n const kid = thumbprint(privateJwk);\n const doc = {\n kid,\n alg: 'ES256' as const,\n publicJwk: publicHalf(privateJwk, kid),\n privateJwk,\n status: 'active' as const,\n };\n try {\n return await ctx.models.Key.create(doc);\n } catch (err) {\n // Two processes booting a cold database both find no key and both write.\n // A duplicate kid means the other one persisted identical material, so\n // re-read; distinct kids mean two live keys, which is harmless because\n // `jwks()` publishes both and `getSigningKey()` picks deterministically.\n if ((err as { code?: number }).code !== 11000) throw err;\n const existing = await ctx.models.Key.findOne({ kid });\n if (!existing) throw err;\n return existing;\n }\n }\n\n return {\n async getSigningKey() {\n const active = configured.find((k) => k.status === 'active');\n if (active) return { kid: active.kid, alg: 'ES256', privateKey: active.privateKey };\n if (configured.length) {\n throw new Error('oauth-host: every configured signing key is `retiring`; one must be `active` to sign with');\n }\n if (!ctx.signing.autoGenerate) throw new Error(MISSING_KEY);\n\n // Oldest first, kid as the tiebreak: every process in the cluster has to\n // land on the same key, or clients see the kid flip per request.\n const doc = await ctx.models.Key.findOne({ status: 'active' }).sort({ createdAt: 1, kid: 1 })\n ?? await (generating ??= generateAndPersist().finally(() => { generating = null; }));\n return { kid: doc.kid, alg: 'ES256', privateKey: importPrivate(doc.kid, doc.privateJwk) };\n },\n\n async jwks() {\n if (configured.length) {\n // Retiring keys stay published: they still sign nothing, but they must\n // keep validating the tokens they already signed.\n return { keys: configured.map((k) => k.publicJwk) };\n }\n const docs = await ctx.models.Key.find({ status: { $in: ['active', 'retiring'] } })\n .sort({ createdAt: 1, kid: 1 });\n return { keys: docs.map((d) => ({ ...d.publicJwk, kid: d.kid, alg: d.alg, use: 'sig' })) };\n },\n };\n}\n","import type { Request } from 'express';\nimport { OAuthError } from '../errors.js';\nimport { generateClientId, generateClientSecret, safeEqual, sha256 } from '../crypto.js';\nimport type { ResolvedContext } from '../config.js';\nimport type {\n ClientBranding,\n ClientsApi,\n ContextsApi,\n CreateClientSpec,\n CreatedClient,\n GrantContext,\n GrantSummary,\n GrantsApi,\n OAuthClientDoc,\n OAuthGrantDoc,\n PackageUser,\n PublicClient,\n ScopeSpec,\n UserId,\n UsersApi,\n} from '../../../types/index.js';\n\n/**\n * The programmatic admin surface — client registration, grant revocation, and\n * the two outbound lifecycle hooks a host has to call.\n *\n * **There is no admin router here, deliberately.** `standards/adapters.md` says\n * `isAdmin` must not gate anything, because the package cannot know what admin\n * means in a host. Shipping these as plain module exports is the strongest\n * available form of that rule: there is no admin router for a host to forget to\n * guard. If a host wants HTTP admin it writes the route and owns the guard, and\n * `examples/` ships the test it is expected to copy.\n *\n * Everything that leaves this module goes through `toPublicClient`. A client\n * document carries secret digests and the pairwise-subject map; neither has any\n * business in a response, a log line, or a dashboard payload.\n *\n * Revocation in here is written as bulk `updateMany` rather than a loop over\n * per-grant helpers. A popular client can hold tens of thousands of grants, and\n * `disable()` has to stay one round trip per collection or it becomes the\n * outage it was called to prevent.\n */\n\n/**\n * A mongo filter, loosely typed on purpose.\n *\n * `FilterQuery` is not exported across the whole supported mongoose range\n * (7/8/9), and a library that imports a type one peer major dropped fails the\n * matrix in a way that has nothing to do with its behaviour — traps #10.\n */\ntype Filter = Record<string, unknown>;\n\n/** Hard ceiling on any list read, above whatever the caller asked for — traps #18. */\nconst MAX_LIST = 200;\nconst DEFAULT_LIST = 50;\n\nfunction clampLimit(requested: unknown): number {\n const n = typeof requested === 'number' && Number.isFinite(requested) ? Math.floor(requested) : DEFAULT_LIST;\n if (n < 1) return 1;\n return Math.min(n, MAX_LIST);\n}\n\nfunction clampSkip(requested: unknown): number {\n const n = typeof requested === 'number' && Number.isFinite(requested) ? Math.floor(requested) : 0;\n return n > 0 ? n : 0;\n}\n\n/**\n * A programmatic failure, not a wire failure.\n *\n * These are thrown at a host's own admin script or route handler, so a plain\n * `Error` with a readable message is the right shape — an RFC token like\n * `invalid_client` means something specific on the wire and would be a lie here.\n */\nfunction notFound(clientId: string): Error {\n return new Error(`oauth-host: no client registered with clientId '${clientId}'`);\n}\n\n// ---------------------------------------------------------------------------\n// Projection\n// ---------------------------------------------------------------------------\n\n/** The client as anything outside the package may see it. Never the secrets. */\nexport function toPublicClient(doc: OAuthClientDoc): PublicClient {\n return {\n clientId: doc.clientId,\n name: doc.name,\n type: doc.type,\n // Defaulted rather than read straight through: rows written before the\n // field existed have no value, and `undefined` here would read as \"unknown\n // provenance\" on a client that plainly was registered by hand.\n registration: doc.registration ?? 'manual',\n ...(doc.metadataUrl ? { metadataUrl: doc.metadataUrl } : {}),\n trusted: Boolean(doc.trusted),\n redirectUris: [...(doc.redirectUris ?? [])],\n allowedScopes: [...(doc.allowedScopes ?? [])],\n allowedResources: [...(doc.allowedResources ?? [])],\n branding: { ...((doc.branding ?? {}) as ClientBranding) },\n status: doc.status,\n createdAt: doc.createdAt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Registration validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate a redirect URI hard, at registration, with the offending value in\n * the message.\n *\n * This is the one field nothing downstream can rescue: `/authorize` compares\n * the incoming `redirect_uri` by exact string equality against this list, so a\n * typo registered today is a partner integration that half-works six weeks\n * later with no error pointing back here.\n *\n * `http` is allowed on loopback and nowhere else. That is not a relaxed rule —\n * real connector development runs against `http://localhost`, and a package\n * that forbids it gets worked around with a fake TLS proxy or, worse, by\n * registering the production client against a dev callback.\n */\nfunction assertRedirectUri(value: unknown): string {\n if (typeof value !== 'string' || !value) {\n throw new TypeError(`oauth-host: every redirectUri must be a string (got ${JSON.stringify(value)})`);\n }\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new TypeError(`oauth-host: redirectUri must be an absolute URI: '${value}'`);\n }\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]';\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) {\n throw new TypeError(\n `oauth-host: redirectUri must be https (http is allowed only on localhost/127.0.0.1): '${value}'`,\n );\n }\n // RFC 6749 §3.1.2 — the endpoint URI MUST NOT include a fragment. The\n // authorization response appends its own parameters, and a fragment already\n // present makes what the client receives undefined.\n if (url.hash) {\n throw new TypeError(`oauth-host: redirectUri must not contain a fragment: '${value}'`);\n }\n return value;\n}\n\nfunction assertRedirectUris(input: unknown): string[] {\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError('oauth-host: a client needs at least one redirectUri');\n }\n return input.map(assertRedirectUri);\n}\n\n/**\n * A client may only be granted scopes the host declared.\n *\n * The two gates in `scopes.ts` (catalog, then registration) both have to hold\n * at request time; this is the earlier one, applied where a human can still fix\n * it. Without it, registering a client would implicitly extend the catalog and\n * the consent screen would have no label to render for the scope.\n */\nfunction assertScopes(ctx: ResolvedContext, input: unknown): string[] {\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError('oauth-host: a client needs at least one entry in allowedScopes');\n }\n for (const id of input) {\n if (typeof id !== 'string' || !ctx.scopeIndex.has(id)) {\n throw new TypeError(\n `oauth-host: allowedScopes contains '${String(id)}', which is not in the configured scope catalog`,\n );\n }\n }\n return [...(input as string[])];\n}\n\n/** Defaults to every configured resource — a client bound to nothing gets no token. */\nfunction assertResources(ctx: ResolvedContext, input: unknown): string[] {\n const declared = new Set(ctx.resources.map((r) => r.id));\n if (input === undefined) return ctx.resources.map((r) => r.id);\n if (!Array.isArray(input) || input.length === 0) {\n throw new TypeError('oauth-host: allowedResources, when given, must list at least one resource');\n }\n for (const id of input) {\n if (typeof id !== 'string' || !declared.has(id)) {\n throw new TypeError(\n `oauth-host: allowedResources contains '${String(id)}', which is not a configured resource`,\n );\n }\n }\n return [...(input as string[])];\n}\n\nfunction assertName(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new TypeError('oauth-host: a client needs a non-empty `name` — it is what the consent screen shows');\n }\n return value.trim();\n}\n\n// ---------------------------------------------------------------------------\n// Bulk revocation, shared by every cascade below\n// ---------------------------------------------------------------------------\n\nasync function revokeGrantsMatching(\n ctx: ResolvedContext,\n filter: Filter,\n by: 'user' | 'admin' | 'system' | 'client',\n): Promise<{ grantsRevoked: number }> {\n const res = await ctx.models.Grant.updateMany(\n { ...filter, revokedAt: null },\n { $set: { revokedAt: new Date(), revokedBy: by } },\n );\n return { grantsRevoked: res.modifiedCount ?? 0 };\n}\n\n/**\n * Tokens carry `clientId`, `userId`, `contextId` and `grantId` denormalized\n * precisely so revocation is one indexed write rather than a join.\n */\nasync function revokeTokensMatching(\n ctx: ResolvedContext,\n filter: Filter,\n): Promise<number> {\n const res = await ctx.models.Token.updateMany(\n { ...filter, revokedAt: null },\n { $set: { revokedAt: new Date() } },\n );\n return res.modifiedCount ?? 0;\n}\n\n// ---------------------------------------------------------------------------\n// Clients\n// ---------------------------------------------------------------------------\n\nexport function createClientsApi(ctx: ResolvedContext): ClientsApi {\n return {\n async create(spec: CreateClientSpec): Promise<CreatedClient> {\n if (!spec || typeof spec !== 'object') {\n throw new TypeError('oauth-host: clients.create(spec) requires a spec object');\n }\n const name = assertName(spec.name);\n const redirectUris = assertRedirectUris(spec.redirectUris);\n const allowedScopes = assertScopes(ctx, spec.allowedScopes);\n const allowedResources = assertResources(ctx, spec.allowedResources);\n\n const clientId = spec.clientId ?? generateClientId();\n const clientSecret = generateClientSecret();\n\n const doc = await ctx.models.Client.create({\n clientId,\n name,\n type: 'confidential',\n registration: 'manual',\n trusted: Boolean(spec.trusted),\n // Only the digest is stored. `clientSecret` below is the only time the\n // raw value exists outside the caller's variable.\n secrets: [{ hash: sha256(clientSecret), label: 'initial', createdAt: new Date() }],\n redirectUris,\n allowedScopes,\n allowedResources,\n branding: spec.branding ?? {},\n status: 'active',\n });\n\n await ctx.audit({ type: 'oauth.client_created', actor: 'admin', clientId });\n\n return { client: toPublicClient(doc), clientId, clientSecret };\n },\n\n async rotateSecret(clientId, opts = {}): Promise<CreatedClient> {\n const doc = await ctx.models.Client.findOne({ clientId });\n if (!doc) throw notFound(clientId);\n // An error, not a no-op. A public client has no secret by construction,\n // and handing the caller one would be worse than useless: the token\n // endpoint refuses a public client that presents a secret, so a\n // provisioning script would happily print a credential that breaks the\n // client the moment it is used.\n if (doc.type === 'public') {\n throw new Error(\n `oauth-host: client '${clientId}' is a public client and has no secret to rotate. `\n + 'Public clients authenticate with client_id and PKCE.',\n );\n }\n\n const retireAfter =typeof opts.retireAfter === 'number' && opts.retireAfter > 0 ? opts.retireAfter : 0;\n const retiresAt = new Date(Date.now() + retireAfter);\n\n // Two live secrets at once is the whole point: the operator deploys the\n // new one, watches `lastUsedAt` move, and only then finishes the rotation.\n // Never push an existing retirement later — an operator who already\n // scheduled a secret to die at noon does not expect a second rotation to\n // resurrect it until midnight.\n for (const record of doc.secrets) {\n record.retiresAt = record.retiresAt && record.retiresAt < retiresAt ? record.retiresAt : retiresAt;\n }\n\n const clientSecret = generateClientSecret();\n doc.secrets.push({\n hash: sha256(clientSecret),\n label: opts.label ?? `rotated-${new Date().toISOString()}`,\n createdAt: new Date(),\n });\n doc.markModified('secrets');\n await doc.save();\n\n ctx.track({ type: 'oauth.client_secret_rotated', clientId });\n await ctx.audit({\n type: 'oauth.client_secret_rotated',\n actor: 'admin',\n clientId,\n meta: { retireAfter, retiresAt },\n });\n\n return { client: toPublicClient(doc), clientId, clientSecret };\n },\n\n async update(clientId, patch): Promise<PublicClient> {\n const doc = await ctx.models.Client.findOne({ clientId });\n if (!doc) throw notFound(clientId);\n\n // Same validators as `create`. A field is only writable through the gate\n // that proved it at registration, or the second write is the hole.\n if (patch.name !== undefined) doc.name = assertName(patch.name);\n if (patch.redirectUris !== undefined) doc.redirectUris = assertRedirectUris(patch.redirectUris);\n if (patch.allowedScopes !== undefined) doc.allowedScopes = assertScopes(ctx, patch.allowedScopes);\n if (patch.allowedResources !== undefined) {\n doc.allowedResources = assertResources(ctx, patch.allowedResources);\n }\n if (patch.branding !== undefined) doc.branding = patch.branding;\n if (patch.trusted !== undefined) doc.trusted = Boolean(patch.trusted);\n\n await doc.save();\n await ctx.audit({ type: 'oauth.client_updated', actor: 'admin', clientId });\n return toPublicClient(doc);\n },\n\n async list(query = {}) {\n // Clamped BEFORE it reaches the query, so no caller-supplied value ever\n // becomes the ceiling — traps #18.\n const limit = clampLimit(query.limit);\n const skip = clampSkip(query.skip);\n const filter: Filter = {};\n if (query.status) filter.status = query.status;\n\n const docs = await ctx.models.Client.find(filter)\n .sort({ createdAt: -1 })\n .skip(skip)\n .limit(limit)\n .lean<OAuthClientDoc[]>();\n\n return { items: docs.map(toPublicClient), limit };\n },\n\n async get(clientId) {\n const doc = await ctx.models.Client.findOne({ clientId }).lean<OAuthClientDoc | null>();\n return doc ? toPublicClient(doc) : null;\n },\n\n async disable(clientId) {\n const doc = await ctx.models.Client.findOne({ clientId });\n if (!doc) throw notFound(clientId);\n\n doc.status = 'disabled';\n await doc.save();\n\n // Disabling without the cascade would leave every issued access token\n // valid until its own expiry — \"revoke access\" would mean \"in an hour\".\n const { grantsRevoked } = await revokeGrantsMatching(ctx, { clientId }, 'admin');\n const tokensRevoked = await revokeTokensMatching(ctx, { clientId });\n // Outstanding authorization codes are live credentials too, and unlike\n // tokens there is no revoked flag to set — they are single-use by design.\n await ctx.models.Code.deleteMany({ clientId });\n await ctx.models.Request.deleteMany({ clientId });\n\n // One audit row, not one per grant: a popular client holds thousands, and\n // a revocation storm in the audit log buries the event that caused it.\n await ctx.audit({\n type: 'oauth.client_disabled',\n actor: 'admin',\n clientId,\n meta: { grantsRevoked, tokensRevoked },\n });\n\n return { grantsRevoked, tokensRevoked };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Client authentication (RFC 6749 §2.3.1)\n// ---------------------------------------------------------------------------\n\n/**\n * RFC 6749 §2.3.1 encodes the userid and password with the\n * `application/x-www-form-urlencoded` rules before base64ing them, which means\n * `+` is a space and `%xx` is a byte. Our own ids and secrets are base64url and\n * contain neither, but a client that follows the RFC literally will encode\n * anyway, and a server that skips the decode rejects a correct credential.\n */\nfunction formUrlDecode(value: string): string {\n try {\n return decodeURIComponent(value.replace(/\\+/g, ' '));\n } catch {\n // A malformed escape is not a credential; let it fail the comparison rather\n // than throw a URIError out of the middle of authentication.\n return value;\n }\n}\n\ninterface ClientCredentials {\n clientId: string;\n /** `null` means no secret was presented at all — which is a public client's whole story. */\n clientSecret: string | null;\n viaBasic: boolean;\n}\n\nfunction readCredentials(req: Request): ClientCredentials | null {\n const header = req.headers?.authorization;\n if (typeof header === 'string' && /^Basic /i.test(header)) {\n const decoded = Buffer.from(header.slice(6).trim(), 'base64').toString('utf8');\n // Split on the FIRST colon only: a userid may not contain one, a password may.\n const sep = decoded.indexOf(':');\n const clientId = formUrlDecode(sep < 0 ? decoded : decoded.slice(0, sep));\n const secret = sep < 0 ? '' : formUrlDecode(decoded.slice(sep + 1));\n // An empty password is \"no secret\", not \"the empty secret\". Some clients\n // send `Basic base64(client_id:)` for `token_endpoint_auth_method=none`.\n return { clientId, clientSecret: secret === '' ? null : secret, viaBasic: true };\n }\n\n const body = (req.body ?? {}) as { client_id?: unknown; client_secret?: unknown };\n if (typeof body.client_id === 'string' && body.client_id) {\n return {\n clientId: body.client_id,\n clientSecret: typeof body.client_secret === 'string' && body.client_secret\n ? body.client_secret\n : null,\n viaBasic: false,\n };\n }\n return null;\n}\n\n/**\n * One error for every failure mode.\n *\n * An unknown client id, a wrong secret, a retired secret and a disabled client\n * all produce this exact object. Distinguishing them turns the token endpoint\n * into a client-id oracle, and the extra detail helps an attacker strictly more\n * than it helps an integrator — who has the audit log.\n */\nfunction authFailure(viaBasic: boolean): OAuthError {\n return new OAuthError(401, 'invalid_client', 'client authentication failed', {\n // RFC 6749 §5.2 — a 401 answering a Basic credential MUST carry the challenge.\n headers: viaBasic ? { 'WWW-Authenticate': 'Basic realm=\"oauth\", charset=\"UTF-8\"' } : {},\n });\n}\n\n/**\n * RFC 6749 §2.3.1 — `client_secret_basic` (the `Authorization` header) or\n * `client_secret_post` (the body). Basic wins when both are present, because a\n * client that sends both and disagrees with itself is a bug we should not\n * paper over by picking the one that happens to verify.\n *\n * **Public clients authenticate by presenting `client_id` alone**\n * (`token_endpoint_auth_method=none`), with PKCE standing in for the secret.\n * The two rules that make that safe are symmetric and neither is optional:\n *\n * public MUST NOT present a secret\n * confidential MUST present one\n *\n * The second is the attack. If a confidential client could authenticate by\n * simply omitting its secret, every registration in the database would be\n * downgradeable to public by anyone who knows a `client_id` — which is a public\n * value. Both violations produce the identical failure object, so neither is an\n * oracle for which kind of client an id names.\n */\nexport async function authenticateClient(\n ctx: ResolvedContext,\n req: Request,\n): Promise<OAuthClientDoc> {\n const creds = readCredentials(req);\n if (!creds || !creds.clientId) throw authFailure(Boolean(creds?.viaBasic));\n\n const client = await ctx.models.Client.findOne({ clientId: creds.clientId });\n if (!client || client.status !== 'active') throw authFailure(creds.viaBasic);\n\n if (client.type === 'public') {\n // Refused, not ignored. A secret presented for a client that has none means\n // the caller believes something false about this registration, and the\n // charitable reading (a copy-pasted confidential config) still ends with a\n // client whose operator thinks a secret is protecting them.\n if (creds.clientSecret !== null) throw authFailure(creds.viaBasic);\n return client;\n }\n\n if (creds.clientSecret === null) throw authFailure(creds.viaBasic);\n\n const now = Date.now();\n let matched: (typeof client.secrets)[number] | undefined;\n for (const record of client.secrets) {\n // A retired secret is gone the instant `retiresAt` passes. That is what\n // makes `rotateSecret` a real cutover rather than an extra key that lives\n // forever because nobody remembered to remove it.\n if (record.retiresAt && record.retiresAt.getTime() <= now) continue;\n // No early exit: the loop runs the same number of comparisons whichever\n // secret matches, so the response time does not say which one it was.\n if (safeEqual(sha256(creds.clientSecret), record.hash)) matched = record;\n }\n if (!matched) throw authFailure(creds.viaBasic);\n\n // The whole reason `lastUsedAt` exists: it is how an operator knows the new\n // secret is actually in use and the rotation is safe to finish. A targeted\n // positional update, not a full `save()` — this runs on every token request.\n const usedAt = new Date();\n matched.lastUsedAt = usedAt;\n await ctx.models.Client.updateOne(\n { clientId: client.clientId, 'secrets.hash': matched.hash },\n { $set: { 'secrets.$.lastUsedAt': usedAt } },\n );\n\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// Grants\n// ---------------------------------------------------------------------------\n\n/** A grant references scope ids; a \"connected apps\" screen needs the catalog entry. */\nfunction describeGrantScopes(ctx: ResolvedContext, ids: string[]): ScopeSpec[] {\n // A scope can leave the catalog while a live grant still references it. Fall\n // back to a bare spec rather than dropping the row — a connected-apps screen\n // missing a line understates what the client can still do.\n return ids.map((id) => ctx.scopeIndex.get(id) ?? { id, label: id });\n}\n\nexport function createGrantsApi(ctx: ResolvedContext): GrantsApi {\n return {\n async list(query) {\n const limit = clampLimit(query?.limit);\n const skip = clampSkip(query?.skip);\n\n const filter: Filter = { revokedAt: null };\n if (query?.userId !== undefined) filter.userId = query.userId;\n if (query?.clientId !== undefined) filter.clientId = query.clientId;\n\n const grants = await ctx.models.Grant.find(filter)\n .sort({ createdAt: -1 })\n .skip(skip)\n .limit(limit)\n .lean<OAuthGrantDoc[]>();\n\n if (grants.length === 0) return { items: [], limit };\n\n // One query for the whole page. The alternative is a client lookup per\n // row, which is the N+1 that makes a twenty-row screen feel broken.\n const clientIds = [...new Set(grants.map((g) => g.clientId))];\n const clients = await ctx.models.Client.find({ clientId: { $in: clientIds } })\n .lean<OAuthClientDoc[]>();\n const byId = new Map(clients.map((c) => [c.clientId, toPublicClient(c)]));\n\n // Context labels come from the host's adapter, which is keyed by user and\n // client — so cache per pair rather than asking once per grant.\n const contextCache = new Map<string, GrantContext[]>();\n const items: GrantSummary[] = [];\n\n for (const grant of grants) {\n const client = byId.get(grant.clientId);\n const summary: GrantSummary = {\n id: String(grant._id),\n client: client\n ? { clientId: client.clientId, name: client.name, branding: client.branding }\n // A grant can outlive a hard-deleted client row. Naming the id beats\n // rendering a blank card the user cannot act on.\n : { clientId: grant.clientId, name: grant.clientId, branding: {} },\n scopes: describeGrantScopes(ctx, grant.scopes ?? []),\n createdAt: grant.createdAt,\n ...(grant.lastUsedAt ? { lastUsedAt: grant.lastUsedAt } : {}),\n };\n\n // Single-subject mode omits the key entirely — not `undefined`, absent.\n // A host that never configured `grantContext` should never see the word.\n if (ctx.grantContext && grant.contextId) {\n const cacheKey = `${String(grant.userId)}:${grant.clientId}`;\n let available = contextCache.get(cacheKey);\n if (!available) {\n // The adapter takes a user, and all we hold is the id the grant was\n // stored with. That is enough for a membership lookup; the package\n // has no user collection to hydrate from and must not grow one.\n const user = { id: grant.userId } as PackageUser;\n available = client\n ? await ctx.grantContext.list(user, { client, scopes: grant.scopes ?? [] })\n : [];\n contextCache.set(cacheKey, available);\n }\n summary.context = available.find((c) => c.id === grant.contextId)\n // Membership may already have ended, which is exactly when the user\n // most wants to see the row. Show the id rather than hiding it.\n ?? { id: grant.contextId, label: grant.contextId };\n }\n\n items.push(summary);\n }\n\n return { items, limit };\n },\n\n async revoke(grantId, opts = {}) {\n const by = opts.by ?? 'admin';\n const grant = await ctx.models.Grant.findById(grantId).catch(() => null);\n // Idempotent, and tolerant of an id that no longer resolves: `users.forget`\n // deletes grants outright, so a revoke arriving after an erasure is a\n // no-op rather than an error.\n if (!grant) return { tokensRevoked: 0 };\n\n const alreadyRevoked = Boolean(grant.revokedAt);\n if (!alreadyRevoked) {\n grant.revokedAt = new Date();\n grant.revokedBy = by;\n await grant.save();\n }\n\n // Run the token sweep even on a repeat call: a token issued in the window\n // between the first revocation and this one would otherwise survive it.\n const tokensRevoked = await revokeTokensMatching(ctx, { grantId: grant._id });\n\n if (!alreadyRevoked) {\n ctx.track({\n type: 'oauth.grant_revoked',\n userId: grant.userId,\n clientId: grant.clientId,\n grantId: String(grant._id),\n ...(grant.contextId ? { contextId: grant.contextId } : {}),\n scopes: grant.scopes,\n });\n await ctx.audit({\n type: 'oauth.grant_revoked',\n actor: by,\n clientId: grant.clientId,\n userId: grant.userId,\n grantId: grant._id,\n meta: { tokensRevoked },\n });\n }\n\n return { tokensRevoked };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Users — the outbound direction of the user adapter\n// ---------------------------------------------------------------------------\n\n/**\n * A pairwise subject lives at `pairwiseSubjects.<userId>` inside the client\n * document, so erasing one means an `$unset` on a computed path. Mongo treats\n * `.` as a path separator and `$` as an operator prefix, so a host whose user\n * ids contain either would have us unset something else entirely.\n */\nfunction pairwiseKey(userId: UserId): string | null {\n const key = String(userId);\n if (!key || key.includes('.') || key.startsWith('$')) return null;\n return key;\n}\n\nexport function createUsersApi(ctx: ResolvedContext): UsersApi {\n return {\n /**\n * Erasure. The user is gone and every trace of them has to go with them.\n *\n * This is the destructive twin of `revokeAll`, and the difference is the\n * whole reason both exist: `forget` DELETES the grant documents and the\n * user's audit rows, `revokeAll` keeps both. A password change must leave a\n * history an operator can read; a deletion request must not.\n *\n * Idempotent — it will be called twice, by a retry or by a host that wires\n * it to both a soft-delete and a hard-delete hook.\n */\n async forget(userId) {\n const grantsResult = await ctx.models.Grant.deleteMany({ userId });\n const tokensResult = await ctx.models.Token.deleteMany({ userId });\n await ctx.models.Code.deleteMany({ userId });\n await ctx.models.Request.deleteMany({ userId });\n\n // The pairwise subject is a pseudonym for this user held inside a client's\n // document. Leaving it behind means the erased user is still addressable\n // by the one identifier a partner stored.\n const key = pairwiseKey(userId);\n if (key) {\n await ctx.models.Client.updateMany(\n { [`pairwiseSubjects.${key}`]: { $exists: true } },\n { $unset: { [`pairwiseSubjects.${key}`]: '' } },\n );\n }\n\n await ctx.models.Audit.deleteMany({ userId });\n\n const grants = grantsResult.deletedCount ?? 0;\n const tokens = tokensResult.deletedCount ?? 0;\n\n // ONE tombstone, naming no personal data — no userId, no client, no\n // scopes. It exists to prove the erasure ran, which is the only thing an\n // auditor may still ask after the subject is gone.\n await ctx.audit({ type: 'oauth.user_forgotten', actor: 'system', meta: { grants, tokens } });\n\n return { grants, tokens };\n },\n\n /**\n * Password change, deactivation, suspected compromise.\n *\n * Kills live access and KEEPS everything else: the grant documents stay so\n * the audit trail still resolves and so the user's connected apps remain\n * visible, and the audit rows stay because that is the record the operator\n * called this to create. See `forget` above for the destructive twin.\n */\n async revokeAll(userId, opts = {}) {\n // Read the ids first: the events below are per-grant, and a user's grant\n // count is bounded by how many apps they connected — a handful, not the\n // unbounded set `clients.disable` faces.\n const live = await ctx.models.Grant.find({ userId, revokedAt: null })\n .limit(MAX_LIST)\n .lean<OAuthGrantDoc[]>();\n\n const { grantsRevoked } = await revokeGrantsMatching(ctx, { userId }, 'system');\n const tokensRevoked = await revokeTokensMatching(ctx, { userId });\n // Codes are single-use credentials with no revoked flag to set.\n await ctx.models.Code.deleteMany({ userId });\n await ctx.models.Request.deleteMany({ userId });\n\n for (const grant of live) {\n ctx.track({\n type: 'oauth.grant_revoked',\n userId,\n clientId: grant.clientId,\n grantId: String(grant._id),\n ...(grant.contextId ? { contextId: grant.contextId } : {}),\n scopes: grant.scopes,\n });\n }\n\n await ctx.audit({\n type: 'oauth.user_access_revoked',\n actor: 'system',\n userId,\n meta: { grantsRevoked, tokensRevoked, ...(opts.reason ? { reason: opts.reason } : {}) },\n });\n\n return { grantsRevoked, tokensRevoked };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Contexts — membership ended\n// ---------------------------------------------------------------------------\n\nexport function createContextsApi(ctx: ResolvedContext): ContextsApi {\n return {\n /**\n * A grant made as an employee has to die when the employment does.\n *\n * `grantContext.verify()` catches this on the next refresh, but an access\n * token already issued is valid for its full hour and nothing re-checks it.\n * This is the push half of that pair, and it is why the adapter has an\n * outbound direction at all.\n */\n async revoked(userId, contextId) {\n const live = await ctx.models.Grant.find({ userId, contextId, revokedAt: null })\n .limit(MAX_LIST)\n .lean<OAuthGrantDoc[]>();\n\n const { grantsRevoked } = await revokeGrantsMatching(ctx, { userId, contextId }, 'system');\n // Tokens carry `contextId` denormalized, so this is one indexed write\n // rather than a lookup per grant.\n const tokensRevoked = await revokeTokensMatching(ctx, { userId, contextId });\n await ctx.models.Code.deleteMany({ userId, contextId });\n\n for (const grant of live) {\n ctx.track({\n type: 'oauth.grant_revoked',\n userId,\n clientId: grant.clientId,\n grantId: String(grant._id),\n contextId,\n scopes: grant.scopes,\n });\n await ctx.audit({\n type: 'oauth.grant_revoked',\n actor: 'system',\n clientId: grant.clientId,\n userId,\n grantId: grant._id,\n meta: { contextId, reason: 'context_membership_ended' },\n });\n }\n\n return { grantsRevoked, tokensRevoked };\n },\n };\n}\n","import { UnredirectableError } from '../errors.js';\nimport type { CimdHostRule, ResolvedContext } from '../config.js';\nimport type { ClientBranding, OAuthClientDoc } from '../../../types/index.js';\n\n/**\n * Client ID Metadata Documents — a `client_id` that is an `https://` URL\n * serving the registration it names.\n *\n * **Read this before changing anything below.** Every other file in this\n * package reacts to input; this one goes and gets some. The authorization\n * server issues an outbound HTTP request whose destination comes from an\n * unauthenticated query parameter, which is server-side request forgery by\n * construction. The allowlist in `clientIdMetadata.allowedHosts` contains most\n * of the risk, and the rest of the defenses exist because an allowlist alone\n * has been enough to lose before:\n *\n * - `https:` only, checked before a socket is opened.\n * - Hostname matched by EQUALITY against the allowlist, not by suffix.\n * `evilclaude.ai` must never match an entry of `claude.ai`.\n * - **Redirects are not followed.** A 3xx is a failure, not a hop — following\n * one is how an allowlisted host becomes an open proxy to everything else,\n * including link-local metadata services.\n * - No URL credentials, no fragment, no non-default port unless the entry\n * names one.\n * - A hard timeout, and a body cap enforced while reading rather than by\n * trusting `Content-Length`.\n * - **Failures are cached too.** Without negative caching a hostile\n * `client_id` can be replayed to make this server hammer a third party, and\n * the authorization endpoint becomes a traffic amplifier.\n *\n * Successful resolutions are persisted in `oauth_clients`, so the cache\n * survives a restart. An in-memory-only cache would mean every process boot\n * re-fetches for every in-flight authorization.\n */\n\n/**\n * How long a failed fetch is remembered. Deliberately much shorter than\n * `cacheTtlMs`: a client fixing a broken document should not wait an hour, but\n * a minute is long enough that a replayed `client_id` cannot be a load\n * generator.\n */\nconst NEGATIVE_TTL_MS = 60_000;\n\n/** Bound on the negative cache. The key is attacker-chosen, so it cannot grow freely. */\nconst MAX_REMEMBERED_FAILURES = 1_000;\n\n/**\n * Every refusal is the same class the authorization endpoint already uses for\n * an unknown `client_id`, and for the same reason: we have not validated a\n * `redirect_uri`, so there is nowhere proven safe to report the error to.\n * Rendering it is the only option. See `errors.ts`.\n */\nfunction refuse(description: string): UnredirectableError {\n return new UnredirectableError('invalid_client', description);\n}\n\n/** A `client_id` shaped like a metadata document URL. Cheap, and does no I/O. */\nexport function isMetadataUrl(clientId: string): boolean {\n return /^https:\\/\\//i.test(clientId);\n}\n\n// ---------------------------------------------------------------------------\n// Before any network call\n// ---------------------------------------------------------------------------\n\nfunction hostAllowed(rules: CimdHostRule[], url: URL): boolean {\n const hostname = url.hostname.toLowerCase();\n return rules.some((rule) => {\n // `URL.port` is `''` for the scheme default, so this also enforces \"no\n // non-default port unless the allowlist entry names one\".\n if (url.port !== rule.port) return false;\n if (hostname === rule.host) return true;\n return rule.subdomains && hostname.endsWith(`.${rule.host}`);\n });\n}\n\n/**\n * Turn a `client_id` into a URL we are willing to fetch, or throw.\n *\n * Everything here runs before a single byte leaves the process — that ordering\n * is the point, and it is what the \"no fetch attempted\" tests assert.\n */\nexport function assertFetchableUrl(ctx: ResolvedContext, clientId: string): URL {\n let url: URL;\n try {\n url = new URL(clientId);\n } catch {\n throw refuse(`client_id is not a valid URL: '${clientId}'`);\n }\n if (url.protocol !== 'https:') {\n throw refuse(`client_id metadata must be served over https (got '${url.protocol}')`);\n }\n // `https://user:pass@allowed.host@evil.host/` and friends. Credentials in a\n // fetched URL have no legitimate use here and are a parser-differential\n // primitive, so they are refused rather than stripped.\n if (url.username || url.password) {\n throw refuse('client_id must not contain URL credentials');\n }\n // A fragment is never sent on the wire, so a client_id carrying one is a\n // second identifier for the same document — and two identifiers for one\n // registration means two client rows.\n if (url.hash) {\n throw refuse('client_id must not contain a fragment');\n }\n if (!hostAllowed(ctx.cimd.allowedHosts, url)) {\n throw refuse(`client_id host '${url.host}' is not in clientIdMetadata.allowedHosts`);\n }\n return url;\n}\n\n// ---------------------------------------------------------------------------\n// The fetch\n// ---------------------------------------------------------------------------\n\n/** RFC 8259 media types, and the `+json` structured suffix. */\nconst JSON_CONTENT_TYPE = /^application\\/(?:[\\w.+-]+\\+)?json\\s*(?:;|$)/i;\n\n/**\n * Read the body, aborting past the cap.\n *\n * `Content-Length` is a claim by the server we are defending against, so the\n * cap is enforced against bytes actually received. A missing or lying header\n * changes nothing.\n */\nasync function readCapped(res: Response, maxBytes: number): Promise<string> {\n const body = res.body;\n if (!body) throw refuse('client_id metadata document was empty');\n\n const reader = body.getReader();\n const chunks: Buffer[] = [];\n let total = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n if (!value) continue;\n total += value.byteLength;\n if (total > maxBytes) {\n // Stop pulling immediately: the point of the cap is not to reject a big\n // document afterwards, it is not to buffer one.\n void reader.cancel();\n throw refuse(`client_id metadata document exceeds ${maxBytes} bytes`);\n }\n chunks.push(Buffer.from(value));\n }\n return Buffer.concat(chunks).toString('utf8');\n}\n\ninterface FetchOutcome {\n /** `null` when the server answered 304 and the cached registration still stands. */\n document: Record<string, unknown> | null;\n etag?: string;\n}\n\nasync function fetchMetadata(\n ctx: ResolvedContext,\n url: URL,\n etag: string | undefined,\n): Promise<FetchOutcome> {\n let res: Response;\n try {\n res = await fetch(url.toString(), {\n method: 'GET',\n // The single most important line in this file. A 3xx is a failure below,\n // not a hop: following redirects would let an allowlisted host forward us\n // to any address it likes, allowlist intact.\n redirect: 'manual',\n headers: {\n accept: 'application/json',\n ...(etag ? { 'if-none-match': etag } : {}),\n },\n signal: AbortSignal.timeout(ctx.cimd.fetchTimeoutMs),\n });\n } catch (err) {\n const name = (err as { name?: string })?.name;\n if (name === 'TimeoutError' || name === 'AbortError') {\n throw refuse(`client_id metadata fetch timed out after ${ctx.cimd.fetchTimeoutMs}ms`);\n }\n throw refuse(`client_id metadata could not be fetched: ${(err as Error)?.message ?? 'network error'}`);\n }\n\n // Answered by `If-None-Match` — the document has not changed and the row we\n // already hold is still the registration.\n if (res.status === 304) return { document: null };\n\n if (res.status >= 300 && res.status < 400) {\n throw refuse(\n `client_id metadata returned a ${res.status} redirect, which is not followed — `\n + 'serve the document at the client_id URL itself',\n );\n }\n if (res.status !== 200) {\n throw refuse(`client_id metadata returned HTTP ${res.status}`);\n }\n\n const contentType = res.headers.get('content-type') ?? '';\n if (!JSON_CONTENT_TYPE.test(contentType)) {\n throw refuse(`client_id metadata must be JSON (got content-type '${contentType || 'none'}')`);\n }\n\n const text = await readCapped(res, ctx.cimd.maxBytes);\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw refuse('client_id metadata document is not valid JSON');\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw refuse('client_id metadata document must be a JSON object');\n }\n\n return {\n document: parsed as Record<string, unknown>,\n ...(res.headers.get('etag') ? { etag: res.headers.get('etag') as string } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport interface CimdRegistration {\n name: string;\n redirectUris: string[];\n allowedScopes: string[];\n branding: ClientBranding;\n}\n\nfunction requireString(doc: Record<string, unknown>, field: string): string {\n const value = doc[field];\n if (typeof value !== 'string' || !value.trim()) {\n throw refuse(`client_id metadata field '${field}' must be a non-empty string`);\n }\n return value.trim();\n}\n\n/**\n * A branding URL that reaches the host's consent screen as an attribute.\n *\n * `javascript:` and `data:` are the reason this is a check and not a copy: the\n * host renders `logoUrl` into an `<img src>` and `homepageUrl` into an `href`,\n * and this package is the last place that can refuse the scheme.\n */\nfunction optionalHttpsUri(doc: Record<string, unknown>, field: string): string | undefined {\n const value = doc[field];\n if (value === undefined || value === null) return undefined;\n if (typeof value !== 'string' || !value.trim()) {\n throw refuse(`client_id metadata field '${field}' must be a string`);\n }\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw refuse(`client_id metadata field '${field}' must be an absolute URL: '${value}'`);\n }\n if (url.protocol !== 'https:') {\n throw refuse(`client_id metadata field '${field}' must be https (got '${url.protocol}')`);\n }\n return value;\n}\n\n/**\n * `http` on loopback and nowhere else — the same rule `clients.create` applies\n * to a manually registered client, because connector development genuinely runs\n * against `http://localhost` and a package that forbids it gets worked around.\n */\nfunction assertRedirectUris(doc: Record<string, unknown>): string[] {\n const value = doc.redirect_uris;\n if (!Array.isArray(value) || value.length === 0) {\n throw refuse(\"client_id metadata field 'redirect_uris' must be a non-empty array\");\n }\n return value.map((entry) => {\n if (typeof entry !== 'string' || !entry) {\n throw refuse(`client_id metadata 'redirect_uris' entries must be strings (got ${JSON.stringify(entry)})`);\n }\n let url: URL;\n try {\n url = new URL(entry);\n } catch {\n throw refuse(`client_id metadata 'redirect_uris' entry must be an absolute URI: '${entry}'`);\n }\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]';\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) {\n throw refuse(\n `client_id metadata 'redirect_uris' entry must be https `\n + `(http is allowed only on localhost/127.0.0.1): '${entry}'`,\n );\n }\n // RFC 6749 §3.1.2 — the authorization response appends its own parameters,\n // and a fragment already present makes what the client receives undefined.\n if (url.hash) {\n throw refuse(`client_id metadata 'redirect_uris' entry must not contain a fragment: '${entry}'`);\n }\n return entry;\n });\n}\n\n/**\n * Validate a fetched document against the URL it came from.\n *\n * The `client_id` equality check is the whole binding. Without it any\n * allowlisted host could serve a document claiming to be any other client, and\n * \"the client_id is the URL\" would stop meaning anything.\n */\nexport function validateMetadataDocument(\n ctx: ResolvedContext,\n url: URL,\n doc: Record<string, unknown>,\n): CimdRegistration {\n const declared = requireString(doc, 'client_id');\n let declaredUrl: URL;\n try {\n declaredUrl = new URL(declared);\n } catch {\n throw refuse(`client_id metadata field 'client_id' is not a URL: '${declared}'`);\n }\n if (declaredUrl.href !== url.href) {\n throw refuse(\n `client_id metadata field 'client_id' is '${declared}', which is not the URL it was `\n + `fetched from ('${url.href}')`,\n );\n }\n\n const method = doc.token_endpoint_auth_method;\n if (method !== undefined && method !== 'none') {\n throw refuse(\n `client_id metadata field 'token_endpoint_auth_method' must be 'none' `\n + `(got ${JSON.stringify(method)}) — a CIMD client holds no secret`,\n );\n }\n\n // Required, not optional-with-a-fallback: a client with no name cannot be\n // meaningfully consented to, and defaulting it to the URL puts a hostname in\n // front of a user being asked to trust something.\n const name = requireString(doc, 'client_name');\n const redirectUris = assertRedirectUris(doc);\n\n // The document narrows; it never widens. A scope the host does not have is\n // dropped rather than refused — a client asking for more than this\n // deployment offers is normal, and the intersection is the honest answer.\n const permitted = new Set(ctx.cimd.allowedScopes.filter((id) => ctx.scopeIndex.has(id)));\n let allowedScopes: string[];\n if (doc.scope === undefined || doc.scope === null) {\n allowedScopes = [...permitted];\n } else {\n if (typeof doc.scope !== 'string') {\n throw refuse(\"client_id metadata field 'scope' must be a space-delimited string\");\n }\n const requested = new Set(doc.scope.split(/\\s+/).filter(Boolean));\n allowedScopes = [...permitted].filter((id) => requested.has(id));\n }\n if (allowedScopes.length === 0) {\n throw refuse(\n \"client_id metadata field 'scope' has no overlap with what this server offers — \"\n + 'there is nothing this client could be granted',\n );\n }\n\n const branding: ClientBranding = {};\n const logoUrl = optionalHttpsUri(doc, 'logo_uri');\n const homepageUrl = optionalHttpsUri(doc, 'client_uri');\n const tosUrl = optionalHttpsUri(doc, 'tos_uri');\n const privacyUrl = optionalHttpsUri(doc, 'policy_uri');\n if (logoUrl) branding.logoUrl = logoUrl;\n if (homepageUrl) branding.homepageUrl = homepageUrl;\n if (tosUrl) branding.tosUrl = tosUrl;\n if (privacyUrl) branding.privacyUrl = privacyUrl;\n\n return { name, redirectUris, allowedScopes, branding };\n}\n\n// ---------------------------------------------------------------------------\n// Caching and persistence\n// ---------------------------------------------------------------------------\n\nfunction rememberFailure(ctx: ResolvedContext, key: string, message: string): void {\n const { failures } = ctx.cimd;\n // Insertion-ordered, so the first key is the oldest. Cheap enough for a cache\n // whose whole job is to be small.\n if (failures.size >= MAX_REMEMBERED_FAILURES) {\n const oldest = failures.keys().next();\n if (!oldest.done) failures.delete(oldest.value);\n }\n failures.set(key, { until: Date.now() + NEGATIVE_TTL_MS, message });\n}\n\nfunction rememberedFailure(ctx: ResolvedContext, key: string): string | null {\n const found = ctx.cimd.failures.get(key);\n if (!found) return null;\n if (found.until <= Date.now()) {\n ctx.cimd.failures.delete(key);\n return null;\n }\n return found.message;\n}\n\nfunction isFresh(ctx: ResolvedContext, client: OAuthClientDoc): boolean {\n const fetchedAt = client.metadataFetchedAt?.getTime();\n if (fetchedAt === undefined) return false;\n return Date.now() - fetchedAt < ctx.cimd.cacheTtlMs;\n}\n\n/**\n * Write the registration back.\n *\n * `status` is absent from `$set` on purpose and that absence is load-bearing:\n * an operator who ran `clients.disable()` on a CIMD client must not have it\n * quietly reactivated the next time its document is re-fetched. `$setOnInsert`\n * gives a brand-new row `active`; nothing ever sets it back.\n */\nasync function persist(\n ctx: ResolvedContext,\n clientId: string,\n url: URL,\n registration: CimdRegistration,\n etag: string | undefined,\n): Promise<OAuthClientDoc> {\n const doc = await ctx.models.Client.findOneAndUpdate(\n { clientId },\n {\n $set: {\n name: registration.name,\n redirectUris: registration.redirectUris,\n allowedScopes: registration.allowedScopes,\n // Every declared resource. A CIMD client cannot express an audience\n // preference, and RFC 8707 validation at `/authorize` narrows it anyway.\n allowedResources: ctx.resources.map((r) => r.id),\n branding: registration.branding,\n metadataUrl: url.href,\n metadataFetchedAt: new Date(),\n ...(etag ? { metadataEtag: etag } : {}),\n },\n $setOnInsert: {\n type: 'public',\n registration: 'cimd',\n trusted: false,\n secrets: [],\n status: 'active',\n },\n },\n { upsert: true, returnDocument: 'after', setDefaultsOnInsert: false },\n ).exec();\n\n return doc as OAuthClientDoc;\n}\n\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a URL-shaped `client_id` into a client registration.\n *\n * Called from `validateAuthorizationRequest` only, and only when CIMD is\n * enabled. Every failure is an `UnredirectableError`, exactly like an unknown\n * `client_id`: at this point in the flow no `redirect_uri` has been validated,\n * so there is no address proven safe to report an error to.\n */\nexport async function resolveCimdClient(\n ctx: ResolvedContext,\n clientId: string,\n): Promise<OAuthClientDoc> {\n const url = assertFetchableUrl(ctx, clientId);\n\n const existing = await ctx.models.Client.findOne({ clientId }).exec();\n if (existing) {\n // Checked before anything else, and before any fetch: a disabled client is\n // an answer, not a cache miss. This is the one ordering that makes\n // `clients.disable()` stick on a registration that re-derives itself.\n if (existing.status !== 'active') {\n throw refuse(`client '${clientId}' is disabled`);\n }\n // A manually registered client that happens to have a URL id is a\n // deliberate operator override. Use it and never fetch.\n if (existing.registration !== 'cimd') return existing;\n if (isFresh(ctx, existing)) return existing;\n }\n\n const remembered = rememberedFailure(ctx, url.href);\n if (remembered) throw refuse(remembered);\n\n try {\n const { document, etag } = await fetchMetadata(ctx, url, existing?.metadataEtag);\n if (!document) {\n // 304. The document is unchanged, so only the freshness stamp moves —\n // without it every request past the TTL would re-ask.\n if (existing) {\n existing.metadataFetchedAt = new Date();\n await existing.save();\n return existing;\n }\n throw refuse('client_id metadata returned 304 with nothing cached to answer from');\n }\n const registration = validateMetadataDocument(ctx, url, document);\n const client = await persist(ctx, clientId, url, registration, etag);\n ctx.logger.debug?.({ clientId }, 'oauth-host: client_id metadata document resolved');\n return client;\n } catch (err) {\n const message = err instanceof UnredirectableError\n ? (err.description ?? 'client_id metadata could not be resolved')\n : 'client_id metadata could not be resolved';\n // Cache the failure. Without this a hostile client_id replayed in a loop\n // turns `/authorize` into an outbound traffic amplifier pointed at whatever\n // allowlisted host is having a bad day.\n rememberFailure(ctx, url.href, message);\n ctx.logger.warn?.({ clientId, err }, 'oauth-host: client_id metadata resolution failed');\n throw err instanceof UnredirectableError ? err : refuse(message);\n }\n}\n","import { OAuthError, invalidScope } from '../errors.js';\nimport type { ResolvedContext } from '../config.js';\nimport type { OAuthClientDoc, ScopeSpec } from '../../../types/index.js';\n\n/**\n * The scope catalog, applied.\n *\n * Two independent gates decide what a client may ask for, and both have to\n * hold: the host's catalog (does this scope exist at all?) and the client's\n * registration (was this client granted the right to ask?). Collapsing them\n * into one list would mean registering a client implicitly extends the catalog.\n *\n * Nothing in here consults the user's existing grants — that is consent's job.\n * These functions run before we know who the user is.\n */\n\n/**\n * RFC 6749 §3.3 — `scope` is a space-delimited list.\n *\n * Deliberately total: an unknown or malformed id survives parsing and is\n * rejected by `validateScopes` with the offending value in the message. Parsing\n * that silently drops junk turns \"you asked for a scope that does not exist\"\n * into \"you were granted less than you asked for\", which is the harder bug.\n */\nexport function parseScope(raw: string | undefined): string[] {\n if (typeof raw !== 'string') return [];\n const seen = new Set<string>();\n for (const id of raw.split(/\\s+/)) if (id) seen.add(id);\n return [...seen];\n}\n\n/**\n * Intersect the request against both gates.\n *\n * Order preserved from the request so the consent screen lists scopes the way\n * the client wrote them. Throws on the FIRST offender rather than filtering:\n * silently narrowing means the client believes it holds access it does not, and\n * discovers otherwise at the first 403 in production.\n */\nexport function validateScopes(\n ctx: ResolvedContext,\n requested: string[],\n client: OAuthClientDoc,\n): string[] {\n const allowed = new Set(client.allowedScopes);\n for (const id of requested) {\n if (!ctx.scopeIndex.has(id)) {\n throw invalidScope(`unknown scope '${id}'`);\n }\n if (!allowed.has(id)) {\n throw invalidScope(`client '${client.clientId}' is not allowed the scope '${id}'`);\n }\n }\n return [...requested];\n}\n\n/**\n * What `/authorize` grants when the request carried no `scope` at all.\n *\n * RFC 6749 §3.3 makes `scope` optional and says the server defines the\n * fallback, so this is policy rather than protocol — and the obvious policy,\n * \"fall back to the client's `allowedScopes`\", is the wrong one. That list is a\n * registration CEILING: a client is registered for everything it may ever ask\n * for, often the whole catalog, and collapsing the ceiling into the default\n * means omitting one parameter silently grants all of it. The two lists answer\n * different questions and must stay different lists.\n *\n * The configured defaults are still intersected with the ceiling — a default\n * must never exceed what the client is registered for — and an empty\n * intersection is an error, because a grant of nothing is a token that can do\n * nothing and a consent screen that asks the user to approve nothing.\n *\n * No catalog check here: `resolveConfig` proved every entry at boot, and\n * re-deriving that per request is how the two answers drift.\n */\nexport function resolveDefaultScopes(ctx: ResolvedContext, client: OAuthClientDoc): string[] {\n if (!ctx.defaultScopes) {\n throw invalidScope(\n 'no `scope` was requested and no `defaultScopes` is configured. Send `scope` on '\n + '/authorize, or configure `defaultScopes` on createOAuthHost — an empty scope set '\n + 'would issue a token that can do nothing.',\n );\n }\n const allowed = new Set(client.allowedScopes);\n const granted = ctx.defaultScopes.filter((id) => allowed.has(id));\n if (granted.length === 0) {\n throw invalidScope(\n `no \\`scope\\` was requested and client '${client.clientId}' is allowed none of the `\n + `configured defaultScopes (${ctx.defaultScopes.join(' ')}). Send \\`scope\\` explicitly, `\n + \"or add one of those scopes to the client's allowedScopes.\",\n );\n }\n return granted;\n}\n\n/**\n * The scope half of the consent payload (plan §8) — a versioned UI contract.\n *\n * Only catalog-visible fields cross this line. `isNew` is the one derived bit:\n * false means the user has already granted it to this client, so the host's UI\n * can dim it and emphasise what re-consent actually adds.\n */\nexport function describeScopes(\n ctx: ResolvedContext,\n ids: string[],\n opts: { previouslyGranted?: string[] } = {},\n): Array<{ id: string; label: string; description?: string; sensitive?: boolean; isNew: boolean }> {\n const granted = new Set(opts.previouslyGranted ?? []);\n return ids.map((id) => {\n // A scope can leave the catalog while a grant referencing it is still live,\n // so fall back to the bare id rather than dropping the row — a consent\n // screen missing a line is worse than one with a thin label.\n const spec: ScopeSpec = ctx.scopeIndex.get(id) ?? { id, label: id };\n return {\n id,\n label: spec.label ?? id,\n ...(spec.description ? { description: spec.description } : {}),\n ...(spec.sensitive ? { sensitive: true } : {}),\n isNew: !granted.has(id),\n };\n });\n}\n\n/**\n * RFC 8707 — resource indicators.\n *\n * The same two gates as scopes: the resource must be declared by the host and\n * allowed for this client. Comparison is exact string equality, which is what\n * `resolveConfig` normalizes the catalog for.\n *\n * When the client sends none we default to its first allowed resource rather\n * than issuing an unbound token: an access token with no audience is one a\n * confused deputy can replay at any API the host runs.\n */\nexport function validateResources(\n ctx: ResolvedContext,\n requested: string[],\n client: OAuthClientDoc,\n): string[] {\n const declared = new Set(ctx.resources.map((r) => r.id));\n // A client registered with no explicit list inherits the whole catalog —\n // `clients.create` fills this in, so an empty array here means an old row.\n const allowed = client.allowedResources.length ? new Set(client.allowedResources) : declared;\n\n if (requested.length === 0) {\n const fallback = client.allowedResources[0] ?? ctx.resources[0]?.id;\n return fallback ? [fallback] : [];\n }\n\n const seen = new Set<string>();\n for (const id of requested) {\n if (!declared.has(id)) {\n // RFC 8707 §2 names this error; clients switch on it to stop retrying.\n throw new OAuthError(400, 'invalid_target', `unknown resource '${id}'`);\n }\n if (!allowed.has(id)) {\n throw new OAuthError(\n 400,\n 'invalid_target',\n `client '${client.clientId}' is not allowed the resource '${id}'`,\n );\n }\n seen.add(id);\n }\n return [...seen];\n}\n","import { randomToken } from '../crypto.js';\nimport { OAuthError, RedirectableAuthError, UnredirectableError } from '../errors.js';\nimport { redirectUriRegistered } from '../redirect-uris.js';\nimport { isMetadataUrl, resolveCimdClient } from './cimd.js';\nimport { parseScope, resolveDefaultScopes, validateResources, validateScopes } from './scopes.js';\nimport type { ResolvedContext } from '../config.js';\nimport type { OAuthClientDoc, OAuthRequestDoc, PackageUser } from '../../../types/index.js';\n\n/**\n * The authorization endpoint's validation, and nothing else.\n *\n * The single most important thing in this file is the ORDER of the checks. It\n * is a security boundary, not a style: until `client_id` resolves to a live\n * registration AND `redirect_uri` matches that registration (`redirect-uris.ts`\n * — exact, with RFC 8252 §7.3's loopback-port carve-out and nothing else), there\n * is no address we have proven safe to send a browser to. Reporting an error by\n * redirect before that point is the open-redirect hole. Everything checked\n * after it may be redirected back to the client with `state` and `iss` intact.\n *\n * See plan §9 (traps §19, inverted) and RFC 6749 §4.1.2.1.\n */\n\nexport interface ValidatedAuthRequest {\n client: OAuthClientDoc;\n redirectUri: string;\n scopes: string[];\n resources: string[];\n state?: string;\n nonce?: string;\n codeChallenge: string;\n prompt?: string;\n maxAge?: number;\n}\n\n/**\n * A single-valued query parameter.\n *\n * Express's query parser yields an array when a parameter repeats. For a\n * security parameter \"first one wins\" is a parameter-pollution primitive, so a\n * repeat is treated as absent and the required-check below reports it.\n */\nfunction one(query: Record<string, unknown>, name: string): string | undefined {\n const value = query[name];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** `resource` is the one parameter RFC 8707 lets repeat. */\nfunction many(query: Record<string, unknown>, name: string): string[] {\n const value = query[name];\n if (typeof value === 'string') return value ? [value] : [];\n if (!Array.isArray(value)) return [];\n return value.filter((v): v is string => typeof v === 'string' && v.length > 0);\n}\n\n/**\n * `client_id` → registration.\n *\n * Two sources, and which one answers is decided by config, not by the value:\n * with `clientIdMetadata` disabled a URL-shaped `client_id` takes the plain\n * database lookup and fails exactly like any other unknown client — no outbound\n * request, and nothing in the response or the timing that says a different code\n * path exists.\n *\n * An unresolvable CIMD client is an `UnredirectableError` for the same reason\n * an unknown one is: no `redirect_uri` has been validated yet, so there is no\n * address proven safe to redirect an error to.\n */\nasync function resolveClient(ctx: ResolvedContext, clientId: string): Promise<OAuthClientDoc> {\n if (ctx.cimd.enabled && isMetadataUrl(clientId)) {\n return resolveCimdClient(ctx, clientId);\n }\n const client = await ctx.models.Client.findOne({ clientId }).exec();\n if (!client) {\n throw new UnredirectableError('invalid_client', `unknown client_id '${clientId}'`);\n }\n return client;\n}\n\nexport async function validateAuthorizationRequest(\n ctx: ResolvedContext,\n query: Record<string, unknown>,\n): Promise<ValidatedAuthRequest> {\n // ── Band 1: unredirectable. No trusted destination exists yet. ────────────\n const clientId = one(query, 'client_id');\n if (!clientId) {\n throw new UnredirectableError('invalid_request', '`client_id` is required');\n }\n\n const client = await resolveClient(ctx, clientId);\n if (client.status !== 'active') {\n throw new UnredirectableError('invalid_client', `client '${clientId}' is disabled`);\n }\n\n const redirectUri = one(query, 'redirect_uri');\n if (!redirectUri) {\n throw new UnredirectableError('invalid_request', '`redirect_uri` is required');\n }\n // Exact comparison against the registration — no prefix match, no wildcard,\n // no ignoring the query string. Every relaxation of this rule is a published\n // attack; a client that needs a second callback registers a second URI. The\n // single exception lives in `redirect-uris.ts`: RFC 8252 §7.3 requires the\n // PORT of a loopback URI to be allowed to vary, because a native client binds\n // an ephemeral one per session.\n if (!redirectUriRegistered(client.redirectUris, redirectUri)) {\n throw new UnredirectableError(\n 'invalid_request',\n `redirect_uri is not registered for client '${clientId}'`,\n );\n }\n\n // ── Band 2: redirectable. Both identifiers are now proven. ────────────────\n const state = one(query, 'state');\n const fail = (code: string, description: string) =>\n new RedirectableAuthError(code, description, redirectUri, state);\n\n const responseType = one(query, 'response_type');\n if (responseType !== 'code') {\n throw new RedirectableAuthError(\n 'unsupported_response_type',\n 'only `response_type=code` is supported',\n redirectUri,\n state,\n );\n }\n\n // PKCE is mandatory in OAuth 2.1 — not \"recommended\", and not skippable for\n // confidential clients. A code intercepted in the browser's redirect chain is\n // useless without the verifier.\n const codeChallenge = one(query, 'code_challenge');\n if (!codeChallenge) {\n throw fail('invalid_request', '`code_challenge` is required (PKCE, RFC 7636)');\n }\n // RFC 7636 §4.3 defaults an omitted method to `plain`, which this package\n // does not implement anywhere. Requiring the parameter makes that rejection\n // explicit instead of letting a downgrade arrive as a default.\n if (one(query, 'code_challenge_method') !== 'S256') {\n throw fail('invalid_request', '`code_challenge_method` must be `S256`');\n }\n\n let scopes: string[];\n let resources: string[];\n try {\n // An absent or empty `scope` takes the configured default rather than an\n // empty set — RFC 6749 §3.3 leaves the fallback to us, and \"granted\n // nothing\" is a dead end the integrator only discovers at the first 403.\n const requested = parseScope(one(query, 'scope'));\n scopes = requested.length\n ? validateScopes(ctx, requested, client)\n : resolveDefaultScopes(ctx, client);\n resources = validateResources(ctx, many(query, 'resource'), client);\n } catch (err) {\n // The scope/resource validators are shared with the token endpoint, where\n // there is no redirect to make. Re-shape rather than duplicate them.\n if (err instanceof OAuthError) throw fail(err.code, err.description ?? err.code);\n throw err;\n }\n\n let maxAge: number | undefined;\n const rawMaxAge = one(query, 'max_age');\n if (rawMaxAge !== undefined) {\n const parsed = Number(rawMaxAge);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw fail('invalid_request', '`max_age` must be a non-negative integer');\n }\n maxAge = parsed;\n }\n\n return {\n client,\n redirectUri,\n scopes,\n resources,\n ...(state !== undefined ? { state } : {}),\n ...(one(query, 'nonce') ? { nonce: one(query, 'nonce') } : {}),\n codeChallenge,\n ...(one(query, 'prompt') ? { prompt: one(query, 'prompt') } : {}),\n ...(maxAge !== undefined ? { maxAge } : {}),\n };\n}\n\n/**\n * Park the validated request and hand back an opaque handle.\n *\n * The handle is what travels through the host's consent UI, which is why the\n * parameters are snapshotted here rather than round-tripped through the\n * browser: a consent screen that can be re-parameterised by editing its own URL\n * approves whatever the last hop asked for.\n */\nexport async function createAuthorizationRequest(\n ctx: ResolvedContext,\n validated: ValidatedAuthRequest,\n user: PackageUser,\n): Promise<OAuthRequestDoc> {\n const doc = await ctx.models.Request.create({\n requestId: randomToken(),\n clientId: validated.client.clientId,\n userId: user.id,\n redirectUri: validated.redirectUri,\n scopes: validated.scopes,\n resources: validated.resources,\n state: validated.state,\n nonce: validated.nonce,\n codeChallenge: validated.codeChallenge,\n codeChallengeMethod: 'S256',\n prompt: validated.prompt,\n maxAge: validated.maxAge,\n expiresAt: new Date(Date.now() + ctx.ttl.authorizationRequest * 1000),\n });\n\n ctx.track({\n type: 'oauth.authorization_requested',\n userId: user.id,\n clientId: validated.client.clientId,\n scopes: validated.scopes,\n meta: { resources: validated.resources },\n });\n\n return doc;\n}\n\n/**\n * Merge a query parameter into a configured URL.\n *\n * `consentUrl` and `loginUrl` are usually host-relative (`/settings/authorize`),\n * and both may already carry a query string. Parsing against a placeholder\n * origin gets the merge right — hand-concatenating `?` is how a second `?`\n * ends up in a redirect.\n */\nfunction withParam(configured: string, name: string, value: string): string {\n const absolute = /^https?:\\/\\//i.test(configured);\n const url = new URL(configured, 'http://oauth-host.invalid');\n url.searchParams.set(name, value);\n return absolute ? url.toString() : `${url.pathname}${url.search}${url.hash}`;\n}\n\n/** Where `/authorize` sends a signed-IN user: the host's own consent page. */\nexport function consentRedirectUrl(ctx: ResolvedContext, requestId: string): string {\n return withParam(ctx.consentUrl, 'request_id', requestId);\n}\n\n/**\n * Where `/authorize` sends a signed-OUT user — standards/adapters.md §Sign-in\n * redirects. `/authorize` is one of the few package routes a user can land on\n * cold, so the host's \"signed out on arrival\" middleware never runs for it.\n *\n * Null when no `loginUrl` is configured: the caller must then answer an error\n * rather than invent a login page that does not exist.\n */\nexport function loginRedirectUrl(ctx: ResolvedContext, returnTo: string): string | null {\n if (!ctx.loginUrl) return null;\n return withParam(ctx.loginUrl, ctx.returnParam, returnTo);\n}\n","import { randomToken, sha256 } from '../crypto.js';\nimport { OAuthError, accessDenied, invalidRequest } from '../errors.js';\nimport { toPublicClient } from './admin.js';\nimport { describeScopes } from './scopes.js';\nimport type { ResolvedContext } from '../config.js';\nimport type {\n OAuthGrantDoc,\n PackageUser,\n} from '../../../types/index.js';\n\n/**\n * Consent — the half of this package that has a human in front of it.\n *\n * The host renders the screen, so `getConsentPayload` IS the UI contract (plan\n * §8) and is versioned as strictly as any route: no `_id`, no grant id, no user\n * id, nothing the host's page has no business rendering. If a field here needs\n * an internal identifier to be useful, the design is wrong, not the rule.\n *\n * `decideConsent` is the write side and is one-shot by construction. An\n * authorization request that could be approved twice mints two codes from one\n * user decision.\n */\n\n/** The consent screen's view of the request. Deliberately id-free. */\nexport interface ConsentPayload {\n client: {\n name: string;\n logoUrl?: string;\n publisher?: string;\n homepageUrl?: string;\n tosUrl?: string;\n privacyUrl?: string;\n };\n scopes: Array<{\n id: string;\n label: string;\n description?: string;\n sensitive?: boolean;\n isNew: boolean;\n }>;\n contexts?: Array<{ id: string; label: string; description?: string }>;\n /**\n * True when `grantContext.list()` returned more than `contexts` carries.\n *\n * Present exactly when `contexts` is. See `CONSENT_CONTEXT_LIMIT`.\n */\n contextsHasMore?: boolean;\n user: { displayName?: string | null; email?: string };\n expiresAt: Date;\n}\n\n/**\n * How many grant contexts the consent payload carries.\n *\n * Every other list in this package is clamped — the admin API defaults to 50\n * with a ceiling of 200 — and this one is on an interactive path, embedded whole\n * in a payload a browser renders. An admin of a host where `list()` answers\n * \"every account in the system\" was the reported case.\n *\n * Truncating silently would be worse than not clamping: account #501 would\n * simply be unconnectable, with nothing in the payload saying so. Hence\n * `contextsHasMore` — it is the flag that lets a consent UI offer search instead\n * of rendering a prefix and calling it the whole list.\n */\nexport const CONSENT_CONTEXT_LIMIT = 50;\n\n/** Same user? Ids may be ObjectId or string depending on the host. */\nfunction sameUser(a: PackageUser['id'], b: PackageUser['id']): boolean {\n return String(a) === String(b);\n}\n\n/**\n * Load a pending request, proving it belongs to the caller.\n *\n * Unknown and expired are the same 404 on purpose: distinguishing them turns\n * the endpoint into an oracle for whether a given handle ever existed.\n */\nasync function loadPending(ctx: ResolvedContext, requestId: string, user: PackageUser) {\n const request = await ctx.models.Request.findOne({ requestId }).exec();\n if (!request || request.expiresAt.getTime() <= Date.now() || request.decision) {\n throw new OAuthError(404, 'invalid_request', 'unknown or expired authorization request');\n }\n // A different user's handle is a distinct failure from a stale one — the\n // browser is signed in as somebody, just not the right somebody, and the\n // host's page needs to say so rather than restart the flow.\n if (!sameUser(request.userId, user.id)) {\n throw accessDenied('this authorization request belongs to another user');\n }\n\n const client = await ctx.models.Client.findOne({ clientId: request.clientId }).exec();\n if (!client || client.status !== 'active') {\n throw new OAuthError(404, 'invalid_request', 'unknown or expired authorization request');\n }\n\n return { request, client };\n}\n\n/**\n * Scopes this user has already given this client.\n *\n * Unioned across every live grant rather than read from one, because the\n * context is not chosen until the user picks it — and a scope already granted\n * under any context is not something to badge as new.\n */\nasync function alreadyGranted(\n ctx: ResolvedContext,\n clientId: string,\n userId: PackageUser['id'],\n): Promise<string[]> {\n const grants = await ctx.models.Grant.find({ clientId, userId, revokedAt: null })\n .select('scopes')\n .lean()\n .exec();\n return [...new Set(grants.flatMap((g) => g.scopes))];\n}\n\nexport async function getConsentPayload(\n ctx: ResolvedContext,\n requestId: string,\n user: PackageUser,\n): Promise<ConsentPayload> {\n const { request, client } = await loadPending(ctx, requestId, user);\n const previouslyGranted = await alreadyGranted(ctx, request.clientId, request.userId);\n\n const branding = client.branding ?? {};\n const payload: ConsentPayload = {\n client: {\n name: client.name,\n ...(branding.logoUrl ? { logoUrl: branding.logoUrl } : {}),\n ...(branding.publisher ? { publisher: branding.publisher } : {}),\n ...(branding.homepageUrl ? { homepageUrl: branding.homepageUrl } : {}),\n ...(branding.tosUrl ? { tosUrl: branding.tosUrl } : {}),\n ...(branding.privacyUrl ? { privacyUrl: branding.privacyUrl } : {}),\n },\n scopes: describeScopes(ctx, request.scopes, { previouslyGranted }),\n user: {\n displayName: user.displayName ?? null,\n ...(user.email ? { email: user.email } : {}),\n },\n expiresAt: request.expiresAt,\n };\n\n // Absent must mean absent (plan §0.2). An empty array reads as \"there are no\n // contexts to choose from\", which is a different statement from \"this host\n // does not have contexts\" — and a UI that renders an empty picker for every\n // single-subject host is exactly the leak that generalization was supposed\n // to avoid.\n if (ctx.grantContext) {\n const all = await ctx.grantContext.list(user, {\n client: toPublicClient(client),\n scopes: request.scopes,\n });\n payload.contexts = all.slice(0, CONSENT_CONTEXT_LIMIT);\n payload.contextsHasMore = all.length > CONSENT_CONTEXT_LIMIT;\n }\n\n return payload;\n}\n\nexport interface ConsentDecision {\n approve: boolean;\n /** What the user actually ticked. Defaults to everything requested. */\n scopes?: string[];\n /** Required exactly when `grantContext` is configured. */\n contextId?: string;\n}\n\n/** Every authorization response carries `iss` — RFC 9207, errors included. */\nfunction authorizationResponse(\n ctx: ResolvedContext,\n redirectUri: string,\n state: string | undefined,\n params: Record<string, string>,\n): string {\n const url = new URL(redirectUri);\n for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);\n if (state !== undefined) url.searchParams.set('state', state);\n url.searchParams.set('iss', ctx.issuer);\n return url.toString();\n}\n\nexport async function decideConsent(\n ctx: ResolvedContext,\n requestId: string,\n user: PackageUser,\n decision: ConsentDecision,\n): Promise<{ redirectTo: string }> {\n const { request, client } = await loadPending(ctx, requestId, user);\n\n // Validate everything BEFORE claiming the request. A rejected decision must\n // leave the handle usable — the host's UI can fix its payload and re-post.\n const approvedScopes = decision.approve\n ? [...new Set(decision.scopes ?? request.scopes)]\n : [];\n for (const id of approvedScopes) {\n // A host UI offering more than the client asked for is a bug in the host,\n // and honouring it would let the consent screen widen its own request.\n if (!request.scopes.includes(id)) {\n throw invalidRequest(`scope '${id}' was not part of this authorization request`);\n }\n }\n\n let contextId: string | null = null;\n if (decision.approve) {\n if (ctx.grantContext) {\n if (!decision.contextId) {\n throw invalidRequest('`contextId` is required — this host configured a grant context');\n }\n if (!(await ctx.grantContext.verify(user, decision.contextId))) {\n throw accessDenied(`not a member of context '${decision.contextId}'`);\n }\n contextId = decision.contextId;\n } else if (decision.contextId) {\n throw invalidRequest('`contextId` is not accepted — this host has no grant context');\n }\n }\n\n // The one-shot guard. Filtering on `decision: null` matches both the missing\n // and the explicitly-null field, and the update is the same round trip, so\n // two concurrent approvals cannot both mint a code.\n const claimed = await ctx.models.Request.findOneAndUpdate(\n { requestId, decision: null },\n { $set: { decision: decision.approve ? 'approved' : 'denied', decidedAt: new Date() } },\n { returnDocument: 'after' },\n ).exec();\n if (!claimed) {\n throw invalidRequest('this authorization request has already been decided');\n }\n\n if (!decision.approve) {\n ctx.track({\n type: 'oauth.consent_denied',\n userId: user.id,\n clientId: request.clientId,\n scopes: request.scopes,\n });\n await ctx.audit({\n type: 'oauth.consent_denied',\n actor: 'user',\n clientId: request.clientId,\n userId: user.id,\n });\n return {\n redirectTo: authorizationResponse(ctx, request.redirectUri, request.state, {\n error: 'access_denied',\n error_description: 'the user denied the request',\n }),\n };\n }\n\n const now = new Date();\n const existing = await ctx.models.Grant.findOne({\n clientId: request.clientId,\n userId: request.userId,\n contextId,\n revokedAt: null,\n }).exec();\n\n // Re-consent unions rather than replaces: a client that asks for a narrower\n // set on its second connect must not silently lose access it still holds a\n // live token for.\n const scopes = [...new Set([...(existing?.scopes ?? []), ...approvedScopes])];\n const resources = [...new Set([...(existing?.resources ?? []), ...request.resources])];\n // `version` is what makes \"you already approved this\" checkable later, so it\n // moves only when the user actually widened the grant.\n const grew = Boolean(existing) && scopes.length > (existing?.scopes.length ?? 0);\n\n const grant = (await ctx.models.Grant.findOneAndUpdate(\n { clientId: request.clientId, userId: request.userId, contextId, revokedAt: null },\n {\n $set: { scopes, resources, lastUsedAt: now },\n // Mongo rejects an update that touches one path through two operators,\n // even when only one of them can apply — and `grew` already implies an\n // existing document, so the two branches are genuinely exclusive.\n ...(grew ? { $inc: { version: 1 } } : { $setOnInsert: { version: 1 } }),\n },\n { returnDocument: 'after', upsert: true, setDefaultsOnInsert: true },\n ).exec()) as OAuthGrantDoc;\n\n // Only the digest is stored. The code itself exists in this function and in\n // the redirect, and nowhere else — a database read cannot replay it.\n const code = randomToken();\n await ctx.models.Code.create({\n codeHash: sha256(code),\n clientId: request.clientId,\n userId: request.userId,\n grantId: grant._id,\n contextId,\n // What was approved now, not the grant's union: the token issued from this\n // code answers for this authorization, not for the history of the grant.\n scopes: approvedScopes,\n resources: request.resources,\n redirectUri: request.redirectUri,\n codeChallenge: request.codeChallenge,\n codeChallengeMethod: 'S256',\n nonce: request.nonce,\n authTime: user.authTime,\n expiresAt: new Date(now.getTime() + ctx.ttl.code * 1000),\n });\n\n ctx.track({\n type: 'oauth.consent_granted',\n userId: user.id,\n clientId: request.clientId,\n grantId: String(grant._id),\n ...(contextId ? { contextId } : {}),\n scopes: approvedScopes,\n });\n await ctx.audit({\n type: 'oauth.consent_granted',\n actor: 'user',\n clientId: request.clientId,\n userId: user.id,\n grantId: grant._id,\n meta: { scopes: approvedScopes, contextId, version: grant.version },\n });\n\n return {\n redirectTo: authorizationResponse(ctx, request.redirectUri, request.state, { code }),\n };\n}\n","import { createHash, sign } from 'node:crypto';\nimport { pairwiseSubject } from '../crypto.js';\nimport { toPublicClient } from './admin.js';\nimport type { ResolvedContext } from '../config.js';\nimport type { KeyManager, SigningKey } from '../keys.js';\nimport type {\n OAuthClientDoc,\n PackageUser,\n UserId,\n} from '../../../types/index.js';\n\n/**\n * The OIDC layer: `sub`, the signed `id_token`, and the `/userinfo` projection.\n *\n * The JWS is written by hand against `node:crypto` rather than pulled from\n * `jose`. Thirty lines against a runtime dependency in an authorization\n * server's trusted computing base is a trade worth making once, and the peer\n * set stays express + mongoose.\n *\n * The one thing that must not be \"cleaned up\": `dsaEncoding: 'ieee-p1363'`.\n * Node's default for ECDSA is DER, JWS ES256 is the fixed-width r‖s pair, and\n * the failure mode is not an exception — it is a client silently rejecting\n * every token while the server logs nothing.\n */\n\nconst b64u = (value: string | Buffer): string =>\n Buffer.from(value as never).toString('base64url');\n\n/**\n * Claims a host's `claims` adapter may not write.\n *\n * The first five are the token's identity and lifetime — letting host data\n * overwrite `sub` or `aud` turns a projection of profile fields into\n * impersonation. `nonce` and `at_hash` are the client's replay and\n * token-binding checks, and they are ours to compute for the same reason.\n */\nconst RESERVED_ID_TOKEN_CLAIMS = new Set(['iss', 'sub', 'aud', 'exp', 'iat', 'nonce', 'at_hash']);\n\nfunction signJws(key: SigningKey, payload: Record<string, unknown>): string {\n const header = { alg: key.alg, typ: 'JWT', kid: key.kid };\n const data = `${b64u(JSON.stringify(header))}.${b64u(JSON.stringify(payload))}`;\n const signature = sign('sha256', Buffer.from(data), {\n key: key.privateKey,\n dsaEncoding: 'ieee-p1363',\n });\n return `${data}.${signature.toString('base64url')}`;\n}\n\n/**\n * OIDC Core §3.1.3.6 — the left-most half of the SHA-256 of the ASCII access\n * token, base64url. It is what lets a client that received both over the same\n * channel prove they belong together.\n */\nfunction atHash(accessToken: string): string {\n const digest = createHash('sha256').update(accessToken, 'ascii').digest();\n return digest.subarray(0, digest.length / 2).toString('base64url');\n}\n\n/**\n * The client as an adapter may see it — `toPublicClient` from `admin.ts`, not a\n * local copy. Three hand-maintained copies of one projection is how a field\n * added to `PublicClient` reaches two of the three places it belongs.\n */\nconst publicClient = toPublicClient;\n\n/**\n * Read a value out of `pairwiseSubjects`, which is a `Map` on a hydrated\n * document and a plain object on a lean one. Both reach here.\n */\nfunction storedSubject(client: OAuthClientDoc, key: string): string | undefined {\n const map = client.pairwiseSubjects as unknown;\n if (map instanceof Map) return map.get(key) as string | undefined;\n if (map && typeof map === 'object') return (map as Record<string, string>)[key];\n return undefined;\n}\n\n/**\n * The `sub` this client sees for this user.\n *\n * `pairwise` is computed from the salt, but it is also **persisted** on the\n * client: the partner stores this value as their primary key, so it has to\n * survive anything that could change the derivation, and \"which subject did we\n * hand out\" has to be answerable from the database rather than recomputed.\n * OIDC Core §8.1.\n */\nexport async function subjectFor(\n ctx: ResolvedContext,\n client: OAuthClientDoc,\n userId: UserId,\n): Promise<string> {\n const key = String(userId);\n if (ctx.subjectMode !== 'pairwise') return key;\n if (!ctx.pairwiseSalt) {\n throw new Error('oauth-host: subjectMode is \"pairwise\" but no `pairwiseSalt` is configured');\n }\n\n const existing = storedSubject(client, key);\n if (existing) return existing;\n\n const subject = pairwiseSubject(key, client.clientId, ctx.pairwiseSalt);\n // `$setOnInsert` semantics by hand: only write when the field is still\n // absent, so a concurrent issuance cannot hand two subjects to one partner.\n await ctx.models.Client.updateOne(\n { clientId: client.clientId, [`pairwiseSubjects.${key}`]: { $exists: false } },\n { $set: { [`pairwiseSubjects.${key}`]: subject } },\n );\n const stored = await ctx.models.Client.findOne(\n { clientId: client.clientId },\n { pairwiseSubjects: 1 },\n );\n return (stored && storedSubject(stored, key)) || subject;\n}\n\n/** Standard claims derivable from the user adapter alone, gated by scope. */\nfunction standardClaims(user: PackageUser, scopes: string[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const granted = new Set(scopes);\n if (granted.has('profile')) {\n if (user.displayName) out.name = user.displayName;\n if (user.avatarUrl) out.picture = user.avatarUrl;\n }\n // No `email_verified`. The host never tells us, and asserting `false` is as\n // wrong as asserting `true` — clients branch on it.\n if (granted.has('email') && user.email) out.email = user.email;\n return out;\n}\n\nasync function hostClaims(\n ctx: ResolvedContext,\n args: { client: OAuthClientDoc; user: PackageUser; scopes: string[]; contextId: string | null },\n): Promise<Record<string, unknown>> {\n if (!ctx.claims) return {};\n return await ctx.claims(args.user, {\n scopes: args.scopes,\n contextId: args.contextId ?? undefined,\n client: publicClient(args.client),\n });\n}\n\nexport async function buildIdToken(\n ctx: ResolvedContext,\n keys: KeyManager,\n args: {\n client: OAuthClientDoc;\n user: PackageUser;\n scopes: string[];\n contextId: string | null;\n nonce?: string;\n authTime?: Date;\n accessToken?: string;\n },\n): Promise<string> {\n const key = await keys.getSigningKey();\n const now = Date.now();\n const skew = ctx.clockSkewMs;\n\n // Server time exclusively — never a client-supplied timestamp. `clockSkewMs`\n // widens the window at both ends rather than shifting it, so a client whose\n // clock is behind does not reject a token that is genuinely fresh. traps §15.\n const payload: Record<string, unknown> = {\n ...standardClaims(args.user, args.scopes),\n ...await hostClaims(ctx, args),\n };\n for (const claim of RESERVED_ID_TOKEN_CLAIMS) delete payload[claim];\n\n payload.iss = ctx.issuer;\n payload.sub = await subjectFor(ctx, args.client, args.user.id);\n payload.aud = args.client.clientId;\n payload.iat = Math.floor(now / 1000);\n payload.nbf = Math.floor((now - skew) / 1000);\n payload.exp = Math.floor((now + ctx.ttl.accessToken * 1000 + skew) / 1000);\n\n const authTime = args.authTime ?? args.user.authTime;\n if (authTime) payload.auth_time = Math.floor(authTime.getTime() / 1000);\n if (args.nonce) payload.nonce = args.nonce;\n if (args.accessToken) payload.at_hash = atHash(args.accessToken);\n\n return signJws(key, payload);\n}\n\n/**\n * The `/userinfo` body.\n *\n * Read live on every call, which is why access tokens carry no claims: there is\n * nothing cached to invalidate when the host's data changes.\n */\nexport async function buildUserInfo(\n ctx: ResolvedContext,\n args: {\n client: OAuthClientDoc;\n user: PackageUser;\n scopes: string[];\n contextId: string | null;\n },\n): Promise<Record<string, unknown>> {\n const claims: Record<string, unknown> = {\n ...standardClaims(args.user, args.scopes),\n ...await hostClaims(ctx, args),\n };\n // `sub` is the one claim a host cannot supply: OIDC Core §5.3.2 requires it\n // to match the `id_token`, and a client that checks will reject a mismatch.\n delete claims.sub;\n return { sub: await subjectFor(ctx, args.client, args.user.id), ...claims };\n}\n","import express from 'express';\nimport mongoose from 'mongoose';\nimport type { NextFunction, Request, RequestHandler, Response, Router } from 'express';\nimport { OAuthError, RedirectableAuthError, invalidRequest, unsupportedGrantType, wrap } from '../errors.js';\nimport { rateLimit } from '../rate-limit.js';\nimport { createKeyManager } from '../keys.js';\nimport { authenticateClient } from '../services/admin.js';\nimport {\n consentRedirectUrl,\n createAuthorizationRequest,\n loginRedirectUrl,\n validateAuthorizationRequest,\n} from '../services/authorize.js';\nimport { decideConsent, getConsentPayload } from '../services/consent.js';\nimport { buildIdToken, buildUserInfo } from '../services/oidc.js';\nimport {\n consumeCode,\n introspectAccessToken,\n issueForCode,\n revokeToken,\n rotateRefresh,\n} from '../services/tokens.js';\nimport type { ResolvedContext } from '../config.js';\nimport type { PackageUser } from '../../../types/index.js';\n\n/**\n * The protocol router.\n *\n * **Three trust bands share this mount, and each handler states its own.**\n * There is deliberately no shared \"authenticated\" middleware here, because the\n * bands authenticate different principals with different credentials:\n *\n * host session GET /authorize, /consent/:id, POST /consent/:id, /me/grants\n * → `ctx.resolveUser(req)` — a browser cookie the HOST issued\n * client POST /token, POST /revoke\n * → `authenticateClient` — a client id and secret\n * bearer GET /userinfo\n * → an access token this server minted\n * public GET /jwks\n *\n * A `router.use(requireSomething)` covering all of them is how a session cookie\n * ends up being sufficient to exchange somebody else's authorization code.\n */\nexport function createOAuthRouter(ctx: ResolvedContext): Router {\n const router = express.Router();\n const w = (h: Parameters<typeof wrap>[1]): RequestHandler => wrap(ctx.logger, h);\n const keys = createKeyManager(ctx);\n\n /**\n * The sanctioned body-parser exception — standards/traps.md #5.\n *\n * A library router must not mount a body parser, because it silently changes\n * parsing for everything mounted after it. RFC 6749 §4.1.3 nonetheless\n * REQUIRES `/token` (and RFC 7009 `/revoke`) to accept\n * `application/x-www-form-urlencoded`, and hosts mount `express.json()` only\n * — so a client following the spec exactly would get \"missing grant_type\"\n * forever. Route-level, on these two routes and nowhere else, never\n * `router.use()`. `test/flow.test.ts` asserts a form POST works on an app\n * that never mounted a urlencoded parser.\n */\n const form = express.urlencoded({ extended: false, limit: '10kb' });\n\n const ipKey = (req: Request): string => req.ip ?? 'unknown';\n const clientKey = (req: Request): string => clientIdFromRequest(req) ?? ipKey(req);\n const cors = corsMiddleware(ctx);\n\n // -------------------------------------------------------------------------\n // Literal paths FIRST. `/consent/:requestId` and `/me/grants/:id` are the\n // parameter routes in this file and they live at the bottom, because a\n // parameter segment will happily swallow a literal declared after it. Keep\n // the test named after that failure so nobody reorders this file back.\n // See standards/traps.md #4.\n // -------------------------------------------------------------------------\n\n // ---- host-session band ----\n\n router.get(\n '/authorize',\n rateLimit(ctx, 'authorize', ipKey),\n w(async (req, res) => {\n let validated;\n try {\n validated = await validateAuthorizationRequest(ctx, req.query as Record<string, unknown>);\n } catch (err) {\n // The redirect-vs-render split is a security boundary, not formatting.\n // A RedirectableAuthError means `client_id` and `redirect_uri` were both\n // validated against the registration, so the client is a proven-safe\n // place to send the error. An UnredirectableError means they were not,\n // and redirecting anyway is the open-redirect hole — it falls through\n // to `wrap`, which renders JSON.\n if (err instanceof RedirectableAuthError) {\n return res.redirect(302, err.toRedirect(ctx.issuer));\n }\n throw err;\n }\n\n const user = await ctx.resolveUser(req);\n if (!user) {\n // `/authorize` is a package route a signed-out user lands on directly,\n // so the sign-in bounce is ours to perform — standards/adapters.md.\n const to = loginRedirectUrl(ctx, `${ctx.issuer}${req.originalUrl}`);\n if (!to) {\n // No `loginUrl` configured. Rendering the error is the only honest\n // answer; redirecting to `/authorize` itself would loop forever.\n throw new OAuthError(\n 401,\n 'login_required',\n 'No user is signed in and no `loginUrl` is configured to send them to',\n );\n }\n return res.redirect(302, to);\n }\n\n const request = await createAuthorizationRequest(ctx, validated, user);\n return res.redirect(302, consentRedirectUrl(ctx, request.requestId));\n }),\n );\n\n router.get(\n '/me/grants',\n w(async (req, res) => {\n const user = await requireUser(ctx, req);\n // Capped and paginated even though a realistic user has under twenty —\n // the cap is what stops a host with one pathological account from\n // discovering the limit in production. See standards/traps.md #18.\n const limit = Math.min(Math.max(Number(req.query.limit) || 20, 1), 100);\n const skip = Math.max(Number(req.query.skip) || 0, 0);\n\n const grants = await ctx.models.Grant\n .find({ userId: user.id, revokedAt: null })\n .sort({ createdAt: -1 })\n .skip(skip)\n .limit(limit)\n .lean();\n\n const clients = await ctx.models.Client\n .find({ clientId: { $in: grants.map((g) => g.clientId) } })\n .lean();\n const byId = new Map(clients.map((c) => [c.clientId, c]));\n\n res.json({\n limit,\n items: grants.map((g) => ({\n // The grant id is the ONLY identifier that leaves: the DELETE below\n // needs it. No user id, no client _id, no token ids.\n id: String(g._id),\n client: {\n clientId: g.clientId,\n name: byId.get(g.clientId)?.name ?? g.clientId,\n branding: byId.get(g.clientId)?.branding ?? {},\n },\n scopes: g.scopes.map((id) => ctx.scopeIndex.get(id) ?? { id, label: id }),\n ...(g.contextId ? { contextId: g.contextId } : {}),\n createdAt: g.createdAt,\n lastUsedAt: g.lastUsedAt,\n })),\n });\n }),\n );\n\n // ---- client-authenticated band ----\n\n router.post(\n '/token',\n cors,\n form,\n rateLimit(ctx, 'token', clientKey),\n w(async (req, res) => {\n // RFC 6749 §5.1 — a token response must never be cached. Set before any\n // branch so an error answer carries it too.\n res.set('Cache-Control', 'no-store');\n res.set('Pragma', 'no-cache');\n\n const client = await authenticateClient(ctx, req);\n const body = (req.body ?? {}) as Record<string, unknown>;\n const grantType = str(body.grant_type);\n\n if (grantType === 'authorization_code') {\n const code = await consumeCode(ctx, str(body.code), {\n clientId: client.clientId,\n redirectUri: str(body.redirect_uri),\n codeVerifier: str(body.code_verifier),\n });\n const issued = await issueForCode(ctx, code);\n const idToken = issued.scopes.includes('openid')\n ? await buildIdToken(ctx, keys, {\n client,\n user: await ctx.loadUser(issued.userId),\n scopes: issued.scopes,\n contextId: issued.contextId,\n nonce: code.nonce,\n authTime: code.authTime,\n accessToken: issued.accessToken,\n })\n : undefined;\n return res.json(tokenResponse(issued, idToken));\n }\n\n if (grantType === 'refresh_token') {\n const issued = await rotateRefresh(ctx, str(body.refresh_token), {\n clientId: client.clientId,\n scope: body.scope === undefined ? undefined : str(body.scope),\n resources: list(body.resource),\n });\n // No `nonce` on a refresh: it belongs to the authorization request that\n // is now long gone, and replaying it would let a client bind a fresh\n // id_token to a stale request.\n const idToken = issued.scopes.includes('openid')\n ? await buildIdToken(ctx, keys, {\n client,\n user: await ctx.loadUser(issued.userId),\n scopes: issued.scopes,\n contextId: issued.contextId,\n accessToken: issued.accessToken,\n })\n : undefined;\n return res.json(tokenResponse(issued, idToken));\n }\n\n throw unsupportedGrantType(\n `'${grantType}' is not supported. This server issues authorization_code and refresh_token only.`,\n );\n }),\n );\n\n router.post(\n '/revoke',\n cors,\n form,\n rateLimit(ctx, 'token', clientKey),\n w(async (req, res) => {\n res.set('Cache-Control', 'no-store');\n const client = await authenticateClient(ctx, req);\n const body = (req.body ?? {}) as Record<string, unknown>;\n await revokeToken(ctx, str(body.token), client.clientId);\n // RFC 7009 §2.2 — an unknown, expired or already-revoked token is a 200.\n // The client's goal (\"this token must not work\") is satisfied either way,\n // and answering 400 turns revocation into a token-existence oracle.\n res.status(200).json({});\n }),\n );\n\n // ---- bearer band ----\n\n router.get(\n '/userinfo',\n w(async (req, res) => {\n const raw = /^Bearer +([^\\s]+)$/i.exec(req.headers.authorization ?? '')?.[1];\n if (!raw) throw bearerChallenge('invalid_request', 'A bearer access token is required');\n\n const token = await introspectAccessToken(ctx, raw);\n if (!token) throw bearerChallenge('invalid_token', 'The access token is expired, revoked or unknown');\n if (!token.scopes.includes('openid')) {\n throw new OAuthError(403, 'insufficient_scope', 'The `openid` scope is required', {\n headers: { 'WWW-Authenticate': 'Bearer error=\"insufficient_scope\", scope=\"openid\"' },\n });\n }\n\n const client = await ctx.models.Client.findOne({ clientId: token.clientId });\n if (!client) throw bearerChallenge('invalid_token', 'The client this token was issued to no longer exists');\n\n res.set('Cache-Control', 'no-store');\n res.json(await buildUserInfo(ctx, {\n client,\n user: await ctx.loadUser(token.userId),\n scopes: token.scopes,\n contextId: token.contextId,\n }));\n }),\n );\n\n // ---- public ----\n\n router.get('/jwks', w(async (_req, res) => {\n // Public keys, and public keys only. Cacheable on purpose: a client\n // refetching JWKS on every token validation is a self-inflicted DoS.\n res.set('Cache-Control', 'public, max-age=300');\n res.json(await keys.jwks());\n }));\n\n if (ctx.cors.tokenEndpoint) {\n router.options('/token', cors, (_req, res) => { res.sendStatus(204); });\n router.options('/revoke', cors, (_req, res) => { res.sendStatus(204); });\n }\n\n // ---- parameter paths LAST ----\n\n router.get(\n '/consent/:requestId',\n rateLimit(ctx, 'consent', ipKey),\n w(async (req, res) => {\n const user = await requireUser(ctx, req);\n res.json(await getConsentPayload(ctx, pathParam(req, 'requestId'), user));\n }),\n );\n\n router.post(\n '/consent/:requestId',\n rateLimit(ctx, 'consent', ipKey),\n w(async (req, res) => {\n const user = await requireUser(ctx, req);\n // The host mounts `express.json()`; this band is the host's own fetch\n // from its consent page, not a spec-mandated form post.\n const body = (req.body ?? {}) as Record<string, unknown>;\n if (typeof body.approve !== 'boolean') {\n throw invalidRequest('`approve` must be a boolean');\n }\n res.json(await decideConsent(ctx, pathParam(req, 'requestId'), user, {\n approve: body.approve,\n scopes: Array.isArray(body.scopes) ? body.scopes.map(String) : undefined,\n contextId: body.contextId === undefined ? undefined : String(body.contextId),\n }));\n }),\n );\n\n router.delete(\n '/me/grants/:id',\n w(async (req, res) => {\n const user = await requireUser(ctx, req);\n const id = pathParam(req, 'id');\n // Validate before querying: an unparseable id is a 404, not a cast error\n // surfacing as a 500.\n if (!mongoose.Types.ObjectId.isValid(id)) {\n throw new OAuthError(404, 'not_found', 'No such grant');\n }\n\n // Scoped to this user's own grants. Without the `userId` term this route\n // revokes anybody's grant for anyone who can guess an id.\n const grant = await ctx.models.Grant.findOneAndUpdate(\n { _id: id, userId: user.id, revokedAt: null },\n { $set: { revokedAt: new Date(), revokedBy: 'user' } },\n );\n if (!grant) throw new OAuthError(404, 'not_found', 'No such grant');\n\n const { modifiedCount } = await ctx.models.Token.updateMany(\n { grantId: grant._id, revokedAt: null },\n { $set: { revokedAt: new Date() } },\n );\n ctx.track({ type: 'oauth.grant_revoked', userId: user.id, clientId: grant.clientId, grantId: String(grant._id) });\n void ctx.audit({ type: 'oauth.grant_revoked', actor: 'user', userId: user.id, clientId: grant.clientId, grantId: grant._id });\n res.json({ revoked: true, tokensRevoked: modifiedCount ?? 0 });\n }),\n );\n\n return router;\n}\n\n// ---------------------------------------------------------------------------\n\nasync function requireUser(ctx: ResolvedContext, req: Request): Promise<PackageUser> {\n const user = await ctx.resolveUser(req);\n if (!user) {\n throw new OAuthError(401, 'login_required', 'No user is signed in for this request');\n }\n return user;\n}\n\nfunction bearerChallenge(code: string, description: string): OAuthError {\n return new OAuthError(401, code, description, {\n headers: { 'WWW-Authenticate': `Bearer error=\"${code}\", error_description=\"${description}\"` },\n });\n}\n\ninterface IssuedLike {\n accessToken: string;\n refreshToken?: string;\n expiresIn: number;\n scopes: string[];\n}\n\nfunction tokenResponse(issued: IssuedLike, idToken?: string): Record<string, unknown> {\n return {\n access_token: issued.accessToken,\n token_type: 'Bearer',\n expires_in: issued.expiresIn,\n ...(issued.refreshToken ? { refresh_token: issued.refreshToken } : {}),\n scope: issued.scopes.join(' '),\n // Only when `openid` was granted. Minting one unasked hands a client an\n // identity assertion it never requested consent for.\n ...(idToken ? { id_token: idToken } : {}),\n };\n}\n\n/**\n * A path parameter as a string.\n *\n * Express 5's types widen `req.params` values to `string | string[]` because a\n * wildcard segment can repeat. None of the parameters here can, so the coercion\n * is a type narrowing rather than a behavioural one.\n */\nfunction pathParam(req: Request, name: string): string {\n const value = (req.params as Record<string, string | string[] | undefined>)[name];\n return Array.isArray(value) ? (value[0] ?? '') : (value ?? '');\n}\n\n/** A form field, coerced to the string the services expect. */\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\n/** `resource` may legally repeat (RFC 8707 §2), so it is always a list here. */\nfunction list(value: unknown): string[] | undefined {\n if (value === undefined) return undefined;\n return Array.isArray(value) ? value.map(String) : [String(value)];\n}\n\n/** The client id as it arrives — Basic credentials or a form field. */\nfunction clientIdFromRequest(req: Request): string | null {\n const header = req.headers.authorization;\n if (header?.startsWith('Basic ')) {\n const decoded = Buffer.from(header.slice(6), 'base64').toString('utf8');\n const id = decoded.split(':')[0];\n if (id) return decodeURIComponent(id);\n }\n const body = (req.body ?? {}) as Record<string, unknown>;\n return typeof body.client_id === 'string' ? body.client_id : null;\n}\n\n/**\n * CORS on `/token` and `/revoke`, off by default.\n *\n * v1 has no public clients, so a browser has no business calling either — this\n * ships as a documented flag rather than an assumption. When it is off the\n * middleware is a passthrough, not a header-stripper: the host may have its own\n * CORS layer and this router does not get to override it.\n */\nfunction corsMiddleware(ctx: ResolvedContext): RequestHandler {\n if (!ctx.cors.tokenEndpoint) return (_req, _res, next) => next();\n\n const allowed = new Set(ctx.cors.origins);\n return (req: Request, res: Response, next: NextFunction) => {\n const origin = req.headers.origin;\n if (allowed.size === 0) {\n res.set('Access-Control-Allow-Origin', '*');\n } else if (origin && allowed.has(origin)) {\n res.set('Access-Control-Allow-Origin', origin);\n // Without `Vary` a shared cache can hand one origin another's answer.\n res.set('Vary', 'Origin');\n }\n res.set('Access-Control-Allow-Headers', 'Authorization, Content-Type');\n res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');\n res.set('Access-Control-Max-Age', '600');\n next();\n };\n}\n","import { resolveConfig } from './config.js';\nimport { syncModelIndexes } from './models.js';\nimport { createProtect } from './protect.js';\nimport { createDiscoveryRouter, createOAuthRouter } from './routes/index.js';\nimport {\n createClientsApi,\n createContextsApi,\n createGrantsApi,\n createUsersApi,\n} from './services/admin.js';\nimport type { CreateOAuthHostConfig, OAuthHostInstance } from '../../types/index.js';\n\nexport { defaultResolveUser, createUserAdapter } from './config.js';\nexport { createModels, syncModelIndexes } from './models.js';\nexport { OAuthError, RedirectableAuthError, UnredirectableError } from './errors.js';\n\n/**\n * oauth-host — the package factory.\n *\n * Returns routers the host mounts. Never an app, never a server.\n *\n * const oauth = createOAuthHost({ connection, issuer, resources, scopes, consentUrl })\n *\n * app.use(oauth.routes.discovery) // origin root\n * app.use('/oauth', express.json(), oauth.routes.oauth)\n * app.use('/mcp', oauth.protect('contacts.read'), mcpRouter)\n *\n * await oauth.syncIndexes() // before the first write\n *\n * Two routers rather than one because `/.well-known/*` is not relocatable —\n * RFC 8414 and RFC 9728 fix those paths at the origin root, and a client\n * bootstrapping from a URL it was given has no way to be told otherwise.\n *\n * The return type is the hand-written `OAuthHostInstance` from `types/`, not an\n * inferred shape. Annotating it here makes `tsc` fail when the source grows a\n * method the published declarations do not mention — the exact drift\n * `types/test-d.ts` exists to catch. See standards/traps.md #9.\n */\nexport function createOAuthHost(config: CreateOAuthHostConfig): OAuthHostInstance {\n const ctx = resolveConfig(config);\n\n return {\n routes: {\n // The discovery document publishes ABSOLUTE endpoint URLs, so it has to be\n // told where the oauth router lives. A router cannot learn its own mount\n // until a request arrives, by which time the metadata is already built.\n discovery: createDiscoveryRouter(ctx, ctx.mountPath),\n oauth: createOAuthRouter(ctx),\n },\n\n protect: createProtect(ctx),\n\n clients: createClientsApi(ctx),\n grants: createGrantsApi(ctx),\n users: createUsersApi(ctx),\n contexts: createContextsApi(ctx),\n\n /**\n * Build every index before the first write.\n *\n * Not optional and not lazy: the unique partial index on grants is what\n * stops one user holding two live grants for the same client, and mongoose\n * builds indexes in the background — a cold database will happily serve\n * the write that violates it first. See standards/traps.md #3.\n */\n syncIndexes: () => syncModelIndexes(ctx.models),\n\n /** Escape hatch. Prefer the APIs above; these carry no invariants. */\n models: ctx.models,\n };\n}\n"]}