{"version":3,"file":"hypha-rpc-websocket.mjs","mappings":";;;;;;;;AAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;;AAEA;AACA,yCAAyC;;AAEzC;AACA,6BAA6B;;AAE7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C;AACA,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uDAAuD;AACvD,uDAAuD;AACvD,uDAAuD;AACvD,uDAAuD;AACvD,uDAAuD;AACvD;AACA,uDAAuD;AACvD,uDAAuD;AACvD,uDAAuD;AACvD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAgB,WAAW;AAC3B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA,cAAc,QAAQ;AACtB;;AAEA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA,kBAAkB,QAAQ;AAC1B;;AAEA;AACA,kBAAkB,QAAQ;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD;;AAEA;AACA;AACA,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,4BAA4B;AACnD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD,uBAAuB,2BAA2B;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA,cAAc,QAAQ;AACtB;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA,cAAc,QAAQ;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAsB;AACtB,sBAAsB;;AAEtB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAsB;AACtB,sBAAsB;;AAEtB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAsB;AACtB,sBAAsB;;AAEtB;AACA;;AAEA,uBAAuB;AACvB,uBAAuB;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;;AAEA,0BAA0B;AAC1B,0BAA0B;;AAE1B;AACA;;AAEA,2BAA2B;AAC3B,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;;AAEA,2BAA2B;AAC3B,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;;AAEA,2BAA2B;AAC3B,2BAA2B;;AAE3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAoB;AACpB,oBAAoB;;AAEpB;AACA;;AAEA,qBAAqB;AACrB,qBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,cAAc,OAAO;AACrB;;AAEA;AACA;AACA;AACA;;AAEA,cAAc,OAAO;;AAErB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,cAAc,QAAQ;AACtB;AACA;;AAEA;;AAEA;AACA;AACA,eAAe,SAAS;AACxB;AACA,iCAAiC,OAAO;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,cAAc,OAAO;AACrB,cAAc,QAAQ;;AAEtB;AACA;AACA;AACA;;AAEA,eAAe,QAAQ;AACvB;AACA;;AAEA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,gBAAgB,QAAQ;AACxB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,cAAc,OAAO;AACrB,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;;AAEA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,kBAAkB,sBAAsB;AACxC;AACA;AACA;AACA;;AAEA;AACA,kBAAkB,gBAAgB;AAClC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,cAAc;AAChC;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,uBAAuB;AACrC,cAAc,gBAAgB;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,eAAe;AACjC,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;AACA,kBAAkB,OAAO;AACzB;AACA,KAAK;AACL,IAAI,SAAS,IAA8B;AAC3C;AACA,aAAa,mBAAO,CAAC,qBAAQ;AAC7B;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA,OAAO;AACP;AACA;AACA,CAAC;;AAED,CAAC,EAAE,KAA6B,kEAAkE;;;;;;;;;;;;;;;;;;;ACt1ElG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,8CAA8C;AAC9C,YAAY,mBAAO,CAAC,wDAAW;AAC/B;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,YAAY;AACvB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,YAAY;AACzB;AACO;AACP;AACA,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,aAAa,SAAS,8CAA8C;AACpE;AACA;AACO;AACP;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB,aAAa,SAAS,0CAA0C;AAChE,wBAAwB;AACxB;AACO;AACP;AACA,wDAAwD;AACxD;AACA,WAAW;AACX;;AAEA;AACA;AACA,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB,aAAa,qBAAqB;AAClC,YAAY,OAAO;AACnB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACpGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAE+B;AAC6C;AACzB;AAIzB;;AAE1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,YAAY;AACvD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yDAAyD,iBAAiB;;AAE1E;AACA;AACA;AACA,wBAAwB,iBAAiB,iBAAiB,gBAAgB;AAC1E;AACA,kCAAkC,oCAAoC;AACtE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2CAA2C,UAAU,cAAc,gBAAgB;AACnF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qCAAqC,6BAA6B;AAClE,4BAA4B,mCAAmC;AAC/D;AACA;AACA;AACA;;AAEA;AACA,gDAAgD,gBAAgB;AAChE,uBAAuB,gBAAgB;AACvC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB,iBAAiB,gBAAgB;AACrE;AACA,6BAA6B,oCAAoC;AACjE;AACA,mBAAmB,wDAAa,GAAG,uBAAuB;AAC1D;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,QAAQ;AACR,sDAAsD,gBAAgB;AACtE;AACA,MAAM;AACN,4DAA4D,UAAU;AACtE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA4B,iBAAiB,iBAAiB,gBAAgB;AAC9E;AACA,sCAAsC,oCAAoC;AAC1E;AACA;AACA,+CAA+C,6CAA6C;AAC5F;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,yCAAyC,gBAAgB,IAAI,WAAW;AACxE;AACA;;AAEA,mBAAmB;;AAEnB;AACA;AACA,QAAQ;AACR;AACA,2CAA2C,cAAc;;AAEzD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,iBAAiB,aAAa,MAAM;AACtF;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,YAAY;AACzB,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA,sBAAsB,wDAAa;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,QAAQ;AACR;AACA,2CAA2C,cAAc;AACzD;AACA;AACA,UAAU;AACV;AACA;;AAEA,cAAc,cAAc;;AAE5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D,YAAY;AAC3E,eAAe;AACf;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA,YAAY;AACZ,2CAA2C,mBAAmB;AAC9D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ,uDAAuD,cAAc;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,gBAAgB;AAC1D,uBAAuB,gBAAgB;AACvC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sBAAsB,iBAAiB,iBAAiB,gBAAgB,aAAa,oCAAoC;;AAEzH;AACA;;AAEA;AACA;AACA;AACA,0BAA0B,sBAAsB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,iBAAiB;AACjD,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,YAAY,GAAG,WAAW,KAAK,WAAW;AAChF;AACA;AACA;AACA;AACA;AACA,uCAAuC,gBAAgB,IAAI,WAAW;AACtE;AACA;;AAEA;AACA,QAAQ;AACR;AACA;AACA,+CAA+C,YAAY,GAAG,WAAW,KAAK,cAAc;AAC5F;AACA;AACA,UAAU;AACV,mDAAmD,cAAc;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACO;AACP;AACA;AACA,eAAe,uDAAM;AACrB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAE,uDAAM;;AAER;;AAEA;;AAEA,kBAAkB,wCAAG;AACrB;AACA;AACA,uBAAuB,mCAAmC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,kBAAkB,gEAAc;AAChC;AACA;AACA,kBAAkB,cAAc,kBAAkB;AAClD,GAAG;;AAEH,uBAAuB,gEAAc;AACrC;AACA;AACA;AACA;AACA,mBAAmB,oDAAoD;AACvE,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA8B,GAAG;AACjC;;AAEA,aAAa,gEAAc;AAC3B;AACA;AACA,kBAAkB,gCAAgC;AAClD,GAAG;;AAEH;AACA,6CAA6C;AAC7C;;AAEA;AACA;AACA;AACA;AACA,mDAAmD,eAAe;AAClE;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,iBAAiB;AAC9B;AACO,8CAA8C;AACrD;AACA;;AAEA;AACA;AACA;AACO,2DAA2D;AAClE,UAAU,mDAAmD;AAC7D,IAAI,gEAAe;AACnB,2BAA2B,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM;;AAEvE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AC12BA;AACA;AACA;AACA;AAe0B;AACyB;;AAEqB;AAOnD;;AAErB;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,YAAY;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEuD;;AAEhD;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAmB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD,KAAK;;AAEL;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI;AACJ,aAAa;AACb,IAAI;AACJ,aAAa;AACb,IAAI;AACJ,aAAa;AACb,IAAI;AACJ,aAAa;AACb,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wCAAwC,IAAI,wBAAwB,KAAK;AACzE;AACA;;AAEA;AACA;AACA;AACA,2CAA2C,IAAI,wBAAwB,KAAK;AAC5E;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,KAAK,GAAG,EAAE;AACnC;AACA;AACA,UAAU;AACV;AACA,4BAA4B,gEAAc;AAC1C;AACA;AACA;AACA,aAAa;AACb,YAAY;AACZ;AACA,8CAA8C,EAAE,aAAa,QAAQ;AACrE;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,oDAAoD,KAAK;AACzD;AACA;AACA,yBAAyB,KAAK,GAAG,EAAE;AACnC;AACA;AACA,UAAU;AACV;AACA,4BAA4B,gEAAc;AAC1C;AACA;AACA;AACA,aAAa;AACb,YAAY;AACZ;AACA,sDAAsD,GAAG,WAAW,QAAQ;AAC5E;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C;AAC1C;;AAEA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,wCAAwC,YAAY;AACpD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACO,kBAAkB,2DAAc;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,IAAI,uDAAM;AACV,IAAI,uDAAM;AACV;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,uBAAuB;AAC3D;AACA;AACA;AACA,uBAAuB;AACvB,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,iCAAiC,qEAAyB;AAC1D;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,oCAAoC;AACpC,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAuC,sBAAsB,GAAG,gBAAgB;AAChF;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA,MAAM,uDAAM;AACZ,MAAM,uDAAM;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,IAAI;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sBAAsB;AACzD;AACA;AACA;AACA,4BAA4B,SAAS,+BAA+B,sBAAsB;AAC1F;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,8CAA8C,SAAS;;AAEvD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,wBAAwB;AACzE;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,wBAAwB;AAC3E;AACA,kBAAkB;AAClB;AACA,kDAAkD,wBAAwB,IAAI,aAAa;AAC3F;AACA;AACA;AACA;;AAEA;AACA;AACA,+CAA+C,iBAAiB;AAChE;AACA,cAAc;AACd;AACA,mCAAmC,iBAAiB,SAAS,eAAe,6CAA6C,0BAA0B;AACnJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,qFAAqF,EAAE;AACvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,UAAU,GAAG,SAAS;AAClE;AACA,mCAAmC,cAAc;AACjD;AACA;AACA,oBAAoB;AACpB;AACA,mCAAmC,UAAU;AAC7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,yEAAyE,eAAe;AACxF;AACA;AACA;AACA,YAAY;AACZ;AACA,yEAAyE,aAAa;AACtF;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,OAAO;AACzC;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA,gCAAgC,2BAA2B;AAC3D;AACA,SAAS;AACT;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0DAAc;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI,uDAAM;AACV;;AAEA;AACA;AACA;AACA,2DAA2D,IAAI;AAC/D;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAsC,IAAI;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,2DAA2D,IAAI;AAC/D;AACA;AACA;AACA;AACA;AACA,0CAA0C,KAAK;AAC/C;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA;AACA;AACA,2DAA2D,IAAI;AAC/D;AACA;AACA;AACA;AACA;AACA,0CAA0C,KAAK;AAC/C;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA;AACA;AACA,0CAA0C,KAAK;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA,2DAA2D,IAAI;AAC/D;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA,0CAA0C,KAAK;AAC/C;AACA;AACA,2CAA2C,KAAK,SAAS,sBAAsB;AAC/E,mBAAmB,6DAAW;AAC9B,YAAY,cAAc;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,KAAK,SAAS,sBAAsB;AAClE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA,MAAM;AACN;AACA,qBAAqB,6DAAW;AAChC,cAAc,cAAc;AAC5B;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,uCAAuC;AACvC;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,qEAAqE,EAAE;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,iEAAiE,EAAE;AACnE;AACA;AACA;AACA;AACA,MAAM;AACN,8DAA8D,EAAE;AAChE;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,2DAA2D,EAAE;AAC7D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA,mDAAmD,SAAS,IAAI,EAAE;AAClE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,QAAQ;AACnD,wCAAwC,QAAQ,WAAW,UAAU;;AAErE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,qDAAqD,EAAE;AACvD;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,2CAA2C,SAAS;AACpD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8CAA8C,WAAW;AACzD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,eAAe,8BAA8B,OAAO;AAC1E;AACA;AACA,MAAM;AACN,2DAA2D,EAAE;AAC7D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN,gEAAgE,EAAE;AAClE;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR,uEAAuE,EAAE;AACzE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B,sBAAsB;AAChD;;AAEA;AACA;AACA;AACA,+CAA+C,WAAW,cAAc,YAAY,GAAG,WAAW;AAClG;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oDAAoD,YAAY,GAAG,WAAW,KAAK,UAAU;AAC7F;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV,IAAI,uDAAM;;AAEV;AACA,IAAI,uDAAM;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0DAA0D,WAAW,wBAAwB,IAAI,KAAK,cAAc;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,uDAAM;AACd;AACA,6BAA6B,QAAQ,KAAK,aAAa;AACvD;AACA;AACA,IAAI,uDAAM,mCAAmC,YAAY;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,sBAAsB,wDAAO;AAC7B;AACA;AACA;AACA;AACA,kBAAkB,SAAS,GAAG,WAAW;AACzC;AACA,4BAA4B,4DAAgB;AAC5C;AACA;AACA;AACA,cAAc,6DAAY;AAC1B;AACA;AACA,cAAc,4DAAW;AACzB;AACA;AACA;AACA,2EAA2E;AAC3E;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,wCAAwC,WAAW,GAAG,WAAW;AACjE;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,YAAY;AACZ;AACA,yCAAyC,4BAA4B,uBAAuB,iBAAiB,KAAK,UAAU;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA,+BAA+B,IAAI;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uDAAM;;AAEV;AACA;AACA;AACA;AACA;AACA,mGAAmG,WAAW;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF,aAAa;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,OAAO;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA,qCAAqC,OAAO,uCAAuC,OAAO;AAC1F;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iBAAiB,GAAG,gBAAgB,GAAG,cAAc;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,UAAU,gCAAgC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,QAAQ;AACR,sDAAsD,SAAS,WAAW,EAAE;AAC5E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,QAAQ;AACR,+DAA+D,EAAE;AACjE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI,uDAAM;AACV;AACA,6BAA6B,WAAW;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,WAAW;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,kEAAiB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW,GAAG,KAAK;AAC1C;AACA;AACA;AACA,aAAa,gBAAgB,GAAG,gBAAgB;AAChD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,+BAA+B,UAAU,IAAI,YAAY,KAAK,MAAM;AACpE;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,4CAA4C,UAAU;AACtD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC,YAAY;AAChD;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,YAAY;AAChD;AACA;AACA,UAAU;AACV;AACA,4DAA4D,WAAW;AACvE;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,YAAY,2BAA2B,cAAc;AACvF;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN,4DAA4D,WAAW;AACvE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAoC,YAAY;AAChD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,gDAAgD,WAAW;AAC3D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,qDAAqD,WAAW;AAChE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,sBAAsB,uBAAuB;AAC7C;AACA;AACA;AACA,+BAA+B,YAAY,qBAAqB,MAAM;AACtE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,WAAW;;AAE1D;AACA;AACA;AACA,MAAM;AACN;AACA,iDAAiD,WAAW;AAC5D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,YAAY;AAC3D;;AAEA;AACA,wBAAwB,WAAW;AACnC;AACA,sCAAsC;AACtC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,MAAM,IAAI,0CAA0C;AAC1G;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,0CAA0C,eAAe;AACzD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,WAAW;AACrD;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,YAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,YAAY;AAC7B;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS,UAAU;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAqC,uDAAM;AAC3C;AACA,mCAAmC;AACnC;AACA;AACA;AACA,4BAA4B,sDAAS;;AAErC;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,QAAQ,GAAG,WAAW,SAAS,YAAY;AAC3E;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,UAAU;AACV;AACA,6DAA6D,aAAa;AAC1E;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,QAAQ,GAAG,WAAW,SAAS,YAAY;AACzE;AACA;AACA;AACA;AACA;AACA,oCAAoC,YAAY,iBAAiB,aAAa;AAC9E;;AAEA;AACA,IAAI,uDAAM;AACV;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B,wDAAa;AACvC;AACA,oBAAoB,wDAAa;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,WAAW;AAClE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,UAAU,UAAU,qBAAqB;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,uDAAM;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,kBAAkB,YAAY,YAAY;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAwC,UAAU,GAAG,UAAU,aAAa,iBAAiB;AAC7F;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,UAAU,GAAG,UAAU;;AAExD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,kBAAkB;AAC7D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY,aAAa,YAAY;AAC/E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd,2DAA2D,aAAa;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,wDAAa;AAC3C,oBAAoB,oBAAoB,QAAQ,0DAAc;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;AAEA;AACA,gCAAgC,wDAAa;AAC7C;AACA,0BAA0B,wDAAa;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,qFAAqF,UAAU,GAAG,UAAU,YAAY,IAAI;AAC5H;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,qFAAqF,UAAU,GAAG,UAAU,YAAY,IAAI;AAC5H;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,UAAU;AACV;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gDAAgD,UAAU;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM,uDAAM;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,UAAU,uDAAM;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,0DAAc;AAC5C;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA,6BAA6B,6DAAW;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0DAAc;AACrD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,iCAAiC,gBAAgB,sDAAsD,YAAY;AACnH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,YAAY,oBAAoB,gBAAgB,sCAAsC,YAAY;AAC9H;AACA;AACA;AACA,+DAA+D,YAAY;AAC3E;AACA;AACA,YAAY;AACZ;AACA,4BAA4B,YAAY,uBAAuB,eAAe,uBAAuB,YAAY;AACjH;AACA;AACA;AACA,qDAAqD,YAAY;AACjE;AACA;AACA;AACA;;AAEA;AACA,sCAAsC,aAAa,KAAK,gBAAgB;AACxE;AACA;AACA,+BAA+B,aAAa,KAAK,gBAAgB;AACjE;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAM,uDAAM;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,aAAa;AAC7D;AACA;AACA,4BAA4B,0DAAc;AAC1C;AACA;AACA,yEAAyE,YAAY;AACrF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAQ,uDAAM;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,uBAAuB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,YAAY,aAAa,eAAe,UAAU,YAAY;AACpI;AACA;AACA,4CAA4C,aAAa,GAAG,YAAY;AACxE;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb,UAAU;AACV;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,iEAAiE,QAAQ,oBAAoB,sBAAsB;AACnH;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM,4DAAW;AACjB,MAAM,iEAAgB;AACtB,MAAM,gEAAe;AACrB,MAAM,+DAAc;AACpB;AACA;AACA,MAAM,uDAAM;AACZ;AACA;AACA;AACA,wBAAwB,uDAAM;AAC9B;;AAEA;AACA;AACA,MAAM,uDAAM;AACZ;AACA,0CAA0C,YAAY;AACtD;;AAEA;AACA,sBAAsB,iEAAgB,aAAa,gEAAe;;AAElE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW,GAAG,UAAU;AAC7C,2BAA2B,WAAW,GAAG,SAAS;AAClD;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ,uDAAM;AACd;AACA;AACA,yBAAyB,uDAAM,GAAG,GAAG,iBAAiB;AACtD,UAAU;AACV,sBAAsB,uDAAM;AAC5B;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW,GAAG,UAAU;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,uDAAM;AACd;AACA,4CAA4C,YAAY;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kEAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,oBAAoB,kEAAiB;AACrC;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,uDAAM,GAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,iDAAiD,QAAQ;AACzD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,4BAA4B,8DAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,QAAQ;AACR,0BAA0B,8DAAiB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,WAAW;AACX,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,+CAA+C,OAAO;AACtD;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,6CAA6C,OAAO;AACpD;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,4CAA4C,OAAO;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtuHO;AACP;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;;AAEO;AACP;AACA,gBAAgB;AAChB;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,yCAAyC,IAAI;AAC7C;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB,sCAAsC;AACtC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA,QAAQ;AACR,2CAA2C;AAC3C;AACA;AACA;;AAEA;AACA;;AAEO;AACP;AACA,gBAAgB;AAChB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,WAAW;AACX;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAyB;AAC/C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEO;AACP;AACA;AACA,wDAAwD,aAAa;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI;AACP;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,GAAG;AACH;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEO;AACP;AACA;AACA;AACA;;AAEA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,SAAS;AACtB;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa,SAAS;AACtB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa,SAAS;AACtB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa,SAAS;AACtB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AC1jBoC;;AAEpC;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH,mBAAmB,kCAAkC;AACrD,mBAAmB,kCAAkC;AACrD,oBAAoB,mCAAmC;AACvD,oBAAoB,mCAAmC;AACvD,uBAAuB,wCAAwC;;AAE/D;AACA,2BAA2B,4BAA4B;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,wBAAwB;AAClE;AACA;AACA,CAAC;;AAEM;AACP;AACA,IAAI,0EAA0E;AAC9E;AACA;AACA;AACA;AACA,EAAE,iDAAM;;AAER;AACA;AACA,EAAE,iDAAM;;AAER;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAE,iDAAM;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACjF+B;AACmB;AACC;;AAEnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,6BAA6B;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA,IAAI,uDAAM;AACV;AACA;AACA,MAAM;AACN,mDAAmD,IAAI;AACvD;AACA;AACA;;AAEA;AACA;AACA,0DAA0D,OAAO;AACjE;AACA;;AAEA;AACA,EAAE,uDAAM;AACR,EAAE,uDAAM;AACR;AACA,uCAAuC,uDAAM;AAC7C;AACA;AACA;AACA;AACA,kBAAkB,wCAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,QAAQ,wCAAwC;AAChD;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,qCAAqC,uDAAM;;AAE3C;AACA;AACA,QAAQ,wCAAwC;AAChD;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,UAAU;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA,2DAA2D,eAAe;AAC1E;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uDAAM;AACtB;AACA;AACA;AACA,gBAAgB,uDAAM;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gEAAc;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB,mBAAmB;AACnB;AACA,iBAAiB;AACjB,eAAe;AACf,8BAA8B,gEAAc;AAC5C;AACA;AACA,8BAA8B,gCAAgC;AAC9D,eAAe;AACf,iCAAiC,gEAAc;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD,gCAAgC;AAChC,mCAAmC,kBAAkB;AACrD,mCAAmC,kBAAkB;AACrD,uBAAuB;AACvB,qBAAqB;AACrB,mBAAmB;AACnB,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kDAAkD,MAAM;AACxD;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAE6C;;;;;;;;;;;AC/W7C;;;;;;;;;;;;;;;ACAgD;AAChD;AACA;AACA;AACA;AACA,uCAAuC;AACvC,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAuB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,uBAAuB;AACjF;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,6DAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAC2B;AAC5B;;;;;;;;;;;;;;AC/DA,iBAAiB,SAAI,IAAI,SAAI;AAC7B;AACA;AACA,eAAe,gBAAgB,sCAAsC,kBAAkB;AACvF,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;AACsB;AACvB;;;;;;;;;;;;;;;;;;;;;;AChCA,iBAAiB,SAAI,IAAI,SAAI;AAC7B,4BAA4B,+DAA+D,iBAAiB;AAC5G;AACA,oCAAoC,MAAM,+BAA+B,YAAY;AACrF,mCAAmC,MAAM,mCAAmC,YAAY;AACxF,gCAAgC;AAChC;AACA,KAAK;AACL;AACA,mBAAmB,SAAI,IAAI,SAAI;AAC/B,cAAc,6BAA6B,0BAA0B,cAAc,qBAAqB;AACxG,iBAAiB,oDAAoD,qEAAqE,cAAc;AACxJ,uBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC,mCAAmC,SAAS;AAC5C,mCAAmC,WAAW,UAAU;AACxD,0CAA0C,cAAc;AACxD;AACA,8GAA8G,OAAO;AACrH,iFAAiF,iBAAiB;AAClG,yDAAyD,gBAAgB,QAAQ;AACjF,+CAA+C,gBAAgB,gBAAgB;AAC/E;AACA,kCAAkC;AAClC;AACA;AACA,UAAU,YAAY,aAAa,SAAS,UAAU;AACtD,oCAAoC,SAAS;AAC7C;AACA;AACA,qBAAqB,SAAI,IAAI,SAAI;AACjC;AACA;AACA,2GAA2G,uFAAuF,cAAc;AAChN,uBAAuB,8BAA8B,gDAAgD,wDAAwD;AAC7J,6CAA6C,sCAAsC,UAAU,mBAAmB,IAAI;AACpH;AACA,eAAe,SAAI,IAAI,SAAI,4BAA4B;AACvD,wBAAwB,SAAI,IAAI,SAAI;AACpC;AACA;AACA,iBAAiB,uFAAuF,cAAc;AACtH,uBAAuB,gCAAgC,qCAAqC,2CAA2C;AACvI,4BAA4B,MAAM,iBAAiB,YAAY;AAC/D,uBAAuB;AACvB,8BAA8B;AAC9B,6BAA6B;AAC7B,4BAA4B;AAC5B;AACoD;AACE;AACY;AACoB;AACX;AACjB;AACV;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,iCAAiC,mEAAgB;AACjD;AACA;AACA,yCAAyC,iBAAiB,+DAAc;AACxE,kCAAkC;AAClC,uCAAuC,eAAe,sDAAU;AAChE,uCAAuC,eAAe,sDAAU;AAChE,yCAAyC,iBAAiB,sDAAU;AACpE,uCAAuC,eAAe,sDAAU;AAChE,uCAAuC,eAAe,sDAAU;AAChE,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,wEAAgB;AACrC,oBAAoB,sEAAc;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,wEAAgB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,iEAAU;AAC9F;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,KAAK,EAAE,EAAwB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,yDAAW,mCAAmC,iEAAU;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,yDAAW;AAC7C;AACA;AACA,kCAAkC,yDAAW;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,yDAAW,yCAAyC,iEAAU;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,SAAS;AACT;AACA;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mEAAsB;AACpD,qBAAqB,6DAAY;AACjC;AACA;AACA,qBAAqB,6DAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAS;AAC7B;AACA;AACA;AACA;AACA,oBAAoB,wDAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACkB;AACnB;;;;;;;;;;;;;;;;;;;;AC7tBiG;AAC3C;AACA;AACK;AACpD;AACA;AACP;AACA;AACA,yCAAyC,iBAAiB,+DAAc;AACxE,kCAAkC;AAClC,mCAAmC;AACnC,4CAA4C;AAC5C,mCAAmC;AACnC,uCAAuC;AACvC,0CAA0C;AAC1C,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,qBAAqB,0FAA0F,qBAAqB;AACzK;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mEAAsB;AAC9C,6BAA6B,0DAAS;AACtC;AACA;AACA,YAAY,6DAAY;AACxB;AACA;AACA;AACA,6BAA6B,0DAAS;AACtC;AACA;AACA,YAAY,6DAAY;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wEAAgB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,sBAAsB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,oBAAoB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,oBAAoB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yDAAS;AACjB;AACA;AACA;AACA;AACA,QAAQ,wDAAQ;AAChB;AACA;AACA;AACA,CAAC;AACkB;AACnB;;;;;;;;;;;;;;AChaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACkB;AACnB;;;;;;;;;;;;;;;;ACXA;AACwC;AACa;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,8DAAkB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA;AACA;AACA;AACA;AACA,+BAA+B,iDAAO;AACtC;AACA;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA,+BAA+B,iDAAO;AACtC;AACA;AACA;AACA,8BAA8B,iDAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,iDAAO;AAC9B;AACA;AACA;AACA;AACA,CAAC;AACyB;AAC1B;;;;;;;;;;;;;;;;;ACtEwC;AACjC;AACP;AACA;AACA;AACA;AACA,kDAAkD,oBAAoB,GAAG,qBAAqB,MAAM,0BAA0B;AAC9H;AACA,YAAY,kBAAkB;AAC9B,YAAY,mBAAmB;AAC/B;AACO;AACP,8BAA8B;AAC9B,sBAAsB,iDAAO;AAC7B;AACA;AACA;AACA;AACA,6BAA6B,0BAA0B;AACvD;AACA,YAAY,kBAAkB;AAC9B,YAAY,mBAAmB;AAC/B;AACO;AACP,8BAA8B;AAC9B,sBAAsB,iDAAO;AAC7B;AACA;AACA;;;;;;;;;;;;;;;AC5BwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,8BAA8B;AAC9B,sBAAsB,iDAAO;AAC7B;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACbA;AACgD;AACK;AAC9C;AACP,2CAA2C;AAC3C,2CAA2C;AACpC;AACP;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA,QAAQ,wDAAQ;AAChB;AACA;AACA;AACO;AACP;AACA;AACA;AACA,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA,qBAAqB;AACrB;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,gCAAgC;AAChC,sBAAsB,wDAAQ;AAC9B;AACA,qBAAqB;AACrB;AACA;AACA,sBAAsB,yDAAW;AACjC;AACA;AACO;AACP;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AChGA;AACO;AACP;AACA;AACO;AACP;AACA,qBAAqB;AACrB;AACA;AACA;AACO;AACP;AACA,qBAAqB;AACrB;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC1BO;AACP;AACA;AACA;;;;;;;;;;;;;;;ACHO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACtBA;AACA;AACuC;AACvC;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,MAAM,gDAAU;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,MAAM,gDAAU;AAChB;AACA;AACA;AACO;AACP;AACA;AACA;AACA;;;;;;SC/JA;SACA;;SAEA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;;SAEA;SACA;;SAEA;SACA;SACA;;;;;UCtBA;UACA;UACA;UACA;UACA,yCAAyC,wCAAwC;UACjF;UACA;UACA;;;;;UCPA;;;;;UCAA;UACA;UACA;UACA,uDAAuD,iBAAiB;UACxE;UACA,gDAAgD,aAAa;UAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACN0E;AAC3B;AAOrB;AACyB;AACoB;;AAEvE;AAM0B;;AAE1B;AAME;;AAE0C;AAChB;AACiB;AAOxB;;AAErB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA;AACA;AACA,uBAAuB;AACvB,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,sCAAsC;AACtC;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA,gCAAgC;AAChC,yCAAyC;AACzC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI,uDAAM;AACV;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,wDAAwD,MAAM;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA,yCAAyC,oCAAoC;AAC7E;AACA,yCAAyC,oCAAoC;AAC7E;AACA,qCAAqC,gCAAgC;AACrE;AACA;AACA,8BAA8B,6CAA6C;AAC3E;;AAEA;AACA;AACA,wCAAwC,2BAA2B;;AAEnE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iFAAiF,WAAW,WAAW,0BAA0B;AACjI;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uDAAM;AAClB;AACA,mDAAmD,+BAA+B,cAAc,gBAAgB;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,6BAA6B,oDAAoD,kDAAkD;AAC1L;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,+BAA+B,gBAAgB,gBAAgB;AAC/H;AACA;AACA,gCAAgC,kCAAkC;AAClE;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,YAAY,wDAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA,uCAAuC,gBAAgB;AACvD,uDAAuD,eAAe;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4CAA4C,cAAc;AAC1D;AACA;;AAEA;AACA;AACA,8CAA8C,uBAAuB;AACrE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uEAAuE,WAAW,KAAK,cAAc;AACrG;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAAgC;AAChC,gCAAgC;AAChC,+BAA+B;;AAE/B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC,gCAAgC,YAAY,MAAM;AACnF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oDAAoD,kBAAkB;AACtE;AACA;AACA,YAAY;AACZ,mBAAmB,EAAE;AACrB;AACA;AACA;AACA,uEAAuE,EAAE;AACzE;AACA,cAAc,YAAY,EAAE;AAC5B;AACA,mBAAmB,EAAE;AACrB;AACA;AACA;AACA,0DAA0D,EAAE;AAC5D;AACA;;AAEA;AACA;AACA,8BAA8B,EAAE;AAChC;AACA,uEAAuE,OAAO;AAC9E,cAAc;AACd;AACA;AACA;AACA,2DAA2D,OAAO;AAClE;AACA,cAAc;AACd;AACA,yDAAyD,OAAO;AAChE;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,wCAAwC,+BAA+B;;AAEvE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,+CAA+C,WAAW;AAC1D;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,wDAAwD,IAAI;AAC5D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,OAAO;AACnE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,6CAA6C,QAAQ,WAAW,YAAY,cAAc;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,IAAI,uDAAM,0CAA0C,WAAW;AAC/D;AACA;AACA,kCAAkC,uCAAuC;AACzE,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN,2DAA2D,kBAAkB;AAC7E;AACA,0CAA0C,kCAAkC;AAC5E,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,6CAA6C,QAAQ,WAAW,YAAY,cAAc;AAC1F;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,IAAI,uDAAM,0CAA0C,WAAW;;AAE/D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uCAAuC;AACvC;AACA;AACA,MAAM;AACN;AACA,iDAAiD,mBAAmB;AACpE;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA,sCAAsC,QAAQ,WAAW,YAAY,WAAW,eAAe;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,uDAAM;AACR;AACA;AACA;;AAEA;AACA;AACA,IAAI,qEAA4B,MAAM,4DAAgB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA,wDAAwD;AACxD,8DAA8D;AAC9D,sCAAsC,gBAAgB,GAAG,eAAe;AACxE,2BAA2B,gEAAa;AACxC;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP,6CAA6C,QAAQ,WAAW,YAAY,WAAW,eAAe;AACtG;AACA;AACA;AACA,iBAAiB,oEAAmB;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,uDAAM;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,uDAAM;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA8B;AAC9B,+BAA+B;AAC/B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN,oDAAoD,sBAAsB;AAC1E;AACA;AACA;AACA;AACA,2CAA2C,0BAA0B,cAAc,iBAAiB;AACpG;AACA;;AAEA;AACA,kBAAkB,wCAAG;AACrB;AACA;AACA,uBAAuB,8BAA8B;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,sCAAsC,iBAAiB;AACvD;;AAEA;AACA;AACA,IAAI,uDAAM;AACV;AACA;AACA;AACA,IAAI,uDAAM;AACV;AACA;AACA;AACA,kCAAkC,SAAS;AAC3C;;AAEA;AACA;AACA,IAAI,uDAAM;AACV,IAAI,uDAAM;AACV,oBAAoB;AACpB;AACA;;AAEA;AACA;AACA;AACA,cAAc,gEAAc;AAC5B;AACA;AACA;AACA,oBAAoB,OAAO,oDAAoD;AAC/E;AACA;AACA,KAAK;AACL,GAAG;AACH,cAAc,gEAAc;AAC5B;AACA;AACA;AACA;AACA,oBAAoB,2DAA2D;AAC/E,OAAO;AACP;AACA,KAAK;AACL,GAAG;AACH,gBAAgB,gEAAc;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA,KAAK;AACL,GAAG;AACH,kBAAkB,gEAAc;AAChC;AACA;AACA,kBAAkB,8BAA8B,gBAAgB;AAChE,GAAG;AACH,qBAAqB,gEAAc;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,gBAAgB;AACpC,oBAAoB;AACpB,uBAAuB,kBAAkB;AACzC,uBAAuB,kBAAkB;AACzC,WAAW;AACX,SAAS;AACT,OAAO;AACP,KAAK;AACL,GAAG;;AAEH,YAAY,gEAAc;AAC1B;AACA;AACA;AACA,oBAAoB,QAAQ,mDAAmD;AAC/E;AACA;AACA,KAAK;AACL,GAAG;;AAEH,UAAU,gEAAc;AACxB;AACA;AACA;AACA;AACA,iBAAiB,uDAAuD;AACxE,mBAAmB,uDAAuD;AAC1E,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;;AAEH,WAAW,gEAAc;AACzB;AACA;AACA;AACA;AACA,iBAAiB,oDAAoD;AACrE,mBAAmB,uDAAuD;AAC1E,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;;AAEH,YAAY,gEAAc;AAC1B;AACA;AACA;AACA;AACA,iBAAiB,uDAAuD;AACxE,mBAAmB,uDAAuD;AAC1E,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;;AAEH,wBAAwB,gEAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;;AAEH,uBAAuB,gEAAc;AACrC;AACA;AACA;AACA;AACA,mBAAmB,wDAAwD;AAC3E;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;AACH,yBAAyB,gEAAc;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,UAAU,qEAAkB,QAAQ,SAAS;AAC7C;AACA,gCAAgC;AAChC;AACA;AACA;AACA,oBAAoB,gEAAc,wBAAwB,0DAA0D;AACpH;AACA;AACA;AACA,KAAK;;AAEL,uBAAuB,gEAAc,CAAC,4DAAa;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA,OAAO;AACP,KAAK;AACL,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,qEAA4B,MAAM,4DAAgB;AAC1D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,kDAAkD,WAAW,GAAG,UAAU;AAC1E,8CAA8C,iBAAiB;AAC/D;;AAEA,sBAAsB,gEAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,aAAa,wEAAwE;AAChI;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;;AAEO,uDAAuD;AAC9D,UAAU,mDAAmD;AAC7D,IAAI,gEAAe;AACnB,2BAA2B,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,YAAY;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,uBAAuB;AACjE;AACA;AACkC;;AAE3B;AACP,KAAK;AACL,aAAa;AACb,gBAAgB;AAChB,kBAAkB;AAClB;AACA;AACA;AACA,qBAAqB;AACrB;AACA,sBAAsB;AACtB,eAAe;AACf,oBAAoB;AACpB,2BAA2B,0BAA0B;AACrD,yBAAyB,wBAAwB;AACjD,4BAA4B;AAC5B,wBAAwB;AACxB;;AAEO;AACP;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;;AAEV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA;AACA,kCAAkC,0BAA0B;AAC5D,MAAM;AACN,yBAAyB,0BAA0B;AACnD;AACA,GAAG;AACH","sources":["webpack://hypha-rpc/./node_modules/tweetnacl/nacl-fast.js","webpack://hypha-rpc/./src/crypto.js","webpack://hypha-rpc/./src/http-client.js","webpack://hypha-rpc/./src/rpc.js","webpack://hypha-rpc/./src/utils/index.js","webpack://hypha-rpc/./src/utils/schema.js","webpack://hypha-rpc/./src/webrtc-client.js","webpack://hypha-rpc/ignored|/home/runner/work/hypha-rpc/hypha-rpc/javascript/node_modules/tweetnacl|crypto","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/CachedKeyDecoder.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/DecodeError.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/Decoder.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/Encoder.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/ExtData.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/ExtensionCodec.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/decode.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/encode.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/timestamp.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/utils/int.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/utils/prettyByte.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/utils/typedArrays.mjs","webpack://hypha-rpc/./node_modules/@msgpack/msgpack/dist.es5+esm/utils/utf8.mjs","webpack://hypha-rpc/webpack/bootstrap","webpack://hypha-rpc/webpack/runtime/define property getters","webpack://hypha-rpc/webpack/runtime/hasOwnProperty shorthand","webpack://hypha-rpc/webpack/runtime/make namespace object","webpack://hypha-rpc/./src/websocket-client.js"],"sourcesContent":["(function(nacl) {\n'use strict';\n\n// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\n// Public domain.\n//\n// Implementation derived from TweetNaCl version 20140427.\n// See for details: http://tweetnacl.cr.yp.to/\n\nvar gf = function(init) {\n  var i, r = new Float64Array(16);\n  if (init) for (i = 0; i < init.length; i++) r[i] = init[i];\n  return r;\n};\n\n//  Pluggable, initialized in high-level API below.\nvar randombytes = function(/* x, n */) { throw new Error('no PRNG'); };\n\nvar _0 = new Uint8Array(16);\nvar _9 = new Uint8Array(32); _9[0] = 9;\n\nvar gf0 = gf(),\n    gf1 = gf([1]),\n    _121665 = gf([0xdb41, 1]),\n    D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),\n    D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),\n    X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),\n    Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),\n    I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);\n\nfunction ts64(x, i, h, l) {\n  x[i]   = (h >> 24) & 0xff;\n  x[i+1] = (h >> 16) & 0xff;\n  x[i+2] = (h >>  8) & 0xff;\n  x[i+3] = h & 0xff;\n  x[i+4] = (l >> 24)  & 0xff;\n  x[i+5] = (l >> 16)  & 0xff;\n  x[i+6] = (l >>  8)  & 0xff;\n  x[i+7] = l & 0xff;\n}\n\nfunction vn(x, xi, y, yi, n) {\n  var i,d = 0;\n  for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];\n  return (1 & ((d - 1) >>> 8)) - 1;\n}\n\nfunction crypto_verify_16(x, xi, y, yi) {\n  return vn(x,xi,y,yi,16);\n}\n\nfunction crypto_verify_32(x, xi, y, yi) {\n  return vn(x,xi,y,yi,32);\n}\n\nfunction core_salsa20(o, p, k, c) {\n  var j0  = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24,\n      j1  = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24,\n      j2  = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24,\n      j3  = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24,\n      j4  = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24,\n      j5  = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24,\n      j6  = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24,\n      j7  = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24,\n      j8  = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24,\n      j9  = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24,\n      j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24,\n      j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24,\n      j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24,\n      j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24,\n      j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24,\n      j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24;\n\n  var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,\n      x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14,\n      x15 = j15, u;\n\n  for (var i = 0; i < 20; i += 2) {\n    u = x0 + x12 | 0;\n    x4 ^= u<<7 | u>>>(32-7);\n    u = x4 + x0 | 0;\n    x8 ^= u<<9 | u>>>(32-9);\n    u = x8 + x4 | 0;\n    x12 ^= u<<13 | u>>>(32-13);\n    u = x12 + x8 | 0;\n    x0 ^= u<<18 | u>>>(32-18);\n\n    u = x5 + x1 | 0;\n    x9 ^= u<<7 | u>>>(32-7);\n    u = x9 + x5 | 0;\n    x13 ^= u<<9 | u>>>(32-9);\n    u = x13 + x9 | 0;\n    x1 ^= u<<13 | u>>>(32-13);\n    u = x1 + x13 | 0;\n    x5 ^= u<<18 | u>>>(32-18);\n\n    u = x10 + x6 | 0;\n    x14 ^= u<<7 | u>>>(32-7);\n    u = x14 + x10 | 0;\n    x2 ^= u<<9 | u>>>(32-9);\n    u = x2 + x14 | 0;\n    x6 ^= u<<13 | u>>>(32-13);\n    u = x6 + x2 | 0;\n    x10 ^= u<<18 | u>>>(32-18);\n\n    u = x15 + x11 | 0;\n    x3 ^= u<<7 | u>>>(32-7);\n    u = x3 + x15 | 0;\n    x7 ^= u<<9 | u>>>(32-9);\n    u = x7 + x3 | 0;\n    x11 ^= u<<13 | u>>>(32-13);\n    u = x11 + x7 | 0;\n    x15 ^= u<<18 | u>>>(32-18);\n\n    u = x0 + x3 | 0;\n    x1 ^= u<<7 | u>>>(32-7);\n    u = x1 + x0 | 0;\n    x2 ^= u<<9 | u>>>(32-9);\n    u = x2 + x1 | 0;\n    x3 ^= u<<13 | u>>>(32-13);\n    u = x3 + x2 | 0;\n    x0 ^= u<<18 | u>>>(32-18);\n\n    u = x5 + x4 | 0;\n    x6 ^= u<<7 | u>>>(32-7);\n    u = x6 + x5 | 0;\n    x7 ^= u<<9 | u>>>(32-9);\n    u = x7 + x6 | 0;\n    x4 ^= u<<13 | u>>>(32-13);\n    u = x4 + x7 | 0;\n    x5 ^= u<<18 | u>>>(32-18);\n\n    u = x10 + x9 | 0;\n    x11 ^= u<<7 | u>>>(32-7);\n    u = x11 + x10 | 0;\n    x8 ^= u<<9 | u>>>(32-9);\n    u = x8 + x11 | 0;\n    x9 ^= u<<13 | u>>>(32-13);\n    u = x9 + x8 | 0;\n    x10 ^= u<<18 | u>>>(32-18);\n\n    u = x15 + x14 | 0;\n    x12 ^= u<<7 | u>>>(32-7);\n    u = x12 + x15 | 0;\n    x13 ^= u<<9 | u>>>(32-9);\n    u = x13 + x12 | 0;\n    x14 ^= u<<13 | u>>>(32-13);\n    u = x14 + x13 | 0;\n    x15 ^= u<<18 | u>>>(32-18);\n  }\n   x0 =  x0 +  j0 | 0;\n   x1 =  x1 +  j1 | 0;\n   x2 =  x2 +  j2 | 0;\n   x3 =  x3 +  j3 | 0;\n   x4 =  x4 +  j4 | 0;\n   x5 =  x5 +  j5 | 0;\n   x6 =  x6 +  j6 | 0;\n   x7 =  x7 +  j7 | 0;\n   x8 =  x8 +  j8 | 0;\n   x9 =  x9 +  j9 | 0;\n  x10 = x10 + j10 | 0;\n  x11 = x11 + j11 | 0;\n  x12 = x12 + j12 | 0;\n  x13 = x13 + j13 | 0;\n  x14 = x14 + j14 | 0;\n  x15 = x15 + j15 | 0;\n\n  o[ 0] = x0 >>>  0 & 0xff;\n  o[ 1] = x0 >>>  8 & 0xff;\n  o[ 2] = x0 >>> 16 & 0xff;\n  o[ 3] = x0 >>> 24 & 0xff;\n\n  o[ 4] = x1 >>>  0 & 0xff;\n  o[ 5] = x1 >>>  8 & 0xff;\n  o[ 6] = x1 >>> 16 & 0xff;\n  o[ 7] = x1 >>> 24 & 0xff;\n\n  o[ 8] = x2 >>>  0 & 0xff;\n  o[ 9] = x2 >>>  8 & 0xff;\n  o[10] = x2 >>> 16 & 0xff;\n  o[11] = x2 >>> 24 & 0xff;\n\n  o[12] = x3 >>>  0 & 0xff;\n  o[13] = x3 >>>  8 & 0xff;\n  o[14] = x3 >>> 16 & 0xff;\n  o[15] = x3 >>> 24 & 0xff;\n\n  o[16] = x4 >>>  0 & 0xff;\n  o[17] = x4 >>>  8 & 0xff;\n  o[18] = x4 >>> 16 & 0xff;\n  o[19] = x4 >>> 24 & 0xff;\n\n  o[20] = x5 >>>  0 & 0xff;\n  o[21] = x5 >>>  8 & 0xff;\n  o[22] = x5 >>> 16 & 0xff;\n  o[23] = x5 >>> 24 & 0xff;\n\n  o[24] = x6 >>>  0 & 0xff;\n  o[25] = x6 >>>  8 & 0xff;\n  o[26] = x6 >>> 16 & 0xff;\n  o[27] = x6 >>> 24 & 0xff;\n\n  o[28] = x7 >>>  0 & 0xff;\n  o[29] = x7 >>>  8 & 0xff;\n  o[30] = x7 >>> 16 & 0xff;\n  o[31] = x7 >>> 24 & 0xff;\n\n  o[32] = x8 >>>  0 & 0xff;\n  o[33] = x8 >>>  8 & 0xff;\n  o[34] = x8 >>> 16 & 0xff;\n  o[35] = x8 >>> 24 & 0xff;\n\n  o[36] = x9 >>>  0 & 0xff;\n  o[37] = x9 >>>  8 & 0xff;\n  o[38] = x9 >>> 16 & 0xff;\n  o[39] = x9 >>> 24 & 0xff;\n\n  o[40] = x10 >>>  0 & 0xff;\n  o[41] = x10 >>>  8 & 0xff;\n  o[42] = x10 >>> 16 & 0xff;\n  o[43] = x10 >>> 24 & 0xff;\n\n  o[44] = x11 >>>  0 & 0xff;\n  o[45] = x11 >>>  8 & 0xff;\n  o[46] = x11 >>> 16 & 0xff;\n  o[47] = x11 >>> 24 & 0xff;\n\n  o[48] = x12 >>>  0 & 0xff;\n  o[49] = x12 >>>  8 & 0xff;\n  o[50] = x12 >>> 16 & 0xff;\n  o[51] = x12 >>> 24 & 0xff;\n\n  o[52] = x13 >>>  0 & 0xff;\n  o[53] = x13 >>>  8 & 0xff;\n  o[54] = x13 >>> 16 & 0xff;\n  o[55] = x13 >>> 24 & 0xff;\n\n  o[56] = x14 >>>  0 & 0xff;\n  o[57] = x14 >>>  8 & 0xff;\n  o[58] = x14 >>> 16 & 0xff;\n  o[59] = x14 >>> 24 & 0xff;\n\n  o[60] = x15 >>>  0 & 0xff;\n  o[61] = x15 >>>  8 & 0xff;\n  o[62] = x15 >>> 16 & 0xff;\n  o[63] = x15 >>> 24 & 0xff;\n}\n\nfunction core_hsalsa20(o,p,k,c) {\n  var j0  = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24,\n      j1  = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24,\n      j2  = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24,\n      j3  = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24,\n      j4  = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24,\n      j5  = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24,\n      j6  = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24,\n      j7  = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24,\n      j8  = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24,\n      j9  = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24,\n      j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24,\n      j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24,\n      j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24,\n      j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24,\n      j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24,\n      j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24;\n\n  var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,\n      x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14,\n      x15 = j15, u;\n\n  for (var i = 0; i < 20; i += 2) {\n    u = x0 + x12 | 0;\n    x4 ^= u<<7 | u>>>(32-7);\n    u = x4 + x0 | 0;\n    x8 ^= u<<9 | u>>>(32-9);\n    u = x8 + x4 | 0;\n    x12 ^= u<<13 | u>>>(32-13);\n    u = x12 + x8 | 0;\n    x0 ^= u<<18 | u>>>(32-18);\n\n    u = x5 + x1 | 0;\n    x9 ^= u<<7 | u>>>(32-7);\n    u = x9 + x5 | 0;\n    x13 ^= u<<9 | u>>>(32-9);\n    u = x13 + x9 | 0;\n    x1 ^= u<<13 | u>>>(32-13);\n    u = x1 + x13 | 0;\n    x5 ^= u<<18 | u>>>(32-18);\n\n    u = x10 + x6 | 0;\n    x14 ^= u<<7 | u>>>(32-7);\n    u = x14 + x10 | 0;\n    x2 ^= u<<9 | u>>>(32-9);\n    u = x2 + x14 | 0;\n    x6 ^= u<<13 | u>>>(32-13);\n    u = x6 + x2 | 0;\n    x10 ^= u<<18 | u>>>(32-18);\n\n    u = x15 + x11 | 0;\n    x3 ^= u<<7 | u>>>(32-7);\n    u = x3 + x15 | 0;\n    x7 ^= u<<9 | u>>>(32-9);\n    u = x7 + x3 | 0;\n    x11 ^= u<<13 | u>>>(32-13);\n    u = x11 + x7 | 0;\n    x15 ^= u<<18 | u>>>(32-18);\n\n    u = x0 + x3 | 0;\n    x1 ^= u<<7 | u>>>(32-7);\n    u = x1 + x0 | 0;\n    x2 ^= u<<9 | u>>>(32-9);\n    u = x2 + x1 | 0;\n    x3 ^= u<<13 | u>>>(32-13);\n    u = x3 + x2 | 0;\n    x0 ^= u<<18 | u>>>(32-18);\n\n    u = x5 + x4 | 0;\n    x6 ^= u<<7 | u>>>(32-7);\n    u = x6 + x5 | 0;\n    x7 ^= u<<9 | u>>>(32-9);\n    u = x7 + x6 | 0;\n    x4 ^= u<<13 | u>>>(32-13);\n    u = x4 + x7 | 0;\n    x5 ^= u<<18 | u>>>(32-18);\n\n    u = x10 + x9 | 0;\n    x11 ^= u<<7 | u>>>(32-7);\n    u = x11 + x10 | 0;\n    x8 ^= u<<9 | u>>>(32-9);\n    u = x8 + x11 | 0;\n    x9 ^= u<<13 | u>>>(32-13);\n    u = x9 + x8 | 0;\n    x10 ^= u<<18 | u>>>(32-18);\n\n    u = x15 + x14 | 0;\n    x12 ^= u<<7 | u>>>(32-7);\n    u = x12 + x15 | 0;\n    x13 ^= u<<9 | u>>>(32-9);\n    u = x13 + x12 | 0;\n    x14 ^= u<<13 | u>>>(32-13);\n    u = x14 + x13 | 0;\n    x15 ^= u<<18 | u>>>(32-18);\n  }\n\n  o[ 0] = x0 >>>  0 & 0xff;\n  o[ 1] = x0 >>>  8 & 0xff;\n  o[ 2] = x0 >>> 16 & 0xff;\n  o[ 3] = x0 >>> 24 & 0xff;\n\n  o[ 4] = x5 >>>  0 & 0xff;\n  o[ 5] = x5 >>>  8 & 0xff;\n  o[ 6] = x5 >>> 16 & 0xff;\n  o[ 7] = x5 >>> 24 & 0xff;\n\n  o[ 8] = x10 >>>  0 & 0xff;\n  o[ 9] = x10 >>>  8 & 0xff;\n  o[10] = x10 >>> 16 & 0xff;\n  o[11] = x10 >>> 24 & 0xff;\n\n  o[12] = x15 >>>  0 & 0xff;\n  o[13] = x15 >>>  8 & 0xff;\n  o[14] = x15 >>> 16 & 0xff;\n  o[15] = x15 >>> 24 & 0xff;\n\n  o[16] = x6 >>>  0 & 0xff;\n  o[17] = x6 >>>  8 & 0xff;\n  o[18] = x6 >>> 16 & 0xff;\n  o[19] = x6 >>> 24 & 0xff;\n\n  o[20] = x7 >>>  0 & 0xff;\n  o[21] = x7 >>>  8 & 0xff;\n  o[22] = x7 >>> 16 & 0xff;\n  o[23] = x7 >>> 24 & 0xff;\n\n  o[24] = x8 >>>  0 & 0xff;\n  o[25] = x8 >>>  8 & 0xff;\n  o[26] = x8 >>> 16 & 0xff;\n  o[27] = x8 >>> 24 & 0xff;\n\n  o[28] = x9 >>>  0 & 0xff;\n  o[29] = x9 >>>  8 & 0xff;\n  o[30] = x9 >>> 16 & 0xff;\n  o[31] = x9 >>> 24 & 0xff;\n}\n\nfunction crypto_core_salsa20(out,inp,k,c) {\n  core_salsa20(out,inp,k,c);\n}\n\nfunction crypto_core_hsalsa20(out,inp,k,c) {\n  core_hsalsa20(out,inp,k,c);\n}\n\nvar sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);\n            // \"expand 32-byte k\"\n\nfunction crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {\n  var z = new Uint8Array(16), x = new Uint8Array(64);\n  var u, i;\n  for (i = 0; i < 16; i++) z[i] = 0;\n  for (i = 0; i < 8; i++) z[i] = n[i];\n  while (b >= 64) {\n    crypto_core_salsa20(x,z,k,sigma);\n    for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i];\n    u = 1;\n    for (i = 8; i < 16; i++) {\n      u = u + (z[i] & 0xff) | 0;\n      z[i] = u & 0xff;\n      u >>>= 8;\n    }\n    b -= 64;\n    cpos += 64;\n    mpos += 64;\n  }\n  if (b > 0) {\n    crypto_core_salsa20(x,z,k,sigma);\n    for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i];\n  }\n  return 0;\n}\n\nfunction crypto_stream_salsa20(c,cpos,b,n,k) {\n  var z = new Uint8Array(16), x = new Uint8Array(64);\n  var u, i;\n  for (i = 0; i < 16; i++) z[i] = 0;\n  for (i = 0; i < 8; i++) z[i] = n[i];\n  while (b >= 64) {\n    crypto_core_salsa20(x,z,k,sigma);\n    for (i = 0; i < 64; i++) c[cpos+i] = x[i];\n    u = 1;\n    for (i = 8; i < 16; i++) {\n      u = u + (z[i] & 0xff) | 0;\n      z[i] = u & 0xff;\n      u >>>= 8;\n    }\n    b -= 64;\n    cpos += 64;\n  }\n  if (b > 0) {\n    crypto_core_salsa20(x,z,k,sigma);\n    for (i = 0; i < b; i++) c[cpos+i] = x[i];\n  }\n  return 0;\n}\n\nfunction crypto_stream(c,cpos,d,n,k) {\n  var s = new Uint8Array(32);\n  crypto_core_hsalsa20(s,n,k,sigma);\n  var sn = new Uint8Array(8);\n  for (var i = 0; i < 8; i++) sn[i] = n[i+16];\n  return crypto_stream_salsa20(c,cpos,d,sn,s);\n}\n\nfunction crypto_stream_xor(c,cpos,m,mpos,d,n,k) {\n  var s = new Uint8Array(32);\n  crypto_core_hsalsa20(s,n,k,sigma);\n  var sn = new Uint8Array(8);\n  for (var i = 0; i < 8; i++) sn[i] = n[i+16];\n  return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s);\n}\n\n/*\n* Port of Andrew Moon's Poly1305-donna-16. Public domain.\n* https://github.com/floodyberry/poly1305-donna\n*/\n\nvar poly1305 = function(key) {\n  this.buffer = new Uint8Array(16);\n  this.r = new Uint16Array(10);\n  this.h = new Uint16Array(10);\n  this.pad = new Uint16Array(8);\n  this.leftover = 0;\n  this.fin = 0;\n\n  var t0, t1, t2, t3, t4, t5, t6, t7;\n\n  t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0                     ) & 0x1fff;\n  t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 <<  3)) & 0x1fff;\n  t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 <<  6)) & 0x1f03;\n  t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>>  7) | (t3 <<  9)) & 0x1fff;\n  t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>>  4) | (t4 << 12)) & 0x00ff;\n  this.r[5] = ((t4 >>>  1)) & 0x1ffe;\n  t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 <<  2)) & 0x1fff;\n  t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 <<  5)) & 0x1f81;\n  t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>>  8) | (t7 <<  8)) & 0x1fff;\n  this.r[9] = ((t7 >>>  5)) & 0x007f;\n\n  this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;\n  this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;\n  this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;\n  this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;\n  this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;\n  this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;\n  this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;\n  this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;\n};\n\npoly1305.prototype.blocks = function(m, mpos, bytes) {\n  var hibit = this.fin ? 0 : (1 << 11);\n  var t0, t1, t2, t3, t4, t5, t6, t7, c;\n  var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;\n\n  var h0 = this.h[0],\n      h1 = this.h[1],\n      h2 = this.h[2],\n      h3 = this.h[3],\n      h4 = this.h[4],\n      h5 = this.h[5],\n      h6 = this.h[6],\n      h7 = this.h[7],\n      h8 = this.h[8],\n      h9 = this.h[9];\n\n  var r0 = this.r[0],\n      r1 = this.r[1],\n      r2 = this.r[2],\n      r3 = this.r[3],\n      r4 = this.r[4],\n      r5 = this.r[5],\n      r6 = this.r[6],\n      r7 = this.r[7],\n      r8 = this.r[8],\n      r9 = this.r[9];\n\n  while (bytes >= 16) {\n    t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0                     ) & 0x1fff;\n    t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 <<  3)) & 0x1fff;\n    t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 <<  6)) & 0x1fff;\n    t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>>  7) | (t3 <<  9)) & 0x1fff;\n    t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>>  4) | (t4 << 12)) & 0x1fff;\n    h5 += ((t4 >>>  1)) & 0x1fff;\n    t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 <<  2)) & 0x1fff;\n    t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 <<  5)) & 0x1fff;\n    t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>>  8) | (t7 <<  8)) & 0x1fff;\n    h9 += ((t7 >>> 5)) | hibit;\n\n    c = 0;\n\n    d0 = c;\n    d0 += h0 * r0;\n    d0 += h1 * (5 * r9);\n    d0 += h2 * (5 * r8);\n    d0 += h3 * (5 * r7);\n    d0 += h4 * (5 * r6);\n    c = (d0 >>> 13); d0 &= 0x1fff;\n    d0 += h5 * (5 * r5);\n    d0 += h6 * (5 * r4);\n    d0 += h7 * (5 * r3);\n    d0 += h8 * (5 * r2);\n    d0 += h9 * (5 * r1);\n    c += (d0 >>> 13); d0 &= 0x1fff;\n\n    d1 = c;\n    d1 += h0 * r1;\n    d1 += h1 * r0;\n    d1 += h2 * (5 * r9);\n    d1 += h3 * (5 * r8);\n    d1 += h4 * (5 * r7);\n    c = (d1 >>> 13); d1 &= 0x1fff;\n    d1 += h5 * (5 * r6);\n    d1 += h6 * (5 * r5);\n    d1 += h7 * (5 * r4);\n    d1 += h8 * (5 * r3);\n    d1 += h9 * (5 * r2);\n    c += (d1 >>> 13); d1 &= 0x1fff;\n\n    d2 = c;\n    d2 += h0 * r2;\n    d2 += h1 * r1;\n    d2 += h2 * r0;\n    d2 += h3 * (5 * r9);\n    d2 += h4 * (5 * r8);\n    c = (d2 >>> 13); d2 &= 0x1fff;\n    d2 += h5 * (5 * r7);\n    d2 += h6 * (5 * r6);\n    d2 += h7 * (5 * r5);\n    d2 += h8 * (5 * r4);\n    d2 += h9 * (5 * r3);\n    c += (d2 >>> 13); d2 &= 0x1fff;\n\n    d3 = c;\n    d3 += h0 * r3;\n    d3 += h1 * r2;\n    d3 += h2 * r1;\n    d3 += h3 * r0;\n    d3 += h4 * (5 * r9);\n    c = (d3 >>> 13); d3 &= 0x1fff;\n    d3 += h5 * (5 * r8);\n    d3 += h6 * (5 * r7);\n    d3 += h7 * (5 * r6);\n    d3 += h8 * (5 * r5);\n    d3 += h9 * (5 * r4);\n    c += (d3 >>> 13); d3 &= 0x1fff;\n\n    d4 = c;\n    d4 += h0 * r4;\n    d4 += h1 * r3;\n    d4 += h2 * r2;\n    d4 += h3 * r1;\n    d4 += h4 * r0;\n    c = (d4 >>> 13); d4 &= 0x1fff;\n    d4 += h5 * (5 * r9);\n    d4 += h6 * (5 * r8);\n    d4 += h7 * (5 * r7);\n    d4 += h8 * (5 * r6);\n    d4 += h9 * (5 * r5);\n    c += (d4 >>> 13); d4 &= 0x1fff;\n\n    d5 = c;\n    d5 += h0 * r5;\n    d5 += h1 * r4;\n    d5 += h2 * r3;\n    d5 += h3 * r2;\n    d5 += h4 * r1;\n    c = (d5 >>> 13); d5 &= 0x1fff;\n    d5 += h5 * r0;\n    d5 += h6 * (5 * r9);\n    d5 += h7 * (5 * r8);\n    d5 += h8 * (5 * r7);\n    d5 += h9 * (5 * r6);\n    c += (d5 >>> 13); d5 &= 0x1fff;\n\n    d6 = c;\n    d6 += h0 * r6;\n    d6 += h1 * r5;\n    d6 += h2 * r4;\n    d6 += h3 * r3;\n    d6 += h4 * r2;\n    c = (d6 >>> 13); d6 &= 0x1fff;\n    d6 += h5 * r1;\n    d6 += h6 * r0;\n    d6 += h7 * (5 * r9);\n    d6 += h8 * (5 * r8);\n    d6 += h9 * (5 * r7);\n    c += (d6 >>> 13); d6 &= 0x1fff;\n\n    d7 = c;\n    d7 += h0 * r7;\n    d7 += h1 * r6;\n    d7 += h2 * r5;\n    d7 += h3 * r4;\n    d7 += h4 * r3;\n    c = (d7 >>> 13); d7 &= 0x1fff;\n    d7 += h5 * r2;\n    d7 += h6 * r1;\n    d7 += h7 * r0;\n    d7 += h8 * (5 * r9);\n    d7 += h9 * (5 * r8);\n    c += (d7 >>> 13); d7 &= 0x1fff;\n\n    d8 = c;\n    d8 += h0 * r8;\n    d8 += h1 * r7;\n    d8 += h2 * r6;\n    d8 += h3 * r5;\n    d8 += h4 * r4;\n    c = (d8 >>> 13); d8 &= 0x1fff;\n    d8 += h5 * r3;\n    d8 += h6 * r2;\n    d8 += h7 * r1;\n    d8 += h8 * r0;\n    d8 += h9 * (5 * r9);\n    c += (d8 >>> 13); d8 &= 0x1fff;\n\n    d9 = c;\n    d9 += h0 * r9;\n    d9 += h1 * r8;\n    d9 += h2 * r7;\n    d9 += h3 * r6;\n    d9 += h4 * r5;\n    c = (d9 >>> 13); d9 &= 0x1fff;\n    d9 += h5 * r4;\n    d9 += h6 * r3;\n    d9 += h7 * r2;\n    d9 += h8 * r1;\n    d9 += h9 * r0;\n    c += (d9 >>> 13); d9 &= 0x1fff;\n\n    c = (((c << 2) + c)) | 0;\n    c = (c + d0) | 0;\n    d0 = c & 0x1fff;\n    c = (c >>> 13);\n    d1 += c;\n\n    h0 = d0;\n    h1 = d1;\n    h2 = d2;\n    h3 = d3;\n    h4 = d4;\n    h5 = d5;\n    h6 = d6;\n    h7 = d7;\n    h8 = d8;\n    h9 = d9;\n\n    mpos += 16;\n    bytes -= 16;\n  }\n  this.h[0] = h0;\n  this.h[1] = h1;\n  this.h[2] = h2;\n  this.h[3] = h3;\n  this.h[4] = h4;\n  this.h[5] = h5;\n  this.h[6] = h6;\n  this.h[7] = h7;\n  this.h[8] = h8;\n  this.h[9] = h9;\n};\n\npoly1305.prototype.finish = function(mac, macpos) {\n  var g = new Uint16Array(10);\n  var c, mask, f, i;\n\n  if (this.leftover) {\n    i = this.leftover;\n    this.buffer[i++] = 1;\n    for (; i < 16; i++) this.buffer[i] = 0;\n    this.fin = 1;\n    this.blocks(this.buffer, 0, 16);\n  }\n\n  c = this.h[1] >>> 13;\n  this.h[1] &= 0x1fff;\n  for (i = 2; i < 10; i++) {\n    this.h[i] += c;\n    c = this.h[i] >>> 13;\n    this.h[i] &= 0x1fff;\n  }\n  this.h[0] += (c * 5);\n  c = this.h[0] >>> 13;\n  this.h[0] &= 0x1fff;\n  this.h[1] += c;\n  c = this.h[1] >>> 13;\n  this.h[1] &= 0x1fff;\n  this.h[2] += c;\n\n  g[0] = this.h[0] + 5;\n  c = g[0] >>> 13;\n  g[0] &= 0x1fff;\n  for (i = 1; i < 10; i++) {\n    g[i] = this.h[i] + c;\n    c = g[i] >>> 13;\n    g[i] &= 0x1fff;\n  }\n  g[9] -= (1 << 13);\n\n  mask = (c ^ 1) - 1;\n  for (i = 0; i < 10; i++) g[i] &= mask;\n  mask = ~mask;\n  for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];\n\n  this.h[0] = ((this.h[0]       ) | (this.h[1] << 13)                    ) & 0xffff;\n  this.h[1] = ((this.h[1] >>>  3) | (this.h[2] << 10)                    ) & 0xffff;\n  this.h[2] = ((this.h[2] >>>  6) | (this.h[3] <<  7)                    ) & 0xffff;\n  this.h[3] = ((this.h[3] >>>  9) | (this.h[4] <<  4)                    ) & 0xffff;\n  this.h[4] = ((this.h[4] >>> 12) | (this.h[5] <<  1) | (this.h[6] << 14)) & 0xffff;\n  this.h[5] = ((this.h[6] >>>  2) | (this.h[7] << 11)                    ) & 0xffff;\n  this.h[6] = ((this.h[7] >>>  5) | (this.h[8] <<  8)                    ) & 0xffff;\n  this.h[7] = ((this.h[8] >>>  8) | (this.h[9] <<  5)                    ) & 0xffff;\n\n  f = this.h[0] + this.pad[0];\n  this.h[0] = f & 0xffff;\n  for (i = 1; i < 8; i++) {\n    f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;\n    this.h[i] = f & 0xffff;\n  }\n\n  mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff;\n  mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff;\n  mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff;\n  mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff;\n  mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff;\n  mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff;\n  mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff;\n  mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff;\n  mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff;\n  mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff;\n  mac[macpos+10] = (this.h[5] >>> 0) & 0xff;\n  mac[macpos+11] = (this.h[5] >>> 8) & 0xff;\n  mac[macpos+12] = (this.h[6] >>> 0) & 0xff;\n  mac[macpos+13] = (this.h[6] >>> 8) & 0xff;\n  mac[macpos+14] = (this.h[7] >>> 0) & 0xff;\n  mac[macpos+15] = (this.h[7] >>> 8) & 0xff;\n};\n\npoly1305.prototype.update = function(m, mpos, bytes) {\n  var i, want;\n\n  if (this.leftover) {\n    want = (16 - this.leftover);\n    if (want > bytes)\n      want = bytes;\n    for (i = 0; i < want; i++)\n      this.buffer[this.leftover + i] = m[mpos+i];\n    bytes -= want;\n    mpos += want;\n    this.leftover += want;\n    if (this.leftover < 16)\n      return;\n    this.blocks(this.buffer, 0, 16);\n    this.leftover = 0;\n  }\n\n  if (bytes >= 16) {\n    want = bytes - (bytes % 16);\n    this.blocks(m, mpos, want);\n    mpos += want;\n    bytes -= want;\n  }\n\n  if (bytes) {\n    for (i = 0; i < bytes; i++)\n      this.buffer[this.leftover + i] = m[mpos+i];\n    this.leftover += bytes;\n  }\n};\n\nfunction crypto_onetimeauth(out, outpos, m, mpos, n, k) {\n  var s = new poly1305(k);\n  s.update(m, mpos, n);\n  s.finish(out, outpos);\n  return 0;\n}\n\nfunction crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {\n  var x = new Uint8Array(16);\n  crypto_onetimeauth(x,0,m,mpos,n,k);\n  return crypto_verify_16(h,hpos,x,0);\n}\n\nfunction crypto_secretbox(c,m,d,n,k) {\n  var i;\n  if (d < 32) return -1;\n  crypto_stream_xor(c,0,m,0,d,n,k);\n  crypto_onetimeauth(c, 16, c, 32, d - 32, c);\n  for (i = 0; i < 16; i++) c[i] = 0;\n  return 0;\n}\n\nfunction crypto_secretbox_open(m,c,d,n,k) {\n  var i;\n  var x = new Uint8Array(32);\n  if (d < 32) return -1;\n  crypto_stream(x,0,32,n,k);\n  if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1;\n  crypto_stream_xor(m,0,c,0,d,n,k);\n  for (i = 0; i < 32; i++) m[i] = 0;\n  return 0;\n}\n\nfunction set25519(r, a) {\n  var i;\n  for (i = 0; i < 16; i++) r[i] = a[i]|0;\n}\n\nfunction car25519(o) {\n  var i, v, c = 1;\n  for (i = 0; i < 16; i++) {\n    v = o[i] + c + 65535;\n    c = Math.floor(v / 65536);\n    o[i] = v - c * 65536;\n  }\n  o[0] += c-1 + 37 * (c-1);\n}\n\nfunction sel25519(p, q, b) {\n  var t, c = ~(b-1);\n  for (var i = 0; i < 16; i++) {\n    t = c & (p[i] ^ q[i]);\n    p[i] ^= t;\n    q[i] ^= t;\n  }\n}\n\nfunction pack25519(o, n) {\n  var i, j, b;\n  var m = gf(), t = gf();\n  for (i = 0; i < 16; i++) t[i] = n[i];\n  car25519(t);\n  car25519(t);\n  car25519(t);\n  for (j = 0; j < 2; j++) {\n    m[0] = t[0] - 0xffed;\n    for (i = 1; i < 15; i++) {\n      m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);\n      m[i-1] &= 0xffff;\n    }\n    m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);\n    b = (m[15]>>16) & 1;\n    m[14] &= 0xffff;\n    sel25519(t, m, 1-b);\n  }\n  for (i = 0; i < 16; i++) {\n    o[2*i] = t[i] & 0xff;\n    o[2*i+1] = t[i]>>8;\n  }\n}\n\nfunction neq25519(a, b) {\n  var c = new Uint8Array(32), d = new Uint8Array(32);\n  pack25519(c, a);\n  pack25519(d, b);\n  return crypto_verify_32(c, 0, d, 0);\n}\n\nfunction par25519(a) {\n  var d = new Uint8Array(32);\n  pack25519(d, a);\n  return d[0] & 1;\n}\n\nfunction unpack25519(o, n) {\n  var i;\n  for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);\n  o[15] &= 0x7fff;\n}\n\nfunction A(o, a, b) {\n  for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];\n}\n\nfunction Z(o, a, b) {\n  for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];\n}\n\nfunction M(o, a, b) {\n  var v, c,\n     t0 = 0,  t1 = 0,  t2 = 0,  t3 = 0,  t4 = 0,  t5 = 0,  t6 = 0,  t7 = 0,\n     t8 = 0,  t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,\n    t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,\n    t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,\n    b0 = b[0],\n    b1 = b[1],\n    b2 = b[2],\n    b3 = b[3],\n    b4 = b[4],\n    b5 = b[5],\n    b6 = b[6],\n    b7 = b[7],\n    b8 = b[8],\n    b9 = b[9],\n    b10 = b[10],\n    b11 = b[11],\n    b12 = b[12],\n    b13 = b[13],\n    b14 = b[14],\n    b15 = b[15];\n\n  v = a[0];\n  t0 += v * b0;\n  t1 += v * b1;\n  t2 += v * b2;\n  t3 += v * b3;\n  t4 += v * b4;\n  t5 += v * b5;\n  t6 += v * b6;\n  t7 += v * b7;\n  t8 += v * b8;\n  t9 += v * b9;\n  t10 += v * b10;\n  t11 += v * b11;\n  t12 += v * b12;\n  t13 += v * b13;\n  t14 += v * b14;\n  t15 += v * b15;\n  v = a[1];\n  t1 += v * b0;\n  t2 += v * b1;\n  t3 += v * b2;\n  t4 += v * b3;\n  t5 += v * b4;\n  t6 += v * b5;\n  t7 += v * b6;\n  t8 += v * b7;\n  t9 += v * b8;\n  t10 += v * b9;\n  t11 += v * b10;\n  t12 += v * b11;\n  t13 += v * b12;\n  t14 += v * b13;\n  t15 += v * b14;\n  t16 += v * b15;\n  v = a[2];\n  t2 += v * b0;\n  t3 += v * b1;\n  t4 += v * b2;\n  t5 += v * b3;\n  t6 += v * b4;\n  t7 += v * b5;\n  t8 += v * b6;\n  t9 += v * b7;\n  t10 += v * b8;\n  t11 += v * b9;\n  t12 += v * b10;\n  t13 += v * b11;\n  t14 += v * b12;\n  t15 += v * b13;\n  t16 += v * b14;\n  t17 += v * b15;\n  v = a[3];\n  t3 += v * b0;\n  t4 += v * b1;\n  t5 += v * b2;\n  t6 += v * b3;\n  t7 += v * b4;\n  t8 += v * b5;\n  t9 += v * b6;\n  t10 += v * b7;\n  t11 += v * b8;\n  t12 += v * b9;\n  t13 += v * b10;\n  t14 += v * b11;\n  t15 += v * b12;\n  t16 += v * b13;\n  t17 += v * b14;\n  t18 += v * b15;\n  v = a[4];\n  t4 += v * b0;\n  t5 += v * b1;\n  t6 += v * b2;\n  t7 += v * b3;\n  t8 += v * b4;\n  t9 += v * b5;\n  t10 += v * b6;\n  t11 += v * b7;\n  t12 += v * b8;\n  t13 += v * b9;\n  t14 += v * b10;\n  t15 += v * b11;\n  t16 += v * b12;\n  t17 += v * b13;\n  t18 += v * b14;\n  t19 += v * b15;\n  v = a[5];\n  t5 += v * b0;\n  t6 += v * b1;\n  t7 += v * b2;\n  t8 += v * b3;\n  t9 += v * b4;\n  t10 += v * b5;\n  t11 += v * b6;\n  t12 += v * b7;\n  t13 += v * b8;\n  t14 += v * b9;\n  t15 += v * b10;\n  t16 += v * b11;\n  t17 += v * b12;\n  t18 += v * b13;\n  t19 += v * b14;\n  t20 += v * b15;\n  v = a[6];\n  t6 += v * b0;\n  t7 += v * b1;\n  t8 += v * b2;\n  t9 += v * b3;\n  t10 += v * b4;\n  t11 += v * b5;\n  t12 += v * b6;\n  t13 += v * b7;\n  t14 += v * b8;\n  t15 += v * b9;\n  t16 += v * b10;\n  t17 += v * b11;\n  t18 += v * b12;\n  t19 += v * b13;\n  t20 += v * b14;\n  t21 += v * b15;\n  v = a[7];\n  t7 += v * b0;\n  t8 += v * b1;\n  t9 += v * b2;\n  t10 += v * b3;\n  t11 += v * b4;\n  t12 += v * b5;\n  t13 += v * b6;\n  t14 += v * b7;\n  t15 += v * b8;\n  t16 += v * b9;\n  t17 += v * b10;\n  t18 += v * b11;\n  t19 += v * b12;\n  t20 += v * b13;\n  t21 += v * b14;\n  t22 += v * b15;\n  v = a[8];\n  t8 += v * b0;\n  t9 += v * b1;\n  t10 += v * b2;\n  t11 += v * b3;\n  t12 += v * b4;\n  t13 += v * b5;\n  t14 += v * b6;\n  t15 += v * b7;\n  t16 += v * b8;\n  t17 += v * b9;\n  t18 += v * b10;\n  t19 += v * b11;\n  t20 += v * b12;\n  t21 += v * b13;\n  t22 += v * b14;\n  t23 += v * b15;\n  v = a[9];\n  t9 += v * b0;\n  t10 += v * b1;\n  t11 += v * b2;\n  t12 += v * b3;\n  t13 += v * b4;\n  t14 += v * b5;\n  t15 += v * b6;\n  t16 += v * b7;\n  t17 += v * b8;\n  t18 += v * b9;\n  t19 += v * b10;\n  t20 += v * b11;\n  t21 += v * b12;\n  t22 += v * b13;\n  t23 += v * b14;\n  t24 += v * b15;\n  v = a[10];\n  t10 += v * b0;\n  t11 += v * b1;\n  t12 += v * b2;\n  t13 += v * b3;\n  t14 += v * b4;\n  t15 += v * b5;\n  t16 += v * b6;\n  t17 += v * b7;\n  t18 += v * b8;\n  t19 += v * b9;\n  t20 += v * b10;\n  t21 += v * b11;\n  t22 += v * b12;\n  t23 += v * b13;\n  t24 += v * b14;\n  t25 += v * b15;\n  v = a[11];\n  t11 += v * b0;\n  t12 += v * b1;\n  t13 += v * b2;\n  t14 += v * b3;\n  t15 += v * b4;\n  t16 += v * b5;\n  t17 += v * b6;\n  t18 += v * b7;\n  t19 += v * b8;\n  t20 += v * b9;\n  t21 += v * b10;\n  t22 += v * b11;\n  t23 += v * b12;\n  t24 += v * b13;\n  t25 += v * b14;\n  t26 += v * b15;\n  v = a[12];\n  t12 += v * b0;\n  t13 += v * b1;\n  t14 += v * b2;\n  t15 += v * b3;\n  t16 += v * b4;\n  t17 += v * b5;\n  t18 += v * b6;\n  t19 += v * b7;\n  t20 += v * b8;\n  t21 += v * b9;\n  t22 += v * b10;\n  t23 += v * b11;\n  t24 += v * b12;\n  t25 += v * b13;\n  t26 += v * b14;\n  t27 += v * b15;\n  v = a[13];\n  t13 += v * b0;\n  t14 += v * b1;\n  t15 += v * b2;\n  t16 += v * b3;\n  t17 += v * b4;\n  t18 += v * b5;\n  t19 += v * b6;\n  t20 += v * b7;\n  t21 += v * b8;\n  t22 += v * b9;\n  t23 += v * b10;\n  t24 += v * b11;\n  t25 += v * b12;\n  t26 += v * b13;\n  t27 += v * b14;\n  t28 += v * b15;\n  v = a[14];\n  t14 += v * b0;\n  t15 += v * b1;\n  t16 += v * b2;\n  t17 += v * b3;\n  t18 += v * b4;\n  t19 += v * b5;\n  t20 += v * b6;\n  t21 += v * b7;\n  t22 += v * b8;\n  t23 += v * b9;\n  t24 += v * b10;\n  t25 += v * b11;\n  t26 += v * b12;\n  t27 += v * b13;\n  t28 += v * b14;\n  t29 += v * b15;\n  v = a[15];\n  t15 += v * b0;\n  t16 += v * b1;\n  t17 += v * b2;\n  t18 += v * b3;\n  t19 += v * b4;\n  t20 += v * b5;\n  t21 += v * b6;\n  t22 += v * b7;\n  t23 += v * b8;\n  t24 += v * b9;\n  t25 += v * b10;\n  t26 += v * b11;\n  t27 += v * b12;\n  t28 += v * b13;\n  t29 += v * b14;\n  t30 += v * b15;\n\n  t0  += 38 * t16;\n  t1  += 38 * t17;\n  t2  += 38 * t18;\n  t3  += 38 * t19;\n  t4  += 38 * t20;\n  t5  += 38 * t21;\n  t6  += 38 * t22;\n  t7  += 38 * t23;\n  t8  += 38 * t24;\n  t9  += 38 * t25;\n  t10 += 38 * t26;\n  t11 += 38 * t27;\n  t12 += 38 * t28;\n  t13 += 38 * t29;\n  t14 += 38 * t30;\n  // t15 left as is\n\n  // first car\n  c = 1;\n  v =  t0 + c + 65535; c = Math.floor(v / 65536);  t0 = v - c * 65536;\n  v =  t1 + c + 65535; c = Math.floor(v / 65536);  t1 = v - c * 65536;\n  v =  t2 + c + 65535; c = Math.floor(v / 65536);  t2 = v - c * 65536;\n  v =  t3 + c + 65535; c = Math.floor(v / 65536);  t3 = v - c * 65536;\n  v =  t4 + c + 65535; c = Math.floor(v / 65536);  t4 = v - c * 65536;\n  v =  t5 + c + 65535; c = Math.floor(v / 65536);  t5 = v - c * 65536;\n  v =  t6 + c + 65535; c = Math.floor(v / 65536);  t6 = v - c * 65536;\n  v =  t7 + c + 65535; c = Math.floor(v / 65536);  t7 = v - c * 65536;\n  v =  t8 + c + 65535; c = Math.floor(v / 65536);  t8 = v - c * 65536;\n  v =  t9 + c + 65535; c = Math.floor(v / 65536);  t9 = v - c * 65536;\n  v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;\n  v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;\n  v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;\n  v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;\n  v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;\n  v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;\n  t0 += c-1 + 37 * (c-1);\n\n  // second car\n  c = 1;\n  v =  t0 + c + 65535; c = Math.floor(v / 65536);  t0 = v - c * 65536;\n  v =  t1 + c + 65535; c = Math.floor(v / 65536);  t1 = v - c * 65536;\n  v =  t2 + c + 65535; c = Math.floor(v / 65536);  t2 = v - c * 65536;\n  v =  t3 + c + 65535; c = Math.floor(v / 65536);  t3 = v - c * 65536;\n  v =  t4 + c + 65535; c = Math.floor(v / 65536);  t4 = v - c * 65536;\n  v =  t5 + c + 65535; c = Math.floor(v / 65536);  t5 = v - c * 65536;\n  v =  t6 + c + 65535; c = Math.floor(v / 65536);  t6 = v - c * 65536;\n  v =  t7 + c + 65535; c = Math.floor(v / 65536);  t7 = v - c * 65536;\n  v =  t8 + c + 65535; c = Math.floor(v / 65536);  t8 = v - c * 65536;\n  v =  t9 + c + 65535; c = Math.floor(v / 65536);  t9 = v - c * 65536;\n  v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;\n  v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;\n  v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;\n  v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;\n  v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;\n  v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;\n  t0 += c-1 + 37 * (c-1);\n\n  o[ 0] = t0;\n  o[ 1] = t1;\n  o[ 2] = t2;\n  o[ 3] = t3;\n  o[ 4] = t4;\n  o[ 5] = t5;\n  o[ 6] = t6;\n  o[ 7] = t7;\n  o[ 8] = t8;\n  o[ 9] = t9;\n  o[10] = t10;\n  o[11] = t11;\n  o[12] = t12;\n  o[13] = t13;\n  o[14] = t14;\n  o[15] = t15;\n}\n\nfunction S(o, a) {\n  M(o, a, a);\n}\n\nfunction inv25519(o, i) {\n  var c = gf();\n  var a;\n  for (a = 0; a < 16; a++) c[a] = i[a];\n  for (a = 253; a >= 0; a--) {\n    S(c, c);\n    if(a !== 2 && a !== 4) M(c, c, i);\n  }\n  for (a = 0; a < 16; a++) o[a] = c[a];\n}\n\nfunction pow2523(o, i) {\n  var c = gf();\n  var a;\n  for (a = 0; a < 16; a++) c[a] = i[a];\n  for (a = 250; a >= 0; a--) {\n      S(c, c);\n      if(a !== 1) M(c, c, i);\n  }\n  for (a = 0; a < 16; a++) o[a] = c[a];\n}\n\nfunction crypto_scalarmult(q, n, p) {\n  var z = new Uint8Array(32);\n  var x = new Float64Array(80), r, i;\n  var a = gf(), b = gf(), c = gf(),\n      d = gf(), e = gf(), f = gf();\n  for (i = 0; i < 31; i++) z[i] = n[i];\n  z[31]=(n[31]&127)|64;\n  z[0]&=248;\n  unpack25519(x,p);\n  for (i = 0; i < 16; i++) {\n    b[i]=x[i];\n    d[i]=a[i]=c[i]=0;\n  }\n  a[0]=d[0]=1;\n  for (i=254; i>=0; --i) {\n    r=(z[i>>>3]>>>(i&7))&1;\n    sel25519(a,b,r);\n    sel25519(c,d,r);\n    A(e,a,c);\n    Z(a,a,c);\n    A(c,b,d);\n    Z(b,b,d);\n    S(d,e);\n    S(f,a);\n    M(a,c,a);\n    M(c,b,e);\n    A(e,a,c);\n    Z(a,a,c);\n    S(b,a);\n    Z(c,d,f);\n    M(a,c,_121665);\n    A(a,a,d);\n    M(c,c,a);\n    M(a,d,f);\n    M(d,b,x);\n    S(b,e);\n    sel25519(a,b,r);\n    sel25519(c,d,r);\n  }\n  for (i = 0; i < 16; i++) {\n    x[i+16]=a[i];\n    x[i+32]=c[i];\n    x[i+48]=b[i];\n    x[i+64]=d[i];\n  }\n  var x32 = x.subarray(32);\n  var x16 = x.subarray(16);\n  inv25519(x32,x32);\n  M(x16,x16,x32);\n  pack25519(q,x16);\n  return 0;\n}\n\nfunction crypto_scalarmult_base(q, n) {\n  return crypto_scalarmult(q, n, _9);\n}\n\nfunction crypto_box_keypair(y, x) {\n  randombytes(x, 32);\n  return crypto_scalarmult_base(y, x);\n}\n\nfunction crypto_box_beforenm(k, y, x) {\n  var s = new Uint8Array(32);\n  crypto_scalarmult(s, x, y);\n  return crypto_core_hsalsa20(k, _0, s, sigma);\n}\n\nvar crypto_box_afternm = crypto_secretbox;\nvar crypto_box_open_afternm = crypto_secretbox_open;\n\nfunction crypto_box(c, m, d, n, y, x) {\n  var k = new Uint8Array(32);\n  crypto_box_beforenm(k, y, x);\n  return crypto_box_afternm(c, m, d, n, k);\n}\n\nfunction crypto_box_open(m, c, d, n, y, x) {\n  var k = new Uint8Array(32);\n  crypto_box_beforenm(k, y, x);\n  return crypto_box_open_afternm(m, c, d, n, k);\n}\n\nvar K = [\n  0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n  0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n  0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n  0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n  0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n  0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n  0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n  0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n  0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n  0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n  0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n  0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n  0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n  0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n  0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n  0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n  0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n  0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n  0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n  0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n  0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n  0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n  0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n  0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n  0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n  0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n  0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n  0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n  0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n  0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n  0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n  0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n  0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n  0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n  0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n  0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n  0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n  0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n  0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n  0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction crypto_hashblocks_hl(hh, hl, m, n) {\n  var wh = new Int32Array(16), wl = new Int32Array(16),\n      bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7,\n      bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7,\n      th, tl, i, j, h, l, a, b, c, d;\n\n  var ah0 = hh[0],\n      ah1 = hh[1],\n      ah2 = hh[2],\n      ah3 = hh[3],\n      ah4 = hh[4],\n      ah5 = hh[5],\n      ah6 = hh[6],\n      ah7 = hh[7],\n\n      al0 = hl[0],\n      al1 = hl[1],\n      al2 = hl[2],\n      al3 = hl[3],\n      al4 = hl[4],\n      al5 = hl[5],\n      al6 = hl[6],\n      al7 = hl[7];\n\n  var pos = 0;\n  while (n >= 128) {\n    for (i = 0; i < 16; i++) {\n      j = 8 * i + pos;\n      wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3];\n      wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7];\n    }\n    for (i = 0; i < 80; i++) {\n      bh0 = ah0;\n      bh1 = ah1;\n      bh2 = ah2;\n      bh3 = ah3;\n      bh4 = ah4;\n      bh5 = ah5;\n      bh6 = ah6;\n      bh7 = ah7;\n\n      bl0 = al0;\n      bl1 = al1;\n      bl2 = al2;\n      bl3 = al3;\n      bl4 = al4;\n      bl5 = al5;\n      bl6 = al6;\n      bl7 = al7;\n\n      // add\n      h = ah7;\n      l = al7;\n\n      a = l & 0xffff; b = l >>> 16;\n      c = h & 0xffff; d = h >>> 16;\n\n      // Sigma1\n      h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32))));\n      l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32))));\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      // Ch\n      h = (ah4 & ah5) ^ (~ah4 & ah6);\n      l = (al4 & al5) ^ (~al4 & al6);\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      // K\n      h = K[i*2];\n      l = K[i*2+1];\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      // w\n      h = wh[i%16];\n      l = wl[i%16];\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      b += a >>> 16;\n      c += b >>> 16;\n      d += c >>> 16;\n\n      th = c & 0xffff | d << 16;\n      tl = a & 0xffff | b << 16;\n\n      // add\n      h = th;\n      l = tl;\n\n      a = l & 0xffff; b = l >>> 16;\n      c = h & 0xffff; d = h >>> 16;\n\n      // Sigma0\n      h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32))));\n      l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32))));\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      // Maj\n      h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2);\n      l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2);\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      b += a >>> 16;\n      c += b >>> 16;\n      d += c >>> 16;\n\n      bh7 = (c & 0xffff) | (d << 16);\n      bl7 = (a & 0xffff) | (b << 16);\n\n      // add\n      h = bh3;\n      l = bl3;\n\n      a = l & 0xffff; b = l >>> 16;\n      c = h & 0xffff; d = h >>> 16;\n\n      h = th;\n      l = tl;\n\n      a += l & 0xffff; b += l >>> 16;\n      c += h & 0xffff; d += h >>> 16;\n\n      b += a >>> 16;\n      c += b >>> 16;\n      d += c >>> 16;\n\n      bh3 = (c & 0xffff) | (d << 16);\n      bl3 = (a & 0xffff) | (b << 16);\n\n      ah1 = bh0;\n      ah2 = bh1;\n      ah3 = bh2;\n      ah4 = bh3;\n      ah5 = bh4;\n      ah6 = bh5;\n      ah7 = bh6;\n      ah0 = bh7;\n\n      al1 = bl0;\n      al2 = bl1;\n      al3 = bl2;\n      al4 = bl3;\n      al5 = bl4;\n      al6 = bl5;\n      al7 = bl6;\n      al0 = bl7;\n\n      if (i%16 === 15) {\n        for (j = 0; j < 16; j++) {\n          // add\n          h = wh[j];\n          l = wl[j];\n\n          a = l & 0xffff; b = l >>> 16;\n          c = h & 0xffff; d = h >>> 16;\n\n          h = wh[(j+9)%16];\n          l = wl[(j+9)%16];\n\n          a += l & 0xffff; b += l >>> 16;\n          c += h & 0xffff; d += h >>> 16;\n\n          // sigma0\n          th = wh[(j+1)%16];\n          tl = wl[(j+1)%16];\n          h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7);\n          l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7)));\n\n          a += l & 0xffff; b += l >>> 16;\n          c += h & 0xffff; d += h >>> 16;\n\n          // sigma1\n          th = wh[(j+14)%16];\n          tl = wl[(j+14)%16];\n          h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6);\n          l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6)));\n\n          a += l & 0xffff; b += l >>> 16;\n          c += h & 0xffff; d += h >>> 16;\n\n          b += a >>> 16;\n          c += b >>> 16;\n          d += c >>> 16;\n\n          wh[j] = (c & 0xffff) | (d << 16);\n          wl[j] = (a & 0xffff) | (b << 16);\n        }\n      }\n    }\n\n    // add\n    h = ah0;\n    l = al0;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[0];\n    l = hl[0];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[0] = ah0 = (c & 0xffff) | (d << 16);\n    hl[0] = al0 = (a & 0xffff) | (b << 16);\n\n    h = ah1;\n    l = al1;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[1];\n    l = hl[1];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[1] = ah1 = (c & 0xffff) | (d << 16);\n    hl[1] = al1 = (a & 0xffff) | (b << 16);\n\n    h = ah2;\n    l = al2;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[2];\n    l = hl[2];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[2] = ah2 = (c & 0xffff) | (d << 16);\n    hl[2] = al2 = (a & 0xffff) | (b << 16);\n\n    h = ah3;\n    l = al3;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[3];\n    l = hl[3];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[3] = ah3 = (c & 0xffff) | (d << 16);\n    hl[3] = al3 = (a & 0xffff) | (b << 16);\n\n    h = ah4;\n    l = al4;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[4];\n    l = hl[4];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[4] = ah4 = (c & 0xffff) | (d << 16);\n    hl[4] = al4 = (a & 0xffff) | (b << 16);\n\n    h = ah5;\n    l = al5;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[5];\n    l = hl[5];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[5] = ah5 = (c & 0xffff) | (d << 16);\n    hl[5] = al5 = (a & 0xffff) | (b << 16);\n\n    h = ah6;\n    l = al6;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[6];\n    l = hl[6];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[6] = ah6 = (c & 0xffff) | (d << 16);\n    hl[6] = al6 = (a & 0xffff) | (b << 16);\n\n    h = ah7;\n    l = al7;\n\n    a = l & 0xffff; b = l >>> 16;\n    c = h & 0xffff; d = h >>> 16;\n\n    h = hh[7];\n    l = hl[7];\n\n    a += l & 0xffff; b += l >>> 16;\n    c += h & 0xffff; d += h >>> 16;\n\n    b += a >>> 16;\n    c += b >>> 16;\n    d += c >>> 16;\n\n    hh[7] = ah7 = (c & 0xffff) | (d << 16);\n    hl[7] = al7 = (a & 0xffff) | (b << 16);\n\n    pos += 128;\n    n -= 128;\n  }\n\n  return n;\n}\n\nfunction crypto_hash(out, m, n) {\n  var hh = new Int32Array(8),\n      hl = new Int32Array(8),\n      x = new Uint8Array(256),\n      i, b = n;\n\n  hh[0] = 0x6a09e667;\n  hh[1] = 0xbb67ae85;\n  hh[2] = 0x3c6ef372;\n  hh[3] = 0xa54ff53a;\n  hh[4] = 0x510e527f;\n  hh[5] = 0x9b05688c;\n  hh[6] = 0x1f83d9ab;\n  hh[7] = 0x5be0cd19;\n\n  hl[0] = 0xf3bcc908;\n  hl[1] = 0x84caa73b;\n  hl[2] = 0xfe94f82b;\n  hl[3] = 0x5f1d36f1;\n  hl[4] = 0xade682d1;\n  hl[5] = 0x2b3e6c1f;\n  hl[6] = 0xfb41bd6b;\n  hl[7] = 0x137e2179;\n\n  crypto_hashblocks_hl(hh, hl, m, n);\n  n %= 128;\n\n  for (i = 0; i < n; i++) x[i] = m[b-n+i];\n  x[n] = 128;\n\n  n = 256-128*(n<112?1:0);\n  x[n-9] = 0;\n  ts64(x, n-8,  (b / 0x20000000) | 0, b << 3);\n  crypto_hashblocks_hl(hh, hl, x, n);\n\n  for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]);\n\n  return 0;\n}\n\nfunction add(p, q) {\n  var a = gf(), b = gf(), c = gf(),\n      d = gf(), e = gf(), f = gf(),\n      g = gf(), h = gf(), t = gf();\n\n  Z(a, p[1], p[0]);\n  Z(t, q[1], q[0]);\n  M(a, a, t);\n  A(b, p[0], p[1]);\n  A(t, q[0], q[1]);\n  M(b, b, t);\n  M(c, p[3], q[3]);\n  M(c, c, D2);\n  M(d, p[2], q[2]);\n  A(d, d, d);\n  Z(e, b, a);\n  Z(f, d, c);\n  A(g, d, c);\n  A(h, b, a);\n\n  M(p[0], e, f);\n  M(p[1], h, g);\n  M(p[2], g, f);\n  M(p[3], e, h);\n}\n\nfunction cswap(p, q, b) {\n  var i;\n  for (i = 0; i < 4; i++) {\n    sel25519(p[i], q[i], b);\n  }\n}\n\nfunction pack(r, p) {\n  var tx = gf(), ty = gf(), zi = gf();\n  inv25519(zi, p[2]);\n  M(tx, p[0], zi);\n  M(ty, p[1], zi);\n  pack25519(r, ty);\n  r[31] ^= par25519(tx) << 7;\n}\n\nfunction scalarmult(p, q, s) {\n  var b, i;\n  set25519(p[0], gf0);\n  set25519(p[1], gf1);\n  set25519(p[2], gf1);\n  set25519(p[3], gf0);\n  for (i = 255; i >= 0; --i) {\n    b = (s[(i/8)|0] >> (i&7)) & 1;\n    cswap(p, q, b);\n    add(q, p);\n    add(p, p);\n    cswap(p, q, b);\n  }\n}\n\nfunction scalarbase(p, s) {\n  var q = [gf(), gf(), gf(), gf()];\n  set25519(q[0], X);\n  set25519(q[1], Y);\n  set25519(q[2], gf1);\n  M(q[3], X, Y);\n  scalarmult(p, q, s);\n}\n\nfunction crypto_sign_keypair(pk, sk, seeded) {\n  var d = new Uint8Array(64);\n  var p = [gf(), gf(), gf(), gf()];\n  var i;\n\n  if (!seeded) randombytes(sk, 32);\n  crypto_hash(d, sk, 32);\n  d[0] &= 248;\n  d[31] &= 127;\n  d[31] |= 64;\n\n  scalarbase(p, d);\n  pack(pk, p);\n\n  for (i = 0; i < 32; i++) sk[i+32] = pk[i];\n  return 0;\n}\n\nvar L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]);\n\nfunction modL(r, x) {\n  var carry, i, j, k;\n  for (i = 63; i >= 32; --i) {\n    carry = 0;\n    for (j = i - 32, k = i - 12; j < k; ++j) {\n      x[j] += carry - 16 * x[i] * L[j - (i - 32)];\n      carry = Math.floor((x[j] + 128) / 256);\n      x[j] -= carry * 256;\n    }\n    x[j] += carry;\n    x[i] = 0;\n  }\n  carry = 0;\n  for (j = 0; j < 32; j++) {\n    x[j] += carry - (x[31] >> 4) * L[j];\n    carry = x[j] >> 8;\n    x[j] &= 255;\n  }\n  for (j = 0; j < 32; j++) x[j] -= carry * L[j];\n  for (i = 0; i < 32; i++) {\n    x[i+1] += x[i] >> 8;\n    r[i] = x[i] & 255;\n  }\n}\n\nfunction reduce(r) {\n  var x = new Float64Array(64), i;\n  for (i = 0; i < 64; i++) x[i] = r[i];\n  for (i = 0; i < 64; i++) r[i] = 0;\n  modL(r, x);\n}\n\n// Note: difference from C - smlen returned, not passed as argument.\nfunction crypto_sign(sm, m, n, sk) {\n  var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);\n  var i, j, x = new Float64Array(64);\n  var p = [gf(), gf(), gf(), gf()];\n\n  crypto_hash(d, sk, 32);\n  d[0] &= 248;\n  d[31] &= 127;\n  d[31] |= 64;\n\n  var smlen = n + 64;\n  for (i = 0; i < n; i++) sm[64 + i] = m[i];\n  for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];\n\n  crypto_hash(r, sm.subarray(32), n+32);\n  reduce(r);\n  scalarbase(p, r);\n  pack(sm, p);\n\n  for (i = 32; i < 64; i++) sm[i] = sk[i];\n  crypto_hash(h, sm, n + 64);\n  reduce(h);\n\n  for (i = 0; i < 64; i++) x[i] = 0;\n  for (i = 0; i < 32; i++) x[i] = r[i];\n  for (i = 0; i < 32; i++) {\n    for (j = 0; j < 32; j++) {\n      x[i+j] += h[i] * d[j];\n    }\n  }\n\n  modL(sm.subarray(32), x);\n  return smlen;\n}\n\nfunction unpackneg(r, p) {\n  var t = gf(), chk = gf(), num = gf(),\n      den = gf(), den2 = gf(), den4 = gf(),\n      den6 = gf();\n\n  set25519(r[2], gf1);\n  unpack25519(r[1], p);\n  S(num, r[1]);\n  M(den, num, D);\n  Z(num, num, r[2]);\n  A(den, r[2], den);\n\n  S(den2, den);\n  S(den4, den2);\n  M(den6, den4, den2);\n  M(t, den6, num);\n  M(t, t, den);\n\n  pow2523(t, t);\n  M(t, t, num);\n  M(t, t, den);\n  M(t, t, den);\n  M(r[0], t, den);\n\n  S(chk, r[0]);\n  M(chk, chk, den);\n  if (neq25519(chk, num)) M(r[0], r[0], I);\n\n  S(chk, r[0]);\n  M(chk, chk, den);\n  if (neq25519(chk, num)) return -1;\n\n  if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);\n\n  M(r[3], r[0], r[1]);\n  return 0;\n}\n\nfunction crypto_sign_open(m, sm, n, pk) {\n  var i;\n  var t = new Uint8Array(32), h = new Uint8Array(64);\n  var p = [gf(), gf(), gf(), gf()],\n      q = [gf(), gf(), gf(), gf()];\n\n  if (n < 64) return -1;\n\n  if (unpackneg(q, pk)) return -1;\n\n  for (i = 0; i < n; i++) m[i] = sm[i];\n  for (i = 0; i < 32; i++) m[i+32] = pk[i];\n  crypto_hash(h, m, n);\n  reduce(h);\n  scalarmult(p, q, h);\n\n  scalarbase(q, sm.subarray(32));\n  add(p, q);\n  pack(t, p);\n\n  n -= 64;\n  if (crypto_verify_32(sm, 0, t, 0)) {\n    for (i = 0; i < n; i++) m[i] = 0;\n    return -1;\n  }\n\n  for (i = 0; i < n; i++) m[i] = sm[i + 64];\n  return n;\n}\n\nvar crypto_secretbox_KEYBYTES = 32,\n    crypto_secretbox_NONCEBYTES = 24,\n    crypto_secretbox_ZEROBYTES = 32,\n    crypto_secretbox_BOXZEROBYTES = 16,\n    crypto_scalarmult_BYTES = 32,\n    crypto_scalarmult_SCALARBYTES = 32,\n    crypto_box_PUBLICKEYBYTES = 32,\n    crypto_box_SECRETKEYBYTES = 32,\n    crypto_box_BEFORENMBYTES = 32,\n    crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,\n    crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,\n    crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,\n    crypto_sign_BYTES = 64,\n    crypto_sign_PUBLICKEYBYTES = 32,\n    crypto_sign_SECRETKEYBYTES = 64,\n    crypto_sign_SEEDBYTES = 32,\n    crypto_hash_BYTES = 64;\n\nnacl.lowlevel = {\n  crypto_core_hsalsa20: crypto_core_hsalsa20,\n  crypto_stream_xor: crypto_stream_xor,\n  crypto_stream: crypto_stream,\n  crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,\n  crypto_stream_salsa20: crypto_stream_salsa20,\n  crypto_onetimeauth: crypto_onetimeauth,\n  crypto_onetimeauth_verify: crypto_onetimeauth_verify,\n  crypto_verify_16: crypto_verify_16,\n  crypto_verify_32: crypto_verify_32,\n  crypto_secretbox: crypto_secretbox,\n  crypto_secretbox_open: crypto_secretbox_open,\n  crypto_scalarmult: crypto_scalarmult,\n  crypto_scalarmult_base: crypto_scalarmult_base,\n  crypto_box_beforenm: crypto_box_beforenm,\n  crypto_box_afternm: crypto_box_afternm,\n  crypto_box: crypto_box,\n  crypto_box_open: crypto_box_open,\n  crypto_box_keypair: crypto_box_keypair,\n  crypto_hash: crypto_hash,\n  crypto_sign: crypto_sign,\n  crypto_sign_keypair: crypto_sign_keypair,\n  crypto_sign_open: crypto_sign_open,\n\n  crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,\n  crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,\n  crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,\n  crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,\n  crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,\n  crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,\n  crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,\n  crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,\n  crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,\n  crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,\n  crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,\n  crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,\n  crypto_sign_BYTES: crypto_sign_BYTES,\n  crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,\n  crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,\n  crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,\n  crypto_hash_BYTES: crypto_hash_BYTES,\n\n  gf: gf,\n  D: D,\n  L: L,\n  pack25519: pack25519,\n  unpack25519: unpack25519,\n  M: M,\n  A: A,\n  S: S,\n  Z: Z,\n  pow2523: pow2523,\n  add: add,\n  set25519: set25519,\n  modL: modL,\n  scalarmult: scalarmult,\n  scalarbase: scalarbase,\n};\n\n/* High-level API */\n\nfunction checkLengths(k, n) {\n  if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');\n  if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size');\n}\n\nfunction checkBoxLengths(pk, sk) {\n  if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size');\n  if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size');\n}\n\nfunction checkArrayTypes() {\n  for (var i = 0; i < arguments.length; i++) {\n    if (!(arguments[i] instanceof Uint8Array))\n      throw new TypeError('unexpected type, use Uint8Array');\n  }\n}\n\nfunction cleanup(arr) {\n  for (var i = 0; i < arr.length; i++) arr[i] = 0;\n}\n\nnacl.randomBytes = function(n) {\n  var b = new Uint8Array(n);\n  randombytes(b, n);\n  return b;\n};\n\nnacl.secretbox = function(msg, nonce, key) {\n  checkArrayTypes(msg, nonce, key);\n  checkLengths(key, nonce);\n  var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);\n  var c = new Uint8Array(m.length);\n  for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];\n  crypto_secretbox(c, m, m.length, nonce, key);\n  return c.subarray(crypto_secretbox_BOXZEROBYTES);\n};\n\nnacl.secretbox.open = function(box, nonce, key) {\n  checkArrayTypes(box, nonce, key);\n  checkLengths(key, nonce);\n  var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);\n  var m = new Uint8Array(c.length);\n  for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];\n  if (c.length < 32) return null;\n  if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;\n  return m.subarray(crypto_secretbox_ZEROBYTES);\n};\n\nnacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;\nnacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;\nnacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;\n\nnacl.scalarMult = function(n, p) {\n  checkArrayTypes(n, p);\n  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');\n  if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');\n  var q = new Uint8Array(crypto_scalarmult_BYTES);\n  crypto_scalarmult(q, n, p);\n  return q;\n};\n\nnacl.scalarMult.base = function(n) {\n  checkArrayTypes(n);\n  if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');\n  var q = new Uint8Array(crypto_scalarmult_BYTES);\n  crypto_scalarmult_base(q, n);\n  return q;\n};\n\nnacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;\nnacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;\n\nnacl.box = function(msg, nonce, publicKey, secretKey) {\n  var k = nacl.box.before(publicKey, secretKey);\n  return nacl.secretbox(msg, nonce, k);\n};\n\nnacl.box.before = function(publicKey, secretKey) {\n  checkArrayTypes(publicKey, secretKey);\n  checkBoxLengths(publicKey, secretKey);\n  var k = new Uint8Array(crypto_box_BEFORENMBYTES);\n  crypto_box_beforenm(k, publicKey, secretKey);\n  return k;\n};\n\nnacl.box.after = nacl.secretbox;\n\nnacl.box.open = function(msg, nonce, publicKey, secretKey) {\n  var k = nacl.box.before(publicKey, secretKey);\n  return nacl.secretbox.open(msg, nonce, k);\n};\n\nnacl.box.open.after = nacl.secretbox.open;\n\nnacl.box.keyPair = function() {\n  var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);\n  var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);\n  crypto_box_keypair(pk, sk);\n  return {publicKey: pk, secretKey: sk};\n};\n\nnacl.box.keyPair.fromSecretKey = function(secretKey) {\n  checkArrayTypes(secretKey);\n  if (secretKey.length !== crypto_box_SECRETKEYBYTES)\n    throw new Error('bad secret key size');\n  var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);\n  crypto_scalarmult_base(pk, secretKey);\n  return {publicKey: pk, secretKey: new Uint8Array(secretKey)};\n};\n\nnacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;\nnacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;\nnacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;\nnacl.box.nonceLength = crypto_box_NONCEBYTES;\nnacl.box.overheadLength = nacl.secretbox.overheadLength;\n\nnacl.sign = function(msg, secretKey) {\n  checkArrayTypes(msg, secretKey);\n  if (secretKey.length !== crypto_sign_SECRETKEYBYTES)\n    throw new Error('bad secret key size');\n  var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);\n  crypto_sign(signedMsg, msg, msg.length, secretKey);\n  return signedMsg;\n};\n\nnacl.sign.open = function(signedMsg, publicKey) {\n  checkArrayTypes(signedMsg, publicKey);\n  if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)\n    throw new Error('bad public key size');\n  var tmp = new Uint8Array(signedMsg.length);\n  var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);\n  if (mlen < 0) return null;\n  var m = new Uint8Array(mlen);\n  for (var i = 0; i < m.length; i++) m[i] = tmp[i];\n  return m;\n};\n\nnacl.sign.detached = function(msg, secretKey) {\n  var signedMsg = nacl.sign(msg, secretKey);\n  var sig = new Uint8Array(crypto_sign_BYTES);\n  for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];\n  return sig;\n};\n\nnacl.sign.detached.verify = function(msg, sig, publicKey) {\n  checkArrayTypes(msg, sig, publicKey);\n  if (sig.length !== crypto_sign_BYTES)\n    throw new Error('bad signature size');\n  if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)\n    throw new Error('bad public key size');\n  var sm = new Uint8Array(crypto_sign_BYTES + msg.length);\n  var m = new Uint8Array(crypto_sign_BYTES + msg.length);\n  var i;\n  for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];\n  for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];\n  return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);\n};\n\nnacl.sign.keyPair = function() {\n  var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);\n  var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);\n  crypto_sign_keypair(pk, sk);\n  return {publicKey: pk, secretKey: sk};\n};\n\nnacl.sign.keyPair.fromSecretKey = function(secretKey) {\n  checkArrayTypes(secretKey);\n  if (secretKey.length !== crypto_sign_SECRETKEYBYTES)\n    throw new Error('bad secret key size');\n  var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);\n  for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];\n  return {publicKey: pk, secretKey: new Uint8Array(secretKey)};\n};\n\nnacl.sign.keyPair.fromSeed = function(seed) {\n  checkArrayTypes(seed);\n  if (seed.length !== crypto_sign_SEEDBYTES)\n    throw new Error('bad seed size');\n  var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);\n  var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);\n  for (var i = 0; i < 32; i++) sk[i] = seed[i];\n  crypto_sign_keypair(pk, sk, true);\n  return {publicKey: pk, secretKey: sk};\n};\n\nnacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;\nnacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;\nnacl.sign.seedLength = crypto_sign_SEEDBYTES;\nnacl.sign.signatureLength = crypto_sign_BYTES;\n\nnacl.hash = function(msg) {\n  checkArrayTypes(msg);\n  var h = new Uint8Array(crypto_hash_BYTES);\n  crypto_hash(h, msg, msg.length);\n  return h;\n};\n\nnacl.hash.hashLength = crypto_hash_BYTES;\n\nnacl.verify = function(x, y) {\n  checkArrayTypes(x, y);\n  // Zero length arguments are considered not equal.\n  if (x.length === 0 || y.length === 0) return false;\n  if (x.length !== y.length) return false;\n  return (vn(x, 0, y, 0, x.length) === 0) ? true : false;\n};\n\nnacl.setPRNG = function(fn) {\n  randombytes = fn;\n};\n\n(function() {\n  // Initialize PRNG if environment provides CSPRNG.\n  // If not, methods calling randombytes will throw.\n  var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;\n  if (crypto && crypto.getRandomValues) {\n    // Browsers.\n    var QUOTA = 65536;\n    nacl.setPRNG(function(x, n) {\n      var i, v = new Uint8Array(n);\n      for (i = 0; i < n; i += QUOTA) {\n        crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));\n      }\n      for (i = 0; i < n; i++) x[i] = v[i];\n      cleanup(v);\n    });\n  } else if (typeof require !== 'undefined') {\n    // Node.js.\n    crypto = require('crypto');\n    if (crypto && crypto.randomBytes) {\n      nacl.setPRNG(function(x, n) {\n        var i, v = crypto.randomBytes(n);\n        for (i = 0; i < n; i++) x[i] = v[i];\n        cleanup(v);\n      });\n    }\n  }\n})();\n\n})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));\n","/**\n * Cryptographic utilities for hypha-rpc end-to-end encrypted service calls.\n *\n * Uses tweetnacl (libsodium-compatible) for:\n * - Curve25519 ECDH + XSalsa20-Poly1305 authenticated encryption (crypto_box)\n *\n * All output is interoperable with the Python PyNaCl package.\n *\n * tweetnacl is an optional dependency. If it is not installed, the hex-conversion\n * helpers still work, but encryption/decryption functions will throw a clear error.\n *\n * @module crypto\n */\n\nlet _nacl = null;\n\nfunction _requireCrypto() {\n  if (_nacl) return _nacl;\n  try {\n    // Use require() for synchronous loading; works in both bundled and Node.js contexts\n    _nacl = require(\"tweetnacl\");\n    // Handle ES module default export\n    if (_nacl.default) _nacl = _nacl.default;\n    return _nacl;\n  } catch (e) {\n    throw new Error(\n      \"The 'tweetnacl' package is required for encryption. \" +\n        \"Install it with: npm install tweetnacl\",\n    );\n  }\n}\n\n/**\n * Convert a 32-byte public key to a 64-character hex string.\n * @param {Uint8Array} publicKeyBytes - 32-byte raw public key.\n * @returns {string} 64-character hex string.\n */\nexport function publicKeyToHex(publicKeyBytes) {\n  return Array.from(publicKeyBytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n    \"\",\n  );\n}\n\n/**\n * Convert a 64-character hex string to a 32-byte public key.\n * @param {string} hexString - 64-character hex string.\n * @returns {Uint8Array} 32-byte raw public key.\n */\nexport function publicKeyFromHex(hexString) {\n  const bytes = new Uint8Array(hexString.length / 2);\n  for (let i = 0; i < bytes.length; i++) {\n    bytes[i] = parseInt(hexString.substr(i * 2, 2), 16);\n  }\n  return bytes;\n}\n\n// --- Curve25519 + XSalsa20-Poly1305 Encryption (crypto_box) ---\n\n/**\n * Generate a Curve25519 keypair for authenticated encryption.\n * @returns {Promise<{privateKey: Uint8Array, publicKey: Uint8Array}>}\n *   Raw 32-byte private key and 32-byte public key.\n */\nexport async function generateEncryptionKeypair() {\n  const nacl = _requireCrypto();\n  const kp = nacl.box.keyPair();\n  return { privateKey: kp.secretKey, publicKey: kp.publicKey };\n}\n\n/**\n * Encrypt plaintext using crypto_box (Curve25519 + XSalsa20-Poly1305).\n * @param {Uint8Array} myPrivateBytes - 32-byte raw Curve25519 private key.\n * @param {Uint8Array} theirPublicBytes - 32-byte raw Curve25519 public key.\n * @param {Uint8Array} plaintext - Data to encrypt.\n * @returns {Promise<{nonce: Uint8Array, ciphertext: Uint8Array}>}\n *   nonce is 24 bytes; ciphertext includes 16-byte Poly1305 auth tag.\n */\nexport async function encryptPayload(myPrivateBytes, theirPublicBytes, plaintext) {\n  const nacl = _requireCrypto();\n  const nonce = nacl.randomBytes(nacl.box.nonceLength); // 24 bytes\n  const ciphertext = nacl.box(plaintext, nonce, theirPublicBytes, myPrivateBytes);\n  return { nonce, ciphertext };\n}\n\n/**\n * Decrypt ciphertext using crypto_box (Curve25519 + XSalsa20-Poly1305).\n * @param {Uint8Array} myPrivateBytes - 32-byte raw Curve25519 private key.\n * @param {Uint8Array} theirPublicBytes - 32-byte raw Curve25519 public key.\n * @param {Uint8Array} nonce - 24-byte nonce used during encryption.\n * @param {Uint8Array} ciphertext - Data to decrypt (includes 16-byte Poly1305 auth tag).\n * @returns {Promise<Uint8Array>} Decrypted plaintext.\n * @throws {Error} If decryption/authentication fails.\n */\nexport async function decryptPayload(myPrivateBytes, theirPublicBytes, nonce, ciphertext) {\n  const nacl = _requireCrypto();\n  const plaintext = nacl.box.open(ciphertext, nonce, theirPublicBytes, myPrivateBytes);\n  if (plaintext === null) {\n    throw new Error(\"Decryption failed\");\n  }\n  return plaintext;\n}\n","/**\n * HTTP Streaming RPC Client for Hypha.\n *\n * This module provides HTTP-based RPC transport as an alternative to WebSocket.\n * It uses:\n * - HTTP GET with streaming (msgpack) for server-to-client messages\n * - HTTP POST for client-to-server messages\n *\n * This is more resilient to network issues than WebSocket because:\n * 1. Each POST request is independent (stateless)\n * 2. GET stream can be easily reconnected\n * 3. Works through more proxies and firewalls\n *\n * ## Performance Optimizations\n *\n * Modern browsers automatically provide optimal HTTP performance:\n *\n * ### Automatic HTTP/2 Support\n * - Browsers negotiate HTTP/2 when server supports it\n * - Multiplexing: Multiple requests over single TCP connection\n * - Header compression: HPACK reduces overhead\n * - Server push: Pre-emptive resource delivery\n *\n * ### Connection Pooling\n * - Browsers maintain connection pools per origin\n * - Automatic keep-alive for HTTP/1.1\n * - Connection reuse reduces latency\n * - No manual configuration needed\n *\n * ### Fetch API Optimizations\n * - `keepalive: true` flag ensures connection reuse\n * - Streaming responses with backpressure handling\n * - Efficient binary data transfer (ArrayBuffer/Uint8Array)\n *\n * ### Server-Side Configuration\n * For optimal performance, ensure server has:\n * - Keep-alive timeout: 300s (matches typical browser defaults) ✓ CONFIGURED\n * - Fast compression: gzip level 1 (2-5x faster than level 5) ✓ CONFIGURED\n * - Uvicorn connection limits optimized ✓ CONFIGURED\n *\n * ### HTTP/2 Support\n * - Uvicorn does NOT natively support HTTP/2 (as of 2026)\n * - In production, use nginx/Caddy/ALB as reverse proxy for HTTP/2\n * - Reverse proxy handles HTTP/2 ↔ HTTP/1.1 translation\n * - Browsers automatically use HTTP/2 when reverse proxy supports it\n * - Current HTTP/1.1 implementation is already optimal\n *\n * ### Performance Results\n * With properly configured server, HTTP transport achieves:\n * - 10-12 MB/s throughput for large payloads (4-15 MB)\n * - 2-3x faster than before optimization\n * - 3-28x faster than WebSocket for data transfer\n * - 31% improvement in connection reuse efficiency\n */\n\nimport { RPC } from \"./rpc.js\";\nimport { assert, randId, waitFor, parseServiceUrl } from \"./utils/index.js\";\nimport { schemaFunction } from \"./utils/schema.js\";\nimport {\n  decode as msgpackDecode,\n  encode as msgpackEncode,\n} from \"@msgpack/msgpack\";\n\nconst MAX_RETRY = 1000000;\n\n/**\n * Extract workspace from a JWT token's scope claim.\n *\n * JWT tokens issued by the Hypha server contain a `scope` field with\n * entries like \"wid:<workspace>\" indicating the current workspace.\n * This function decodes the JWT payload (base64url-encoded JSON) to\n * extract the workspace without requiring any crypto library.\n *\n * @param {string} token - JWT token string\n * @returns {string|null} Workspace name or null if not found\n */\nfunction extractWorkspaceFromToken(token) {\n  if (!token) return null;\n  try {\n    const parts = token.split(\".\");\n    if (parts.length !== 3) return null;\n    // Decode the payload (second part) from base64url\n    let payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n    // Pad to multiple of 4\n    while (payload.length % 4) payload += \"=\";\n    const decoded = JSON.parse(atob(payload));\n    const scope = decoded.scope;\n    if (typeof scope !== \"string\") return null;\n    // Look for \"wid:<workspace>\" in the scope string\n    const match = scope.match(/(?:^|\\s)wid:(\\S+)/);\n    return match ? match[1] : null;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * HTTP Streaming RPC Connection.\n *\n * Uses HTTP GET with streaming for receiving messages and HTTP POST for sending messages.\n * Uses msgpack binary format with length-prefixed frames for efficient binary data support.\n */\nexport class HTTPStreamingRPCConnection {\n  /**\n   * Initialize HTTP streaming connection.\n   *\n   * @param {string} server_url - The server URL (http:// or https://)\n   * @param {string} client_id - Unique client identifier\n   * @param {string} workspace - Target workspace (optional)\n   * @param {string} token - Authentication token (optional)\n   * @param {string} reconnection_token - Token for reconnection (optional)\n   * @param {number} timeout - Request timeout in seconds (default: 60)\n   * @param {number} token_refresh_interval - Interval for token refresh (default: 2 hours)\n   */\n  constructor(\n    server_url,\n    client_id,\n    workspace = null,\n    token = null,\n    reconnection_token = null,\n    timeout = 60,\n    token_refresh_interval = 2 * 60 * 60,\n  ) {\n    assert(server_url && client_id, \"server_url and client_id are required\");\n    this._server_url = server_url.replace(/\\/$/, \"\");\n    this._client_id = client_id;\n    this._workspace = workspace;\n    this._token = token;\n    this._reconnection_token = reconnection_token;\n    this._timeout = timeout;\n    this._token_refresh_interval = token_refresh_interval;\n\n    // If no workspace specified but token provided, extract workspace from token\n    if (!this._workspace && this._token) {\n      this._workspace = extractWorkspaceFromToken(this._token);\n    }\n\n    this._handle_message = null;\n    this._handle_disconnected = null;\n    this._handle_connected = null;\n\n    this._closed = false;\n    this._enable_reconnect = false;\n    this._is_reconnection = false;\n    this.connection_info = null;\n    this.manager_id = null;\n\n    this._abort_controller = null;\n    this._refresh_token_task = null;\n  }\n\n  /**\n   * Register message handler.\n   */\n  on_message(handler) {\n    assert(handler, \"handler is required\");\n    this._handle_message = handler;\n  }\n\n  /**\n   * Register disconnection handler.\n   */\n  on_disconnected(handler) {\n    this._handle_disconnected = handler;\n  }\n\n  /**\n   * Register connection handler.\n   */\n  on_connected(handler) {\n    this._handle_connected = handler;\n  }\n\n  /**\n   * Get HTTP headers with authentication.\n   *\n   * @param {boolean} for_stream - If true, set Accept header for msgpack stream\n   * @returns {Object} Headers object\n   */\n  _get_headers(for_stream = false) {\n    const headers = {\n      \"Content-Type\": \"application/msgpack\",\n    };\n    if (for_stream) {\n      headers[\"Accept\"] = \"application/x-msgpack-stream\";\n    }\n    if (this._token) {\n      headers[\"Authorization\"] = `Bearer ${this._token}`;\n    }\n    return headers;\n  }\n\n  /**\n   * Open the streaming connection.\n   */\n  async open() {\n    console.info(`Opening HTTP streaming connection to ${this._server_url}`);\n\n    // Build stream URL using the workspace-less /rpc endpoint.\n    // Workspace is passed as a query parameter when available.\n    // On first connection, workspace may be null (server assigns one via connection_info).\n    let stream_url = `${this._server_url}/rpc?client_id=${this._client_id}`;\n    if (this._workspace) {\n      stream_url += `&workspace=${encodeURIComponent(this._workspace)}`;\n    }\n\n    // Start streaming in background\n    this._startStreamLoop(stream_url);\n\n    // Wait for connection info (first message)\n    const start = Date.now();\n    while (this.connection_info === null) {\n      await new Promise((resolve) => setTimeout(resolve, 100));\n      if (Date.now() - start > this._timeout * 1000) {\n        throw new Error(\"Timeout waiting for connection info\");\n      }\n      if (this._closed) {\n        throw new Error(\"Connection closed during setup\");\n      }\n    }\n\n    this.manager_id = this.connection_info.manager_id;\n    if (this._workspace) {\n      const actual_ws = this.connection_info.workspace;\n      if (actual_ws !== this._workspace) {\n        throw new Error(\n          `Connected to wrong workspace: ${actual_ws}, expected: ${this._workspace}`,\n        );\n      }\n    }\n    this._workspace = this.connection_info.workspace;\n\n    if (this.connection_info.reconnection_token) {\n      this._reconnection_token = this.connection_info.reconnection_token;\n    }\n\n    // Adjust token refresh interval based on server's token lifetime\n    if (this.connection_info.reconnection_token_life_time) {\n      const token_life_time = this.connection_info.reconnection_token_life_time;\n      if (this._token_refresh_interval > token_life_time / 1.5) {\n        console.warn(\n          `Token refresh interval (${this._token_refresh_interval}s) is too long, ` +\n            `adjusting to ${(token_life_time / 1.5).toFixed(0)}s based on token lifetime`,\n        );\n        this._token_refresh_interval = token_life_time / 1.5;\n      }\n    }\n\n    console.info(\n      `HTTP streaming connected to workspace: ${this._workspace}, ` +\n        `manager_id: ${this.manager_id}`,\n    );\n\n    // Start token refresh\n    if (this._token_refresh_interval > 0) {\n      this._startTokenRefresh();\n    }\n\n    if (this._handle_connected) {\n      await this._handle_connected(this.connection_info);\n    }\n\n    return this.connection_info;\n  }\n\n  /**\n   * Start periodic token refresh via POST.\n   */\n  _startTokenRefresh() {\n    // Clear existing refresh if any\n    if (this._refresh_token_task) {\n      clearInterval(this._refresh_token_task);\n    }\n\n    // Initial delay of 2s, then periodic refresh\n    setTimeout(() => {\n      this._sendRefreshToken();\n      this._refresh_token_task = setInterval(() => {\n        this._sendRefreshToken();\n      }, this._token_refresh_interval * 1000);\n    }, 2000);\n  }\n\n  /**\n   * Send a token refresh request via POST.\n   */\n  async _sendRefreshToken() {\n    if (this._closed) return;\n    try {\n      // After open(), _workspace is always set from connection_info\n      let url = `${this._server_url}/rpc?client_id=${this._client_id}`;\n      if (this._workspace) {\n        url += `&workspace=${encodeURIComponent(this._workspace)}`;\n      }\n      const body = msgpackEncode({ type: \"refresh_token\" });\n      const response = await fetch(url, {\n        method: \"POST\",\n        headers: this._get_headers(false),\n        body: body,\n      });\n      if (response.ok) {\n        // console.debug(\"Token refresh requested successfully\");\n      } else {\n        console.warn(`Token refresh request failed: ${response.status}`);\n      }\n    } catch (e) {\n      console.warn(`Failed to send refresh token request: ${e.message}`);\n    }\n  }\n\n  /**\n   * Start the streaming loop.\n   *\n   * OPTIMIZATION: Modern browsers automatically:\n   * - Negotiate HTTP/2 when server supports it\n   * - Use connection pooling for multiple requests to same origin\n   * - Handle keep-alive for persistent connections\n   * - Stream responses efficiently with backpressure handling\n   */\n  async _startStreamLoop(url) {\n    this._enable_reconnect = true;\n    this._closed = false;\n    let retry = 0;\n    this._is_reconnection = false;\n\n    while (!this._closed && retry < MAX_RETRY) {\n      try {\n        // Update URL with current workspace (set from connection_info after initial open).\n        // Workspace is passed as a query parameter when available.\n        let stream_url = `${this._server_url}/rpc?client_id=${this._client_id}`;\n        if (this._workspace) {\n          stream_url += `&workspace=${encodeURIComponent(this._workspace)}`;\n        }\n        if (this._reconnection_token) {\n          stream_url += `&reconnection_token=${encodeURIComponent(this._reconnection_token)}`;\n        }\n\n        // OPTIMIZATION: Browser fetch automatically streams responses\n        // and negotiates HTTP/2 when available for better performance\n        this._abort_controller = new AbortController();\n        const response = await fetch(stream_url, {\n          method: \"GET\",\n          headers: this._get_headers(true),\n          signal: this._abort_controller.signal,\n        });\n\n        if (!response.ok) {\n          const error_text = await response.text();\n          throw new Error(\n            `Stream failed with status ${response.status}: ${error_text}`,\n          );\n        }\n\n        retry = 0; // Reset retry counter on successful connection\n\n        // Process binary msgpack stream with 4-byte length prefix\n        await this._processMsgpackStream(response);\n      } catch (error) {\n        if (this._closed) break;\n        console.error(`Connection error: ${error.message}`);\n\n        if (!this._enable_reconnect) {\n          break;\n        }\n      }\n\n      // After the first connection attempt, all subsequent ones are reconnections\n      this._is_reconnection = true;\n\n      // Reconnection logic\n      if (!this._closed && this._enable_reconnect) {\n        retry += 1;\n        // Exponential backoff with max 60 seconds\n        const delay = Math.min(Math.pow(2, Math.min(retry, 6)), 60);\n        console.warn(\n          `Stream disconnected, reconnecting in ${delay.toFixed(1)}s (attempt ${retry})`,\n        );\n        await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n      } else {\n        break;\n      }\n    }\n\n    if (!this._closed && this._handle_disconnected) {\n      this._handle_disconnected(\"Stream ended\");\n    }\n  }\n\n  /**\n   * Check if frame data is a control message and decode it.\n   *\n   * Control messages vs RPC messages:\n   * - Control messages: Single msgpack object with \"type\" field (connection_info, ping, etc.)\n   * - RPC messages: May contain multiple concatenated msgpack objects (main message + extra data)\n   *\n   * We only need to decode the first object to check if it's a control message.\n   * RPC messages are passed as raw bytes to the handler.\n   *\n   * @param {Uint8Array} frame_data - The msgpack frame data\n   * @returns {Object|null} Decoded control message or null\n   */\n  _tryDecodeControlMessage(frame_data) {\n    try {\n      // Decode the first msgpack object in the frame\n      const decoded = msgpackDecode(frame_data);\n\n      // Control messages are simple objects with a \"type\" field\n      if (typeof decoded === \"object\" && decoded !== null && decoded.type) {\n        const controlTypes = [\n          \"connection_info\",\n          \"ping\",\n          \"pong\",\n          \"reconnection_token\",\n          \"error\",\n        ];\n        if (controlTypes.includes(decoded.type)) {\n          return decoded;\n        }\n      }\n\n      // Not a control message\n      return null;\n    } catch {\n      // Decode failed - this is an RPC message\n      return null;\n    }\n  }\n\n  /**\n   * Process msgpack stream with 4-byte length prefix.\n   *\n   * Includes a read timeout to detect dead connections. The Hypha server\n   * sends pings every ~30s, so if no data arrives within READ_TIMEOUT_MS,\n   * the connection is considered dead and the stream is cancelled to\n   * trigger reconnection.\n   */\n  async _processMsgpackStream(response) {\n    const reader = response.body.getReader();\n    // Expose the reader so external code (e.g. daemon heartbeat) can cancel it\n    this._reader = reader;\n    // Growing buffer to avoid O(n^2) re-allocation on every chunk\n    let buffer = new Uint8Array(4096);\n    let bufferLen = 0;\n\n    // Read timeout: server sends pings every ~30s, so 120s = 4 missed pings = dead\n    const READ_TIMEOUT_MS = 120_000;\n\n    while (!this._closed) {\n      let readResult;\n      let timeoutId;\n      try {\n        readResult = await Promise.race([\n          reader.read(),\n          new Promise((_, reject) => {\n            timeoutId = setTimeout(\n              () => reject(new Error(\"Stream read timeout (no data for 120s)\")),\n              READ_TIMEOUT_MS,\n            );\n          }),\n        ]);\n        clearTimeout(timeoutId);\n      } catch (error) {\n        clearTimeout(timeoutId);\n        console.warn(`Stream read error: ${error.message}`);\n        try {\n          reader.cancel();\n        } catch {}\n        break;\n      }\n\n      const { done, value } = readResult;\n\n      if (done) break;\n\n      // Grow buffer if needed (double size until it fits)\n      const needed = bufferLen + value.length;\n      if (needed > buffer.length) {\n        let newSize = buffer.length;\n        while (newSize < needed) newSize *= 2;\n        const grown = new Uint8Array(newSize);\n        grown.set(buffer.subarray(0, bufferLen));\n        buffer = grown;\n      }\n      buffer.set(value, bufferLen);\n      bufferLen += value.length;\n\n      // Process complete frames from buffer\n      let offset = 0;\n      while (bufferLen - offset >= 4) {\n        // Read 4-byte length prefix (big-endian)\n        const length =\n          (buffer[offset] << 24) |\n          (buffer[offset + 1] << 16) |\n          (buffer[offset + 2] << 8) |\n          buffer[offset + 3];\n\n        if (bufferLen - offset < 4 + length) {\n          // Incomplete frame, wait for more data\n          break;\n        }\n\n        // Extract the frame (slice creates a copy, which is needed since buffer is reused)\n        const frame_data = buffer.slice(offset + 4, offset + 4 + length);\n        offset += 4 + length;\n\n        // Try to decode as control message first\n        const controlMsg = this._tryDecodeControlMessage(frame_data);\n        if (controlMsg) {\n          const msg_type = controlMsg.type;\n          if (msg_type === \"connection_info\") {\n            this.connection_info = controlMsg;\n            // On reconnection, update state and notify RPC layer.\n            // Run as a non-blocking task so the stream can continue\n            // processing incoming RPC responses (the reconnection\n            // handler sends RPC calls that need stream responses).\n            if (this._is_reconnection) {\n              this._handleReconnection(controlMsg).catch((err) => {\n                console.error(`Reconnection handling failed: ${err.message}`);\n              });\n            }\n            continue;\n          } else if (msg_type === \"ping\" || msg_type === \"pong\") {\n            continue;\n          } else if (msg_type === \"reconnection_token\") {\n            this._reconnection_token = controlMsg.reconnection_token;\n            continue;\n          } else if (msg_type === \"error\") {\n            console.error(`Server error: ${controlMsg.message}`);\n            continue;\n          }\n        }\n\n        // For RPC messages (or unrecognized control messages), pass raw frame data to handler\n        if (this._handle_message) {\n          try {\n            await this._handle_message(frame_data);\n          } catch (error) {\n            console.error(`Error in message handler: ${error.message}`);\n          }\n        }\n      }\n      // Compact: shift remaining data to the front of the buffer\n      if (offset > 0) {\n        const remaining = bufferLen - offset;\n        if (remaining > 0) {\n          buffer.copyWithin(0, offset, bufferLen);\n        }\n        bufferLen = remaining;\n      }\n    }\n\n    this._reader = null;\n  }\n\n  /**\n   * Handle reconnection: update state and notify RPC layer.\n   */\n  async _handleReconnection(connection_info) {\n    this.manager_id = connection_info.manager_id;\n    this._workspace = connection_info.workspace;\n\n    if (connection_info.reconnection_token) {\n      this._reconnection_token = connection_info.reconnection_token;\n    }\n\n    // Adjust token refresh interval if needed\n    if (connection_info.reconnection_token_life_time) {\n      const token_life_time = connection_info.reconnection_token_life_time;\n      if (this._token_refresh_interval > token_life_time / 1.5) {\n        this._token_refresh_interval = token_life_time / 1.5;\n      }\n    }\n\n    console.warn(\n      `Stream reconnected to workspace: ${this._workspace}, ` +\n        `manager_id: ${this.manager_id}`,\n    );\n\n    // Notify RPC layer so it can re-register services\n    if (this._handle_connected) {\n      await this._handle_connected(this.connection_info);\n    }\n\n    // Wait a short time for services to be re-registered\n    await new Promise((resolve) => setTimeout(resolve, 500));\n  }\n\n  /**\n   * Send a message to the server via HTTP POST.\n   *\n   * OPTIMIZATION: Uses keepalive flag for connection reuse.\n   * Modern browsers automatically:\n   * - Use HTTP/2 when available (multiplexing, header compression)\n   * - Manage connection pooling with HTTP/1.1 keep-alive\n   * - Reuse connections for same-origin requests\n   */\n  async emit_message(data) {\n    if (this._closed) {\n      throw new Error(\"Connection is closed\");\n    }\n\n    // Build POST URL using the workspace-less /rpc endpoint.\n    // Workspace is passed as a query parameter when available.\n    if (!this._workspace) {\n      throw new Error(\"Workspace not set - connection not established\");\n    }\n    let post_url = `${this._server_url}/rpc?client_id=${this._client_id}&workspace=${encodeURIComponent(this._workspace)}`;\n\n    // Ensure data is Uint8Array\n    const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n\n    // Retry logic to handle transient issues such as load balancer\n    // routing POST requests to a different server instance than the GET stream\n    const maxRetries = 3;\n    for (let attempt = 0; attempt < maxRetries; attempt++) {\n      try {\n        // Note: keepalive has a 64KB body size limit in browsers, so only use\n        // it for small payloads. For large payloads, skip keepalive.\n        const useKeepalive = body.length < 60000;\n        const response = await fetch(post_url, {\n          method: \"POST\",\n          headers: this._get_headers(false),\n          body: body,\n          ...(useKeepalive && { keepalive: true }),\n        });\n\n        if (!response.ok) {\n          const error_text = await response.text();\n          // Retry on 400 errors that indicate the server doesn't recognize\n          // our stream (e.g., load balancer routed to a different instance)\n          if (response.status === 400 && attempt < maxRetries - 1) {\n            console.warn(\n              `POST failed (attempt ${attempt + 1}/${maxRetries}): ${error_text}, retrying...`,\n            );\n            await new Promise((r) => setTimeout(r, 500 * (attempt + 1)));\n            continue;\n          }\n          throw new Error(\n            `POST failed with status ${response.status}: ${error_text}`,\n          );\n        }\n\n        return true;\n      } catch (error) {\n        if (attempt < maxRetries - 1 && !this._closed) {\n          console.warn(\n            `Failed to send message (attempt ${attempt + 1}/${maxRetries}): ${error.message}, retrying...`,\n          );\n          await new Promise((r) => setTimeout(r, 500 * (attempt + 1)));\n        } else {\n          console.error(`Failed to send message: ${error.message}`);\n          throw error;\n        }\n      }\n    }\n  }\n\n  /**\n   * Set reconnection flag.\n   */\n  set_reconnection(value) {\n    this._enable_reconnect = value;\n  }\n\n  /**\n   * Close the connection.\n   */\n  async disconnect(reason = \"client disconnect\") {\n    if (this._closed) return;\n\n    this._closed = true;\n\n    // Clear token refresh interval\n    if (this._refresh_token_task) {\n      clearInterval(this._refresh_token_task);\n      this._refresh_token_task = null;\n    }\n\n    // Abort any active stream fetch to release the connection immediately\n    if (this._abort_controller) {\n      this._abort_controller.abort();\n      this._abort_controller = null;\n    }\n\n    if (this._handle_disconnected) {\n      this._handle_disconnected(reason);\n    }\n  }\n}\n\n/**\n * Normalize server URL for HTTP transport.\n */\nexport function normalizeServerUrl(server_url) {\n  if (!server_url) {\n    throw new Error(\"server_url is required\");\n  }\n\n  // Convert ws:// to http://\n  if (server_url.startsWith(\"ws://\")) {\n    server_url = server_url.replace(\"ws://\", \"http://\");\n  } else if (server_url.startsWith(\"wss://\")) {\n    server_url = server_url.replace(\"wss://\", \"https://\");\n  }\n\n  // Remove /ws suffix if present (WebSocket endpoint)\n  if (server_url.endsWith(\"/ws\")) {\n    server_url = server_url.slice(0, -3);\n  }\n\n  return server_url.replace(/\\/$/, \"\");\n}\n\n/**\n * Internal function to establish HTTP streaming connection.\n */\nexport async function _connectToServerHTTP(config) {\n  let clientId = config.clientId || config.client_id;\n  if (!clientId) {\n    clientId = randId();\n  }\n\n  const server_url = normalizeServerUrl(config.serverUrl || config.server_url);\n\n  const connection = new HTTPStreamingRPCConnection(\n    server_url,\n    clientId,\n    config.workspace,\n    config.token,\n    config.reconnection_token,\n    config.method_timeout || 30,\n    config.token_refresh_interval || 2 * 60 * 60,\n  );\n\n  const connection_info = await connection.open();\n  assert(connection_info, \"Failed to connect to server\");\n\n  await new Promise((resolve) => setTimeout(resolve, 100));\n\n  const workspace = connection_info.workspace;\n\n  const rpc = new RPC(connection, {\n    client_id: clientId,\n    workspace,\n    default_context: { connection_type: \"http_streaming\" },\n    silent: config.silent || false,\n    name: config.name,\n    method_timeout: config.method_timeout,\n    app_id: config.app_id,\n    server_base_url: connection_info.public_base_url,\n    encryption: config.encryption || false,\n    encryption_private_key: config.encryption_private_key || null,\n    encryption_public_key: config.encryption_public_key || null,\n  });\n\n  await rpc.waitFor(\"services_registered\", config.method_timeout || 120);\n\n  const wm = await rpc.get_manager_service({\n    timeout: config.method_timeout || 30,\n    case_conversion: \"camel\",\n  });\n  wm.rpc = rpc;\n\n  // Auto-refresh workspace manager proxy after reconnection.\n  // See websocket-client.js for detailed explanation.\n  let isInitialRefresh = true;\n  rpc.on(\"manager_refreshed\", async () => {\n    if (isInitialRefresh) {\n      isInitialRefresh = false;\n      return;\n    }\n    try {\n      const newTarget = `*/${rpc._connection.manager_id}`;\n      for (const key of Object.keys(wm)) {\n        if (typeof wm[key] === \"function\" && wm[key].__rpc_object__) {\n          wm[key].__rpc_object__._rtarget = newTarget;\n        }\n      }\n      console.info(\n        \"Workspace manager proxy retargeted after reconnection (new manager_id:\",\n        rpc._connection?.manager_id + \")\",\n      );\n    } catch (err) {\n      console.warn(\n        \"Failed to retarget workspace manager after reconnection:\",\n        err,\n      );\n    }\n  });\n\n  // Add standard methods\n  wm.disconnect = schemaFunction(rpc.disconnect.bind(rpc), {\n    name: \"disconnect\",\n    description: \"Disconnect from server\",\n    parameters: { properties: {}, type: \"object\" },\n  });\n\n  wm.registerService = schemaFunction(rpc.register_service.bind(rpc), {\n    name: \"registerService\",\n    description: \"Register a service\",\n    parameters: {\n      properties: {\n        service: { description: \"Service to register\", type: \"object\" },\n      },\n      required: [\"service\"],\n      type: \"object\",\n    },\n  });\n\n  const _getService = wm.getService;\n  wm.getService = async (query, config = {}) => {\n    return await _getService(query, config);\n  };\n  if (_getService.__schema__) {\n    wm.getService.__schema__ = _getService.__schema__;\n  }\n\n  async function serve() {\n    await new Promise(() => {}); // Wait forever\n  }\n\n  wm.serve = schemaFunction(serve, {\n    name: \"serve\",\n    description: \"Run event loop forever\",\n    parameters: { type: \"object\", properties: {} },\n  });\n\n  if (connection_info) {\n    wm.config = Object.assign(wm.config || {}, connection_info);\n  }\n\n  // Handle force-exit from manager\n  if (connection.manager_id) {\n    rpc.on(\"force-exit\", async (message) => {\n      if (message.from === \"*/\" + connection.manager_id) {\n        console.info(`Disconnecting from server: ${message.reason}`);\n        await rpc.disconnect();\n      }\n    });\n  }\n\n  return wm;\n}\n\n/**\n * Connect to server using HTTP streaming transport.\n *\n * This is an alternative to WebSocket connection that's more resilient\n * to network issues.\n *\n * @param {Object} config - Configuration object\n * @returns {Promise<Object>} Connected workspace manager\n */\nexport async function connectToServerHTTP(config = {}) {\n  return await _connectToServerHTTP(config);\n}\n\n/**\n * Get a remote service using HTTP transport.\n */\nexport async function getRemoteServiceHTTP(serviceUri, config = {}) {\n  const { serverUrl, workspace, clientId, serviceId, appId } =\n    parseServiceUrl(serviceUri);\n  const fullServiceId = `${workspace}/${clientId}:${serviceId}@${appId}`;\n\n  if (config.serverUrl) {\n    if (config.serverUrl !== serverUrl) {\n      throw new Error(\"server_url mismatch\");\n    }\n  }\n  config.serverUrl = serverUrl;\n\n  const server = await connectToServerHTTP(config);\n  return await server.getService(fullServiceId);\n}\n","/**\n * Contains the RPC object used both by the application\n * site, and by each plugin\n */\nimport {\n  randId,\n  typedArrayToDtype,\n  dtypeToTypedArray,\n  MessageEmitter,\n  assert,\n  waitFor,\n  convertCase,\n  expandKwargs,\n  Semaphore,\n  isAsyncGenerator,\n  isGenerator,\n  isAsyncIterator,\n  isSyncIterator,\n} from \"./utils/index.js\";\nimport { schemaFunction } from \"./utils/schema.js\";\n\nimport { encode as msgpack_packb, decodeMulti } from \"@msgpack/msgpack\";\nimport {\n  publicKeyToHex,\n  publicKeyFromHex,\n  generateEncryptionKeypair,\n  encryptPayload,\n  decryptPayload,\n} from \"./crypto.js\";\n\n/**\n * Extract parameter names from a function's source text.\n * Works with regular functions, arrow functions, async functions,\n * destructured params, default values, and rest params.\n * Note: will not work with minified/bundled code where param names are mangled.\n * @param {Function} fn - The function to inspect.\n * @returns {string[]} Array of parameter names.\n */\nfunction getParamNames(fn) {\n  const src = fn.toString();\n  // Match these forms (with optional leading async):\n  //   function(a, b)           – anonymous function\n  //   function name(a, b)      – named function\n  //   (a, b) =>                – arrow function\n  //   a =>                     – single-param arrow (no parens)\n  //   name(a, b) {             – shorthand method (object literal / class)\n  const match = src.match(\n    /^(?:async\\s+)?(?:function\\s*\\w*)?\\s*\\(([^)]*)\\)|^(?:async\\s+)?(\\w+)\\s*=>|^(?:async\\s+)?\\w+\\s*\\(([^)]*)\\)/,\n  );\n  if (!match) return [];\n  const paramStr =\n    match[1] !== undefined\n      ? match[1]\n      : match[2] !== undefined\n        ? match[2]\n        : match[3];\n  if (!paramStr || !paramStr.trim()) return [];\n  return paramStr\n    .split(\",\")\n    .map((p) =>\n      p\n        .trim()\n        .replace(/\\s*=.*$/, \"\") // strip default values\n        .replace(/^\\.\\.\\.\\s*/, \"\"), // strip rest operator\n    )\n    .filter(Boolean);\n}\n\n/**\n * Apply an out-of-band encryption public key to all remote methods in a service.\n * @param {Object} svc - The decoded service object.\n * @param {Uint8Array} encPubBytes - 32-byte raw X25519 public key.\n */\nfunction _applyEncryptionKeyToService(svc, encPubBytes) {\n  if (svc && typeof svc === \"object\" && !ArrayBuffer.isView(svc)) {\n    for (const key of Object.keys(svc)) {\n      const value = svc[key];\n      if (typeof value === \"function\" && value.__rpc_object__) {\n        value.__rpc_object__._renc_pub = encPubBytes;\n      } else if (\n        value &&\n        typeof value === \"object\" &&\n        !ArrayBuffer.isView(value)\n      ) {\n        _applyEncryptionKeyToService(value, encPubBytes);\n      }\n    }\n  }\n}\n\nexport { _applyEncryptionKeyToService, getParamNames };\n\nexport const API_VERSION = 3;\nconst CHUNK_SIZE = 1024 * 256;\nconst CONCURRENCY_LIMIT = 30;\n\nconst ArrayBufferView = Object.getPrototypeOf(\n  Object.getPrototypeOf(new Uint8Array()),\n).constructor;\n\n/**\n * Check if a value is a primitive type that needs no encoding/decoding.\n */\nfunction _isPrimitive(v) {\n  if (v === null || v === undefined) return true;\n  const t = typeof v;\n  return t === \"number\" || t === \"string\" || t === \"boolean\";\n}\n\n/**\n * Check if an array (and nested arrays/objects) contains only primitives.\n */\nfunction _allPrimitivesArray(arr) {\n  for (let i = 0; i < arr.length; i++) {\n    const v = arr[i];\n    if (_isPrimitive(v)) continue;\n    if (v instanceof Uint8Array) continue;\n    if (Array.isArray(v)) {\n      if (!_allPrimitivesArray(v)) return false;\n      continue;\n    }\n    if (v && v.constructor === Object) {\n      if (\"_rtype\" in v) return false;\n      if (!_allPrimitivesObject(v)) return false;\n      continue;\n    }\n    return false;\n  }\n  return true;\n}\n\n/**\n * Check if an object (and nested objects/arrays) contains only primitives.\n */\nfunction _allPrimitivesObject(obj) {\n  const values = Object.values(obj);\n  for (let i = 0; i < values.length; i++) {\n    const v = values[i];\n    if (_isPrimitive(v)) continue;\n    if (v instanceof Uint8Array) continue;\n    if (Array.isArray(v)) {\n      if (!_allPrimitivesArray(v)) return false;\n      continue;\n    }\n    if (v && v.constructor === Object) {\n      if (\"_rtype\" in v) return false;\n      if (!_allPrimitivesObject(v)) return false;\n      continue;\n    }\n    return false;\n  }\n  return true;\n}\n\nfunction _appendBuffer(buffer1, buffer2) {\n  const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n  tmp.set(new Uint8Array(buffer1), 0);\n  tmp.set(new Uint8Array(buffer2), buffer1.byteLength);\n  return tmp.buffer;\n}\n\n/**\n * Wrap a promise with a timeout.\n * @param {Promise} promise - The promise to wrap.\n * @param {number} timeoutMs - The timeout in milliseconds.\n * @param {string} message - Optional error message for timeout.\n * @returns {Promise} - The wrapped promise that will reject on timeout.\n */\nfunction withTimeout(promise, timeoutMs, message = \"Operation timed out\") {\n  return new Promise((resolve, reject) => {\n    const timeoutId = setTimeout(() => {\n      reject(new Error(`TimeoutError: ${message}`));\n    }, timeoutMs);\n\n    promise\n      .then((result) => {\n        clearTimeout(timeoutId);\n        resolve(result);\n      })\n      .catch((error) => {\n        clearTimeout(timeoutId);\n        reject(error);\n      });\n  });\n}\n\nfunction indexObject(obj, is) {\n  if (!is) throw new Error(\"undefined index\");\n  if (typeof is === \"string\") return indexObject(obj, is.split(\".\"));\n  else if (is.length === 0) return obj;\n  else return indexObject(obj[is[0]], is.slice(1));\n}\n\n// Simple fallback schema generation - no docstring parsing for JS\n\nfunction _get_schema(obj, name = null, skipContext = false) {\n  if (Array.isArray(obj)) {\n    return obj.map((v, i) => _get_schema(v, null, skipContext));\n  } else if (typeof obj === \"object\" && obj !== null) {\n    let schema = {};\n    for (let k in obj) {\n      schema[k] = _get_schema(obj[k], k, skipContext);\n    }\n    return schema;\n  } else if (typeof obj === \"function\") {\n    if (obj.__schema__) {\n      const schema = JSON.parse(JSON.stringify(obj.__schema__));\n      if (name) {\n        schema.name = name;\n        obj.__schema__.name = name;\n      }\n      if (skipContext) {\n        if (schema.parameters && schema.parameters.properties) {\n          delete schema.parameters.properties[\"context\"];\n        }\n        if (schema.parameters && schema.parameters.required) {\n          const contextIndex = schema.parameters.required.indexOf(\"context\");\n          if (contextIndex > -1) {\n            schema.parameters.required.splice(contextIndex, 1);\n          }\n        }\n      }\n      return { type: \"function\", function: schema };\n    } else {\n      // Simple fallback for JavaScript - just return basic function schema with name\n      const funcName = name || obj.name || \"function\";\n      return {\n        type: \"function\",\n        function: {\n          name: funcName,\n        },\n      };\n    }\n  } else if (typeof obj === \"number\") {\n    return { type: \"number\" };\n  } else if (typeof obj === \"string\") {\n    return { type: \"string\" };\n  } else if (typeof obj === \"boolean\") {\n    return { type: \"boolean\" };\n  } else if (obj === null) {\n    return { type: \"null\" };\n  } else {\n    return {};\n  }\n}\n\nfunction _annotate_service(service, serviceTypeInfo) {\n  function validateKeys(serviceDict, schemaDict, path = \"root\") {\n    // Validate that all keys in schemaDict exist in serviceDict\n    for (let key in schemaDict) {\n      if (!serviceDict.hasOwnProperty(key)) {\n        throw new Error(`Missing key '${key}' in service at path '${path}'`);\n      }\n    }\n\n    // Check for any unexpected keys in serviceDict\n    for (let key in serviceDict) {\n      if (key !== \"type\" && !schemaDict.hasOwnProperty(key)) {\n        throw new Error(`Unexpected key '${key}' in service at path '${path}'`);\n      }\n    }\n  }\n\n  function annotateRecursive(newService, schemaInfo, path = \"root\") {\n    if (typeof newService === \"object\" && !Array.isArray(newService)) {\n      validateKeys(newService, schemaInfo, path);\n      for (let k in newService) {\n        let v = newService[k];\n        let newPath = `${path}.${k}`;\n        if (typeof v === \"object\" && !Array.isArray(v)) {\n          annotateRecursive(v, schemaInfo[k], newPath);\n        } else if (typeof v === \"function\") {\n          if (schemaInfo.hasOwnProperty(k)) {\n            newService[k] = schemaFunction(v, {\n              name: schemaInfo[k][\"name\"],\n              description: schemaInfo[k].description || \"\",\n              parameters: schemaInfo[k][\"parameters\"],\n            });\n          } else {\n            throw new Error(\n              `Missing schema for function '${k}' at path '${newPath}'`,\n            );\n          }\n        }\n      }\n    } else if (Array.isArray(newService)) {\n      if (newService.length !== schemaInfo.length) {\n        throw new Error(`Length mismatch at path '${path}'`);\n      }\n      newService.forEach((v, i) => {\n        let newPath = `${path}[${i}]`;\n        if (typeof v === \"object\" && !Array.isArray(v)) {\n          annotateRecursive(v, schemaInfo[i], newPath);\n        } else if (typeof v === \"function\") {\n          if (schemaInfo.hasOwnProperty(i)) {\n            newService[i] = schemaFunction(v, {\n              name: schemaInfo[i][\"name\"],\n              description: schemaInfo[i].description || \"\",\n              parameters: schemaInfo[i][\"parameters\"],\n            });\n          } else {\n            throw new Error(\n              `Missing schema for function at index ${i} in path '${newPath}'`,\n            );\n          }\n        }\n      });\n    }\n  }\n\n  validateKeys(service, serviceTypeInfo[\"definition\"]);\n  annotateRecursive(service, serviceTypeInfo[\"definition\"]);\n  return service;\n}\n\nfunction getFunctionInfo(func) {\n  const funcString = func.toString();\n\n  // Extract function name\n  const nameMatch = funcString.match(/function\\s*(\\w*)/);\n  const name = (nameMatch && nameMatch[1]) || \"\";\n\n  // Extract function parameters, excluding comments\n  const paramsMatch = funcString.match(/\\(([^)]*)\\)/);\n  let params = \"\";\n  if (paramsMatch) {\n    params = paramsMatch[1]\n      .split(\",\")\n      .map((p) =>\n        p\n          .replace(/\\/\\*.*?\\*\\//g, \"\") // Remove block comments\n          .replace(/\\/\\/.*$/g, \"\"),\n      ) // Remove line comments\n      .filter((p) => p.trim().length > 0) // Remove empty strings after removing comments\n      .map((p) => p.trim()) // Trim remaining whitespace\n      .join(\", \");\n  }\n\n  // Extract function docstring (block comment)\n  let docMatch = funcString.match(/\\)\\s*\\{\\s*\\/\\*([\\s\\S]*?)\\*\\//);\n  const docstringBlock = (docMatch && docMatch[1].trim()) || \"\";\n\n  // Extract function docstring (line comment)\n  docMatch = funcString.match(/\\)\\s*\\{\\s*(\\/\\/[\\s\\S]*?)\\n\\s*[^\\s\\/]/);\n  const docstringLine =\n    (docMatch &&\n      docMatch[1]\n        .split(\"\\n\")\n        .map((s) => s.replace(/^\\/\\/\\s*/, \"\").trim())\n        .join(\"\\n\")) ||\n    \"\";\n\n  const docstring = docstringBlock || docstringLine;\n  return (\n    name &&\n    params.length > 0 && {\n      name: name,\n      sig: params,\n      doc: docstring,\n    }\n  );\n}\n\nfunction concatArrayBuffers(buffers) {\n  var buffersLengths = buffers.map(function (b) {\n      return b.byteLength;\n    }),\n    totalBufferlength = buffersLengths.reduce(function (p, c) {\n      return p + c;\n    }, 0),\n    unit8Arr = new Uint8Array(totalBufferlength);\n  buffersLengths.reduce(function (p, c, i) {\n    unit8Arr.set(new Uint8Array(buffers[i]), p);\n    return p + c;\n  }, 0);\n  return unit8Arr.buffer;\n}\n\nclass Timer {\n  constructor(timeout, callback, args, label) {\n    this._timeout = timeout;\n    this._callback = callback;\n    this._args = args;\n    this._label = label || \"timer\";\n    this._task = null;\n    this.started = false;\n  }\n\n  start() {\n    if (this.started) {\n      this.reset();\n    } else {\n      this._task = setTimeout(() => {\n        this._callback.apply(this, this._args);\n      }, this._timeout * 1000);\n      this.started = true;\n    }\n  }\n\n  clear() {\n    if (this._task && this.started) {\n      clearTimeout(this._task);\n      this._task = null;\n      this.started = false;\n    } else {\n      console.warn(`Clearing a timer (${this._label}) which is not started`);\n    }\n  }\n\n  reset() {\n    if (this._task) {\n      clearTimeout(this._task);\n    }\n    this._task = setTimeout(() => {\n      this._callback.apply(this, this._args);\n    }, this._timeout * 1000);\n    this.started = true;\n  }\n}\n\nclass RemoteService extends Object {}\n\n// Error patterns indicating a stale service reference that can be retried\nconst STALE_SERVICE_ERROR_PATTERNS = [\n  \"Method expired or not found\",\n  \"Session not found\",\n  \"Peer\",  // \"Peer X is not connected\"\n  \"Method not found\",\n  \"Connection was closed\",\n  \"Connection is closed\",\n];\n\nfunction isStaleServiceError(error) {\n  const msg = String(error && error.message ? error.message : error);\n  return STALE_SERVICE_ERROR_PATTERNS.some((pattern) => msg.includes(pattern));\n}\n\n/**\n * RPC object represents a single site in the\n * communication protocol between the application and the plugin\n *\n * @param {Object} connection a special object allowing to send\n * and receive messages from the opposite site (basically it\n * should only provide send() and onMessage() methods)\n */\nexport class RPC extends MessageEmitter {\n  constructor(\n    connection,\n    {\n      client_id = null,\n      default_context = null,\n      name = null,\n      codecs = null,\n      method_timeout = null,\n      rintf_timeout = null,\n      max_message_buffer_size = 0,\n      debug = false,\n      workspace = null,\n      silent = false,\n      logger = undefined,\n      app_id = null,\n      server_base_url = null,\n      long_message_chunk_size = null,\n      encryption = false,\n      encryption_private_key = null,\n      encryption_public_key = null,\n    },\n  ) {\n    super(debug);\n    this._codecs = codecs || {};\n    assert(client_id && typeof client_id === \"string\");\n    assert(client_id, \"client_id is required\");\n    this._client_id = client_id;\n    this._name = name;\n    this._app_id = app_id || \"*\";\n    this._local_workspace = workspace;\n    this._silent = silent;\n    // Configurable logger: pass `logger: null` to suppress all output,\n    // or `logger: customObj` with {debug,info,warn,error} methods.\n    // Default uses console when not silent.\n    if (logger === null || silent) {\n      const noop = () => {};\n      this._logger = { debug: noop, info: noop, warn: noop, error: noop, log: noop };\n    } else if (logger) {\n      this._logger = logger;\n    } else {\n      this._logger = console;\n    }\n    this.default_context = default_context || {};\n    this._method_annotations = new WeakMap();\n    this._max_message_buffer_size = max_message_buffer_size;\n    this._chunk_store = {};\n    this._method_timeout = method_timeout || 30;\n    this._rintf_timeout = rintf_timeout || 10;\n    this._server_base_url = server_base_url;\n    this._long_message_chunk_size = long_message_chunk_size || CHUNK_SIZE;\n\n    // make sure there is an execute function\n    this._services = {};\n    this._object_store = {\n      services: this._services,\n    };\n    // Index: target_id -> Set of top-level session keys for fast cleanup\n    this._targetIdIndex = {};\n    // Index: allowed_caller -> Set of _rintf service IDs for lifecycle cleanup\n    this._rintfCallerIndex = {};\n    // Track last known manager_id for stale call rejection on reconnection\n    this._last_manager_id = null;\n\n    // Encryption support (X25519 ECDH + AES-256-GCM)\n    this._encryption_enabled = false;\n    this._encryption_private_key = null;\n    this._encryption_public_key = null;\n    this._encryption_ready = null;\n    if (encryption) {\n      if (encryption_private_key && encryption_public_key) {\n        this._encryption_private_key = encryption_private_key;\n        this._encryption_public_key = encryption_public_key;\n        this._encryption_enabled = true;\n        this._encryption_ready = Promise.resolve();\n      } else {\n        this._encryption_ready = generateEncryptionKeypair().then((keyPair) => {\n          this._encryption_private_key = keyPair.privateKey;\n          this._encryption_public_key = keyPair.publicKey;\n          this._encryption_enabled = true;\n        });\n      }\n    }\n\n    // Track background tasks for proper cleanup\n    this._background_tasks = new Set();\n\n    // Periodic session sweep for stale sessions with no activity.\n    // Default: 10 minutes (matching Python).\n    this._sessionMaxAge = 10 * 60 * 1000;\n    this._sessionSweepInterval = setInterval(() => {\n      this._sweepStaleSessions();\n    }, this._sessionMaxAge / 2);\n\n    // Set up global unhandled promise rejection handler for RPC-related errors\n    // Use a class-level reference counter so the handler is added once and removed\n    // only when the last RPC instance is closed.\n    this._unhandledRejectionHandler = (event) => {\n      const reason = event.reason;\n      if (reason && typeof reason === \"object\") {\n        const reasonStr = reason.toString();\n        if (\n          reasonStr.includes(\"Method not found\") ||\n          reasonStr.includes(\"Session not found\") ||\n          reasonStr.includes(\"Method expired\") ||\n          reasonStr.includes(\"Connection is closed\") ||\n          reasonStr.includes(\"Client disconnected\") ||\n          reasonStr.includes(\"RPC connection closed\")\n        ) {\n          // console.debug(\n            // \"Ignoring expected disconnection/method error:\",\n            // reason,\n          // );\n          event.preventDefault();\n          return;\n        }\n      }\n      this._logger.warn(\"Unhandled RPC promise rejection:\", reason);\n    };\n\n    this._unhandledRejectionNodeHandler = null;\n\n    if (!RPC._rejectionHandlerCount) {\n      RPC._rejectionHandlerCount = 0;\n    }\n    RPC._rejectionHandlerCount++;\n\n    if (RPC._rejectionHandlerCount === 1) {\n      if (typeof window !== \"undefined\") {\n        window.addEventListener(\n          \"unhandledrejection\",\n          this._unhandledRejectionHandler,\n        );\n      } else if (typeof process !== \"undefined\") {\n        this._unhandledRejectionNodeHandler = (reason, promise) => {\n          this._unhandledRejectionHandler({\n            reason,\n            promise,\n            preventDefault: () => {},\n          });\n        };\n        process.on(\"unhandledRejection\", this._unhandledRejectionNodeHandler);\n      }\n    }\n\n    if (connection) {\n      this.add_service({\n        id: \"built-in\",\n        type: \"built-in\",\n        name: `Built-in services for ${this._local_workspace}/${this._client_id}`,\n        config: {\n          require_context: true,\n          visibility: \"public\",\n          api_version: API_VERSION,\n        },\n        ping: this._ping.bind(this),\n        get_service: this.get_local_service.bind(this),\n        message_cache: {\n          create: this._create_message.bind(this),\n          append: this._append_message.bind(this),\n          set: this._set_message.bind(this),\n          process: this._process_message.bind(this),\n          remove: this._remove_message.bind(this),\n        },\n      });\n      this._boundHandleMethod = this._handle_method.bind(this);\n      this._boundHandleError = console.error;\n      this.on(\"method\", this._boundHandleMethod);\n      this.on(\"error\", this._boundHandleError);\n      this.on(\"peer_not_found\", this._handlePeerNotFound.bind(this));\n\n      assert(connection.emit_message && connection.on_message);\n      assert(\n        connection.manager_id !== undefined,\n        \"Connection must have manager_id\",\n      );\n      this._emit_message = connection.emit_message.bind(connection);\n      connection.on_message(this._on_message.bind(this));\n      this._connection = connection;\n      const onConnected = async (connectionInfo) => {\n        if (!this._silent && this._connection.manager_id) {\n          // Immediately reject all pending calls targeting the old manager.\n          // After server restart, the manager_id changes. Any in-flight RPC\n          // calls to the old manager will never get a response (the server\n          // silently drops messages to unknown */{id} targets). Rejecting\n          // them here avoids waiting for the full method timeout (~10-30s).\n          const currentManagerId = this._connection.manager_id;\n          if (\n            this._last_manager_id &&\n            this._last_manager_id !== currentManagerId\n          ) {\n            const oldTarget = `*/${this._last_manager_id}`;\n            const cleaned = this._cleanupSessionsForClient(oldTarget);\n            if (cleaned > 0) {\n              this._logger.info(\n                `Rejected ${cleaned} stale call(s) to old manager ${this._last_manager_id}`,\n              );\n            }\n          }\n          this._last_manager_id = currentManagerId;\n\n          try {\n            // Get fresh manager service (one RPC roundtrip, ~50-100ms)\n            const manager = await this.get_manager_service({\n              timeout: 20,\n              case_conversion: \"camel\",\n            });\n\n            // Fire manager_refreshed IMMEDIATELY — before service re-registration.\n            // This allows connectToServer's wm proxy to be updated as soon as\n            // possible, minimizing the window where stale methods exist.\n            this._fire(\"manager_refreshed\", { manager });\n\n            const services = Object.values(this._services);\n            let servicesCount = services.length;\n            let registeredCount = 0;\n            const failedServices = [];\n\n            // Use timeout for service registration to prevent hanging\n            // _method_timeout is in seconds, withTimeout expects milliseconds\n            const serviceRegistrationTimeout = (this._method_timeout || 30) * 1000;\n\n            for (let service of services) {\n              // Skip local-only services (e.g. _rintf_ callback proxies) —\n              // they must never be registered with the server; doing so\n              // creates zombie entries in Redis.\n              if (service.config && service.config._local_only) {\n                servicesCount--;\n                continue;\n              }\n              try {\n                const serviceInfo = this._extract_service_info(service);\n                await withTimeout(\n                  manager.registerService(serviceInfo),\n                  serviceRegistrationTimeout,\n                  `Timeout registering service ${service.id || \"unknown\"}`,\n                );\n                registeredCount++;\n              } catch (serviceError) {\n                failedServices.push(service.id || \"unknown\");\n                if (\n                  serviceError.message &&\n                  serviceError.message.includes(\"TimeoutError\")\n                ) {\n                  this._logger.error(\n                    `Timeout registering service ${service.id || \"unknown\"}`,\n                  );\n                } else {\n                  this._logger.error(\n                    `Failed to register service ${service.id || \"unknown\"}: ${serviceError}`,\n                  );\n                }\n              }\n            }\n\n            if (registeredCount === servicesCount) {\n              this._logger.info(\n                `Successfully registered all ${registeredCount} services with the server`,\n              );\n            } else {\n              this._logger.warn(\n                `Only registered ${registeredCount} out of ${servicesCount} services with the server. Failed services: ${failedServices.join(\", \")}`,\n              );\n            }\n\n            // Fire event with registration status\n            this._fire(\"services_registered\", {\n              total: servicesCount,\n              registered: registeredCount,\n              failed: failedServices,\n            });\n\n            // Track whether all services were registered so the\n            // reconnection loop can detect partial failures and retry.\n            this._connection._services_registered_ok =\n              failedServices.length === 0;\n\n            // Subscribe to client_disconnected events if the manager supports it\n            try {\n              if (\n                manager.subscribe &&\n                typeof manager.subscribe === \"function\"\n              ) {\n                // Clean up previous subscription and handler to prevent\n                // duplicates on reconnection (listener leak fix)\n                if (this._clientDisconnectedSubscription) {\n                  try {\n                    if (\n                      typeof this._clientDisconnectedSubscription.unsubscribe ===\n                      \"function\"\n                    ) {\n                      this._clientDisconnectedSubscription.unsubscribe();\n                    }\n                  } catch (e) {\n                    // console.debug(`Error unsubscribing old client_disconnected: ${e}`);\n                  }\n                  this._clientDisconnectedSubscription = null;\n                }\n                if (this._boundHandleClientDisconnected) {\n                  try {\n                    this.off(\n                      \"client_disconnected\",\n                      this._boundHandleClientDisconnected,\n                    );\n                  } catch (e) {\n                    // Handler may not be in list if previous setup was interrupted\n                  }\n                  this._boundHandleClientDisconnected = null;\n                }\n\n                // console.debug(\"Subscribing to client_disconnected events\");\n\n                // Store handler at instance level so it can be removed later\n                this._boundHandleClientDisconnected = async (event) => {\n                  // The client ID is in event.data.id based on the event structure\n                  const clientId = event.data?.id || event.client;\n                  const workspace = event.data?.workspace;\n                  if (clientId && workspace) {\n                    // Construct the full client path with workspace prefix\n                    const fullClientId = `${workspace}/${clientId}`;\n                    // console.debug(\n                      // `Client ${fullClientId} disconnected, cleaning up sessions`,\n                    // );\n                    await this._handleClientDisconnected(fullClientId);\n                  } else if (clientId) {\n                    // console.debug(\n                      // `Client ${clientId} disconnected, cleaning up sessions`,\n                    // );\n                    await this._handleClientDisconnected(clientId);\n                  }\n                };\n\n                // Subscribe to the event topic first with timeout\n                this._clientDisconnectedSubscription = await withTimeout(\n                  manager.subscribe([\"client_disconnected\"]),\n                  serviceRegistrationTimeout,\n                  \"Timeout subscribing to client_disconnected events\",\n                );\n\n                // Then register the local event handler\n                this.on(\n                  \"client_disconnected\",\n                  this._boundHandleClientDisconnected,\n                );\n\n                // console.debug(\n                  // \"Successfully subscribed to client_disconnected events\",\n                // );\n              } else {\n                // console.debug(\n                  // \"Manager does not support subscribe method, skipping client_disconnected handling\",\n                // );\n                this._clientDisconnectedSubscription = null;\n              }\n            } catch (subscribeError) {\n              // console.debug(\n                // `Failed to subscribe to client_disconnected events: ${subscribeError}`,\n              // );\n              this._clientDisconnectedSubscription = null;\n            }\n          } catch (managerError) {\n            this._logger.error(\n              `Failed to get manager service for registering services: ${managerError}`,\n            );\n            // Fire event with error status\n            this._fire(\"services_registration_failed\", {\n              error: managerError.toString(),\n              total_services: Object.keys(this._services).length,\n            });\n            // Mark registration as failed so the reconnection loop\n            // can detect and retry\n            this._connection._services_registered_ok = false;\n          }\n        } else {\n          // console.debug(\"Connection established\", connectionInfo);\n        }\n        if (connectionInfo) {\n          if (connectionInfo.public_base_url) {\n            this._server_base_url = connectionInfo.public_base_url;\n          }\n          this._fire(\"connected\", connectionInfo);\n        }\n      };\n      connection.on_connected(onConnected);\n\n      // Register disconnect handler to reject all pending RPC calls\n      // This ensures no remote function call hangs forever when the connection drops\n      if (typeof connection.on_disconnected === \"function\") {\n        connection.on_disconnected((reason) => {\n          // If reconnection is enabled AND the connection is not permanently closed,\n          // don't reject pending calls immediately — they may succeed after reconnect.\n          // When _closed is true (max retries exhausted or server refused reconnect),\n          // we must reject immediately so callers are not left hanging forever.\n          if (connection._enable_reconnect && !connection._closed) {\n            this._logger.info(\n              `Connection lost (${reason}), reconnection enabled - pending calls will be handled by timeout`,\n            );\n            return;\n          }\n          this._logger.warn(\n            `Connection lost (${reason}), rejecting all pending RPC calls`,\n          );\n          this._rejectPendingCalls(\n            `Connection lost: ${reason || \"unknown reason\"}`,\n          );\n        });\n      }\n\n      onConnected();\n    } else {\n      this._emit_message = function () {\n        this._logger.log(\"No connection to emit message\");\n      };\n    }\n  }\n\n  /**\n   * Return this client's X25519 public key as a 64-char hex string.\n   * Returns null if encryption is not enabled.\n   */\n  getPublicKey() {\n    if (!this._encryption_enabled || !this._encryption_public_key) return null;\n    return publicKeyToHex(this._encryption_public_key);\n  }\n\n  register_codec(config) {\n    if (!config[\"name\"] || (!config[\"encoder\"] && !config[\"decoder\"])) {\n      throw new Error(\n        \"Invalid codec format, please make sure you provide a name, type, encoder and decoder.\",\n      );\n    } else {\n      if (config.type) {\n        for (let k of Object.keys(this._codecs)) {\n          if (this._codecs[k].type === config.type || k === config.name) {\n            delete this._codecs[k];\n            this._logger.warn(\"Remove duplicated codec: \" + k);\n          }\n        }\n      }\n      this._codecs[config[\"name\"]] = config;\n    }\n  }\n\n  async _ping(msg, context) {\n    assert(msg == \"ping\");\n    return \"pong\";\n  }\n\n  async ping(client_id, timeout) {\n    let method = this._generate_remote_method({\n      _rserver: this._server_base_url,\n      _rtarget: client_id,\n      _rmethod: \"services.built-in.ping\",\n      _rpromise: true,\n      _rdoc: \"Ping a remote client\",\n    });\n    assert((await method(\"ping\", timeout)) == \"pong\");\n  }\n\n  _create_message(key, heartbeat, overwrite, context) {\n    if (heartbeat) {\n      if (!this._object_store[key]) {\n        throw new Error(`session does not exist anymore: ${key}`);\n      }\n      this._object_store[key][\"timer\"].reset();\n    }\n\n    if (!this._object_store[\"message_cache\"]) {\n      this._object_store[\"message_cache\"] = {};\n    }\n\n    // Evict stale cache entries (older than 5 minutes) and enforce size limit\n    const cache = this._object_store[\"message_cache\"];\n    const MAX_CACHE_SIZE = 256;\n    const MAX_CACHE_AGE = 5 * 60 * 1000;\n    const cacheKeys = Object.keys(cache);\n    if (cacheKeys.length >= MAX_CACHE_SIZE) {\n      const now = Date.now();\n      for (const k of cacheKeys) {\n        const entry = cache[k];\n        if (\n          entry &&\n          entry._cache_created_at &&\n          now - entry._cache_created_at > MAX_CACHE_AGE\n        ) {\n          delete cache[k];\n        }\n      }\n      // If still over limit, evict oldest entries\n      const remaining = Object.keys(cache);\n      if (remaining.length >= MAX_CACHE_SIZE) {\n        remaining\n          .sort(\n            (a, b) =>\n              (cache[a]._cache_created_at || 0) -\n              (cache[b]._cache_created_at || 0),\n          )\n          .slice(0, remaining.length - MAX_CACHE_SIZE + 1)\n          .forEach((k) => delete cache[k]);\n      }\n    }\n\n    if (!overwrite && cache[key]) {\n      throw new Error(\n        `Message with the same key (${key}) already exists in the cache store, please use overwrite=true or remove it first.`,\n      );\n    }\n    cache[key] = [];\n    cache[key]._cache_created_at = Date.now();\n  }\n\n  _append_message(key, data, heartbeat, context) {\n    if (heartbeat) {\n      if (!this._object_store[key]) {\n        throw new Error(`session does not exist anymore: ${key}`);\n      }\n      this._object_store[key][\"timer\"].reset();\n    }\n    const cache = this._object_store[\"message_cache\"];\n    if (!cache[key]) {\n      throw new Error(`Message with key ${key} does not exists.`);\n    }\n    assert(data instanceof ArrayBufferView);\n    cache[key].push(data);\n  }\n\n  _set_message(key, index, data, heartbeat, context) {\n    if (heartbeat) {\n      if (!this._object_store[key]) {\n        throw new Error(`session does not exist anymore: ${key}`);\n      }\n      this._object_store[key][\"timer\"].reset();\n    }\n    const cache = this._object_store[\"message_cache\"];\n    if (!cache[key]) {\n      throw new Error(`Message with key ${key} does not exists.`);\n    }\n    assert(data instanceof ArrayBufferView);\n    cache[key][index] = data;\n  }\n\n  _remove_message(key, context) {\n    const cache = this._object_store[\"message_cache\"];\n    if (!cache[key]) {\n      throw new Error(`Message with key ${key} does not exists.`);\n    }\n    delete cache[key];\n  }\n\n  _process_message(key, heartbeat, context) {\n    if (heartbeat) {\n      if (!this._object_store[key]) {\n        throw new Error(`session does not exist anymore: ${key}`);\n      }\n      this._object_store[key][\"timer\"].reset();\n    }\n    const cache = this._object_store[\"message_cache\"];\n    assert(!!context, \"Context is required\");\n    if (!cache[key]) {\n      throw new Error(`Message with key ${key} does not exists.`);\n    }\n    cache[key] = concatArrayBuffers(cache[key]);\n    // console.debug(`Processing message ${key} (bytes=${cache[key].byteLength})`);\n    let unpacker = decodeMulti(cache[key]);\n    const { done, value } = unpacker.next();\n    const main = value;\n    // Make sure the fields are from trusted source\n    Object.assign(main, {\n      from: context.from,\n      to: context.to,\n      ws: context.ws,\n      user: context.user,\n    });\n    main[\"ctx\"] = JSON.parse(JSON.stringify(main));\n    Object.assign(main[\"ctx\"], this.default_context);\n    if (!done) {\n      let extra = unpacker.next();\n      Object.assign(main, extra.value);\n    }\n    this._fire(main[\"type\"], main);\n    // console.debug(\n    //   this._client_id,\n    //   `Processed message ${key} (bytes=${cache[key].byteLength})`,\n    // );\n    delete cache[key];\n  }\n\n  _on_message(message) {\n    if (typeof message === \"string\") {\n      const main = JSON.parse(message);\n      // Add trusted context to the method call\n      main[\"ctx\"] = Object.assign({}, main, this.default_context);\n      this._fire(main[\"type\"], main);\n    } else if (message instanceof ArrayBuffer || ArrayBuffer.isView(message)) {\n      // Handle both ArrayBuffer (WebSocket) and Uint8Array/ArrayBufferView (HTTP transport)\n      let unpacker = decodeMulti(message);\n      const { done, value } = unpacker.next();\n      const main = value;\n      // Add trusted context to the method call\n      main[\"ctx\"] = Object.assign({}, main, this.default_context);\n      if (!done) {\n        let extra = unpacker.next();\n        Object.assign(main, extra.value);\n      }\n      this._fire(main[\"type\"], main);\n    } else if (typeof message === \"object\") {\n      // Add trusted context to the method call\n      message[\"ctx\"] = Object.assign({}, message, this.default_context);\n      this._fire(message[\"type\"], message);\n    } else {\n      throw new Error(\"Invalid message format\");\n    }\n  }\n\n  reset() {\n    this._removeRejectionHandler();\n    this._event_handlers = {};\n    this._services = {};\n  }\n\n  _removeRejectionHandler() {\n    if (RPC._rejectionHandlerCount && RPC._rejectionHandlerCount > 0) {\n      RPC._rejectionHandlerCount--;\n      if (RPC._rejectionHandlerCount === 0) {\n        if (typeof window !== \"undefined\" && this._unhandledRejectionHandler) {\n          window.removeEventListener(\n            \"unhandledrejection\",\n            this._unhandledRejectionHandler,\n          );\n        } else if (\n          typeof process !== \"undefined\" &&\n          this._unhandledRejectionNodeHandler\n        ) {\n          process.removeListener(\n            \"unhandledRejection\",\n            this._unhandledRejectionNodeHandler,\n          );\n        }\n      }\n    }\n    this._unhandledRejectionHandler = null;\n    this._unhandledRejectionNodeHandler = null;\n  }\n\n  close() {\n    // Clean up all pending sessions (rejects promises, clears timers/heartbeats, deletes sessions)\n    this._cleanupOnDisconnect();\n\n    // Remove method and error event listeners\n    if (this._boundHandleMethod) {\n      this.off(\"method\", this._boundHandleMethod);\n      this._boundHandleMethod = null;\n    }\n    if (this._boundHandleError) {\n      this.off(\"error\", this._boundHandleError);\n      this._boundHandleError = null;\n    }\n\n    // Clean up client_disconnected subscription and handler\n    if (this._clientDisconnectedSubscription) {\n      try {\n        if (\n          typeof this._clientDisconnectedSubscription.unsubscribe === \"function\"\n        ) {\n          this._clientDisconnectedSubscription.unsubscribe();\n        }\n      } catch (e) {\n        // console.debug(`Error unsubscribing client_disconnected: ${e}`);\n      }\n      this._clientDisconnectedSubscription = null;\n    }\n    if (this._boundHandleClientDisconnected) {\n      this.off(\"client_disconnected\", this._boundHandleClientDisconnected);\n      this._boundHandleClientDisconnected = null;\n    }\n\n    // Remove the global unhandled rejection handler\n    this._removeRejectionHandler();\n\n    // Remove ALL remaining event handlers to prevent memory leaks\n    // This clears any custom event listeners registered by users via .on()\n    this.off();\n\n    // Clean up background tasks\n    try {\n      for (const task of this._background_tasks) {\n        if (task && typeof task.cancel === \"function\") {\n          try {\n            task.cancel();\n          } catch (e) {\n            // console.debug(`Error canceling background task: ${e}`);\n          }\n        }\n      }\n      this._background_tasks.clear();\n    } catch (e) {\n      // console.debug(`Error cleaning up background tasks: ${e}`);\n    }\n\n    // Clear session sweep interval\n    if (this._sessionSweepInterval) {\n      clearInterval(this._sessionSweepInterval);\n      this._sessionSweepInterval = null;\n    }\n\n    // Clean up connection references to prevent circular references\n    try {\n      this._connection = null;\n      this._emit_message = function () {\n        // console.debug(\"RPC connection closed, ignoring message\");\n        return Promise.reject(new Error(\"Connection is closed\"));\n      };\n    } catch (e) {\n      // console.debug(`Error during connection cleanup: ${e}`);\n    }\n\n    this._fire(\"disconnected\");\n  }\n\n  /**\n   * Unregister a single _rintf service and remove it from the caller index.\n   * Safe to call even if the service was already removed.\n   */\n  _unregisterRintfService(serviceId, allowedCaller) {\n    if (this._services[serviceId]) {\n      delete this._services[serviceId];\n    }\n    if (allowedCaller && this._rintfCallerIndex[allowedCaller]) {\n      this._rintfCallerIndex[allowedCaller].delete(serviceId);\n      if (this._rintfCallerIndex[allowedCaller].size === 0) {\n        delete this._rintfCallerIndex[allowedCaller];\n      }\n    }\n  }\n\n  /**\n   * Remove all _rintf services whose allowed caller is the given client.\n   * Passive lifecycle cleanup: when a client disconnects, any _rintf\n   * callbacks that only it could invoke become dead resources.\n   * @returns {number} Number of _rintf services cleaned up\n   */\n  _cleanupRintfForCaller(clientId) {\n    const serviceIds = this._rintfCallerIndex[clientId];\n    if (!serviceIds) return 0;\n    delete this._rintfCallerIndex[clientId];\n    let cleaned = 0;\n    for (const sid of serviceIds) {\n      const svc = this._services[sid];\n      if (svc) {\n        if (typeof svc._dispose === \"function\") {\n          try {\n            svc._dispose();\n          } catch (e) {\n            /* ignore errors from dispose handlers */\n          }\n        }\n        delete this._services[sid];\n        cleaned++;\n      }\n    }\n    return cleaned;\n  }\n\n  async _handleClientDisconnected(clientId) {\n    try {\n      // Clean up all sessions for the disconnected client\n      const sessionsCleaned = this._cleanupSessionsForClient(clientId);\n\n      // Clean up _rintf services whose allowed caller is the disconnected client\n      const rintfCleaned = this._cleanupRintfForCaller(clientId);\n\n      // Fire an event to notify about the client disconnection\n      this._fire(\"remote_client_disconnected\", {\n        client_id: clientId,\n        sessions_cleaned: sessionsCleaned,\n        rintf_cleaned: rintfCleaned,\n      });\n    } catch (e) {\n      this._logger.error(\n        `Error handling client disconnection for ${clientId}: ${e}`,\n      );\n    }\n  }\n\n  _handlePeerNotFound(data) {\n    /**\n     * Handle server notification that target peer is not connected.\n     *\n     * When the server detects that an RPC message targets a disconnected\n     * client, it sends back a 'peer_not_found' message instead of silently\n     * dropping it. This allows pending calls to fail immediately.\n     */\n    const sessionId = data.session;\n    const peerId = data.peer_id || data.from || \"unknown\";\n    const errorMsg = data.error || `Peer ${peerId} is not connected`;\n    // console.debug(`Peer not found: ${peerId} (session=${sessionId})`);\n\n    // Reject the specific pending call identified by sessionId\n    if (sessionId) {\n      const session = this._object_store[sessionId];\n      if (session && typeof session === \"object\") {\n        this._cleanupSessionEntry(session, errorMsg);\n        delete this._object_store[sessionId];\n        this._removeFromTargetIdIndex(sessionId);\n      }\n    }\n\n    // Also clean up all other sessions targeting this peer\n    if (peerId) {\n      this._cleanupSessionsForClient(peerId);\n    }\n  }\n\n  _removeFromTargetIdIndex(sessionId) {\n    /**\n     * Remove a session from the target_id index.\n     * Call this before removing a session from _object_store.\n     */\n    const topKey = sessionId.split(\".\")[0];\n    const session = this._object_store[topKey];\n    if (session && typeof session === \"object\") {\n      const targetId = session.target_id;\n      if (targetId && targetId in this._targetIdIndex) {\n        this._targetIdIndex[targetId].delete(topKey);\n        if (this._targetIdIndex[targetId].size === 0) {\n          delete this._targetIdIndex[targetId];\n        }\n      }\n    }\n  }\n\n  /**\n   * Clean up a single session entry: reject promise, clear timer, cancel heartbeat.\n   * Centralizes the cleanup logic used by multiple methods.\n   * @param {object} session - The session object from _object_store\n   * @param {string|null} rejectReason - If provided, reject the session's promise with this reason\n   */\n  _cleanupSessionEntry(session, rejectReason = null) {\n    if (!session || typeof session !== \"object\") return;\n    if (\n      rejectReason &&\n      session.reject &&\n      typeof session.reject === \"function\"\n    ) {\n      try {\n        session.reject(new Error(rejectReason));\n      } catch (e) {\n        // console.debug(`Error rejecting session: ${e}`);\n      }\n    }\n    if (session.heartbeat_task) {\n      try {\n        clearInterval(session.heartbeat_task);\n      } catch (e) {\n        /* ignore */\n      }\n    }\n    if (\n      session.timer &&\n      session.timer.started &&\n      typeof session.timer.clear === \"function\"\n    ) {\n      try {\n        session.timer.clear();\n      } catch (e) {\n        /* ignore */\n      }\n    }\n  }\n\n  _cleanupSessionsForClient(clientId) {\n    let sessionsCleaned = 0;\n\n    // Use index for O(1) lookup instead of iterating all sessions\n    const sessionKeys = this._targetIdIndex[clientId];\n    if (!sessionKeys) return 0;\n\n    const reason = `Client disconnected: ${clientId}`;\n    for (const sessionKey of sessionKeys) {\n      const session = this._object_store[sessionKey];\n      if (!session || typeof session !== \"object\") continue;\n      if (session.target_id !== clientId) continue;\n\n      this._cleanupSessionEntry(session, reason);\n      delete this._object_store[sessionKey];\n      sessionsCleaned++;\n      // console.debug(`Cleaned up session: ${sessionKey}`);\n    }\n\n    delete this._targetIdIndex[clientId];\n    return sessionsCleaned;\n  }\n\n  _rejectPendingCalls(reason = \"Connection lost\") {\n    /**\n     * Reject all pending RPC calls when the connection is lost.\n     * Does NOT remove sessions (connection might be re-established).\n     */\n    try {\n      let rejectedCount = 0;\n      for (const key of Object.keys(this._object_store)) {\n        if (key === \"services\" || key === \"message_cache\") continue;\n        const value = this._object_store[key];\n        if (typeof value === \"object\" && value !== null) {\n          if (value.reject && typeof value.reject === \"function\") {\n            rejectedCount++;\n          }\n          this._cleanupSessionEntry(value, reason);\n        }\n      }\n      if (rejectedCount > 0) {\n        this._logger.warn(\n          `Rejected ${rejectedCount} pending RPC call(s) due to: ${reason}`,\n        );\n      }\n    } catch (e) {\n      this._logger.error(`Error rejecting pending calls: ${e}`);\n    }\n  }\n\n  _cleanupOnDisconnect() {\n    try {\n      // console.debug(\"Cleaning up all sessions due to local RPC disconnection\");\n\n      const keysToDelete = [];\n      for (const key of Object.keys(this._object_store)) {\n        if (key === \"services\" || key === \"message_cache\") continue;\n        const value = this._object_store[key];\n        this._cleanupSessionEntry(value, \"RPC connection closed\");\n        keysToDelete.push(key);\n      }\n\n      for (const key of keysToDelete) {\n        delete this._object_store[key];\n      }\n\n      this._targetIdIndex = {};\n      this._rintfCallerIndex = {};\n    } catch (e) {\n      this._logger.error(`Error during cleanup on disconnect: ${e}`);\n    }\n  }\n\n  async disconnect() {\n    // Store connection reference before closing\n    const connection = this._connection;\n    this.close();\n\n    // Disconnect the underlying connection if it exists\n    if (connection) {\n      try {\n        await connection.disconnect();\n      } catch (e) {\n        // console.debug(`Error disconnecting underlying connection: ${e}`);\n      }\n    }\n  }\n\n  async get_manager_service(config, maxRetries = 20) {\n    config = config || {};\n    const baseDelay = 500;\n    const maxDelay = 10000;\n    let lastError = null;\n\n    for (let attempt = 0; attempt < maxRetries; attempt++) {\n      const retryDelay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);\n\n      if (!this._connection.manager_id) {\n        if (attempt < maxRetries - 1) {\n          this._logger.warn(\n            `Manager ID not set, retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`,\n          );\n          await new Promise((resolve) => setTimeout(resolve, retryDelay));\n          continue;\n        } else {\n          throw new Error(\"Manager ID not set after maximum retries\");\n        }\n      }\n\n      try {\n        const svc = await this.get_remote_service(\n          `*/${this._connection.manager_id}:default`,\n          config,\n        );\n        return svc;\n      } catch (e) {\n        lastError = e;\n        this._logger.warn(\n          `Failed to get manager service (attempt ${attempt + 1}/${maxRetries}): ${e.message}`,\n        );\n        if (attempt < maxRetries - 1) {\n          await new Promise((resolve) => setTimeout(resolve, retryDelay));\n        }\n      }\n    }\n\n    throw lastError;\n  }\n\n  get_all_local_services() {\n    return this._services;\n  }\n  get_local_service(service_id, context) {\n    assert(service_id);\n    assert(context, \"Context is required\");\n\n    const [ws, client_id] = context[\"to\"].split(\"/\");\n    assert(\n      client_id === this._client_id,\n      \"Services can only be accessed locally\",\n    );\n\n    const service = this._services[service_id];\n    if (!service) {\n      throw new Error(\"Service not found: \" + service_id);\n    }\n\n    // Note: Do NOT mutate service.config.workspace here!\n    // Doing so would corrupt the stored service config when called from\n    // a different workspace (e.g., \"public\"), causing reconnection to fail\n    // because _extract_service_info would use the wrong workspace value.\n\n    // allow access for the same workspace\n    if (\n      service.config.visibility == \"public\" ||\n      service.config.visibility == \"unlisted\"\n    ) {\n      return service;\n    }\n\n    // allow access for the same workspace\n    if (context[\"ws\"] === ws) {\n      return service;\n    }\n\n    // Check if user is from an authorized workspace\n    const authorized_workspaces = service.config.authorized_workspaces;\n    if (\n      authorized_workspaces &&\n      authorized_workspaces.includes(context[\"ws\"])\n    ) {\n      return service;\n    }\n\n    throw new Error(\n      `Permission denied for getting protected service: ${service_id}, workspace mismatch: ${ws} != ${context[\"ws\"]}`,\n    );\n  }\n  async get_remote_service(service_uri, config) {\n    let {\n      timeout,\n      case_conversion,\n      kwargs_expansion,\n      encryption_public_key,\n      _no_retry,\n    } = config || {};\n    timeout = timeout === undefined ? this._method_timeout : timeout;\n    if (!service_uri && this._connection.manager_id) {\n      service_uri = \"*/\" + this._connection.manager_id;\n    } else if (!service_uri.includes(\":\")) {\n      service_uri = this._client_id + \":\" + service_uri;\n    }\n    const provider = service_uri.split(\":\")[0];\n    let service_id = service_uri.split(\":\")[1];\n    if (service_id.includes(\"@\")) {\n      service_id = service_id.split(\"@\")[0];\n      const app_id = service_uri.split(\"@\")[1];\n      if (this._app_id && this._app_id !== \"*\")\n        assert(\n          app_id === this._app_id,\n          `Invalid app id: ${app_id} != ${this._app_id}`,\n        );\n    }\n    assert(provider, `Invalid service uri: ${service_uri}`);\n\n    try {\n      const method = this._generate_remote_method({\n        _rserver: this._server_base_url,\n        _rtarget: provider,\n        _rmethod: \"services.built-in.get_service\",\n        _rpromise: true,\n        _rdoc: \"Get a remote service\",\n      });\n      let svc = await waitFor(\n        method(service_id),\n        timeout,\n        \"Timeout Error: Failed to get remote service: \" + service_uri,\n      );\n      svc.id = `${provider}:${service_id}`;\n      if (encryption_public_key) {\n        const encPubBytes = publicKeyFromHex(encryption_public_key);\n        _applyEncryptionKeyToService(svc, encPubBytes);\n      }\n      if (kwargs_expansion) {\n        svc = expandKwargs(svc);\n      }\n      if (case_conversion) {\n        svc = convertCase(svc, case_conversion);\n      }\n      const result = Object.assign(new RemoteService(), svc);\n      if (!_no_retry) {\n        this._wrapServiceMethodsWithRetry(result, service_uri, config || {});\n      }\n      return result;\n    } catch (e) {\n      this._logger.warn(\"Failed to get remote service: \" + service_uri, e);\n      throw e;\n    }\n  }\n\n  _wrapServiceMethodsWithRetry(svc, serviceUri, config) {\n    const rpc = this;\n    for (const key of Object.keys(svc)) {\n      const val = svc[key];\n      if (typeof val !== \"function\") continue;\n      const methodName = key;\n      const originalMethod = val;\n\n      const retryWrapper = async function (...args) {\n        try {\n          return await originalMethod(...args);\n        } catch (e) {\n          if (isStaleServiceError(e)) {\n            console.info(\n              `Stale service error on ${serviceUri}:${methodName}, refreshing and retrying:`,\n              e.message || e,\n            );\n            const retryConfig = { ...config, _no_retry: true };\n            const refreshed = await rpc.get_remote_service(\n              serviceUri,\n              retryConfig,\n            );\n            const newMethod = refreshed[methodName];\n            if (!newMethod) throw e;\n            return await newMethod(...args);\n          }\n          throw e;\n        }\n      };\n\n      // Preserve metadata from the original method\n      retryWrapper.__rpc_object__ = originalMethod.__rpc_object__;\n      retryWrapper.__name__ = originalMethod.__name__ || methodName;\n      retryWrapper.__doc__ = originalMethod.__doc__;\n      retryWrapper.__schema__ = originalMethod.__schema__;\n      svc[key] = retryWrapper;\n    }\n  }\n  _annotate_service_methods(\n    aObject,\n    object_id,\n    require_context,\n    run_in_executor,\n    visibility,\n    authorized_workspaces,\n    trusted_keys,\n    rintf_allowed_caller,\n  ) {\n    if (typeof aObject === \"function\") {\n      // mark the method as a remote method that requires context\n      let method_name = object_id.split(\".\")[1];\n      this._method_annotations.set(aObject, {\n        require_context: Array.isArray(require_context)\n          ? require_context.includes(method_name)\n          : !!require_context,\n        run_in_executor: run_in_executor,\n        method_id: \"services.\" + object_id,\n        visibility: visibility,\n        authorized_workspaces: authorized_workspaces,\n        trusted_keys: trusted_keys,\n        rintf_allowed_caller: rintf_allowed_caller,\n      });\n    } else if (aObject instanceof Array || aObject instanceof Object) {\n      for (let key of Object.keys(aObject)) {\n        let val = aObject[key];\n        if (typeof val === \"function\" && val.__rpc_object__) {\n          let client_id = val.__rpc_object__._rtarget;\n          if (client_id.includes(\"/\")) {\n            client_id = client_id.split(\"/\")[1];\n          }\n          if (this._client_id === client_id) {\n            if (aObject instanceof Array) {\n              aObject = aObject.slice();\n            }\n            // recover local method\n            aObject[key] = indexObject(\n              this._object_store,\n              val.__rpc_object__._rmethod,\n            );\n            val = aObject[key]; // make sure it's annotated later\n          } else {\n            throw new Error(\n              `Local method not found: ${val.__rpc_object__._rmethod}, client id mismatch ${this._client_id} != ${client_id}`,\n            );\n          }\n        }\n        this._annotate_service_methods(\n          val,\n          object_id + \".\" + key,\n          require_context,\n          run_in_executor,\n          visibility,\n          authorized_workspaces,\n          trusted_keys,\n          rintf_allowed_caller,\n        );\n      }\n    }\n  }\n  add_service(api, overwrite) {\n    if (!api || Array.isArray(api)) throw new Error(\"Invalid service object\");\n    if (api.constructor === Object) {\n      api = Object.assign({}, api);\n    } else {\n      const normApi = {};\n      const props = Object.getOwnPropertyNames(api).concat(\n        Object.getOwnPropertyNames(Object.getPrototypeOf(api)),\n      );\n      for (let k of props) {\n        if (k !== \"constructor\") {\n          if (typeof api[k] === \"function\") normApi[k] = api[k].bind(api);\n          else normApi[k] = api[k];\n        }\n      }\n      // For class instance, we need set a default id\n      api.id = api.id || \"default\";\n      api = normApi;\n    }\n    assert(\n      api.id && typeof api.id === \"string\",\n      `Service id not found: ${api}`,\n    );\n    if (!api.name) {\n      api.name = api.id;\n    }\n    if (!api.config) {\n      api.config = {};\n    }\n    if (!api.type) {\n      api.type = \"generic\";\n    }\n    // require_context only applies to the top-level functions\n    let require_context = false,\n      run_in_executor = false;\n    if (api.config.require_context)\n      require_context = api.config.require_context;\n    if (api.config.run_in_executor) run_in_executor = true;\n    const visibility = api.config.visibility || \"protected\";\n    assert([\"protected\", \"public\", \"unlisted\"].includes(visibility));\n\n    // Validate authorized_workspaces\n    const authorized_workspaces = api.config.authorized_workspaces;\n    if (authorized_workspaces !== undefined) {\n      if (visibility !== \"protected\") {\n        throw new Error(\n          `authorized_workspaces can only be set when visibility is 'protected', got visibility='${visibility}'`,\n        );\n      }\n      if (!Array.isArray(authorized_workspaces)) {\n        throw new Error(\n          \"authorized_workspaces must be an array of workspace ids\",\n        );\n      }\n      for (const ws_id of authorized_workspaces) {\n        if (typeof ws_id !== \"string\") {\n          throw new Error(\n            `Each workspace id in authorized_workspaces must be a string, got ${typeof ws_id}`,\n          );\n        }\n      }\n    }\n    const trustedKeysHex = api.config.trusted_keys;\n    let trusted_keys = null;\n    if (trustedKeysHex && trustedKeysHex.length > 0) {\n      if (!Array.isArray(trustedKeysHex)) {\n        throw new Error(\n          \"trusted_keys must be an array of hex-encoded public keys\",\n        );\n      }\n      trusted_keys = new Set();\n      for (const keyHex of trustedKeysHex) {\n        if (typeof keyHex !== \"string\" || keyHex.length !== 64) {\n          throw new Error(\n            `Each trusted key must be a 64-char hex string, got: ${keyHex}`,\n          );\n        }\n        trusted_keys.add(keyHex);\n      }\n    }\n    const rintf_allowed_caller = api.config._rintf_allowed_caller || null;\n    this._annotate_service_methods(\n      api,\n      api[\"id\"],\n      require_context,\n      run_in_executor,\n      visibility,\n      authorized_workspaces,\n      trusted_keys,\n      rintf_allowed_caller,\n    );\n\n    if (this._services[api.id]) {\n      if (overwrite) {\n        delete this._services[api.id];\n      } else {\n        throw new Error(\n          `Service already exists: ${api.id}, please specify a different id (not ${api.id}) or overwrite=true`,\n        );\n      }\n    }\n    this._services[api.id] = api;\n    return api;\n  }\n\n  _extract_service_info(service) {\n    const config = service.config || {};\n    config.workspace =\n      config.workspace || this._local_workspace || this._connection.workspace;\n    if (!config.workspace) {\n      throw new Error(\n        \"Workspace is not set. Please ensure the connection has a workspace or set local_workspace.\",\n      );\n    }\n    const skipContext = config.require_context;\n    const excludeKeys = [\n      \"id\",\n      \"config\",\n      \"name\",\n      \"description\",\n      \"type\",\n      \"docs\",\n      \"app_id\",\n      \"service_schema\",\n    ];\n    const filteredService = {};\n    for (const key of Object.keys(service)) {\n      if (!excludeKeys.includes(key)) {\n        filteredService[key] = service[key];\n      }\n    }\n    const serviceSchema = _get_schema(filteredService, null, skipContext);\n    const serviceInfo = {\n      config: config,\n      id: `${config.workspace}/${this._client_id}:${service[\"id\"]}`,\n      name: service.name || service[\"id\"],\n      description: service.description || \"\",\n      type: service.type || \"generic\",\n      docs: service.docs || null,\n      app_id: this._app_id,\n      service_schema: serviceSchema,\n    };\n    return serviceInfo;\n  }\n\n  async get_service_schema(service) {\n    const skipContext = service.config.require_context;\n    return _get_schema(service, null, skipContext);\n  }\n\n  async register_service(api, config) {\n    let { check_type, notify, overwrite } = config || {};\n    notify = notify === undefined ? true : notify;\n    let manager;\n    if (check_type && api.type) {\n      try {\n        manager = await this.get_manager_service({\n          timeout: 10,\n          case_conversion: \"camel\",\n        });\n        const type_info = await manager.get_service_type(api.type);\n        api = _annotate_service(api, type_info);\n      } catch (e) {\n        throw new Error(`Failed to get service type ${api.type}, error: ${e}`);\n      }\n    }\n\n    const service = this.add_service(api, overwrite);\n    const serviceInfo = this._extract_service_info(service);\n    if (notify) {\n      try {\n        manager =\n          manager ||\n          (await this.get_manager_service({\n            timeout: 10,\n            case_conversion: \"camel\",\n          }));\n        await manager.registerService(serviceInfo);\n      } catch (e) {\n        throw new Error(`Failed to notify workspace manager: ${e}`);\n      }\n    }\n    return serviceInfo;\n  }\n\n  async unregister_service(service, notify) {\n    notify = notify === undefined ? true : notify;\n    let service_id;\n    if (typeof service === \"string\") {\n      service_id = service;\n    } else {\n      service_id = service.id;\n    }\n    assert(\n      service_id && typeof service_id === \"string\",\n      `Invalid service id: ${service_id}`,\n    );\n    if (service_id.includes(\":\")) {\n      service_id = service_id.split(\":\")[1];\n    }\n    if (service_id.includes(\"@\")) {\n      service_id = service_id.split(\"@\")[0];\n    }\n    if (!this._services[service_id]) {\n      throw new Error(`Service not found: ${service_id}`);\n    }\n    // Auto-detect _rintf services (local-only, never registered with server)\n    if (service_id.startsWith(\"_rintf_\")) {\n      notify = false;\n      // Also clean up from the caller index\n      for (const [caller, sids] of Object.entries(this._rintfCallerIndex)) {\n        sids.delete(service_id);\n        if (sids.size === 0) {\n          delete this._rintfCallerIndex[caller];\n        }\n      }\n    }\n    if (notify) {\n      const manager = await this.get_manager_service({\n        timeout: 10,\n        case_conversion: \"camel\",\n      });\n      await manager.unregisterService(service_id);\n    }\n    delete this._services[service_id];\n  }\n\n  _ndarray(typedArray, shape, dtype) {\n    const _dtype = typedArrayToDtype(typedArray);\n    if (dtype && dtype !== _dtype) {\n      throw (\n        \"dtype doesn't match the type of the array: \" + _dtype + \" != \" + dtype\n      );\n    }\n    shape = shape || [typedArray.length];\n    return {\n      _rtype: \"ndarray\",\n      _rvalue: typedArray.buffer,\n      _rshape: shape,\n      _rdtype: _dtype,\n    };\n  }\n\n  _encode_callback(\n    name,\n    callback,\n    session_id,\n    clear_after_called,\n    timer,\n    local_workspace,\n    description,\n  ) {\n    let method_id = `${session_id}.${name}`;\n    let encoded = {\n      _rtype: \"method\",\n      _rtarget: local_workspace\n        ? `${local_workspace}/${this._client_id}`\n        : this._client_id,\n      _rmethod: method_id,\n      _rpromise: false,\n    };\n\n    const self = this;\n    let wrapped_callback = function () {\n      try {\n        callback.apply(null, Array.prototype.slice.call(arguments));\n      } catch (error) {\n        self._logger.error(\n          `Error in callback(${method_id}, ${description}): ${error}`,\n        );\n      } finally {\n        // Clear the timer first if it exists\n        if (timer && timer.started) {\n          timer.clear();\n        }\n\n        // Clean up the entire session when resolve/reject is called\n        if (clear_after_called && self._object_store[session_id]) {\n          if (name === \"resolve\" || name === \"reject\") {\n            self._removeFromTargetIdIndex(session_id);\n            delete self._object_store[session_id];\n          } else {\n            self._cleanup_session_if_needed(session_id, name);\n          }\n        }\n      }\n    };\n    wrapped_callback.__name__ = `callback(${method_id})`;\n    return [encoded, wrapped_callback];\n  }\n\n  _cleanup_session_if_needed(session_id, callback_name) {\n    /**\n     * Clean session management - all logic in one place.\n     */\n    if (!session_id) {\n      // console.debug(\"Cannot cleanup session: session_id is empty\");\n      return;\n    }\n\n    try {\n      const store = this._get_session_store(session_id, false);\n      if (!store) {\n        // console.debug(`Session ${session_id} not found for cleanup`);\n        return;\n      }\n\n      let should_cleanup = false;\n\n      // Promise sessions: let the promise manager decide cleanup\n      if (store._promise_manager) {\n        try {\n          const promise_manager = store._promise_manager;\n          if (\n            promise_manager.should_cleanup_on_callback &&\n            promise_manager.should_cleanup_on_callback(callback_name)\n          ) {\n            if (promise_manager.settle) {\n              promise_manager.settle();\n            }\n            should_cleanup = true;\n            // console.debug(\n              // `Promise session ${session_id} settled and marked for cleanup`,\n            // );\n          }\n        } catch (e) {\n          this._logger.warn(\n            `Error in promise manager cleanup for session ${session_id}:`,\n            e,\n          );\n        }\n      } else {\n        // Regular sessions: only cleanup temporary method call sessions\n        // Don't cleanup service registration sessions or persistent sessions\n        // Only cleanup sessions that are clearly temporary promises for method calls\n        if (\n          (callback_name === \"resolve\" || callback_name === \"reject\") &&\n          store._callbacks &&\n          Object.keys(store._callbacks).includes(callback_name)\n        ) {\n          should_cleanup = true;\n          // console.debug(\n            // `Regular session ${session_id} marked for cleanup after ${callback_name}`,\n          // );\n        }\n      }\n\n      if (should_cleanup) {\n        this._cleanup_session_completely(session_id);\n      }\n    } catch (error) {\n      this._logger.warn(`Error during session cleanup for ${session_id}:`, error);\n    }\n  }\n\n  _cleanup_session_completely(session_id) {\n    /**\n     * Complete session cleanup with resource management.\n     */\n    try {\n      // Clean up target_id index before deleting the session\n      this._removeFromTargetIdIndex(session_id);\n\n      const store = this._get_session_store(session_id, false);\n      if (!store) {\n        // console.debug(`Session ${session_id} already cleaned up`);\n        return;\n      }\n\n      // Clean up resources before removing session\n      if (\n        store.timer &&\n        store.timer.started &&\n        typeof store.timer.clear === \"function\"\n      ) {\n        try {\n          store.timer.clear();\n        } catch (error) {\n          this._logger.warn(\n            `Error clearing timer for session ${session_id}:`,\n            error,\n          );\n        }\n      }\n\n      if (\n        store.heartbeat_task &&\n        typeof store.heartbeat_task.cancel === \"function\"\n      ) {\n        try {\n          store.heartbeat_task.cancel();\n        } catch (error) {\n          this._logger.warn(\n            `Error canceling heartbeat for session ${session_id}:`,\n            error,\n          );\n        }\n      }\n\n      // Navigate and clean session path\n      const levels = session_id.split(\".\");\n      let current_store = this._object_store;\n\n      // Navigate to parent of target level\n      for (let i = 0; i < levels.length - 1; i++) {\n        const level = levels[i];\n        if (!current_store[level]) {\n          // console.debug(\n            // `Session path ${session_id} not found at level ${level}`,\n          // );\n          return;\n        }\n        current_store = current_store[level];\n      }\n\n      // Delete the final level\n      const final_key = levels[levels.length - 1];\n      if (current_store[final_key]) {\n        delete current_store[final_key];\n        // console.debug(`Cleaned up session ${session_id}`);\n\n        // Clean up empty parent containers\n        this._cleanup_empty_containers(levels.slice(0, -1));\n      }\n    } catch (error) {\n      this._logger.warn(\n        `Error in complete session cleanup for ${session_id}:`,\n        error,\n      );\n    }\n  }\n\n  _cleanup_empty_containers(path_levels) {\n    /**\n     * Clean up empty parent containers to prevent memory leaks.\n     */\n    try {\n      // Work backwards from the deepest level\n      for (let depth = path_levels.length - 1; depth >= 0; depth--) {\n        let current_store = this._object_store;\n\n        // Navigate to parent of current depth\n        for (let i = 0; i < depth; i++) {\n          current_store = current_store[path_levels[i]];\n          if (!current_store) return; // Path doesn't exist\n        }\n\n        // Check if container at current depth is empty\n        const container_key = path_levels[depth];\n        const container = current_store[container_key];\n\n        if (\n          container &&\n          typeof container === \"object\" &&\n          Object.keys(container).length === 0\n        ) {\n          delete current_store[container_key];\n          // console.debug(\n            // `Cleaned up empty container at depth ${depth}: ${path_levels.slice(0, depth + 1).join(\".\")}`,\n          // );\n        } else {\n          // Container is not empty, stop cleanup\n          break;\n        }\n      }\n    } catch (error) {\n      this._logger.warn(\"Error cleaning up empty containers:\", error);\n    }\n  }\n\n  get_session_stats() {\n    /**\n     * Get detailed session statistics.\n     */\n    const stats = {\n      total_sessions: 0,\n      promise_sessions: 0,\n      regular_sessions: 0,\n      sessions_with_timers: 0,\n      sessions_with_heartbeat: 0,\n      system_stores: {},\n      session_ids: [],\n      memory_usage: 0,\n    };\n\n    if (!this._object_store) {\n      return stats;\n    }\n\n    for (const key in this._object_store) {\n      const value = this._object_store[key];\n\n      if ([\"services\", \"message_cache\"].includes(key)) {\n        // System stores - don't count these as sessions\n        stats.system_stores[key] = {\n          size:\n            typeof value === \"object\" && value ? Object.keys(value).length : 0,\n        };\n        continue;\n      }\n\n      // Count all non-system non-empty objects as sessions\n      if (value && typeof value === \"object\") {\n        const sessionKeys = Object.keys(value);\n\n        // Only skip completely empty objects\n        if (sessionKeys.length > 0) {\n          stats.total_sessions++;\n          stats.session_ids.push(key);\n\n          if (value._promise_manager) {\n            stats.promise_sessions++;\n          } else {\n            stats.regular_sessions++;\n          }\n\n          if (value._timer || value.timer) stats.sessions_with_timers++;\n          if (value._heartbeat || value.heartbeat)\n            stats.sessions_with_heartbeat++;\n\n          // Estimate memory usage\n          stats.memory_usage += JSON.stringify(value).length;\n        }\n      }\n    }\n\n    return stats;\n  }\n\n  _force_cleanup_all_sessions() {\n    /**\n     * Force cleanup all sessions (for testing purposes).\n     */\n    if (!this._object_store) {\n      // console.debug(\"Force cleaning up 0 sessions\");\n      return;\n    }\n\n    let cleaned_count = 0;\n    const keys_to_delete = [];\n\n    for (const key in this._object_store) {\n      // Don't delete system stores\n      if (![\"services\", \"message_cache\"].includes(key)) {\n        const value = this._object_store[key];\n        if (\n          value &&\n          typeof value === \"object\" &&\n          Object.keys(value).length > 0\n        ) {\n          keys_to_delete.push(key);\n          cleaned_count++;\n        }\n      }\n    }\n\n    // Delete the sessions\n    for (const key of keys_to_delete) {\n      delete this._object_store[key];\n    }\n\n    // Clear the target_id index since all sessions are removed\n    this._targetIdIndex = {};\n    this._rintfCallerIndex = {};\n\n    // console.debug(`Force cleaning up ${cleaned_count} sessions`);\n  }\n\n  _sweepStaleSessions() {\n    const now = Date.now();\n    let swept = 0;\n    for (const key of Object.keys(this._object_store)) {\n      if (key === \"services\" || key === \"message_cache\") continue;\n      const session = this._object_store[key];\n      // Use last-activity time if available, fall back to creation time\n      const lastActivity =\n        session && (session._last_activity_at || session._created_at);\n      if (\n        session &&\n        typeof session === \"object\" &&\n        lastActivity &&\n        now - lastActivity > this._sessionMaxAge\n      ) {\n        // Only sweep sessions that have no timer (active timers mean they are in use)\n        // and no active promise callbacks (resolve/reject mean the session is awaiting a response)\n        if (!session.timer || !session.timer.started) {\n          if (\n            typeof session.resolve === \"function\" ||\n            typeof session.reject === \"function\"\n          ) {\n            // Session still has active promise callbacks, skip it\n            continue;\n          }\n          this._removeFromTargetIdIndex(key);\n          if (session.heartbeat_task) clearInterval(session.heartbeat_task);\n          delete this._object_store[key];\n          swept++;\n        }\n      }\n    }\n    if (swept > 0) {\n      // console.debug(`Swept ${swept} stale session(s)`);\n    }\n  }\n\n  // Clean helper to identify promise method calls by session type\n  _is_promise_method_call(method_path) {\n    const session_id = method_path.split(\".\")[0];\n    const session = this._get_session_store(session_id, false);\n    return session && session._promise_manager;\n  }\n\n  // Simplified Promise Manager - enhanced version\n  _create_promise_manager() {\n    /**\n     * Create a promise manager to track promise state and decide cleanup.\n     */\n    return {\n      should_cleanup_on_callback: (callback_name) => {\n        return [\"resolve\", \"reject\"].includes(callback_name);\n      },\n      settle: () => {\n        // Promise is settled (resolved or rejected)\n        // console.debug(\"Promise settled\");\n      },\n    };\n  }\n\n  async _encode_promise(\n    resolve,\n    reject,\n    session_id,\n    clear_after_called,\n    timer,\n    local_workspace,\n    description,\n  ) {\n    let store = this._get_session_store(session_id, true);\n    if (!store) {\n      this._logger.warn(\n        `Failed to create session store ${session_id}, session management may be impaired`,\n      );\n      store = {};\n    }\n\n    // Clean promise lifecycle management - TYPE-BASED, not string-based\n    store._promise_manager = this._create_promise_manager();\n\n    let encoded = {};\n\n    if (timer && reject && this._method_timeout) {\n      [encoded.heartbeat, store.heartbeat] = this._encode_callback(\n        \"heartbeat\",\n        timer.reset.bind(timer),\n        session_id,\n        false,\n        null,\n        local_workspace,\n      );\n      store.timer = timer;\n      encoded.interval = this._method_timeout / 2;\n    } else {\n      timer = null;\n    }\n\n    [encoded.resolve, store.resolve] = this._encode_callback(\n      \"resolve\",\n      resolve,\n      session_id,\n      clear_after_called,\n      timer,\n      local_workspace,\n      `resolve (${description})`,\n    );\n    [encoded.reject, store.reject] = this._encode_callback(\n      \"reject\",\n      reject,\n      session_id,\n      clear_after_called,\n      timer,\n      local_workspace,\n      `reject (${description})`,\n    );\n    return encoded;\n  }\n\n  async _send_chunks(data, target_id, session_id) {\n    // 1) Get the remote service\n    const remote_services = await this.get_remote_service(\n      `${target_id}:built-in`,\n    );\n    if (!remote_services.message_cache) {\n      throw new Error(\n        \"Remote client does not support message caching for large messages.\",\n      );\n    }\n\n    const message_cache = remote_services.message_cache;\n    const message_id = session_id || randId();\n    const total_size = data.length;\n    const start_time = Date.now(); // measure time\n    const chunk_num = Math.ceil(total_size / this._long_message_chunk_size);\n    if (remote_services.config.api_version >= 3) {\n      await message_cache.create(message_id, !!session_id);\n      const semaphore = new Semaphore(CONCURRENCY_LIMIT);\n\n      const tasks = [];\n      for (let idx = 0; idx < chunk_num; idx++) {\n        const startByte = idx * this._long_message_chunk_size;\n        const chunk = data.slice(\n          startByte,\n          startByte + this._long_message_chunk_size,\n        );\n\n        const taskFn = async () => {\n          await message_cache.set(message_id, idx, chunk, !!session_id);\n          // console.debug(\n          //   `Sending chunk ${idx + 1}/${chunk_num} (total=${total_size} bytes)`,\n          // );\n        };\n\n        // Push into an array, each one runs under the semaphore\n        tasks.push(semaphore.run(taskFn));\n      }\n\n      // Wait for all chunk uploads to finish\n      try {\n        await Promise.all(tasks);\n      } catch (error) {\n        // If any chunk fails, clean up the message cache\n        try {\n          await message_cache.remove(message_id);\n        } catch (cleanupError) {\n          this._logger.error(\n            `Failed to clean up message cache after error: ${cleanupError}`,\n          );\n        }\n        throw error;\n      }\n    } else {\n      // 3) Legacy version (sequential appends):\n      await message_cache.create(message_id, !!session_id);\n      for (let idx = 0; idx < chunk_num; idx++) {\n        const startByte = idx * this._long_message_chunk_size;\n        const chunk = data.slice(\n          startByte,\n          startByte + this._long_message_chunk_size,\n        );\n        await message_cache.append(message_id, chunk, !!session_id);\n        // console.debug(\n        //   `Sending chunk ${idx + 1}/${chunk_num} (total=${total_size} bytes)`,\n        // );\n      }\n    }\n    await message_cache.process(message_id, !!session_id);\n    const durationSec = ((Date.now() - start_time) / 1000).toFixed(2);\n    // console.debug(`All chunks (${total_size} bytes) sent in ${durationSec} s`);\n  }\n\n  emit(main_message, extra_data) {\n    assert(\n      typeof main_message === \"object\" && main_message.type,\n      \"Invalid message, must be an object with a `type` fields.\",\n    );\n    if (!main_message.to) {\n      this._fire(main_message.type, main_message);\n      return;\n    }\n\n    let message_package = msgpack_packb(main_message);\n    if (extra_data) {\n      const extra = msgpack_packb(extra_data);\n      const combined = new Uint8Array(message_package.length + extra.length);\n      combined.set(message_package);\n      combined.set(extra, message_package.length);\n      message_package = combined;\n    }\n    const total_size = message_package.length;\n    if (total_size > this._long_message_chunk_size + 1024) {\n      this._logger.warn(`Sending large message (size=${total_size})`);\n    }\n    return this._emit_message(message_package);\n  }\n\n  _generate_remote_method(\n    encoded_method,\n    remote_parent,\n    local_parent,\n    remote_workspace,\n    local_workspace,\n  ) {\n    let target_id = encoded_method._rtarget;\n    if (remote_workspace && !target_id.includes(\"/\")) {\n      // Don't modify target_id if it starts with */ (workspace manager service)\n      if (!target_id.startsWith(\"*/\")) {\n        if (remote_workspace !== target_id) {\n          target_id = remote_workspace + \"/\" + target_id;\n        }\n        // Fix the target id to be an absolute id\n        encoded_method._rtarget = target_id;\n      }\n    }\n    let method_id = encoded_method._rmethod;\n    let with_promise = encoded_method._rpromise || false;\n    const description = `method: ${method_id}, docs: ${encoded_method._rdoc}`;\n    const self = this;\n\n    function remote_method() {\n      return new Promise(async (resolve, reject) => {\n        try {\n          // Read target_id from encoded_method at call time (not captured\n          // at generation time) so that _rtarget can be updated after\n          // reconnection without regenerating the method closures.\n          const target_id = encoded_method._rtarget;\n          let local_session_id = randId();\n          if (local_parent) {\n            // Store the children session under the parent\n            local_session_id = local_parent + \".\" + local_session_id;\n          }\n          let store = self._get_session_store(local_session_id, true);\n          if (!store) {\n            reject(\n              new Error(\n                `Runtime Error: Failed to get session store ${local_session_id} (context: ${description})`,\n              ),\n            );\n            return;\n          }\n          store[\"target_id\"] = target_id;\n          // Update target_id index for fast session cleanup\n          const topKey = local_session_id.split(\".\")[0];\n          if (!(target_id in self._targetIdIndex)) {\n            self._targetIdIndex[target_id] = new Set();\n          }\n          self._targetIdIndex[target_id].add(topKey);\n          const args = await self._encode(\n            Array.prototype.slice.call(arguments),\n            local_session_id,\n            local_workspace,\n          );\n          const argLength = args.length;\n          // if the last argument is an object, mark it as kwargs\n          const withKwargs =\n            argLength > 0 &&\n            typeof args[argLength - 1] === \"object\" &&\n            args[argLength - 1] !== null &&\n            args[argLength - 1]._rkwargs;\n          if (withKwargs) delete args[argLength - 1]._rkwargs;\n\n          let from_client;\n          if (!self._local_workspace) {\n            from_client = self._client_id;\n          } else {\n            from_client = self._local_workspace + \"/\" + self._client_id;\n          }\n\n          let main_message = {\n            type: \"method\",\n            from: from_client,\n            to: target_id,\n            method: method_id,\n          };\n          let extra_data = {};\n          if (args) {\n            extra_data[\"args\"] = args;\n          }\n          if (withKwargs) {\n            extra_data[\"with_kwargs\"] = withKwargs;\n          }\n\n          // console.log(\n          //   `Calling remote method ${target_id}:${method_id}, session: ${local_session_id}`\n          // );\n          if (remote_parent) {\n            // Set the parent session\n            // Note: It's a session id for the remote, not the current client\n            main_message[\"parent\"] = remote_parent;\n          }\n\n          let timer = null;\n          if (with_promise) {\n            // Only pass the current session id to the remote\n            // if we want to received the result\n            // I.e. the session id won't be passed for promises themselves\n            main_message[\"session\"] = local_session_id;\n            let method_name = `${target_id}:${method_id}`;\n\n            // Create a timer that gets reset by heartbeat\n            // Methods can run indefinitely as long as heartbeat keeps resetting the timer\n            // IMPORTANT: When timeout occurs, we must clean up the session to prevent memory leaks\n            const timeoutCallback = function (error_msg) {\n              // First reject the promise - wrap in Error for proper stack traces\n              reject(new Error(error_msg));\n              // Then clean up the entire session to stop all callbacks\n              if (self._object_store[local_session_id]) {\n                // Clean up target_id index before deleting the session\n                self._removeFromTargetIdIndex(local_session_id);\n                delete self._object_store[local_session_id];\n                // console.debug(\n                  // `Cleaned up session ${local_session_id} after timeout`,\n                // );\n              }\n            };\n\n            // Use shorter timeout for _rintf_ callbacks to fail fast\n            // when the peer holding the callback has disconnected\n            const effectiveTimeout = method_id.includes(\"_rintf_\")\n              ? self._rintf_timeout\n              : self._method_timeout;\n            timer = new Timer(\n              effectiveTimeout,\n              timeoutCallback,\n              [\n                `Method call timed out: ${method_name}, context: ${description}`,\n              ],\n              method_name,\n            );\n            let clear_after_called = true;\n\n            const promiseData = await self._encode_promise(\n              resolve,\n              reject,\n              local_session_id,\n              clear_after_called,\n              timer,\n              local_workspace,\n              description,\n            );\n\n            if (with_promise === true) {\n              extra_data[\"promise\"] = promiseData;\n            } else if (with_promise === \"*\") {\n              extra_data[\"promise\"] = \"*\";\n              extra_data[\"t\"] = effectiveTimeout / 2;\n            } else {\n              throw new Error(`Unsupported promise type: ${with_promise}`);\n            }\n          }\n          // E2E encrypt extra_data if both sides support encryption\n          if (self._encryption_ready) {\n            await self._encryption_ready;\n          }\n          if (\n            extra_data &&\n            self._encryption_enabled &&\n            encoded_method._renc_pub\n          ) {\n            const plaintext = msgpack_packb(extra_data);\n            const { nonce, ciphertext } = await encryptPayload(\n              self._encryption_private_key,\n              new Uint8Array(encoded_method._renc_pub),\n              plaintext,\n            );\n            extra_data = {\n              _enc: {\n                v: 2,\n                pub: self._encryption_public_key,\n                nonce: nonce,\n              },\n              data: ciphertext,\n            };\n          }\n\n          // The message consists of two segments, the main message and extra data\n          let message_package = msgpack_packb(main_message);\n          if (extra_data) {\n            const extra = msgpack_packb(extra_data);\n            const combined = new Uint8Array(\n              message_package.length + extra.length,\n            );\n            combined.set(message_package);\n            combined.set(extra, message_package.length);\n            message_package = combined;\n          }\n          const total_size = message_package.length;\n          if (\n            total_size <= self._long_message_chunk_size + 1024 ||\n            remote_method.__no_chunk__\n          ) {\n            self\n              ._emit_message(message_package)\n              .then(function () {\n                if (timer) {\n                  // Start the timer after message is sent successfully\n                  timer.start();\n                }\n                if (!with_promise) {\n                  // Fire-and-forget: resolve immediately after message is sent.\n                  // Without this, the promise never resolves because no response\n                  // is expected. This is critical for heartbeat callbacks which\n                  // use _rpromise=false and are awaited in a loop.\n                  resolve(null);\n                }\n              })\n              .catch(function (err) {\n                const error_msg = `Failed to send the request when calling method (${target_id}:${method_id}), error: ${err}`;\n                if (reject) {\n                  reject(new Error(error_msg));\n                } else {\n                  // No reject callback available, log the error to prevent unhandled promise rejections\n                  self._logger.warn(\"Unhandled RPC method call error:\", error_msg);\n                }\n                if (timer && timer.started) {\n                  timer.clear();\n                }\n              });\n          } else {\n            // send chunk by chunk\n            self\n              ._send_chunks(message_package, target_id, remote_parent)\n              .then(function () {\n                if (timer) {\n                  // Start the timer after message is sent successfully\n                  timer.start();\n                }\n                if (!with_promise) {\n                  // Fire-and-forget: resolve immediately after message is sent\n                  resolve(null);\n                }\n              })\n              .catch(function (err) {\n                const error_msg = `Failed to send the request when calling method (${target_id}:${method_id}), error: ${err}`;\n                if (reject) {\n                  reject(new Error(error_msg));\n                } else {\n                  // No reject callback available, log the error to prevent unhandled promise rejections\n                  self._logger.warn(\"Unhandled RPC method call error:\", error_msg);\n                }\n                if (timer && timer.started) {\n                  timer.clear();\n                }\n              });\n          }\n        } catch (err) {\n          reject(err);\n        }\n      });\n    }\n\n    // Generate debugging information for the method\n    remote_method.__rpc_object__ = encoded_method;\n    const parts = method_id.split(\".\");\n\n    remote_method.__name__ = encoded_method._rname || parts[parts.length - 1];\n    if (remote_method.__name__.includes(\"#\")) {\n      remote_method.__name__ = remote_method.__name__.split(\"#\")[1];\n    }\n    remote_method.__doc__ =\n      encoded_method._rdoc || `Remote method: ${method_id}`;\n    remote_method.__schema__ = encoded_method._rschema;\n    // Prevent circular chunk sending\n    remote_method.__no_chunk__ =\n      encoded_method._rmethod === \"services.built-in.message_cache.append\";\n    return remote_method;\n  }\n\n  get_client_info() {\n    const services = [];\n    for (let service of Object.values(this._services)) {\n      // Exclude local-only services (e.g. _rintf_ callback proxies)\n      if (service.config && service.config._local_only) continue;\n      services.push(this._extract_service_info(service));\n    }\n\n    return {\n      id: this._client_id,\n      services: services,\n    };\n  }\n\n  async _handle_method(data) {\n    let resolve = null;\n    let reject = null;\n    let heartbeat_task = null;\n    try {\n      assert(data.method && data.ctx && data.from);\n      const method_name = data.from + \":\" + data.method;\n      const remote_workspace = data.from.split(\"/\")[0];\n      const remote_client_id = data.from.split(\"/\")[1];\n      // Make sure the target id is an absolute id\n      data[\"to\"] = data[\"to\"].includes(\"/\")\n        ? data[\"to\"]\n        : remote_workspace + \"/\" + data[\"to\"];\n      data[\"ctx\"][\"to\"] = data[\"to\"];\n      let local_workspace;\n      if (!this._local_workspace) {\n        local_workspace = data[\"to\"].split(\"/\")[0];\n      } else {\n        if (this._local_workspace && this._local_workspace !== \"*\") {\n          assert(\n            data[\"to\"].split(\"/\")[0] === this._local_workspace,\n            \"Workspace mismatch: \" +\n              data[\"to\"].split(\"/\")[0] +\n              \" != \" +\n              this._local_workspace,\n          );\n        }\n        local_workspace = this._local_workspace;\n      }\n      const local_parent = data.parent;\n\n      // E2E Decryption: if extra_data was encrypted, decrypt it now\n      let callerEncryptionPub = null;\n      if (data._enc && this._encryption_enabled) {\n        const encInfo = data._enc;\n        if (encInfo && typeof encInfo === \"object\" && encInfo.v === 2) {\n          callerEncryptionPub = new Uint8Array(encInfo.pub);\n          const nonce = new Uint8Array(encInfo.nonce);\n          const ciphertext = new Uint8Array(data.data);\n          let plaintext;\n          try {\n            plaintext = await decryptPayload(\n              this._encryption_private_key,\n              callerEncryptionPub,\n              nonce,\n              ciphertext,\n            );\n          } catch (e) {\n            throw new Error(\n              `Decryption failed for method ${method_name}. Invalid key or tampered data.`,\n            );\n          }\n          // Unpack original extra_data and merge back\n          const decoded = [];\n          for (const item of decodeMulti(plaintext)) {\n            decoded.push(item);\n          }\n          const originalExtra = decoded[0];\n          delete data._enc;\n          delete data.data;\n          Object.assign(data, originalExtra);\n          // Store caller's encryption pub in context\n          data.ctx.encryption = true;\n          data.ctx.caller_public_key = publicKeyToHex(callerEncryptionPub);\n        }\n      }\n\n      if (data.promise) {\n        // Decode the promise with the remote session id\n        // Such that the session id will be passed to the remote as a parent session id\n        const promise = await this._decode(\n          data.promise === \"*\"\n            ? this._expand_promise(data, callerEncryptionPub)\n            : data.promise,\n          data.session,\n          local_parent,\n          remote_workspace,\n          local_workspace,\n        );\n        resolve = promise.resolve;\n        reject = promise.reject;\n        if (promise.heartbeat && promise.interval) {\n          const _self = this;\n          async function heartbeat() {\n            try {\n              // console.debug(\"Reset heartbeat timer: \" + data.method);\n              await promise.heartbeat();\n            } catch (err) {\n              _self._logger.error(err);\n            }\n          }\n          heartbeat_task = setInterval(heartbeat, promise.interval * 1000);\n          // Store the heartbeat task in the session store for cleanup\n          if (data.session) {\n            const session_store = this._get_session_store(data.session, false);\n            if (session_store) {\n              session_store.heartbeat_task = heartbeat_task;\n            }\n          }\n        }\n      }\n\n      let method;\n\n      try {\n        method = indexObject(this._object_store, data[\"method\"]);\n        // Update last-activity time for session GC\n        const methodParts = data[\"method\"].split(\".\");\n        if (methodParts.length > 1) {\n          const topKey = methodParts[0];\n          if (topKey !== \"services\" && topKey !== \"message_cache\") {\n            // Skip system stores — they are not GC-managed sessions\n            const topSession = this._object_store[topKey];\n            if (topSession && typeof topSession === \"object\") {\n              topSession._last_activity_at = Date.now();\n            }\n          }\n        }\n      } catch (e) {\n        // Clean promise method detection - TYPE-BASED, not string-based\n        if (this._is_promise_method_call(data[\"method\"])) {\n          // console.debug(\n            // `Promise method ${data[\"method\"]} not available (detected by session type), ignoring: ${method_name}`,\n          // );\n          return;\n        }\n\n        // Check if this is a session-based method call that might have expired\n        const method_parts = data[\"method\"].split(\".\");\n        if (method_parts.length > 1) {\n          const session_id = method_parts[0];\n          // Check if the session exists but the specific method doesn't\n          if (session_id in this._object_store) {\n            // console.debug(\n              // `Session ${session_id} exists but method ${data[\"method\"]} not found, likely expired callback: ${method_name}`,\n            // );\n            // For expired callbacks, don't throw an exception, just log and return\n            if (typeof reject === \"function\") {\n              reject(new Error(`Method expired or not found: ${method_name}`));\n            }\n            return;\n          } else {\n            // console.debug(\n              // `Session ${session_id} not found for method ${data[\"method\"]}, likely cleaned up: ${method_name}`,\n            // );\n            // For cleaned up sessions, just log and return without throwing\n            if (typeof reject === \"function\") {\n              reject(new Error(`Session not found: ${method_name}`));\n            }\n            return;\n          }\n        }\n\n        // console.debug(\n          // `Failed to find method ${method_name} at ${this._client_id}`,\n        // );\n        const error = new Error(\n          `Method not found: ${method_name} at ${this._client_id}`,\n        );\n        if (typeof reject === \"function\") {\n          reject(error);\n        } else {\n          // Log the error instead of throwing to prevent unhandled exceptions\n          this._logger.warn(\n            \"Method not found and no reject callback:\",\n            error.message,\n          );\n        }\n        return;\n      }\n\n      assert(\n        method && typeof method === \"function\",\n        \"Invalid method: \" + method_name,\n      );\n\n      // Check permission\n      if (this._method_annotations.has(method)) {\n        // For services, it should not be protected\n        if (this._method_annotations.get(method).visibility === \"protected\") {\n          // Allow access from same workspace\n          if (local_workspace === remote_workspace) {\n            // Access granted\n          }\n          // Check if remote workspace is in authorized_workspaces list\n          else if (\n            this._method_annotations.get(method).authorized_workspaces &&\n            this._method_annotations\n              .get(method)\n              .authorized_workspaces.includes(remote_workspace)\n          ) {\n            // Access granted\n          }\n          // Allow manager access\n          else if (\n            remote_workspace === \"*\" &&\n            remote_client_id === this._connection.manager_id\n          ) {\n            // Access granted\n          }\n          // Allow _rintf callbacks from the specific client they were sent to\n          else if (\n            this._method_annotations.get(method).rintf_allowed_caller\n          ) {\n            const allowed =\n              this._method_annotations.get(method).rintf_allowed_caller;\n            const caller = data.from || \"\";\n            if (caller !== allowed) {\n              throw new Error(\n                \"Permission denied for _rintf callback \" +\n                  method_name +\n                  \", caller \" +\n                  caller +\n                  \" is not the allowed caller \" +\n                  allowed,\n              );\n            }\n            // Access granted — caller matches the _rintf target\n          } else {\n            throw new Error(\n              \"Permission denied for invoking protected method \" +\n                method_name +\n                \", workspace mismatch: \" +\n                local_workspace +\n                \" != \" +\n                remote_workspace,\n            );\n          }\n        }\n      } else {\n        // For sessions, the target_id should match exactly\n        let session_target_id =\n          this._object_store[data.method.split(\".\")[0]].target_id;\n        if (\n          local_workspace === remote_workspace &&\n          session_target_id &&\n          session_target_id.indexOf(\"/\") === -1\n        ) {\n          session_target_id = local_workspace + \"/\" + session_target_id;\n        }\n        if (session_target_id !== data.from) {\n          throw new Error(\n            \"Access denied for method call (\" +\n              method_name +\n              \") from \" +\n              data.from +\n              \" to target \" +\n              session_target_id,\n          );\n        }\n      }\n\n      // Check trusted_keys (encryption-based authentication)\n      if (this._method_annotations.has(method)) {\n        const annotation = this._method_annotations.get(method);\n        if (annotation.trusted_keys) {\n          if (!callerEncryptionPub) {\n            throw new Error(\n              `Encryption required for method ${method_name} (trusted_keys is set)`,\n            );\n          }\n          const callerHex = publicKeyToHex(callerEncryptionPub);\n          if (!annotation.trusted_keys.has(callerHex)) {\n            throw new Error(\n              `Caller's public key is not in the trusted keys list for ${method_name}`,\n            );\n          }\n        }\n      }\n\n      // Make sure the parent session is still open\n      // Skip for service methods — services are persistent and don't\n      // depend on the originating session being alive.\n      if (local_parent && !data.method.startsWith(\"services.\")) {\n        // The parent session should be a session that generate the current method call\n        assert(\n          this._get_session_store(local_parent, true) !== null,\n          \"Parent session was closed: \" + local_parent,\n        );\n      }\n      let args;\n      if (data.args) {\n        args = await this._decode(\n          data.args,\n          data.session,\n          null,\n          remote_workspace,\n          null,\n        );\n      } else {\n        args = [];\n      }\n\n      // Unpack kwargs into positional arguments when with_kwargs is set.\n      // This mirrors Python's _handle_method which pops the last arg as\n      // a kwargs dict and passes it via **kwargs. Since JS doesn't have\n      // **kwargs, we map the dict keys to the function's parameter names.\n      if (data.with_kwargs && args.length > 0) {\n        const kwargs = args.pop();\n        if (typeof kwargs === \"object\" && kwargs !== null) {\n          const paramNames = getParamNames(method);\n          // Filter out 'context' — it's handled separately by require_context\n          const mappableParams = paramNames.filter((n) => n !== \"context\");\n          args = mappableParams.map((name) => kwargs[name]);\n        } else {\n          // Not a dict — push it back (shouldn't happen, but be safe)\n          args.push(kwargs);\n        }\n      }\n\n      if (\n        this._method_annotations.has(method) &&\n        this._method_annotations.get(method).require_context\n      ) {\n        // if args.length + 1 is less than the required number of arguments we will pad with undefined\n        // so we make sure the last argument is the context\n        if (args.length + 1 < method.length) {\n          for (let i = args.length; i < method.length - 1; i++) {\n            args.push(undefined);\n          }\n        }\n        args.push(data.ctx);\n        // assert(\n        //   args.length === method.length,\n        //   `Runtime Error: Invalid number of arguments for method ${method_name}, expected ${method.length} but got ${args.length}`,\n        // );\n      }\n      // console.debug(`Executing method: ${method_name} (${data.method})`);\n      if (data.promise) {\n        const result = method.apply(null, args);\n        if (result instanceof Promise) {\n          result\n            .then((result) => {\n              resolve(result);\n            })\n            .catch((err) => {\n              reject(err);\n            })\n            .finally(() => {\n              clearInterval(heartbeat_task);\n            });\n        } else {\n          resolve(result);\n          clearInterval(heartbeat_task);\n        }\n      } else {\n        method.apply(null, args);\n        clearInterval(heartbeat_task);\n      }\n    } catch (err) {\n      if (reject) {\n        reject(err);\n      } else {\n        this._logger.error(\"Error during calling method: \", err);\n      }\n      clearInterval(heartbeat_task);\n    }\n  }\n\n  encode(aObject, session_id) {\n    return this._encode(aObject, session_id);\n  }\n\n  _get_session_store(session_id, create) {\n    if (!session_id) {\n      return null;\n    }\n    let store = this._object_store;\n    const levels = session_id.split(\".\");\n    if (create) {\n      const last_index = levels.length - 1;\n      for (let level of levels.slice(0, last_index)) {\n        if (!store[level]) {\n          // Instead of returning null, create intermediate sessions as needed\n          store[level] = {};\n        }\n        store = store[level];\n      }\n      // Create the last level\n      if (!store[levels[last_index]]) {\n        store[levels[last_index]] = {};\n        const now = Date.now();\n        store[levels[last_index]]._created_at = now;\n        store[levels[last_index]]._last_activity_at = now;\n      }\n      return store[levels[last_index]];\n    } else {\n      for (let level of levels) {\n        if (!store[level]) {\n          return null;\n        }\n        store = store[level];\n      }\n      return store;\n    }\n  }\n\n  /**\n   * Prepares the provided set of remote method arguments for\n   * sending to the remote site, replaces all the callbacks with\n   * identifiers\n   *\n   * @param {Array} args to wrap\n   *\n   * @returns {Array} wrapped arguments\n   */\n  async _encode(aObject, session_id, local_workspace) {\n    const aType = typeof aObject;\n    if (\n      aType === \"number\" ||\n      aType === \"string\" ||\n      aType === \"boolean\" ||\n      aObject === null ||\n      aObject === undefined ||\n      aObject instanceof Uint8Array\n    ) {\n      return aObject;\n    }\n    if (aObject instanceof ArrayBuffer) {\n      return {\n        _rtype: \"memoryview\",\n        _rvalue: new Uint8Array(aObject),\n      };\n    }\n    // Reuse the remote object\n    if (aObject.__rpc_object__) {\n      const _server = aObject.__rpc_object__._rserver || this._server_base_url;\n      if (_server === this._server_base_url) {\n        return aObject.__rpc_object__;\n      } // else {\n      //   console.debug(\n      //     `Encoding remote function from a different server ${_server}, current server: ${this._server_base_url}`,\n      //   );\n      // }\n    }\n\n    let bObject;\n\n    // skip if already encoded\n    if (aObject.constructor instanceof Object && aObject._rtype) {\n      // make sure the interface functions are encoded\n      const temp = aObject._rtype;\n      delete aObject._rtype;\n      bObject = await this._encode(aObject, session_id, local_workspace);\n      bObject._rtype = temp;\n      return bObject;\n    }\n\n    if (\n      isGenerator(aObject) ||\n      isAsyncGenerator(aObject) ||\n      isAsyncIterator(aObject) ||\n      isSyncIterator(aObject)\n    ) {\n      // Handle generator/iterator objects\n      assert(\n        session_id && typeof session_id === \"string\",\n        \"Session ID is required for generator encoding\",\n      );\n      const object_id = randId();\n      const close_id = object_id + \":close\";\n\n      // Get the session store\n      const store = this._get_session_store(session_id, true);\n      assert(\n        store !== null,\n        `Failed to create session store ${session_id} due to invalid parent`,\n      );\n\n      // Check if it's an async generator/iterator\n      const isAsync = isAsyncGenerator(aObject) || isAsyncIterator(aObject);\n\n      // Define method to get next item from the generator/iterator\n      const nextItemMethod = async () => {\n        if (isAsync) {\n          const result = await aObject.next();\n          if (result.done) {\n            delete store[object_id];\n            delete store[close_id];\n            return { _rtype: \"stop_iteration\" };\n          }\n          return result.value;\n        } else {\n          const result = aObject.next();\n          if (result.done) {\n            delete store[object_id];\n            delete store[close_id];\n            return { _rtype: \"stop_iteration\" };\n          }\n          return result.value;\n        }\n      };\n\n      // Define method to close/cleanup the generator/iterator early\n      const closeGeneratorMethod = async () => {\n        try {\n          if (typeof aObject.return === \"function\") {\n            if (isAsync) {\n              await aObject.return();\n            } else {\n              aObject.return();\n            }\n          }\n        } catch (e) {\n          // ignore close errors\n        } finally {\n          delete store[object_id];\n          delete store[close_id];\n        }\n        return true;\n      };\n\n      // Store both methods in the session\n      store[object_id] = nextItemMethod;\n      store[close_id] = closeGeneratorMethod;\n\n      // Create a method that will be used to fetch the next item from the generator\n      bObject = {\n        _rtype: \"generator\",\n        _rserver: this._server_base_url,\n        _rtarget: this._client_id,\n        _rmethod: `${session_id}.${object_id}`,\n        _rclose_method: `${session_id}.${close_id}`,\n        _rpromise: \"*\",\n        _rdoc: \"Remote generator\",\n      };\n      return bObject;\n    } else if (typeof aObject === \"function\") {\n      if (this._method_annotations.has(aObject)) {\n        let annotation = this._method_annotations.get(aObject);\n        bObject = {\n          _rtype: \"method\",\n          _rserver: this._server_base_url,\n          _rtarget: this._client_id,\n          _rmethod: annotation.method_id,\n          _rpromise: \"*\",\n          _rname: aObject.name,\n        };\n      } else {\n        assert(typeof session_id === \"string\");\n        let object_id;\n        if (aObject.__name__) {\n          object_id = `${randId()}#${aObject.__name__}`;\n        } else {\n          object_id = randId();\n        }\n        bObject = {\n          _rtype: \"method\",\n          _rserver: this._server_base_url,\n          _rtarget: this._client_id,\n          _rmethod: `${session_id}.${object_id}`,\n          _rpromise: \"*\",\n          _rname: aObject.name,\n        };\n        // Attach encryption public key for session methods (e.g. resolve/reject)\n        if (this._encryption_enabled) {\n          bObject._renc_pub = this._encryption_public_key;\n        }\n        let store = this._get_session_store(session_id, true);\n        assert(\n          store !== null,\n          `Failed to create session store ${session_id} due to invalid parent`,\n        );\n        store[object_id] = aObject;\n      }\n      bObject._rdoc = aObject.__doc__;\n      if (!bObject._rdoc) {\n        try {\n          const funcInfo = getFunctionInfo(aObject);\n          if (funcInfo && !bObject._rdoc) {\n            bObject._rdoc = `${funcInfo.doc}`;\n          }\n        } catch (e) {\n          this._logger.error(\"Failed to extract function docstring:\", aObject);\n        }\n      }\n      bObject._rschema = aObject.__schema__;\n      return bObject;\n    }\n    const isarray = Array.isArray(aObject);\n\n    for (let tp of Object.keys(this._codecs)) {\n      const codec = this._codecs[tp];\n      if (codec.encoder && aObject instanceof codec.type) {\n        // TODO: what if multiple encoders found\n        let encodedObj = await Promise.resolve(codec.encoder(aObject));\n        if (encodedObj && !encodedObj._rtype) encodedObj._rtype = codec.name;\n        // encode the functions in the interface object\n        if (typeof encodedObj === \"object\") {\n          const temp = encodedObj._rtype;\n          delete encodedObj._rtype;\n          encodedObj = await this._encode(\n            encodedObj,\n            session_id,\n            local_workspace,\n          );\n          encodedObj._rtype = temp;\n        }\n        bObject = encodedObj;\n        return bObject;\n      }\n    }\n\n    if (\n      /*global tf*/\n      typeof tf !== \"undefined\" &&\n      tf.Tensor &&\n      aObject instanceof tf.Tensor\n    ) {\n      const v_buffer = aObject.dataSync();\n      bObject = {\n        _rtype: \"ndarray\",\n        _rvalue: new Uint8Array(v_buffer.buffer),\n        _rshape: aObject.shape,\n        _rdtype: aObject.dtype,\n      };\n    } else if (\n      /*global nj*/\n      typeof nj !== \"undefined\" &&\n      nj.NdArray &&\n      aObject instanceof nj.NdArray\n    ) {\n      if (!aObject.selection || !aObject.selection.data) {\n        throw new Error(\"Invalid NumJS array: missing selection or data\");\n      }\n      const dtype = typedArrayToDtype(aObject.selection.data);\n      bObject = {\n        _rtype: \"ndarray\",\n        _rvalue: new Uint8Array(aObject.selection.data.buffer),\n        _rshape: aObject.shape,\n        _rdtype: dtype,\n      };\n    } else if (aObject instanceof Error) {\n      this._logger.error(aObject);\n      bObject = {\n        _rtype: \"error\",\n        _rvalue: aObject.toString(),\n        _rtrace: aObject.stack,\n      };\n    }\n    // send objects supported by structure clone algorithm\n    // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n    else if (\n      aObject !== Object(aObject) ||\n      aObject instanceof Boolean ||\n      aObject instanceof String ||\n      aObject instanceof Date ||\n      aObject instanceof RegExp ||\n      (typeof ImageData !== \"undefined\" && aObject instanceof ImageData) ||\n      (typeof FileList !== \"undefined\" && aObject instanceof FileList) ||\n      (typeof FileSystemDirectoryHandle !== \"undefined\" &&\n        aObject instanceof FileSystemDirectoryHandle) ||\n      (typeof FileSystemFileHandle !== \"undefined\" &&\n        aObject instanceof FileSystemFileHandle) ||\n      (typeof FileSystemHandle !== \"undefined\" &&\n        aObject instanceof FileSystemHandle) ||\n      (typeof FileSystemWritableFileStream !== \"undefined\" &&\n        aObject instanceof FileSystemWritableFileStream)\n    ) {\n      bObject = aObject;\n      // TODO: avoid object such as DynamicPlugin instance.\n    } else if (aObject instanceof Blob) {\n      let _current_pos = 0;\n      async function read(length) {\n        let blob;\n        if (length) {\n          blob = aObject.slice(_current_pos, _current_pos + length);\n        } else {\n          blob = aObject.slice(_current_pos);\n        }\n        const ret = new Uint8Array(await blob.arrayBuffer());\n        _current_pos = _current_pos + ret.byteLength;\n        return ret;\n      }\n      function seek(pos) {\n        _current_pos = pos;\n      }\n      bObject = {\n        _rtype: \"iostream\",\n        _rnative: \"js:blob\",\n        type: aObject.type,\n        name: aObject.name,\n        size: aObject.size,\n        path: aObject._path || aObject.webkitRelativePath,\n        read: await this._encode(read, session_id, local_workspace),\n        seek: await this._encode(seek, session_id, local_workspace),\n      };\n    } else if (aObject instanceof ArrayBufferView) {\n      const dtype = typedArrayToDtype(aObject);\n      bObject = {\n        _rtype: \"typedarray\",\n        _rvalue: new Uint8Array(aObject.buffer),\n        _rdtype: dtype,\n      };\n    } else if (aObject instanceof DataView) {\n      bObject = {\n        _rtype: \"memoryview\",\n        _rvalue: new Uint8Array(aObject.buffer),\n      };\n    } else if (aObject instanceof Set) {\n      bObject = {\n        _rtype: \"set\",\n        _rvalue: await this._encode(\n          Array.from(aObject),\n          session_id,\n          local_workspace,\n        ),\n      };\n    } else if (aObject instanceof Map) {\n      bObject = {\n        _rtype: \"orderedmap\",\n        _rvalue: await this._encode(\n          Array.from(aObject),\n          session_id,\n          local_workspace,\n        ),\n      };\n    } else if (\n      aObject.constructor === Object ||\n      Array.isArray(aObject) ||\n      aObject instanceof RemoteService\n    ) {\n      // Auto-register _rintf objects as local services\n      if (\n        !isarray &&\n        aObject._rintf === true &&\n        Object.keys(aObject).some(\n          (k) => !k.startsWith(\"_\") && typeof aObject[k] === \"function\",\n        )\n      ) {\n        const serviceId = `_rintf_${randId()}`;\n        // Resolve the allowed caller from the session's target_id.\n        // Only the client this _rintf is being sent to can call it back.\n        let allowedCaller = null;\n        if (session_id) {\n          const topKey = session_id.split(\".\")[0];\n          const sessionStore = this._object_store[topKey];\n          if (sessionStore && sessionStore.target_id) {\n            allowedCaller = sessionStore.target_id;\n          }\n        }\n        const serviceApi = { id: serviceId };\n        serviceApi.config = {\n          visibility: \"protected\",\n          _local_only: true,\n        };\n        if (allowedCaller) {\n          serviceApi.config._rintf_allowed_caller = allowedCaller;\n        }\n\n        // Add _dispose method for active lifecycle management.\n        // The remote side (allowed caller) can call _dispose() to\n        // actively unregister this _rintf service when it's done.\n        const self = this;\n        serviceApi._dispose = () => {\n          self._unregisterRintfService(serviceId, allowedCaller);\n        };\n\n        for (const k of Object.keys(aObject)) {\n          if (!k.startsWith(\"_\") && typeof aObject[k] === \"function\") {\n            serviceApi[k] = aObject[k];\n          }\n        }\n        this.add_service(serviceApi, true);\n        // Track in caller index for passive cleanup on disconnect\n        if (allowedCaller) {\n          if (!this._rintfCallerIndex[allowedCaller]) {\n            this._rintfCallerIndex[allowedCaller] = new Set();\n          }\n          this._rintfCallerIndex[allowedCaller].add(serviceId);\n        }\n        // Store service_id back on the original object so the caller\n        // can later call rpc.unregister_service(serviceId) to clean up.\n        aObject._rintf_service_id = serviceId;\n        // Encode all values — callables are now annotated as service methods\n        bObject = {};\n        for (const key of Object.keys(aObject)) {\n          bObject[key] = await this._encode(\n            aObject[key],\n            session_id,\n            local_workspace,\n          );\n        }\n        // Encode _dispose so the remote side can call it\n        bObject._dispose = await this._encode(\n          serviceApi._dispose,\n          session_id,\n          local_workspace,\n        );\n        bObject._rintf_service_id = serviceId;\n        return bObject;\n      }\n\n      // Fast path: if all values are primitives, return as-is\n      if (isarray) {\n        if (_allPrimitivesArray(aObject)) return aObject;\n      } else if (\n        !(\"_rtype\" in aObject) &&\n        !(aObject instanceof RemoteService)\n      ) {\n        if (_allPrimitivesObject(aObject)) return aObject;\n      }\n      bObject = isarray ? [] : {};\n      const keys = Object.keys(aObject);\n      for (let k of keys) {\n        bObject[k] = await this._encode(\n          aObject[k],\n          session_id,\n          local_workspace,\n        );\n      }\n    } else {\n      throw `hypha-rpc: Unsupported data type: ${aObject}, you can register a custom codec to encode/decode the object.`;\n    }\n\n    if (!bObject) {\n      throw new Error(\"Failed to encode object\");\n    }\n    return bObject;\n  }\n\n  async decode(aObject) {\n    return await this._decode(aObject);\n  }\n\n  async _decode(\n    aObject,\n    remote_parent,\n    local_parent,\n    remote_workspace,\n    local_workspace,\n  ) {\n    if (!aObject) {\n      return aObject;\n    }\n    let bObject;\n    if (aObject._rtype) {\n      if (\n        this._codecs[aObject._rtype] &&\n        this._codecs[aObject._rtype].decoder\n      ) {\n        const temp = aObject._rtype;\n        delete aObject._rtype;\n        aObject = await this._decode(\n          aObject,\n          remote_parent,\n          local_parent,\n          remote_workspace,\n          local_workspace,\n        );\n        aObject._rtype = temp;\n\n        bObject = await Promise.resolve(\n          this._codecs[aObject._rtype].decoder(aObject),\n        );\n      } else if (aObject._rtype === \"method\") {\n        bObject = this._generate_remote_method(\n          aObject,\n          remote_parent,\n          local_parent,\n          remote_workspace,\n          local_workspace,\n        );\n      } else if (aObject._rtype === \"generator\") {\n        // Capture logger for use in async generator proxy (function scope)\n        const _genLogger = this._logger;\n        // Create a method to fetch next items from the remote generator\n        const gen_method = this._generate_remote_method(\n          aObject,\n          remote_parent,\n          local_parent,\n          remote_workspace,\n          local_workspace,\n        );\n\n        // Create close method if available\n        let close_method = null;\n        if (aObject._rclose_method) {\n          const closeObj = {\n            _rtype: \"method\",\n            _rserver: aObject._rserver,\n            _rtarget: aObject._rtarget,\n            _rmethod: aObject._rclose_method,\n            _rpromise: \"*\",\n          };\n          close_method = this._generate_remote_method(\n            closeObj,\n            remote_parent,\n            local_parent,\n            remote_workspace,\n            local_workspace,\n          );\n        }\n\n        // Create an async generator proxy with cleanup support\n        async function* asyncGeneratorProxy() {\n          let completedNormally = false;\n          try {\n            while (true) {\n              const next_item = await gen_method();\n              // Check for StopIteration signal\n              if (next_item && next_item._rtype === \"stop_iteration\") {\n                completedNormally = true;\n                break;\n              }\n              yield next_item;\n            }\n          } catch (error) {\n            _genLogger.error(\"Error in generator:\", error);\n            throw error;\n          } finally {\n            // If not completed normally, send close signal to clean up remote generator\n            if (!completedNormally && close_method) {\n              try {\n                await close_method();\n              } catch (e) {\n                // ignore close errors\n              }\n            }\n          }\n        }\n        bObject = asyncGeneratorProxy();\n      } else if (aObject._rtype === \"ndarray\") {\n        /*global nj tf*/\n        //create build array/tensor if used in the plugin\n        if (typeof nj !== \"undefined\" && nj.array) {\n          if (Array.isArray(aObject._rvalue)) {\n            aObject._rvalue = aObject._rvalue.reduce(_appendBuffer);\n          }\n          bObject = nj\n            .array(new Uint8(aObject._rvalue), aObject._rdtype)\n            .reshape(aObject._rshape);\n        } else if (typeof tf !== \"undefined\" && tf.Tensor) {\n          if (Array.isArray(aObject._rvalue)) {\n            aObject._rvalue = aObject._rvalue.reduce(_appendBuffer);\n          }\n          const arraytype = dtypeToTypedArray[aObject._rdtype];\n          bObject = tf.tensor(\n            new arraytype(aObject._rvalue),\n            aObject._rshape,\n            aObject._rdtype,\n          );\n        } else {\n          //keep it as regular if transfered to the main app\n          bObject = aObject;\n        }\n      } else if (aObject._rtype === \"error\") {\n        bObject = new Error(\n          \"RemoteError: \" + aObject._rvalue + \"\\n\" + (aObject._rtrace || \"\"),\n        );\n      } else if (aObject._rtype === \"typedarray\") {\n        const arraytype = dtypeToTypedArray[aObject._rdtype];\n        if (!arraytype)\n          throw new Error(\"unsupported dtype: \" + aObject._rdtype);\n        const buffer = aObject._rvalue.buffer.slice(\n          aObject._rvalue.byteOffset,\n          aObject._rvalue.byteOffset + aObject._rvalue.byteLength,\n        );\n        bObject = new arraytype(buffer);\n      } else if (aObject._rtype === \"memoryview\") {\n        bObject = aObject._rvalue.buffer.slice(\n          aObject._rvalue.byteOffset,\n          aObject._rvalue.byteOffset + aObject._rvalue.byteLength,\n        ); // ArrayBuffer\n      } else if (aObject._rtype === \"iostream\") {\n        if (aObject._rnative === \"js:blob\") {\n          const read = await this._generate_remote_method(\n            aObject.read,\n            remote_parent,\n            local_parent,\n            remote_workspace,\n            local_workspace,\n          );\n          const bytes = await read();\n          bObject = new Blob([bytes], {\n            type: aObject.type,\n            name: aObject.name,\n          });\n        } else {\n          bObject = {};\n          for (let k of Object.keys(aObject)) {\n            if (!k.startsWith(\"_\")) {\n              bObject[k] = await this._decode(\n                aObject[k],\n                remote_parent,\n                local_parent,\n                remote_workspace,\n                local_workspace,\n              );\n            }\n          }\n        }\n        bObject[\"__rpc_object__\"] = aObject;\n      } else if (aObject._rtype === \"orderedmap\") {\n        bObject = new Map(\n          await this._decode(\n            aObject._rvalue,\n            remote_parent,\n            local_parent,\n            remote_workspace,\n            local_workspace,\n          ),\n        );\n      } else if (aObject._rtype === \"set\") {\n        bObject = new Set(\n          await this._decode(\n            aObject._rvalue,\n            remote_parent,\n            local_parent,\n            remote_workspace,\n            local_workspace,\n          ),\n        );\n      } else {\n        const temp = aObject._rtype;\n        delete aObject._rtype;\n        bObject = await this._decode(\n          aObject,\n          remote_parent,\n          local_parent,\n          remote_workspace,\n          local_workspace,\n        );\n        bObject._rtype = temp;\n      }\n    } else if (aObject.constructor === Object || Array.isArray(aObject)) {\n      const isarray = Array.isArray(aObject);\n      // Fast path: skip recursive descent if all values are primitives\n      if (isarray) {\n        if (_allPrimitivesArray(aObject)) return aObject;\n      } else {\n        if (_allPrimitivesObject(aObject)) return aObject;\n      }\n      bObject = isarray ? [] : {};\n      for (let k of Object.keys(aObject)) {\n        if (isarray || aObject.hasOwnProperty(k)) {\n          const v = aObject[k];\n          bObject[k] = await this._decode(\n            v,\n            remote_parent,\n            local_parent,\n            remote_workspace,\n            local_workspace,\n          );\n        }\n      }\n    } else {\n      bObject = aObject;\n    }\n    if (bObject === undefined) {\n      throw new Error(\"Failed to decode object\");\n    }\n    return bObject;\n  }\n\n  _expand_promise(data, callerEncryptionPub) {\n    const target = data.from.split(\"/\")[1];\n    const session = data.session;\n    const method = data.method;\n    const heartbeat = {\n      _rtype: \"method\",\n      _rtarget: target,\n      _rmethod: `${session}.heartbeat`,\n      _rdoc: `heartbeat callback for method: ${method}`,\n    };\n    const resolve = {\n      _rtype: \"method\",\n      _rtarget: target,\n      _rmethod: `${session}.resolve`,\n      _rdoc: `resolve callback for method: ${method}`,\n    };\n    const reject = {\n      _rtype: \"method\",\n      _rtarget: target,\n      _rmethod: `${session}.reject`,\n      _rdoc: `reject callback for method: ${method}`,\n    };\n    // Attach caller's encryption pubkey so responses are encrypted back\n    if (callerEncryptionPub) {\n      heartbeat._renc_pub = callerEncryptionPub;\n      resolve._renc_pub = callerEncryptionPub;\n      reject._renc_pub = callerEncryptionPub;\n    }\n    return {\n      heartbeat,\n      resolve,\n      reject,\n      interval: data.t,\n    };\n  }\n}\n","export function randId() {\n  return Math.random().toString(36).substr(2, 10) + new Date().getTime();\n}\n\nexport function toCamelCase(str) {\n  // Check if the string is already in camelCase\n  if (!str.includes(\"_\")) {\n    return str;\n  }\n  // Convert from snake_case to camelCase\n  return str.replace(/_./g, (match) => match[1].toUpperCase());\n}\n\nexport function toSnakeCase(str) {\n  // Convert from camelCase to snake_case\n  return str.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n}\n\nexport function expandKwargs(obj) {\n  if (typeof obj !== \"object\" || obj === null) {\n    return obj; // Return the value if obj is not an object\n  }\n\n  const newObj = Array.isArray(obj) ? [] : {};\n\n  for (const key in obj) {\n    if (obj.hasOwnProperty(key)) {\n      const value = obj[key];\n\n      if (typeof value === \"function\") {\n        newObj[key] = (...args) => {\n          if (args.length === 0) {\n            throw new Error(`Function \"${key}\" expects at least one argument.`);\n          }\n\n          // Check if the last argument is an object\n          const lastArg = args[args.length - 1];\n          let kwargs = {};\n\n          if (\n            typeof lastArg === \"object\" &&\n            lastArg !== null &&\n            !Array.isArray(lastArg)\n          ) {\n            // Extract kwargs from the last argument\n            kwargs = { ...lastArg, _rkwarg: true };\n            args = args.slice(0, -1); // Remove the last argument from args\n          }\n\n          // Call the original function with positional args followed by kwargs\n          return value(...args, kwargs);\n        };\n\n        // Preserve metadata like __name__ and __schema__\n        newObj[key].__name__ = key;\n        if (value.__schema__) {\n          newObj[key].__schema__ = { ...value.__schema__ };\n          newObj[key].__schema__.name = key;\n        }\n      } else {\n        newObj[key] = expandKwargs(value); // Recursively process nested objects\n      }\n    }\n  }\n\n  return newObj;\n}\n\nexport function convertCase(obj, caseType) {\n  if (typeof obj !== \"object\" || obj === null || !caseType) {\n    return obj; // Return the value if obj is not an object\n  }\n\n  const newObj = Array.isArray(obj) ? [] : {};\n\n  for (const key in obj) {\n    if (obj.hasOwnProperty(key)) {\n      const value = obj[key];\n      const camelKey = toCamelCase(key);\n      const snakeKey = toSnakeCase(key);\n\n      if (caseType === \"camel\") {\n        newObj[camelKey] = convertCase(value, caseType);\n        if (typeof value === \"function\") {\n          newObj[camelKey].__name__ = camelKey;\n          if (value.__schema__) {\n            newObj[camelKey].__schema__ = { ...value.__schema__ };\n            newObj[camelKey].__schema__.name = camelKey;\n          }\n        }\n      } else if (caseType === \"snake\") {\n        newObj[snakeKey] = convertCase(value, caseType);\n        if (typeof value === \"function\") {\n          newObj[snakeKey].__name__ = snakeKey;\n          if (value.__schema__) {\n            newObj[snakeKey].__schema__ = { ...value.__schema__ };\n            newObj[snakeKey].__schema__.name = snakeKey;\n          }\n        }\n      } else {\n        // TODO handle schema for camel + snake\n        if (caseType.includes(\"camel\")) {\n          newObj[camelKey] = convertCase(value, \"camel\");\n        }\n        if (caseType.includes(\"snake\")) {\n          newObj[snakeKey] = convertCase(value, \"snake\");\n        }\n      }\n    }\n  }\n\n  return newObj;\n}\n\nexport function parseServiceUrl(url) {\n  // Ensure no trailing slash\n  url = url.replace(/\\/$/, \"\");\n\n  // Regex pattern to match the URL structure\n  const pattern = new RegExp(\n    \"^(https?:\\\\/\\\\/[^/]+)\" + // server_url (http or https followed by domain)\n      \"\\\\/([a-z0-9_-]+)\" + // workspace (lowercase letters, numbers, - or _)\n      \"\\\\/services\\\\/\" + // static part of the URL\n      \"(?:(?<clientId>[a-zA-Z0-9_-]+):)?\" + // optional client_id\n      \"(?<serviceId>[a-zA-Z0-9_-]+)\" + // service_id\n      \"(?:@(?<appId>[a-zA-Z0-9_-]+))?\", // optional app_id\n  );\n\n  const match = url.match(pattern);\n  if (!match) {\n    throw new Error(\"URL does not match the expected pattern\");\n  }\n\n  const serverUrl = match[1];\n  const workspace = match[2];\n  const clientId = match.groups?.clientId || \"*\";\n  const serviceId = match.groups?.serviceId;\n  const appId = match.groups?.appId || \"*\";\n\n  return { serverUrl, workspace, clientId, serviceId, appId };\n}\n\nexport const dtypeToTypedArray = {\n  int8: Int8Array,\n  int16: Int16Array,\n  int32: Int32Array,\n  uint8: Uint8Array,\n  uint16: Uint16Array,\n  uint32: Uint32Array,\n  float32: Float32Array,\n  float64: Float64Array,\n  array: Array,\n};\n\nexport async function loadRequirementsInWindow(requirements) {\n  function _importScript(url) {\n    //url is URL of external file, implementationCode is the code\n    //to be called from the file, location is the location to\n    //insert the <script> element\n    return new Promise((resolve, reject) => {\n      var scriptTag = document.createElement(\"script\");\n      scriptTag.src = url;\n      scriptTag.type = \"text/javascript\";\n      scriptTag.onload = resolve;\n      scriptTag.onreadystatechange = function () {\n        if (this.readyState === \"loaded\" || this.readyState === \"complete\") {\n          resolve();\n        }\n      };\n      scriptTag.onerror = reject;\n      document.head.appendChild(scriptTag);\n    });\n  }\n\n  // support importScripts outside web worker\n  async function importScripts() {\n    var args = Array.prototype.slice.call(arguments),\n      len = args.length,\n      i = 0;\n    for (; i < len; i++) {\n      await _importScript(args[i]);\n    }\n  }\n\n  if (\n    requirements &&\n    (Array.isArray(requirements) || typeof requirements === \"string\")\n  ) {\n    try {\n      var link_node;\n      requirements =\n        typeof requirements === \"string\" ? [requirements] : requirements;\n      if (Array.isArray(requirements)) {\n        for (var i = 0; i < requirements.length; i++) {\n          if (\n            requirements[i].toLowerCase().endsWith(\".css\") ||\n            requirements[i].startsWith(\"css:\")\n          ) {\n            if (requirements[i].startsWith(\"css:\")) {\n              requirements[i] = requirements[i].slice(4);\n            }\n            link_node = document.createElement(\"link\");\n            link_node.rel = \"stylesheet\";\n            link_node.href = requirements[i];\n            document.head.appendChild(link_node);\n          } else if (\n            requirements[i].toLowerCase().endsWith(\".mjs\") ||\n            requirements[i].startsWith(\"mjs:\")\n          ) {\n            // import esmodule\n            if (requirements[i].startsWith(\"mjs:\")) {\n              requirements[i] = requirements[i].slice(4);\n            }\n            await new Function(\"url\", \"return import(url)\")(requirements[i]);\n          } else if (\n            requirements[i].toLowerCase().endsWith(\".js\") ||\n            requirements[i].startsWith(\"js:\")\n          ) {\n            if (requirements[i].startsWith(\"js:\")) {\n              requirements[i] = requirements[i].slice(3);\n            }\n            await importScripts(requirements[i]);\n          } else if (requirements[i].startsWith(\"http\")) {\n            await importScripts(requirements[i]);\n          } else if (requirements[i].startsWith(\"cache:\")) {\n            //ignore cache\n          } else {\n            console.log(\"Unprocessed requirements url: \" + requirements[i]);\n          }\n        }\n      } else {\n        throw \"unsupported requirements definition\";\n      }\n    } catch (e) {\n      throw \"failed to import required scripts: \" + requirements.toString();\n    }\n  }\n}\n\nexport async function loadRequirementsInWebworker(requirements) {\n  if (\n    requirements &&\n    (Array.isArray(requirements) || typeof requirements === \"string\")\n  ) {\n    try {\n      if (!Array.isArray(requirements)) {\n        requirements = [requirements];\n      }\n      for (var i = 0; i < requirements.length; i++) {\n        if (\n          requirements[i].toLowerCase().endsWith(\".css\") ||\n          requirements[i].startsWith(\"css:\")\n        ) {\n          throw \"unable to import css in a webworker\";\n        } else if (\n          requirements[i].toLowerCase().endsWith(\".js\") ||\n          requirements[i].startsWith(\"js:\")\n        ) {\n          if (requirements[i].startsWith(\"js:\")) {\n            requirements[i] = requirements[i].slice(3);\n          }\n          importScripts(requirements[i]);\n        } else if (requirements[i].startsWith(\"http\")) {\n          importScripts(requirements[i]);\n        } else if (requirements[i].startsWith(\"cache:\")) {\n          //ignore cache\n        } else {\n          console.log(\"Unprocessed requirements url: \" + requirements[i]);\n        }\n      }\n    } catch (e) {\n      throw \"failed to import required scripts: \" + requirements.toString();\n    }\n  }\n}\n\nexport function loadRequirements(requirements) {\n  if (\n    typeof WorkerGlobalScope !== \"undefined\" &&\n    self instanceof WorkerGlobalScope\n  ) {\n    return loadRequirementsInWebworker(requirements);\n  } else {\n    return loadRequirementsInWindow(requirements);\n  }\n}\n\nexport function normalizeConfig(config) {\n  config.version = config.version || \"0.1.0\";\n  config.description =\n    config.description || `[TODO: add description for ${config.name} ]`;\n  config.type = config.type || \"rpc-window\";\n  config.id = config.id || randId();\n  config.target_origin = config.target_origin || \"*\";\n  config.allow_execution = config.allow_execution || false;\n  // remove functions\n  config = Object.keys(config).reduce((p, c) => {\n    if (typeof config[c] !== \"function\") p[c] = config[c];\n    return p;\n  }, {});\n  return config;\n}\nexport const typedArrayToDtypeMapping = {\n  Int8Array: \"int8\",\n  Int16Array: \"int16\",\n  Int32Array: \"int32\",\n  Uint8Array: \"uint8\",\n  Uint16Array: \"uint16\",\n  Uint32Array: \"uint32\",\n  Float32Array: \"float32\",\n  Float64Array: \"float64\",\n  Array: \"array\",\n};\n\nconst typedArrayToDtypeKeys = [];\nfor (const arrType of Object.keys(typedArrayToDtypeMapping)) {\n  typedArrayToDtypeKeys.push(eval(arrType));\n}\n\nexport function typedArrayToDtype(obj) {\n  let dtype = typedArrayToDtypeMapping[obj.constructor.name];\n  if (!dtype) {\n    const pt = Object.getPrototypeOf(obj);\n    for (const arrType of typedArrayToDtypeKeys) {\n      if (pt instanceof arrType) {\n        dtype = typedArrayToDtypeMapping[arrType.name];\n        break;\n      }\n    }\n  }\n  return dtype;\n}\n\nfunction cacheUrlInServiceWorker(url) {\n  return new Promise(function (resolve, reject) {\n    const message = {\n      command: \"add\",\n      url: url,\n    };\n    if (!navigator.serviceWorker || !navigator.serviceWorker.register) {\n      reject(\"Service worker is not supported.\");\n      return;\n    }\n    const messageChannel = new MessageChannel();\n    messageChannel.port1.onmessage = function (event) {\n      if (event.data && event.data.error) {\n        reject(event.data.error);\n      } else {\n        resolve(event.data && event.data.result);\n      }\n    };\n\n    if (navigator.serviceWorker && navigator.serviceWorker.controller) {\n      navigator.serviceWorker.controller.postMessage(message, [\n        messageChannel.port2,\n      ]);\n    } else {\n      reject(\"Service worker controller is not available\");\n    }\n  });\n}\n\nexport async function cacheRequirements(requirements) {\n  requirements = requirements || [];\n  if (!Array.isArray(requirements)) {\n    requirements = [requirements];\n  }\n  for (let req of requirements) {\n    //remove prefix\n    if (req.startsWith(\"js:\")) req = req.slice(3);\n    if (req.startsWith(\"css:\")) req = req.slice(4);\n    if (req.startsWith(\"cache:\")) req = req.slice(6);\n    if (!req.startsWith(\"http\")) continue;\n\n    await cacheUrlInServiceWorker(req).catch((e) => {\n      console.error(e);\n    });\n  }\n}\n\nexport function assert(condition, message) {\n  if (!condition) {\n    throw new Error(message || \"Assertion failed\");\n  }\n}\n\n//#Source https://bit.ly/2neWfJ2\nexport function urlJoin(...args) {\n  return args\n    .join(\"/\")\n    .replace(/[\\/]+/g, \"/\")\n    .replace(/^(.+):\\//, \"$1://\")\n    .replace(/^file:/, \"file:/\")\n    .replace(/\\/(\\?|&|#[^!])/g, \"$1\")\n    .replace(/\\?/g, \"&\")\n    .replace(\"&\", \"?\");\n}\n\nexport function waitFor(prom, time, error) {\n  let timer;\n  return Promise.race([\n    prom,\n    new Promise(\n      (_r, rej) =>\n        (timer = setTimeout(() => {\n          rej(error || \"Timeout Error\");\n        }, time * 1000)),\n    ),\n  ]).finally(() => clearTimeout(timer));\n}\n\nexport class MessageEmitter {\n  constructor(debug) {\n    this._event_handlers = {};\n    this._once_handlers = {};\n    this._debug = debug;\n  }\n  emit() {\n    throw new Error(\"emit is not implemented\");\n  }\n  on(event, handler) {\n    if (!this._event_handlers[event]) {\n      this._event_handlers[event] = [];\n    }\n    this._event_handlers[event].push(handler);\n  }\n  once(event, handler) {\n    handler.___event_run_once = true;\n    this.on(event, handler);\n  }\n  off(event, handler) {\n    if (!event && !handler) {\n      // remove all events handlers\n      this._event_handlers = {};\n    } else if (event && !handler) {\n      // remove all hanlders for the event\n      if (this._event_handlers[event]) this._event_handlers[event] = [];\n    } else {\n      // remove a specific handler\n      if (this._event_handlers[event]) {\n        const idx = this._event_handlers[event].indexOf(handler);\n        if (idx >= 0) {\n          this._event_handlers[event].splice(idx, 1);\n        }\n      }\n    }\n  }\n  _fire(event, data) {\n    if (this._event_handlers[event]) {\n      var i = this._event_handlers[event].length;\n      while (i--) {\n        const handler = this._event_handlers[event][i];\n        try {\n          handler(data);\n        } catch (e) {\n          console.error(e);\n        } finally {\n          if (handler.___event_run_once) {\n            this._event_handlers[event].splice(i, 1);\n          }\n        }\n      }\n    } else {\n      if (this._debug) {\n        console.warn(\"unhandled event\", event, data);\n      }\n    }\n  }\n\n  waitFor(event, timeout) {\n    return new Promise((resolve, reject) => {\n      const handler = (data) => {\n        clearTimeout(timer);\n        resolve(data);\n      };\n      this.once(event, handler);\n      const timer = setTimeout(() => {\n        this.off(event, handler);\n        reject(new Error(\"Timeout\"));\n      }, timeout * 1000);\n    });\n  }\n}\n\nexport class Semaphore {\n  constructor(max) {\n    this.max = max;\n    this.queue = [];\n    this.current = 0;\n  }\n  async run(task) {\n    if (this.current >= this.max) {\n      // Wait until a slot is free\n      await new Promise((resolve) => this.queue.push(resolve));\n    }\n    this.current++;\n    try {\n      return await task();\n    } finally {\n      this.current--;\n      if (this.queue.length > 0) {\n        // release one waiter\n        this.queue.shift()();\n      }\n    }\n  }\n}\n\n/**\n * Check if the object is a generator\n * @param {Object} obj - Object to check\n * @returns {boolean} - True if the object is a generator\n */\nexport function isGenerator(obj) {\n  if (!obj) return false;\n\n  return (\n    typeof obj === \"object\" &&\n    typeof obj.next === \"function\" &&\n    typeof obj.throw === \"function\" &&\n    typeof obj.return === \"function\"\n  );\n}\n\n/**\n * Check if an object is an async generator object\n * @param {any} obj - Object to check\n * @returns {boolean} True if object is an async generator object\n */\nexport function isAsyncGenerator(obj) {\n  if (!obj) return false;\n  // Check if it's an async generator object\n  return (\n    typeof obj === \"object\" &&\n    typeof obj.next === \"function\" &&\n    typeof obj.throw === \"function\" &&\n    typeof obj.return === \"function\" &&\n    Symbol.asyncIterator in Object(obj) &&\n    obj[Symbol.toStringTag] === \"AsyncGenerator\"\n  );\n}\n\n/**\n * Check if an object is a custom async iterator (has Symbol.asyncIterator and next()) but not an async generator\n * @param {any} obj - Object to check\n * @returns {boolean} True if object is a custom async iterator\n */\nexport function isAsyncIterator(obj) {\n  if (!obj || isAsyncGenerator(obj)) return false;\n  return (\n    typeof obj === \"object\" &&\n    Symbol.asyncIterator in Object(obj) &&\n    typeof obj.next === \"function\"\n  );\n}\n\n/**\n * Check if an object is a custom sync iterator (has Symbol.iterator and next()) but not a generator\n * @param {any} obj - Object to check\n * @returns {boolean} True if object is a custom sync iterator\n */\nexport function isSyncIterator(obj) {\n  if (!obj || isGenerator(obj)) return false;\n  return (\n    typeof obj === \"object\" &&\n    Symbol.iterator in Object(obj) &&\n    typeof obj.next === \"function\" &&\n    !Array.isArray(obj) &&\n    typeof obj !== \"string\"\n  );\n}\n","import { assert } from \"./index.js\";\n\n// Schema builder utility inspired by Zod for consistent API with Python\nexport const z = {\n  object: (properties) => ({\n    type: \"object\",\n    properties,\n    required: Object.keys(properties).filter(\n      (key) => !properties[key]._optional,\n    ),\n  }),\n\n  string: () => ({ type: \"string\", _optional: false }),\n  number: () => ({ type: \"number\", _optional: false }),\n  integer: () => ({ type: \"integer\", _optional: false }),\n  boolean: () => ({ type: \"boolean\", _optional: false }),\n  array: (items) => ({ type: \"array\", items, _optional: false }),\n\n  // Make field optional\n  optional: (schema) => ({ ...schema, _optional: true }),\n};\n\n// Add description method to schema types\n[\"string\", \"number\", \"integer\", \"boolean\", \"array\"].forEach((type) => {\n  z[type] = () => {\n    const schema = {\n      type: type === \"integer\" ? \"integer\" : type,\n      _optional: false,\n    };\n    schema.describe = (description) => ({ ...schema, description });\n    return schema;\n  };\n});\n\nexport function schemaFunction(\n  func,\n  { schema_type = \"auto\", name = null, description = null, parameters = null },\n) {\n  if (!func || typeof func !== \"function\") {\n    throw Error(\"func should be a function\");\n  }\n  assert(schema_type === \"auto\", \"schema_type should be auto\");\n\n  // If no name provided, try to get it from function\n  const funcName = name || func.name;\n  assert(funcName, \"name should not be null\");\n\n  // If parameters is a z.object result, convert it properly\n  let processedParameters = parameters;\n  if (\n    parameters &&\n    typeof parameters === \"object\" &&\n    parameters.type === \"object\"\n  ) {\n    processedParameters = {\n      type: \"object\",\n      properties: parameters.properties || {},\n      required: parameters.required || [],\n    };\n\n    // Clean up internal _optional flags\n    for (const [key, schema] of Object.entries(\n      processedParameters.properties,\n    )) {\n      if (schema._optional !== undefined) {\n        delete schema._optional;\n      }\n    }\n  }\n\n  assert(\n    processedParameters && processedParameters.type === \"object\",\n    \"parameters should be an object schema\",\n  );\n\n  func.__schema__ = {\n    name: funcName,\n    description: description || \"\",\n    parameters: processedParameters,\n  };\n  return func;\n}\n","import { RPC } from \"./rpc.js\";\nimport { assert, randId } from \"./utils/index.js\";\nimport { schemaFunction } from \"./utils/schema.js\";\n\nclass WebRTCConnection {\n  constructor(channel) {\n    this._data_channel = channel;\n    this._handle_message = null;\n    this._reconnection_token = null;\n    this._handle_disconnected = null;\n    this._handle_connected = () => {};\n    this.manager_id = null;\n    this._data_channel.onopen = async () => {\n      this._handle_connected &&\n        this._handle_connected({ channel: this._data_channel });\n    };\n    this._data_channel.onmessage = async (event) => {\n      let data = event.data;\n      if (data instanceof Blob) {\n        data = await data.arrayBuffer();\n      }\n      if (this._handle_message) {\n        this._handle_message(data);\n      }\n    };\n    this._data_channel.onclose = () => {\n      if (this._handle_disconnected) this._handle_disconnected(\"closed\");\n      console.log(\"data channel closed\");\n      this._data_channel = null;\n    };\n  }\n\n  on_disconnected(handler) {\n    this._handle_disconnected = handler;\n  }\n\n  on_connected(handler) {\n    this._handle_connected = handler;\n  }\n\n  on_message(handler) {\n    assert(handler, \"handler is required\");\n    this._handle_message = handler;\n  }\n\n  async emit_message(data) {\n    assert(this._handle_message, \"No handler for message\");\n    try {\n      this._data_channel.send(data);\n    } catch (exp) {\n      console.error(`Failed to send data, error: ${exp}`);\n      throw exp;\n    }\n  }\n\n  async disconnect(reason) {\n    this._data_channel = null;\n    console.info(`data channel connection disconnected (${reason})`);\n  }\n}\n\nasync function _setupRPC(config) {\n  assert(config.channel, \"No channel provided\");\n  assert(config.workspace, \"No workspace provided\");\n  const channel = config.channel;\n  const clientId = config.client_id || randId();\n  const connection = new WebRTCConnection(channel);\n  config.context = config.context || {};\n  config.context.connection_type = \"webrtc\";\n  config.context.ws = config.workspace;\n  const rpc = new RPC(connection, {\n    client_id: clientId,\n    default_context: config.context,\n    name: config.name,\n    method_timeout: config.method_timeout || 10.0,\n    workspace: config.workspace,\n    app_id: config.app_id,\n    long_message_chunk_size: config.long_message_chunk_size,\n    silent: config.silent || false,\n  });\n  return rpc;\n}\n\nasync function _createOffer(params, server, config, onInit, context) {\n  config = config || {};\n  let offer = new RTCSessionDescription({\n    sdp: params.sdp,\n    type: params.type,\n  });\n\n  let pc = new RTCPeerConnection({\n    iceServers: config.ice_servers || [\n      { urls: [\"stun:stun.l.google.com:19302\"] },\n    ],\n    sdpSemantics: \"unified-plan\",\n  });\n\n  if (server) {\n    pc.addEventListener(\"datachannel\", async (event) => {\n      const channel = event.channel;\n      let ctx = null;\n      if (context && context.user) ctx = { user: context.user, ws: context.ws };\n      const rpc = await _setupRPC({\n        channel: channel,\n        client_id: channel.label,\n        workspace: server.config.workspace,\n        context: ctx,\n      });\n      // Map all the local services to the webrtc client\n      rpc._services = server.rpc._services;\n    });\n  }\n\n  if (onInit) {\n    await onInit(pc);\n  }\n\n  await pc.setRemoteDescription(offer);\n\n  let answer = await pc.createAnswer();\n  await pc.setLocalDescription(answer);\n\n  // Wait for ICE candidates to be gathered (important for Firefox)\n  await new Promise((resolveIce) => {\n    if (pc.iceGatheringState === \"complete\") {\n      resolveIce();\n    } else {\n      pc.addEventListener(\"icegatheringstatechange\", () => {\n        if (pc.iceGatheringState === \"complete\") {\n          resolveIce();\n        }\n      });\n      // Don't wait forever for ICE gathering\n      setTimeout(resolveIce, 5000);\n    }\n  });\n\n  return {\n    sdp: pc.localDescription.sdp,\n    type: pc.localDescription.type,\n    workspace: server.config.workspace,\n  };\n}\n\nasync function getRTCService(server, service_id, config) {\n  config = config || {};\n  config.peer_id = config.peer_id || randId();\n\n  const pc = new RTCPeerConnection({\n    iceServers: config.ice_servers || [\n      { urls: [\"stun:stun.l.google.com:19302\"] },\n    ],\n    sdpSemantics: \"unified-plan\",\n  });\n\n  return new Promise(async (resolve, reject) => {\n    let resolved = false;\n    const timeout = setTimeout(() => {\n      if (!resolved) {\n        resolved = true;\n        pc.close();\n        reject(new Error(\"WebRTC Connection timeout\"));\n      }\n    }, 30000); // Increase timeout to 30 seconds\n\n    try {\n      pc.addEventListener(\n        \"connectionstatechange\",\n        () => {\n          console.log(\"WebRTC Connection state: \", pc.connectionState);\n          if (pc.connectionState === \"failed\") {\n            if (!resolved) {\n              resolved = true;\n              clearTimeout(timeout);\n              pc.close();\n              reject(new Error(\"WebRTC Connection failed\"));\n            }\n          } else if (pc.connectionState === \"closed\") {\n            if (!resolved) {\n              resolved = true;\n              clearTimeout(timeout);\n              reject(new Error(\"WebRTC Connection closed\"));\n            }\n          } else if (pc.connectionState === \"connected\") {\n            console.log(\"WebRTC Connection established successfully\");\n          }\n        },\n        false,\n      );\n\n      // Add ICE connection state change handler for better debugging\n      pc.addEventListener(\"iceconnectionstatechange\", () => {\n        console.log(\"ICE Connection state: \", pc.iceConnectionState);\n        if (pc.iceConnectionState === \"failed\") {\n          if (!resolved) {\n            resolved = true;\n            clearTimeout(timeout);\n            pc.close();\n            reject(new Error(\"ICE Connection failed\"));\n          }\n        }\n      });\n\n      if (config.on_init) {\n        await config.on_init(pc);\n        delete config.on_init;\n      }\n\n      let channel = pc.createDataChannel(config.peer_id, { ordered: true });\n      channel.binaryType = \"arraybuffer\";\n\n      // Wait for ICE gathering to complete before creating offer\n      const offer = await pc.createOffer();\n      await pc.setLocalDescription(offer);\n\n      // Wait for ICE candidates to be gathered (important for Firefox)\n      await new Promise((resolveIce) => {\n        if (pc.iceGatheringState === \"complete\") {\n          resolveIce();\n        } else {\n          pc.addEventListener(\"icegatheringstatechange\", () => {\n            if (pc.iceGatheringState === \"complete\") {\n              resolveIce();\n            }\n          });\n          // Don't wait forever for ICE gathering\n          setTimeout(resolveIce, 5000);\n        }\n      });\n\n      const svc = await server.getService(service_id);\n      const answer = await svc.offer({\n        sdp: pc.localDescription.sdp,\n        type: pc.localDescription.type,\n      });\n\n      channel.onopen = () => {\n        config.channel = channel;\n        config.workspace = answer.workspace;\n        // Increase timeout for Firefox compatibility\n        setTimeout(async () => {\n          if (!resolved) {\n            try {\n              const rpc = await _setupRPC(config);\n              pc.rpc = rpc;\n              async function get_service(name, ...args) {\n                assert(\n                  !name.includes(\":\"),\n                  \"WebRTC service name should not contain ':'\",\n                );\n                assert(\n                  !name.includes(\"/\"),\n                  \"WebRTC service name should not contain '/'\",\n                );\n                return await rpc.get_remote_service(\n                  config.workspace + \"/\" + config.peer_id + \":\" + name,\n                  ...args,\n                );\n              }\n              async function disconnect() {\n                await rpc.disconnect();\n                pc.close();\n              }\n              pc.getService = schemaFunction(get_service, {\n                name: \"getService\",\n                description: \"Get a remote service via webrtc\",\n                parameters: {\n                  type: \"object\",\n                  properties: {\n                    service_id: {\n                      type: \"string\",\n                      description:\n                        \"Service ID. This should be a service id in the format: 'workspace/service_id', 'workspace/client_id:service_id' or 'workspace/client_id:service_id@app_id'\",\n                    },\n                    config: {\n                      type: \"object\",\n                      description: \"Options for the service\",\n                    },\n                  },\n                  required: [\"id\"],\n                },\n              });\n              pc.disconnect = schemaFunction(disconnect, {\n                name: \"disconnect\",\n                description: \"Disconnect from the webrtc connection via webrtc\",\n                parameters: { type: \"object\", properties: {} },\n              });\n              pc.registerCodec = schemaFunction(rpc.register_codec, {\n                name: \"registerCodec\",\n                description: \"Register a codec for the webrtc connection\",\n                parameters: {\n                  type: \"object\",\n                  properties: {\n                    codec: {\n                      type: \"object\",\n                      description: \"Codec to register\",\n                      properties: {\n                        name: { type: \"string\" },\n                        type: {},\n                        encoder: { type: \"function\" },\n                        decoder: { type: \"function\" },\n                      },\n                    },\n                  },\n                },\n              });\n              resolved = true;\n              clearTimeout(timeout);\n              resolve(pc);\n            } catch (e) {\n              if (!resolved) {\n                resolved = true;\n                clearTimeout(timeout);\n                reject(e);\n              }\n            }\n          }\n        }, 1000); // Increase timeout to 1 second for Firefox\n      };\n\n      channel.onclose = () => {\n        if (!resolved) {\n          resolved = true;\n          clearTimeout(timeout);\n          reject(new Error(\"Data channel closed\"));\n        }\n      };\n\n      channel.onerror = (error) => {\n        if (!resolved) {\n          resolved = true;\n          clearTimeout(timeout);\n          reject(new Error(`Data channel error: ${error}`));\n        }\n      };\n\n      await pc.setRemoteDescription(\n        new RTCSessionDescription({\n          sdp: answer.sdp,\n          type: answer.type,\n        }),\n      );\n    } catch (e) {\n      if (!resolved) {\n        resolved = true;\n        clearTimeout(timeout);\n        reject(e);\n      }\n    }\n  });\n}\n\nasync function registerRTCService(server, service_id, config) {\n  config = config || {\n    visibility: \"protected\",\n    require_context: true,\n  };\n  const onInit = config.on_init;\n  delete config.on_init;\n  return await server.registerService({\n    id: service_id,\n    config,\n    offer: (params, context) =>\n      _createOffer(params, server, config, onInit, context),\n  });\n}\n\nexport { getRTCService, registerRTCService };\n","/* (ignored) */","import { utf8DecodeJs } from \"./utils/utf8.mjs\";\nvar DEFAULT_MAX_KEY_LENGTH = 16;\nvar DEFAULT_MAX_LENGTH_PER_KEY = 16;\nvar CachedKeyDecoder = /** @class */ (function () {\n    function CachedKeyDecoder(maxKeyLength, maxLengthPerKey) {\n        if (maxKeyLength === void 0) { maxKeyLength = DEFAULT_MAX_KEY_LENGTH; }\n        if (maxLengthPerKey === void 0) { maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY; }\n        this.maxKeyLength = maxKeyLength;\n        this.maxLengthPerKey = maxLengthPerKey;\n        this.hit = 0;\n        this.miss = 0;\n        // avoid `new Array(N)`, which makes a sparse array,\n        // because a sparse array is typically slower than a non-sparse array.\n        this.caches = [];\n        for (var i = 0; i < this.maxKeyLength; i++) {\n            this.caches.push([]);\n        }\n    }\n    CachedKeyDecoder.prototype.canBeCached = function (byteLength) {\n        return byteLength > 0 && byteLength <= this.maxKeyLength;\n    };\n    CachedKeyDecoder.prototype.find = function (bytes, inputOffset, byteLength) {\n        var records = this.caches[byteLength - 1];\n        FIND_CHUNK: for (var _i = 0, records_1 = records; _i < records_1.length; _i++) {\n            var record = records_1[_i];\n            var recordBytes = record.bytes;\n            for (var j = 0; j < byteLength; j++) {\n                if (recordBytes[j] !== bytes[inputOffset + j]) {\n                    continue FIND_CHUNK;\n                }\n            }\n            return record.str;\n        }\n        return null;\n    };\n    CachedKeyDecoder.prototype.store = function (bytes, value) {\n        var records = this.caches[bytes.length - 1];\n        var record = { bytes: bytes, str: value };\n        if (records.length >= this.maxLengthPerKey) {\n            // `records` are full!\n            // Set `record` to an arbitrary position.\n            records[(Math.random() * records.length) | 0] = record;\n        }\n        else {\n            records.push(record);\n        }\n    };\n    CachedKeyDecoder.prototype.decode = function (bytes, inputOffset, byteLength) {\n        var cachedValue = this.find(bytes, inputOffset, byteLength);\n        if (cachedValue != null) {\n            this.hit++;\n            return cachedValue;\n        }\n        this.miss++;\n        var str = utf8DecodeJs(bytes, inputOffset, byteLength);\n        // Ensure to copy a slice of bytes because the byte may be NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.\n        var slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);\n        this.store(slicedCopyOfBytes, str);\n        return str;\n    };\n    return CachedKeyDecoder;\n}());\nexport { CachedKeyDecoder };\n//# sourceMappingURL=CachedKeyDecoder.mjs.map","var __extends = (this && this.__extends) || (function () {\n    var extendStatics = function (d, b) {\n        extendStatics = Object.setPrototypeOf ||\n            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n        return extendStatics(d, b);\n    };\n    return function (d, b) {\n        if (typeof b !== \"function\" && b !== null)\n            throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n        extendStatics(d, b);\n        function __() { this.constructor = d; }\n        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n    };\n})();\nvar DecodeError = /** @class */ (function (_super) {\n    __extends(DecodeError, _super);\n    function DecodeError(message) {\n        var _this = _super.call(this, message) || this;\n        // fix the prototype chain in a cross-platform way\n        var proto = Object.create(DecodeError.prototype);\n        Object.setPrototypeOf(_this, proto);\n        Object.defineProperty(_this, \"name\", {\n            configurable: true,\n            enumerable: false,\n            value: DecodeError.name,\n        });\n        return _this;\n    }\n    return DecodeError;\n}(Error));\nexport { DecodeError };\n//# sourceMappingURL=DecodeError.mjs.map","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n    function verb(n) { return function (v) { return step([n, v]); }; }\n    function step(op) {\n        if (f) throw new TypeError(\"Generator is already executing.\");\n        while (_) try {\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n            if (y = 0, t) op = [op[0] & 2, t.value];\n            switch (op[0]) {\n                case 0: case 1: t = op; break;\n                case 4: _.label++; return { value: op[1], done: false };\n                case 5: _.label++; y = op[1]; op = [0]; continue;\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                default:\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                    if (t[2]) _.ops.pop();\n                    _.trys.pop(); continue;\n            }\n            op = body.call(thisArg, _);\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n    }\n};\nvar __asyncValues = (this && this.__asyncValues) || function (o) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var m = o[Symbol.asyncIterator], i;\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nvar __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\nvar __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n    function fulfill(value) { resume(\"next\", value); }\n    function reject(value) { resume(\"throw\", value); }\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n};\nimport { prettyByte } from \"./utils/prettyByte.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { getInt64, getUint64, UINT32_MAX } from \"./utils/int.mjs\";\nimport { utf8DecodeJs, TEXT_DECODER_THRESHOLD, utf8DecodeTD } from \"./utils/utf8.mjs\";\nimport { createDataView, ensureUint8Array } from \"./utils/typedArrays.mjs\";\nimport { CachedKeyDecoder } from \"./CachedKeyDecoder.mjs\";\nimport { DecodeError } from \"./DecodeError.mjs\";\nvar isValidMapKeyType = function (key) {\n    var keyType = typeof key;\n    return keyType === \"string\" || keyType === \"number\";\n};\nvar HEAD_BYTE_REQUIRED = -1;\nvar EMPTY_VIEW = new DataView(new ArrayBuffer(0));\nvar EMPTY_BYTES = new Uint8Array(EMPTY_VIEW.buffer);\n// IE11: Hack to support IE11.\n// IE11: Drop this hack and just use RangeError when IE11 is obsolete.\nexport var DataViewIndexOutOfBoundsError = (function () {\n    try {\n        // IE11: The spec says it should throw RangeError,\n        // IE11: but in IE11 it throws TypeError.\n        EMPTY_VIEW.getInt8(0);\n    }\n    catch (e) {\n        return e.constructor;\n    }\n    throw new Error(\"never reached\");\n})();\nvar MORE_DATA = new DataViewIndexOutOfBoundsError(\"Insufficient data\");\nvar sharedCachedKeyDecoder = new CachedKeyDecoder();\nvar Decoder = /** @class */ (function () {\n    function Decoder(extensionCodec, context, maxStrLength, maxBinLength, maxArrayLength, maxMapLength, maxExtLength, keyDecoder) {\n        if (extensionCodec === void 0) { extensionCodec = ExtensionCodec.defaultCodec; }\n        if (context === void 0) { context = undefined; }\n        if (maxStrLength === void 0) { maxStrLength = UINT32_MAX; }\n        if (maxBinLength === void 0) { maxBinLength = UINT32_MAX; }\n        if (maxArrayLength === void 0) { maxArrayLength = UINT32_MAX; }\n        if (maxMapLength === void 0) { maxMapLength = UINT32_MAX; }\n        if (maxExtLength === void 0) { maxExtLength = UINT32_MAX; }\n        if (keyDecoder === void 0) { keyDecoder = sharedCachedKeyDecoder; }\n        this.extensionCodec = extensionCodec;\n        this.context = context;\n        this.maxStrLength = maxStrLength;\n        this.maxBinLength = maxBinLength;\n        this.maxArrayLength = maxArrayLength;\n        this.maxMapLength = maxMapLength;\n        this.maxExtLength = maxExtLength;\n        this.keyDecoder = keyDecoder;\n        this.totalPos = 0;\n        this.pos = 0;\n        this.view = EMPTY_VIEW;\n        this.bytes = EMPTY_BYTES;\n        this.headByte = HEAD_BYTE_REQUIRED;\n        this.stack = [];\n    }\n    Decoder.prototype.reinitializeState = function () {\n        this.totalPos = 0;\n        this.headByte = HEAD_BYTE_REQUIRED;\n        this.stack.length = 0;\n        // view, bytes, and pos will be re-initialized in setBuffer()\n    };\n    Decoder.prototype.setBuffer = function (buffer) {\n        this.bytes = ensureUint8Array(buffer);\n        this.view = createDataView(this.bytes);\n        this.pos = 0;\n    };\n    Decoder.prototype.appendBuffer = function (buffer) {\n        if (this.headByte === HEAD_BYTE_REQUIRED && !this.hasRemaining(1)) {\n            this.setBuffer(buffer);\n        }\n        else {\n            var remainingData = this.bytes.subarray(this.pos);\n            var newData = ensureUint8Array(buffer);\n            // concat remainingData + newData\n            var newBuffer = new Uint8Array(remainingData.length + newData.length);\n            newBuffer.set(remainingData);\n            newBuffer.set(newData, remainingData.length);\n            this.setBuffer(newBuffer);\n        }\n    };\n    Decoder.prototype.hasRemaining = function (size) {\n        return this.view.byteLength - this.pos >= size;\n    };\n    Decoder.prototype.createExtraByteError = function (posToShow) {\n        var _a = this, view = _a.view, pos = _a.pos;\n        return new RangeError(\"Extra \".concat(view.byteLength - pos, \" of \").concat(view.byteLength, \" byte(s) found at buffer[\").concat(posToShow, \"]\"));\n    };\n    /**\n     * @throws {@link DecodeError}\n     * @throws {@link RangeError}\n     */\n    Decoder.prototype.decode = function (buffer) {\n        this.reinitializeState();\n        this.setBuffer(buffer);\n        var object = this.doDecodeSync();\n        if (this.hasRemaining(1)) {\n            throw this.createExtraByteError(this.pos);\n        }\n        return object;\n    };\n    Decoder.prototype.decodeMulti = function (buffer) {\n        return __generator(this, function (_a) {\n            switch (_a.label) {\n                case 0:\n                    this.reinitializeState();\n                    this.setBuffer(buffer);\n                    _a.label = 1;\n                case 1:\n                    if (!this.hasRemaining(1)) return [3 /*break*/, 3];\n                    return [4 /*yield*/, this.doDecodeSync()];\n                case 2:\n                    _a.sent();\n                    return [3 /*break*/, 1];\n                case 3: return [2 /*return*/];\n            }\n        });\n    };\n    Decoder.prototype.decodeAsync = function (stream) {\n        var stream_1, stream_1_1;\n        var e_1, _a;\n        return __awaiter(this, void 0, void 0, function () {\n            var decoded, object, buffer, e_1_1, _b, headByte, pos, totalPos;\n            return __generator(this, function (_c) {\n                switch (_c.label) {\n                    case 0:\n                        decoded = false;\n                        _c.label = 1;\n                    case 1:\n                        _c.trys.push([1, 6, 7, 12]);\n                        stream_1 = __asyncValues(stream);\n                        _c.label = 2;\n                    case 2: return [4 /*yield*/, stream_1.next()];\n                    case 3:\n                        if (!(stream_1_1 = _c.sent(), !stream_1_1.done)) return [3 /*break*/, 5];\n                        buffer = stream_1_1.value;\n                        if (decoded) {\n                            throw this.createExtraByteError(this.totalPos);\n                        }\n                        this.appendBuffer(buffer);\n                        try {\n                            object = this.doDecodeSync();\n                            decoded = true;\n                        }\n                        catch (e) {\n                            if (!(e instanceof DataViewIndexOutOfBoundsError)) {\n                                throw e; // rethrow\n                            }\n                            // fallthrough\n                        }\n                        this.totalPos += this.pos;\n                        _c.label = 4;\n                    case 4: return [3 /*break*/, 2];\n                    case 5: return [3 /*break*/, 12];\n                    case 6:\n                        e_1_1 = _c.sent();\n                        e_1 = { error: e_1_1 };\n                        return [3 /*break*/, 12];\n                    case 7:\n                        _c.trys.push([7, , 10, 11]);\n                        if (!(stream_1_1 && !stream_1_1.done && (_a = stream_1.return))) return [3 /*break*/, 9];\n                        return [4 /*yield*/, _a.call(stream_1)];\n                    case 8:\n                        _c.sent();\n                        _c.label = 9;\n                    case 9: return [3 /*break*/, 11];\n                    case 10:\n                        if (e_1) throw e_1.error;\n                        return [7 /*endfinally*/];\n                    case 11: return [7 /*endfinally*/];\n                    case 12:\n                        if (decoded) {\n                            if (this.hasRemaining(1)) {\n                                throw this.createExtraByteError(this.totalPos);\n                            }\n                            return [2 /*return*/, object];\n                        }\n                        _b = this, headByte = _b.headByte, pos = _b.pos, totalPos = _b.totalPos;\n                        throw new RangeError(\"Insufficient data in parsing \".concat(prettyByte(headByte), \" at \").concat(totalPos, \" (\").concat(pos, \" in the current buffer)\"));\n                }\n            });\n        });\n    };\n    Decoder.prototype.decodeArrayStream = function (stream) {\n        return this.decodeMultiAsync(stream, true);\n    };\n    Decoder.prototype.decodeStream = function (stream) {\n        return this.decodeMultiAsync(stream, false);\n    };\n    Decoder.prototype.decodeMultiAsync = function (stream, isArray) {\n        return __asyncGenerator(this, arguments, function decodeMultiAsync_1() {\n            var isArrayHeaderRequired, arrayItemsLeft, stream_2, stream_2_1, buffer, e_2, e_3_1;\n            var e_3, _a;\n            return __generator(this, function (_b) {\n                switch (_b.label) {\n                    case 0:\n                        isArrayHeaderRequired = isArray;\n                        arrayItemsLeft = -1;\n                        _b.label = 1;\n                    case 1:\n                        _b.trys.push([1, 13, 14, 19]);\n                        stream_2 = __asyncValues(stream);\n                        _b.label = 2;\n                    case 2: return [4 /*yield*/, __await(stream_2.next())];\n                    case 3:\n                        if (!(stream_2_1 = _b.sent(), !stream_2_1.done)) return [3 /*break*/, 12];\n                        buffer = stream_2_1.value;\n                        if (isArray && arrayItemsLeft === 0) {\n                            throw this.createExtraByteError(this.totalPos);\n                        }\n                        this.appendBuffer(buffer);\n                        if (isArrayHeaderRequired) {\n                            arrayItemsLeft = this.readArraySize();\n                            isArrayHeaderRequired = false;\n                            this.complete();\n                        }\n                        _b.label = 4;\n                    case 4:\n                        _b.trys.push([4, 9, , 10]);\n                        _b.label = 5;\n                    case 5:\n                        if (!true) return [3 /*break*/, 8];\n                        return [4 /*yield*/, __await(this.doDecodeSync())];\n                    case 6: return [4 /*yield*/, _b.sent()];\n                    case 7:\n                        _b.sent();\n                        if (--arrayItemsLeft === 0) {\n                            return [3 /*break*/, 8];\n                        }\n                        return [3 /*break*/, 5];\n                    case 8: return [3 /*break*/, 10];\n                    case 9:\n                        e_2 = _b.sent();\n                        if (!(e_2 instanceof DataViewIndexOutOfBoundsError)) {\n                            throw e_2; // rethrow\n                        }\n                        return [3 /*break*/, 10];\n                    case 10:\n                        this.totalPos += this.pos;\n                        _b.label = 11;\n                    case 11: return [3 /*break*/, 2];\n                    case 12: return [3 /*break*/, 19];\n                    case 13:\n                        e_3_1 = _b.sent();\n                        e_3 = { error: e_3_1 };\n                        return [3 /*break*/, 19];\n                    case 14:\n                        _b.trys.push([14, , 17, 18]);\n                        if (!(stream_2_1 && !stream_2_1.done && (_a = stream_2.return))) return [3 /*break*/, 16];\n                        return [4 /*yield*/, __await(_a.call(stream_2))];\n                    case 15:\n                        _b.sent();\n                        _b.label = 16;\n                    case 16: return [3 /*break*/, 18];\n                    case 17:\n                        if (e_3) throw e_3.error;\n                        return [7 /*endfinally*/];\n                    case 18: return [7 /*endfinally*/];\n                    case 19: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    Decoder.prototype.doDecodeSync = function () {\n        DECODE: while (true) {\n            var headByte = this.readHeadByte();\n            var object = void 0;\n            if (headByte >= 0xe0) {\n                // negative fixint (111x xxxx) 0xe0 - 0xff\n                object = headByte - 0x100;\n            }\n            else if (headByte < 0xc0) {\n                if (headByte < 0x80) {\n                    // positive fixint (0xxx xxxx) 0x00 - 0x7f\n                    object = headByte;\n                }\n                else if (headByte < 0x90) {\n                    // fixmap (1000 xxxx) 0x80 - 0x8f\n                    var size = headByte - 0x80;\n                    if (size !== 0) {\n                        this.pushMapState(size);\n                        this.complete();\n                        continue DECODE;\n                    }\n                    else {\n                        object = {};\n                    }\n                }\n                else if (headByte < 0xa0) {\n                    // fixarray (1001 xxxx) 0x90 - 0x9f\n                    var size = headByte - 0x90;\n                    if (size !== 0) {\n                        this.pushArrayState(size);\n                        this.complete();\n                        continue DECODE;\n                    }\n                    else {\n                        object = [];\n                    }\n                }\n                else {\n                    // fixstr (101x xxxx) 0xa0 - 0xbf\n                    var byteLength = headByte - 0xa0;\n                    object = this.decodeUtf8String(byteLength, 0);\n                }\n            }\n            else if (headByte === 0xc0) {\n                // nil\n                object = null;\n            }\n            else if (headByte === 0xc2) {\n                // false\n                object = false;\n            }\n            else if (headByte === 0xc3) {\n                // true\n                object = true;\n            }\n            else if (headByte === 0xca) {\n                // float 32\n                object = this.readF32();\n            }\n            else if (headByte === 0xcb) {\n                // float 64\n                object = this.readF64();\n            }\n            else if (headByte === 0xcc) {\n                // uint 8\n                object = this.readU8();\n            }\n            else if (headByte === 0xcd) {\n                // uint 16\n                object = this.readU16();\n            }\n            else if (headByte === 0xce) {\n                // uint 32\n                object = this.readU32();\n            }\n            else if (headByte === 0xcf) {\n                // uint 64\n                object = this.readU64();\n            }\n            else if (headByte === 0xd0) {\n                // int 8\n                object = this.readI8();\n            }\n            else if (headByte === 0xd1) {\n                // int 16\n                object = this.readI16();\n            }\n            else if (headByte === 0xd2) {\n                // int 32\n                object = this.readI32();\n            }\n            else if (headByte === 0xd3) {\n                // int 64\n                object = this.readI64();\n            }\n            else if (headByte === 0xd9) {\n                // str 8\n                var byteLength = this.lookU8();\n                object = this.decodeUtf8String(byteLength, 1);\n            }\n            else if (headByte === 0xda) {\n                // str 16\n                var byteLength = this.lookU16();\n                object = this.decodeUtf8String(byteLength, 2);\n            }\n            else if (headByte === 0xdb) {\n                // str 32\n                var byteLength = this.lookU32();\n                object = this.decodeUtf8String(byteLength, 4);\n            }\n            else if (headByte === 0xdc) {\n                // array 16\n                var size = this.readU16();\n                if (size !== 0) {\n                    this.pushArrayState(size);\n                    this.complete();\n                    continue DECODE;\n                }\n                else {\n                    object = [];\n                }\n            }\n            else if (headByte === 0xdd) {\n                // array 32\n                var size = this.readU32();\n                if (size !== 0) {\n                    this.pushArrayState(size);\n                    this.complete();\n                    continue DECODE;\n                }\n                else {\n                    object = [];\n                }\n            }\n            else if (headByte === 0xde) {\n                // map 16\n                var size = this.readU16();\n                if (size !== 0) {\n                    this.pushMapState(size);\n                    this.complete();\n                    continue DECODE;\n                }\n                else {\n                    object = {};\n                }\n            }\n            else if (headByte === 0xdf) {\n                // map 32\n                var size = this.readU32();\n                if (size !== 0) {\n                    this.pushMapState(size);\n                    this.complete();\n                    continue DECODE;\n                }\n                else {\n                    object = {};\n                }\n            }\n            else if (headByte === 0xc4) {\n                // bin 8\n                var size = this.lookU8();\n                object = this.decodeBinary(size, 1);\n            }\n            else if (headByte === 0xc5) {\n                // bin 16\n                var size = this.lookU16();\n                object = this.decodeBinary(size, 2);\n            }\n            else if (headByte === 0xc6) {\n                // bin 32\n                var size = this.lookU32();\n                object = this.decodeBinary(size, 4);\n            }\n            else if (headByte === 0xd4) {\n                // fixext 1\n                object = this.decodeExtension(1, 0);\n            }\n            else if (headByte === 0xd5) {\n                // fixext 2\n                object = this.decodeExtension(2, 0);\n            }\n            else if (headByte === 0xd6) {\n                // fixext 4\n                object = this.decodeExtension(4, 0);\n            }\n            else if (headByte === 0xd7) {\n                // fixext 8\n                object = this.decodeExtension(8, 0);\n            }\n            else if (headByte === 0xd8) {\n                // fixext 16\n                object = this.decodeExtension(16, 0);\n            }\n            else if (headByte === 0xc7) {\n                // ext 8\n                var size = this.lookU8();\n                object = this.decodeExtension(size, 1);\n            }\n            else if (headByte === 0xc8) {\n                // ext 16\n                var size = this.lookU16();\n                object = this.decodeExtension(size, 2);\n            }\n            else if (headByte === 0xc9) {\n                // ext 32\n                var size = this.lookU32();\n                object = this.decodeExtension(size, 4);\n            }\n            else {\n                throw new DecodeError(\"Unrecognized type byte: \".concat(prettyByte(headByte)));\n            }\n            this.complete();\n            var stack = this.stack;\n            while (stack.length > 0) {\n                // arrays and maps\n                var state = stack[stack.length - 1];\n                if (state.type === 0 /* State.ARRAY */) {\n                    state.array[state.position] = object;\n                    state.position++;\n                    if (state.position === state.size) {\n                        stack.pop();\n                        object = state.array;\n                    }\n                    else {\n                        continue DECODE;\n                    }\n                }\n                else if (state.type === 1 /* State.MAP_KEY */) {\n                    if (!isValidMapKeyType(object)) {\n                        throw new DecodeError(\"The type of key must be string or number but \" + typeof object);\n                    }\n                    if (object === \"__proto__\") {\n                        throw new DecodeError(\"The key __proto__ is not allowed\");\n                    }\n                    state.key = object;\n                    state.type = 2 /* State.MAP_VALUE */;\n                    continue DECODE;\n                }\n                else {\n                    // it must be `state.type === State.MAP_VALUE` here\n                    state.map[state.key] = object;\n                    state.readCount++;\n                    if (state.readCount === state.size) {\n                        stack.pop();\n                        object = state.map;\n                    }\n                    else {\n                        state.key = null;\n                        state.type = 1 /* State.MAP_KEY */;\n                        continue DECODE;\n                    }\n                }\n            }\n            return object;\n        }\n    };\n    Decoder.prototype.readHeadByte = function () {\n        if (this.headByte === HEAD_BYTE_REQUIRED) {\n            this.headByte = this.readU8();\n            // console.log(\"headByte\", prettyByte(this.headByte));\n        }\n        return this.headByte;\n    };\n    Decoder.prototype.complete = function () {\n        this.headByte = HEAD_BYTE_REQUIRED;\n    };\n    Decoder.prototype.readArraySize = function () {\n        var headByte = this.readHeadByte();\n        switch (headByte) {\n            case 0xdc:\n                return this.readU16();\n            case 0xdd:\n                return this.readU32();\n            default: {\n                if (headByte < 0xa0) {\n                    return headByte - 0x90;\n                }\n                else {\n                    throw new DecodeError(\"Unrecognized array type byte: \".concat(prettyByte(headByte)));\n                }\n            }\n        }\n    };\n    Decoder.prototype.pushMapState = function (size) {\n        if (size > this.maxMapLength) {\n            throw new DecodeError(\"Max length exceeded: map length (\".concat(size, \") > maxMapLengthLength (\").concat(this.maxMapLength, \")\"));\n        }\n        this.stack.push({\n            type: 1 /* State.MAP_KEY */,\n            size: size,\n            key: null,\n            readCount: 0,\n            map: {},\n        });\n    };\n    Decoder.prototype.pushArrayState = function (size) {\n        if (size > this.maxArrayLength) {\n            throw new DecodeError(\"Max length exceeded: array length (\".concat(size, \") > maxArrayLength (\").concat(this.maxArrayLength, \")\"));\n        }\n        this.stack.push({\n            type: 0 /* State.ARRAY */,\n            size: size,\n            array: new Array(size),\n            position: 0,\n        });\n    };\n    Decoder.prototype.decodeUtf8String = function (byteLength, headerOffset) {\n        var _a;\n        if (byteLength > this.maxStrLength) {\n            throw new DecodeError(\"Max length exceeded: UTF-8 byte length (\".concat(byteLength, \") > maxStrLength (\").concat(this.maxStrLength, \")\"));\n        }\n        if (this.bytes.byteLength < this.pos + headerOffset + byteLength) {\n            throw MORE_DATA;\n        }\n        var offset = this.pos + headerOffset;\n        var object;\n        if (this.stateIsMapKey() && ((_a = this.keyDecoder) === null || _a === void 0 ? void 0 : _a.canBeCached(byteLength))) {\n            object = this.keyDecoder.decode(this.bytes, offset, byteLength);\n        }\n        else if (byteLength > TEXT_DECODER_THRESHOLD) {\n            object = utf8DecodeTD(this.bytes, offset, byteLength);\n        }\n        else {\n            object = utf8DecodeJs(this.bytes, offset, byteLength);\n        }\n        this.pos += headerOffset + byteLength;\n        return object;\n    };\n    Decoder.prototype.stateIsMapKey = function () {\n        if (this.stack.length > 0) {\n            var state = this.stack[this.stack.length - 1];\n            return state.type === 1 /* State.MAP_KEY */;\n        }\n        return false;\n    };\n    Decoder.prototype.decodeBinary = function (byteLength, headOffset) {\n        if (byteLength > this.maxBinLength) {\n            throw new DecodeError(\"Max length exceeded: bin length (\".concat(byteLength, \") > maxBinLength (\").concat(this.maxBinLength, \")\"));\n        }\n        if (!this.hasRemaining(byteLength + headOffset)) {\n            throw MORE_DATA;\n        }\n        var offset = this.pos + headOffset;\n        var object = this.bytes.subarray(offset, offset + byteLength);\n        this.pos += headOffset + byteLength;\n        return object;\n    };\n    Decoder.prototype.decodeExtension = function (size, headOffset) {\n        if (size > this.maxExtLength) {\n            throw new DecodeError(\"Max length exceeded: ext length (\".concat(size, \") > maxExtLength (\").concat(this.maxExtLength, \")\"));\n        }\n        var extType = this.view.getInt8(this.pos + headOffset);\n        var data = this.decodeBinary(size, headOffset + 1 /* extType */);\n        return this.extensionCodec.decode(data, extType, this.context);\n    };\n    Decoder.prototype.lookU8 = function () {\n        return this.view.getUint8(this.pos);\n    };\n    Decoder.prototype.lookU16 = function () {\n        return this.view.getUint16(this.pos);\n    };\n    Decoder.prototype.lookU32 = function () {\n        return this.view.getUint32(this.pos);\n    };\n    Decoder.prototype.readU8 = function () {\n        var value = this.view.getUint8(this.pos);\n        this.pos++;\n        return value;\n    };\n    Decoder.prototype.readI8 = function () {\n        var value = this.view.getInt8(this.pos);\n        this.pos++;\n        return value;\n    };\n    Decoder.prototype.readU16 = function () {\n        var value = this.view.getUint16(this.pos);\n        this.pos += 2;\n        return value;\n    };\n    Decoder.prototype.readI16 = function () {\n        var value = this.view.getInt16(this.pos);\n        this.pos += 2;\n        return value;\n    };\n    Decoder.prototype.readU32 = function () {\n        var value = this.view.getUint32(this.pos);\n        this.pos += 4;\n        return value;\n    };\n    Decoder.prototype.readI32 = function () {\n        var value = this.view.getInt32(this.pos);\n        this.pos += 4;\n        return value;\n    };\n    Decoder.prototype.readU64 = function () {\n        var value = getUint64(this.view, this.pos);\n        this.pos += 8;\n        return value;\n    };\n    Decoder.prototype.readI64 = function () {\n        var value = getInt64(this.view, this.pos);\n        this.pos += 8;\n        return value;\n    };\n    Decoder.prototype.readF32 = function () {\n        var value = this.view.getFloat32(this.pos);\n        this.pos += 4;\n        return value;\n    };\n    Decoder.prototype.readF64 = function () {\n        var value = this.view.getFloat64(this.pos);\n        this.pos += 8;\n        return value;\n    };\n    return Decoder;\n}());\nexport { Decoder };\n//# sourceMappingURL=Decoder.mjs.map","import { utf8EncodeJs, utf8Count, TEXT_ENCODER_THRESHOLD, utf8EncodeTE } from \"./utils/utf8.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { setInt64, setUint64 } from \"./utils/int.mjs\";\nimport { ensureUint8Array } from \"./utils/typedArrays.mjs\";\nexport var DEFAULT_MAX_DEPTH = 100;\nexport var DEFAULT_INITIAL_BUFFER_SIZE = 2048;\nvar Encoder = /** @class */ (function () {\n    function Encoder(extensionCodec, context, maxDepth, initialBufferSize, sortKeys, forceFloat32, ignoreUndefined, forceIntegerToFloat) {\n        if (extensionCodec === void 0) { extensionCodec = ExtensionCodec.defaultCodec; }\n        if (context === void 0) { context = undefined; }\n        if (maxDepth === void 0) { maxDepth = DEFAULT_MAX_DEPTH; }\n        if (initialBufferSize === void 0) { initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE; }\n        if (sortKeys === void 0) { sortKeys = false; }\n        if (forceFloat32 === void 0) { forceFloat32 = false; }\n        if (ignoreUndefined === void 0) { ignoreUndefined = false; }\n        if (forceIntegerToFloat === void 0) { forceIntegerToFloat = false; }\n        this.extensionCodec = extensionCodec;\n        this.context = context;\n        this.maxDepth = maxDepth;\n        this.initialBufferSize = initialBufferSize;\n        this.sortKeys = sortKeys;\n        this.forceFloat32 = forceFloat32;\n        this.ignoreUndefined = ignoreUndefined;\n        this.forceIntegerToFloat = forceIntegerToFloat;\n        this.pos = 0;\n        this.view = new DataView(new ArrayBuffer(this.initialBufferSize));\n        this.bytes = new Uint8Array(this.view.buffer);\n    }\n    Encoder.prototype.reinitializeState = function () {\n        this.pos = 0;\n    };\n    /**\n     * This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.\n     *\n     * @returns Encodes the object and returns a shared reference the encoder's internal buffer.\n     */\n    Encoder.prototype.encodeSharedRef = function (object) {\n        this.reinitializeState();\n        this.doEncode(object, 1);\n        return this.bytes.subarray(0, this.pos);\n    };\n    /**\n     * @returns Encodes the object and returns a copy of the encoder's internal buffer.\n     */\n    Encoder.prototype.encode = function (object) {\n        this.reinitializeState();\n        this.doEncode(object, 1);\n        return this.bytes.slice(0, this.pos);\n    };\n    Encoder.prototype.doEncode = function (object, depth) {\n        if (depth > this.maxDepth) {\n            throw new Error(\"Too deep objects in depth \".concat(depth));\n        }\n        if (object == null) {\n            this.encodeNil();\n        }\n        else if (typeof object === \"boolean\") {\n            this.encodeBoolean(object);\n        }\n        else if (typeof object === \"number\") {\n            this.encodeNumber(object);\n        }\n        else if (typeof object === \"string\") {\n            this.encodeString(object);\n        }\n        else {\n            this.encodeObject(object, depth);\n        }\n    };\n    Encoder.prototype.ensureBufferSizeToWrite = function (sizeToWrite) {\n        var requiredSize = this.pos + sizeToWrite;\n        if (this.view.byteLength < requiredSize) {\n            this.resizeBuffer(requiredSize * 2);\n        }\n    };\n    Encoder.prototype.resizeBuffer = function (newSize) {\n        var newBuffer = new ArrayBuffer(newSize);\n        var newBytes = new Uint8Array(newBuffer);\n        var newView = new DataView(newBuffer);\n        newBytes.set(this.bytes);\n        this.view = newView;\n        this.bytes = newBytes;\n    };\n    Encoder.prototype.encodeNil = function () {\n        this.writeU8(0xc0);\n    };\n    Encoder.prototype.encodeBoolean = function (object) {\n        if (object === false) {\n            this.writeU8(0xc2);\n        }\n        else {\n            this.writeU8(0xc3);\n        }\n    };\n    Encoder.prototype.encodeNumber = function (object) {\n        if (Number.isSafeInteger(object) && !this.forceIntegerToFloat) {\n            if (object >= 0) {\n                if (object < 0x80) {\n                    // positive fixint\n                    this.writeU8(object);\n                }\n                else if (object < 0x100) {\n                    // uint 8\n                    this.writeU8(0xcc);\n                    this.writeU8(object);\n                }\n                else if (object < 0x10000) {\n                    // uint 16\n                    this.writeU8(0xcd);\n                    this.writeU16(object);\n                }\n                else if (object < 0x100000000) {\n                    // uint 32\n                    this.writeU8(0xce);\n                    this.writeU32(object);\n                }\n                else {\n                    // uint 64\n                    this.writeU8(0xcf);\n                    this.writeU64(object);\n                }\n            }\n            else {\n                if (object >= -0x20) {\n                    // negative fixint\n                    this.writeU8(0xe0 | (object + 0x20));\n                }\n                else if (object >= -0x80) {\n                    // int 8\n                    this.writeU8(0xd0);\n                    this.writeI8(object);\n                }\n                else if (object >= -0x8000) {\n                    // int 16\n                    this.writeU8(0xd1);\n                    this.writeI16(object);\n                }\n                else if (object >= -0x80000000) {\n                    // int 32\n                    this.writeU8(0xd2);\n                    this.writeI32(object);\n                }\n                else {\n                    // int 64\n                    this.writeU8(0xd3);\n                    this.writeI64(object);\n                }\n            }\n        }\n        else {\n            // non-integer numbers\n            if (this.forceFloat32) {\n                // float 32\n                this.writeU8(0xca);\n                this.writeF32(object);\n            }\n            else {\n                // float 64\n                this.writeU8(0xcb);\n                this.writeF64(object);\n            }\n        }\n    };\n    Encoder.prototype.writeStringHeader = function (byteLength) {\n        if (byteLength < 32) {\n            // fixstr\n            this.writeU8(0xa0 + byteLength);\n        }\n        else if (byteLength < 0x100) {\n            // str 8\n            this.writeU8(0xd9);\n            this.writeU8(byteLength);\n        }\n        else if (byteLength < 0x10000) {\n            // str 16\n            this.writeU8(0xda);\n            this.writeU16(byteLength);\n        }\n        else if (byteLength < 0x100000000) {\n            // str 32\n            this.writeU8(0xdb);\n            this.writeU32(byteLength);\n        }\n        else {\n            throw new Error(\"Too long string: \".concat(byteLength, \" bytes in UTF-8\"));\n        }\n    };\n    Encoder.prototype.encodeString = function (object) {\n        var maxHeaderSize = 1 + 4;\n        var strLength = object.length;\n        if (strLength > TEXT_ENCODER_THRESHOLD) {\n            var byteLength = utf8Count(object);\n            this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);\n            this.writeStringHeader(byteLength);\n            utf8EncodeTE(object, this.bytes, this.pos);\n            this.pos += byteLength;\n        }\n        else {\n            var byteLength = utf8Count(object);\n            this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);\n            this.writeStringHeader(byteLength);\n            utf8EncodeJs(object, this.bytes, this.pos);\n            this.pos += byteLength;\n        }\n    };\n    Encoder.prototype.encodeObject = function (object, depth) {\n        // try to encode objects with custom codec first of non-primitives\n        var ext = this.extensionCodec.tryToEncode(object, this.context);\n        if (ext != null) {\n            this.encodeExtension(ext);\n        }\n        else if (Array.isArray(object)) {\n            this.encodeArray(object, depth);\n        }\n        else if (ArrayBuffer.isView(object)) {\n            this.encodeBinary(object);\n        }\n        else if (typeof object === \"object\") {\n            this.encodeMap(object, depth);\n        }\n        else {\n            // symbol, function and other special object come here unless extensionCodec handles them.\n            throw new Error(\"Unrecognized object: \".concat(Object.prototype.toString.apply(object)));\n        }\n    };\n    Encoder.prototype.encodeBinary = function (object) {\n        var size = object.byteLength;\n        if (size < 0x100) {\n            // bin 8\n            this.writeU8(0xc4);\n            this.writeU8(size);\n        }\n        else if (size < 0x10000) {\n            // bin 16\n            this.writeU8(0xc5);\n            this.writeU16(size);\n        }\n        else if (size < 0x100000000) {\n            // bin 32\n            this.writeU8(0xc6);\n            this.writeU32(size);\n        }\n        else {\n            throw new Error(\"Too large binary: \".concat(size));\n        }\n        var bytes = ensureUint8Array(object);\n        this.writeU8a(bytes);\n    };\n    Encoder.prototype.encodeArray = function (object, depth) {\n        var size = object.length;\n        if (size < 16) {\n            // fixarray\n            this.writeU8(0x90 + size);\n        }\n        else if (size < 0x10000) {\n            // array 16\n            this.writeU8(0xdc);\n            this.writeU16(size);\n        }\n        else if (size < 0x100000000) {\n            // array 32\n            this.writeU8(0xdd);\n            this.writeU32(size);\n        }\n        else {\n            throw new Error(\"Too large array: \".concat(size));\n        }\n        for (var _i = 0, object_1 = object; _i < object_1.length; _i++) {\n            var item = object_1[_i];\n            this.doEncode(item, depth + 1);\n        }\n    };\n    Encoder.prototype.countWithoutUndefined = function (object, keys) {\n        var count = 0;\n        for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {\n            var key = keys_1[_i];\n            if (object[key] !== undefined) {\n                count++;\n            }\n        }\n        return count;\n    };\n    Encoder.prototype.encodeMap = function (object, depth) {\n        var keys = Object.keys(object);\n        if (this.sortKeys) {\n            keys.sort();\n        }\n        var size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;\n        if (size < 16) {\n            // fixmap\n            this.writeU8(0x80 + size);\n        }\n        else if (size < 0x10000) {\n            // map 16\n            this.writeU8(0xde);\n            this.writeU16(size);\n        }\n        else if (size < 0x100000000) {\n            // map 32\n            this.writeU8(0xdf);\n            this.writeU32(size);\n        }\n        else {\n            throw new Error(\"Too large map object: \".concat(size));\n        }\n        for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {\n            var key = keys_2[_i];\n            var value = object[key];\n            if (!(this.ignoreUndefined && value === undefined)) {\n                this.encodeString(key);\n                this.doEncode(value, depth + 1);\n            }\n        }\n    };\n    Encoder.prototype.encodeExtension = function (ext) {\n        var size = ext.data.length;\n        if (size === 1) {\n            // fixext 1\n            this.writeU8(0xd4);\n        }\n        else if (size === 2) {\n            // fixext 2\n            this.writeU8(0xd5);\n        }\n        else if (size === 4) {\n            // fixext 4\n            this.writeU8(0xd6);\n        }\n        else if (size === 8) {\n            // fixext 8\n            this.writeU8(0xd7);\n        }\n        else if (size === 16) {\n            // fixext 16\n            this.writeU8(0xd8);\n        }\n        else if (size < 0x100) {\n            // ext 8\n            this.writeU8(0xc7);\n            this.writeU8(size);\n        }\n        else if (size < 0x10000) {\n            // ext 16\n            this.writeU8(0xc8);\n            this.writeU16(size);\n        }\n        else if (size < 0x100000000) {\n            // ext 32\n            this.writeU8(0xc9);\n            this.writeU32(size);\n        }\n        else {\n            throw new Error(\"Too large extension object: \".concat(size));\n        }\n        this.writeI8(ext.type);\n        this.writeU8a(ext.data);\n    };\n    Encoder.prototype.writeU8 = function (value) {\n        this.ensureBufferSizeToWrite(1);\n        this.view.setUint8(this.pos, value);\n        this.pos++;\n    };\n    Encoder.prototype.writeU8a = function (values) {\n        var size = values.length;\n        this.ensureBufferSizeToWrite(size);\n        this.bytes.set(values, this.pos);\n        this.pos += size;\n    };\n    Encoder.prototype.writeI8 = function (value) {\n        this.ensureBufferSizeToWrite(1);\n        this.view.setInt8(this.pos, value);\n        this.pos++;\n    };\n    Encoder.prototype.writeU16 = function (value) {\n        this.ensureBufferSizeToWrite(2);\n        this.view.setUint16(this.pos, value);\n        this.pos += 2;\n    };\n    Encoder.prototype.writeI16 = function (value) {\n        this.ensureBufferSizeToWrite(2);\n        this.view.setInt16(this.pos, value);\n        this.pos += 2;\n    };\n    Encoder.prototype.writeU32 = function (value) {\n        this.ensureBufferSizeToWrite(4);\n        this.view.setUint32(this.pos, value);\n        this.pos += 4;\n    };\n    Encoder.prototype.writeI32 = function (value) {\n        this.ensureBufferSizeToWrite(4);\n        this.view.setInt32(this.pos, value);\n        this.pos += 4;\n    };\n    Encoder.prototype.writeF32 = function (value) {\n        this.ensureBufferSizeToWrite(4);\n        this.view.setFloat32(this.pos, value);\n        this.pos += 4;\n    };\n    Encoder.prototype.writeF64 = function (value) {\n        this.ensureBufferSizeToWrite(8);\n        this.view.setFloat64(this.pos, value);\n        this.pos += 8;\n    };\n    Encoder.prototype.writeU64 = function (value) {\n        this.ensureBufferSizeToWrite(8);\n        setUint64(this.view, this.pos, value);\n        this.pos += 8;\n    };\n    Encoder.prototype.writeI64 = function (value) {\n        this.ensureBufferSizeToWrite(8);\n        setInt64(this.view, this.pos, value);\n        this.pos += 8;\n    };\n    return Encoder;\n}());\nexport { Encoder };\n//# sourceMappingURL=Encoder.mjs.map","/**\n * ExtData is used to handle Extension Types that are not registered to ExtensionCodec.\n */\nvar ExtData = /** @class */ (function () {\n    function ExtData(type, data) {\n        this.type = type;\n        this.data = data;\n    }\n    return ExtData;\n}());\nexport { ExtData };\n//# sourceMappingURL=ExtData.mjs.map","// ExtensionCodec to handle MessagePack extensions\nimport { ExtData } from \"./ExtData.mjs\";\nimport { timestampExtension } from \"./timestamp.mjs\";\nvar ExtensionCodec = /** @class */ (function () {\n    function ExtensionCodec() {\n        // built-in extensions\n        this.builtInEncoders = [];\n        this.builtInDecoders = [];\n        // custom extensions\n        this.encoders = [];\n        this.decoders = [];\n        this.register(timestampExtension);\n    }\n    ExtensionCodec.prototype.register = function (_a) {\n        var type = _a.type, encode = _a.encode, decode = _a.decode;\n        if (type >= 0) {\n            // custom extensions\n            this.encoders[type] = encode;\n            this.decoders[type] = decode;\n        }\n        else {\n            // built-in extensions\n            var index = 1 + type;\n            this.builtInEncoders[index] = encode;\n            this.builtInDecoders[index] = decode;\n        }\n    };\n    ExtensionCodec.prototype.tryToEncode = function (object, context) {\n        // built-in extensions\n        for (var i = 0; i < this.builtInEncoders.length; i++) {\n            var encodeExt = this.builtInEncoders[i];\n            if (encodeExt != null) {\n                var data = encodeExt(object, context);\n                if (data != null) {\n                    var type = -1 - i;\n                    return new ExtData(type, data);\n                }\n            }\n        }\n        // custom extensions\n        for (var i = 0; i < this.encoders.length; i++) {\n            var encodeExt = this.encoders[i];\n            if (encodeExt != null) {\n                var data = encodeExt(object, context);\n                if (data != null) {\n                    var type = i;\n                    return new ExtData(type, data);\n                }\n            }\n        }\n        if (object instanceof ExtData) {\n            // to keep ExtData as is\n            return object;\n        }\n        return null;\n    };\n    ExtensionCodec.prototype.decode = function (data, type, context) {\n        var decodeExt = type < 0 ? this.builtInDecoders[-1 - type] : this.decoders[type];\n        if (decodeExt) {\n            return decodeExt(data, type, context);\n        }\n        else {\n            // decode() does not fail, returns ExtData instead.\n            return new ExtData(type, data);\n        }\n    };\n    ExtensionCodec.defaultCodec = new ExtensionCodec();\n    return ExtensionCodec;\n}());\nexport { ExtensionCodec };\n//# sourceMappingURL=ExtensionCodec.mjs.map","import { Decoder } from \"./Decoder.mjs\";\nexport var defaultDecodeOptions = {};\n/**\n * It decodes a single MessagePack object in a buffer.\n *\n * This is a synchronous decoding function.\n * See other variants for asynchronous decoding: {@link decodeAsync()}, {@link decodeStream()}, or {@link decodeArrayStream()}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decode(buffer, options) {\n    if (options === void 0) { options = defaultDecodeOptions; }\n    var decoder = new Decoder(options.extensionCodec, options.context, options.maxStrLength, options.maxBinLength, options.maxArrayLength, options.maxMapLength, options.maxExtLength);\n    return decoder.decode(buffer);\n}\n/**\n * It decodes multiple MessagePack objects in a buffer.\n * This is corresponding to {@link decodeMultiStream()}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decodeMulti(buffer, options) {\n    if (options === void 0) { options = defaultDecodeOptions; }\n    var decoder = new Decoder(options.extensionCodec, options.context, options.maxStrLength, options.maxBinLength, options.maxArrayLength, options.maxMapLength, options.maxExtLength);\n    return decoder.decodeMulti(buffer);\n}\n//# sourceMappingURL=decode.mjs.map","import { Encoder } from \"./Encoder.mjs\";\nvar defaultEncodeOptions = {};\n/**\n * It encodes `value` in the MessagePack format and\n * returns a byte buffer.\n *\n * The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.\n */\nexport function encode(value, options) {\n    if (options === void 0) { options = defaultEncodeOptions; }\n    var encoder = new Encoder(options.extensionCodec, options.context, options.maxDepth, options.initialBufferSize, options.sortKeys, options.forceFloat32, options.ignoreUndefined, options.forceIntegerToFloat);\n    return encoder.encodeSharedRef(value);\n}\n//# sourceMappingURL=encode.mjs.map","// https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type\nimport { DecodeError } from \"./DecodeError.mjs\";\nimport { getInt64, setInt64 } from \"./utils/int.mjs\";\nexport var EXT_TIMESTAMP = -1;\nvar TIMESTAMP32_MAX_SEC = 0x100000000 - 1; // 32-bit unsigned int\nvar TIMESTAMP64_MAX_SEC = 0x400000000 - 1; // 34-bit unsigned int\nexport function encodeTimeSpecToTimestamp(_a) {\n    var sec = _a.sec, nsec = _a.nsec;\n    if (sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC) {\n        // Here sec >= 0 && nsec >= 0\n        if (nsec === 0 && sec <= TIMESTAMP32_MAX_SEC) {\n            // timestamp 32 = { sec32 (unsigned) }\n            var rv = new Uint8Array(4);\n            var view = new DataView(rv.buffer);\n            view.setUint32(0, sec);\n            return rv;\n        }\n        else {\n            // timestamp 64 = { nsec30 (unsigned), sec34 (unsigned) }\n            var secHigh = sec / 0x100000000;\n            var secLow = sec & 0xffffffff;\n            var rv = new Uint8Array(8);\n            var view = new DataView(rv.buffer);\n            // nsec30 | secHigh2\n            view.setUint32(0, (nsec << 2) | (secHigh & 0x3));\n            // secLow32\n            view.setUint32(4, secLow);\n            return rv;\n        }\n    }\n    else {\n        // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n        var rv = new Uint8Array(12);\n        var view = new DataView(rv.buffer);\n        view.setUint32(0, nsec);\n        setInt64(view, 4, sec);\n        return rv;\n    }\n}\nexport function encodeDateToTimeSpec(date) {\n    var msec = date.getTime();\n    var sec = Math.floor(msec / 1e3);\n    var nsec = (msec - sec * 1e3) * 1e6;\n    // Normalizes { sec, nsec } to ensure nsec is unsigned.\n    var nsecInSec = Math.floor(nsec / 1e9);\n    return {\n        sec: sec + nsecInSec,\n        nsec: nsec - nsecInSec * 1e9,\n    };\n}\nexport function encodeTimestampExtension(object) {\n    if (object instanceof Date) {\n        var timeSpec = encodeDateToTimeSpec(object);\n        return encodeTimeSpecToTimestamp(timeSpec);\n    }\n    else {\n        return null;\n    }\n}\nexport function decodeTimestampToTimeSpec(data) {\n    var view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n    // data may be 32, 64, or 96 bits\n    switch (data.byteLength) {\n        case 4: {\n            // timestamp 32 = { sec32 }\n            var sec = view.getUint32(0);\n            var nsec = 0;\n            return { sec: sec, nsec: nsec };\n        }\n        case 8: {\n            // timestamp 64 = { nsec30, sec34 }\n            var nsec30AndSecHigh2 = view.getUint32(0);\n            var secLow32 = view.getUint32(4);\n            var sec = (nsec30AndSecHigh2 & 0x3) * 0x100000000 + secLow32;\n            var nsec = nsec30AndSecHigh2 >>> 2;\n            return { sec: sec, nsec: nsec };\n        }\n        case 12: {\n            // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n            var sec = getInt64(view, 4);\n            var nsec = view.getUint32(0);\n            return { sec: sec, nsec: nsec };\n        }\n        default:\n            throw new DecodeError(\"Unrecognized data size for timestamp (expected 4, 8, or 12): \".concat(data.length));\n    }\n}\nexport function decodeTimestampExtension(data) {\n    var timeSpec = decodeTimestampToTimeSpec(data);\n    return new Date(timeSpec.sec * 1e3 + timeSpec.nsec / 1e6);\n}\nexport var timestampExtension = {\n    type: EXT_TIMESTAMP,\n    encode: encodeTimestampExtension,\n    decode: decodeTimestampExtension,\n};\n//# sourceMappingURL=timestamp.mjs.map","// Integer Utility\nexport var UINT32_MAX = 4294967295;\n// DataView extension to handle int64 / uint64,\n// where the actual range is 53-bits integer (a.k.a. safe integer)\nexport function setUint64(view, offset, value) {\n    var high = value / 4294967296;\n    var low = value; // high bits are truncated by DataView\n    view.setUint32(offset, high);\n    view.setUint32(offset + 4, low);\n}\nexport function setInt64(view, offset, value) {\n    var high = Math.floor(value / 4294967296);\n    var low = value; // high bits are truncated by DataView\n    view.setUint32(offset, high);\n    view.setUint32(offset + 4, low);\n}\nexport function getInt64(view, offset) {\n    var high = view.getInt32(offset);\n    var low = view.getUint32(offset + 4);\n    return high * 4294967296 + low;\n}\nexport function getUint64(view, offset) {\n    var high = view.getUint32(offset);\n    var low = view.getUint32(offset + 4);\n    return high * 4294967296 + low;\n}\n//# sourceMappingURL=int.mjs.map","export function prettyByte(byte) {\n    return \"\".concat(byte < 0 ? \"-\" : \"\", \"0x\").concat(Math.abs(byte).toString(16).padStart(2, \"0\"));\n}\n//# sourceMappingURL=prettyByte.mjs.map","export function ensureUint8Array(buffer) {\n    if (buffer instanceof Uint8Array) {\n        return buffer;\n    }\n    else if (ArrayBuffer.isView(buffer)) {\n        return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n    }\n    else if (buffer instanceof ArrayBuffer) {\n        return new Uint8Array(buffer);\n    }\n    else {\n        // ArrayLike<number>\n        return Uint8Array.from(buffer);\n    }\n}\nexport function createDataView(buffer) {\n    if (buffer instanceof ArrayBuffer) {\n        return new DataView(buffer);\n    }\n    var bufferView = ensureUint8Array(buffer);\n    return new DataView(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);\n}\n//# sourceMappingURL=typedArrays.mjs.map","var _a, _b, _c;\n/* eslint-disable @typescript-eslint/no-unnecessary-condition */\nimport { UINT32_MAX } from \"./int.mjs\";\nvar TEXT_ENCODING_AVAILABLE = (typeof process === \"undefined\" || ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a[\"TEXT_ENCODING\"]) !== \"never\") &&\n    typeof TextEncoder !== \"undefined\" &&\n    typeof TextDecoder !== \"undefined\";\nexport function utf8Count(str) {\n    var strLength = str.length;\n    var byteLength = 0;\n    var pos = 0;\n    while (pos < strLength) {\n        var value = str.charCodeAt(pos++);\n        if ((value & 0xffffff80) === 0) {\n            // 1-byte\n            byteLength++;\n            continue;\n        }\n        else if ((value & 0xfffff800) === 0) {\n            // 2-bytes\n            byteLength += 2;\n        }\n        else {\n            // handle surrogate pair\n            if (value >= 0xd800 && value <= 0xdbff) {\n                // high surrogate\n                if (pos < strLength) {\n                    var extra = str.charCodeAt(pos);\n                    if ((extra & 0xfc00) === 0xdc00) {\n                        ++pos;\n                        value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n                    }\n                }\n            }\n            if ((value & 0xffff0000) === 0) {\n                // 3-byte\n                byteLength += 3;\n            }\n            else {\n                // 4-byte\n                byteLength += 4;\n            }\n        }\n    }\n    return byteLength;\n}\nexport function utf8EncodeJs(str, output, outputOffset) {\n    var strLength = str.length;\n    var offset = outputOffset;\n    var pos = 0;\n    while (pos < strLength) {\n        var value = str.charCodeAt(pos++);\n        if ((value & 0xffffff80) === 0) {\n            // 1-byte\n            output[offset++] = value;\n            continue;\n        }\n        else if ((value & 0xfffff800) === 0) {\n            // 2-bytes\n            output[offset++] = ((value >> 6) & 0x1f) | 0xc0;\n        }\n        else {\n            // handle surrogate pair\n            if (value >= 0xd800 && value <= 0xdbff) {\n                // high surrogate\n                if (pos < strLength) {\n                    var extra = str.charCodeAt(pos);\n                    if ((extra & 0xfc00) === 0xdc00) {\n                        ++pos;\n                        value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n                    }\n                }\n            }\n            if ((value & 0xffff0000) === 0) {\n                // 3-byte\n                output[offset++] = ((value >> 12) & 0x0f) | 0xe0;\n                output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n            }\n            else {\n                // 4-byte\n                output[offset++] = ((value >> 18) & 0x07) | 0xf0;\n                output[offset++] = ((value >> 12) & 0x3f) | 0x80;\n                output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n            }\n        }\n        output[offset++] = (value & 0x3f) | 0x80;\n    }\n}\nvar sharedTextEncoder = TEXT_ENCODING_AVAILABLE ? new TextEncoder() : undefined;\nexport var TEXT_ENCODER_THRESHOLD = !TEXT_ENCODING_AVAILABLE\n    ? UINT32_MAX\n    : typeof process !== \"undefined\" && ((_b = process === null || process === void 0 ? void 0 : process.env) === null || _b === void 0 ? void 0 : _b[\"TEXT_ENCODING\"]) !== \"force\"\n        ? 200\n        : 0;\nfunction utf8EncodeTEencode(str, output, outputOffset) {\n    output.set(sharedTextEncoder.encode(str), outputOffset);\n}\nfunction utf8EncodeTEencodeInto(str, output, outputOffset) {\n    sharedTextEncoder.encodeInto(str, output.subarray(outputOffset));\n}\nexport var utf8EncodeTE = (sharedTextEncoder === null || sharedTextEncoder === void 0 ? void 0 : sharedTextEncoder.encodeInto) ? utf8EncodeTEencodeInto : utf8EncodeTEencode;\nvar CHUNK_SIZE = 4096;\nexport function utf8DecodeJs(bytes, inputOffset, byteLength) {\n    var offset = inputOffset;\n    var end = offset + byteLength;\n    var units = [];\n    var result = \"\";\n    while (offset < end) {\n        var byte1 = bytes[offset++];\n        if ((byte1 & 0x80) === 0) {\n            // 1 byte\n            units.push(byte1);\n        }\n        else if ((byte1 & 0xe0) === 0xc0) {\n            // 2 bytes\n            var byte2 = bytes[offset++] & 0x3f;\n            units.push(((byte1 & 0x1f) << 6) | byte2);\n        }\n        else if ((byte1 & 0xf0) === 0xe0) {\n            // 3 bytes\n            var byte2 = bytes[offset++] & 0x3f;\n            var byte3 = bytes[offset++] & 0x3f;\n            units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);\n        }\n        else if ((byte1 & 0xf8) === 0xf0) {\n            // 4 bytes\n            var byte2 = bytes[offset++] & 0x3f;\n            var byte3 = bytes[offset++] & 0x3f;\n            var byte4 = bytes[offset++] & 0x3f;\n            var unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;\n            if (unit > 0xffff) {\n                unit -= 0x10000;\n                units.push(((unit >>> 10) & 0x3ff) | 0xd800);\n                unit = 0xdc00 | (unit & 0x3ff);\n            }\n            units.push(unit);\n        }\n        else {\n            units.push(byte1);\n        }\n        if (units.length >= CHUNK_SIZE) {\n            result += String.fromCharCode.apply(String, units);\n            units.length = 0;\n        }\n    }\n    if (units.length > 0) {\n        result += String.fromCharCode.apply(String, units);\n    }\n    return result;\n}\nvar sharedTextDecoder = TEXT_ENCODING_AVAILABLE ? new TextDecoder() : null;\nexport var TEXT_DECODER_THRESHOLD = !TEXT_ENCODING_AVAILABLE\n    ? UINT32_MAX\n    : typeof process !== \"undefined\" && ((_c = process === null || process === void 0 ? void 0 : process.env) === null || _c === void 0 ? void 0 : _c[\"TEXT_DECODER\"]) !== \"force\"\n        ? 200\n        : 0;\nexport function utf8DecodeTD(bytes, inputOffset, byteLength) {\n    var stringBytes = bytes.subarray(inputOffset, inputOffset + byteLength);\n    return sharedTextDecoder.decode(stringBytes);\n}\n//# sourceMappingURL=utf8.mjs.map","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { RPC, API_VERSION, _applyEncryptionKeyToService } from \"./rpc.js\";\nimport { publicKeyFromHex } from \"./crypto.js\";\nimport {\n  assert,\n  randId,\n  waitFor,\n  loadRequirements,\n  parseServiceUrl,\n} from \"./utils/index.js\";\nimport { schemaFunction } from \"./utils/schema.js\";\nimport { getRTCService, registerRTCService } from \"./webrtc-client.js\";\n\n// Import HTTP client for internal use and re-export\nimport {\n  HTTPStreamingRPCConnection,\n  connectToServerHTTP,\n  getRemoteServiceHTTP,\n  normalizeServerUrl as normalizeServerUrlHTTP,\n} from \"./http-client.js\";\n\n// Re-export HTTP client classes and functions\nexport {\n  HTTPStreamingRPCConnection,\n  connectToServerHTTP,\n  getRemoteServiceHTTP,\n  normalizeServerUrlHTTP,\n};\n\nexport { RPC, API_VERSION, schemaFunction };\nexport { loadRequirements };\nexport { getRTCService, registerRTCService };\nexport {\n  generateEncryptionKeypair,\n  encryptPayload,\n  decryptPayload,\n  publicKeyToHex,\n  publicKeyFromHex,\n} from \"./crypto.js\";\n\nconst MAX_RETRY = 1000000;\n\nclass WebsocketRPCConnection {\n  constructor(\n    server_url,\n    client_id,\n    workspace,\n    token,\n    reconnection_token = null,\n    timeout = 60,\n    WebSocketClass = null,\n    token_refresh_interval = 2 * 60 * 60,\n    additional_headers = null,\n    ping_interval = 30,\n    logger = undefined,\n  ) {\n    assert(server_url && client_id, \"server_url and client_id are required\");\n    // Configurable logger (same as RPC class)\n    if (logger === null) {\n      const noop = () => {};\n      this._logger = { debug: noop, info: noop, warn: noop, error: noop, log: noop };\n    } else if (logger) {\n      this._logger = logger;\n    } else {\n      this._logger = console;\n    }\n    this._server_url = server_url;\n    this._client_id = client_id;\n    this._workspace = workspace;\n    this._token = token;\n    this._reconnection_token = reconnection_token;\n    this._websocket = null;\n    this._handle_message = null;\n    this._handle_connected = null; // Connection open event handler\n    this._handle_disconnected = null; // Disconnection event handler\n    this._timeout = timeout;\n    this._WebSocketClass = WebSocketClass || WebSocket; // Allow overriding the WebSocket class\n    this._closed = false;\n    this._legacy_auth = null;\n    this.connection_info = null;\n    this._enable_reconnect = false;\n    this._token_refresh_interval = token_refresh_interval;\n    this.manager_id = null;\n    this._refresh_token_task = null;\n    this._ping_task = null;\n    this._ping_interval = ping_interval;\n    this._reconnect_timeouts = new Set(); // Track reconnection timeouts\n    this._additional_headers = additional_headers;\n    this._reconnecting = false; // Mutex to prevent overlapping reconnection attempts\n    this._closedDuringReconnect = false; // Flag for close events during reconnection\n    this._disconnectedNotified = false;\n  }\n\n  /**\n   * Centralized cleanup method to clear all timers and prevent resource leaks\n   */\n  _cleanup() {\n    // Clear token refresh delay timeout\n    if (this._refresh_token_delay) {\n      clearTimeout(this._refresh_token_delay);\n      this._refresh_token_delay = null;\n    }\n\n    // Clear token refresh interval\n    if (this._refresh_token_task) {\n      clearInterval(this._refresh_token_task);\n      this._refresh_token_task = null;\n    }\n\n    // Clear ping keepalive interval\n    if (this._ping_task) {\n      clearInterval(this._ping_task);\n      this._ping_task = null;\n    }\n\n    // Clear all reconnection timeouts\n    for (const timeoutId of this._reconnect_timeouts) {\n      clearTimeout(timeoutId);\n    }\n    this._reconnect_timeouts.clear();\n  }\n\n  on_message(handler) {\n    assert(handler, \"handler is required\");\n    this._handle_message = handler;\n  }\n\n  on_connected(handler) {\n    this._handle_connected = handler;\n  }\n\n  on_disconnected(handler) {\n    this._handle_disconnected = handler;\n  }\n\n  async _attempt_connection(server_url, attempt_fallback = true) {\n    return new Promise((resolve, reject) => {\n      this._legacy_auth = false;\n      const websocket = new this._WebSocketClass(server_url);\n      websocket.binaryType = \"arraybuffer\";\n\n      websocket.onopen = () => {\n        this._logger.info(\"WebSocket connection established\");\n        resolve(websocket);\n      };\n\n      websocket.onerror = (event) => {\n        this._logger.error(\"WebSocket connection error:\", event);\n        reject(new Error(`WebSocket connection error: ${event}`));\n      };\n\n      websocket.onclose = (event) => {\n        if (event.code === 1003 && attempt_fallback) {\n          this._logger.info(\n            \"Received 1003 error, attempting connection with query parameters.\",\n          );\n          this._legacy_auth = true;\n          this._attempt_connection_with_query_params(server_url)\n            .then(resolve)\n            .catch(reject);\n        } else {\n          this._notifyDisconnected(event.reason);\n        }\n      };\n    });\n  }\n\n  async _attempt_connection_with_query_params(server_url) {\n    // Initialize an array to hold parts of the query string\n    const queryParamsParts = [];\n\n    // Conditionally add each parameter if it has a non-empty value\n    if (this._client_id)\n      queryParamsParts.push(`client_id=${encodeURIComponent(this._client_id)}`);\n    if (this._workspace)\n      queryParamsParts.push(`workspace=${encodeURIComponent(this._workspace)}`);\n    if (this._token)\n      queryParamsParts.push(`token=${encodeURIComponent(this._token)}`);\n    if (this._reconnection_token)\n      queryParamsParts.push(\n        `reconnection_token=${encodeURIComponent(this._reconnection_token)}`,\n      );\n\n    // Join the parts with '&' to form the final query string, prepend '?' if there are any parameters\n    const queryString =\n      queryParamsParts.length > 0 ? `?${queryParamsParts.join(\"&\")}` : \"\";\n\n    // Construct the full URL by appending the query string if it exists\n    const full_url = server_url + queryString;\n\n    return await this._attempt_connection(full_url, false);\n  }\n\n  _establish_connection() {\n    return new Promise((resolve, reject) => {\n      let settled = false;\n\n      // Handle WebSocket closing before connection_info is received.\n      // Without this, the promise hangs until the outer waitFor timeout (60s).\n      const prevOnClose = this._websocket.onclose;\n      this._websocket.onclose = (event) => {\n        if (!settled) {\n          settled = true;\n          reject(\n            new Error(\n              `ConnectionAbortedError: WebSocket closed during handshake (code=${event.code}, reason=${event.reason || \"unknown\"})`,\n            ),\n          );\n        }\n        // Delegate to any previously-set onclose handler\n        if (prevOnClose) prevOnClose.call(this._websocket, event);\n      };\n\n      const prevOnError = this._websocket.onerror;\n      this._websocket.onerror = (event) => {\n        if (!settled) {\n          settled = true;\n          reject(\n            new Error(\n              `ConnectionAbortedError: WebSocket error during handshake`,\n            ),\n          );\n        }\n        if (prevOnError) prevOnError.call(this._websocket, event);\n      };\n\n      this._websocket.onmessage = (event) => {\n        const data = event.data;\n        if (typeof data !== \"string\") {\n          // Binary message received before connection info, ignore it\n          return;\n        }\n        const first_message = JSON.parse(data);\n        if (first_message.type == \"connection_info\") {\n          settled = true;\n          this.connection_info = first_message;\n          if (this._workspace) {\n            assert(\n              this.connection_info.workspace === this._workspace,\n              `Connected to the wrong workspace: ${this.connection_info.workspace}, expected: ${this._workspace}`,\n            );\n          }\n          if (this.connection_info.reconnection_token) {\n            this._reconnection_token = this.connection_info.reconnection_token;\n          }\n          if (this.connection_info.reconnection_token_life_time) {\n            // make sure the token refresh interval is less than the token life time\n            if (\n              this._token_refresh_interval >\n              this.connection_info.reconnection_token_life_time / 1.5\n            ) {\n              this._logger.warn(\n                `Token refresh interval is too long (${this._token_refresh_interval}), setting it to 1.5 times of the token life time(${this.connection_info.reconnection_token_life_time}).`,\n              );\n              this._token_refresh_interval =\n                this.connection_info.reconnection_token_life_time / 1.5;\n            }\n          }\n          this.manager_id = this.connection_info.manager_id || null;\n          this._logger.log(\n            `Successfully connected to the server, workspace: ${this.connection_info.workspace}, manager_id: ${this.manager_id}`,\n          );\n          if (this.connection_info.announcement) {\n            this._logger.log(`${this.connection_info.announcement}`);\n          }\n          resolve(this.connection_info);\n        } else if (first_message.type == \"error\") {\n          settled = true;\n          const error = \"ConnectionAbortedError: \" + first_message.message;\n          this._logger.error(\"Failed to connect, \" + error);\n          reject(new Error(error));\n          return;\n        } else {\n          settled = true;\n          this._logger.error(\n            \"ConnectionAbortedError: Unexpected message received from the server:\",\n            data,\n          );\n          reject(\n            new Error(\n              \"ConnectionAbortedError: Unexpected message received from the server\",\n            ),\n          );\n          return;\n        }\n      };\n    });\n  }\n\n  async open() {\n    this._logger.log(\n      \"Creating a new websocket connection to\",\n      this._server_url.split(\"?\")[0],\n    );\n    try {\n      this._websocket = await this._attempt_connection(this._server_url);\n      if (this._legacy_auth) {\n        throw new Error(\n          \"NotImplementedError: Legacy authentication is not supported\",\n        );\n      }\n      // Send authentication info as the first message if connected without query params\n      const authInfo = JSON.stringify({\n        client_id: this._client_id,\n        workspace: this._workspace,\n        token: this._token,\n        reconnection_token: this._reconnection_token,\n      });\n      this._websocket.send(authInfo);\n      // Wait for the first message from the server\n      await waitFor(\n        this._establish_connection(),\n        this._timeout,\n        \"Failed to receive the first message from the server\",\n      );\n      if (this._token_refresh_interval > 0) {\n        this._refresh_token_delay = setTimeout(() => {\n          this._refresh_token_delay = null;\n          if (this._closed) return;\n          this._send_refresh_token();\n          this._refresh_token_task = setInterval(() => {\n            this._send_refresh_token();\n          }, this._token_refresh_interval * 1000);\n        }, 2000);\n      }\n      // Start periodic ping to keep the connection alive.\n      // Browser WebSocket API doesn't support protocol-level ping frames,\n      // so we send application-level {\"type\": \"ping\"} messages that the\n      // Hypha server recognizes and responds to with {\"type\": \"pong\"}.\n      // Without this, idle connections are closed by the server's\n      // HYPHA_WS_IDLE_TIMEOUT (default 600s).\n      if (this._ping_interval > 0) {\n        this._ping_task = setInterval(() => {\n          if (!this._closed) {\n            this._send_ping();\n          }\n        }, this._ping_interval * 1000);\n      }\n      // Listen to messages from the server\n      this._enable_reconnect = true;\n      this._closed = false;\n      this._disconnectedNotified = false;\n      this._websocket.onmessage = (event) => {\n        if (typeof event.data === \"string\") {\n          const parsedData = JSON.parse(event.data);\n          if (parsedData.type === \"reconnection_token\") {\n            this._reconnection_token = parsedData.reconnection_token;\n          } else if (parsedData.type === \"pong\") {\n            // Keepalive response, no action needed\n          } else {\n            this._logger.log(\"Received message from the server:\", parsedData);\n          }\n        } else {\n          this._handle_message(event.data);\n        }\n      };\n\n      this._websocket.onerror = (event) => {\n        this._logger.error(\"WebSocket connection error:\", event);\n        // Clean up timers on error\n        this._cleanup();\n      };\n\n      this._websocket.onclose = this._handle_close.bind(this);\n\n      if (this._handle_connected) {\n        // Await async callbacks so errors (e.g. service re-registration\n        // failures) propagate instead of becoming unhandled rejections.\n        await this._handle_connected(this.connection_info);\n      }\n      return this.connection_info;\n    } catch (error) {\n      // Clean up any timers that might have been set up before the error\n      this._cleanup();\n      this._logger.error(\n        \"Failed to connect to\",\n        this._server_url.split(\"?\")[0],\n        error,\n      );\n      throw error;\n    }\n  }\n\n  _send_ping() {\n    if (this._websocket && this._websocket.readyState === WebSocket.OPEN) {\n      this._websocket.send(JSON.stringify({ type: \"ping\" }));\n    }\n  }\n\n  _send_refresh_token() {\n    if (this._websocket && this._websocket.readyState === WebSocket.OPEN) {\n      const refreshMessage = JSON.stringify({ type: \"refresh_token\" });\n      this._websocket.send(refreshMessage);\n      // console.log(\"Requested refresh token\");\n    }\n  }\n\n  _notifyDisconnected(reason) {\n    if (this._disconnectedNotified) return;\n    this._disconnectedNotified = true;\n    if (this._handle_disconnected) {\n      this._handle_disconnected(reason);\n    }\n  }\n\n  _handle_close(event) {\n    if (\n      !this._closed &&\n      this._websocket &&\n      this._websocket.readyState === WebSocket.CLOSED\n    ) {\n      // Clean up timers when connection closes\n      this._cleanup();\n      // Reset the guard so reconnection can re-notify on next disconnect\n      this._disconnectedNotified = false;\n\n      // Even if it's a graceful closure (codes 1000, 1001), if it wasn't user-initiated,\n      // we should attempt to reconnect (e.g., server restart, k8s upgrade)\n      if (this._enable_reconnect) {\n        if ([1000, 1001].includes(event.code)) {\n          this._logger.warn(\n            `Websocket connection closed gracefully by server (code: ${event.code}): ${event.reason} - attempting reconnect`,\n          );\n        } else {\n          this._logger.warn(\n            \"Websocket connection closed unexpectedly (code: %s): %s\",\n            event.code,\n            event.reason,\n          );\n        }\n\n        // Notify the RPC layer immediately so it can reject pending calls\n        this._notifyDisconnected(event.reason);\n\n        // If a reconnection is already in progress, signal it so the\n        // reconnect loop can detect that the newly-opened socket died and retry.\n        if (this._reconnecting) {\n          this._closedDuringReconnect = true;\n          return;\n        }\n        this._reconnecting = true;\n\n        let retry = 0;\n        const baseDelay = 1000; // Start with 1 second\n        const maxDelay = 60000; // Maximum delay of 60 seconds\n        const maxJitter = 0.1; // Maximum jitter factor\n\n        const reconnect = async () => {\n          // Check if we were explicitly closed\n          if (this._closed) {\n            this._logger.info(\"Connection was closed, stopping reconnection\");\n            this._reconnecting = false;\n            return;\n          }\n\n          try {\n            this._logger.warn(\n              `Reconnecting to ${this._server_url.split(\"?\")[0]} (attempt #${retry})`,\n            );\n            // Reset the flag before each attempt so we can detect new close\n            // events that arrive while open() and the settle period run.\n            this._closedDuringReconnect = false;\n\n            // Open the connection, this will trigger the on_connected callback\n            await this.open();\n\n            // Wait a short time for services to be registered\n            // This gives time for the on_connected callback to complete\n            // which includes re-registering all services to the server\n            await new Promise((resolve) => setTimeout(resolve, 500));\n\n            // Check if the WebSocket died during the settle period.\n            // This handles the race where _handle_close fires while\n            // _reconnecting is true and sets _closedDuringReconnect.\n            if (\n              this._closedDuringReconnect ||\n              !this._websocket ||\n              this._websocket.readyState !== WebSocket.OPEN\n            ) {\n              this._logger.warn(\n                \"WebSocket closed during reconnection settle period, retrying...\",\n              );\n              this._closedDuringReconnect = false;\n              // Fall through to the retry logic below\n              throw new Error(\"Connection lost during reconnection settle\");\n            }\n\n            // Check if service re-registration succeeded.\n            // The on_connected callback sets this flag; if any\n            // services failed to register, retry instead of\n            // declaring success with missing services.\n            if (this._services_registered_ok === false) {\n              this._logger.warn(\n                \"Service re-registration failed, retrying...\",\n              );\n              throw new Error(\n                \"Service re-registration failed after reconnection\",\n              );\n            }\n\n            this._logger.warn(\n              `Successfully reconnected to server ${this._server_url} (services re-registered)`,\n            );\n            this._reconnecting = false;\n          } catch (e) {\n            if (`${e}`.includes(\"ConnectionAbortedError:\")) {\n              this._logger.warn(\"Server refused to reconnect:\", e);\n              this._closed = true;\n              this._reconnecting = false;\n              this._notifyDisconnected(`Server refused reconnection: ${e}`);\n              return;\n            } else if (`${e}`.includes(\"NotImplementedError:\")) {\n              this._logger.error(\n                `${e}\\nIt appears that you are trying to connect to a hypha server that is older than 0.20.0, please upgrade the hypha server or use the websocket client in imjoy-rpc(https://www.npmjs.com/package/imjoy-rpc) instead`,\n              );\n              this._closed = true;\n              this._reconnecting = false;\n              this._notifyDisconnected(`Server too old: ${e}`);\n              return;\n            }\n\n            // Log specific error types for better debugging\n            // Convert to string first to safely handle non-standard error objects\n            const errStr = `${e}`;\n            if (errStr.includes(\"NetworkError\") || errStr.includes(\"network\")) {\n              this._logger.error(`Network error during reconnection: ${errStr}`);\n            } else if (\n              errStr.includes(\"TimeoutError\") || errStr.includes(\"timeout\")\n            ) {\n              this._logger.error(\n                `Connection timeout during reconnection: ${errStr}`,\n              );\n            } else {\n              this._logger.error(\n                `Unexpected error during reconnection: ${errStr}`,\n              );\n            }\n\n            // Calculate exponential backoff with jitter\n            const delay = Math.min(baseDelay * Math.pow(2, retry), maxDelay);\n            // Add jitter to prevent thundering herd\n            const jitter = (Math.random() * 2 - 1) * maxJitter * delay;\n            const finalDelay = Math.max(100, delay + jitter);\n\n            // console.debug(`Waiting ${(finalDelay / 1000).toFixed(2)}s before next reconnection attempt`);\n\n            // Track the reconnection timeout to prevent leaks\n            const timeoutId = setTimeout(async () => {\n              this._reconnect_timeouts.delete(timeoutId);\n\n              // Check if connection was restored externally\n              if (\n                this._websocket &&\n                this._websocket.readyState === WebSocket.OPEN\n              ) {\n                this._logger.info(\"Connection restored externally\");\n                this._reconnecting = false;\n                return;\n              }\n\n              // Check if we were explicitly closed\n              if (this._closed) {\n                this._logger.info(\"Connection was closed, stopping reconnection\");\n                this._reconnecting = false;\n                return;\n              }\n\n              retry += 1;\n              if (retry < MAX_RETRY) {\n                await reconnect();\n              } else {\n                this._logger.error(\n                  `Failed to reconnect after ${MAX_RETRY} attempts, giving up.`,\n                );\n                this._closed = true;\n                this._reconnecting = false;\n                this._notifyDisconnected(\"Max reconnection attempts exceeded\");\n              }\n            }, finalDelay);\n            this._reconnect_timeouts.add(timeoutId);\n          }\n        };\n        reconnect();\n      }\n    } else {\n      // Clean up timers in all cases\n      this._cleanup();\n      this._notifyDisconnected(event.reason);\n    }\n  }\n\n  async emit_message(data) {\n    if (this._closed) {\n      throw new Error(\"Connection is closed\");\n    }\n    if (!this._websocket || this._websocket.readyState !== WebSocket.OPEN) {\n      await this.open();\n    }\n    try {\n      this._websocket.send(data);\n    } catch (exp) {\n      this._logger.error(`Failed to send data, error: ${exp}`);\n      throw exp;\n    }\n  }\n\n  disconnect(reason) {\n    this._closed = true;\n    this._reconnecting = false;\n    this._closedDuringReconnect = false;\n    // Ensure websocket is closed if it exists and is not already closed or closing\n    if (\n      this._websocket &&\n      this._websocket.readyState !== WebSocket.CLOSED &&\n      this._websocket.readyState !== WebSocket.CLOSING\n    ) {\n      this._websocket.close(1000, reason);\n    }\n    // Use centralized cleanup to clear all timers\n    this._cleanup();\n    this._logger.info(`WebSocket connection disconnected (${reason})`);\n  }\n}\n\nfunction normalizeServerUrl(server_url) {\n  if (!server_url) throw new Error(\"server_url is required\");\n  if (server_url.startsWith(\"http://\")) {\n    server_url =\n      server_url.replace(\"http://\", \"ws://\").replace(/\\/$/, \"\") + \"/ws\";\n  } else if (server_url.startsWith(\"https://\")) {\n    server_url =\n      server_url.replace(\"https://\", \"wss://\").replace(/\\/$/, \"\") + \"/ws\";\n  }\n  return server_url;\n}\n\n/**\n * Login to the hypha server.\n *\n * Configuration options:\n *   server_url: The server URL (required)\n *   workspace: Target workspace (optional)\n *   login_service_id: Login service ID (default: \"public/hypha-login\")\n *   expires_in: Token expiration time (optional)\n *   login_timeout: Timeout for login process (default: 60)\n *   login_callback: Callback function for login URL (optional)\n *   profile: Whether to return user profile (optional)\n *   additional_headers: Additional HTTP headers (optional)\n *   transport: Transport type - \"websocket\" (default) or \"http\"\n */\nexport async function login(config) {\n  const _logger = config.logger === null ? { log() {}, warn() {}, error() {}, info() {} } : (config.logger || console);\n  const service_id = config.login_service_id || \"public/hypha-login\";\n  const workspace = config.workspace;\n  const expires_in = config.expires_in;\n  const timeout = config.login_timeout || 60;\n  const callback = config.login_callback;\n  const profile = config.profile;\n  const additional_headers = config.additional_headers;\n  const transport = config.transport || \"websocket\";\n\n  const server = await connectToServer({\n    name: \"initial login client\",\n    server_url: config.server_url,\n    additional_headers: additional_headers,\n    transport: transport,\n  });\n  try {\n    const svc = await server.getService(service_id);\n    assert(svc, `Failed to get the login service: ${service_id}`);\n    let context;\n    if (workspace) {\n      context = await svc.start({ workspace, expires_in, _rkwargs: true });\n    } else {\n      context = await svc.start();\n    }\n    if (callback) {\n      await callback(context);\n    } else {\n      _logger.log(`Please open your browser and login at ${context.login_url}`);\n    }\n    return await svc.check(context.key, { timeout, profile, _rkwargs: true });\n  } catch (error) {\n    throw error;\n  } finally {\n    await server.disconnect();\n  }\n}\n\n/**\n * Logout from the hypha server.\n *\n * Configuration options:\n *   server_url: The server URL (required)\n *   login_service_id: Login service ID (default: \"public/hypha-login\")\n *   logout_callback: Callback function for logout URL (optional)\n *   additional_headers: Additional HTTP headers (optional)\n *   transport: Transport type - \"websocket\" (default) or \"http\"\n */\nexport async function logout(config) {\n  const _logger = config.logger === null ? { log() {}, warn() {}, error() {}, info() {} } : (config.logger || console);\n  const service_id = config.login_service_id || \"public/hypha-login\";\n  const callback = config.logout_callback;\n  const additional_headers = config.additional_headers;\n  const transport = config.transport || \"websocket\";\n\n  const server = await connectToServer({\n    name: \"initial logout client\",\n    server_url: config.server_url,\n    additional_headers: additional_headers,\n    transport: transport,\n  });\n  try {\n    const svc = await server.getService(service_id);\n    assert(svc, `Failed to get the login service: ${service_id}`);\n\n    // Check if logout function exists for backward compatibility\n    if (!svc.logout) {\n      throw new Error(\n        \"Logout is not supported by this server. \" +\n          \"Please upgrade the Hypha server to a version that supports logout.\",\n      );\n    }\n\n    const context = await svc.logout({});\n    if (callback) {\n      await callback(context);\n    } else {\n      _logger.log(\n        `Please open your browser to logout at ${context.logout_url}`,\n      );\n    }\n    return context;\n  } catch (error) {\n    throw error;\n  } finally {\n    await server.disconnect();\n  }\n}\n\nasync function webrtcGetService(wm, query, config, logger) {\n  config = config || {};\n  const _logger = logger === null ? { log() {}, warn() {}, error() {}, info() {}, debug() {} } : (logger || console);\n  // Default to \"auto\" since this wrapper is only used when connection was\n  // established with webrtc: true\n  const webrtc = config.webrtc !== undefined ? config.webrtc : \"auto\";\n  const webrtc_config = config.webrtc_config;\n  const encryptionPublicKey = config.encryption_public_key;\n  if (config.webrtc !== undefined) delete config.webrtc;\n  if (config.webrtc_config !== undefined) delete config.webrtc_config;\n  if (config.encryption_public_key !== undefined)\n    delete config.encryption_public_key;\n  assert(\n    [undefined, true, false, \"auto\"].includes(webrtc),\n    \"webrtc must be true, false or 'auto'\",\n  );\n\n  const svc = await wm.getService(query, config);\n  if (encryptionPublicKey) {\n    _applyEncryptionKeyToService(svc, publicKeyFromHex(encryptionPublicKey));\n  }\n  if (webrtc === true || webrtc === \"auto\") {\n    if (svc.id.includes(\":\") && svc.id.includes(\"/\")) {\n      try {\n        // Extract remote client_id from service id\n        // svc.id format: \"workspace/client_id:service_id\"\n        const wsAndClient = svc.id.split(\":\")[0]; // \"workspace/client_id\"\n        const parts = wsAndClient.split(\"/\");\n        const remoteClientId = parts[parts.length - 1]; // \"client_id\"\n        const remoteWorkspace = parts.slice(0, -1).join(\"/\"); // \"workspace\"\n        const remoteRtcServiceId = `${remoteWorkspace}/${remoteClientId}-rtc`;\n        const peer = await getRTCService(wm, remoteRtcServiceId, webrtc_config);\n        const rtcSvc = await peer.getService(svc.id.split(\":\")[1], config);\n        rtcSvc._webrtc = true;\n        rtcSvc._peer = peer;\n        rtcSvc._service = svc;\n        return rtcSvc;\n      } catch (e) {\n        _logger.warn(\n          \"Failed to get webrtc service, using websocket connection\",\n          e,\n        );\n      }\n    }\n    if (webrtc === true) {\n      throw new Error(\"Failed to get the service via webrtc\");\n    }\n  }\n  return svc;\n}\n\nexport async function connectToServer(config) {\n  const _logger = config.logger === null ? { log() {}, warn() {}, error() {}, info() {}, debug() {} } : (config.logger || console);\n  // Support HTTP transport via transport option\n  const transport = config.transport || \"websocket\";\n  if (transport === \"http\") {\n    return await connectToServerHTTP(config);\n  }\n\n  if (config.server) {\n    config.server_url = config.server_url || config.server.url;\n    config.WebSocketClass =\n      config.WebSocketClass || config.server.WebSocketClass;\n  }\n  let clientId = config.client_id;\n  if (!clientId) {\n    clientId = randId();\n    config.client_id = clientId;\n  }\n  if (Object.keys(config).length === 0) {\n    if (typeof process !== \"undefined\" && process.env) {\n      // Node.js\n      config.server_url = process.env.HYPHA_SERVER_URL;\n      config.token = process.env.HYPHA_TOKEN;\n      config.client_id = process.env.HYPHA_CLIENT_ID;\n      config.workspace = process.env.HYPHA_WORKSPACE;\n    } else if (typeof self !== \"undefined\" && self.env) {\n      // WebWorker (only if you inject self.env manually)\n      config.server_url = self.env.HYPHA_SERVER_URL;\n      config.token = self.env.HYPHA_TOKEN;\n      config.client_id = self.env.HYPHA_CLIENT_ID;\n      config.workspace = self.env.HYPHA_WORKSPACE;\n    } else if (typeof globalThis !== \"undefined\" && globalThis.env) {\n      // Browser (only if you define globalThis.env beforehand)\n      config.server_url = globalThis.env.HYPHA_SERVER_URL;\n      config.token = globalThis.env.HYPHA_TOKEN;\n      config.client_id = globalThis.env.HYPHA_CLIENT_ID;\n      config.workspace = globalThis.env.HYPHA_WORKSPACE;\n    }\n  }\n\n  let server_url = normalizeServerUrl(config.server_url);\n\n  let connection = new WebsocketRPCConnection(\n    server_url,\n    clientId,\n    config.workspace,\n    config.token,\n    config.reconnection_token,\n    config.method_timeout || 60,\n    config.WebSocketClass,\n    config.token_refresh_interval,\n    config.additional_headers,\n    config.ping_interval,\n    config.logger,\n  );\n  const connection_info = await connection.open();\n  assert(\n    connection_info,\n    \"Failed to connect to the server, no connection info obtained. This issue is most likely due to an outdated Hypha server version. Please use `imjoy-rpc` for compatibility, or upgrade the Hypha server to the latest version.\",\n  );\n  // wait for 0.5 seconds\n  await new Promise((resolve) => setTimeout(resolve, 100));\n  // Ensure manager_id is set before proceeding\n  if (!connection.manager_id) {\n    _logger.warn(\"Manager ID not set immediately, waiting...\");\n\n    // Wait for manager_id to be set with timeout\n    const maxWaitTime = 5000; // 5 seconds\n    const checkInterval = 100; // 100ms\n    const startTime = Date.now();\n\n    while (!connection.manager_id && Date.now() - startTime < maxWaitTime) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n    }\n\n    if (!connection.manager_id) {\n      _logger.error(\"Manager ID still not set after waiting\");\n      throw new Error(\"Failed to get manager ID from server\");\n    } else {\n      _logger.info(`Manager ID set after waiting: ${connection.manager_id}`);\n    }\n  }\n  if (config.workspace && connection_info.workspace !== config.workspace) {\n    throw new Error(\n      `Connected to the wrong workspace: ${connection_info.workspace}, expected: ${config.workspace}`,\n    );\n  }\n\n  const workspace = connection_info.workspace;\n  const rpc = new RPC(connection, {\n    client_id: clientId,\n    workspace,\n    default_context: { connection_type: \"websocket\" },\n    silent: config.silent || false,\n    logger: config.logger,\n    name: config.name,\n    method_timeout: config.method_timeout,\n    rintf_timeout: config.rintf_timeout,\n    app_id: config.app_id,\n    server_base_url: connection_info.public_base_url,\n    long_message_chunk_size: config.long_message_chunk_size,\n    encryption: config.encryption || false,\n    encryption_private_key: config.encryption_private_key || null,\n    encryption_public_key: config.encryption_public_key || null,\n  });\n  await rpc.waitFor(\"services_registered\", config.method_timeout || 120);\n  const wm = await rpc.get_manager_service({\n    timeout: config.method_timeout,\n    case_conversion: \"camel\",\n    kwargs_expansion: config.kwargs_expansion || false,\n  });\n  wm.rpc = rpc;\n\n  // Auto-refresh workspace manager proxy after reconnection.\n  // When the server restarts, it assigns a new manager_id. The remote\n  // methods on wm have their target baked into __rpc_object__._rtarget.\n  // Since remote_method() reads _rtarget at call time (not generation\n  // time), we just update _rtarget on every existing method — no need\n  // to regenerate methods or copy from a fresh proxy. This preserves\n  // locally-overridden methods (registerService, unregisterService, etc.)\n  // that would otherwise be lost by wholesale function copying.\n  let isInitialRefresh = true;\n  rpc.on(\"manager_refreshed\", async () => {\n    if (isInitialRefresh) {\n      isInitialRefresh = false;\n      return; // Skip the first event (initial connection, wm is already fresh)\n    }\n    try {\n      const newTarget = `*/${rpc._connection.manager_id}`;\n      // Retarget all remote methods on the wm proxy to the new manager\n      for (const key of Object.keys(wm)) {\n        if (typeof wm[key] === \"function\" && wm[key].__rpc_object__) {\n          wm[key].__rpc_object__._rtarget = newTarget;\n        }\n      }\n      _logger.info(\n        \"Workspace manager proxy retargeted after reconnection (new manager_id:\",\n        rpc._connection?.manager_id + \")\",\n      );\n    } catch (err) {\n      _logger.warn(\n        \"Failed to retarget workspace manager after reconnection:\",\n        err,\n      );\n    }\n  });\n\n  async function _export(api) {\n    api.id = \"default\";\n    api.name = api.name || config.name || api.id;\n    api.description = api.description || config.description;\n    await rpc.register_service(api, { overwrite: true });\n  }\n\n  async function getApp(clientId) {\n    clientId = clientId || \"*\";\n    assert(!clientId.includes(\":\"), \"clientId should not contain ':'\");\n    if (!clientId.includes(\"/\")) {\n      clientId = connection_info.workspace + \"/\" + clientId;\n    }\n    assert(\n      clientId.split(\"/\").length === 2,\n      \"clientId should match pattern workspace/clientId\",\n    );\n    return await wm.getService(`${clientId}:default`);\n  }\n\n  async function listApps(ws) {\n    ws = ws || workspace;\n    assert(!ws.includes(\":\"), \"workspace should not contain ':'\");\n    assert(!ws.includes(\"/\"), \"workspace should not contain '/'\");\n    const query = { workspace: ws, service_id: \"default\" };\n    return await wm.listServices(query);\n  }\n\n  if (connection_info) {\n    wm.config = Object.assign(wm.config, connection_info);\n  }\n  wm.export = schemaFunction(_export, {\n    name: \"export\",\n    description: \"Export the api.\",\n    parameters: {\n      properties: { api: { description: \"The api to export\", type: \"object\" } },\n      required: [\"api\"],\n      type: \"object\",\n    },\n  });\n  wm.getApp = schemaFunction(getApp, {\n    name: \"getApp\",\n    description: \"Get the app.\",\n    parameters: {\n      properties: {\n        clientId: { default: \"*\", description: \"The clientId\", type: \"string\" },\n      },\n      type: \"object\",\n    },\n  });\n  wm.listApps = schemaFunction(listApps, {\n    name: \"listApps\",\n    description: \"List the apps.\",\n    parameters: {\n      properties: {\n        workspace: {\n          default: workspace,\n          description: \"The workspace\",\n          type: \"string\",\n        },\n      },\n      type: \"object\",\n    },\n  });\n  wm.disconnect = schemaFunction(rpc.disconnect.bind(rpc), {\n    name: \"disconnect\",\n    description: \"Disconnect from the server.\",\n    parameters: { type: \"object\", properties: {}, required: [] },\n  });\n  wm.registerCodec = schemaFunction(rpc.register_codec.bind(rpc), {\n    name: \"registerCodec\",\n    description: \"Register a codec for the webrtc connection\",\n    parameters: {\n      type: \"object\",\n      properties: {\n        codec: {\n          type: \"object\",\n          description: \"Codec to register\",\n          properties: {\n            name: { type: \"string\" },\n            type: {},\n            encoder: { type: \"function\" },\n            decoder: { type: \"function\" },\n          },\n        },\n      },\n    },\n  });\n\n  wm.emit = schemaFunction(rpc.emit.bind(rpc), {\n    name: \"emit\",\n    description: \"Emit a message.\",\n    parameters: {\n      properties: { data: { description: \"The data to emit\", type: \"object\" } },\n      required: [\"data\"],\n      type: \"object\",\n    },\n  });\n\n  wm.on = schemaFunction(rpc.on.bind(rpc), {\n    name: \"on\",\n    description: \"Register a message handler.\",\n    parameters: {\n      properties: {\n        event: { description: \"The event to listen to\", type: \"string\" },\n        handler: { description: \"The handler function\", type: \"function\" },\n      },\n      required: [\"event\", \"handler\"],\n      type: \"object\",\n    },\n  });\n\n  wm.off = schemaFunction(rpc.off.bind(rpc), {\n    name: \"off\",\n    description: \"Remove a message handler.\",\n    parameters: {\n      properties: {\n        event: { description: \"The event to remove\", type: \"string\" },\n        handler: { description: \"The handler function\", type: \"function\" },\n      },\n      required: [\"event\", \"handler\"],\n      type: \"object\",\n    },\n  });\n\n  wm.once = schemaFunction(rpc.once.bind(rpc), {\n    name: \"once\",\n    description: \"Register a one-time message handler.\",\n    parameters: {\n      properties: {\n        event: { description: \"The event to listen to\", type: \"string\" },\n        handler: { description: \"The handler function\", type: \"function\" },\n      },\n      required: [\"event\", \"handler\"],\n      type: \"object\",\n    },\n  });\n\n  wm.getServiceSchema = schemaFunction(rpc.get_service_schema, {\n    name: \"getServiceSchema\",\n    description: \"Get the service schema.\",\n    parameters: {\n      properties: {\n        service: {\n          description: \"The service to extract schema\",\n          type: \"object\",\n        },\n      },\n      required: [\"service\"],\n      type: \"object\",\n    },\n  });\n\n  wm.registerService = schemaFunction(rpc.register_service.bind(rpc), {\n    name: \"registerService\",\n    description: \"Register a service.\",\n    parameters: {\n      properties: {\n        service: { description: \"The service to register\", type: \"object\" },\n        force: {\n          default: false,\n          description: \"Force to register the service\",\n          type: \"boolean\",\n        },\n      },\n      required: [\"service\"],\n      type: \"object\",\n    },\n  });\n  wm.unregisterService = schemaFunction(rpc.unregister_service.bind(rpc), {\n    name: \"unregisterService\",\n    description: \"Unregister a service.\",\n    parameters: {\n      properties: {\n        service: {\n          description: \"The service id to unregister\",\n          type: \"string\",\n        },\n        notify: {\n          default: true,\n          description: \"Notify the workspace manager\",\n          type: \"boolean\",\n        },\n      },\n      required: [\"service\"],\n      type: \"object\",\n    },\n  });\n  if (connection.manager_id) {\n    rpc.on(\"force-exit\", async (message) => {\n      if (message.from === \"*/\" + connection.manager_id) {\n        _logger.log(\"Disconnecting from server, reason:\", message.reason);\n        await rpc.disconnect();\n      }\n    });\n  }\n  if (config.webrtc) {\n    await registerRTCService(wm, `${clientId}-rtc`, config.webrtc_config);\n    // make a copy of wm, so webrtc can use the original wm.getService\n    const _wm = Object.assign({}, wm);\n    const description = _wm.getService.__schema__.description;\n    // TODO: Fix the schema for adding options for webrtc\n    const parameters = _wm.getService.__schema__.parameters;\n    wm.getService = schemaFunction(function(query, cfg) { return webrtcGetService(_wm, query, cfg, config.logger); }, {\n      name: \"getService\",\n      description,\n      parameters,\n    });\n\n    wm.getRTCService = schemaFunction(getRTCService.bind(null, wm), {\n      name: \"getRTCService\",\n      description: \"Get the webrtc connection, returns a peer connection.\",\n      parameters: {\n        properties: {\n          config: {\n            description: \"The config for the webrtc service\",\n            type: \"object\",\n          },\n        },\n        required: [\"config\"],\n        type: \"object\",\n      },\n    });\n  } else {\n    const _getService = wm.getService;\n    wm.getService = async (query, config) => {\n      config = config || {};\n      const encryptionPublicKey = config.encryption_public_key;\n      delete config.encryption_public_key;\n      const svc = await _getService(query, config);\n      if (encryptionPublicKey) {\n        _applyEncryptionKeyToService(svc, publicKeyFromHex(encryptionPublicKey));\n      }\n      return svc;\n    };\n    wm.getService.__schema__ = _getService.__schema__;\n  }\n\n  async function registerProbes(probes) {\n    probes.id = \"probes\";\n    probes.name = \"Probes\";\n    probes.config = { visibility: \"public\" };\n    probes.type = \"probes\";\n    probes.description = `Probes Service, visit ${server_url}/${workspace}services/probes for the available probes.`;\n    return await wm.registerService(probes, { overwrite: true });\n  }\n\n  wm.registerProbes = schemaFunction(registerProbes, {\n    name: \"registerProbes\",\n    description: \"Register probes service\",\n    parameters: {\n      properties: {\n        probes: {\n          description:\n            \"The probes to register, e.g. {'liveness': {'type': 'function', 'description': 'Check the liveness of the service'}}\",\n          type: \"object\",\n        },\n      },\n      required: [\"probes\"],\n      type: \"object\",\n    },\n  });\n  return wm;\n}\n\nexport async function getRemoteService(serviceUri, config = {}) {\n  const { serverUrl, workspace, clientId, serviceId, appId } =\n    parseServiceUrl(serviceUri);\n  const fullServiceId = `${workspace}/${clientId}:${serviceId}@${appId}`;\n\n  if (config.serverUrl) {\n    if (config.serverUrl !== serverUrl) {\n      throw new Error(\n        \"server_url in config does not match the server_url in the url\",\n      );\n    }\n  }\n  config.serverUrl = serverUrl;\n  const server = await connectToServer(config);\n  return await server.getService(fullServiceId);\n}\n\nexport class LocalWebSocket {\n  constructor(url, client_id, workspace) {\n    this.url = url;\n    this.onopen = () => {};\n    this.onmessage = () => {};\n    this.onclose = () => {};\n    this.onerror = () => {};\n    this.client_id = client_id;\n    this.workspace = workspace;\n    const context = typeof window !== \"undefined\" ? window : self;\n    const isWindow = typeof window !== \"undefined\";\n    this.postMessage = (message) => {\n      if (isWindow) {\n        window.parent.postMessage(message, \"*\");\n      } else {\n        self.postMessage(message);\n      }\n    };\n\n    this.readyState = WebSocket.CONNECTING;\n    this._context = context;\n    this._messageListener = (event) => {\n      const { type, data, to } = event.data;\n      if (to !== this.client_id) {\n        return;\n      }\n      switch (type) {\n        case \"message\":\n          if (this.readyState === WebSocket.OPEN && this.onmessage) {\n            this.onmessage({ data: data });\n          }\n          break;\n        case \"connected\":\n          this.readyState = WebSocket.OPEN;\n          this.onopen(event);\n          break;\n        case \"closed\":\n          this.readyState = WebSocket.CLOSED;\n          this.onclose(event);\n          break;\n        default:\n          break;\n      }\n    };\n    context.addEventListener(\"message\", this._messageListener, false);\n\n    if (!this.client_id) throw new Error(\"client_id is required\");\n    if (!this.workspace) throw new Error(\"workspace is required\");\n    this.postMessage({\n      type: \"connect\",\n      url: this.url,\n      from: this.client_id,\n      workspace: this.workspace,\n    });\n  }\n\n  send(data) {\n    if (this.readyState === WebSocket.OPEN) {\n      this.postMessage({\n        type: \"message\",\n        data: data,\n        from: this.client_id,\n        workspace: this.workspace,\n      });\n    }\n  }\n\n  close() {\n    this.readyState = WebSocket.CLOSING;\n    this.postMessage({\n      type: \"close\",\n      from: this.client_id,\n      workspace: this.workspace,\n    });\n    if (this._context && this._messageListener) {\n      this._context.removeEventListener(\n        \"message\",\n        this._messageListener,\n        false,\n      );\n      this._messageListener = null;\n    }\n    this.onclose();\n  }\n\n  addEventListener(type, listener) {\n    if (type === \"message\") {\n      this.onmessage = listener;\n    }\n    if (type === \"open\") {\n      this.onopen = listener;\n    }\n    if (type === \"close\") {\n      this.onclose = listener;\n    }\n    if (type === \"error\") {\n      this.onerror = listener;\n    }\n  }\n}\n\n// Also export a hyphaWebsocketClient namespace for backwards compatibility.\n// hypha-core's deno build does: import { hyphaWebsocketClient } from 'hypha-rpc'\n// The UMD build wraps everything under this name via webpack's `library` option,\n// but the ESM build exports flat, so we need this explicit re-export.\nexport { WebsocketRPCConnection };\n\nexport const hyphaWebsocketClient = {\n  RPC,\n  API_VERSION,\n  schemaFunction,\n  loadRequirements,\n  login,\n  logout,\n  connectToServer,\n  connectToServerHTTP,\n  getRemoteService,\n  getRemoteServiceHTTP,\n  getRTCService,\n  registerRTCService,\n  get setupLocalClient() { return setupLocalClient; },\n  get LocalWebSocket() { return LocalWebSocket; },\n  HTTPStreamingRPCConnection,\n  normalizeServerUrlHTTP,\n};\n\nexport function setupLocalClient({\n  enable_execution = false,\n  on_ready = null,\n}) {\n  return new Promise((resolve, reject) => {\n    const context = typeof window !== \"undefined\" ? window : self;\n    const isWindow = typeof window !== \"undefined\";\n    context.addEventListener(\n      \"message\",\n      (event) => {\n        const {\n          type,\n          server_url,\n          workspace,\n          client_id,\n          token,\n          method_timeout,\n          name,\n          config,\n        } = event.data;\n\n        if (type === \"initializeHyphaClient\") {\n          if (!server_url || !workspace || !client_id) {\n            _logger.error(\"server_url, workspace, and client_id are required.\");\n            return;\n          }\n\n          if (!server_url.startsWith(\"https://local-hypha-server:\")) {\n            _logger.error(\n              \"server_url should start with https://local-hypha-server:\",\n            );\n            return;\n          }\n\n          class FixedLocalWebSocket extends LocalWebSocket {\n            constructor(url) {\n              // Call the parent class's constructor with fixed values\n              super(url, client_id, workspace);\n            }\n          }\n          connectToServer({\n            server_url,\n            workspace,\n            client_id,\n            token,\n            method_timeout,\n            name,\n            WebSocketClass: FixedLocalWebSocket,\n          }).then(async (server) => {\n            globalThis.api = server;\n            try {\n              // for iframe\n              if (isWindow && enable_execution) {\n                function loadScript(script) {\n                  return new Promise((resolve, reject) => {\n                    const scriptElement = document.createElement(\"script\");\n                    scriptElement.innerHTML = script.content;\n                    scriptElement.lang = script.lang;\n\n                    scriptElement.onload = () => resolve();\n                    scriptElement.onerror = (e) => reject(e);\n\n                    document.head.appendChild(scriptElement);\n                  });\n                }\n                if (config.styles && config.styles.length > 0) {\n                  for (const style of config.styles) {\n                    const styleElement = document.createElement(\"style\");\n                    styleElement.innerHTML = style.content;\n                    styleElement.lang = style.lang;\n                    document.head.appendChild(styleElement);\n                  }\n                }\n                if (config.links && config.links.length > 0) {\n                  for (const link of config.links) {\n                    const linkElement = document.createElement(\"a\");\n                    linkElement.href = link.url;\n                    linkElement.innerText = link.text;\n                    document.body.appendChild(linkElement);\n                  }\n                }\n                if (config.windows && config.windows.length > 0) {\n                  for (const w of config.windows) {\n                    document.body.innerHTML = w.content;\n                    break;\n                  }\n                }\n                if (config.scripts && config.scripts.length > 0) {\n                  for (const script of config.scripts) {\n                    if (script.lang !== \"javascript\")\n                      throw new Error(\"Only javascript scripts are supported\");\n                    await loadScript(script); // Await the loading of each script\n                  }\n                }\n              }\n              // for web worker\n              else if (\n                !isWindow &&\n                enable_execution &&\n                config.scripts &&\n                config.scripts.length > 0\n              ) {\n                for (const script of config.scripts) {\n                  if (script.lang !== \"javascript\")\n                    throw new Error(\"Only javascript scripts are supported\");\n                  eval(script.content);\n                }\n              }\n\n              if (on_ready) {\n                await on_ready(server, config);\n              }\n              resolve(server);\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n      },\n      false,\n    );\n    if (isWindow) {\n      window.parent.postMessage({ type: \"hyphaClientReady\" }, \"*\");\n    } else {\n      self.postMessage({ type: \"hyphaClientReady\" });\n    }\n  });\n}\n"],"names":[],"sourceRoot":""}