@amxts/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/README.ru.md +162 -0
  4. package/amxmodx/base/include/amxconst.inc +594 -0
  5. package/amxmodx/base/include/amxmisc.inc +902 -0
  6. package/amxmodx/base/include/amxmodx.inc +3447 -0
  7. package/amxmodx/base/include/amxmodx_version.inc +20 -0
  8. package/amxmodx/base/include/cellarray.inc +525 -0
  9. package/amxmodx/base/include/cellstack.inc +166 -0
  10. package/amxmodx/base/include/celltrie.inc +412 -0
  11. package/amxmodx/base/include/core.inc +202 -0
  12. package/amxmodx/base/include/csstats.inc +298 -0
  13. package/amxmodx/base/include/csstats_const.inc +29 -0
  14. package/amxmodx/base/include/cstrike.inc +1287 -0
  15. package/amxmodx/base/include/cstrike_const.inc +521 -0
  16. package/amxmodx/base/include/csx.inc +259 -0
  17. package/amxmodx/base/include/cvars.inc +547 -0
  18. package/amxmodx/base/include/datapack.inc +161 -0
  19. package/amxmodx/base/include/dbi.inc +154 -0
  20. package/amxmodx/base/include/dodconst.inc +152 -0
  21. package/amxmodx/base/include/dodfun.inc +152 -0
  22. package/amxmodx/base/include/dodstats.inc +69 -0
  23. package/amxmodx/base/include/dodx.inc +161 -0
  24. package/amxmodx/base/include/engine.inc +1343 -0
  25. package/amxmodx/base/include/engine_const.inc +310 -0
  26. package/amxmodx/base/include/engine_stocks.inc +248 -0
  27. package/amxmodx/base/include/esf.inc +70 -0
  28. package/amxmodx/base/include/esf_const.inc +74 -0
  29. package/amxmodx/base/include/fakemeta.inc +1127 -0
  30. package/amxmodx/base/include/fakemeta_const.inc +793 -0
  31. package/amxmodx/base/include/fakemeta_stocks.inc +395 -0
  32. package/amxmodx/base/include/fakemeta_util.inc +882 -0
  33. package/amxmodx/base/include/file.inc +666 -0
  34. package/amxmodx/base/include/float.inc +422 -0
  35. package/amxmodx/base/include/fun.inc +333 -0
  36. package/amxmodx/base/include/gameconfig.inc +93 -0
  37. package/amxmodx/base/include/geoip.inc +264 -0
  38. package/amxmodx/base/include/ham_const.inc +4352 -0
  39. package/amxmodx/base/include/hamsandwich.inc +439 -0
  40. package/amxmodx/base/include/hlsdk_const.inc +808 -0
  41. package/amxmodx/base/include/json.inc +777 -0
  42. package/amxmodx/base/include/lang.inc +119 -0
  43. package/amxmodx/base/include/message_const.inc +1130 -0
  44. package/amxmodx/base/include/message_stocks.inc +161 -0
  45. package/amxmodx/base/include/messages.inc +604 -0
  46. package/amxmodx/base/include/newmenus.inc +387 -0
  47. package/amxmodx/base/include/ns.inc +754 -0
  48. package/amxmodx/base/include/ns_const.inc +196 -0
  49. package/amxmodx/base/include/nvault.inc +154 -0
  50. package/amxmodx/base/include/regex.inc +348 -0
  51. package/amxmodx/base/include/sockets.inc +183 -0
  52. package/amxmodx/base/include/sorting.inc +107 -0
  53. package/amxmodx/base/include/sqlx.inc +582 -0
  54. package/amxmodx/base/include/string.inc +786 -0
  55. package/amxmodx/base/include/string_const.inc +156 -0
  56. package/amxmodx/base/include/string_stocks.inc +325 -0
  57. package/amxmodx/base/include/textparse_ini.inc +214 -0
  58. package/amxmodx/base/include/textparse_smc.inc +261 -0
  59. package/amxmodx/base/include/tfcconst.inc +84 -0
  60. package/amxmodx/base/include/tfcstats.inc +62 -0
  61. package/amxmodx/base/include/tfcx.inc +148 -0
  62. package/amxmodx/base/include/time.inc +118 -0
  63. package/amxmodx/base/include/tsconst.inc +154 -0
  64. package/amxmodx/base/include/tsfun.inc +198 -0
  65. package/amxmodx/base/include/tsstats.inc +65 -0
  66. package/amxmodx/base/include/tsx.inc +88 -0
  67. package/amxmodx/base/include/vault.inc +60 -0
  68. package/amxmodx/base/include/vector.inc +131 -0
  69. package/amxmodx/base/include/xs.inc +1570 -0
  70. package/as/amxts.d.ts +153 -0
  71. package/as/constants.ts +4730 -0
  72. package/as/effects.ts +1449 -0
  73. package/as/entities.ts +5482 -0
  74. package/as/events.ts +3054 -0
  75. package/as/facade.ts +4639 -0
  76. package/as/flags.ts +299 -0
  77. package/as/fs.ts +287 -0
  78. package/as/hooks.ts +18536 -0
  79. package/as/kit.ts +25 -0
  80. package/as/lib/check.ts +86 -0
  81. package/as/modules/http.ts +184 -0
  82. package/as/natives.ts +11845 -0
  83. package/as/os.ts +30 -0
  84. package/as/promise.ts +1392 -0
  85. package/as/promise.types.d.ts +82 -0
  86. package/as/remote.ts +288 -0
  87. package/as/tsconfig.json +22 -0
  88. package/as/vector.ts +65 -0
  89. package/bin/amxts.mjs +10 -0
  90. package/includes/menu_core.inc +355 -0
  91. package/includes/order.txt +54 -0
  92. package/includes/sources.json +27 -0
  93. package/includes/universal_config.inc +355 -0
  94. package/lint/oxlint-plugin.mjs +77 -0
  95. package/node_modules/assemblyscript/LICENSE +201 -0
  96. package/node_modules/assemblyscript/NOTICE +93 -0
  97. package/node_modules/assemblyscript/package.json +63 -0
  98. package/node_modules/assemblyscript/std/README.md +6 -0
  99. package/node_modules/assemblyscript/std/assembly/array.ts +526 -0
  100. package/node_modules/assemblyscript/std/assembly/arraybuffer.ts +77 -0
  101. package/node_modules/assemblyscript/std/assembly/atomics.ts +127 -0
  102. package/node_modules/assemblyscript/std/assembly/bindings/asyncify.ts +16 -0
  103. package/node_modules/assemblyscript/std/assembly/bindings/dom.ts +291 -0
  104. package/node_modules/assemblyscript/std/assembly/bindings/node.ts +6 -0
  105. package/node_modules/assemblyscript/std/assembly/builtins.ts +2631 -0
  106. package/node_modules/assemblyscript/std/assembly/compat.ts +2 -0
  107. package/node_modules/assemblyscript/std/assembly/console.ts +42 -0
  108. package/node_modules/assemblyscript/std/assembly/crypto.ts +9 -0
  109. package/node_modules/assemblyscript/std/assembly/dataview.ts +181 -0
  110. package/node_modules/assemblyscript/std/assembly/date.ts +373 -0
  111. package/node_modules/assemblyscript/std/assembly/diagnostics.ts +11 -0
  112. package/node_modules/assemblyscript/std/assembly/error.ts +44 -0
  113. package/node_modules/assemblyscript/std/assembly/function.ts +38 -0
  114. package/node_modules/assemblyscript/std/assembly/index.d.ts +2822 -0
  115. package/node_modules/assemblyscript/std/assembly/iterator.ts +35 -0
  116. package/node_modules/assemblyscript/std/assembly/map.ts +260 -0
  117. package/node_modules/assemblyscript/std/assembly/math.ts +3289 -0
  118. package/node_modules/assemblyscript/std/assembly/memory.ts +123 -0
  119. package/node_modules/assemblyscript/std/assembly/number.ts +388 -0
  120. package/node_modules/assemblyscript/std/assembly/object.ts +36 -0
  121. package/node_modules/assemblyscript/std/assembly/performance.ts +9 -0
  122. package/node_modules/assemblyscript/std/assembly/polyfills.ts +27 -0
  123. package/node_modules/assemblyscript/std/assembly/process.ts +50 -0
  124. package/node_modules/assemblyscript/std/assembly/reference.ts +48 -0
  125. package/node_modules/assemblyscript/std/assembly/regexp.ts +12 -0
  126. package/node_modules/assemblyscript/std/assembly/rt/README.md +83 -0
  127. package/node_modules/assemblyscript/std/assembly/rt/common.ts +81 -0
  128. package/node_modules/assemblyscript/std/assembly/rt/index-incremental.ts +2 -0
  129. package/node_modules/assemblyscript/std/assembly/rt/index-minimal.ts +2 -0
  130. package/node_modules/assemblyscript/std/assembly/rt/index-stub.ts +1 -0
  131. package/node_modules/assemblyscript/std/assembly/rt/index.d.ts +37 -0
  132. package/node_modules/assemblyscript/std/assembly/rt/itcms.ts +419 -0
  133. package/node_modules/assemblyscript/std/assembly/rt/rtrace.ts +15 -0
  134. package/node_modules/assemblyscript/std/assembly/rt/stub.ts +133 -0
  135. package/node_modules/assemblyscript/std/assembly/rt/tcms.ts +254 -0
  136. package/node_modules/assemblyscript/std/assembly/rt/tlsf.ts +592 -0
  137. package/node_modules/assemblyscript/std/assembly/rt.ts +87 -0
  138. package/node_modules/assemblyscript/std/assembly/set.ts +220 -0
  139. package/node_modules/assemblyscript/std/assembly/shared/feature.ts +65 -0
  140. package/node_modules/assemblyscript/std/assembly/shared/runtime.ts +11 -0
  141. package/node_modules/assemblyscript/std/assembly/shared/target.ts +11 -0
  142. package/node_modules/assemblyscript/std/assembly/shared/tsconfig.json +11 -0
  143. package/node_modules/assemblyscript/std/assembly/shared/typeinfo.ts +72 -0
  144. package/node_modules/assemblyscript/std/assembly/staticarray.ts +401 -0
  145. package/node_modules/assemblyscript/std/assembly/string.ts +847 -0
  146. package/node_modules/assemblyscript/std/assembly/symbol.ts +114 -0
  147. package/node_modules/assemblyscript/std/assembly/table.ts +16 -0
  148. package/node_modules/assemblyscript/std/assembly/tsconfig.json +6 -0
  149. package/node_modules/assemblyscript/std/assembly/typedarray.ts +1945 -0
  150. package/node_modules/assemblyscript/std/assembly/uri.ts +17 -0
  151. package/node_modules/assemblyscript/std/assembly/util/bytes.ts +107 -0
  152. package/node_modules/assemblyscript/std/assembly/util/casemap.ts +497 -0
  153. package/node_modules/assemblyscript/std/assembly/util/error.ts +54 -0
  154. package/node_modules/assemblyscript/std/assembly/util/hash.ts +117 -0
  155. package/node_modules/assemblyscript/std/assembly/util/math.ts +1922 -0
  156. package/node_modules/assemblyscript/std/assembly/util/memory.ts +290 -0
  157. package/node_modules/assemblyscript/std/assembly/util/number.ts +873 -0
  158. package/node_modules/assemblyscript/std/assembly/util/sort.ts +313 -0
  159. package/node_modules/assemblyscript/std/assembly/util/string.ts +1202 -0
  160. package/node_modules/assemblyscript/std/assembly/util/uri.ts +275 -0
  161. package/node_modules/assemblyscript/std/assembly/vector.ts +4 -0
  162. package/node_modules/assemblyscript/std/assembly.json +16 -0
  163. package/node_modules/assemblyscript/std/portable/index.d.ts +462 -0
  164. package/node_modules/assemblyscript/std/portable/index.js +416 -0
  165. package/node_modules/assemblyscript/std/portable.json +11 -0
  166. package/node_modules/assemblyscript/std/types/assembly/index.d.ts +1 -0
  167. package/node_modules/assemblyscript/std/types/assembly/package.json +3 -0
  168. package/node_modules/assemblyscript/std/types/portable/index.d.ts +1 -0
  169. package/node_modules/assemblyscript/std/types/portable/package.json +3 -0
  170. package/node_modules/assemblyscript/tsconfig-base.json +13 -0
  171. package/package.json +112 -0
  172. package/runtime/deps/assemblyscript/LICENSE +201 -0
  173. package/runtime/deps/assemblyscript/NOTICE +93 -0
  174. package/runtime/deps/assemblyscript/bin/asc.js +35 -0
  175. package/runtime/deps/assemblyscript/dist/asc.js +25035 -0
  176. package/runtime/deps/assemblyscript/dist/assemblyscript.js +337 -0
  177. package/runtime/deps/assemblyscript/node_modules/binaryen/LICENSE +201 -0
  178. package/runtime/deps/assemblyscript/node_modules/binaryen/index.js +28905 -0
  179. package/runtime/deps/assemblyscript/node_modules/binaryen/package.json +50 -0
  180. package/runtime/deps/assemblyscript/node_modules/long/LICENSE +202 -0
  181. package/runtime/deps/assemblyscript/node_modules/long/index.js +1581 -0
  182. package/runtime/deps/assemblyscript/node_modules/long/package.json +58 -0
  183. package/runtime/deps/assemblyscript/package.json +114 -0
  184. package/runtime/host/amxts.inc +85 -0
  185. package/runtime/licenses/AMXX-LICENSE.txt +34 -0
  186. package/runtime/licenses/AssemblyScript-LICENSE +201 -0
  187. package/runtime/licenses/AssemblyScript-NOTICE +93 -0
  188. package/runtime/licenses/Binaryen-LICENSE +201 -0
  189. package/runtime/licenses/Bun-LICENSE.md +84 -0
  190. package/runtime/licenses/GPL-3.0.txt +674 -0
  191. package/runtime/licenses/LLVM-LICENSE.TXT +279 -0
  192. package/runtime/licenses/README.md +25 -0
  193. package/runtime/licenses/WAMR-LICENSE +219 -0
  194. package/runtime/natives.txt +1095 -0
  195. package/runtime/patches/README.md +59 -0
  196. package/runtime/patches/assemblyscript-0.28.20-amxts.patch +14174 -0
  197. package/runtime/patches/wamr-2.4.5-amxts.patch +364 -0
  198. package/scripts/apply-docs.ts +508 -0
  199. package/scripts/asc.ts +27 -0
  200. package/scripts/auto-imports.ts +258 -0
  201. package/scripts/build-wasm.ts +595 -0
  202. package/scripts/check.ts +93 -0
  203. package/scripts/compile-cache.ts +179 -0
  204. package/scripts/compile.ts +401 -0
  205. package/scripts/docker-server.ts +73 -0
  206. package/scripts/docs/as/amxts.ts +210 -0
  207. package/scripts/docs/as/effects.ts +1684 -0
  208. package/scripts/docs/as/facade.ts +3302 -0
  209. package/scripts/docs/as/fs.ts +173 -0
  210. package/scripts/docs/as/lib/check.ts +68 -0
  211. package/scripts/docs/as/modules/http.ts +66 -0
  212. package/scripts/docs/as/os.ts +16 -0
  213. package/scripts/docs/as/promise.ts +132 -0
  214. package/scripts/docs/as/promise.types.ts +63 -0
  215. package/scripts/docs/as/vector.ts +48 -0
  216. package/scripts/docs/entities.ts +2338 -0
  217. package/scripts/docs/events.ts +245 -0
  218. package/scripts/docs/game.ts +497 -0
  219. package/scripts/docs/messages.ts +148 -0
  220. package/scripts/file-contents.ts +74 -0
  221. package/scripts/includes.ts +134 -0
  222. package/scripts/player-fields.ts +866 -0
  223. package/scripts/plugin-cache.ts +92 -0
  224. package/scripts/plugin-natives.ts +1157 -0
  225. package/scripts/prebuilt.ts +268 -0
  226. package/scripts/prepare.ts +134 -0
  227. package/scripts/project.ts +973 -0
  228. package/scripts/run.ts +28 -0
  229. package/scripts/shared-modules.ts +906 -0
  230. package/scripts/system.ts +33 -0
  231. package/scripts/tracked-fs.ts +115 -0
  232. package/scripts/typed-configs.ts +788 -0
  233. package/scripts/ui.ts +77 -0
  234. package/src/cli-api.mjs +175 -0
  235. package/src/parser/include-parser.ts +506 -0
  236. package/src/system.mjs +155 -0
  237. package/src/testing/compile-cache.ts +31 -0
  238. package/src/testing/compile.ts +222 -0
  239. package/src/testing/coroutines.ts +191 -0
  240. package/src/testing/index.ts +39 -0
  241. package/src/testing/kits.ts +55 -0
  242. package/src/testing/memory.ts +125 -0
  243. package/src/testing/natives.ts +925 -0
  244. package/src/testing/server.ts +1874 -0
  245. package/src/testing/setup.ts +63 -0
  246. package/src/testing/tables.ts +139 -0
  247. package/src/types.ts +51 -0
