@honeybbq/teamspeak-client 0.2.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +1 -0
  2. package/dist/address-BR-5unVo.cjs +2 -0
  3. package/dist/address-BR-5unVo.cjs.map +1 -0
  4. package/dist/address-BfmovVpp.js +65 -0
  5. package/dist/address-BfmovVpp.js.map +1 -0
  6. package/dist/address.d.ts +9 -0
  7. package/dist/address.d.ts.map +1 -0
  8. package/dist/api.d.ts.map +1 -1
  9. package/dist/client.d.ts +2 -0
  10. package/dist/client.d.ts.map +1 -1
  11. package/dist/command/index.cjs +1 -1
  12. package/dist/command/index.mjs +2 -2
  13. package/dist/{command-CTDmBXd_.js → command-BLe-C2L2.js} +2 -4
  14. package/dist/{command-CUPNiKRl.cjs.map → command-BLe-C2L2.js.map} +1 -1
  15. package/dist/command-DAK4pUBP.cjs +4 -0
  16. package/dist/command-DAK4pUBP.cjs.map +1 -0
  17. package/dist/commands.d.ts.map +1 -1
  18. package/dist/{crypt-handshake-D2Rsi2e3.cjs → crypt-handshake-CQkQreLx.cjs} +2 -2
  19. package/dist/crypt-handshake-CQkQreLx.cjs.map +1 -0
  20. package/dist/{crypt-handshake-DIj51kno.js → crypt-handshake-DziOY4Lq.js} +2 -2
  21. package/dist/crypt-handshake-DziOY4Lq.js.map +1 -0
  22. package/dist/{crypt-init2-C2X9oK4i.js → crypt-init2-D70ha4LB.js} +6 -6
  23. package/dist/crypt-init2-D70ha4LB.js.map +1 -0
  24. package/dist/{crypt-init2-CazdFwqF.cjs → crypt-init2-DparLekm.cjs} +2 -2
  25. package/dist/crypt-init2-DparLekm.cjs.map +1 -0
  26. package/dist/crypto/crypt.d.ts.map +1 -1
  27. package/dist/crypto/eax.d.ts.map +1 -1
  28. package/dist/crypto/identity.d.ts.map +1 -1
  29. package/dist/crypto/index.cjs +1 -1
  30. package/dist/crypto/index.mjs +2 -2
  31. package/dist/{crypto-CwIMggQG.js → crypto-Bg02m4ZE.js} +7 -7
  32. package/dist/crypto-Bg02m4ZE.js.map +1 -0
  33. package/dist/crypto-CDlweUL3.cjs +2 -0
  34. package/dist/crypto-CDlweUL3.cjs.map +1 -0
  35. package/dist/discovery/index.cjs +1 -1
  36. package/dist/discovery/index.mjs +1 -1
  37. package/dist/discovery/resolver.d.ts.map +1 -1
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/{handler-BP38rMNl.js → handler-DI_abe9c.js} +153 -125
  40. package/dist/handler-DI_abe9c.js.map +1 -0
  41. package/dist/handler-DuwoO5RC.cjs +2 -0
  42. package/dist/handler-DuwoO5RC.cjs.map +1 -0
  43. package/dist/handshake/index.cjs +1 -1
  44. package/dist/handshake/index.mjs +2 -2
  45. package/dist/handshake/license.d.ts.map +1 -1
  46. package/dist/helpers.d.ts.map +1 -1
  47. package/dist/index.cjs +2 -2
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.mjs +236 -191
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/{parser-B6cGUByG.cjs → parser-CL33R9tr.cjs} +2 -2
  52. package/dist/parser-CL33R9tr.cjs.map +1 -0
  53. package/dist/{parser-BPzO8py_.js → parser-DZMv3Jm-.js} +2 -2
  54. package/dist/parser-DZMv3Jm-.js.map +1 -0
  55. package/dist/primitives-cNNAeFCo.cjs +2 -0
  56. package/dist/primitives-cNNAeFCo.cjs.map +1 -0
  57. package/dist/primitives-xIr6Tjk4.js +1457 -0
  58. package/dist/primitives-xIr6Tjk4.js.map +1 -0
  59. package/dist/resolver-6B8dI9gr.js +141 -0
  60. package/dist/resolver-6B8dI9gr.js.map +1 -0
  61. package/dist/resolver-DCcmyWSK.cjs +4 -0
  62. package/dist/resolver-DCcmyWSK.cjs.map +1 -0
  63. package/dist/throttle.d.ts.map +1 -1
  64. package/dist/transfer.d.ts.map +1 -1
  65. package/dist/transport/generation-window.d.ts.map +1 -1
  66. package/dist/transport/handler.d.ts +2 -0
  67. package/dist/transport/handler.d.ts.map +1 -1
  68. package/dist/transport/index.cjs +1 -1
  69. package/dist/transport/index.mjs +1 -1
  70. package/dist/transport/quicklz.d.ts.map +1 -1
  71. package/dist/types.d.ts +2 -0
  72. package/dist/types.d.ts.map +1 -1
  73. package/package.json +6 -7
  74. package/dist/command/command.test.d.ts +0 -2
  75. package/dist/command/command.test.d.ts.map +0 -1
  76. package/dist/command-CTDmBXd_.js.map +0 -1
  77. package/dist/command-CUPNiKRl.cjs +0 -4
  78. package/dist/crypt-handshake-D2Rsi2e3.cjs.map +0 -1
  79. package/dist/crypt-handshake-DIj51kno.js.map +0 -1
  80. package/dist/crypt-init2-C2X9oK4i.js.map +0 -1
  81. package/dist/crypt-init2-CazdFwqF.cjs.map +0 -1
  82. package/dist/crypto/eax.test.d.ts +0 -2
  83. package/dist/crypto/eax.test.d.ts.map +0 -1
  84. package/dist/crypto/identity.test.d.ts +0 -2
  85. package/dist/crypto/identity.test.d.ts.map +0 -1
  86. package/dist/crypto-CwIMggQG.js.map +0 -1
  87. package/dist/crypto-IbzNNTgO.cjs +0 -2
  88. package/dist/crypto-IbzNNTgO.cjs.map +0 -1
  89. package/dist/handler-BJdwhtkp.cjs +0 -2
  90. package/dist/handler-BJdwhtkp.cjs.map +0 -1
  91. package/dist/handler-BP38rMNl.js.map +0 -1
  92. package/dist/handshake.test.d.ts +0 -2
  93. package/dist/handshake.test.d.ts.map +0 -1
  94. package/dist/helpers.test.d.ts +0 -2
  95. package/dist/helpers.test.d.ts.map +0 -1
  96. package/dist/integration.test.d.ts +0 -12
  97. package/dist/integration.test.d.ts.map +0 -1
  98. package/dist/notifications.test.d.ts +0 -2
  99. package/dist/notifications.test.d.ts.map +0 -1
  100. package/dist/parser-B6cGUByG.cjs.map +0 -1
  101. package/dist/parser-BPzO8py_.js.map +0 -1
  102. package/dist/primitives-Bt-L4BZa.js +0 -1483
  103. package/dist/primitives-Bt-L4BZa.js.map +0 -1
  104. package/dist/primitives-ClIhDdNZ.cjs +0 -2
  105. package/dist/primitives-ClIhDdNZ.cjs.map +0 -1
  106. package/dist/resolver-B7jho9CP.cjs +0 -4
  107. package/dist/resolver-B7jho9CP.cjs.map +0 -1
  108. package/dist/resolver-BDCF2KbM.js +0 -162
  109. package/dist/resolver-BDCF2KbM.js.map +0 -1
  110. package/dist/throttle.test.d.ts +0 -2
  111. package/dist/throttle.test.d.ts.map +0 -1
  112. package/dist/transport/generation-window.test.d.ts +0 -2
  113. package/dist/transport/generation-window.test.d.ts.map +0 -1
  114. package/dist/transport/packet.test.d.ts +0 -2
  115. package/dist/transport/packet.test.d.ts.map +0 -1
  116. package/dist/transport/quicklz.test.d.ts +0 -2
  117. package/dist/transport/quicklz.test.d.ts.map +0 -1
  118. package/dist/types-ANvuLFWH.cjs +0 -2
  119. package/dist/types-ANvuLFWH.cjs.map +0 -1
  120. package/dist/types-Xm1vrW4s.js +0 -18
  121. package/dist/types-Xm1vrW4s.js.map +0 -1
