@3sixty/api-server-native 0.20.0-next.0 → 0.20.0-next.1

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,"file":"nativeWebServer.js","sources":["../../src/nativeWebServer.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,uCAAuC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EACN,YAAY,IAAI,gBAAgB,EAKhC,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,YAAY,IAAI,iBAAiB,EAA8B,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,YAAY,IAAI,eAAe,EAA4B,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAkB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACN,aAAa,EACb,eAAe,EAYf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAe,EAAE,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjG,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAmC,MAAM,WAAW,CAAC;AAIpE;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAkD;IACtF;;OAEG;IACI,MAAM,CAAU,UAAU,GAAW,iBAAiB,CAAC;IAE9D;;;OAGG;IACK,MAAM,CAAU,mBAAmB,GAC1C,4HAA4H,CAAC;IAE9H;;;OAGG;IACK,MAAM,CAAU,mBAAmB,GAAW,IAAI,CAAC;IAE3D;;;OAGG;IACK,MAAM,CAAU,UAAU,GAAa,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAEjF;;;OAGG;IACK,MAAM,CAAU,eAAe,GAAuB;QAC7D,MAAM,EAAE;YACP,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB;YACnE,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC;SACxC;KACD,CAAC;IAEF;;;OAGG;IACK,MAAM,CAAU,YAAY,GAEhC;QACH,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;QAClC,EAAE,EAAE,KAAK,EAAC,IAAI,EAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,eAAe,CAAC;QACvF,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;KAChC,CAAC;IAEF;;;OAGG;IACK,MAAM,CAAU,mBAAmB,GAA4C;QACtF,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE;QACrC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,eAAe,CAAC;QACpE,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;QAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE;KACnC,CAAC;IAEF;;;OAGG;IACK,MAAM,CAAU,mBAAmB,GAAG,IAAI,OAAO,EAA0B,CAAC;IAEpF;;;OAGG;IACc,OAAO,CAAyC;IAEjE;;;OAGG;IACc,eAAe,CAAS;IAEzC;;;OAGG;IACc,UAAU,CAAgC;IAE3D;;;OAGG;IACc,aAAa,CAAyB;IAEvD;;;OAGG;IACc,qBAAqB,CAA8C;IAEpF;;;OAGG;IACK,iBAAiB,CAAS;IAElC;;;OAGG;IACK,KAAK,CAMX;IAEF;;;OAGG;IACK,OAAO,CAA4B;IAE3C;;;OAGG;IACK,kBAAkB,CAAc;IAExC;;;OAGG;IACK,aAAa,CAAU;IAE/B;;;OAGG;IACH,YAAY,OAA4C;QACvD,KAAK,CAAC;YACL,oBAAoB,EAAE,OAAO,EAAE,oBAAoB;YACnD,kBAAkB,EAAE,OAAO,EAAE,kBAAkB;YAC/C,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB;SACrD,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,IAAI,IAAI,CAAC;QAC/D,yFAAyF;QACzF,iEAAiE;QACjE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,aAAa,GAAG;YACpB,IAAI,EAAE,SAAS;YACf,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM;SAC1B,CAAC;QACF,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,eAAe,CAAC,UAAU,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,WAAW;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,KAAK,CACjB,mBAA2C,EAC3C,UAAyB,EACzB,qBAA+C,EAC/C,YAA6B,EAC7B,OAA2B;QAE3B,MAAM,IAAI,CAAC,YAAY,CACtB,mBAAmB,EACnB,UAAU,EACV,qBAAqB,EACrB,YAAY,EACZ,OAAO,CACP,CAAC;QAEF,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrD,CAAC;QAED,6DAA6D;QAC7D,KAAK,MAAM,iBAAiB,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACzE,KAAK,MAAM,SAAS,IAAI,iBAAiB,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACtD,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,iBAAiB,CAAC;YACzE,CAAC;QACF,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,GAAG;YACZ,iBAAiB,EAAE,WAAW,CAAC,iBAAiB;YAChD,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5C,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;YACnD,aAAa,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;SACpD,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC5C,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE3D,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;QACtE,MAAM,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;IAED;;;;;OAKG;IACO,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,IAAY;QACtD,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE,CACnF,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;YAC/C,CAAC,CAAC,iBAAiB,CAAC,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,QAAQ,CAAC;YAC7F,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAEnC,wEAAwE;QACxE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAEvB,gGAAgG;QAChG,MAAM,KAAK,GACV,IAAI,KAAK,WAAW;YACnB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEX,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QAEtB,KAAK,MAAM,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YACtF,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;gBAC5D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,iEAAiE;gBACjE,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;oBACxB,KAAK,EAAE,MAAM;oBACb,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;oBACd,MAAM,EAAE,eAAe,CAAC,UAAU;oBAClC,OAAO,EAAE,yBAAyB;oBAClC,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;oBACpC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;iBAC/B,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,WAAW;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAClD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;QAE7B,mFAAmF;QACnF,0DAA0D;QAC1D,MAAM,OAAO,GAAoB,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvF,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACO,eAAe;QACxB,MAAM,SAAS,GAAyD,EAAE,CAAC;QAC3E,KAAK,MAAM,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC;YAClC,IAAI,EAAE,CAAC,MAAM,CAAoD,OAAO,CAAC,EAAE,CAAC;gBAC3E,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1F,CAAC;QACF,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;OAGG;IACO,cAAc;QACvB,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACO,iBAAiB;QAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;IACzC,CAAC;IAED;;;OAGG;IACO,kBAAkB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,aAAa,CAC1B,UAAsC,EACtC,mBAA2C,EAC3C,UAAyB;QAEzB,IAAI,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACrE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACpC,IAAI,IAAI,GAAG,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC5D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBACnB,CAAC;gBACD,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;oBACxB,KAAK,EAAE,MAAM;oBACb,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;oBACd,MAAM,EAAE,eAAe,CAAC,UAAU;oBAClC,OAAO,EAAE,gBAAgB;oBACzB,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE;iBAC/C,CAAC,CAAC;gBAEH,MAAM,YAAY,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC;oBACvD,CAAC,CAAC,SAAS,CAAC,SAAS;oBACrB,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC;gBACzB,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;gBAC3C,IAAI,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,kBAAkB,EAAE;wBACtE,KAAK,EAAE,IAAI;wBACX,SAAS,EAAE,YAAY;qBACvB,CAAC,CAAC;gBACJ,CAAC;gBAED,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CACvF,IAAI,CAAC,iBAAiB,CACrB,GAAG,EACH,GAAG,EACH,SAAS,EACT,MAAgC,EAChC,YAAY,EACZ,SAAS,CACT,CACD,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,eAAe,CAC5B,qBAA+C,EAC/C,YAA6B;QAE7B,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,IAAI,EAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1F,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;gBACxC,MAAM,IAAI,GAAG,YAAY,CAAC,kBAAkB,CAC3C,YAAY,CAAC,mBAAmB,CAAC,WAAW,CAAC,IAAI,CAAC,CAClD,CAAC;gBACF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAElC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAE3C,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;oBACxB,KAAK,EAAE,MAAM;oBACb,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;oBACd,MAAM,EAAE,eAAe,CAAC,UAAU;oBAClC,OAAO,EAAE,kBAAkB;oBAC3B,IAAI,EAAE;wBACL,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI;wBACtC,SAAS;wBACT,SAAS,EAAE,KAAK;qBAChB;iBACD,CAAC,CAAC;gBAEH,MAAM,eAAe,GAAG,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;gBAEzC,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;oBAC/C,MAAM,mBAAmB,GAAyB;wBACjD,MAAM,EAAE,UAAU,CAAC,GAAG;wBACtB,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG;wBACzB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,KAA0B;wBAClD,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,OAAuB;wBACjD,QAAQ,EAAE,MAAM,CAAC,EAAE;qBACnB,CAAC;oBAEF,sDAAsD;oBACtD,IAAI,CAAC;wBACJ,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;4BACtD,MAAM,SAAS,CAAC,mBAAmB,EAAE,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;wBAC/E,CAAC;oBACF,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACd,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,eAAe,CAAC,YAAY,CAC7D,GAAG,EACH,IAAI,CAAC,kBAAkB,CACvB,CAAC;wBACF,MAAM,QAAQ,GAAkB,EAAE,CAAC;wBACnC,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;wBACxF,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBAC9B,CAAC;oBAED,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;wBAClC,IAAI,CAAC;4BACJ,mDAAmD;4BACnD,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;gCAC5D,MAAM,YAAY,CAAC,mBAAmB,EAAE,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;4BAClF,CAAC;wBACF,CAAC;wBAAC,MAAM,CAAC;4BACR,yEAAyE;wBAC1E,CAAC;oBACF,CAAC,CAAC,CAAC;oBAEH,+BAA+B;oBAC/B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAC,IAAI,EAAC,EAAE;wBAC7B,+EAA+E;wBAC/E,oEAAoE;wBACpE,IAAI,CAAC;4BACJ,MAAM,IAAI,CAAC,mBAAmB,CAC7B,WAAW,EACX,MAAM,EACN,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EACzB,KAAK,EACL,IAAI,CACJ,CAAC;wBACH,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC;4BACd,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,eAAe,CAAC,YAAY,CAC7D,GAAG,EACH,IAAI,CAAC,kBAAkB,CACvB,CAAC;4BACF,MAAM,QAAQ,GAAkB,EAAE,CAAC;4BACnC,eAAe,CAAC,aAAa,CAC5B,QAAQ,EACR,KAAK,EACL,cAAc,EACd,IAAI,CAAC,kBAAkB,CACvB,CAAC;4BACF,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;wBAC9B,CAAC;oBACF,CAAC,CAAC,CAAC;gBACJ,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,aAAa,CAAC,GAAoB,EAAE,GAAmB;QACpE,IAAI,CAAC;YACJ,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO;YACR,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,UAAU,CAAC,GAAG,CAAsB,CAAC;YACnE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;YAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAEpC,uEAAuE;YACvE,MAAM,IAAI,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAChE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACJ,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,MAAM,IAAI,CAAC,oBAAoB,CAC9B,cAAc,CAAC,UAAU,EACzB,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CACzE,CAAC;gBACH,CAAC;YACF,CAAC;YAED,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC3C,sFAAsF;YACtF,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;gBACnD,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,MAAM,KAAK,GACV,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAuB,CAAC;gBACvF,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACP,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;wBAC/D,MAAM,IAAI,CAAC,oBAAoB,CAC9B,cAAc,CAAC,UAAU,EACzB,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE;4BAC5D,KAAK;4BACL,cAAc,EAAE,IAAI,CAAC,eAAe;yBACpC,CAAC,CACF,CAAC;oBACH,CAAC;gBACF,CAAC;gBACD,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9E,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAC,iBAAiB,CAC9B,GAAoB,EACpB,GAAmB,EACnB,SAAiB,EACjB,UAAkC,EAClC,KAAwB,EACxB,SAAsB;QAEtB,MAAM,QAAQ,GAAI,GAAG,CAAC,MAA6B,CAAC,SAAS,KAAK,IAAI,CAAC;QACvE,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;QAC3C,6EAA6E;QAC7E,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAChF,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,aAAa,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAuB,CAAC;QAE5C,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAChD,CAAC,GAAG,CAAC,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,EAAgB,EAC1D,GAAG,aAAa,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,EACnC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAC7C,KAAK,EACL,UAAU,EACV,OAAO,CACP,CAAC;QAEF,MAAM,YAAY,GAAkB,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClF,MAAM,cAAc,GAAG,EAAE,CAAC;QAE1B,MAAM,IAAI,CAAC,iBAAiB,CAC3B,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,cAAc,CACd,CAAC;QAEF,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,mBAAmB,CAChC,WAAyB,EACzB,MAAc,EACd,QAAgB,EAChB,SAAiB,EACjB,OAAiC;QAEjC,MAAM,mBAAmB,GAAyB;YACjD,MAAM,EAAE,UAAU,CAAC,GAAG;YACtB,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,KAA0B;YAClD,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,OAAuB;YACjD,+EAA+E;YAC/E,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACnD,QAAQ,EAAE,MAAM,CAAC,EAAE;SACnB,CAAC;QACF,MAAM,YAAY,GAAkB,EAAE,CAAC;QACvC,MAAM,UAAU,GAAgB,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,EAAE,CAAC;QAE1B,OAAO,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC;QACtC,OAAO,mBAAmB,CAAC,KAAK,EAAE,SAAS,CAAC;QAE5C,MAAM,IAAI,CAAC,mBAAmB,CAC7B,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACzB,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC,CACD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,SAAS,CAAC,GAAoB,EAAE,GAAmB;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAClC,MAAM,OAAO,GACZ,IAAI,CAAC,iBAAiB,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACd,CAAC;QAED,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC;QAC1D,GAAG,CAAC,SAAS,CAAC,+BAA+B,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEnE,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;YACvC,IACC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;gBACvB,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,EAC5D,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,EAAE;oBACxC,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,GAAG,SAAS,CAAC,SAAS,iBAAiB;iBAClE,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gBACrC,OAAO,IAAI,CAAC;YACb,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,EAAE;gBACvC,8BAA8B,EAAE,IAAI,CAAC,YAAY;gBACjD,8BAA8B,EAAE,IAAI,CAAC,YAAY;gBACjD,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,GAAG;aAChC,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,SAAS,CACtB,GAAoB,EACpB,OAAqB,EACrB,SAAiB;QAEjB,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;YACrE,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3D,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACb,IAAI,EAAE;aACN,WAAW,EAAE,CAAC;QAEhB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,sEAAsE;YACtE,IAAI,SAAS,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,oBAAoB,CAC9B,cAAc,CAAC,UAAU,EACzB,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC,CAC7D,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAChE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAClC,OAAO,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,SAAS,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,CAAC,oBAAoB,CAC9B,cAAc,CAAC,UAAU,EACzB,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,GAAG,CAAC,CAC/E,CAAC;YACH,CAAC;QACF,CAAC;QAED,IAAI,SAAS,KAAK,SAAS,CAAC,SAAS,EAAE,CAAC;YACvC,OAAO,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,CAAC,oBAAoB,CAC9B,cAAc,CAAC,oBAAoB,EACnC,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,sBAAsB,EAAE;YACpE,WAAW,EAAE,SAAS;SACtB,CAAC,CACF,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,QAAQ,CACrB,GAAoB,EACpB,OAAqB,EACrB,SAAiB;QAEjB,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC;YAChF,MAAM,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,KAAe,CAAC;YAC/B,KAAK,IAAI,MAAM,CAAC,UAAU,CAAC;YAC3B,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAED,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACK,uBAAuB,CAAC,SAAiB;QAChD,OAAO,IAAI,CAAC,oBAAoB,CAC/B,cAAc,CAAC,eAAe,EAC9B,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,CAAC,CAC3E,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,oBAAoB,CAAC,UAA0B,EAAE,KAAmB;QAC3E,eAAe,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,YAAY,CACzB,GAAoB,EACpB,GAAmB,EACnB,YAA2B;QAE3B,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC3C,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;gBACvC,CAAC;YACF,CAAC;QACF,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,IAAI,cAAc,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAY,YAAY,CAAC,IAAI,CAAC;QAE3C,IACC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;YACjB,MAAM,KAAK,cAAc,CAAC,SAAS;YACnC,MAAM,KAAK,cAAc,CAAC,WAAW,EACpC,CAAC;YACF,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC,WAAW,CAAC;YAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,OAAO,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;gBAC1C,OAAO,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAC;gBACvC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;gBACjD,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC/B,MAAM,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC9E,CAAC;iBAAM,CAAC;gBACP,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC/B,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7B,CAAC;YACD,OAAO;QACR,CAAC;QAED,IAAI,IAAgB,CAAC;QACrB,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,IAAI,GAAG,OAAO,CAAC;YACf,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC,WAAW,CAAC;QAC5D,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC,SAAS,iBAAiB,CAAC;QAC9E,CAAC;aAAM,CAAC;YACP,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,iBAAiB,CAAC;QACzE,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,IAAI,eAAe,CAAC,mBAAmB,EAAE,CAAC;YAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,IAAI,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC1D,OAAO,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAC;gBACvC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;YAClD,CAAC;QACF,CAAC;QAED,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;QACrD,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACK,YAAY,CAAC,OAAgB;QACpC,IAAI,EAAE,CAAC,QAAQ,CAAE,OAA6B,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,OAAO,OAAmB,CAAC;QAC5B,CAAC;QACD,IAAI,EAAE,CAAC,QAAQ,CAAE,OAAmC,CAAC,SAAS,CAAC,EAAE,CAAC;YACjE,OAAO,QAAQ,CAAC,OAAO,CAAC,OAA6B,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACK,cAAc,CAAC,GAAoB,EAAE,OAA4B;QACxE,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrD,IACC,CAAC,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC;YAC/B,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YACtC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;YACvB,CAAC,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,EACrD,CAAC;YACF,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,QAA4B,CAAC;QACjC,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5D,MAAM,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACjE,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,CAAC;gBAC3C,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACjD,CAAC,CAAC,CAAC,CAAC;YACL,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YACnD,MAAM,UAAU,GACf,QAAQ,KAAK,GAAG;gBACf,CAAC,CAAC,eAAe,CAAC,UAAU;gBAC5B,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;YAC3D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACpC,MAAM,QAAQ,GACb,OAAO,GAAG,eAAe;oBACzB,CAAC,OAAO,KAAK,eAAe;wBAC3B,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC;wBACxB,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;4BAC5C,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACjD,IAAI,OAAO,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;oBAC7B,QAAQ,GAAG,SAAS,CAAC;oBACrB,eAAe,GAAG,OAAO,CAAC;gBAC3B,CAAC;YACF,CAAC;QACF,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACK,UAAU,CAAC,GAAmB,EAAE,OAA4B,EAAE,KAAa;QAClF,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;QACtB,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAE,CAAC;QAC3F,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,SAAS,CAAC,GAAmB,EAAE,KAAc;QAC1D,IAAI,cAAc,GAAG,eAAe,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAe,CAAC,CAAC;QAC9E,IAAI,GAAW,CAAC;QAChB,IAAI,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzD,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC;YACzB,cAAc,GAAG,YAAY,CAAC,cAAc,CAAC;QAC9C,CAAC;aAAM,CAAC;YACP,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC;QACjD,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;YACxB,KAAK,EAAE,OAAO;YACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,MAAM,EAAE,eAAe,CAAC,UAAU;YAClC,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,GAAG;SACV,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YACrB,6EAA6E;YAC7E,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,OAAO;QACR,CAAC;QAED,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,OAAO,GAAwB;YACpC,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,iBAAiB;YAC7D,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,UAAU;SAC5C,CAAC;QACF,IAAI,cAAc,KAAK,cAAc,CAAC,eAAe,EAAE,CAAC;YACvD,qFAAqF;YACrF,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;QAC9B,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,QAAQ,CACrB,MAA4C,EAC5C,IAAY,EACZ,IAAY;QAEZ,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;gBAC9B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC5B,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,iBAAiB,CAC9B,YAAoB,EACpB,MAAiC;QAEjC,MAAM,YAAY,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1E,YAAY,CAAC,iBAAiB,EAAE,CAAC;QACjC,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,YAAY,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,WAAW,CAAC,MAA4C;QACrE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["// Copyright 2026 3Sixty Trade Ltd.\n// SPDX-License-Identifier: Apache-2.0.\nimport { lookup } from \"node:dns/promises\";\nimport { once } from \"node:events\";\nimport {\n\tcreateServer as createHttpServer,\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeaders,\n\ttype Server as HttpServer,\n\ttype ServerResponse\n} from \"node:http\";\nimport { createServer as createHttpsServer, type Server as HttpsServer } from \"node:https\";\nimport { createServer as createNetServer, type Server as NetServer } from \"node:net\";\nimport { parse as parseQuery } from \"node:querystring\";\nimport { Readable, type Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport type { ReadableStream as NodeReadableStream } from \"node:stream/web\";\nimport type { TLSSocket } from \"node:tls\";\nimport { promisify } from \"node:util\";\nimport zlib from \"node:zlib\";\nimport { BaseServer } from \"@3sixty/api-core-server\";\nimport {\n\tHttpBodyLimit,\n\tHttpErrorHelper,\n\ttype IHttpRequest,\n\ttype IHttpRequestPathParams,\n\ttype IHttpRequestQuery,\n\ttype IHttpResponse,\n\ttype IMimeTypeProcessor,\n\ttype IRestRoute,\n\ttype IRestRouteProcessor,\n\ttype ISocketRoute,\n\ttype ISocketRouteProcessor,\n\ttype ISocketServerRequest,\n\ttype IWebServerOptions\n} from \"@3sixty/api-models\";\nimport type { IContextIds } from \"@3sixty/context\";\nimport { BaseError, Converter, GeneralError, type IError, Is, StringHelper } from \"@3sixty/core\";\n\nimport { HeaderTypes, HttpMethod, HttpStatusCode, type IHttpHeaders, MimeTypes } from \"@3sixty/web\";\nimport Router from \"find-my-way\";\nimport { Server, type ServerOptions, type Socket } from \"socket.io\";\nimport type { INativeWebServerConfig } from \"./models/INativeWebServerConfig.js\";\nimport type { INativeWebServerConstructorOptions } from \"./models/INativeWebServerConstructorOptions.js\";\n\n/**\n * Implementation of the web server using the Node.js HTTP server and the find-my-way router.\n */\nexport class NativeWebServer extends BaseServer<Router.Instance<Router.HTTPVersion.V1>> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = \"NativeWebServer\";\n\n\t/**\n\t * Matches the content types which are worth compressing.\n\t * @internal\n\t */\n\tprivate static readonly _COMPRESSIBLE_TYPES: RegExp =\n\t\t/^\\s*(?:text\\/(?!event-stream)|application\\/(?:json|javascript|xml|x-www-form-urlencoded)|[^;\\s]+\\+(?:json|xml|text|yaml))/i;\n\n\t/**\n\t * The minimum size in bytes of a response body before it is compressed.\n\t * @internal\n\t */\n\tprivate static readonly _COMPRESS_THRESHOLD: number = 1024;\n\n\t/**\n\t * The supported response encodings in order of preference, matching the Fastify defaults.\n\t * @internal\n\t */\n\tprivate static readonly _ENCODINGS: string[] = [\"zstd\", \"br\", \"gzip\", \"deflate\"];\n\n\t/**\n\t * The Brotli options, matching the Fastify defaults as the zlib defaults are very slow.\n\t * @internal\n\t */\n\tprivate static readonly _BROTLI_OPTIONS: zlib.BrotliOptions = {\n\t\tparams: {\n\t\t\t[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,\n\t\t\t[zlib.constants.BROTLI_PARAM_QUALITY]: 4\n\t\t}\n\t};\n\n\t/**\n\t * The compressors for each encoding.\n\t * @internal\n\t */\n\tprivate static readonly _COMPRESSORS: {\n\t\t[encoding: string]: (body: Uint8Array) => Promise<Buffer>;\n\t} = {\n\t\tzstd: promisify(zlib.zstdCompress),\n\t\tbr: async body => promisify(zlib.brotliCompress)(body, NativeWebServer._BROTLI_OPTIONS),\n\t\tgzip: promisify(zlib.gzip),\n\t\tdeflate: promisify(zlib.deflate)\n\t};\n\n\t/**\n\t * The stream compressors for each encoding.\n\t * @internal\n\t */\n\tprivate static readonly _STREAM_COMPRESSORS: { [encoding: string]: () => Transform } = {\n\t\tzstd: () => zlib.createZstdCompress(),\n\t\tbr: () => zlib.createBrotliCompress(NativeWebServer._BROTLI_OPTIONS),\n\t\tgzip: () => zlib.createGzip(),\n\t\tdeflate: () => zlib.createDeflate()\n\t};\n\n\t/**\n\t * The HTTP status codes for the errors raised by the transport.\n\t * @internal\n\t */\n\tprivate static readonly _ERROR_STATUS_CODES = new WeakMap<object, HttpStatusCode>();\n\n\t/**\n\t * The router.\n\t * @internal\n\t */\n\tprivate readonly _router: Router.Instance<Router.HTTPVersion.V1>;\n\n\t/**\n\t * The maximum length of a path param.\n\t * @internal\n\t */\n\tprivate readonly _maxParamLength: number;\n\n\t/**\n\t * The options for the node web server.\n\t * @internal\n\t */\n\tprivate readonly _webConfig: INativeWebServerConfig[\"web\"];\n\n\t/**\n\t * The options for the socket server.\n\t * @internal\n\t */\n\tprivate readonly _socketConfig: Partial<ServerOptions>;\n\n\t/**\n\t * The mime type processors keyed by the media type they handle.\n\t * @internal\n\t */\n\tprivate readonly _mimeTypeProcessorMap: { [mediaType: string]: IMimeTypeProcessor };\n\n\t/**\n\t * The body limit for requests which do not match a route.\n\t * @internal\n\t */\n\tprivate _defaultBodyLimit: number;\n\n\t/**\n\t * The resolved CORS settings, available once built.\n\t * @internal\n\t */\n\tprivate _cors?: {\n\t\thasWildcardOrigin: boolean;\n\t\torigins: string[];\n\t\tallowMethods: string;\n\t\tallowHeaders: string;\n\t\texposeHeaders: string;\n\t};\n\n\t/**\n\t * The node server, available once listening.\n\t * @internal\n\t */\n\tprivate _server?: HttpServer | HttpsServer;\n\n\t/**\n\t * Listeners for additional bound addresses, which forward connections to the main server.\n\t * @internal\n\t */\n\tprivate _additionalServers: NetServer[];\n\n\t/**\n\t * The socket server, available once built with socket routes.\n\t * @internal\n\t */\n\tprivate _socketServer?: Server;\n\n\t/**\n\t * Create a new instance of NativeWebServer.\n\t * @param options The options for the server.\n\t */\n\tconstructor(options?: INativeWebServerConstructorOptions) {\n\t\tsuper({\n\t\t\tloggingComponentType: options?.loggingComponentType,\n\t\t\tmimeTypeProcessors: options?.mimeTypeProcessors,\n\t\t\tincludeErrorStack: options?.config?.includeErrorStack\n\t\t});\n\n\t\tthis._webConfig = options?.config?.web;\n\t\tthis._maxParamLength = this._webConfig?.maxParamLength ?? 2000;\n\t\t// The router does not match a route with a param over its limit, so the limit is checked\n\t\t// once matched, to respond like Fastify rather than as not found\n\t\tthis._router = Router({ maxParamLength: Number.MAX_SAFE_INTEGER });\n\t\tthis._socketConfig = {\n\t\t\tpath: \"/socket\",\n\t\t\t...options?.config?.socket\n\t\t};\n\t\tthis._mimeTypeProcessorMap = {};\n\t\tthis._defaultBodyLimit = 0;\n\t\tthis._additionalServers = [];\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn NativeWebServer.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the web server instance.\n\t * @returns The web server instance.\n\t */\n\tpublic getInstance(): Router.Instance<Router.HTTPVersion.V1> {\n\t\treturn this._router;\n\t}\n\n\t/**\n\t * Build the server.\n\t * @param restRouteProcessors The processors for incoming requests over REST.\n\t * @param restRoutes The REST routes.\n\t * @param socketRouteProcessors The processors for incoming requests over Sockets.\n\t * @param socketRoutes The socket routes.\n\t * @param options Options for building the server.\n\t * @returns A promise that resolves when the server is fully built and ready to start.\n\t */\n\tpublic async build(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[],\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[],\n\t\toptions?: IWebServerOptions\n\t): Promise<void> {\n\t\tawait this.prepareBuild(\n\t\t\trestRouteProcessors,\n\t\t\trestRoutes,\n\t\t\tsocketRouteProcessors,\n\t\t\tsocketRoutes,\n\t\t\toptions\n\t\t);\n\n\t\tif (Is.arrayValue(socketRoutes)) {\n\t\t\tthis._socketServer = new Server(this._socketConfig);\n\t\t}\n\n\t\t// Processors supplied first take precedence for a media type\n\t\tfor (const mimeTypeProcessor of [...this._mimeTypeProcessors].reverse()) {\n\t\t\tfor (const mediaType of mimeTypeProcessor.getTypes()) {\n\t\t\t\tthis._mimeTypeProcessorMap[mediaType.toLowerCase()] = mimeTypeProcessor;\n\t\t\t}\n\t\t}\n\n\t\tconst corsOptions = this.resolveCorsOptions(options);\n\t\tthis._cors = {\n\t\t\thasWildcardOrigin: corsOptions.hasWildcardOrigin,\n\t\t\torigins: corsOptions.origins,\n\t\t\tallowMethods: corsOptions.methods.join(\", \"),\n\t\t\tallowHeaders: corsOptions.allowedHeaders.join(\", \"),\n\t\t\texposeHeaders: corsOptions.exposedHeaders.join(\", \")\n\t\t};\n\n\t\tconst bodyLimits = this.resolveBodyLimits();\n\t\tthis._defaultBodyLimit = bodyLimits[HttpBodyLimit.Default];\n\n\t\tawait this.addRoutesRest(bodyLimits, restRouteProcessors, restRoutes);\n\t\tawait this.addRoutesSocket(socketRouteProcessors, socketRoutes);\n\t}\n\n\t/**\n\t * Start listening for connections on the transport.\n\t * @param host The host to bind to.\n\t * @param port The port to bind to.\n\t * @returns A promise that resolves when the transport is listening.\n\t */\n\tprotected async serverListen(host: string, port: number): Promise<void> {\n\t\tconst listener = async (req: IncomingMessage, res: ServerResponse): Promise<void> =>\n\t\t\tthis.handleRequest(req, res);\n\n\t\tconst server = Is.object(this._webConfig?.https)\n\t\t\t? createHttpsServer({ ...this._webConfig.serverOptions, ...this._webConfig.https }, listener)\n\t\t\t: createHttpServer(this._webConfig?.serverOptions ?? {}, listener);\n\t\tthis._socketServer?.attach(server);\n\n\t\t// Generate the optimised lookups now that all the routes are registered\n\t\tthis._router.compile();\n\n\t\t// Like Fastify, bind every address localhost resolves to, so both IPv4 and IPv6 clients connect\n\t\tconst hosts =\n\t\t\thost === \"localhost\"\n\t\t\t\t? [...new Set((await lookup(host, { all: true })).map(a => a.address))]\n\t\t\t\t: [host];\n\n\t\tawait this.listenOn(server, hosts[0], port);\n\t\tthis._server = server;\n\n\t\tfor (const additionalHost of hosts.slice(1)) {\n\t\t\tconst additionalServer = createNetServer(socket => server.emit(\"connection\", socket));\n\t\t\ttry {\n\t\t\t\tawait this.listenOn(additionalServer, additionalHost, port);\n\t\t\t\tthis._additionalServers.push(additionalServer);\n\t\t\t} catch (err) {\n\t\t\t\t// An additional address failing to bind does not stop the server\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: NativeWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"additionalBindingFailed\",\n\t\t\t\t\tdata: { host: additionalHost, port },\n\t\t\t\t\terror: BaseError.fromError(err)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Close the transport and all of its connections.\n\t * @returns A promise that resolves when the transport has closed.\n\t */\n\tprotected async serverClose(): Promise<void> {\n\t\tconst server = this._server;\n\t\tconst additionalServers = this._additionalServers;\n\t\tthis._server = undefined;\n\t\tthis._additionalServers = [];\n\n\t\t// The forwarded connections are only released when the main server closes its idle\n\t\t// connections, so all the servers must be closed together\n\t\tconst closing: Promise<void>[] = additionalServers.map(async s => this.closeServer(s));\n\n\t\tif (!Is.empty(this._socketServer)) {\n\t\t\tclosing.push(this.closeSocketServer(this._socketServer, server));\n\t\t} else if (!Is.empty(server)) {\n\t\t\tclosing.push(this.closeServer(server));\n\t\t}\n\n\t\tawait Promise.all(closing);\n\t}\n\n\t/**\n\t * Get the addresses the transport is bound to.\n\t * @returns The bound addresses.\n\t */\n\tprotected serverAddresses(): { address: string; family?: string; port: number }[] {\n\t\tconst addresses: { address: string; family?: string; port: number }[] = [];\n\t\tfor (const server of [this._server, ...this._additionalServers]) {\n\t\t\tconst address = server?.address();\n\t\t\tif (Is.object<{ address: string; family: string; port: number }>(address)) {\n\t\t\t\taddresses.push({ address: address.address, family: address.family, port: address.port });\n\t\t\t}\n\t\t}\n\t\treturn addresses;\n\t}\n\n\t/**\n\t * Whether the transport is serving over TLS.\n\t * @returns True if the transport is secure.\n\t */\n\tprotected serverIsSecure(): boolean {\n\t\treturn Is.object(this._webConfig?.https);\n\t}\n\n\t/**\n\t * Whether the transport is currently listening for connections.\n\t * @returns True if the transport is listening.\n\t */\n\tprotected serverIsListening(): boolean {\n\t\treturn this._server?.listening ?? false;\n\t}\n\n\t/**\n\t * Whether a GET route is registered for the root path.\n\t * @returns True if the root route is registered.\n\t */\n\tprotected serverHasRootRoute(): boolean {\n\t\treturn this._router.hasRoute(HttpMethod.GET, \"/\");\n\t}\n\n\t/**\n\t * Add the REST routes to the server.\n\t * @param bodyLimits The named body limits in bytes.\n\t * @param restRouteProcessors The processors for the incoming requests.\n\t * @param restRoutes The REST routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesRest(\n\t\tbodyLimits: { [name: string]: number },\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[]\n\t): Promise<void> {\n\t\tif (Is.arrayValue(restRouteProcessors) && Is.arrayValue(restRoutes)) {\n\t\t\tfor (const restRoute of restRoutes) {\n\t\t\t\tlet path = StringHelper.trimTrailingSlashes(restRoute.path);\n\t\t\t\tif (!path.startsWith(\"/\")) {\n\t\t\t\t\tpath = `/${path}`;\n\t\t\t\t}\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: NativeWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"restRouteAdded\",\n\t\t\t\t\tdata: { route: path, method: restRoute.method }\n\t\t\t\t});\n\n\t\t\t\tconst bodyLimitKey = Is.stringValue(restRoute.bodyLimit)\n\t\t\t\t\t? restRoute.bodyLimit\n\t\t\t\t\t: HttpBodyLimit.Default;\n\t\t\t\tconst bodyLimit = bodyLimits[bodyLimitKey];\n\t\t\t\tif (Is.empty(bodyLimit)) {\n\t\t\t\t\tthrow new GeneralError(NativeWebServer.CLASS_NAME, \"unknownBodyLimit\", {\n\t\t\t\t\t\troute: path,\n\t\t\t\t\t\tbodyLimit: bodyLimitKey\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis._router.on(restRoute.method, path, async (req, res, params, store, searchParams) =>\n\t\t\t\t\tthis.handleRequestRest(\n\t\t\t\t\t\treq,\n\t\t\t\t\t\tres,\n\t\t\t\t\t\tbodyLimit,\n\t\t\t\t\t\tparams as IHttpRequestPathParams,\n\t\t\t\t\t\tsearchParams,\n\t\t\t\t\t\trestRoute\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add the socket routes to the server.\n\t * @param socketRouteProcessors The processors for the incoming requests.\n\t * @param socketRoutes The socket routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesSocket(\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[]\n\t): Promise<void> {\n\t\tconst io = this._socketServer;\n\t\tif (Is.arrayValue(socketRouteProcessors) && Is.arrayValue(socketRoutes) && !Is.empty(io)) {\n\t\t\tfor (const socketRoute of socketRoutes) {\n\t\t\t\tconst path = StringHelper.trimLeadingSlashes(\n\t\t\t\t\tStringHelper.trimTrailingSlashes(socketRoute.path)\n\t\t\t\t);\n\t\t\t\tconst pathParts = path.split(\"/\");\n\n\t\t\t\tconst namespace = `/${pathParts[0]}`;\n\t\t\t\tconst topic = pathParts.slice(1).join(\"/\");\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: NativeWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"socketRouteAdded\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\thandshakePath: this._socketConfig.path,\n\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\teventName: topic\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst socketNamespace = io.of(namespace);\n\n\t\t\t\tsocketNamespace.on(\"connection\", async socket => {\n\t\t\t\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\t\t\t\tmethod: HttpMethod.GET,\n\t\t\t\t\t\turl: socket.handshake.url,\n\t\t\t\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\t\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t\t\t\tsocketId: socket.id\n\t\t\t\t\t};\n\n\t\t\t\t\t// Pass the connected information on to any processors\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const connected of this._socketChains.connected) {\n\t\t\t\t\t\t\tawait connected(socketServerRequest, socketRoute, this._loggingComponentType);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\tHttpErrorHelper.buildResponse(response, error, httpStatusCode, this._includeErrorStack);\n\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t}\n\n\t\t\t\t\tsocket.on(\"disconnect\", async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// The socket disconnected so notify any processors\n\t\t\t\t\t\t\tfor (const disconnected of this._socketChains.disconnected) {\n\t\t\t\t\t\t\t\tawait disconnected(socketServerRequest, socketRoute, this._loggingComponentType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// If something fails on a disconnect there is not much we can do with it\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// Handle any incoming messages\n\t\t\t\t\tsocket.on(topic, async data => {\n\t\t\t\t\t\t// The listener is async, so anything escaping it would surface as an unhandled\n\t\t\t\t\t\t// rejection and terminate the process, emit it on the topic instead\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.handleRequestSocket(\n\t\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\t\tsocket,\n\t\t\t\t\t\t\t\t`/${pathParts.join(\"/\")}`,\n\t\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\t\tdata\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\t\tHttpErrorHelper.buildResponse(\n\t\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\thttpStatusCode,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle an incoming HTTP request, routing it to its handler.\n\t * @param req The incoming request.\n\t * @param res The outgoing response.\n\t * @internal\n\t */\n\tprivate async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n\t\ttry {\n\t\t\tif (this.applyCors(req, res)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst method = (req.method ?? HttpMethod.GET) as Router.HTTPMethod;\n\t\t\tconst url = req.url ?? \"/\";\n\t\t\tconst queryStart = url.indexOf(\"?\");\n\n\t\t\t// Like Fastify, a path which is not valid percent encoding is rejected\n\t\t\tconst path = queryStart === -1 ? url : url.slice(0, queryStart);\n\t\t\tif (path.includes(\"%\")) {\n\t\t\t\ttry {\n\t\t\t\t\tdecodeURIComponent(path);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow this.createTransportError(\n\t\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"invalidUrl\", { path }, err)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet found = this._router.find(method, url);\n\t\t\t// Like Fastify, HEAD requests are served by the GET route when there is no HEAD route\n\t\t\tif (Is.empty(found) && method === HttpMethod.HEAD) {\n\t\t\t\tfound = this._router.find(HttpMethod.GET, url);\n\t\t\t}\n\n\t\t\tif (Is.empty(found)) {\n\t\t\t\tconst query =\n\t\t\t\t\tqueryStart === -1 ? {} : (parseQuery(url.slice(queryStart + 1)) as IHttpRequestQuery);\n\t\t\t\tawait this.handleRequestRest(req, res, this._defaultBodyLimit, {}, query);\n\t\t\t} else {\n\t\t\t\tfor (const param of Object.keys(found.params)) {\n\t\t\t\t\tif ((found.params[param]?.length ?? 0) > this._maxParamLength) {\n\t\t\t\t\t\tthrow this.createTransportError(\n\t\t\t\t\t\t\tHttpStatusCode.uriTooLong,\n\t\t\t\t\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"paramTooLong\", {\n\t\t\t\t\t\t\t\tparam,\n\t\t\t\t\t\t\t\tmaxParamLength: this._maxParamLength\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait found.handler(req, res, found.params, found.store, found.searchParams);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tawait this.sendError(res, err);\n\t\t}\n\t}\n\n\t/**\n\t * Handle the incoming REST request.\n\t * @param req The incoming request.\n\t * @param res The outgoing response.\n\t * @param bodyLimit The maximum size of the request body in bytes.\n\t * @param pathParams The request path params.\n\t * @param query The request query params.\n\t * @param restRoute The REST route to handle.\n\t * @internal\n\t */\n\tprivate async handleRequestRest(\n\t\treq: IncomingMessage,\n\t\tres: ServerResponse,\n\t\tbodyLimit: number,\n\t\tpathParams: IHttpRequestPathParams,\n\t\tquery: IHttpRequestQuery,\n\t\trestRoute?: IRestRoute\n\t): Promise<void> {\n\t\tconst isSecure = (req.socket as Partial<TLSSocket>).encrypted === true;\n\t\tlet host = req.headers.host ?? \"localhost\";\n\t\t// Like Fastify, the default port for the protocol is omitted from the origin\n\t\tif ((isSecure && host.endsWith(\":443\")) || (!isSecure && host.endsWith(\":80\"))) {\n\t\t\thost = host.slice(0, host.lastIndexOf(\":\"));\n\t\t}\n\t\tconst requestOrigin = `${isSecure ? \"https\" : \"http\"}://${host}`;\n\t\tconst headers = req.headers as IHttpHeaders;\n\n\t\tconst httpServerRequest = this.buildServerRequest(\n\t\t\t(req.method ?? HttpMethod.GET).toUpperCase() as HttpMethod,\n\t\t\t`${requestOrigin}${req.url ?? \"/\"}`,\n\t\t\tawait this.parseBody(req, headers, bodyLimit),\n\t\t\tquery,\n\t\t\tpathParams,\n\t\t\theaders\n\t\t);\n\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds = this.buildContextIds(requestOrigin, httpServerRequest.headers);\n\t\tconst processorState = {};\n\n\t\tawait this.runProcessorsRest(\n\t\t\trestRoute,\n\t\t\thttpServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState\n\t\t);\n\n\t\tawait this.sendResponse(req, res, httpResponse);\n\t}\n\n\t/**\n\t * Handle the incoming socket request.\n\t * @param socketRoute The socket route to handle.\n\t * @param socket The socket to handle.\n\t * @param fullPath The full path of the socket route.\n\t * @param emitTopic The topic to emit the response on.\n\t * @param request The incoming request.\n\t * @internal\n\t */\n\tprivate async handleRequestSocket(\n\t\tsocketRoute: ISocketRoute,\n\t\tsocket: Socket,\n\t\tfullPath: string,\n\t\temitTopic: string,\n\t\trequest: IHttpRequest | undefined\n\t): Promise<void> {\n\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: fullPath,\n\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t// The payload arrives straight off the wire, so it can be missing or any shape\n\t\t\tbody: Is.object(request) ? request.body : undefined,\n\t\t\tsocketId: socket.id\n\t\t};\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds: IContextIds = {};\n\t\tconst processorState = {};\n\n\t\tdelete socketServerRequest.query?.EIO;\n\t\tdelete socketServerRequest.query?.transport;\n\n\t\tawait this.runProcessorsSocket(\n\t\t\tsocketRoute,\n\t\t\tsocketServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState,\n\t\t\temitTopic,\n\t\t\tasync (topic, response) => {\n\t\t\t\tsocket.emit(topic, response);\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Apply the CORS headers to the response, mirroring the Fastify CORS plugin.\n\t * @param req The incoming request.\n\t * @param res The outgoing response.\n\t * @returns True if the request was a preflight request which has been responded to.\n\t * @internal\n\t */\n\tprivate applyCors(req: IncomingMessage, res: ServerResponse): boolean {\n\t\tconst cors = this._cors;\n\t\tif (Is.empty(cors)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tres.setHeader(\"vary\", \"Origin\");\n\n\t\tconst origin = req.headers.origin;\n\t\tconst allowed =\n\t\t\tcors.hasWildcardOrigin || (Is.stringValue(origin) && cors.origins.includes(origin));\n\t\tif (!allowed) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (Is.stringValue(origin)) {\n\t\t\tres.setHeader(\"access-control-allow-origin\", origin);\n\t\t}\n\t\tres.setHeader(\"access-control-allow-credentials\", \"true\");\n\t\tres.setHeader(\"access-control-expose-headers\", cors.exposeHeaders);\n\n\t\tif (req.method === HttpMethod.OPTIONS) {\n\t\t\tif (\n\t\t\t\t!Is.stringValue(origin) ||\n\t\t\t\t!Is.stringValue(req.headers[\"access-control-request-method\"])\n\t\t\t) {\n\t\t\t\tres.writeHead(HttpStatusCode.badRequest, {\n\t\t\t\t\t[HeaderTypes.ContentType]: `${MimeTypes.PlainText}; charset=utf-8`\n\t\t\t\t});\n\t\t\t\tres.end(\"Invalid Preflight Request\");\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tres.writeHead(HttpStatusCode.noContent, {\n\t\t\t\t\"access-control-allow-methods\": cors.allowMethods,\n\t\t\t\t\"access-control-allow-headers\": cors.allowHeaders,\n\t\t\t\t[HeaderTypes.ContentLength]: \"0\"\n\t\t\t});\n\t\t\tres.end();\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Read and parse the request body based on its content type.\n\t * @param req The incoming request.\n\t * @param headers The request headers.\n\t * @param bodyLimit The maximum size of the request body in bytes.\n\t * @returns The parsed body, or undefined if there is no body.\n\t * @throws GeneralError If the body is too large, malformed or an unsupported media type.\n\t * @internal\n\t */\n\tprivate async parseBody(\n\t\treq: IncomingMessage,\n\t\theaders: IHttpHeaders,\n\t\tbodyLimit: number\n\t): Promise<unknown> {\n\t\tif (req.method === HttpMethod.GET || req.method === HttpMethod.HEAD) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst contentType = headers[HeaderTypes.ContentType];\n\t\tconst mediaType = (Is.string(contentType) ? contentType : \"\")\n\t\t\t.split(\";\")[0]\n\t\t\t.trim()\n\t\t\t.toLowerCase();\n\n\t\tconst raw = await this.readBody(req, headers, bodyLimit);\n\t\tif (Is.empty(raw)) {\n\t\t\t// Like Fastify, declaring a JSON body without sending one is an error\n\t\t\tif (mediaType === MimeTypes.Json) {\n\t\t\t\tthrow this.createTransportError(\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"emptyJsonBody\")\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst mimeTypeProcessor = this._mimeTypeProcessorMap[mediaType];\n\t\tif (!Is.empty(mimeTypeProcessor)) {\n\t\t\treturn mimeTypeProcessor.handle(raw);\n\t\t}\n\n\t\tif (mediaType === MimeTypes.Json) {\n\t\t\tconst text = Converter.bytesToUtf8(raw);\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(text);\n\t\t\t} catch (err) {\n\t\t\t\tthrow this.createTransportError(\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"invalidJsonBody\", undefined, err)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (mediaType === MimeTypes.PlainText) {\n\t\t\treturn Converter.bytesToUtf8(raw);\n\t\t}\n\n\t\tthrow this.createTransportError(\n\t\t\tHttpStatusCode.unsupportedMediaType,\n\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"unsupportedMediaType\", {\n\t\t\t\tcontentType: mediaType\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Read the raw request body, enforcing the body limit while streaming.\n\t * @param req The incoming request.\n\t * @param headers The request headers.\n\t * @param bodyLimit The maximum size of the request body in bytes.\n\t * @returns The raw body, or undefined if it is empty.\n\t * @throws GeneralError If the body is larger than the limit.\n\t * @internal\n\t */\n\tprivate async readBody(\n\t\treq: IncomingMessage,\n\t\theaders: IHttpHeaders,\n\t\tbodyLimit: number\n\t): Promise<Buffer | undefined> {\n\t\tconst contentLength = headers[HeaderTypes.ContentLength];\n\t\tif (Is.string(contentLength) && Number.parseInt(contentLength, 10) > bodyLimit) {\n\t\t\tthrow this.createBodyTooLargeError(bodyLimit);\n\t\t}\n\n\t\tconst chunks: Buffer[] = [];\n\t\tlet total = 0;\n\t\tfor await (const chunk of req) {\n\t\t\tconst buffer = chunk as Buffer;\n\t\t\ttotal += buffer.byteLength;\n\t\t\tif (total > bodyLimit) {\n\t\t\t\tthrow this.createBodyTooLargeError(bodyLimit);\n\t\t\t}\n\t\t\tchunks.push(buffer);\n\t\t}\n\n\t\treturn total === 0 ? undefined : Buffer.concat(chunks, total);\n\t}\n\n\t/**\n\t * Create the error for a body which exceeds the limit.\n\t * @param bodyLimit The maximum size of the request body in bytes.\n\t * @returns The error.\n\t * @internal\n\t */\n\tprivate createBodyTooLargeError(bodyLimit: number): GeneralError {\n\t\treturn this.createTransportError(\n\t\t\tHttpStatusCode.payloadTooLarge,\n\t\t\tnew GeneralError(NativeWebServer.CLASS_NAME, \"bodyTooLarge\", { bodyLimit })\n\t\t);\n\t}\n\n\t/**\n\t * Mark an error as raised by the transport, so it is responded to with a specific status code.\n\t * @param statusCode The status code for the response.\n\t * @param error The error.\n\t * @returns The error.\n\t * @internal\n\t */\n\tprivate createTransportError(statusCode: HttpStatusCode, error: GeneralError): GeneralError {\n\t\tNativeWebServer._ERROR_STATUS_CODES.set(error, statusCode);\n\t\treturn error;\n\t}\n\n\t/**\n\t * Send the processed response.\n\t * @param req The incoming request.\n\t * @param res The outgoing response.\n\t * @param httpResponse The processed response.\n\t * @internal\n\t */\n\tprivate async sendResponse(\n\t\treq: IncomingMessage,\n\t\tres: ServerResponse,\n\t\thttpResponse: IHttpResponse\n\t): Promise<void> {\n\t\tthis.validateResponse(httpResponse);\n\n\t\tconst headers: OutgoingHttpHeaders = {};\n\t\tif (!Is.empty(httpResponse.headers)) {\n\t\t\tfor (const header of Object.keys(httpResponse.headers)) {\n\t\t\t\tconst value = httpResponse.headers[header];\n\t\t\t\tif (!Is.empty(value)) {\n\t\t\t\t\theaders[header.toLowerCase()] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst status = httpResponse.statusCode ?? HttpStatusCode.ok;\n\t\tconst payload: unknown = httpResponse.body;\n\n\t\tif (\n\t\t\tIs.empty(payload) ||\n\t\t\tstatus === HttpStatusCode.noContent ||\n\t\t\tstatus === HttpStatusCode.notModified\n\t\t) {\n\t\t\tres.writeHead(status, headers);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\n\t\tconst stream = this.toNodeStream(payload);\n\t\tif (!Is.empty(stream)) {\n\t\t\theaders[HeaderTypes.ContentType] ??= MimeTypes.OctetStream;\n\t\t\tconst encoding = this.selectEncoding(req, headers);\n\t\t\tif (Is.stringValue(encoding)) {\n\t\t\t\tdelete headers[HeaderTypes.ContentLength];\n\t\t\t\theaders[\"content-encoding\"] = encoding;\n\t\t\t\tthis.appendVary(res, headers, \"Accept-Encoding\");\n\t\t\t\tres.writeHead(status, headers);\n\t\t\t\tawait pipeline(stream, NativeWebServer._STREAM_COMPRESSORS[encoding](), res);\n\t\t\t} else {\n\t\t\t\tres.writeHead(status, headers);\n\t\t\t\tawait pipeline(stream, res);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tlet body: Uint8Array;\n\t\tif (Is.uint8Array(payload)) {\n\t\t\tbody = payload;\n\t\t\theaders[HeaderTypes.ContentType] ??= MimeTypes.OctetStream;\n\t\t} else if (Is.string(payload)) {\n\t\t\tbody = Converter.utf8ToBytes(payload);\n\t\t\theaders[HeaderTypes.ContentType] ??= `${MimeTypes.PlainText}; charset=utf-8`;\n\t\t} else {\n\t\t\tbody = Converter.utf8ToBytes(JSON.stringify(payload));\n\t\t\theaders[HeaderTypes.ContentType] ??= `${MimeTypes.Json}; charset=utf-8`;\n\t\t}\n\n\t\tif (body.byteLength >= NativeWebServer._COMPRESS_THRESHOLD) {\n\t\t\tconst encoding = this.selectEncoding(req, headers);\n\t\t\tif (Is.stringValue(encoding)) {\n\t\t\t\tbody = await NativeWebServer._COMPRESSORS[encoding](body);\n\t\t\t\theaders[\"content-encoding\"] = encoding;\n\t\t\t\tthis.appendVary(res, headers, \"Accept-Encoding\");\n\t\t\t}\n\t\t}\n\n\t\theaders[HeaderTypes.ContentLength] = body.byteLength;\n\t\tres.writeHead(status, headers);\n\t\tres.end(body);\n\t}\n\n\t/**\n\t * Convert a streaming response payload to a Node stream.\n\t * @param payload The response payload.\n\t * @returns The stream, or undefined if the payload is not a stream.\n\t * @internal\n\t */\n\tprivate toNodeStream(payload: unknown): Readable | undefined {\n\t\tif (Is.function((payload as Partial<Readable>).pipe)) {\n\t\t\treturn payload as Readable;\n\t\t}\n\t\tif (Is.function((payload as Partial<ReadableStream>).getReader)) {\n\t\t\treturn Readable.fromWeb(payload as NodeReadableStream);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Select the encoding for the response, if it should be compressed.\n\t * @param req The incoming request.\n\t * @param headers The response headers.\n\t * @returns The encoding, or undefined if the response should not be compressed.\n\t * @internal\n\t */\n\tprivate selectEncoding(req: IncomingMessage, headers: OutgoingHttpHeaders): string | undefined {\n\t\tconst acceptEncoding = req.headers[\"accept-encoding\"];\n\t\tconst contentType = headers[HeaderTypes.ContentType];\n\t\tif (\n\t\t\t!Is.stringValue(acceptEncoding) ||\n\t\t\t!Is.empty(headers[\"content-encoding\"]) ||\n\t\t\t!Is.string(contentType) ||\n\t\t\t!NativeWebServer._COMPRESSIBLE_TYPES.test(contentType)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tlet selected: string | undefined;\n\t\tlet selectedQuality = 0;\n\t\tfor (const part of acceptEncoding.toLowerCase().split(\",\")) {\n\t\t\tconst [name, ...params] = part.trim().split(\";\");\n\t\t\tconst qualityParam = params.find(p => p.trim().startsWith(\"q=\"));\n\t\t\tconst quality = Is.stringValue(qualityParam)\n\t\t\t\t? Number.parseFloat(qualityParam.trim().slice(2))\n\t\t\t\t: 1;\n\t\t\tconst encoding = name === \"x-gzip\" ? \"gzip\" : name;\n\t\t\tconst candidates =\n\t\t\t\tencoding === \"*\"\n\t\t\t\t\t? NativeWebServer._ENCODINGS\n\t\t\t\t\t: NativeWebServer._ENCODINGS.filter(e => e === encoding);\n\t\t\tfor (const candidate of candidates) {\n\t\t\t\tconst isBetter =\n\t\t\t\t\tquality > selectedQuality ||\n\t\t\t\t\t(quality === selectedQuality &&\n\t\t\t\t\t\tIs.stringValue(selected) &&\n\t\t\t\t\t\tNativeWebServer._ENCODINGS.indexOf(candidate) <\n\t\t\t\t\t\t\tNativeWebServer._ENCODINGS.indexOf(selected));\n\t\t\t\tif (quality > 0 && isBetter) {\n\t\t\t\t\tselected = candidate;\n\t\t\t\t\tselectedQuality = quality;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn selected;\n\t}\n\n\t/**\n\t * Append a value to the vary header, keeping any value already set on the response.\n\t * @param res The outgoing response.\n\t * @param headers The response headers.\n\t * @param value The value to append.\n\t * @internal\n\t */\n\tprivate appendVary(res: ServerResponse, headers: OutgoingHttpHeaders, value: string): void {\n\t\tconst existing = headers.vary ?? res.getHeader(\"vary\");\n\t\tif (Is.empty(existing)) {\n\t\t\theaders.vary = value;\n\t\t} else {\n\t\t\theaders.vary = `${Is.array(existing) ? existing.join(\", \") : String(existing)}, ${value}`;\n\t\t}\n\t}\n\n\t/**\n\t * Send an error response.\n\t * @param res The outgoing response.\n\t * @param error The error to send.\n\t * @internal\n\t */\n\tprivate async sendError(res: ServerResponse, error: unknown): Promise<void> {\n\t\tlet httpStatusCode = NativeWebServer._ERROR_STATUS_CODES.get(error as object);\n\t\tlet err: IError;\n\t\tif (Is.empty(httpStatusCode)) {\n\t\t\tconst errorAndCode = HttpErrorHelper.processError(error);\n\t\t\terr = errorAndCode.error;\n\t\t\thttpStatusCode = errorAndCode.httpStatusCode;\n\t\t} else {\n\t\t\terr = BaseError.fromError(error).toJsonObject();\n\t\t}\n\n\t\tawait this._logging?.log({\n\t\t\tlevel: \"error\",\n\t\t\tts: Date.now(),\n\t\t\tsource: NativeWebServer.CLASS_NAME,\n\t\t\tmessage: \"badRequest\",\n\t\t\terror: err\n\t\t});\n\n\t\tif (res.headersSent) {\n\t\t\t// The response is already partly sent, so the only option left is to drop it\n\t\t\tres.destroy();\n\t\t\treturn;\n\t\t}\n\n\t\tconst body = Converter.utf8ToBytes(JSON.stringify({ error: err }));\n\t\tconst headers: OutgoingHttpHeaders = {\n\t\t\t[HeaderTypes.ContentType]: `${MimeTypes.Json}; charset=utf-8`,\n\t\t\t[HeaderTypes.ContentLength]: body.byteLength\n\t\t};\n\t\tif (httpStatusCode === HttpStatusCode.payloadTooLarge) {\n\t\t\t// The unread body would otherwise hold the connection open, so close it like Fastify\n\t\t\theaders.connection = \"close\";\n\t\t}\n\t\tres.writeHead(httpStatusCode, headers);\n\t\tres.end(body);\n\t}\n\n\t/**\n\t * Listen on a host and port.\n\t * @param server The server to listen with.\n\t * @param host The host to bind to.\n\t * @param port The port to bind to.\n\t * @returns A promise that resolves when the server is listening.\n\t * @internal\n\t */\n\tprivate async listenOn(\n\t\tserver: HttpServer | HttpsServer | NetServer,\n\t\thost: string,\n\t\tport: number\n\t): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.once(\"error\", reject);\n\t\t\tserver.listen(port, host, () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Close the socket server, which also closes the server it is attached to.\n\t * @param socketServer The socket server to close.\n\t * @param server The server the socket server is attached to.\n\t * @returns A promise that resolves when both servers have closed.\n\t * @internal\n\t */\n\tprivate async closeSocketServer(\n\t\tsocketServer: Server,\n\t\tserver?: HttpServer | HttpsServer\n\t): Promise<void> {\n\t\tconst serverClosed = Is.empty(server) ? undefined : once(server, \"close\");\n\t\tsocketServer.disconnectSockets();\n\t\tawait socketServer.close();\n\t\tawait serverClosed;\n\t}\n\n\t/**\n\t * Close a server.\n\t * @param server The server to close.\n\t * @returns A promise that resolves when the server has closed.\n\t * @internal\n\t */\n\tprivate async closeServer(server: HttpServer | HttpsServer | NetServer): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.close(err => (Is.empty(err) ? resolve() : reject(err)));\n\t\t});\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export * from "./models/INativeWebServerConfig.js";
2
+ export * from "./models/INativeWebServerConstructorOptions.js";
3
+ export * from "./nativeWebServer.js";
@@ -0,0 +1,33 @@
1
+ import type { ServerOptions as HttpServerOptions } from "node:http";
2
+ import type { ServerOptions as HttpsServerOptions } from "node:https";
3
+ import type { ServerOptions as SocketServerOptions } from "socket.io";
4
+ /**
5
+ * The configuration for the native web server.
6
+ */
7
+ export interface INativeWebServerConfig {
8
+ /**
9
+ * The web server options.
10
+ */
11
+ web?: {
12
+ /**
13
+ * The options for the Node.js HTTP server, such as the timeouts.
14
+ */
15
+ serverOptions?: HttpServerOptions;
16
+ /**
17
+ * The TLS options, when provided the server is served over HTTPS.
18
+ */
19
+ https?: HttpsServerOptions;
20
+ /**
21
+ * The maximum length of a path parameter, defaults to 2000.
22
+ */
23
+ maxParamLength?: number;
24
+ };
25
+ /**
26
+ * The socket server options.
27
+ */
28
+ socket?: Partial<SocketServerOptions>;
29
+ /**
30
+ * Include the stack with errors.
31
+ */
32
+ includeErrorStack?: boolean;
33
+ }
@@ -0,0 +1,19 @@
1
+ import type { IMimeTypeProcessor } from "@3sixty/api-models";
2
+ import type { INativeWebServerConfig } from "./INativeWebServerConfig.js";
3
+ /**
4
+ * The options for the native web server constructor.
5
+ */
6
+ export interface INativeWebServerConstructorOptions {
7
+ /**
8
+ * The type of the logging component to use, if undefined, no logging will happen.
9
+ */
10
+ loggingComponentType?: string;
11
+ /**
12
+ * Additional configuration for the server.
13
+ */
14
+ config?: INativeWebServerConfig;
15
+ /**
16
+ * Additional MIME type processors.
17
+ */
18
+ mimeTypeProcessors?: IMimeTypeProcessor[];
19
+ }
@@ -0,0 +1,74 @@
1
+ import { BaseServer } from "@3sixty/api-core-server";
2
+ import { type IRestRoute, type IRestRouteProcessor, type ISocketRoute, type ISocketRouteProcessor, type IWebServerOptions } from "@3sixty/api-models";
3
+ import Router from "find-my-way";
4
+ import type { INativeWebServerConstructorOptions } from "./models/INativeWebServerConstructorOptions.js";
5
+ /**
6
+ * Implementation of the web server using the Node.js HTTP server and the find-my-way router.
7
+ */
8
+ export declare class NativeWebServer extends BaseServer<Router.Instance<Router.HTTPVersion.V1>> {
9
+ /**
10
+ * Runtime name for the class.
11
+ */
12
+ static readonly CLASS_NAME: string;
13
+ /**
14
+ * Create a new instance of NativeWebServer.
15
+ * @param options The options for the server.
16
+ */
17
+ constructor(options?: INativeWebServerConstructorOptions);
18
+ /**
19
+ * Returns the class name of the component.
20
+ * @returns The class name of the component.
21
+ */
22
+ className(): string;
23
+ /**
24
+ * Get the web server instance.
25
+ * @returns The web server instance.
26
+ */
27
+ getInstance(): Router.Instance<Router.HTTPVersion.V1>;
28
+ /**
29
+ * Build the server.
30
+ * @param restRouteProcessors The processors for incoming requests over REST.
31
+ * @param restRoutes The REST routes.
32
+ * @param socketRouteProcessors The processors for incoming requests over Sockets.
33
+ * @param socketRoutes The socket routes.
34
+ * @param options Options for building the server.
35
+ * @returns A promise that resolves when the server is fully built and ready to start.
36
+ */
37
+ build(restRouteProcessors?: IRestRouteProcessor[], restRoutes?: IRestRoute[], socketRouteProcessors?: ISocketRouteProcessor[], socketRoutes?: ISocketRoute[], options?: IWebServerOptions): Promise<void>;
38
+ /**
39
+ * Start listening for connections on the transport.
40
+ * @param host The host to bind to.
41
+ * @param port The port to bind to.
42
+ * @returns A promise that resolves when the transport is listening.
43
+ */
44
+ protected serverListen(host: string, port: number): Promise<void>;
45
+ /**
46
+ * Close the transport and all of its connections.
47
+ * @returns A promise that resolves when the transport has closed.
48
+ */
49
+ protected serverClose(): Promise<void>;
50
+ /**
51
+ * Get the addresses the transport is bound to.
52
+ * @returns The bound addresses.
53
+ */
54
+ protected serverAddresses(): {
55
+ address: string;
56
+ family?: string;
57
+ port: number;
58
+ }[];
59
+ /**
60
+ * Whether the transport is serving over TLS.
61
+ * @returns True if the transport is secure.
62
+ */
63
+ protected serverIsSecure(): boolean;
64
+ /**
65
+ * Whether the transport is currently listening for connections.
66
+ * @returns True if the transport is listening.
67
+ */
68
+ protected serverIsListening(): boolean;
69
+ /**
70
+ * Whether a GET route is registered for the root path.
71
+ * @returns True if the root route is registered.
72
+ */
73
+ protected serverHasRootRoute(): boolean;
74
+ }
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## [0.20.0-next.1](https://github.com/3sixtyglobal/api/compare/api-server-native-v0.20.0-next.0...api-server-native-v0.20.0-next.1) (2026-10-23)
4
+
5
+
6
+ ### Features
7
+
8
+ * authorization ([#51](https://github.com/3sixtyglobal/api/issues/51)) ([023ef94](https://github.com/3sixtyglobal/api/commit/023ef94925114e88522cbe6f703d9b05a202bc6d))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @3sixty/api-core-server bumped from 0.20.0-next.0 to 0.20.0-next.1
16
+ * @3sixty/api-models bumped from 0.20.0-next.0 to 0.20.0-next.1
17
+ * devDependencies
18
+ * @3sixty/api-processors bumped from 0.20.0-next.0 to 0.20.0-next.1
@@ -0,0 +1,70 @@
1
+ # Server Native Examples
2
+
3
+ Use these snippets to build and run the native server with explicit lifecycle control in scripts and integration tests.
4
+
5
+ ## NativeWebServer
6
+
7
+ ```typescript
8
+ import { NativeWebServer } from '@3sixty/api-server-native';
9
+
10
+ const webServer = new NativeWebServer();
11
+
12
+ await webServer.build(undefined, undefined, undefined, undefined, {
13
+ port: 8080,
14
+ host: '0.0.0.0'
15
+ });
16
+
17
+ await webServer.start();
18
+ const router = webServer.getInstance();
19
+
20
+ console.log(router.hasRoute('GET', '/')); // false
21
+
22
+ await webServer.stop();
23
+ ```
24
+
25
+ ```typescript
26
+ import { readFile } from 'node:fs/promises';
27
+ import { RestRouteProcessor, SocketRouteProcessor } from '@3sixty/api-processors';
28
+ import { NativeWebServer } from '@3sixty/api-server-native';
29
+ import { HttpMethod } from '@3sixty/web';
30
+
31
+ const webServer = new NativeWebServer({
32
+ config: {
33
+ web: {
34
+ https: {
35
+ key: await readFile('server.key'),
36
+ cert: await readFile('server.crt')
37
+ }
38
+ },
39
+ socket: { path: '/socket' }
40
+ }
41
+ });
42
+
43
+ await webServer.build(
44
+ [new RestRouteProcessor()],
45
+ [
46
+ {
47
+ operationId: 'info',
48
+ path: '/info',
49
+ method: HttpMethod.GET,
50
+ tag: 'info',
51
+ summary: 'Get the server information',
52
+ handler: async () => ({ body: { name: 'example' } })
53
+ }
54
+ ],
55
+ [new SocketRouteProcessor()],
56
+ [
57
+ {
58
+ operationId: 'echo',
59
+ path: '/events/echo',
60
+ handler: async (socketRequestContext, request, responseEmitter) => {
61
+ await responseEmitter('echo', { body: request.body });
62
+ }
63
+ }
64
+ ],
65
+ { port: 3000, host: 'localhost' }
66
+ );
67
+
68
+ await webServer.start();
69
+ await webServer.stop();
70
+ ```