@@ -0,0 +1,847 @@
1
+ /// <reference path="./rt/index.d.ts" />
2
+
3
+ import { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from "./rt/common";
4
+ import { compareImpl, strtol, strtod, isSpace, isAscii, isFinalSigma, toLower8, toUpper8 } from "./util/string";
5
+ import { SPECIALS_UPPER, casemap, bsearch } from "./util/casemap";
6
+ import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_UNPAIRED_SURROGATE } from "./util/error";
7
+ import { idof } from "./builtins";
8
+ import { Array } from "./array";
9
+
10
+ @final export abstract class String {
11
+
12
+ @lazy static readonly MAX_LENGTH: i32 = <i32>(BLOCK_MAXSIZE >>> alignof<u16>());
13
+
14
+ static fromCharCode(unit: i32, surr: i32 = -1): String {
15
+ let hasSur = surr > 0;
16
+ let out = changetype<String>(__new(2 << i32(hasSur), idof<String>()));
17
+ store<u16>(changetype<usize>(out), <u16>unit);
18
+ if (hasSur) store<u16>(changetype<usize>(out), <u16>surr, 2);
19
+ return out;
20
+ }
21
+
22
+ static fromCharCodes(units: Array<i32>): String {
23
+ let length = units.length;
24
+ let out = changetype<String>(__new(<usize>length << 1, idof<String>()));
25
+ let ptr = units.dataStart;
26
+ for (let i = 0; i < length; ++i) {
27
+ store<u16>(changetype<usize>(out) + (<usize>i << 1), load<i32>(ptr + (<usize>i << 2)));
28
+ }
29
+ return out;
30
+ }
31
+
32
+ static fromCodePoint(code: i32): String {
33
+ let hasSur = <u32>code > 0xFFFF;
34
+ let out = changetype<String>(__new(2 << i32(hasSur), idof<String>()));
35
+ if (!hasSur) {
36
+ store<u16>(changetype<usize>(out), <u16>code);
37
+ } else {
38
+ // Checks valid code point range
39
+ assert(<u32>code <= 0x10FFFF);
40
+ code -= 0x10000;
41
+ let hi = (code & 0x03FF) | 0xDC00;
42
+ let lo = code >>> 10 | 0xD800;
43
+ store<u32>(changetype<usize>(out), lo | hi << 16);
44
+ }
45
+ return out;
46
+ }
47
+
48
+ @builtin static raw(parts: TemplateStringsArray, ...args: unknown[]): string { return unreachable(); }
49
+
50
+ get length(): i32 {
51
+ return changetype<OBJECT>(changetype<usize>(this) - TOTAL_OVERHEAD).rtSize >> 1;
52
+ }
53
+
54
+ at(pos: i32): String {
55
+ let len = this.length;
56
+ pos += select(0, len, pos >= 0);
57
+ if (<u32>pos >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
58
+ let out = __new(2, idof<String>());
59
+ store<u16>(out, load<u16>(changetype<usize>(this) + (<usize>pos << 1)));
60
+ return changetype<String>(out); // retains
61
+ }
62
+
63
+ @operator("[]") charAt(pos: i32): String {
64
+ if (<u32>pos >= <u32>this.length) return changetype<String>("");
65
+ let out = changetype<String>(__new(2, idof<String>()));
66
+ store<u16>(changetype<usize>(out), load<u16>(changetype<usize>(this) + (<usize>pos << 1)));
67
+ return out;
68
+ }
69
+
70
+ charCodeAt(pos: i32): i32 {
71
+ if (<u32>pos >= <u32>this.length) return -1; // (NaN)
72
+ return load<u16>(changetype<usize>(this) + (<usize>pos << 1));
73
+ }
74
+
75
+ codePointAt(pos: i32): i32 {
76
+ let len = this.length;
77
+ if (<u32>pos >= <u32>len) return -1; // (undefined)
78
+ let first = <i32>load<u16>(changetype<usize>(this) + (<usize>pos << 1));
79
+ if ((first & 0xFC00) != 0xD800 || pos + 1 == len) return first;
80
+ let second = <i32>load<u16>(changetype<usize>(this) + (<usize>pos << 1), 2);
81
+ if ((second & 0xFC00) != 0xDC00) return first;
82
+ return (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
83
+ }
84
+
85
+ @operator("+") private static __concat(left: String, right: String): String {
86
+ return left.concat(right);
87
+ }
88
+
89
+ concat(other: String): String {
90
+ let thisSize: isize = this.length << 1;
91
+ let otherSize: isize = other.length << 1;
92
+ let outSize: usize = thisSize + otherSize;
93
+ if (outSize == 0) return changetype<String>("");
94
+ let out = changetype<String>(__new(outSize, idof<String>()));
95
+ memory.copy(changetype<usize>(out), changetype<usize>(this), thisSize);
96
+ memory.copy(changetype<usize>(out) + thisSize, changetype<usize>(other), otherSize);
97
+ return out;
98
+ }
99
+
100
+ endsWith(search: String, end: i32 = String.MAX_LENGTH): bool {
101
+ end = min(max(end, 0), this.length);
102
+ let searchLength = <isize>search.length;
103
+ let searchStart = <isize>end - searchLength;
104
+ if (searchStart < 0) return false;
105
+ // @ts-ignore: string <-> String
106
+ return !compareImpl(this, searchStart, search, 0, searchLength);
107
+ }
108
+
109
+ @operator("==") private static __eq(left: String | null, right: String | null): bool {
110
+ if (changetype<usize>(left) == changetype<usize>(right)) return true;
111
+ if (changetype<usize>(left) == 0 || changetype<usize>(right) == 0) return false;
112
+ let leftLength = changetype<string>(left).length;
113
+ if (leftLength != changetype<string>(right).length) return false;
114
+ // @ts-ignore: string <-> String
115
+ return !compareImpl(left, 0, right, 0, leftLength);
116
+ }
117
+
118
+ @operator.prefix("!")
119
+ private static __not(str: String | null): bool {
120
+ return changetype<usize>(str) == 0 || !changetype<string>(str).length;
121
+ }
122
+
123
+ @operator("!=")
124
+ private static __ne(left: String | null, right: String | null): bool {
125
+ return !this.__eq(left, right);
126
+ }
127
+
128
+ @operator(">") private static __gt(left: String, right: String): bool {
129
+ if (changetype<usize>(left) == changetype<usize>(right)) return false;
130
+ let leftLength = left.length;
131
+ if (!leftLength) return false;
132
+ let rightLength = right.length;
133
+ if (!rightLength) return true;
134
+ // @ts-ignore: string <-> String
135
+ let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));
136
+ return res ? res > 0 : leftLength > rightLength;
137
+ }
138
+
139
+ @operator(">=") private static __gte(left: String, right: String): bool {
140
+ return !this.__lt(left, right);
141
+ }
142
+
143
+ @operator("<") private static __lt(left: String, right: String): bool {
144
+ if (changetype<usize>(left) == changetype<usize>(right)) return false;
145
+ let rightLength = right.length;
146
+ if (!rightLength) return false;
147
+ let leftLength = left.length;
148
+ if (!leftLength) return true;
149
+ // @ts-ignore: string <-> String
150
+ let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));
151
+ return res ? res < 0 : leftLength < rightLength;
152
+ }
153
+
154
+ @operator("<=") private static __lte(left: String, right: String): bool {
155
+ return !this.__gt(left, right);
156
+ }
157
+
158
+ includes(search: String, start: i32 = 0): bool {
159
+ return this.indexOf(search, start) != -1;
160
+ }
161
+
162
+ indexOf(search: String, start: i32 = 0): i32 {
163
+ let searchLen = <isize>search.length;
164
+ if (!searchLen) return 0;
165
+ let len = <isize>this.length;
166
+ if (!len) return -1;
167
+ let searchStart = min(max(<isize>start, 0), len);
168
+ for (len -= searchLen; searchStart <= len; ++searchStart) {
169
+ // @ts-ignore: string <-> String
170
+ if (!compareImpl(this, searchStart, search, 0, searchLen)) return <i32>searchStart;
171
+ }
172
+ return -1;
173
+ }
174
+
175
+ lastIndexOf(search: String, start: i32 = i32.MAX_VALUE): i32 {
176
+ let searchLen = <isize>search.length;
177
+ if (!searchLen) return this.length;
178
+ let len = this.length;
179
+ if (!len) return -1;
180
+ let searchStart = min(max(<isize>start, 0), <isize>len - searchLen);
181
+ for (; searchStart >= 0; --searchStart) {
182
+ // @ts-ignore: string <-> String
183
+ if (!compareImpl(this, searchStart, search, 0, searchLen)) return <i32>searchStart;
184
+ }
185
+ return -1;
186
+ }
187
+
188
+ // TODO: implement full locale comparison with locales and Collator options
189
+ localeCompare(other: String): i32 {
190
+ if (changetype<usize>(other) == changetype<usize>(this)) return 0;
191
+ let alen = this.length;
192
+ let blen = other.length;
193
+ // @ts-ignore: string <-> String
194
+ let res = compareImpl(this, 0, other, 0, <usize>min(alen, blen));
195
+ res = res ? res : alen - blen;
196
+ // normalize to [-1, 1] range
197
+ return i32(res > 0) - i32(res < 0);
198
+ }
199
+
200
+ startsWith(search: String, start: i32 = 0): bool {
201
+ let len = <isize>this.length;
202
+ let searchStart = min(max(<isize>start, 0), len);
203
+ let searchLength = <isize>search.length;
204
+ if (searchLength + searchStart > len) return false;
205
+ // @ts-ignore: string <-> String
206
+ return !compareImpl(this, searchStart, search, 0, searchLength);
207
+ }
208
+
209
+ substr(start: i32, length: i32 = i32.MAX_VALUE): String { // legacy
210
+ let intStart: isize = start;
211
+ let end: isize = length;
212
+ let len: isize = this.length;
213
+ if (intStart < 0) intStart = max(len + intStart, 0);
214
+ let size = min(max(end, 0), len - intStart) << 1;
215
+ if (size <= 0) return changetype<String>("");
216
+ let out = changetype<String>(__new(size, idof<String>()));
217
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + (intStart << 1), size);
218
+ return out;
219
+ }
220
+
221
+ substring(start: i32, end: i32 = i32.MAX_VALUE): String {
222
+ let len: isize = this.length;
223
+ let finalStart = min<isize>(max(start, 0), len);
224
+ let finalEnd = min<isize>(max(end, 0), len);
225
+ let fromPos = min<isize>(finalStart, finalEnd) << 1;
226
+ let toPos = max<isize>(finalStart, finalEnd) << 1;
227
+ let size = toPos - fromPos;
228
+ if (!size) return changetype<String>("");
229
+ if (!fromPos && toPos == len << 1) return this;
230
+ let out = changetype<String>(__new(size, idof<String>()));
231
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + fromPos, size);
232
+ return out;
233
+ }
234
+
235
+ trim(): String {
236
+ let len = this.length;
237
+ let size: usize = len << 1;
238
+ while (size && isSpace(load<u16>(changetype<usize>(this) + size - 2))) {
239
+ size -= 2;
240
+ }
241
+ let offset: usize = 0;
242
+ while (offset < size && isSpace(load<u16>(changetype<usize>(this) + offset))) {
243
+ offset += 2; size -= 2;
244
+ }
245
+ if (!size) return changetype<String>("");
246
+ if (!offset && size == len << 1) return this;
247
+ let out = changetype<String>(__new(size, idof<String>()));
248
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + offset, size);
249
+ return out;
250
+ }
251
+
252
+ @inline
253
+ trimLeft(): String {
254
+ return this.trimStart();
255
+ }
256
+
257
+ @inline
258
+ trimRight(): String {
259
+ return this.trimEnd();
260
+ }
261
+
262
+ trimStart(): String {
263
+ let size = <usize>this.length << 1;
264
+ let offset: usize = 0;
265
+ while (offset < size && isSpace(load<u16>(changetype<usize>(this) + offset))) {
266
+ offset += 2;
267
+ }
268
+ if (!offset) return this;
269
+ size -= offset;
270
+ if (!size) return changetype<String>("");
271
+ let out = changetype<String>(__new(size, idof<String>()));
272
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + offset, size);
273
+ return out;
274
+ }
275
+
276
+ trimEnd(): String {
277
+ let originalSize = <usize>this.length << 1;
278
+ let size = originalSize;
279
+ while (size && isSpace(load<u16>(changetype<usize>(this) + size - 2))) {
280
+ size -= 2;
281
+ }
282
+ if (!size) return changetype<String>("");
283
+ if (size == originalSize) return this;
284
+ let out = changetype<String>(__new(size, idof<String>()));
285
+ memory.copy(changetype<usize>(out), changetype<usize>(this), size);
286
+ return out;
287
+ }
288
+
289
+ padStart(length: i32, pad: string = " "): String {
290
+ let thisSize = <usize>this.length << 1;
291
+ let targetSize = <usize>length << 1;
292
+ let padSize = <usize>pad.length << 1;
293
+ if (targetSize < thisSize || !padSize) return this;
294
+ let prependSize = targetSize - thisSize;
295
+ let out = changetype<String>(__new(targetSize, idof<String>()));
296
+ if (prependSize > padSize) {
297
+ let repeatCount = (prependSize - 2) / padSize;
298
+ let restBase = repeatCount * padSize;
299
+ let restSize = prependSize - restBase;
300
+ memory.repeat(changetype<usize>(out), changetype<usize>(pad), padSize, repeatCount);
301
+ memory.copy(changetype<usize>(out) + restBase, changetype<usize>(pad), restSize);
302
+ } else {
303
+ memory.copy(changetype<usize>(out), changetype<usize>(pad), prependSize);
304
+ }
305
+ memory.copy(changetype<usize>(out) + prependSize, changetype<usize>(this), thisSize);
306
+ return out;
307
+ }
308
+
309
+ padEnd(length: i32, pad: string = " "): String {
310
+ let thisSize = <usize>this.length << 1;
311
+ let targetSize = <usize>length << 1;
312
+ let padSize = <usize>pad.length << 1;
313
+ if (targetSize < thisSize || !padSize) return this;
314
+ let appendSize = targetSize - thisSize;
315
+ let out = changetype<String>(__new(targetSize, idof<String>()));
316
+ memory.copy(changetype<usize>(out), changetype<usize>(this), thisSize);
317
+ if (appendSize > padSize) {
318
+ let repeatCount = (appendSize - 2) / padSize;
319
+ let restBase = repeatCount * padSize;
320
+ let restSize = appendSize - restBase;
321
+ memory.repeat(changetype<usize>(out) + thisSize, changetype<usize>(pad), padSize, repeatCount);
322
+ memory.copy(changetype<usize>(out) + thisSize + restBase, changetype<usize>(pad), restSize);
323
+ } else {
324
+ memory.copy(changetype<usize>(out) + thisSize, changetype<usize>(pad), appendSize);
325
+ }
326
+ return out;
327
+ }
328
+
329
+ repeat(count: i32 = 0): String {
330
+ let length = this.length;
331
+
332
+ // Most browsers can't handle strings 1 << 28 chars or longer
333
+ if (count < 0 || <u64>length * count > (1 << 28)) {
334
+ throw new RangeError(E_INVALIDLENGTH);
335
+ }
336
+
337
+ if (count == 0 || !length) return changetype<String>("");
338
+ if (count == 1) return this;
339
+ let out = changetype<String>(__new((length * count) << 1, idof<String>()));
340
+ memory.repeat(changetype<usize>(out), changetype<usize>(this), <usize>length << 1, count);
341
+ return out;
342
+ }
343
+
344
+ replace(search: String, replacement: String): String {
345
+ let len: usize = this.length;
346
+ let slen: usize = search.length;
347
+ if (len <= slen) {
348
+ return len < slen ? this : select<String>(replacement, this, search == this);
349
+ }
350
+ let index: isize = this.indexOf(search);
351
+ if (~index) {
352
+ let rlen: usize = replacement.length;
353
+ len -= slen;
354
+ let olen = len + rlen;
355
+ if (olen) {
356
+ let out = changetype<String>(__new(olen << 1, idof<String>()));
357
+ memory.copy(changetype<usize>(out), changetype<usize>(this), index << 1);
358
+ memory.copy(
359
+ changetype<usize>(out) + (index << 1),
360
+ changetype<usize>(replacement),
361
+ rlen << 1
362
+ );
363
+ memory.copy(
364
+ changetype<usize>(out) + ((index + rlen) << 1),
365
+ changetype<usize>(this) + ((index + slen) << 1),
366
+ (len - index) << 1
367
+ );
368
+ return out;
369
+ }
370
+ }
371
+ return this;
372
+ }
373
+
374
+ replaceAll(search: String, replacement: String): String {
375
+ let thisLen: usize = this.length;
376
+ let searchLen: usize = search.length;
377
+ if (thisLen <= searchLen) {
378
+ return thisLen < searchLen
379
+ ? this
380
+ : select<String>(replacement, this, search == this);
381
+ }
382
+ let replaceLen: usize = replacement.length;
383
+ if (!searchLen) {
384
+ if (!replaceLen) return this;
385
+ // Special case: 'abc'.replaceAll('', '-') -> '-a-b-c-'
386
+ let out = changetype<String>(__new((thisLen + (thisLen + 1) * replaceLen) << 1, idof<String>()));
387
+ memory.copy(changetype<usize>(out), changetype<usize>(replacement), replaceLen << 1);
388
+ let offset = replaceLen;
389
+ for (let i: usize = 0; i < thisLen; ++i) {
390
+ store<u16>(
391
+ changetype<usize>(out) + (offset++ << 1),
392
+ load<u16>(changetype<usize>(this) + (i << 1))
393
+ );
394
+ memory.copy(
395
+ changetype<usize>(out) + (offset << 1),
396
+ changetype<usize>(replacement),
397
+ replaceLen << 1
398
+ );
399
+ offset += replaceLen;
400
+ }
401
+ return out;
402
+ }
403
+ let prev: isize = 0, next: isize = 0;
404
+ if (searchLen == replaceLen) {
405
+ // Fast path when search and replacement have same length
406
+ let outSize = thisLen << 1;
407
+ let out = changetype<String>(__new(outSize, idof<String>()));
408
+ memory.copy(changetype<usize>(out), changetype<usize>(this), outSize);
409
+ while (~(next = <isize>this.indexOf(search, <i32>prev))) {
410
+ memory.copy(changetype<usize>(out) + (next << 1), changetype<usize>(replacement), replaceLen << 1);
411
+ prev = next + searchLen;
412
+ }
413
+ return out;
414
+ }
415
+ let out: String | null = null, offset: usize = 0, outSize = thisLen;
416
+ while (~(next = <isize>this.indexOf(search, <i32>prev))) {
417
+ if (!out) out = changetype<String>(__new(thisLen << 1, idof<String>()));
418
+ let chunk = next - prev;
419
+ if (offset + chunk + replaceLen > outSize) {
420
+ outSize <<= 1;
421
+ out = changetype<String>(__renew(changetype<usize>(out), outSize << 1));
422
+ }
423
+ memory.copy(
424
+ changetype<usize>(out) + (offset << 1),
425
+ changetype<usize>(this) + (prev << 1),
426
+ chunk << 1
427
+ );
428
+ offset += chunk;
429
+ memory.copy(
430
+ changetype<usize>(out) + (offset << 1),
431
+ changetype<usize>(replacement),
432
+ replaceLen << 1
433
+ );
434
+ offset += replaceLen;
435
+ prev = next + searchLen;
436
+ }
437
+ if (out) {
438
+ let rest = thisLen - prev;
439
+ if (offset + rest > outSize) {
440
+ outSize <<= 1;
441
+ out = changetype<String>(__renew(changetype<usize>(out), outSize << 1));
442
+ }
443
+ if (rest) {
444
+ memory.copy(
445
+ changetype<usize>(out) + (offset << 1),
446
+ changetype<usize>(this) + (prev << 1),
447
+ rest << 1
448
+ );
449
+ }
450
+ rest += offset;
451
+ if (outSize > rest) {
452
+ out = changetype<String>(__renew(changetype<usize>(out), rest << 1));
453
+ }
454
+ return out;
455
+ }
456
+ return this;
457
+ }
458
+
459
+ slice(start: i32, end: i32 = i32.MAX_VALUE): String {
460
+ let len = this.length;
461
+ start = start < 0 ? max(start + len, 0) : min(start, len);
462
+ end = end < 0 ? max(end + len, 0) : min(end, len);
463
+ len = end - start;
464
+ if (len <= 0) return changetype<String>("");
465
+ let out = changetype<String>(__new(len << 1, idof<String>()));
466
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + (<usize>start << 1), <usize>len << 1);
467
+ return out;
468
+ }
469
+
470
+ split(separator: String | null = null, limit: i32 = i32.MAX_VALUE): String[] {
471
+ if (!limit) return changetype<String[]>(__newArray(0, alignof<String>(), idof<Array<String>>()));
472
+ if (changetype<usize>(separator) == 0) return [ this ];
473
+ let length: isize = this.length;
474
+ let sepLen = changetype<string>(separator).length;
475
+ if (limit < 0) limit = i32.MAX_VALUE;
476
+ if (!sepLen) {
477
+ if (!length) return changetype<String[]>(__newArray(0, alignof<String>(), idof<Array<String>>()));
478
+ // split by chars
479
+ length = min<isize>(length, <isize>limit);
480
+ let result = changetype<String[]>(__newArray(<i32>length, alignof<String>(), idof<Array<String>>()));
481
+ // @ts-ignore: cast
482
+ let resultStart = result.dataStart as usize;
483
+ for (let i: isize = 0; i < length; ++i) {
484
+ let charStr = changetype<String>(__new(2, idof<String>()));
485
+ store<u16>(changetype<usize>(charStr), load<u16>(changetype<usize>(this) + (<usize>i << 1)));
486
+ store<usize>(resultStart + (<usize>i << alignof<usize>()), changetype<usize>(charStr)); // result[i] = charStr
487
+ __link(changetype<usize>(result), changetype<usize>(charStr), true);
488
+ }
489
+ return result;
490
+ } else if (!length) {
491
+ let result = changetype<String[]>(__newArray(1, alignof<String>(), idof<Array<String>>()));
492
+ // @ts-ignore: cast
493
+ store<usize>(result.dataStart as usize, changetype<usize>("")); // static ""
494
+ return result;
495
+ }
496
+ let result = changetype<String[]>(__newArray(0, alignof<String>(), idof<Array<String>>()));
497
+ let end = 0, start = 0, i = 0;
498
+ while (~(end = this.indexOf(changetype<string>(separator), start))) {
499
+ let len = end - start;
500
+ if (len > 0) {
501
+ let out = changetype<String>(__new(<usize>len << 1, idof<String>()));
502
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + (<usize>start << 1), <usize>len << 1);
503
+ result.push(out);
504
+ } else {
505
+ result.push(changetype<String>(""));
506
+ }
507
+ if (++i == limit) return result;
508
+ start = end + sepLen;
509
+ }
510
+ if (!start) { // also means: loop above didn't do anything
511
+ result.push(this);
512
+ return result;
513
+ }
514
+ let len = length - start;
515
+ if (len > 0) {
516
+ let out = changetype<String>(__new(<usize>len << 1, idof<String>()));
517
+ memory.copy(changetype<usize>(out), changetype<usize>(this) + (<usize>start << 1), <usize>len << 1);
518
+ result.push(out);
519
+ } else {
520
+ result.push(changetype<String>("")); // static ""
521
+ }
522
+ return result;
523
+ }
524
+
525
+ toLowerCase(): String {
526
+ let len = <usize>this.length;
527
+ if (!len) return this;
528
+ let codes = changetype<String>(__new(len * 2 * 2, idof<String>()));
529
+ let j: usize = 0;
530
+ for (let i: usize = 0; i < len; ++i, ++j) {
531
+ let c = <u32>load<u16>(changetype<usize>(this) + (i << 1));
532
+ if (isAscii(c)) {
533
+ store<u16>(changetype<usize>(codes) + (j << 1), toLower8(c));
534
+ } else {
535
+ // check and read surrogate pair
536
+ if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {
537
+ let c1 = <u32>load<u16>(changetype<usize>(this) + (i << 1), 2);
538
+ if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {
539
+ let c0 = c;
540
+ c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;
541
+ ++i;
542
+ if (c >= 0x20000) {
543
+ store<u32>(changetype<usize>(codes) + (j << 1), c0 | (c1 << 16));
544
+ ++j;
545
+ continue;
546
+ }
547
+ }
548
+ }
549
+ // check special casing for lower table. It has one ently so instead lookup we just inline this.
550
+ if (c == 0x0130) {
551
+ // 0x0130 -> [0x0069, 0x0307]
552
+ store<u32>(changetype<usize>(codes) + (j << 1), (0x0307 << 16) | 0x0069);
553
+ ++j;
554
+ } else if (c == 0x03A3) { // 'Σ'
555
+ // Σ maps to σ but except at the end of a word where it maps to ς
556
+ let sigma = 0x03C3; // σ
557
+ if (len > 1 && isFinalSigma(changetype<usize>(this), i, len)) {
558
+ sigma = 0x03C2; // ς
559
+ }
560
+ store<u16>(changetype<usize>(codes) + (j << 1), sigma);
561
+ } else if (c - 0x24B6 <= 0x24CF - 0x24B6) {
562
+ // Range 0x24B6 <= c <= 0x24CF not covered by casemap and require special early handling
563
+ store<u16>(changetype<usize>(codes) + (j << 1), c + 26);
564
+ } else {
565
+ let code = casemap(c, 0) & 0x1FFFFF;
566
+ if (code < 0x10000) {
567
+ store<u16>(changetype<usize>(codes) + (j << 1), code);
568
+ } else {
569
+ // store as surrogare pair
570
+ code -= 0x10000;
571
+ let lo = (code >>> 10) | 0xD800;
572
+ let hi = (code & 0x03FF) | 0xDC00;
573
+ store<u32>(changetype<usize>(codes) + (j << 1), lo | (hi << 16));
574
+ ++j;
575
+ }
576
+ }
577
+ }
578
+ }
579
+ return changetype<String>(__renew(changetype<usize>(codes), j << 1));
580
+ }
581
+
582
+ toUpperCase(): String {
583
+ let len = <usize>this.length;
584
+ if (!len) return this;
585
+ let codes = changetype<String>(__new(len * 3 * 2, idof<String>()));
586
+ let specialsPtr = changetype<usize>(SPECIALS_UPPER);
587
+ let specialsLen = SPECIALS_UPPER.length;
588
+ let j: usize = 0;
589
+ for (let i: usize = 0; i < len; ++i, ++j) {
590
+ let c = <u32>load<u16>(changetype<usize>(this) + (i << 1));
591
+ if (isAscii(c)) {
592
+ store<u16>(changetype<usize>(codes) + (j << 1), toUpper8(c));
593
+ } else {
594
+ // check and read surrogate pair
595
+ if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {
596
+ let c1 = <u32>load<u16>(changetype<usize>(this) + (i << 1), 2);
597
+ if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {
598
+ let c0 = c;
599
+ c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;
600
+ ++i;
601
+ if (c >= 0x20000) {
602
+ store<u32>(changetype<usize>(codes) + (j << 1), c0 | (c1 << 16));
603
+ ++j;
604
+ continue;
605
+ }
606
+ }
607
+ }
608
+ // Range 0x24D0 <= c <= 0x24E9 not covered by casemap and require special early handling
609
+ if (c - 0x24D0 <= 0x24E9 - 0x24D0) {
610
+ // monkey patch
611
+ store<u16>(changetype<usize>(codes) + (j << 1), c - 26);
612
+ } else {
613
+ let index: usize = -1;
614
+ // Fast range check. See first and last rows in specialsUpper table
615
+ if (c - 0x00DF <= 0xFB17 - 0x00DF) {
616
+ index = <usize>bsearch(c, specialsPtr, specialsLen);
617
+ }
618
+ if (~index) {
619
+ // load next 3 code points from row with `index` offset for specialsUpper table
620
+ let ab = load<u32>(specialsPtr + (index << 1), 2);
621
+ let cc = load<u16>(specialsPtr + (index << 1), 6);
622
+ store<u32>(changetype<usize>(codes) + (j << 1), ab, 0);
623
+ store<u16>(changetype<usize>(codes) + (j << 1), cc, 4);
624
+ j += 1 + usize(cc != 0);
625
+ } else {
626
+ let code = casemap(c, 1) & 0x1FFFFF;
627
+ if (code < 0x10000) {
628
+ store<u16>(changetype<usize>(codes) + (j << 1), code);
629
+ } else {
630
+ // store as surrogare pair
631
+ code -= 0x10000;
632
+ let lo = (code >>> 10) | 0xD800;
633
+ let hi = (code & 0x03FF) | 0xDC00;
634
+ store<u32>(changetype<usize>(codes) + (j << 1), lo | (hi << 16));
635
+ ++j;
636
+ }
637
+ }
638
+ }
639
+ }
640
+ }
641
+ return changetype<String>(__renew(changetype<usize>(codes), j << 1));
642
+ }
643
+
644
+ toString(): String {
645
+ return this;
646
+ }
647
+ }
648
+
649
+ // @ts-ignore: nolib
650
+ export type string = String;
651
+
652
+ export function parseInt(str: string, radix: i32 = 0): f64 {
653
+ return strtol<f64>(str, radix);
654
+ }
655
+
656
+ export function parseFloat(str: string): f64 {
657
+ return strtod(str);
658
+ }
659
+
660
+ // Encoding helpers
661
+ export namespace String {
662
+
663
+ export namespace UTF8 {
664
+
665
+ export const enum ErrorMode {
666
+ WTF8,
667
+ REPLACE,
668
+ ERROR
669
+ }
670
+
671
+ export function byteLength(str: string, nullTerminated: bool = false): i32 {
672
+ let strOff = changetype<usize>(str);
673
+ let strEnd = strOff + <usize>changetype<OBJECT>(changetype<usize>(str) - TOTAL_OVERHEAD).rtSize;
674
+ let bufLen = i32(nullTerminated);
675
+ while (strOff < strEnd) {
676
+ let c1 = <u32>load<u16>(strOff);
677
+ if (c1 < 128) {
678
+ // @ts-ignore: cast
679
+ if (nullTerminated & !c1) break;
680
+ bufLen += 1;
681
+ } else if (c1 < 2048) {
682
+ bufLen += 2;
683
+ } else {
684
+ if ((c1 & 0xFC00) == 0xD800 && strOff + 2 < strEnd) {
685
+ if ((<u32>load<u16>(strOff, 2) & 0xFC00) == 0xDC00) {
686
+ bufLen += 4; strOff += 4;
687
+ continue;
688
+ }
689
+ }
690
+ bufLen += 3;
691
+ }
692
+ strOff += 2;
693
+ }
694
+ return bufLen;
695
+ }
696
+
697
+ export function encode(str: string, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): ArrayBuffer {
698
+ let buf = changetype<ArrayBuffer>(__new(<usize>byteLength(str, nullTerminated), idof<ArrayBuffer>()));
699
+ encodeUnsafe(changetype<usize>(str), str.length, changetype<usize>(buf), nullTerminated, errorMode);
700
+ return buf;
701
+ }
702
+
703
+ // @ts-ignore: decorator
704
+ @unsafe
705
+ export function encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): usize {
706
+ let strEnd = str + (<usize>len << 1);
707
+ let bufOff = buf;
708
+ while (str < strEnd) {
709
+ let c1 = <u32>load<u16>(str);
710
+ if (c1 < 128) {
711
+ store<u8>(bufOff, c1);
712
+ bufOff++;
713
+ // @ts-ignore: cast
714
+ if (nullTerminated & !c1) return bufOff - buf;
715
+ } else if (c1 < 2048) {
716
+ let b0 = c1 >> 6 | 192;
717
+ let b1 = c1 & 63 | 128;
718
+ store<u16>(bufOff, b1 << 8 | b0);
719
+ bufOff += 2;
720
+ } else {
721
+ // D800: 11011 0 0000000000 Lead
722
+ // DBFF: 11011 0 1111111111
723
+ // DC00: 11011 1 0000000000 Trail
724
+ // DFFF: 11011 1 1111111111
725
+ // F800: 11111 0 0000000000 Mask
726
+ // FC00: 11111 1 0000000000
727
+ if ((c1 & 0xF800) == 0xD800) {
728
+ if (c1 < 0xDC00 && str + 2 < strEnd) {
729
+ let c2 = <u32>load<u16>(str, 2);
730
+ if ((c2 & 0xFC00) == 0xDC00) {
731
+ c1 = 0x10000 + ((c1 & 0x03FF) << 10) | (c2 & 0x03FF);
732
+ let b0 = c1 >> 18 | 240;
733
+ let b1 = c1 >> 12 & 63 | 128;
734
+ let b2 = c1 >> 6 & 63 | 128;
735
+ let b3 = c1 & 63 | 128;
736
+ store<u32>(bufOff, b3 << 24 | b2 << 16 | b1 << 8 | b0);
737
+ bufOff += 4; str += 4;
738
+ continue;
739
+ }
740
+ }
741
+ if (errorMode != ErrorMode.WTF8) { // unlikely
742
+ if (errorMode == ErrorMode.ERROR) throw new Error(E_UNPAIRED_SURROGATE);
743
+ c1 = 0xFFFD;
744
+ }
745
+ }
746
+ let b0 = c1 >> 12 | 224;
747
+ let b1 = c1 >> 6 & 63 | 128;
748
+ let b2 = c1 & 63 | 128;
749
+ store<u16>(bufOff, b1 << 8 | b0);
750
+ store<u8>(bufOff, b2, 2);
751
+ bufOff += 3;
752
+ }
753
+ str += 2;
754
+ }
755
+ if (nullTerminated) {
756
+ store<u8>(bufOff++, 0);
757
+ }
758
+ return bufOff - buf;
759
+ }
760
+
761
+ export function decode(buf: ArrayBuffer, nullTerminated: bool = false): String {
762
+ return decodeUnsafe(changetype<usize>(buf), buf.byteLength, nullTerminated);
763
+ }
764
+
765
+ // @ts-ignore: decorator
766
+ @unsafe
767
+ export function decodeUnsafe(buf: usize, len: usize, nullTerminated: bool = false): String {
768
+ let bufOff = buf;
769
+ let bufEnd = buf + len;
770
+ assert(bufEnd >= bufOff); // guard wraparound
771
+ let str = changetype<String>(__new(len << 1, idof<String>())); // max is one u16 char per u8 byte
772
+ let strOff = changetype<usize>(str);
773
+ while (bufOff < bufEnd) {
774
+ let u0 = <u32>load<u8>(bufOff); ++bufOff;
775
+ if (!(u0 & 128)) {
776
+ // @ts-ignore: cast
777
+ if (nullTerminated & !u0) break;
778
+ store<u16>(strOff, u0);
779
+ } else {
780
+ if (bufEnd == bufOff) break;
781
+ let u1 = <u32>load<u8>(bufOff) & 63; ++bufOff;
782
+ if ((u0 & 224) == 192) {
783
+ store<u16>(strOff, (u0 & 31) << 6 | u1);
784
+ } else {
785
+ if (bufEnd == bufOff) break;
786
+ let u2 = <u32>load<u8>(bufOff) & 63; ++bufOff;
787
+ if ((u0 & 240) == 224) {
788
+ u0 = (u0 & 15) << 12 | u1 << 6 | u2;
789
+ } else {
790
+ if (bufEnd == bufOff) break;
791
+ u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | <u32>load<u8>(bufOff) & 63;
792
+ ++bufOff;
793
+ }
794
+ if (u0 < 0x10000) {
795
+ store<u16>(strOff, u0);
796
+ } else {
797
+ u0 -= 0x10000;
798
+ let lo = u0 >> 10 | 0xD800;
799
+ let hi = (u0 & 0x03FF) | 0xDC00;
800
+ store<u32>(strOff, lo | (hi << 16));
801
+ strOff += 2;
802
+ }
803
+ }
804
+ }
805
+ strOff += 2;
806
+ }
807
+ return changetype<String>(__renew(changetype<usize>(str), strOff - changetype<usize>(str)));
808
+ }
809
+ }
810
+
811
+ export namespace UTF16 {
812
+
813
+ export function byteLength(str: string): i32 {
814
+ return changetype<OBJECT>(changetype<usize>(str) - TOTAL_OVERHEAD).rtSize;
815
+ }
816
+
817
+ export function encode(str: string): ArrayBuffer {
818
+ let buf = changetype<ArrayBuffer>(__new(<usize>byteLength(str), idof<ArrayBuffer>()));
819
+ encodeUnsafe(changetype<usize>(str), str.length, changetype<usize>(buf));
820
+ return buf;
821
+ }
822
+
823
+ // @ts-ignore: decorator
824
+ @unsafe
825
+ export function encodeUnsafe(str: usize, len: i32, buf: usize): usize {
826
+ let size = <usize>len << 1;
827
+ memory.copy(buf, changetype<usize>(str), size);
828
+ return size;
829
+ }
830
+
831
+ export function decode(buf: ArrayBuffer): String {
832
+ return decodeUnsafe(changetype<usize>(buf), buf.byteLength);
833
+ }
834
+
835
+ // @ts-ignore: decorator
836
+ @unsafe
837
+ export function decodeUnsafe(buf: usize, len: usize): String {
838
+ let str = changetype<String>(__new(len &= ~1, idof<String>()));
839
+ memory.copy(changetype<usize>(str), buf, len);
840
+ return str;
841
+ }
842
+ }
843
+ }
844
+
845
+ export class TemplateStringsArray extends Array<string> {
846
+ readonly raw: string[];
847
+ }