@@ -0,0 +1,141 @@
1
+ import { n as e, o as t, r as n, t as r } from "./address-BfmovVpp.js";
2
+ import { resolveSrv as i } from "node:dns/promises";
3
+ import { createConnection as a } from "node:net";
4
+ //#region src/discovery/resolver.ts
5
+ var o = 41144, s = "https://named.myteamspeak.com/lookup", c = 6e5, l = class {
6
+ #e = /* @__PURE__ */ new Map();
7
+ constructor(e = t) {}
8
+ async resolve(t, i) {
9
+ if (!t) throw Error("empty address");
10
+ let a = this.#t(t);
11
+ if (a) return a;
12
+ let { host: o, port: s } = n(t);
13
+ if (r(o)) return [{
14
+ addr: e(o, s),
15
+ source: "Direct",
16
+ expiry: /* @__PURE__ */ new Date(0)
17
+ }];
18
+ if (!o.includes(".") && o !== "localhost") {
19
+ let e = await u(o, i);
20
+ if (e) return this.resolve(e, i);
21
+ }
22
+ let c = await this.#r(o, i);
23
+ if (c) return this.#n(t, c);
24
+ let l = p(o), d = await this.#i(l, o, i);
25
+ if (d) return this.#n(t, [{
26
+ addr: d,
27
+ source: "TSDNS-SRV",
28
+ expiry: /* @__PURE__ */ new Date(0)
29
+ }]);
30
+ let f = await this.#a(l, o, i);
31
+ if (f) return this.#n(t, [{
32
+ addr: f,
33
+ source: "TSDNS-Direct",
34
+ expiry: /* @__PURE__ */ new Date(0)
35
+ }]);
36
+ let m = [{
37
+ addr: e(o, s),
38
+ source: "Direct",
39
+ expiry: /* @__PURE__ */ new Date(0)
40
+ }];
41
+ return this.#n(t, m);
42
+ }
43
+ #t(e) {
44
+ let t = this.#e.get(e);
45
+ if (!t || t.length === 0) return null;
46
+ let n = t[0];
47
+ return n.expiry.getTime() > 0 && Date.now() > n.expiry.getTime() ? null : t;
48
+ }
49
+ #n(e, t) {
50
+ let n = new Date(Date.now() + c), r = t.map((e) => ({
51
+ ...e,
52
+ expiry: n
53
+ }));
54
+ return this.#e.set(e, r), r;
55
+ }
56
+ async #r(t, n) {
57
+ try {
58
+ let r = await m(i(`_ts3._udp.${t}`), n);
59
+ return !r || r.length === 0 ? null : r.map((t) => ({
60
+ addr: e(t.name.replace(/\.$/, ""), String(t.port)),
61
+ source: "SRV",
62
+ expiry: /* @__PURE__ */ new Date(0)
63
+ }));
64
+ } catch {
65
+ return null;
66
+ }
67
+ }
68
+ async #i(t, n, r) {
69
+ for (let a of t) try {
70
+ let t = await m(i(`_tsdns._tcp.${a}`), r);
71
+ if (!t || t.length === 0) continue;
72
+ for (let i of t) {
73
+ let t = await d(e(i.name.replace(/\.$/, ""), String(i.port)), n, r);
74
+ if (t) return t;
75
+ }
76
+ } catch {
77
+ continue;
78
+ }
79
+ return null;
80
+ }
81
+ async #a(t, n, r) {
82
+ for (let i of t) {
83
+ let t = await d(e(i, String(o)), n, r);
84
+ if (t) return t;
85
+ }
86
+ return null;
87
+ }
88
+ };
89
+ async function u(e, t) {
90
+ try {
91
+ let n = new URL(s);
92
+ n.searchParams.set("name", e);
93
+ let r = t ? { signal: t } : {}, i = await fetch(n.toString(), r);
94
+ return i.ok && (await i.text()).split("\n")[0]?.trim() || null;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ function d(e, t, n) {
100
+ let [r, i] = f(e), o = parseInt(i, 10);
101
+ return new Promise((e) => {
102
+ let i = setTimeout(() => {
103
+ s.destroy(), e(null);
104
+ }, 3e3), s = a({
105
+ host: r,
106
+ port: o,
107
+ timeout: 2e3
108
+ }, () => {
109
+ s.write(`${t}\n`);
110
+ }), c = "";
111
+ s.on("data", (t) => {
112
+ c += t.toString();
113
+ let n = c.indexOf("\n");
114
+ if (n >= 0) {
115
+ clearTimeout(i), s.destroy();
116
+ let t = c.slice(0, n).trim();
117
+ e(!t || t === "404" || t === "errors" ? null : t);
118
+ }
119
+ }), s.on("error", () => {
120
+ clearTimeout(i), e(null);
121
+ }), n && n.addEventListener("abort", () => {
122
+ clearTimeout(i), s.destroy(), e(null);
123
+ }, { once: !0 });
124
+ });
125
+ }
126
+ function f(e) {
127
+ let { host: t, port: r } = n(e);
128
+ return [t, r];
129
+ }
130
+ function p(e) {
131
+ let t = e.split("."), n = [];
132
+ for (let e = 0; e < t.length - 1; e++) n.push(t.slice(e).join("."));
133
+ return n.slice(0, 3);
134
+ }
135
+ function m(e, t) {
136
+ return t ? Promise.race([e, new Promise((e, n) => t.addEventListener("abort", () => n(t.reason), { once: !0 }))]) : e;
137
+ }
138
+ //#endregion
139
+ export { l as t };
140
+
141
+ //# sourceMappingURL=resolver-6B8dI9gr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver-6B8dI9gr.js","names":["joinHostPort","noopLogger","splitHostPort","isIpAddress","TS_DNS_DEFAULT_PORT","NICKNAME_LOOKUP_URL","CACHE_TTL_MS","Resolver","inputAddr","cached","#getValidCache","host","port","nickAddr","resolveNickname","signal","srvResults","#resolveSRV","#setCache","domainList","getDomainList","tsdnsSrv","#resolveTSDNSSRV","tsdnsDirect","#resolveTSDNSDirect","fallback","#cache","first","expiry","withExpiry","results","r","key","srvs","withSignal","resolveSrv","srv","domain","domains","result","queryTSDNS","queryHost","url","nickname","init","resp","portStr","splitHostPortParts","tsdnsAddr","timeout","socket","resolve","createConnection","buf","chunk","idx","line","addr","parts","list","i","promise","reject"],"sources":["../src/discovery/resolver.ts"],"sourcesContent":["import { resolveSrv } from \"node:dns/promises\";\nimport { createConnection } from \"node:net\";\nimport type { Logger } from \"../types.js\";\nimport type { ResolvedAddr } from \"../types.js\";\nimport { noopLogger } from \"../types.js\";\nimport { isIpAddress, joinHostPort, splitHostPort } from \"../address.js\";\n\nconst TS_DNS_DEFAULT_PORT = 41144;\nconst NICKNAME_LOOKUP_URL = \"https://named.myteamspeak.com/lookup\";\nconst CACHE_TTL_MS = 10 * 60 * 1000;\n\nexport class Resolver {\n readonly #cache = new Map<string, ResolvedAddr[]>();\n\n constructor(_log: Logger = noopLogger) {}\n\n async resolve(inputAddr: string, signal?: AbortSignal): Promise<ResolvedAddr[]> {\n if (!inputAddr) throw new Error(\"empty address\");\n\n const cached = this.#getValidCache(inputAddr);\n if (cached) return cached;\n\n const { host, port } = splitHostPort(inputAddr);\n\n if (isIpAddress(host)) {\n return [{ addr: joinHostPort(host, port), source: \"Direct\", expiry: new Date(0) }];\n }\n\n // Nickname resolution (no dots → not a domain)\n if (!host.includes(\".\") && host !== \"localhost\") {\n const nickAddr = await resolveNickname(host, signal);\n if (nickAddr) {\n return this.resolve(nickAddr, signal);\n }\n }\n\n // SRV _ts3._udp.<host>\n const srvResults = await this.#resolveSRV(host, signal);\n if (srvResults) return this.#setCache(inputAddr, srvResults);\n\n const domainList = getDomainList(host);\n\n // TSDNS via SRV _tsdns._tcp.<domain>\n const tsdnsSrv = await this.#resolveTSDNSSRV(domainList, host, signal);\n if (tsdnsSrv) {\n return this.#setCache(inputAddr, [\n { addr: tsdnsSrv, source: \"TSDNS-SRV\", expiry: new Date(0) },\n ]);\n }\n\n // TSDNS direct :41144\n const tsdnsDirect = await this.#resolveTSDNSDirect(domainList, host, signal);\n if (tsdnsDirect) {\n return this.#setCache(inputAddr, [\n { addr: tsdnsDirect, source: \"TSDNS-Direct\", expiry: new Date(0) },\n ]);\n }\n\n // Plain DNS fallback\n const fallback: ResolvedAddr[] = [\n { addr: joinHostPort(host, port), source: \"Direct\", expiry: new Date(0) },\n ];\n return this.#setCache(inputAddr, fallback);\n }\n\n #getValidCache(inputAddr: string): ResolvedAddr[] | null {\n const cached = this.#cache.get(inputAddr);\n if (!cached || cached.length === 0) return null;\n const first = cached[0]!;\n if (first.expiry.getTime() > 0 && Date.now() > first.expiry.getTime()) return null;\n return cached;\n }\n\n #setCache(key: string, results: ResolvedAddr[]): ResolvedAddr[] {\n const expiry = new Date(Date.now() + CACHE_TTL_MS);\n const withExpiry = results.map((r) => ({ ...r, expiry }));\n this.#cache.set(key, withExpiry);\n return withExpiry;\n }\n\n async #resolveSRV(host: string, signal?: AbortSignal): Promise<ResolvedAddr[] | null> {\n try {\n const srvs = await withSignal(resolveSrv(`_ts3._udp.${host}`), signal);\n if (!srvs || srvs.length === 0) return null;\n return srvs.map((srv) => ({\n addr: joinHostPort(srv.name.replace(/\\.$/, \"\"), String(srv.port)),\n source: \"SRV\",\n expiry: new Date(0),\n }));\n } catch {\n return null;\n }\n }\n\n async #resolveTSDNSSRV(\n domains: string[],\n queryHost: string,\n signal?: AbortSignal,\n ): Promise<string | null> {\n for (const domain of domains) {\n try {\n const srvs = await withSignal(resolveSrv(`_tsdns._tcp.${domain}`), signal);\n if (!srvs || srvs.length === 0) continue;\n for (const srv of srvs) {\n const tsdnsAddr = joinHostPort(srv.name.replace(/\\.$/, \"\"), String(srv.port));\n const result = await queryTSDNS(tsdnsAddr, queryHost, signal);\n if (result) return result;\n }\n } catch {\n continue;\n }\n }\n return null;\n }\n\n async #resolveTSDNSDirect(\n domains: string[],\n queryHost: string,\n signal?: AbortSignal,\n ): Promise<string | null> {\n for (const domain of domains) {\n const tsdnsAddr = joinHostPort(domain, String(TS_DNS_DEFAULT_PORT));\n const result = await queryTSDNS(tsdnsAddr, queryHost, signal);\n if (result) return result;\n }\n return null;\n }\n}\n\n// ---- Helpers ----------------------------------------------------------------\n\nasync function resolveNickname(nickname: string, signal?: AbortSignal): Promise<string | null> {\n try {\n const url = new URL(NICKNAME_LOOKUP_URL);\n url.searchParams.set(\"name\", nickname);\n const init: RequestInit = signal ? { signal } : {};\n const resp = await fetch(url.toString(), init);\n if (!resp.ok) return null;\n const text = await resp.text();\n const line = text.split(\"\\n\")[0]?.trim();\n return line || null;\n } catch {\n return null;\n }\n}\n\nfunction queryTSDNS(\n tsdnsAddr: string,\n queryHost: string,\n signal?: AbortSignal,\n): Promise<string | null> {\n const [host, portStr] = splitHostPortParts(tsdnsAddr);\n const port = parseInt(portStr, 10);\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n socket.destroy();\n resolve(null);\n }, 3_000);\n\n const socket = createConnection({ host, port, timeout: 2_000 }, () => {\n socket.write(`${queryHost}\\n`);\n });\n\n let buf = \"\";\n socket.on(\"data\", (chunk: Buffer) => {\n buf += chunk.toString();\n const idx = buf.indexOf(\"\\n\");\n if (idx >= 0) {\n clearTimeout(timeout);\n socket.destroy();\n const line = buf.slice(0, idx).trim();\n if (!line || line === \"404\" || line === \"errors\") resolve(null);\n else resolve(line);\n }\n });\n\n socket.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(null);\n });\n\n if (signal) {\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timeout);\n socket.destroy();\n resolve(null);\n },\n { once: true },\n );\n }\n });\n}\n\nfunction splitHostPortParts(addr: string): [string, string] {\n const { host, port } = splitHostPort(addr);\n return [host, port];\n}\n\nfunction getDomainList(host: string): string[] {\n const parts = host.split(\".\");\n const list: string[] = [];\n for (let i = 0; i < parts.length - 1; i++) {\n list.push(parts.slice(i).join(\".\"));\n }\n return list.slice(0, 3);\n}\n\nfunction withSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n signal.addEventListener(\"abort\", () => reject(signal.reason), { once: true }),\n ),\n ]);\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ const e=require("./address-BR-5unVo.cjs");let t=require("node:dns/promises"),n=require("node:net");var r=41144,i=`https://named.myteamspeak.com/lookup`,a=6e5,o=class{#e=new Map;constructor(t=e.o){}async resolve(t,n){if(!t)throw Error(`empty address`);let r=this.#t(t);if(r)return r;let{host:i,port:a}=e.r(t);if(e.t(i))return[{addr:e.n(i,a),source:`Direct`,expiry:new Date(0)}];if(!i.includes(`.`)&&i!==`localhost`){let e=await s(i,n);if(e)return this.resolve(e,n)}let o=await this.#r(i,n);if(o)return this.#n(t,o);let c=u(i),l=await this.#i(c,i,n);if(l)return this.#n(t,[{addr:l,source:`TSDNS-SRV`,expiry:new Date(0)}]);let d=await this.#a(c,i,n);if(d)return this.#n(t,[{addr:d,source:`TSDNS-Direct`,expiry:new Date(0)}]);let f=[{addr:e.n(i,a),source:`Direct`,expiry:new Date(0)}];return this.#n(t,f)}#t(e){let t=this.#e.get(e);if(!t||t.length===0)return null;let n=t[0];return n.expiry.getTime()>0&&Date.now()>n.expiry.getTime()?null:t}#n(e,t){let n=new Date(Date.now()+a),r=t.map(e=>({...e,expiry:n}));return this.#e.set(e,r),r}async#r(n,r){try{let i=await d((0,t.resolveSrv)(`_ts3._udp.${n}`),r);return!i||i.length===0?null:i.map(t=>({addr:e.n(t.name.replace(/\.$/,``),String(t.port)),source:`SRV`,expiry:new Date(0)}))}catch{return null}}async#i(n,r,i){for(let a of n)try{let n=await d((0,t.resolveSrv)(`_tsdns._tcp.${a}`),i);if(!n||n.length===0)continue;for(let t of n){let n=await c(e.n(t.name.replace(/\.$/,``),String(t.port)),r,i);if(n)return n}}catch{continue}return null}async#a(t,n,i){for(let a of t){let t=await c(e.n(a,String(r)),n,i);if(t)return t}return null}};async function s(e,t){try{let n=new URL(i);n.searchParams.set(`name`,e);let r=t?{signal:t}:{},a=await fetch(n.toString(),r);return a.ok&&(await a.text()).split(`
2
+ `)[0]?.trim()||null}catch{return null}}function c(e,t,r){let[i,a]=l(e),o=parseInt(a,10);return new Promise(e=>{let a=setTimeout(()=>{s.destroy(),e(null)},3e3),s=(0,n.createConnection)({host:i,port:o,timeout:2e3},()=>{s.write(`${t}\n`)}),c=``;s.on(`data`,t=>{c+=t.toString();let n=c.indexOf(`
3
+ `);if(n>=0){clearTimeout(a),s.destroy();let t=c.slice(0,n).trim();e(!t||t===`404`||t===`errors`?null:t)}}),s.on(`error`,()=>{clearTimeout(a),e(null)}),r&&r.addEventListener(`abort`,()=>{clearTimeout(a),s.destroy(),e(null)},{once:!0})})}function l(t){let{host:n,port:r}=e.r(t);return[n,r]}function u(e){let t=e.split(`.`),n=[];for(let e=0;e<t.length-1;e++)n.push(t.slice(e).join(`.`));return n.slice(0,3)}function d(e,t){return t?Promise.race([e,new Promise((e,n)=>t.addEventListener(`abort`,()=>n(t.reason),{once:!0}))]):e}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return o}});
4
+ //# sourceMappingURL=resolver-DCcmyWSK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver-DCcmyWSK.cjs","names":["noopLogger","splitHostPort","isIpAddress","joinHostPort","resolveSrv","createConnection","require_address","node_dns_promises","node_net","TS_DNS_DEFAULT_PORT","NICKNAME_LOOKUP_URL","CACHE_TTL_MS","Resolver","inputAddr","cached","#getValidCache","host","port","nickAddr","resolveNickname","signal","srvResults","#resolveSRV","#setCache","domainList","getDomainList","tsdnsSrv","#resolveTSDNSSRV","tsdnsDirect","#resolveTSDNSDirect","fallback","#cache","first","expiry","withExpiry","results","r","key","srvs","withSignal","srv","domain","domains","result","queryTSDNS","queryHost","url","nickname","init","resp","portStr","splitHostPortParts","tsdnsAddr","timeout","socket","resolve","buf","chunk","idx","line","addr","parts","list","i","promise","reject"],"sources":["../src/discovery/resolver.ts"],"sourcesContent":["import { resolveSrv } from \"node:dns/promises\";\nimport { createConnection } from \"node:net\";\nimport type { Logger } from \"../types.js\";\nimport type { ResolvedAddr } from \"../types.js\";\nimport { noopLogger } from \"../types.js\";\nimport { isIpAddress, joinHostPort, splitHostPort } from \"../address.js\";\n\nconst TS_DNS_DEFAULT_PORT = 41144;\nconst NICKNAME_LOOKUP_URL = \"https://named.myteamspeak.com/lookup\";\nconst CACHE_TTL_MS = 10 * 60 * 1000;\n\nexport class Resolver {\n readonly #cache = new Map<string, ResolvedAddr[]>();\n\n constructor(_log: Logger = noopLogger) {}\n\n async resolve(inputAddr: string, signal?: AbortSignal): Promise<ResolvedAddr[]> {\n if (!inputAddr) throw new Error(\"empty address\");\n\n const cached = this.#getValidCache(inputAddr);\n if (cached) return cached;\n\n const { host, port } = splitHostPort(inputAddr);\n\n if (isIpAddress(host)) {\n return [{ addr: joinHostPort(host, port), source: \"Direct\", expiry: new Date(0) }];\n }\n\n // Nickname resolution (no dots → not a domain)\n if (!host.includes(\".\") && host !== \"localhost\") {\n const nickAddr = await resolveNickname(host, signal);\n if (nickAddr) {\n return this.resolve(nickAddr, signal);\n }\n }\n\n // SRV _ts3._udp.<host>\n const srvResults = await this.#resolveSRV(host, signal);\n if (srvResults) return this.#setCache(inputAddr, srvResults);\n\n const domainList = getDomainList(host);\n\n // TSDNS via SRV _tsdns._tcp.<domain>\n const tsdnsSrv = await this.#resolveTSDNSSRV(domainList, host, signal);\n if (tsdnsSrv) {\n return this.#setCache(inputAddr, [\n { addr: tsdnsSrv, source: \"TSDNS-SRV\", expiry: new Date(0) },\n ]);\n }\n\n // TSDNS direct :41144\n const tsdnsDirect = await this.#resolveTSDNSDirect(domainList, host, signal);\n if (tsdnsDirect) {\n return this.#setCache(inputAddr, [\n { addr: tsdnsDirect, source: \"TSDNS-Direct\", expiry: new Date(0) },\n ]);\n }\n\n // Plain DNS fallback\n const fallback: ResolvedAddr[] = [\n { addr: joinHostPort(host, port), source: \"Direct\", expiry: new Date(0) },\n ];\n return this.#setCache(inputAddr, fallback);\n }\n\n #getValidCache(inputAddr: string): ResolvedAddr[] | null {\n const cached = this.#cache.get(inputAddr);\n if (!cached || cached.length === 0) return null;\n const first = cached[0]!;\n if (first.expiry.getTime() > 0 && Date.now() > first.expiry.getTime()) return null;\n return cached;\n }\n\n #setCache(key: string, results: ResolvedAddr[]): ResolvedAddr[] {\n const expiry = new Date(Date.now() + CACHE_TTL_MS);\n const withExpiry = results.map((r) => ({ ...r, expiry }));\n this.#cache.set(key, withExpiry);\n return withExpiry;\n }\n\n async #resolveSRV(host: string, signal?: AbortSignal): Promise<ResolvedAddr[] | null> {\n try {\n const srvs = await withSignal(resolveSrv(`_ts3._udp.${host}`), signal);\n if (!srvs || srvs.length === 0) return null;\n return srvs.map((srv) => ({\n addr: joinHostPort(srv.name.replace(/\\.$/, \"\"), String(srv.port)),\n source: \"SRV\",\n expiry: new Date(0),\n }));\n } catch {\n return null;\n }\n }\n\n async #resolveTSDNSSRV(\n domains: string[],\n queryHost: string,\n signal?: AbortSignal,\n ): Promise<string | null> {\n for (const domain of domains) {\n try {\n const srvs = await withSignal(resolveSrv(`_tsdns._tcp.${domain}`), signal);\n if (!srvs || srvs.length === 0) continue;\n for (const srv of srvs) {\n const tsdnsAddr = joinHostPort(srv.name.replace(/\\.$/, \"\"), String(srv.port));\n const result = await queryTSDNS(tsdnsAddr, queryHost, signal);\n if (result) return result;\n }\n } catch {\n continue;\n }\n }\n return null;\n }\n\n async #resolveTSDNSDirect(\n domains: string[],\n queryHost: string,\n signal?: AbortSignal,\n ): Promise<string | null> {\n for (const domain of domains) {\n const tsdnsAddr = joinHostPort(domain, String(TS_DNS_DEFAULT_PORT));\n const result = await queryTSDNS(tsdnsAddr, queryHost, signal);\n if (result) return result;\n }\n return null;\n }\n}\n\n// ---- Helpers ----------------------------------------------------------------\n\nasync function resolveNickname(nickname: string, signal?: AbortSignal): Promise<string | null> {\n try {\n const url = new URL(NICKNAME_LOOKUP_URL);\n url.searchParams.set(\"name\", nickname);\n const init: RequestInit = signal ? { signal } : {};\n const resp = await fetch(url.toString(), init);\n if (!resp.ok) return null;\n const text = await resp.text();\n const line = text.split(\"\\n\")[0]?.trim();\n return line || null;\n } catch {\n return null;\n }\n}\n\nfunction queryTSDNS(\n tsdnsAddr: string,\n queryHost: string,\n signal?: AbortSignal,\n): Promise<string | null> {\n const [host, portStr] = splitHostPortParts(tsdnsAddr);\n const port = parseInt(portStr, 10);\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n socket.destroy();\n resolve(null);\n }, 3_000);\n\n const socket = createConnection({ host, port, timeout: 2_000 }, () => {\n socket.write(`${queryHost}\\n`);\n });\n\n let buf = \"\";\n socket.on(\"data\", (chunk: Buffer) => {\n buf += chunk.toString();\n const idx = buf.indexOf(\"\\n\");\n if (idx >= 0) {\n clearTimeout(timeout);\n socket.destroy();\n const line = buf.slice(0, idx).trim();\n if (!line || line === \"404\" || line === \"errors\") resolve(null);\n else resolve(line);\n }\n });\n\n socket.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(null);\n });\n\n if (signal) {\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timeout);\n socket.destroy();\n resolve(null);\n },\n { once: true },\n );\n }\n });\n}\n\nfunction splitHostPortParts(addr: string): [string, string] {\n const { host, port } = splitHostPort(addr);\n return [host, port];\n}\n\nfunction getDomainList(host: string): string[] {\n const parts = host.split(\".\");\n const list: string[] = [];\n for (let i = 0; i < parts.length - 1; i++) {\n list.push(parts.slice(i).join(\".\"));\n }\n return list.slice(0, 3);\n}\n\nfunction withSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n signal.addEventListener(\"abort\", () => reject(signal.reason), { once: true }),\n ),\n ]);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,eAAe;;IAC1B,MAAM,CAAC,QAAQ,CAAC,UAAU,KAAO;IACjC,MAAM,CAAC,QAAQ,CAAC,SAAS,KAAO;IAK1B,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAkChD"}
1
+ {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,eAAe;;IAC1B,MAAM,CAAC,QAAQ,CAAC,UAAU,KAAO;IACjC,MAAM,CAAC,QAAQ,CAAC,SAAS,KAAO;IAK1B,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC9C;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAG1E,KAAK,cAAc,GACf,cAAc,GACd,gBAAgB,GAChB,OAAO,YAAY,EAAE,sBAAsB,CAAC;AAEhD,qBAAa,mBAAmB;;IAI9B,QAAQ,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAU7D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAKlD,KAAK,IAAI,IAAI;CAId;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,UAAU,EAAE,MAAM,CAAC,CAmBpC;AAED,sDAAsD;AACtD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,OAAO,GACjB,MAAM,CAWR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CASR;AAED,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,CAAC"}
1
+ {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAG1E,KAAK,cAAc,GACf,cAAc,GACd,gBAAgB,GAChB,OAAO,YAAY,EAAE,sBAAsB,CAAC;AAEhD,qBAAa,mBAAmB;;IAI9B,QAAQ,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAQ5D;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAGjD;IAED,KAAK,IAAI,IAAI,CAGZ;CACF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,UAAU,EAAE,MAAM,CAAC,CAmBpC;AAED,sDAAsD;AACtD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,OAAO,GACjB,MAAM,CAWR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CASR;AAED,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"generation-window.d.ts","sourceRoot":"","sources":["../../src/transport/generation-window.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;;gBAMf,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAK3C,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU7B,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAM5C,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMjC,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAQxC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAO1C,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIzC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAW5C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAK1C,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"generation-window.d.ts","sourceRoot":"","sources":["../../src/transport/generation-window.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;;IAM3B,YAAY,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAG1C;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ5B;IAED,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAI3C;IAED,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAIhC;IAED,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAMvC;IAED,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKzC;IAED,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAExC;IAED,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE3C;IASD,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGzC;IAED,KAAK,IAAI,IAAI,CAGZ;CACF"}
@@ -13,6 +13,8 @@ export declare class PacketHandler {
13
13
  receivedFinalInitAck(): void;
14
14
  sendPacket(pType: PacketType, data: Uint8Array, flags: number): void;
15
15
  sendVoicePacket(data: Uint8Array, codec: number): void;
16
+ /** Send an unencrypted TeamSpeak voice whisper packet to up to 32 clients. */
17
+ sendWhisperPacket(data: Uint8Array, targetClientIds: number[], codec: number): void;
16
18
  close(): void;
17
19
  }
18
20
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/transport/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,KAAK,MAAM,EACX,UAAU,EAMX,MAAM,aAAa,CAAC;AAwBrB,qBAAa,aAAa;;IACxB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC9C,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;gBAyB1C,KAAK,EAAE,KAAK,EAAE,MAAM,GAAE,MAAmB;IAKrD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBpC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAkC5B,oBAAoB,IAAI,IAAI;IAI5B,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IASpE,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA+BtD,KAAK,IAAI,IAAI;CAocd"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/transport/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAGpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,KAAK,MAAM,EACX,UAAU,EAMX,MAAM,aAAa,CAAC;AAyBrB,qBAAa,aAAa;;IACxB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC9C,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAyBtD,YAAY,KAAK,EAAE,KAAK,EAAE,MAAM,GAAE,MAAmB,EAGpD;IAED,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE5B;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBnC;IAED,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAgC3B;IAED,oBAAoB,IAAI,IAAI,CAE3B;IAED,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOnE;IAED,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CA6BrD;IAED,8EAA8E;IAC9E,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAwClF;IAED,KAAK,IAAI,IAAI,CAMZ;CAwcF"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../handler-BJdwhtkp.cjs");exports.GenerationWindow=e.r,exports.PacketFlags=e.i,exports.PacketHandler=e.t,exports.PacketType=e.a,exports.Qlz=e.n,exports.buildC2SHeader=e.o,exports.isUnencrypted=e.s,exports.packetFlags=e.c,exports.packetType=e.l,exports.parseC2SHeader=e.u,exports.parseS2CHeader=e.d;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../handler-DuwoO5RC.cjs");exports.GenerationWindow=e.r,exports.PacketFlags=e.i,exports.PacketHandler=e.t,exports.PacketType=e.a,exports.Qlz=e.n,exports.buildC2SHeader=e.o,exports.isUnencrypted=e.s,exports.packetFlags=e.c,exports.packetType=e.l,exports.parseC2SHeader=e.u,exports.parseS2CHeader=e.d;
@@ -1,2 +1,2 @@
1
- import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "../handler-BP38rMNl.js";
1
+ import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "../handler-DI_abe9c.js";
2
2
  export { s as GenerationWindow, r as PacketFlags, l as PacketHandler, e as PacketType, a as Qlz, o as buildC2SHeader, c as isUnencrypted, t as packetFlags, i as packetType, u as parseC2SHeader, n as parseS2CHeader };
@@ -1 +1 @@
1
- {"version":3,"file":"quicklz.d.ts","sourceRoot":"","sources":["../../src/transport/quicklz.ts"],"names":[],"mappings":"AASA,qBAAa,GAAG;;IAGd,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;CA+HzC"}
1
+ {"version":3,"file":"quicklz.d.ts","sourceRoot":"","sources":["../../src/transport/quicklz.ts"],"names":[],"mappings":"AASA,qBAAa,GAAG;;IAGd,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CA4BvC;CAmGF"}
package/dist/types.d.ts CHANGED
@@ -38,6 +38,8 @@ export interface ChannelInfo {
38
38
  description: string;
39
39
  id: bigint;
40
40
  parentID: bigint;
41
+ /** ID of the sibling channel this one is sorted after; 0 means first. */
42
+ order: bigint;
41
43
  }
42
44
  export interface FileUploadInfo {
43
45
  fileTransferKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAI3E,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;CAClB;AAID,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,mBAAmB,CAAC;IACjC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,KAAK,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,0BAAkB,YAAY;IAC5B,YAAY,IAAI;IAChB,UAAU,IAAI;IACd,SAAS,IAAI;CACd;AAID,MAAM,MAAM,iBAAiB,GAAG,CAC9B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,KACjC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpC,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI,KAC1C,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI,CAAC;AAI7C,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAC9C;AAED,iDAAiD;AACjD,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,aAAa,EAAE,MAK3B,CAAC;AAIF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;CACd;AAID,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACtE;AAID,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACxC,eAAe,CAAC,EAAE,eAAe,EAAE,CAAC;IACpC,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honeybbq/teamspeak-client",
3
- "version": "0.2.3",
3
+ "version": "0.3.1",
4
4
  "description": "TeamSpeak 3 client SDK for Node.js — a clean-room TypeScript port of the Go reference implementation",
5
5
  "keywords": [
6
6
  "client",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "scripts": {
58
- "build": "vite build && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist",
58
+ "build": "vite build && tsc -p tsconfig.build.json --emitDeclarationOnly",
59
59
  "test": "vitest run",
60
60
  "test:watch": "vitest",
61
61
  "lint": "oxlint .",
@@ -71,14 +71,13 @@
71
71
  "@noble/curves": "^2.0.1"
72
72
  },
73
73
  "devDependencies": {
74
- "@types/node": "^25.6.0",
75
- "oxfmt": "^0.58.0",
74
+ "@types/node": "^26.1.1",
75
+ "oxfmt": "^0.71.0",
76
76
  "oxlint": "^1.59.0",
77
77
  "tsx": "^4.21.0",
78
- "typescript": "^6.0.2",
78
+ "typescript": "^7.0.2",
79
79
  "vite": "^8.0.8",
80
- "vite-plugin-dts": "^5.0.0",
81
- "vitest": "^4.1.4"
80
+ "vitest": "^5.0.0"
82
81
  },
83
82
  "engines": {
84
83
  "node": ">=20.19"
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=command.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.test.d.ts","sourceRoot":"","sources":["../../src/command/command.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command-CTDmBXd_.js","names":[],"sources":["../src/command/command.ts"],"sourcesContent":["import type { EscapedString } from \"../types.js\";\n\nconst ESCAPE_MAP: [string, string][] = [\n [\"\\\\\", \"\\\\\\\\\"],\n [\"/\", \"\\\\/\"],\n [\" \", \"\\\\s\"],\n [\"|\", \"\\\\p\"],\n [\"\\x07\", \"\\\\a\"],\n [\"\\x08\", \"\\\\b\"],\n [\"\\x0C\", \"\\\\f\"],\n [\"\\n\", \"\\\\n\"],\n [\"\\r\", \"\\\\r\"],\n [\"\\t\", \"\\\\t\"],\n [\"\\x0B\", \"\\\\v\"],\n];\n\nexport function escape(s: string): EscapedString {\n let result = s;\n for (const [from, to] of ESCAPE_MAP) {\n result = result.split(from).join(to);\n }\n return result as EscapedString;\n}\n\nexport function unescape(s: string): string {\n // Process escape sequences in a single pass to avoid double-substitution\n let result = \"\";\n let i = 0;\n while (i < s.length) {\n if (s[i] === \"\\\\\" && i + 1 < s.length) {\n const next = s[i + 1];\n switch (next) {\n case \"\\\\\":\n result += \"\\\\\";\n i += 2;\n break;\n case \"/\":\n result += \"/\";\n i += 2;\n break;\n case \"s\":\n result += \" \";\n i += 2;\n break;\n case \"p\":\n result += \"|\";\n i += 2;\n break;\n case \"a\":\n result += \"\\x07\";\n i += 2;\n break;\n case \"b\":\n result += \"\\x08\";\n i += 2;\n break;\n case \"f\":\n result += \"\\x0C\";\n i += 2;\n break;\n case \"n\":\n result += \"\\n\";\n i += 2;\n break;\n case \"r\":\n result += \"\\r\";\n i += 2;\n break;\n case \"t\":\n result += \"\\t\";\n i += 2;\n break;\n case \"v\":\n result += \"\\x0B\";\n i += 2;\n break;\n default:\n result += s[i] ?? \"\";\n i++;\n break;\n }\n } else {\n result += s[i] ?? \"\";\n i++;\n }\n }\n return result;\n}\n\nexport interface Command {\n name: string;\n params: Record<string, string>;\n}\n\n/** Build a TS3 command string from an unordered params map. */\nexport function buildCommand(cmd: string, params: Record<string, string>): string {\n const parts: string[] = [escape(cmd)];\n for (const [k, v] of Object.entries(params)) {\n parts.push(`${k}=${escape(v)}`);\n }\n return parts.join(\" \");\n}\n\n/** Build a TS3 command string preserving parameter order. */\nexport function buildCommandOrdered(\n cmd: string,\n params: ReadonlyArray<readonly [string, string]>,\n): string {\n const parts: string[] = [escape(cmd)];\n for (const [k, v] of params) {\n parts.push(`${k}=${escape(v)}`);\n }\n return parts.join(\" \");\n}\n"],"mappings":";AAEA,IAAM,IAAiC;CACrC,CAAC,MAAM,MAAM;CACb,CAAC,KAAK,KAAK;CACX,CAAC,KAAK,KAAK;CACX,CAAC,KAAK,KAAK;CACX,CAAC,QAAQ,KAAK;CACd,CAAC,MAAQ,KAAK;CACd,CAAC,MAAQ,KAAK;CACd,CAAC,MAAM,KAAK;CACZ,CAAC,MAAM,KAAK;CACZ,CAAC,KAAM,KAAK;CACZ,CAAC,MAAQ,KAAK;AAChB;AAEA,SAAgB,EAAO,GAA0B;CAC/C,IAAI,IAAS;CACb,KAAK,IAAM,CAAC,GAAM,MAAO,GACvB,IAAS,EAAO,MAAM,CAAI,CAAC,CAAC,KAAK,CAAE;CAErC,OAAO;AACT;AAEA,SAAgB,EAAS,GAAmB;CAE1C,IAAI,IAAS,IACT,IAAI;CACR,OAAO,IAAI,EAAE,SACX,IAAI,EAAE,OAAO,QAAQ,IAAI,IAAI,EAAE,QAE7B,QADa,EAAE,IAAI,IACnB;EACE,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,KACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,KACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,KACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,QACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,KACV,KAAK;GACL;EACF,KAAK;GAEH,AADA,KAAU,MACV,KAAK;GACL;EACF;GAEE,AADA,KAAU,EAAE,MAAM,IAClB;GACA;CACJ;MAGA,AADA,KAAU,EAAE,MAAM,IAClB;CAGJ,OAAO;AACT;AAQA,SAAgB,EAAa,GAAa,GAAwC;CAChF,IAAM,IAAkB,CAAC,EAAO,CAAG,CAAC;CACpC,KAAK,IAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,CAAM,GACxC,EAAM,KAAK,GAAG,EAAE,GAAG,EAAO,CAAC,GAAG;CAEhC,OAAO,EAAM,KAAK,GAAG;AACvB;AAGA,SAAgB,EACd,GACA,GACQ;CACR,IAAM,IAAkB,CAAC,EAAO,CAAG,CAAC;CACpC,KAAK,IAAM,CAAC,GAAG,MAAM,GACnB,EAAM,KAAK,GAAG,EAAE,GAAG,EAAO,CAAC,GAAG;CAEhC,OAAO,EAAM,KAAK,GAAG;AACvB"}
@@ -1,4 +0,0 @@
1
- var e=[[`\\`,`\\\\`],[`/`,`\\/`],[` `,`\\s`],[`|`,`\\p`],[`\x07`,`\\a`],[`\b`,`\\b`],[`\f`,`\\f`],[`
2
- `,`\\n`],[`\r`,`\\r`],[` `,`\\t`],[`\v`,`\\v`]];function t(t){let n=t;for(let[t,r]of e)n=n.split(t).join(r);return n}function n(e){let t=``,n=0;for(;n<e.length;)if(e[n]===`\\`&&n+1<e.length)switch(e[n+1]){case`\\`:t+=`\\`,n+=2;break;case`/`:t+=`/`,n+=2;break;case`s`:t+=` `,n+=2;break;case`p`:t+=`|`,n+=2;break;case`a`:t+=`\x07`,n+=2;break;case`b`:t+=`\b`,n+=2;break;case`f`:t+=`\f`,n+=2;break;case`n`:t+=`
3
- `,n+=2;break;case`r`:t+=`\r`,n+=2;break;case`t`:t+=` `,n+=2;break;case`v`:t+=`\v`,n+=2;break;default:t+=e[n]??``,n++;break}else t+=e[n]??``,n++;return t}function r(e,n){let r=[t(e)];for(let[e,i]of Object.entries(n))r.push(`${e}=${t(i)}`);return r.join(` `)}function i(e,n){let r=[t(e)];for(let[e,i]of n)r.push(`${e}=${t(i)}`);return r.join(` `)}Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return r}});
4
- //# sourceMappingURL=command-CUPNiKRl.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypt-handshake-D2Rsi2e3.cjs","names":[],"sources":["../src/handshake/crypt-handshake.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { buildCommandOrdered } from \"../command/command.js\";\nimport type { Crypt } from \"../crypto/crypt.js\";\n\nexport const INIT_VERSION = 1566914096; // 3.5.0 [Stable]\n\nconst INIT_VERSION_LEN = 4;\nconst INIT_TYPE_LEN = 1;\nconst INIT_STEP_LEN = 21;\n\n/**\n * Handle the TS3INIT1 handshake steps.\n * Returns the response bytes to send, or null if nothing should be sent.\n */\nexport function processInit1(crypt: Crypt, data: Uint8Array | null): Uint8Array | null {\n if (data === null || (data.length >= 1 && data[0] === 0x7f)) {\n return buildInit1StartPacket();\n }\n\n switch (data[0]) {\n case 0:\n return buildInit1Step1Packet(data);\n case 1:\n return buildInit1Step2Packet(data);\n case 2:\n return buildInit1Step3Packet(data);\n case 3:\n return buildInit1Step4Packet(crypt, data);\n default:\n return null;\n }\n}\n\nfunction buildInit1StartPacket(): Uint8Array {\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 4 + 4 + 8);\n const view = new DataView(sendData.buffer);\n\n view.setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x00;\n\n const nowSec = Math.floor(Date.now() / 1000);\n const clampedNow = Math.max(0, Math.min(nowSec, 0xffff_ffff));\n view.setUint32(5, clampedNow, false);\n\n const rng = randomBytes(4);\n sendData.set(rng, 9);\n\n return sendData;\n}\n\nfunction buildInit1Step1Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_STEP_LEN) return null;\n\n const sendData = new Uint8Array(INIT_TYPE_LEN + 16 + 4);\n sendData[0] = 0x01;\n\n // TS rand: little-endian uint32 at offset [INIT_VERSION_LEN + INIT_TYPE_LEN + 4]\n const tsRandOffset = INIT_VERSION_LEN + INIT_TYPE_LEN + 4;\n const tsRand =\n data[tsRandOffset]! |\n (data[tsRandOffset + 1]! << 8) |\n (data[tsRandOffset + 2]! << 16) |\n (data[tsRandOffset + 3]! << 24);\n\n new DataView(sendData.buffer).setUint32(INIT_TYPE_LEN + 16, tsRand >>> 0, false);\n return sendData;\n}\n\nfunction buildInit1Step2Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_STEP_LEN) return null;\n\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 16 + 4);\n new DataView(sendData.buffer).setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x02;\n sendData.set(data.slice(1, 21), 5);\n return sendData;\n}\n\nfunction buildInit1Step3Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_VERSION_LEN + INIT_TYPE_LEN + 16 + 4) return null;\n\n const sendData = new Uint8Array(INIT_TYPE_LEN + 64 + 64 + 4 + 100);\n sendData[0] = 0x03;\n sendData[INIT_TYPE_LEN + 64 - 1] = 1;\n sendData[INIT_TYPE_LEN + 64 + 64 - 1] = 1;\n new DataView(sendData.buffer).setUint32(INIT_TYPE_LEN + 64 + 64, 1, false);\n return sendData;\n}\n\nfunction buildInit1Step4Packet(crypt: Crypt, data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_TYPE_LEN + 64 + 64 + 4 + 100) return null;\n\n const level = new DataView(data.buffer, data.byteOffset).getUint32(1 + 128, false);\n const y = crypt.solveRsaChallenge(data, 1, level);\n\n crypt.alphaTmp = new Uint8Array(randomBytes(10));\n\n const alphaB64 = Buffer.from(crypt.alphaTmp).toString(\"base64\");\n const omegaB64 = crypt.identity.publicKeyBase64();\n\n const cmd = buildCommandOrdered(\"clientinitiv\", [\n [\"alpha\", alphaB64],\n [\"omega\", omegaB64],\n [\"ot\", \"1\"],\n [\"ip\", \"\"],\n ]);\n const cmdBytes = Buffer.from(cmd);\n\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 232 + 64 + cmdBytes.length);\n const view = new DataView(sendData.buffer);\n view.setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x04;\n sendData.set(data.slice(1, 233), 5);\n sendData.set(y.slice(0, 64), 5 + 232);\n sendData.set(cmdBytes, 5 + 232 + 64);\n\n return sendData;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypt-handshake-DIj51kno.js","names":[],"sources":["../src/handshake/crypt-handshake.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { buildCommandOrdered } from \"../command/command.js\";\nimport type { Crypt } from \"../crypto/crypt.js\";\n\nexport const INIT_VERSION = 1566914096; // 3.5.0 [Stable]\n\nconst INIT_VERSION_LEN = 4;\nconst INIT_TYPE_LEN = 1;\nconst INIT_STEP_LEN = 21;\n\n/**\n * Handle the TS3INIT1 handshake steps.\n * Returns the response bytes to send, or null if nothing should be sent.\n */\nexport function processInit1(crypt: Crypt, data: Uint8Array | null): Uint8Array | null {\n if (data === null || (data.length >= 1 && data[0] === 0x7f)) {\n return buildInit1StartPacket();\n }\n\n switch (data[0]) {\n case 0:\n return buildInit1Step1Packet(data);\n case 1:\n return buildInit1Step2Packet(data);\n case 2:\n return buildInit1Step3Packet(data);\n case 3:\n return buildInit1Step4Packet(crypt, data);\n default:\n return null;\n }\n}\n\nfunction buildInit1StartPacket(): Uint8Array {\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 4 + 4 + 8);\n const view = new DataView(sendData.buffer);\n\n view.setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x00;\n\n const nowSec = Math.floor(Date.now() / 1000);\n const clampedNow = Math.max(0, Math.min(nowSec, 0xffff_ffff));\n view.setUint32(5, clampedNow, false);\n\n const rng = randomBytes(4);\n sendData.set(rng, 9);\n\n return sendData;\n}\n\nfunction buildInit1Step1Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_STEP_LEN) return null;\n\n const sendData = new Uint8Array(INIT_TYPE_LEN + 16 + 4);\n sendData[0] = 0x01;\n\n // TS rand: little-endian uint32 at offset [INIT_VERSION_LEN + INIT_TYPE_LEN + 4]\n const tsRandOffset = INIT_VERSION_LEN + INIT_TYPE_LEN + 4;\n const tsRand =\n data[tsRandOffset]! |\n (data[tsRandOffset + 1]! << 8) |\n (data[tsRandOffset + 2]! << 16) |\n (data[tsRandOffset + 3]! << 24);\n\n new DataView(sendData.buffer).setUint32(INIT_TYPE_LEN + 16, tsRand >>> 0, false);\n return sendData;\n}\n\nfunction buildInit1Step2Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_STEP_LEN) return null;\n\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 16 + 4);\n new DataView(sendData.buffer).setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x02;\n sendData.set(data.slice(1, 21), 5);\n return sendData;\n}\n\nfunction buildInit1Step3Packet(data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_VERSION_LEN + INIT_TYPE_LEN + 16 + 4) return null;\n\n const sendData = new Uint8Array(INIT_TYPE_LEN + 64 + 64 + 4 + 100);\n sendData[0] = 0x03;\n sendData[INIT_TYPE_LEN + 64 - 1] = 1;\n sendData[INIT_TYPE_LEN + 64 + 64 - 1] = 1;\n new DataView(sendData.buffer).setUint32(INIT_TYPE_LEN + 64 + 64, 1, false);\n return sendData;\n}\n\nfunction buildInit1Step4Packet(crypt: Crypt, data: Uint8Array): Uint8Array | null {\n if (data.length !== INIT_TYPE_LEN + 64 + 64 + 4 + 100) return null;\n\n const level = new DataView(data.buffer, data.byteOffset).getUint32(1 + 128, false);\n const y = crypt.solveRsaChallenge(data, 1, level);\n\n crypt.alphaTmp = new Uint8Array(randomBytes(10));\n\n const alphaB64 = Buffer.from(crypt.alphaTmp).toString(\"base64\");\n const omegaB64 = crypt.identity.publicKeyBase64();\n\n const cmd = buildCommandOrdered(\"clientinitiv\", [\n [\"alpha\", alphaB64],\n [\"omega\", omegaB64],\n [\"ot\", \"1\"],\n [\"ip\", \"\"],\n ]);\n const cmdBytes = Buffer.from(cmd);\n\n const sendData = new Uint8Array(INIT_VERSION_LEN + INIT_TYPE_LEN + 232 + 64 + cmdBytes.length);\n const view = new DataView(sendData.buffer);\n view.setUint32(0, INIT_VERSION, false);\n sendData[4] = 0x04;\n sendData.set(data.slice(1, 233), 5);\n sendData.set(y.slice(0, 64), 5 + 232);\n sendData.set(cmdBytes, 5 + 232 + 64);\n\n return sendData;\n}\n"],"mappings":";;;AAIA,IAAa,IAAe,YAItB,IAAgB;AAMtB,SAAgB,EAAa,GAAc,GAA4C;CACrF,IAAI,MAAS,QAAS,EAAK,UAAU,KAAK,EAAK,OAAO,KACpD,OAAO,EAAsB;CAG/B,QAAQ,EAAK,IAAb;EACE,KAAK,GACH,OAAO,EAAsB,CAAI;EACnC,KAAK,GACH,OAAO,EAAsB,CAAI;EACnC,KAAK,GACH,OAAO,EAAsB,CAAI;EACnC,KAAK,GACH,OAAO,EAAsB,GAAO,CAAI;EAC1C,SACE,OAAO;CACX;AACF;AAEA,SAAS,IAAoC;CAC3C,IAAM,oBAAW,IAAI,WAAW,EAA4C,GACtE,IAAO,IAAI,SAAS,EAAS,MAAM;CAGzC,AADA,EAAK,UAAU,GAAG,GAAc,EAAK,GACrC,EAAS,KAAK;CAEd,IAAM,IAAS,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,GACrC,IAAa,KAAK,IAAI,GAAG,KAAK,IAAI,GAAQ,UAAW,CAAC;CAC5D,EAAK,UAAU,GAAG,GAAY,EAAK;CAEnC,IAAM,IAAM,EAAY,CAAC;CAGzB,OAFA,EAAS,IAAI,GAAK,CAAC,GAEZ;AACT;AAEA,SAAS,EAAsB,GAAqC;CAClE,IAAI,EAAK,WAAW,GAAe,OAAO;CAE1C,IAAM,oBAAW,IAAI,WAAW,EAAsB;CACtD,EAAS,KAAK;CAId,IAAM,IACJ,EAAK,KACJ,EAAK,OAAsB,IAC3B,EAAK,OAAsB,KAC3B,EAAK,OAAsB;CAG9B,OADA,IAAI,SAAS,EAAS,MAAM,CAAC,CAAC,UAAU,IAAoB,MAAW,GAAG,EAAK,GACxE;AACT;AAEA,SAAS,EAAsB,GAAqC;CAClE,IAAI,EAAK,WAAW,GAAe,OAAO;CAE1C,IAAM,oBAAW,IAAI,WAAW,EAAyC;CAIzE,OAHA,IAAI,SAAS,EAAS,MAAM,CAAC,CAAC,UAAU,GAAG,GAAc,EAAK,GAC9D,EAAS,KAAK,GACd,EAAS,IAAI,EAAK,MAAM,GAAG,EAAE,GAAG,CAAC,GAC1B;AACT;AAEA,SAAS,EAAsB,GAAqC;CAClE,IAAI,EAAK,WAAW,IAA2C,OAAO;CAEtE,IAAM,oBAAW,IAAI,WAAW,GAAiC;CAKjE,OAJA,EAAS,KAAK,GACd,EAAS,MAA0B,GACnC,EAAS,OAA+B,GACxC,IAAI,SAAS,EAAS,MAAM,CAAC,CAAC,UAAU,KAAyB,GAAG,EAAK,GAClE;AACT;AAEA,SAAS,EAAsB,GAAc,GAAqC;CAChF,IAAI,EAAK,WAAW,KAAmC,OAAO;CAE9D,IAAM,IAAQ,IAAI,SAAS,EAAK,QAAQ,EAAK,UAAU,CAAC,CAAC,UAAU,KAAS,EAAK,GAC3E,IAAI,EAAM,kBAAkB,GAAM,GAAG,CAAK;CAEhD,EAAM,WAAW,IAAI,WAAW,EAAY,EAAE,CAAC;CAE/C,IAAM,IAAW,OAAO,KAAK,EAAM,QAAQ,CAAC,CAAC,SAAS,QAAQ,GACxD,IAAW,EAAM,SAAS,gBAAgB,GAE1C,IAAM,EAAoB,gBAAgB;EAC9C,CAAC,SAAS,CAAQ;EAClB,CAAC,SAAS,CAAQ;EAClB,CAAC,MAAM,GAAG;EACV,CAAC,MAAM,EAAE;CACX,CAAC,GACK,IAAW,OAAO,KAAK,CAAG,GAE1B,IAAW,IAAI,WAAW,MAA8C,EAAS,MAAM;CAQ7F,OANA,IADiB,SAAS,EAAS,MACnC,CAAA,CAAK,UAAU,GAAG,GAAc,EAAK,GACrC,EAAS,KAAK,GACd,EAAS,IAAI,EAAK,MAAM,GAAG,GAAG,GAAG,CAAC,GAClC,EAAS,IAAI,EAAE,MAAM,GAAG,EAAE,GAAG,GAAO,GACpC,EAAS,IAAI,GAAU,GAAY,GAE5B;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypt-init2-C2X9oK4i.js","names":[],"sources":["../src/handshake/license.ts","../src/handshake/crypt-init2.ts"],"sourcesContent":["import { hash512 } from \"../crypto/identity.js\";\nimport { clampScalar, scalarMultFull, bytesToBigIntLE } from \"../crypto/primitives.js\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\n\n// The root key is a 33-byte Ed25519 point\nconst LICENSE_ROOT_KEY = new Uint8Array([\n 0xcd, 0x0d, 0xe2, 0xae, 0xd4, 0x63, 0x45, 0x50, 0x9a, 0x7e, 0x3c, 0xfd, 0x8f, 0x68, 0xb3, 0xdc,\n 0x75, 0x55, 0xb2, 0x9d, 0xcc, 0xec, 0x73, 0xcd, 0x18, 0x75, 0x0f, 0x99, 0x38, 0x12, 0x40, 0x8a,\n]);\n\nconst enum LicenseBlockType {\n Intermediate = 0,\n Server = 2,\n Ts5Server = 8,\n Ephemeral = 32,\n}\n\ninterface LicenseBlock {\n readonly key: Uint8Array; // 32-byte Ed25519 point\n readonly hash: Uint8Array; // SHA-512 truncated to 32 bytes\n properties: Uint8Array[];\n issuer: string;\n notValidBefore: Date;\n notValidAfter: Date;\n blockType: LicenseBlockType;\n serverType: number;\n}\n\nexport class LicenseChain {\n readonly blocks: LicenseBlock[];\n\n constructor(blocks: LicenseBlock[]) {\n this.blocks = blocks;\n }\n\n /**\n * Derive the session key by chaining Ed25519 point arithmetic starting from\n * the root key through each license block.\n */\n deriveKey(): Uint8Array<ArrayBuffer> {\n let round: Uint8Array<ArrayBuffer> = Uint8Array.from(LICENSE_ROOT_KEY);\n for (const block of this.blocks) {\n round = deriveKeyFromBlock(block, round);\n }\n return round;\n }\n}\n\nexport function parseLicenses(data: Uint8Array): LicenseChain {\n if (data.length < 1) throw new Error(\"license too short\");\n if (data[0] !== 1) throw new Error(\"unsupported license version\");\n\n let remaining = data.slice(1);\n const blocks: LicenseBlock[] = [];\n\n while (remaining.length > 0) {\n const { block, consumed } = parseLicenseBlock(remaining);\n blocks.push(block);\n remaining = remaining.slice(consumed);\n }\n\n return new LicenseChain(blocks);\n}\n\nfunction parseLicenseBlock(data: Uint8Array): { block: LicenseBlock; consumed: number } {\n const MIN_BLOCK_LEN = 42;\n if (data.length < MIN_BLOCK_LEN) throw new Error(\"license too short\");\n if (data[0] !== 0) throw new Error(`wrong key kind in license: ${data[0]}`);\n\n const blockType = data[33] as LicenseBlockType;\n\n // Timestamps are seconds since Unix epoch offset by 0x50e22700\n const UNIX_OFFSET = 0x50e22700;\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const notValidBefore = new Date((view.getUint32(34, false) + UNIX_OFFSET) * 1000);\n const notValidAfter = new Date((view.getUint32(38, false) + UNIX_OFFSET) * 1000);\n\n if (notValidAfter < notValidBefore) {\n throw new Error(\"license times are invalid\");\n }\n\n const key = Uint8Array.from(data.slice(1, 33));\n\n const { payload, payloadRead } = parseBlockPayload(blockType, data, MIN_BLOCK_LEN);\n\n const allLen = MIN_BLOCK_LEN + payloadRead;\n const hashInput = data.slice(1, allLen);\n const hashFull = hash512(Uint8Array.from(hashInput));\n const hash = Uint8Array.from(hashFull.slice(0, 32));\n\n return {\n block: {\n key,\n hash,\n properties: payload.properties,\n issuer: payload.issuer,\n notValidBefore,\n notValidAfter,\n blockType,\n serverType: payload.serverType,\n },\n consumed: allLen,\n };\n}\n\ninterface BlockPayload {\n issuer: string;\n serverType: number;\n properties: Uint8Array[];\n read: number;\n}\n\nfunction parseBlockPayload(\n blockType: LicenseBlockType,\n data: Uint8Array,\n minBlockLen: number,\n): { payload: BlockPayload; payloadRead: number } {\n switch (blockType) {\n case LicenseBlockType.Intermediate: {\n const { str, read } = readNullString(data.slice(46));\n return {\n payload: { issuer: str, serverType: 0, properties: [], read: 5 + read },\n payloadRead: 5 + read,\n };\n }\n case LicenseBlockType.Server: {\n const { str, read } = readNullString(data.slice(47));\n return {\n payload: { issuer: str, serverType: data[42] ?? 0, properties: [], read: 6 + read },\n payloadRead: 6 + read,\n };\n }\n case LicenseBlockType.Ts5Server: {\n const propCount = data[43] !== undefined ? data[43] : 0;\n let pos = 44;\n const properties: Uint8Array[] = [];\n for (let i = 0; i < propCount; i++) {\n if (pos >= data.length) throw new Error(\"license too short\");\n const propLen = data[pos++]!;\n if (pos + propLen > data.length) throw new Error(\"license too short\");\n properties.push(Uint8Array.from(data.slice(pos, pos + propLen)));\n pos += propLen;\n }\n return {\n payload: { issuer: \"\", serverType: data[42] ?? 0, properties, read: pos - minBlockLen },\n payloadRead: pos - minBlockLen,\n };\n }\n case LicenseBlockType.Ephemeral:\n return { payload: { issuer: \"\", serverType: 0, properties: [], read: 0 }, payloadRead: 0 };\n default:\n throw new Error(`invalid license block type: ${blockType}`);\n }\n}\n\n/**\n * Scan for a null-terminated string and return its content and the index\n * of the null byte (NOT including it in the count, matching Go behaviour).\n * The parent formulas (`5 + read`, `6 + read`) already add 1 for the null.\n */\nfunction readNullString(data: Uint8Array): { str: string; read: number } {\n for (let i = 0; i < data.length; i++) {\n if (data[i] === 0) {\n return { str: new TextDecoder().decode(data.slice(0, i)), read: i };\n }\n }\n throw new Error(\"non-null-terminated issuer string\");\n}\n\n/**\n * Derive the next key given a parent key and a license block.\n * Mirrors Go's licenseBlock.deriveKey.\n */\nfunction deriveKeyFromBlock(block: LicenseBlock, parent: Uint8Array): Uint8Array<ArrayBuffer> {\n const scalarBytes = Uint8Array.from(block.hash);\n clampScalar(scalarBytes);\n\n // Use raw scalar WITHOUT reducing mod n — NaCl's ge_scalarmult_vartime\n // uses the raw 256-bit scalar. Reducing mod n changes the result when\n // the point has a small-order component (Ed25519 cofactor = 8).\n const scalar = bytesToBigIntLE(scalarBytes);\n\n const pub = ed25519.Point.fromBytes(block.key);\n const negPub = pub.negate();\n\n const par = ed25519.Point.fromBytes(parent);\n const negPar = par.negate();\n\n const res = scalarMultFull(negPub, scalar).add(negPar);\n const raw = res.toBytes();\n const final = new Uint8Array(raw.length) as Uint8Array<ArrayBuffer>;\n final.set(raw);\n final[31] = (final[31] !== undefined ? final[31] : 0) ^ 0x80;\n\n return final;\n}\n","import type { Crypt } from \"../crypto/crypt.js\";\nimport { importPublicKey } from \"../crypto/identity.js\";\nimport { verifySign, getSharedSecret2 } from \"../crypto/primitives.js\";\nimport { parseLicenses } from \"./license.js\";\n\n/**\n * CryptoInit2 performs the second stage of crypto initialization (Ed25519 ECDH).\n * Mirrors Go's handshake.CryptoInit2.\n */\nexport function cryptoInit2(\n crypt: Crypt,\n license: string,\n omega: string,\n proof: string,\n beta: string,\n privateKey: Uint8Array,\n): void {\n if (crypt.alphaTmp.length === 0) {\n throw new Error(\"alpha is not initialized\");\n }\n\n const licenseBytes = Buffer.from(license, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n const proofBytes = Buffer.from(proof, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n if (!verifySign(serverPubKey, licenseBytes, proofBytes)) {\n throw new Error(\"init proof is not valid\");\n }\n\n const licenses = parseLicenses(licenseBytes);\n const key = licenses.deriveKey();\n\n const sharedSecret = getSharedSecret2(key, privateKey);\n\n crypt.setSharedSecret(crypt.alphaTmp, betaBytes, sharedSecret);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypt-init2-CazdFwqF.cjs","names":[],"sources":["../src/handshake/license.ts","../src/handshake/crypt-init2.ts"],"sourcesContent":["import { hash512 } from \"../crypto/identity.js\";\nimport { clampScalar, scalarMultFull, bytesToBigIntLE } from \"../crypto/primitives.js\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\n\n// The root key is a 33-byte Ed25519 point\nconst LICENSE_ROOT_KEY = new Uint8Array([\n 0xcd, 0x0d, 0xe2, 0xae, 0xd4, 0x63, 0x45, 0x50, 0x9a, 0x7e, 0x3c, 0xfd, 0x8f, 0x68, 0xb3, 0xdc,\n 0x75, 0x55, 0xb2, 0x9d, 0xcc, 0xec, 0x73, 0xcd, 0x18, 0x75, 0x0f, 0x99, 0x38, 0x12, 0x40, 0x8a,\n]);\n\nconst enum LicenseBlockType {\n Intermediate = 0,\n Server = 2,\n Ts5Server = 8,\n Ephemeral = 32,\n}\n\ninterface LicenseBlock {\n readonly key: Uint8Array; // 32-byte Ed25519 point\n readonly hash: Uint8Array; // SHA-512 truncated to 32 bytes\n properties: Uint8Array[];\n issuer: string;\n notValidBefore: Date;\n notValidAfter: Date;\n blockType: LicenseBlockType;\n serverType: number;\n}\n\nexport class LicenseChain {\n readonly blocks: LicenseBlock[];\n\n constructor(blocks: LicenseBlock[]) {\n this.blocks = blocks;\n }\n\n /**\n * Derive the session key by chaining Ed25519 point arithmetic starting from\n * the root key through each license block.\n */\n deriveKey(): Uint8Array<ArrayBuffer> {\n let round: Uint8Array<ArrayBuffer> = Uint8Array.from(LICENSE_ROOT_KEY);\n for (const block of this.blocks) {\n round = deriveKeyFromBlock(block, round);\n }\n return round;\n }\n}\n\nexport function parseLicenses(data: Uint8Array): LicenseChain {\n if (data.length < 1) throw new Error(\"license too short\");\n if (data[0] !== 1) throw new Error(\"unsupported license version\");\n\n let remaining = data.slice(1);\n const blocks: LicenseBlock[] = [];\n\n while (remaining.length > 0) {\n const { block, consumed } = parseLicenseBlock(remaining);\n blocks.push(block);\n remaining = remaining.slice(consumed);\n }\n\n return new LicenseChain(blocks);\n}\n\nfunction parseLicenseBlock(data: Uint8Array): { block: LicenseBlock; consumed: number } {\n const MIN_BLOCK_LEN = 42;\n if (data.length < MIN_BLOCK_LEN) throw new Error(\"license too short\");\n if (data[0] !== 0) throw new Error(`wrong key kind in license: ${data[0]}`);\n\n const blockType = data[33] as LicenseBlockType;\n\n // Timestamps are seconds since Unix epoch offset by 0x50e22700\n const UNIX_OFFSET = 0x50e22700;\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const notValidBefore = new Date((view.getUint32(34, false) + UNIX_OFFSET) * 1000);\n const notValidAfter = new Date((view.getUint32(38, false) + UNIX_OFFSET) * 1000);\n\n if (notValidAfter < notValidBefore) {\n throw new Error(\"license times are invalid\");\n }\n\n const key = Uint8Array.from(data.slice(1, 33));\n\n const { payload, payloadRead } = parseBlockPayload(blockType, data, MIN_BLOCK_LEN);\n\n const allLen = MIN_BLOCK_LEN + payloadRead;\n const hashInput = data.slice(1, allLen);\n const hashFull = hash512(Uint8Array.from(hashInput));\n const hash = Uint8Array.from(hashFull.slice(0, 32));\n\n return {\n block: {\n key,\n hash,\n properties: payload.properties,\n issuer: payload.issuer,\n notValidBefore,\n notValidAfter,\n blockType,\n serverType: payload.serverType,\n },\n consumed: allLen,\n };\n}\n\ninterface BlockPayload {\n issuer: string;\n serverType: number;\n properties: Uint8Array[];\n read: number;\n}\n\nfunction parseBlockPayload(\n blockType: LicenseBlockType,\n data: Uint8Array,\n minBlockLen: number,\n): { payload: BlockPayload; payloadRead: number } {\n switch (blockType) {\n case LicenseBlockType.Intermediate: {\n const { str, read } = readNullString(data.slice(46));\n return {\n payload: { issuer: str, serverType: 0, properties: [], read: 5 + read },\n payloadRead: 5 + read,\n };\n }\n case LicenseBlockType.Server: {\n const { str, read } = readNullString(data.slice(47));\n return {\n payload: { issuer: str, serverType: data[42] ?? 0, properties: [], read: 6 + read },\n payloadRead: 6 + read,\n };\n }\n case LicenseBlockType.Ts5Server: {\n const propCount = data[43] !== undefined ? data[43] : 0;\n let pos = 44;\n const properties: Uint8Array[] = [];\n for (let i = 0; i < propCount; i++) {\n if (pos >= data.length) throw new Error(\"license too short\");\n const propLen = data[pos++]!;\n if (pos + propLen > data.length) throw new Error(\"license too short\");\n properties.push(Uint8Array.from(data.slice(pos, pos + propLen)));\n pos += propLen;\n }\n return {\n payload: { issuer: \"\", serverType: data[42] ?? 0, properties, read: pos - minBlockLen },\n payloadRead: pos - minBlockLen,\n };\n }\n case LicenseBlockType.Ephemeral:\n return { payload: { issuer: \"\", serverType: 0, properties: [], read: 0 }, payloadRead: 0 };\n default:\n throw new Error(`invalid license block type: ${blockType}`);\n }\n}\n\n/**\n * Scan for a null-terminated string and return its content and the index\n * of the null byte (NOT including it in the count, matching Go behaviour).\n * The parent formulas (`5 + read`, `6 + read`) already add 1 for the null.\n */\nfunction readNullString(data: Uint8Array): { str: string; read: number } {\n for (let i = 0; i < data.length; i++) {\n if (data[i] === 0) {\n return { str: new TextDecoder().decode(data.slice(0, i)), read: i };\n }\n }\n throw new Error(\"non-null-terminated issuer string\");\n}\n\n/**\n * Derive the next key given a parent key and a license block.\n * Mirrors Go's licenseBlock.deriveKey.\n */\nfunction deriveKeyFromBlock(block: LicenseBlock, parent: Uint8Array): Uint8Array<ArrayBuffer> {\n const scalarBytes = Uint8Array.from(block.hash);\n clampScalar(scalarBytes);\n\n // Use raw scalar WITHOUT reducing mod n — NaCl's ge_scalarmult_vartime\n // uses the raw 256-bit scalar. Reducing mod n changes the result when\n // the point has a small-order component (Ed25519 cofactor = 8).\n const scalar = bytesToBigIntLE(scalarBytes);\n\n const pub = ed25519.Point.fromBytes(block.key);\n const negPub = pub.negate();\n\n const par = ed25519.Point.fromBytes(parent);\n const negPar = par.negate();\n\n const res = scalarMultFull(negPub, scalar).add(negPar);\n const raw = res.toBytes();\n const final = new Uint8Array(raw.length) as Uint8Array<ArrayBuffer>;\n final.set(raw);\n final[31] = (final[31] !== undefined ? final[31] : 0) ^ 0x80;\n\n return final;\n}\n","import type { Crypt } from \"../crypto/crypt.js\";\nimport { importPublicKey } from \"../crypto/identity.js\";\nimport { verifySign, getSharedSecret2 } from \"../crypto/primitives.js\";\nimport { parseLicenses } from \"./license.js\";\n\n/**\n * CryptoInit2 performs the second stage of crypto initialization (Ed25519 ECDH).\n * Mirrors Go's handshake.CryptoInit2.\n */\nexport function cryptoInit2(\n crypt: Crypt,\n license: string,\n omega: string,\n proof: string,\n beta: string,\n privateKey: Uint8Array,\n): void {\n if (crypt.alphaTmp.length === 0) {\n throw new Error(\"alpha is not initialized\");\n }\n\n const licenseBytes = Buffer.from(license, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n const proofBytes = Buffer.from(proof, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n if (!verifySign(serverPubKey, licenseBytes, proofBytes)) {\n throw new Error(\"init proof is not valid\");\n }\n\n const licenses = parseLicenses(licenseBytes);\n const key = licenses.deriveKey();\n\n const sharedSecret = getSharedSecret2(key, privateKey);\n\n crypt.setSharedSecret(crypt.alphaTmp, betaBytes, sharedSecret);\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=eax.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eax.test.d.ts","sourceRoot":"","sources":["../../src/crypto/eax.test.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=identity.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../../src/crypto/identity.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto-CwIMggQG.js","names":["#key","#cmac","#cachedKeys","#getSharedSecret"],"sources":["../src/crypto/eax.ts","../src/crypto/crypt.ts"],"sourcesContent":["import { createCipheriv, timingSafeEqual } from \"node:crypto\";\nimport { EAXTagMismatchError } from \"../errors.js\";\n\nconst EAX_TAG_SIZE = 8;\nconst EAX_BLOCK_SIZE = 16;\n\n/**\n * AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).\n * Uses AES-CMAC for authentication and AES-CTR for encryption.\n */\nexport class EAX {\n readonly #key: Uint8Array;\n\n constructor(key: Uint8Array) {\n if (key.length !== 16) throw new Error(\"EAX requires a 16-byte key\");\n this.#key = key;\n }\n\n encrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n plaintext: Uint8Array,\n ): [ciphertext: Uint8Array, tag: Uint8Array] {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n\n const ciphertext = aesCtr(this.#key, nStar, plaintext);\n\n const cStar = this.#cmac(2, ciphertext);\n\n const tag = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n tag[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n return [ciphertext, tag];\n }\n\n decrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n ): Uint8Array {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n const cStar = this.#cmac(2, ciphertext);\n\n const expected = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n expected[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n if (!timingSafeEqual(Buffer.from(expected), Buffer.from(tag.slice(0, EAX_TAG_SIZE)))) {\n throw new EAXTagMismatchError();\n }\n\n return aesCtr(this.#key, nStar, ciphertext);\n }\n\n /**\n * AES-CMAC per RFC 4493:\n * input = [0…0 tag] ++ data (one block prefix)\n */\n #cmac(tagByte: number, data: Uint8Array): Uint8Array {\n const input = new Uint8Array(EAX_BLOCK_SIZE + data.length);\n // first block: zeros then tag byte at the last position\n input[EAX_BLOCK_SIZE - 1] = tagByte;\n input.set(data, EAX_BLOCK_SIZE);\n\n return aesCmac(this.#key, input);\n }\n}\n\n// ---- AES-CTR ----------------------------------------------------------------\n\nfunction aesCtr(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array {\n const cipher = createCipheriv(\"aes-128-ctr\", Buffer.from(key), Buffer.from(iv));\n return Buffer.concat([cipher.update(Buffer.from(data)), cipher.final()]);\n}\n\n// ---- AES-CMAC (RFC 4493) ----------------------------------------------------\n\nfunction aesEcb(key: Uint8Array, block: Uint8Array): Uint8Array {\n // Node.js does not expose ECB directly; simulate via CTR with zero IV and\n // a zero-input (CTR of 0-block XOR with input = ECB)\n const cipher = createCipheriv(\"aes-128-ecb\", Buffer.from(key), null);\n cipher.setAutoPadding(false);\n return Buffer.concat([cipher.update(Buffer.from(block)), cipher.final()]);\n}\n\nfunction xorBlock(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n for (let i = 0; i < EAX_BLOCK_SIZE; i++) out[i] = a[i]! ^ b[i]!;\n return out;\n}\n\nfunction shiftLeft1(b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n let carry = 0;\n for (let i = EAX_BLOCK_SIZE - 1; i >= 0; i--) {\n const shifted = ((b[i]! << 1) | carry) & 0xff;\n carry = b[i]! >> 7;\n out[i] = shifted;\n }\n return out;\n}\n\nconst RB = new Uint8Array(EAX_BLOCK_SIZE);\nRB[EAX_BLOCK_SIZE - 1] = 0x87;\n\nfunction generateSubkeys(key: Uint8Array): [Uint8Array, Uint8Array] {\n const zero = new Uint8Array(EAX_BLOCK_SIZE);\n const L = aesEcb(key, zero);\n\n let K1 = shiftLeft1(L);\n if ((L[0]! & 0x80) !== 0) K1 = xorBlock(K1, RB);\n\n let K2 = shiftLeft1(K1);\n if ((K1[0]! & 0x80) !== 0) K2 = xorBlock(K2, RB);\n\n return [K1, K2];\n}\n\nexport function aesCmac(key: Uint8Array, message: Uint8Array): Uint8Array {\n const [K1, K2] = generateSubkeys(key);\n\n const n = Math.max(1, Math.ceil(message.length / EAX_BLOCK_SIZE));\n const lastBlockComplete = message.length > 0 && message.length % EAX_BLOCK_SIZE === 0;\n\n let X: Uint8Array = new Uint8Array(EAX_BLOCK_SIZE);\n\n for (let i = 0; i < n - 1; i++) {\n const block = message.slice(i * EAX_BLOCK_SIZE, (i + 1) * EAX_BLOCK_SIZE);\n X = Uint8Array.from(aesEcb(key, xorBlock(X, block)));\n }\n\n const lastBlock = new Uint8Array(EAX_BLOCK_SIZE);\n const lastStart = (n - 1) * EAX_BLOCK_SIZE;\n const lastSlice = message.slice(lastStart);\n lastBlock.set(lastSlice);\n\n let Mn: Uint8Array;\n if (lastBlockComplete) {\n Mn = xorBlock(lastBlock, K1);\n } else {\n if (lastSlice.length < EAX_BLOCK_SIZE) lastBlock[lastSlice.length] = 0x80;\n Mn = xorBlock(lastBlock, K2);\n }\n\n return Uint8Array.from(aesEcb(key, xorBlock(X, Mn)));\n}\n","import { createHash, createECDH } from \"node:crypto\";\nimport { FakeSignatureMismatchError } from \"../errors.js\";\nimport type { Identity } from \"./identity.js\";\nimport { importPublicKey } from \"./identity.js\";\nimport { EAX } from \"./eax.js\";\n\nconst FAKE_SIGNATURE_SIZE = 8;\nconst IV_ALPHA_SIZE = 10;\nconst INIT1_PACKET_TYPE = 8;\nconst PACKET_TYPE_MASK = 0x0f;\n\nconst INIT1_MAC = Buffer.from(\"TS3INIT1\");\n\nexport interface KeyNonce {\n key: Uint8Array;\n nonce: Uint8Array;\n gen: number;\n}\n\n/** Precomputed dummy key/nonce matching the TS3 client pre-crypto placeholder. */\nconst DUMMY_KEY = Buffer.from(\"c:\\\\windows\\\\syste\");\nconst DUMMY_NONCE = Buffer.from(\"m\\\\firewall32.cpl\");\n\nexport class Crypt {\n readonly identity: Identity;\n\n ivStruct: Uint8Array = new Uint8Array(0);\n fakeSignature: Uint8Array = new Uint8Array(FAKE_SIGNATURE_SIZE);\n alphaTmp: Uint8Array = new Uint8Array(0);\n cryptoInitComplete = false;\n\n readonly #cachedKeys = new Map<bigint, KeyNonce>();\n\n constructor(identity: Identity) {\n this.identity = identity;\n }\n\n solveRsaChallenge(data: Uint8Array, offset: number, level: number): Uint8Array {\n if (level < 0 || level > 1_000_000) {\n throw new Error(\"RSA challenge level out of range\");\n }\n\n const xBytes = data.slice(offset, offset + 64);\n const nBytes = data.slice(offset + 64, offset + 128);\n\n let y = bytesToBigInt(xBytes);\n const n = bytesToBigInt(nBytes);\n\n for (let i = 0; i < level; i++) {\n y = (y * y) % n;\n }\n\n return bigIntToBytes(y, 64);\n }\n\n initCrypto(alpha: string, beta: string, omega: string): void {\n const alphaBytes = Buffer.from(alpha, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n const sharedSecret = this.#getSharedSecret(serverPubKey);\n\n this.setSharedSecret(alphaBytes, betaBytes, sharedSecret);\n }\n\n setSharedSecret(alpha: Uint8Array, beta: Uint8Array, sharedKey: Uint8Array): void {\n this.ivStruct = new Uint8Array(IV_ALPHA_SIZE + beta.length);\n for (let i = 0; i < IV_ALPHA_SIZE; i++) {\n const a = sharedKey[i];\n const b = alpha[i];\n this.ivStruct[i] = ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n for (let i = 0; i < beta.length; i++) {\n const a = sharedKey[IV_ALPHA_SIZE + i];\n const b = beta[i];\n this.ivStruct[IV_ALPHA_SIZE + i] =\n ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n\n const digest = createHash(\"sha1\").update(this.ivStruct).digest();\n this.fakeSignature = new Uint8Array(digest.buffer, digest.byteOffset, FAKE_SIGNATURE_SIZE);\n this.cryptoInitComplete = true;\n }\n\n getKeyNonce(\n fromServer: boolean,\n packetID: number,\n generationID: number,\n packetType: number,\n dummy: boolean,\n ): [key: Uint8Array, nonce: Uint8Array] {\n if (dummy) {\n return [Uint8Array.from(DUMMY_KEY), Uint8Array.from(DUMMY_NONCE)];\n }\n\n const cacheKey = makeCacheKey(fromServer, packetType, generationID);\n let kn = this.#cachedKeys.get(cacheKey);\n\n if (kn === undefined) {\n const tmpToHash = new Uint8Array(6 + this.ivStruct.length);\n tmpToHash[0] = fromServer ? 0x30 : 0x31;\n tmpToHash[1] = packetType & PACKET_TYPE_MASK;\n new DataView(tmpToHash.buffer).setUint32(2, generationID, false);\n tmpToHash.set(this.ivStruct, 6);\n\n const hash = createHash(\"sha256\").update(tmpToHash).digest();\n kn = {\n key: Uint8Array.from(hash.slice(0, 16)),\n nonce: Uint8Array.from(hash.slice(16, 32)),\n gen: generationID,\n };\n this.#cachedKeys.set(cacheKey, kn);\n }\n\n const key = Uint8Array.from(kn.key);\n key[0] = (key[0] !== undefined ? key[0] : 0) ^ ((packetID >> 8) & 0xff);\n key[1] = (key[1] !== undefined ? key[1] : 0) ^ (packetID & 0xff);\n\n return [key, kn.nonce];\n }\n\n encrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n plaintext: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): [ciphertext: Uint8Array, mac: Uint8Array] {\n if (packetType === INIT1_PACKET_TYPE) {\n return [plaintext, INIT1_MAC];\n }\n if (unencrypted) {\n return [plaintext, this.fakeSignature];\n }\n\n const [key, nonce] = this.getKeyNonce(false, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.encrypt(nonce, header, plaintext);\n }\n\n decrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): Uint8Array {\n if (packetType === INIT1_PACKET_TYPE) {\n return ciphertext;\n }\n if (unencrypted) {\n const fsSub = tag.slice(0, FAKE_SIGNATURE_SIZE);\n if (!Buffer.from(fsSub).equals(Buffer.from(this.fakeSignature))) {\n throw new FakeSignatureMismatchError();\n }\n return ciphertext;\n }\n\n const [key, nonce] = this.getKeyNonce(true, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.decrypt(nonce, header, ciphertext, tag);\n }\n\n #getSharedSecret(serverPubKey: import(\"node:crypto\").KeyObject): Uint8Array {\n const privJwk = this.identity.privateKey.export({ format: \"jwk\" }) as {\n d: string;\n };\n const pubJwk = serverPubKey.export({ format: \"jwk\" }) as {\n x: string;\n y: string;\n };\n\n const ecdh = createECDH(\"prime256v1\");\n const dBytes = Buffer.from(privJwk.d, \"base64url\");\n ecdh.setPrivateKey(dBytes);\n\n const xBytes = base64UrlToBytes(pubJwk.x, 32);\n const yBytes = base64UrlToBytes(pubJwk.y, 32);\n const uncompressed = Buffer.alloc(65);\n uncompressed[0] = 0x04;\n xBytes.copy(uncompressed, 1);\n yBytes.copy(uncompressed, 33);\n\n const rawSecret = ecdh.computeSecret(uncompressed);\n return createHash(\"sha1\").update(rawSecret).digest();\n }\n}\n\n// ---- Helpers ----------------------------------------------------------------\n\nfunction makeCacheKey(fromServer: boolean, packetType: number, generationID: number): bigint {\n let key = 0n;\n if (fromServer) key |= 1n << 40n;\n key |= BigInt(packetType & PACKET_TYPE_MASK) << 32n;\n key |= BigInt(generationID);\n return key;\n}\n\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let result = 0n;\n for (const b of bytes) result = (result << 8n) | BigInt(b);\n return result;\n}\n\nfunction bigIntToBytes(value: bigint, size: number): Uint8Array {\n const result = new Uint8Array(size);\n let v = value;\n for (let i = size - 1; i >= 0; i--) {\n result[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return result;\n}\n\nfunction base64UrlToBytes(b64url: string, size: number): Buffer {\n const buf = Buffer.from(b64url, \"base64url\");\n if (buf.length === size) return buf;\n const padded = Buffer.alloc(size);\n buf.copy(padded, size - buf.length);\n return padded;\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- const e=require("./primitives-ClIhDdNZ.cjs");let t=require("node:crypto");var n=8,r=16,i=class{#e;constructor(e){if(e.length!==16)throw Error(`EAX requires a 16-byte key`);this.#e=e}encrypt(e,t,r){let i=this.#t(0,e),o=this.#t(1,t),s=a(this.#e,i,r),c=this.#t(2,s),l=new Uint8Array(n);for(let e=0;e<n;e++)l[e]=i[e]^o[e]^c[e];return[s,l]}decrypt(r,i,o,s){let c=this.#t(0,r),l=this.#t(1,i),u=this.#t(2,o),d=new Uint8Array(n);for(let e=0;e<n;e++)d[e]=c[e]^l[e]^u[e];if(!(0,t.timingSafeEqual)(Buffer.from(d),Buffer.from(s.slice(0,n))))throw new e.v;return a(this.#e,c,o)}#t(e,t){let n=new Uint8Array(r+t.length);return n[r-1]=e,n.set(t,r),d(this.#e,n)}};function a(e,n,r){let i=(0,t.createCipheriv)(`aes-128-ctr`,Buffer.from(e),Buffer.from(n));return Buffer.concat([i.update(Buffer.from(r)),i.final()])}function o(e,n){let r=(0,t.createCipheriv)(`aes-128-ecb`,Buffer.from(e),null);return r.setAutoPadding(!1),Buffer.concat([r.update(Buffer.from(n)),r.final()])}function s(e,t){let n=new Uint8Array(r);for(let i=0;i<r;i++)n[i]=e[i]^t[i];return n}function c(e){let t=new Uint8Array(r),n=0;for(let i=r-1;i>=0;i--){let r=(e[i]<<1|n)&255;n=e[i]>>7,t[i]=r}return t}var l=new Uint8Array(r);l[r-1]=135;function u(e){let t=o(e,new Uint8Array(r)),n=c(t);t[0]&128&&(n=s(n,l));let i=c(n);return n[0]&128&&(i=s(i,l)),[n,i]}function d(e,t){let[n,i]=u(e),a=Math.max(1,Math.ceil(t.length/r)),c=t.length>0&&t.length%r===0,l=new Uint8Array(r);for(let n=0;n<a-1;n++){let i=t.slice(n*r,(n+1)*r);l=Uint8Array.from(o(e,s(l,i)))}let d=new Uint8Array(r),f=(a-1)*r,p=t.slice(f);d.set(p);let m;return c?m=s(d,n):(p.length<r&&(d[p.length]=128),m=s(d,i)),Uint8Array.from(o(e,s(l,m)))}var f=8,p=10,m=8,h=15,g=Buffer.from(`TS3INIT1`),_=Buffer.from(`c:\\windows\\syste`),v=Buffer.from(`m\\firewall32.cpl`),y=class{identity;ivStruct=new Uint8Array;fakeSignature=new Uint8Array(f);alphaTmp=new Uint8Array;cryptoInitComplete=!1;#e=new Map;constructor(e){this.identity=e}solveRsaChallenge(e,t,n){if(n<0||n>1e6)throw Error(`RSA challenge level out of range`);let r=e.slice(t,t+64),i=e.slice(t+64,t+128),a=x(r),o=x(i);for(let e=0;e<n;e++)a=a*a%o;return S(a,64)}initCrypto(t,n,r){let i=Buffer.from(t,`base64`),a=Buffer.from(n,`base64`),o=e.m(Buffer.from(r,`base64`)),s=this.#t(o);this.setSharedSecret(i,a,s)}setSharedSecret(e,n,r){this.ivStruct=new Uint8Array(p+n.length);for(let t=0;t<p;t++){let n=r[t],i=e[t];this.ivStruct[t]=((n===void 0?0:n)^(i===void 0?0:i))&255}for(let e=0;e<n.length;e++){let t=r[p+e],i=n[e];this.ivStruct[p+e]=((t===void 0?0:t)^(i===void 0?0:i))&255}let i=(0,t.createHash)(`sha1`).update(this.ivStruct).digest();this.fakeSignature=new Uint8Array(i.buffer,i.byteOffset,f),this.cryptoInitComplete=!0}getKeyNonce(e,n,r,i,a){if(a)return[Uint8Array.from(_),Uint8Array.from(v)];let o=b(e,i,r),s=this.#e.get(o);if(s===void 0){let n=new Uint8Array(6+this.ivStruct.length);n[0]=e?48:49,n[1]=i&h,new DataView(n.buffer).setUint32(2,r,!1),n.set(this.ivStruct,6);let a=(0,t.createHash)(`sha256`).update(n).digest();s={key:Uint8Array.from(a.slice(0,16)),nonce:Uint8Array.from(a.slice(16,32)),gen:r},this.#e.set(o,s)}let c=Uint8Array.from(s.key);return c[0]=(c[0]===void 0?0:c[0])^n>>8&255,c[1]=(c[1]===void 0?0:c[1])^n&255,[c,s.nonce]}encrypt(e,t,n,r,a,o,s){if(e===m)return[a,g];if(s)return[a,this.fakeSignature];let[c,l]=this.getKeyNonce(!1,t,n,e,o);return new i(c).encrypt(l,r,a)}decrypt(t,n,r,a,o,s,c,l){if(t===m)return o;if(l){let t=s.slice(0,f);if(!Buffer.from(t).equals(Buffer.from(this.fakeSignature)))throw new e.y;return o}let[u,d]=this.getKeyNonce(!0,n,r,t,c);return new i(u).decrypt(d,a,o,s)}#t(e){let n=this.identity.privateKey.export({format:`jwk`}),r=e.export({format:`jwk`}),i=(0,t.createECDH)(`prime256v1`),a=Buffer.from(n.d,`base64url`);i.setPrivateKey(a);let o=C(r.x,32),s=C(r.y,32),c=Buffer.alloc(65);c[0]=4,o.copy(c,1),s.copy(c,33);let l=i.computeSecret(c);return(0,t.createHash)(`sha1`).update(l).digest()}};function b(e,t,n){let r=0n;return e&&(r|=1n<<40n),r|=BigInt(t&h)<<32n,r|=BigInt(n),r}function x(e){let t=0n;for(let n of e)t=t<<8n|BigInt(n);return t}function S(e,t){let n=new Uint8Array(t),r=e;for(let e=t-1;e>=0;e--)n[e]=Number(r&255n),r>>=8n;return n}function C(e,t){let n=Buffer.from(e,`base64url`);if(n.length===t)return n;let r=Buffer.alloc(t);return n.copy(r,t-n.length),r}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return y}});
2
- //# sourceMappingURL=crypto-IbzNNTgO.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto-IbzNNTgO.cjs","names":["#key","#cmac","#cachedKeys","#getSharedSecret"],"sources":["../src/crypto/eax.ts","../src/crypto/crypt.ts"],"sourcesContent":["import { createCipheriv, timingSafeEqual } from \"node:crypto\";\nimport { EAXTagMismatchError } from \"../errors.js\";\n\nconst EAX_TAG_SIZE = 8;\nconst EAX_BLOCK_SIZE = 16;\n\n/**\n * AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).\n * Uses AES-CMAC for authentication and AES-CTR for encryption.\n */\nexport class EAX {\n readonly #key: Uint8Array;\n\n constructor(key: Uint8Array) {\n if (key.length !== 16) throw new Error(\"EAX requires a 16-byte key\");\n this.#key = key;\n }\n\n encrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n plaintext: Uint8Array,\n ): [ciphertext: Uint8Array, tag: Uint8Array] {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n\n const ciphertext = aesCtr(this.#key, nStar, plaintext);\n\n const cStar = this.#cmac(2, ciphertext);\n\n const tag = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n tag[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n return [ciphertext, tag];\n }\n\n decrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n ): Uint8Array {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n const cStar = this.#cmac(2, ciphertext);\n\n const expected = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n expected[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n if (!timingSafeEqual(Buffer.from(expected), Buffer.from(tag.slice(0, EAX_TAG_SIZE)))) {\n throw new EAXTagMismatchError();\n }\n\n return aesCtr(this.#key, nStar, ciphertext);\n }\n\n /**\n * AES-CMAC per RFC 4493:\n * input = [0…0 tag] ++ data (one block prefix)\n */\n #cmac(tagByte: number, data: Uint8Array): Uint8Array {\n const input = new Uint8Array(EAX_BLOCK_SIZE + data.length);\n // first block: zeros then tag byte at the last position\n input[EAX_BLOCK_SIZE - 1] = tagByte;\n input.set(data, EAX_BLOCK_SIZE);\n\n return aesCmac(this.#key, input);\n }\n}\n\n// ---- AES-CTR ----------------------------------------------------------------\n\nfunction aesCtr(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array {\n const cipher = createCipheriv(\"aes-128-ctr\", Buffer.from(key), Buffer.from(iv));\n return Buffer.concat([cipher.update(Buffer.from(data)), cipher.final()]);\n}\n\n// ---- AES-CMAC (RFC 4493) ----------------------------------------------------\n\nfunction aesEcb(key: Uint8Array, block: Uint8Array): Uint8Array {\n // Node.js does not expose ECB directly; simulate via CTR with zero IV and\n // a zero-input (CTR of 0-block XOR with input = ECB)\n const cipher = createCipheriv(\"aes-128-ecb\", Buffer.from(key), null);\n cipher.setAutoPadding(false);\n return Buffer.concat([cipher.update(Buffer.from(block)), cipher.final()]);\n}\n\nfunction xorBlock(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n for (let i = 0; i < EAX_BLOCK_SIZE; i++) out[i] = a[i]! ^ b[i]!;\n return out;\n}\n\nfunction shiftLeft1(b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n let carry = 0;\n for (let i = EAX_BLOCK_SIZE - 1; i >= 0; i--) {\n const shifted = ((b[i]! << 1) | carry) & 0xff;\n carry = b[i]! >> 7;\n out[i] = shifted;\n }\n return out;\n}\n\nconst RB = new Uint8Array(EAX_BLOCK_SIZE);\nRB[EAX_BLOCK_SIZE - 1] = 0x87;\n\nfunction generateSubkeys(key: Uint8Array): [Uint8Array, Uint8Array] {\n const zero = new Uint8Array(EAX_BLOCK_SIZE);\n const L = aesEcb(key, zero);\n\n let K1 = shiftLeft1(L);\n if ((L[0]! & 0x80) !== 0) K1 = xorBlock(K1, RB);\n\n let K2 = shiftLeft1(K1);\n if ((K1[0]! & 0x80) !== 0) K2 = xorBlock(K2, RB);\n\n return [K1, K2];\n}\n\nexport function aesCmac(key: Uint8Array, message: Uint8Array): Uint8Array {\n const [K1, K2] = generateSubkeys(key);\n\n const n = Math.max(1, Math.ceil(message.length / EAX_BLOCK_SIZE));\n const lastBlockComplete = message.length > 0 && message.length % EAX_BLOCK_SIZE === 0;\n\n let X: Uint8Array = new Uint8Array(EAX_BLOCK_SIZE);\n\n for (let i = 0; i < n - 1; i++) {\n const block = message.slice(i * EAX_BLOCK_SIZE, (i + 1) * EAX_BLOCK_SIZE);\n X = Uint8Array.from(aesEcb(key, xorBlock(X, block)));\n }\n\n const lastBlock = new Uint8Array(EAX_BLOCK_SIZE);\n const lastStart = (n - 1) * EAX_BLOCK_SIZE;\n const lastSlice = message.slice(lastStart);\n lastBlock.set(lastSlice);\n\n let Mn: Uint8Array;\n if (lastBlockComplete) {\n Mn = xorBlock(lastBlock, K1);\n } else {\n if (lastSlice.length < EAX_BLOCK_SIZE) lastBlock[lastSlice.length] = 0x80;\n Mn = xorBlock(lastBlock, K2);\n }\n\n return Uint8Array.from(aesEcb(key, xorBlock(X, Mn)));\n}\n","import { createHash, createECDH } from \"node:crypto\";\nimport { FakeSignatureMismatchError } from \"../errors.js\";\nimport type { Identity } from \"./identity.js\";\nimport { importPublicKey } from \"./identity.js\";\nimport { EAX } from \"./eax.js\";\n\nconst FAKE_SIGNATURE_SIZE = 8;\nconst IV_ALPHA_SIZE = 10;\nconst INIT1_PACKET_TYPE = 8;\nconst PACKET_TYPE_MASK = 0x0f;\n\nconst INIT1_MAC = Buffer.from(\"TS3INIT1\");\n\nexport interface KeyNonce {\n key: Uint8Array;\n nonce: Uint8Array;\n gen: number;\n}\n\n/** Precomputed dummy key/nonce matching the TS3 client pre-crypto placeholder. */\nconst DUMMY_KEY = Buffer.from(\"c:\\\\windows\\\\syste\");\nconst DUMMY_NONCE = Buffer.from(\"m\\\\firewall32.cpl\");\n\nexport class Crypt {\n readonly identity: Identity;\n\n ivStruct: Uint8Array = new Uint8Array(0);\n fakeSignature: Uint8Array = new Uint8Array(FAKE_SIGNATURE_SIZE);\n alphaTmp: Uint8Array = new Uint8Array(0);\n cryptoInitComplete = false;\n\n readonly #cachedKeys = new Map<bigint, KeyNonce>();\n\n constructor(identity: Identity) {\n this.identity = identity;\n }\n\n solveRsaChallenge(data: Uint8Array, offset: number, level: number): Uint8Array {\n if (level < 0 || level > 1_000_000) {\n throw new Error(\"RSA challenge level out of range\");\n }\n\n const xBytes = data.slice(offset, offset + 64);\n const nBytes = data.slice(offset + 64, offset + 128);\n\n let y = bytesToBigInt(xBytes);\n const n = bytesToBigInt(nBytes);\n\n for (let i = 0; i < level; i++) {\n y = (y * y) % n;\n }\n\n return bigIntToBytes(y, 64);\n }\n\n initCrypto(alpha: string, beta: string, omega: string): void {\n const alphaBytes = Buffer.from(alpha, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n const sharedSecret = this.#getSharedSecret(serverPubKey);\n\n this.setSharedSecret(alphaBytes, betaBytes, sharedSecret);\n }\n\n setSharedSecret(alpha: Uint8Array, beta: Uint8Array, sharedKey: Uint8Array): void {\n this.ivStruct = new Uint8Array(IV_ALPHA_SIZE + beta.length);\n for (let i = 0; i < IV_ALPHA_SIZE; i++) {\n const a = sharedKey[i];\n const b = alpha[i];\n this.ivStruct[i] = ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n for (let i = 0; i < beta.length; i++) {\n const a = sharedKey[IV_ALPHA_SIZE + i];\n const b = beta[i];\n this.ivStruct[IV_ALPHA_SIZE + i] =\n ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n\n const digest = createHash(\"sha1\").update(this.ivStruct).digest();\n this.fakeSignature = new Uint8Array(digest.buffer, digest.byteOffset, FAKE_SIGNATURE_SIZE);\n this.cryptoInitComplete = true;\n }\n\n getKeyNonce(\n fromServer: boolean,\n packetID: number,\n generationID: number,\n packetType: number,\n dummy: boolean,\n ): [key: Uint8Array, nonce: Uint8Array] {\n if (dummy) {\n return [Uint8Array.from(DUMMY_KEY), Uint8Array.from(DUMMY_NONCE)];\n }\n\n const cacheKey = makeCacheKey(fromServer, packetType, generationID);\n let kn = this.#cachedKeys.get(cacheKey);\n\n if (kn === undefined) {\n const tmpToHash = new Uint8Array(6 + this.ivStruct.length);\n tmpToHash[0] = fromServer ? 0x30 : 0x31;\n tmpToHash[1] = packetType & PACKET_TYPE_MASK;\n new DataView(tmpToHash.buffer).setUint32(2, generationID, false);\n tmpToHash.set(this.ivStruct, 6);\n\n const hash = createHash(\"sha256\").update(tmpToHash).digest();\n kn = {\n key: Uint8Array.from(hash.slice(0, 16)),\n nonce: Uint8Array.from(hash.slice(16, 32)),\n gen: generationID,\n };\n this.#cachedKeys.set(cacheKey, kn);\n }\n\n const key = Uint8Array.from(kn.key);\n key[0] = (key[0] !== undefined ? key[0] : 0) ^ ((packetID >> 8) & 0xff);\n key[1] = (key[1] !== undefined ? key[1] : 0) ^ (packetID & 0xff);\n\n return [key, kn.nonce];\n }\n\n encrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n plaintext: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): [ciphertext: Uint8Array, mac: Uint8Array] {\n if (packetType === INIT1_PACKET_TYPE) {\n return [plaintext, INIT1_MAC];\n }\n if (unencrypted) {\n return [plaintext, this.fakeSignature];\n }\n\n const [key, nonce] = this.getKeyNonce(false, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.encrypt(nonce, header, plaintext);\n }\n\n decrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): Uint8Array {\n if (packetType === INIT1_PACKET_TYPE) {\n return ciphertext;\n }\n if (unencrypted) {\n const fsSub = tag.slice(0, FAKE_SIGNATURE_SIZE);\n if (!Buffer.from(fsSub).equals(Buffer.from(this.fakeSignature))) {\n throw new FakeSignatureMismatchError();\n }\n return ciphertext;\n }\n\n const [key, nonce] = this.getKeyNonce(true, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.decrypt(nonce, header, ciphertext, tag);\n }\n\n #getSharedSecret(serverPubKey: import(\"node:crypto\").KeyObject): Uint8Array {\n const privJwk = this.identity.privateKey.export({ format: \"jwk\" }) as {\n d: string;\n };\n const pubJwk = serverPubKey.export({ format: \"jwk\" }) as {\n x: string;\n y: string;\n };\n\n const ecdh = createECDH(\"prime256v1\");\n const dBytes = Buffer.from(privJwk.d, \"base64url\");\n ecdh.setPrivateKey(dBytes);\n\n const xBytes = base64UrlToBytes(pubJwk.x, 32);\n const yBytes = base64UrlToBytes(pubJwk.y, 32);\n const uncompressed = Buffer.alloc(65);\n uncompressed[0] = 0x04;\n xBytes.copy(uncompressed, 1);\n yBytes.copy(uncompressed, 33);\n\n const rawSecret = ecdh.computeSecret(uncompressed);\n return createHash(\"sha1\").update(rawSecret).digest();\n }\n}\n\n// ---- Helpers ----------------------------------------------------------------\n\nfunction makeCacheKey(fromServer: boolean, packetType: number, generationID: number): bigint {\n let key = 0n;\n if (fromServer) key |= 1n << 40n;\n key |= BigInt(packetType & PACKET_TYPE_MASK) << 32n;\n key |= BigInt(generationID);\n return key;\n}\n\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let result = 0n;\n for (const b of bytes) result = (result << 8n) | BigInt(b);\n return result;\n}\n\nfunction bigIntToBytes(value: bigint, size: number): Uint8Array {\n const result = new Uint8Array(size);\n let v = value;\n for (let i = size - 1; i >= 0; i--) {\n result[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return result;\n}\n\nfunction base64UrlToBytes(b64url: string, size: number): Buffer {\n const buf = Buffer.from(b64url, \"base64url\");\n if (buf.length === size) return buf;\n const padded = Buffer.alloc(size);\n buf.copy(padded, size - buf.length);\n return padded;\n}\n"],"mappings":"0EAGA,IAAM,EAAe,EACf,EAAiB,GAMV,EAAb,KAAiB,CACf,GAEA,YAAY,EAAiB,CAC3B,GAAI,EAAI,SAAW,GAAI,MAAU,MAAM,4BAA4B,EACnE,KAAKA,GAAO,CACd,CAEA,QACE,EACA,EACA,EAC2C,CAC3C,IAAM,EAAQ,KAAKC,GAAM,EAAG,CAAK,EAC3B,EAAQ,KAAKA,GAAM,EAAG,CAAM,EAE5B,EAAa,EAAO,KAAKD,GAAM,EAAO,CAAS,EAE/C,EAAQ,KAAKC,GAAM,EAAG,CAAU,EAEhC,EAAM,IAAI,WAAW,CAAY,EACvC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAc,IAChC,EAAI,GAAK,EAAM,GAAM,EAAM,GAAM,EAAM,GAGzC,MAAO,CAAC,EAAY,CAAG,CACzB,CAEA,QACE,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAQ,KAAKA,GAAM,EAAG,CAAK,EAC3B,EAAQ,KAAKA,GAAM,EAAG,CAAM,EAC5B,EAAQ,KAAKA,GAAM,EAAG,CAAU,EAEhC,EAAW,IAAI,WAAW,CAAY,EAC5C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAc,IAChC,EAAS,GAAK,EAAM,GAAM,EAAM,GAAM,EAAM,GAG9C,GAAI,EAAA,EAAA,EAAA,gBAAA,CAAiB,OAAO,KAAK,CAAQ,EAAG,OAAO,KAAK,EAAI,MAAM,EAAG,CAAY,CAAC,CAAC,EACjF,MAAM,IAAI,EAAA,EAGZ,OAAO,EAAO,KAAKD,GAAM,EAAO,CAAU,CAC5C,CAMA,GAAM,EAAiB,EAA8B,CACnD,IAAM,EAAQ,IAAI,WAAW,EAAiB,EAAK,MAAM,EAKzD,MAHA,GAAM,EAAiB,GAAK,EAC5B,EAAM,IAAI,EAAM,CAAc,EAEvB,EAAQ,KAAKA,GAAM,CAAK,CACjC,CACF,EAIA,SAAS,EAAO,EAAiB,EAAgB,EAA8B,CAC7E,IAAM,GAAA,EAAA,EAAA,eAAA,CAAwB,cAAe,OAAO,KAAK,CAAG,EAAG,OAAO,KAAK,CAAE,CAAC,EAC9E,OAAO,OAAO,OAAO,CAAC,EAAO,OAAO,OAAO,KAAK,CAAI,CAAC,EAAG,EAAO,MAAM,CAAC,CAAC,CACzE,CAIA,SAAS,EAAO,EAAiB,EAA+B,CAG9D,IAAM,GAAA,EAAA,EAAA,eAAA,CAAwB,cAAe,OAAO,KAAK,CAAG,EAAG,IAAI,EAEnE,OADA,EAAO,eAAe,EAAK,EACpB,OAAO,OAAO,CAAC,EAAO,OAAO,OAAO,KAAK,CAAK,CAAC,EAAG,EAAO,MAAM,CAAC,CAAC,CAC1E,CAEA,SAAS,EAAS,EAAe,EAA2B,CAC1D,IAAM,EAAM,IAAI,WAAW,CAAc,EACzC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAgB,IAAK,EAAI,GAAK,EAAE,GAAM,EAAE,GAC5D,OAAO,CACT,CAEA,SAAS,EAAW,EAA2B,CAC7C,IAAM,EAAM,IAAI,WAAW,CAAc,EACrC,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAiB,EAAG,GAAK,EAAG,IAAK,CAC5C,IAAM,GAAY,EAAE,IAAO,EAAK,GAAS,IACzC,EAAQ,EAAE,IAAO,EACjB,EAAI,GAAK,CACX,CACA,OAAO,CACT,CAEA,IAAM,EAAK,IAAI,WAAW,CAAc,EACxC,EAAG,EAAiB,GAAK,IAEzB,SAAS,EAAgB,EAA2C,CAElE,IAAM,EAAI,EAAO,EAAK,IADL,WAAW,CACN,CAAI,EAEtB,EAAK,EAAW,CAAC,EAChB,EAAE,GAAM,MAAa,EAAK,EAAS,EAAI,CAAE,GAE9C,IAAI,EAAK,EAAW,CAAE,EAGtB,OAFK,EAAG,GAAM,MAAa,EAAK,EAAS,EAAI,CAAE,GAExC,CAAC,EAAI,CAAE,CAChB,CAEA,SAAgB,EAAQ,EAAiB,EAAiC,CACxE,GAAM,CAAC,EAAI,GAAM,EAAgB,CAAG,EAE9B,EAAI,KAAK,IAAI,EAAG,KAAK,KAAK,EAAQ,OAAS,CAAc,CAAC,EAC1D,EAAoB,EAAQ,OAAS,GAAK,EAAQ,OAAS,IAAmB,EAEhF,EAAgB,IAAI,WAAW,CAAc,EAEjD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,EAAG,IAAK,CAC9B,IAAM,EAAQ,EAAQ,MAAM,EAAI,GAAiB,EAAI,GAAK,CAAc,EACxE,EAAI,WAAW,KAAK,EAAO,EAAK,EAAS,EAAG,CAAK,CAAC,CAAC,CACrD,CAEA,IAAM,EAAY,IAAI,WAAW,CAAc,EACzC,GAAa,EAAI,GAAK,EACtB,EAAY,EAAQ,MAAM,CAAS,EACzC,EAAU,IAAI,CAAS,EAEvB,IAAI,EAQJ,OAPI,EACF,EAAK,EAAS,EAAW,CAAE,GAEvB,EAAU,OAAS,IAAgB,EAAU,EAAU,QAAU,KACrE,EAAK,EAAS,EAAW,CAAE,GAGtB,WAAW,KAAK,EAAO,EAAK,EAAS,EAAG,CAAE,CAAC,CAAC,CACrD,CCjJA,IAAM,EAAsB,EACtB,EAAgB,GAChB,EAAoB,EACpB,EAAmB,GAEnB,EAAY,OAAO,KAAK,UAAU,EASlC,EAAY,OAAO,KAAK,oBAAoB,EAC5C,EAAc,OAAO,KAAK,mBAAmB,EAEtC,EAAb,KAAmB,CACjB,SAEA,SAAuB,IAAI,WAC3B,cAA4B,IAAI,WAAW,CAAmB,EAC9D,SAAuB,IAAI,WAC3B,mBAAqB,GAErB,GAAuB,IAAI,IAE3B,YAAY,EAAoB,CAC9B,KAAK,SAAW,CAClB,CAEA,kBAAkB,EAAkB,EAAgB,EAA2B,CAC7E,GAAI,EAAQ,GAAK,EAAQ,IACvB,MAAU,MAAM,kCAAkC,EAGpD,IAAM,EAAS,EAAK,MAAM,EAAQ,EAAS,EAAE,EACvC,EAAS,EAAK,MAAM,EAAS,GAAI,EAAS,GAAG,EAE/C,EAAI,EAAc,CAAM,EACtB,EAAI,EAAc,CAAM,EAE9B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,IACzB,EAAK,EAAI,EAAK,EAGhB,OAAO,EAAc,EAAG,EAAE,CAC5B,CAEA,WAAW,EAAe,EAAc,EAAqB,CAC3D,IAAM,EAAa,OAAO,KAAK,EAAO,QAAQ,EACxC,EAAY,OAAO,KAAK,EAAM,QAAQ,EAGtC,EAAe,EAAA,EAFF,OAAO,KAAK,EAAO,QAED,CAAU,EACzC,EAAe,KAAKG,GAAiB,CAAY,EAEvD,KAAK,gBAAgB,EAAY,EAAW,CAAY,CAC1D,CAEA,gBAAgB,EAAmB,EAAkB,EAA6B,CAChF,KAAK,SAAW,IAAI,WAAW,EAAgB,EAAK,MAAM,EAC1D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAe,IAAK,CACtC,IAAM,EAAI,EAAU,GACd,EAAI,EAAM,GAChB,KAAK,SAAS,KAAO,IAAM,IAAA,GAAgB,EAAJ,IAAU,IAAM,IAAA,GAAgB,EAAJ,IAAU,GAC/E,CACA,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAI,EAAU,EAAgB,GAC9B,EAAI,EAAK,GACf,KAAK,SAAS,EAAgB,KAC1B,IAAM,IAAA,GAAgB,EAAJ,IAAU,IAAM,IAAA,GAAgB,EAAJ,IAAU,GAC9D,CAEA,IAAM,GAAA,EAAA,EAAA,WAAA,CAAoB,MAAM,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,EAC/D,KAAK,cAAgB,IAAI,WAAW,EAAO,OAAQ,EAAO,WAAY,CAAmB,EACzF,KAAK,mBAAqB,EAC5B,CAEA,YACE,EACA,EACA,EACA,EACA,EACsC,CACtC,GAAI,EACF,MAAO,CAAC,WAAW,KAAK,CAAS,EAAG,WAAW,KAAK,CAAW,CAAC,EAGlE,IAAM,EAAW,EAAa,EAAY,EAAY,CAAY,EAC9D,EAAK,KAAKD,GAAY,IAAI,CAAQ,EAEtC,GAAI,IAAO,IAAA,GAAW,CACpB,IAAM,EAAY,IAAI,WAAW,EAAI,KAAK,SAAS,MAAM,EACzD,EAAU,GAAK,EAAa,GAAO,GACnC,EAAU,GAAK,EAAa,EAC5B,IAAI,SAAS,EAAU,MAAM,CAAC,CAAC,UAAU,EAAG,EAAc,EAAK,EAC/D,EAAU,IAAI,KAAK,SAAU,CAAC,EAE9B,IAAM,GAAA,EAAA,EAAA,WAAA,CAAkB,QAAQ,CAAC,CAAC,OAAO,CAAS,CAAC,CAAC,OAAO,EAC3D,EAAK,CACH,IAAK,WAAW,KAAK,EAAK,MAAM,EAAG,EAAE,CAAC,EACtC,MAAO,WAAW,KAAK,EAAK,MAAM,GAAI,EAAE,CAAC,EACzC,IAAK,CACP,EACA,KAAKA,GAAY,IAAI,EAAU,CAAE,CACnC,CAEA,IAAM,EAAM,WAAW,KAAK,EAAG,GAAG,EAIlC,MAHA,GAAI,IAAM,EAAI,KAAO,IAAA,GAAqB,EAAT,EAAI,IAAY,GAAY,EAAK,IAClE,EAAI,IAAM,EAAI,KAAO,IAAA,GAAqB,EAAT,EAAI,IAAW,EAAW,IAEpD,CAAC,EAAK,EAAG,KAAK,CACvB,CAEA,QACE,EACA,EACA,EACA,EACA,EACA,EACA,EAC2C,CAC3C,GAAI,IAAe,EACjB,MAAO,CAAC,EAAW,CAAS,EAE9B,GAAI,EACF,MAAO,CAAC,EAAW,KAAK,aAAa,EAGvC,GAAM,CAAC,EAAK,GAAS,KAAK,YAAY,GAAO,EAAU,EAAc,EAAY,CAAK,EAEtF,OAAO,IADS,EAAI,CACb,CAAA,CAAI,QAAQ,EAAO,EAAQ,CAAS,CAC7C,CAEA,QACE,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACY,CACZ,GAAI,IAAe,EACjB,OAAO,EAET,GAAI,EAAa,CACf,IAAM,EAAQ,EAAI,MAAM,EAAG,CAAmB,EAC9C,GAAI,CAAC,OAAO,KAAK,CAAK,CAAC,CAAC,OAAO,OAAO,KAAK,KAAK,aAAa,CAAC,EAC5D,MAAM,IAAI,EAAA,EAEZ,OAAO,CACT,CAEA,GAAM,CAAC,EAAK,GAAS,KAAK,YAAY,GAAM,EAAU,EAAc,EAAY,CAAK,EAErF,OAAO,IADS,EAAI,CACb,CAAA,CAAI,QAAQ,EAAO,EAAQ,EAAY,CAAG,CACnD,CAEA,GAAiB,EAA2D,CAC1E,IAAM,EAAU,KAAK,SAAS,WAAW,OAAO,CAAE,OAAQ,KAAM,CAAC,EAG3D,EAAS,EAAa,OAAO,CAAE,OAAQ,KAAM,CAAC,EAK9C,GAAA,EAAA,EAAA,WAAA,CAAkB,YAAY,EAC9B,EAAS,OAAO,KAAK,EAAQ,EAAG,WAAW,EACjD,EAAK,cAAc,CAAM,EAEzB,IAAM,EAAS,EAAiB,EAAO,EAAG,EAAE,EACtC,EAAS,EAAiB,EAAO,EAAG,EAAE,EACtC,EAAe,OAAO,MAAM,EAAE,EACpC,EAAa,GAAK,EAClB,EAAO,KAAK,EAAc,CAAC,EAC3B,EAAO,KAAK,EAAc,EAAE,EAE5B,IAAM,EAAY,EAAK,cAAc,CAAY,EACjD,OAAA,EAAA,EAAA,WAAA,CAAkB,MAAM,CAAC,CAAC,OAAO,CAAS,CAAC,CAAC,OAAO,CACrD,CACF,EAIA,SAAS,EAAa,EAAqB,EAAoB,EAA8B,CAC3F,IAAI,EAAM,GAIV,OAHI,IAAY,GAAO,IAAM,KAC7B,GAAO,OAAO,EAAa,CAAgB,GAAK,IAChD,GAAO,OAAO,CAAY,EACnB,CACT,CAEA,SAAS,EAAc,EAA2B,CAChD,IAAI,EAAS,GACb,IAAK,IAAM,KAAK,EAAO,EAAU,GAAU,GAAM,OAAO,CAAC,EACzD,OAAO,CACT,CAEA,SAAS,EAAc,EAAe,EAA0B,CAC9D,IAAM,EAAS,IAAI,WAAW,CAAI,EAC9B,EAAI,EACR,IAAK,IAAI,EAAI,EAAO,EAAG,GAAK,EAAG,IAC7B,EAAO,GAAK,OAAO,EAAI,IAAK,EAC5B,IAAM,GAER,OAAO,CACT,CAEA,SAAS,EAAiB,EAAgB,EAAsB,CAC9D,IAAM,EAAM,OAAO,KAAK,EAAQ,WAAW,EAC3C,GAAI,EAAI,SAAW,EAAM,OAAO,EAChC,IAAM,EAAS,OAAO,MAAM,CAAI,EAEhC,OADA,EAAI,KAAK,EAAQ,EAAO,EAAI,MAAM,EAC3B,CACT"}