rusteerio 0.0.0-stage → 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 (206) hide show
  1. package/CONTRIBUTING.md +73 -0
  2. package/Cargo.lock +1051 -0
  3. package/Cargo.toml +36 -0
  4. package/LICENSE +21 -0
  5. package/README.md +252 -2
  6. package/RELEASING.md +138 -0
  7. package/THIRD_PARTY_NOTICES.md +7443 -0
  8. package/build.rs +3 -0
  9. package/dist/chunk-DKULX6VO.mjs +3185 -0
  10. package/dist/chunk-DKULX6VO.mjs.map +1 -0
  11. package/dist/chunk-OHPGEY3E.mjs +32 -0
  12. package/dist/chunk-OHPGEY3E.mjs.map +1 -0
  13. package/dist/index.cjs +3230 -0
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/index.d.mts +113 -0
  16. package/dist/index.d.ts +113 -0
  17. package/dist/index.mjs +38 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/slim.cjs +2441 -0
  20. package/dist/slim.cjs.map +1 -0
  21. package/dist/slim.d.mts +11 -0
  22. package/dist/slim.d.ts +11 -0
  23. package/dist/slim.mjs +19 -0
  24. package/dist/slim.mjs.map +1 -0
  25. package/dist/types-BP6TpxE5.d.mts +532 -0
  26. package/dist/types-BP6TpxE5.d.ts +532 -0
  27. package/dist/utils.cjs +61 -0
  28. package/dist/utils.cjs.map +1 -0
  29. package/dist/utils.d.mts +13 -0
  30. package/dist/utils.d.ts +13 -0
  31. package/dist/utils.mjs +17 -0
  32. package/dist/utils.mjs.map +1 -0
  33. package/native/src/arena.rs +1781 -0
  34. package/native/src/attributes.rs +923 -0
  35. package/native/src/codec.rs +172 -0
  36. package/native/src/diagnostics.rs +1249 -0
  37. package/native/src/extraction.rs +226 -0
  38. package/native/src/gc.rs +166 -0
  39. package/native/src/hook_sink.rs +727 -0
  40. package/native/src/hook_stream.rs +513 -0
  41. package/native/src/lib.rs +2095 -0
  42. package/native/src/location.rs +392 -0
  43. package/native/src/runtime.rs +189 -0
  44. package/native/src/selector.rs +1287 -0
  45. package/native/src/sink.rs +261 -0
  46. package/native/src/stream.rs +334 -0
  47. package/native/src/tokenizer.rs +355 -0
  48. package/native/src/tracker.rs +232 -0
  49. package/native/vendor/README.md +25 -0
  50. package/native/vendor/html5ever-0.35.0/.cargo_vcs_info.json +6 -0
  51. package/native/vendor/html5ever-0.35.0/Cargo.lock +828 -0
  52. package/native/vendor/html5ever-0.35.0/Cargo.toml +85 -0
  53. package/native/vendor/html5ever-0.35.0/LICENSE-APACHE +201 -0
  54. package/native/vendor/html5ever-0.35.0/LICENSE-MIT +25 -0
  55. package/native/vendor/html5ever-0.35.0/README.md +60 -0
  56. package/native/vendor/html5ever-0.35.0/benches/html5ever.rs +86 -0
  57. package/native/vendor/html5ever-0.35.0/data/bench/lipsum-zh.html +19 -0
  58. package/native/vendor/html5ever-0.35.0/data/bench/lipsum.html +40 -0
  59. package/native/vendor/html5ever-0.35.0/data/bench/medium-fragment.html +24 -0
  60. package/native/vendor/html5ever-0.35.0/data/bench/small-fragment.html +7 -0
  61. package/native/vendor/html5ever-0.35.0/data/bench/strong.html +1 -0
  62. package/native/vendor/html5ever-0.35.0/data/bench/tiny-fragment.html +1 -0
  63. package/native/vendor/html5ever-0.35.0/examples/arena.rs +356 -0
  64. package/native/vendor/html5ever-0.35.0/examples/capi/tokenize.c +74 -0
  65. package/native/vendor/html5ever-0.35.0/examples/noop-tokenize.rs +47 -0
  66. package/native/vendor/html5ever-0.35.0/examples/noop-tree-builder.rs +132 -0
  67. package/native/vendor/html5ever-0.35.0/examples/print-tree-actions.rs +185 -0
  68. package/native/vendor/html5ever-0.35.0/examples/tokenize.rs +111 -0
  69. package/native/vendor/html5ever-0.35.0/src/driver.rs +148 -0
  70. package/native/vendor/html5ever-0.35.0/src/lib.rs +30 -0
  71. package/native/vendor/html5ever-0.35.0/src/macros.rs +34 -0
  72. package/native/vendor/html5ever-0.35.0/src/serialize/mod.rs +255 -0
  73. package/native/vendor/html5ever-0.35.0/src/tokenizer/char_ref/mod.rs +451 -0
  74. package/native/vendor/html5ever-0.35.0/src/tokenizer/interface.rs +99 -0
  75. package/native/vendor/html5ever-0.35.0/src/tokenizer/mod.rs +2305 -0
  76. package/native/vendor/html5ever-0.35.0/src/tokenizer/states.rs +97 -0
  77. package/native/vendor/html5ever-0.35.0/src/tree_builder/data.rs +170 -0
  78. package/native/vendor/html5ever-0.35.0/src/tree_builder/mod.rs +1848 -0
  79. package/native/vendor/html5ever-0.35.0/src/tree_builder/rules.rs +1494 -0
  80. package/native/vendor/html5ever-0.35.0/src/tree_builder/tag_sets.rs +114 -0
  81. package/native/vendor/html5ever-0.35.0/src/tree_builder/types.rs +91 -0
  82. package/native/vendor/html5ever-0.35.0/src/util/str.rs +52 -0
  83. package/native/vendor/html5gum-0.8.4/Cargo.lock +1006 -0
  84. package/native/vendor/html5gum-0.8.4/Cargo.toml +109 -0
  85. package/native/vendor/html5gum-0.8.4/LICENSE +19 -0
  86. package/native/vendor/html5gum-0.8.4/README.md +110 -0
  87. package/native/vendor/html5gum-0.8.4/benches/files/0050.html +2131 -0
  88. package/native/vendor/html5gum-0.8.4/benches/files/6D30.html +1004 -0
  89. package/native/vendor/html5gum-0.8.4/benches/files.rs +32 -0
  90. package/native/vendor/html5gum-0.8.4/benches/patterns.rs +31 -0
  91. package/native/vendor/html5gum-0.8.4/src/arrayvec.rs +29 -0
  92. package/native/vendor/html5gum-0.8.4/src/char_validator.rs +134 -0
  93. package/native/vendor/html5gum-0.8.4/src/emitters/callback.rs +676 -0
  94. package/native/vendor/html5gum-0.8.4/src/emitters/default.rs +207 -0
  95. package/native/vendor/html5gum-0.8.4/src/emitters/emitter.rs +344 -0
  96. package/native/vendor/html5gum-0.8.4/src/emitters/html5ever.rs +306 -0
  97. package/native/vendor/html5gum-0.8.4/src/emitters/mod.rs +25 -0
  98. package/native/vendor/html5gum-0.8.4/src/entities.rs +3342 -0
  99. package/native/vendor/html5gum-0.8.4/src/error.rs +96 -0
  100. package/native/vendor/html5gum-0.8.4/src/htmlstring.rs +130 -0
  101. package/native/vendor/html5gum-0.8.4/src/lib.rs +66 -0
  102. package/native/vendor/html5gum-0.8.4/src/machine.rs +2136 -0
  103. package/native/vendor/html5gum-0.8.4/src/machine_helper.rs +277 -0
  104. package/native/vendor/html5gum-0.8.4/src/read_helper.rs +244 -0
  105. package/native/vendor/html5gum-0.8.4/src/reader.rs +440 -0
  106. package/native/vendor/html5gum-0.8.4/src/span.rs +98 -0
  107. package/native/vendor/html5gum-0.8.4/src/state.rs +16 -0
  108. package/native/vendor/html5gum-0.8.4/src/testutils.rs +71 -0
  109. package/native/vendor/html5gum-0.8.4/src/tokenizer.rs +189 -0
  110. package/native/vendor/html5gum-0.8.4/src/utils.rs +88 -0
  111. package/native/vendor/markup5ever-0.35.0/.cargo_vcs_info.json +6 -0
  112. package/native/vendor/markup5ever-0.35.0/Cargo.toml +45 -0
  113. package/native/vendor/markup5ever-0.35.0/LICENSE-APACHE +201 -0
  114. package/native/vendor/markup5ever-0.35.0/LICENSE-MIT +25 -0
  115. package/native/vendor/markup5ever-0.35.0/interface/mod.rs +422 -0
  116. package/native/vendor/markup5ever-0.35.0/interface/tree_builder.rs +280 -0
  117. package/native/vendor/markup5ever-0.35.0/lib.rs +59 -0
  118. package/native/vendor/markup5ever-0.35.0/serialize.rs +77 -0
  119. package/native/vendor/markup5ever-0.35.0/util/buffer_queue.rs +333 -0
  120. package/native/vendor/markup5ever-0.35.0/util/smallcharset.rs +88 -0
  121. package/package.json +137 -4
  122. package/rusteerio.darwin-arm64.node +0 -0
  123. package/rusteerio.darwin-x64.node +0 -0
  124. package/rusteerio.linux-arm64-gnu.node +0 -0
  125. package/rusteerio.linux-arm64-musl.node +0 -0
  126. package/rusteerio.linux-x64-gnu.node +0 -0
  127. package/rusteerio.linux-x64-musl.node +0 -0
  128. package/rusteerio.win32-arm64-msvc.node +0 -0
  129. package/rusteerio.win32-x64-msvc.node +0 -0
  130. package/scripts/check-native.mjs +15 -0
  131. package/scripts/check-release.mjs +235 -0
  132. package/scripts/fix-declarations.mjs +27 -0
  133. package/scripts/generate-notices.mjs +176 -0
  134. package/scripts/notices/README.md +13 -0
  135. package/scripts/notices/cheerio-MIT.txt +21 -0
  136. package/scripts/notices/html5ever-AUTHORS.txt +20 -0
  137. package/scripts/notices/html5ever-COPYRIGHT.txt +8 -0
  138. package/scripts/notices/html5ever-LICENSE-APACHE.txt +201 -0
  139. package/scripts/notices/html5ever-LICENSE-MIT.txt +25 -0
  140. package/scripts/notices/napi-rs-MIT.txt +43 -0
  141. package/scripts/notices/neon-MIT.txt +19 -0
  142. package/scripts/notices/runtime-01c266bced4a434da005.txt +3 -0
  143. package/scripts/notices/runtime-0a54e647fe54104658b5.txt +14 -0
  144. package/scripts/notices/runtime-0b74dfa0bcee5c420c6b.txt +25 -0
  145. package/scripts/notices/runtime-0d542e0c8804e39aa7f3.txt +177 -0
  146. package/scripts/notices/runtime-0f96a83840e146e43c0e.txt +21 -0
  147. package/scripts/notices/runtime-123a331b5dbf04c30097.txt +25 -0
  148. package/scripts/notices/runtime-172020dbfd5b53a226df.txt +34 -0
  149. package/scripts/notices/runtime-209fbbe0ad52d9235e37.txt +26 -0
  150. package/scripts/notices/runtime-23f18e03dc49df91622f.txt +23 -0
  151. package/scripts/notices/runtime-268872b9816f90fd8e85.txt +220 -0
  152. package/scripts/notices/runtime-35242e7a83f69875e6ed.txt +176 -0
  153. package/scripts/notices/runtime-378f5840b258e2779c39.txt +25 -0
  154. package/scripts/notices/runtime-4108245a1f2df9d4e94d.txt +25 -0
  155. package/scripts/notices/runtime-4455bf75a91154108304.txt +21 -0
  156. package/scripts/notices/runtime-553fffcd9b1cb158bc3e.txt +13 -0
  157. package/scripts/notices/runtime-62c7a1e35f56406896d7.txt +176 -0
  158. package/scripts/notices/runtime-6485b8ed310d3f0340bf.txt +25 -0
  159. package/scripts/notices/runtime-69fef7b0f322a6555415.txt +201 -0
  160. package/scripts/notices/runtime-6df43f6f4b5d4587f3d8.txt +187 -0
  161. package/scripts/notices/runtime-799e9ca9d179295ef372.txt +24 -0
  162. package/scripts/notices/runtime-7b63ecd5f1902af1b637.txt +25 -0
  163. package/scripts/notices/runtime-7bc7d5de2a0b793d4e1a.txt +21 -0
  164. package/scripts/notices/runtime-7e12e5df4bae12cb2158.txt +24 -0
  165. package/scripts/notices/runtime-861399f8c21c042b1105.txt +12 -0
  166. package/scripts/notices/runtime-8ada45cd9f843acf64e4.txt +201 -0
  167. package/scripts/notices/runtime-90eb64f0279b0d9432ac.txt +12 -0
  168. package/scripts/notices/runtime-a60eea817514531668d7.txt +201 -0
  169. package/scripts/notices/runtime-a7c936ff1ed8fa340172.txt +25 -0
  170. package/scripts/notices/runtime-ab6eec6caf0fa5775e41.txt +275 -0
  171. package/scripts/notices/runtime-b1181a40b2a7b25cf66f.txt +19 -0
  172. package/scripts/notices/runtime-b71bd43a069ca0641a9e.txt +25 -0
  173. package/scripts/notices/runtime-c16f8dcf1a368b83be78.txt +201 -0
  174. package/scripts/notices/runtime-c2cfccb812fe482101a8.txt +21 -0
  175. package/scripts/notices/runtime-e99d88d232bf57d70f0f.txt +25 -0
  176. package/scripts/notices/runtime-f32fb3b417a194167cfa.txt +9 -0
  177. package/scripts/notices/runtime-f5062c9a188d81dfe66b.txt +39 -0
  178. package/scripts/notices/runtime-f9070a832833fa7488fd.txt +4 -0
  179. package/scripts/notices/runtime-fab3dd6bdab226f1c086.txt +373 -0
  180. package/scripts/notices/runtime-fba3318d0c600380177e.txt +62 -0
  181. package/scripts/notices/runtime-ff8f68cb076caf8cefe7.txt +25 -0
  182. package/scripts/notices/runtime-ff92bed461f50338dd70.txt +74 -0
  183. package/scripts/notices/runtime.json +1632 -0
  184. package/scripts/notices/sources.json +555 -0
  185. package/scripts/notices/xray-MIT.txt +21 -0
  186. package/src/attributes.ts +271 -0
  187. package/src/codec.ts +74 -0
  188. package/src/dom.ts +87 -0
  189. package/src/extract-plan.ts +97 -0
  190. package/src/extract.ts +130 -0
  191. package/src/hooks.ts +220 -0
  192. package/src/index.ts +223 -0
  193. package/src/io.ts +491 -0
  194. package/src/native.ts +135 -0
  195. package/src/nodes.ts +290 -0
  196. package/src/parse.ts +53 -0
  197. package/src/parser-types.ts +157 -0
  198. package/src/router.ts +327 -0
  199. package/src/selection.ts +566 -0
  200. package/src/slim.ts +12 -0
  201. package/src/transport.ts +104 -0
  202. package/src/types.ts +186 -0
  203. package/src/utils.ts +29 -0
  204. package/src/workers.ts +21 -0
  205. package/tsconfig.json +15 -0
  206. package/tsup.config.ts +16 -0
package/dist/slim.cjs ADDED
@@ -0,0 +1,2441 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/slim.ts
21
+ var slim_exports = {};
22
+ __export(slim_exports, {
23
+ contains: () => contains,
24
+ dom: () => dom,
25
+ load: () => load2,
26
+ merge: () => merge
27
+ });
28
+ module.exports = __toCommonJS(slim_exports);
29
+
30
+ // src/native.ts
31
+ var import_node_module = require("module");
32
+ var import_node_fs = require("fs");
33
+ var import_node_path = require("path");
34
+ var import_node_url = require("url");
35
+
36
+ // src/codec.ts
37
+ var reserved = /[\ud800-\ue800]/;
38
+ var encoded = /[\ue000-\ue800]/;
39
+ var escapeUnit = 59392;
40
+ var isWellFormed = String.prototype.isWellFormed;
41
+ function encodeString(value) {
42
+ if (!encoded.test(value) && (isWellFormed ? isWellFormed.call(value) : !reserved.test(value))) return value;
43
+ const parts = [];
44
+ let start = 0;
45
+ for (let index = 0; index < value.length; index++) {
46
+ const unit = value.charCodeAt(index);
47
+ if (unit >= 55296 && unit <= 56319) {
48
+ const next = value.charCodeAt(index + 1);
49
+ if (next >= 56320 && next <= 57343) {
50
+ index++;
51
+ continue;
52
+ }
53
+ }
54
+ let replacement;
55
+ if (unit >= 55296 && unit <= 57343) replacement = String.fromCharCode(57344 + unit - 55296);
56
+ else if (unit >= 57344 && unit <= escapeUnit) replacement = "\uE800" + value[index];
57
+ if (replacement !== void 0) {
58
+ parts.push(value.slice(start, index), replacement);
59
+ start = index + 1;
60
+ }
61
+ }
62
+ return start === 0 ? value : parts.join("") + value.slice(start);
63
+ }
64
+ function decodeString(value) {
65
+ if (!encoded.test(value)) return value;
66
+ const parts = [];
67
+ let start = 0;
68
+ for (let index = 0; index < value.length; index++) {
69
+ const unit = value.charCodeAt(index);
70
+ if (unit < 57344 || unit > escapeUnit) continue;
71
+ const next = value.charCodeAt(index + 1);
72
+ if (unit === escapeUnit) {
73
+ if (next < 57344 || next > escapeUnit || Number.isNaN(next)) continue;
74
+ parts.push(value.slice(start, index), value[++index]);
75
+ } else parts.push(value.slice(start, index), String.fromCharCode(55296 + unit - 57344));
76
+ start = index + 1;
77
+ }
78
+ return start === 0 ? value : parts.join("") + value.slice(start);
79
+ }
80
+ var stringToken = /"(?:[^"\\]|\\[\s\S])*"/g;
81
+ var encodeJsonCandidate = /[\ud800-\ue800]|\\u(?:d[89a-f][\da-f]{2}|e[0-8][\da-f]{2})/i;
82
+ var escapedJsonCandidate = /\\u(?:d[89a-f][\da-f]{2}|e[0-8][\da-f]{2})/i;
83
+ var decodeJsonCandidate = /[\ue000-\ue800]|\\ue[0-8][\da-f]{2}/i;
84
+ function encodeJson(value) {
85
+ if (!encodeJsonCandidate.test(value)) return value;
86
+ if (isWellFormed?.call(value) && !encoded.test(value) && !escapedJsonCandidate.test(value)) return value;
87
+ return value.replace(stringToken, (token) => JSON.stringify(encodeString(JSON.parse(token))));
88
+ }
89
+ function decodeJson(value) {
90
+ return decodeJsonCandidate.test(value) ? value.replace(stringToken, (token) => JSON.stringify(decodeString(JSON.parse(token)))) : value;
91
+ }
92
+ function encodeOptions(value) {
93
+ if (value === void 0) return '{"__utf16Codec":true}';
94
+ const json = encodeJson(value);
95
+ if (!json.trimStart().startsWith("{")) return '{"__utf16Codec":true}';
96
+ const end = json.lastIndexOf("}");
97
+ const prefix = json.slice(0, end);
98
+ return prefix + (prefix.trimEnd().endsWith("{") ? "" : ",") + '"__utf16Codec":true' + json.slice(end);
99
+ }
100
+
101
+ // src/transport.ts
102
+ var registryKey = /* @__PURE__ */ Symbol.for("rusteerio.native-transport.v1");
103
+ var globals = globalThis;
104
+ var registry = globals[registryKey] ??= { documents: /* @__PURE__ */ new WeakMap(), originals: /* @__PURE__ */ new WeakMap(), userErrors: /* @__PURE__ */ new WeakSet() };
105
+ function wrapNativeBinding(binding) {
106
+ const raw = binding;
107
+ const { documents, originals, userErrors } = registry;
108
+ const restoreError = (error) => {
109
+ if (error instanceof Error && !userErrors.has(error)) {
110
+ const message = decodeString(error.message);
111
+ if (message !== error.message) {
112
+ const stack = error.stack;
113
+ error.message = message;
114
+ if (stack) error.stack = decodeString(stack);
115
+ }
116
+ }
117
+ throw error;
118
+ };
119
+ const invoke = (call) => {
120
+ try {
121
+ const result = call();
122
+ return result instanceof Promise ? result.catch(restoreError) : result;
123
+ } catch (error) {
124
+ return restoreError(error);
125
+ }
126
+ };
127
+ const wrapBridge = (bridge) => (request) => {
128
+ try {
129
+ return encodeJson(bridge(decodeJson(request)));
130
+ } catch (error) {
131
+ if (error !== null && (typeof error === "object" || typeof error === "function")) userErrors.add(error);
132
+ throw error;
133
+ }
134
+ };
135
+ const jsonMethods = /* @__PURE__ */ new Set(["op", "node", "exportTree", "parserDiagnostics", "adopt"]);
136
+ const wrapDocument = (document) => {
137
+ const cached2 = documents.get(document);
138
+ if (cached2) return cached2;
139
+ const methods = /* @__PURE__ */ new Map();
140
+ const wrapped2 = new Proxy(document, {
141
+ get(target, property2) {
142
+ const value = Reflect.get(target, property2, target);
143
+ if (typeof value !== "function") return value;
144
+ if (property2 === "constructor") return value;
145
+ if (methods.has(property2)) return methods.get(property2);
146
+ const method = (...input) => invoke(() => {
147
+ const args = input.slice();
148
+ if (property2 === "op") args[1] = encodeJson(args[1]);
149
+ else if (property2 === "create") {
150
+ args[0] = encodeString(args[0]);
151
+ if (typeof args[2] === "string") args[2] = encodeOptions(args[2]);
152
+ } else if (property2 === "select" || property2 === "matches") args[0] = encodeString(args[0]);
153
+ else if (property2 === "attr") args[1] = encodeString(args[1]);
154
+ else if (property2 === "adopt") args[0] = originals.get(args[0]) ?? args[0];
155
+ const result = Reflect.apply(value, target, args);
156
+ if (property2 === "op" && args[0] === "serialize" && typeof result === "string" && result.startsWith("{")) {
157
+ const error = JSON.parse(result).__nativeError;
158
+ if (error?.name === "URIError") throw new URIError(error.message);
159
+ }
160
+ return typeof result === "string" ? jsonMethods.has(String(property2)) ? decodeJson(result) : decodeString(result) : result;
161
+ });
162
+ methods.set(property2, method);
163
+ return method;
164
+ }
165
+ });
166
+ documents.set(document, wrapped2);
167
+ originals.set(wrapped2, document);
168
+ return wrapped2;
169
+ };
170
+ const wrapStream = (stream) => {
171
+ let carry = "";
172
+ return {
173
+ async write(chunk) {
174
+ let source = carry + chunk;
175
+ carry = "";
176
+ const last = source.charCodeAt(source.length - 1);
177
+ if (last >= 55296 && last <= 56319) {
178
+ carry = source.slice(-1);
179
+ source = source.slice(0, -1);
180
+ }
181
+ if (source) await invoke(() => stream.write(encodeString(source)));
182
+ },
183
+ async finish() {
184
+ if (carry) {
185
+ const final = carry;
186
+ carry = "";
187
+ await invoke(() => stream.write(encodeString(final)));
188
+ }
189
+ return wrapDocument(await invoke(() => stream.finish()));
190
+ },
191
+ abort() {
192
+ carry = "";
193
+ return invoke(() => stream.abort());
194
+ }
195
+ };
196
+ };
197
+ const wrapConstructor = (Constructor, argumentsFor, wrap) => new Proxy(Constructor, {
198
+ construct(target, args) {
199
+ return wrap(invoke(() => Reflect.construct(target, argumentsFor(args))));
200
+ }
201
+ });
202
+ const wrapped = { ...raw };
203
+ wrapped.NativeDocument = wrapConstructor(raw.NativeDocument, ([html, isDocument2, options]) => [encodeString(html), isDocument2, encodeOptions(options)], wrapDocument);
204
+ if (raw.NativeStream) wrapped.NativeStream = wrapConstructor(raw.NativeStream, ([options, isDocument2, bridge]) => [encodeOptions(options), isDocument2, bridge && wrapBridge(bridge)], wrapStream);
205
+ if (raw.NativeHookStream) wrapped.NativeHookStream = wrapConstructor(raw.NativeHookStream, ([isDocument2, options, bridge]) => [isDocument2, encodeOptions(options), wrapBridge(bridge)], wrapStream);
206
+ if (raw.parseWithTreeAdapter) wrapped.parseWithTreeAdapter = (source, isDocument2, options, bridge) => wrapDocument(invoke(() => raw.parseWithTreeAdapter(encodeString(source), isDocument2, encodeOptions(options), wrapBridge(bridge))));
207
+ if (raw.parseAsync) wrapped.parseAsync = async (source, isDocument2, options) => wrapDocument(await invoke(() => raw.parseAsync(encodeString(source), isDocument2, encodeOptions(options))));
208
+ if (raw.parseManyAsync) wrapped.parseManyAsync = async (sources, isDocument2, threads, options) => (await invoke(() => raw.parseManyAsync(sources.map(encodeString), isDocument2, threads, encodeOptions(options)))).map(wrapDocument);
209
+ if (raw.extractPlanManyAsync) wrapped.extractPlanManyAsync = async (sources, plan, threads, options) => decodeJson(await invoke(() => raw.extractPlanManyAsync(sources.map(encodeString), encodeJson(plan), threads, encodeOptions(options))));
210
+ if (raw.extractManyAsync) wrapped.extractManyAsync = async (sources, queries, threads, isDocument2, options) => decodeJson(await invoke(() => raw.extractManyAsync(sources.map(encodeString), queries.map((query) => ({ ...query, key: encodeString(query.key), selector: encodeString(query.selector), ...query.attr === void 0 ? {} : { attr: encodeString(query.attr) } })), threads, isDocument2, encodeOptions(options))));
211
+ return wrapped;
212
+ }
213
+
214
+ // src/native.ts
215
+ var import_meta = {};
216
+ var cached;
217
+ var attempted = false;
218
+ var bindingError;
219
+ function nativeBinding() {
220
+ if (attempted) return cached;
221
+ attempted = true;
222
+ const moduleDirectory = typeof __dirname === "string" ? __dirname : (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
223
+ const require2 = (0, import_node_module.createRequire)((0, import_node_path.join)(moduleDirectory, "rusteerio-loader.cjs"));
224
+ const directories = [moduleDirectory, (0, import_node_path.dirname)(moduleDirectory)];
225
+ const libc = process.platform === "linux" ? process.report?.getReport()?.header?.glibcVersionRuntime ? "gnu" : "musl" : void 0;
226
+ const platform = `${process.platform}-${process.arch}${libc ? `-${libc}` : process.platform === "win32" ? "-msvc" : ""}`;
227
+ const names = [`rusteerio.${platform}.node`, "rusteerio.node"];
228
+ const candidates = [...new Set(directories.flatMap((directory) => names.map((name) => (0, import_node_path.join)(directory, name))))];
229
+ for (const candidate of candidates) {
230
+ if (!(0, import_node_fs.existsSync)(candidate)) continue;
231
+ try {
232
+ const loaded = require2(candidate);
233
+ if (typeof loaded.NativeDocument === "function") {
234
+ cached = wrapNativeBinding(loaded);
235
+ return cached;
236
+ }
237
+ } catch (error) {
238
+ bindingError ??= error;
239
+ }
240
+ }
241
+ return void 0;
242
+ }
243
+ function requireNative() {
244
+ const binding = nativeBinding();
245
+ if (binding) return binding;
246
+ throw new Error('Rusteerio could not load its Rust native binding. Reinstall rusteerio for this platform or run "npm run build:native" from a source checkout.', { cause: bindingError });
247
+ }
248
+
249
+ // src/hooks.ts
250
+ var tokenCallbacks = ["onattribdata", "onattribentity", "onattribend", "onattribname", "oncdata", "onclosetag", "oncomment", "ondeclaration", "onend", "onopentagend", "onopentagname", "onprocessinginstruction", "onselfclosingtag", "ontext", "ontextentity"];
251
+ function createTokenizerSession(options) {
252
+ const events = [];
253
+ const callbacks = Object.fromEntries(tokenCallbacks.map((name) => [name, (...args) => {
254
+ if (name === "ontextentity" || name === "onattribentity") {
255
+ const codePoint = +args[0];
256
+ String.fromCodePoint(codePoint);
257
+ args[0] = codePoint;
258
+ }
259
+ events.push([name, ...args]);
260
+ }]));
261
+ const Constructor = options.Tokenizer;
262
+ const tokenizer = new Constructor(options, callbacks);
263
+ return {
264
+ write(chunk) {
265
+ if (tokenizer.running) tokenizer.write(chunk);
266
+ },
267
+ end() {
268
+ tokenizer.end();
269
+ const result = cleanParserOptions(options);
270
+ result.__tokenEvents = events;
271
+ return result;
272
+ }
273
+ };
274
+ }
275
+ function cleanParserOptions(options) {
276
+ const result = { ...options };
277
+ delete result.Tokenizer;
278
+ delete result.treeAdapter;
279
+ delete result.onParseError;
280
+ delete result.__tokenEvents;
281
+ if (!options._useHtmlParser2 && options.onParseError) {
282
+ result.__collectParseErrors = true;
283
+ result.sourceCodeLocationInfo = true;
284
+ }
285
+ return result;
286
+ }
287
+ function parserOptions(source, options) {
288
+ if (options._useHtmlParser2 && options.Tokenizer) {
289
+ const session = createTokenizerSession(options);
290
+ session.write(source);
291
+ return session.end();
292
+ }
293
+ return cleanParserOptions(options);
294
+ }
295
+ function deliverParseErrors(document, options) {
296
+ if (options._useHtmlParser2 || !options.onParseError) return;
297
+ const diagnostics = document.parserDiagnostics?.();
298
+ const errors = typeof diagnostics === "string" ? JSON.parse(diagnostics) : diagnostics ?? [];
299
+ for (const error of errors) options.onParseError(error);
300
+ }
301
+ function hasParserHooks(options) {
302
+ return !!(options._useHtmlParser2 ? options.Tokenizer : options.treeAdapter || options.onParseError);
303
+ }
304
+ function treeAdapterBridge(adapter, options) {
305
+ const deliveredErrors = /* @__PURE__ */ new Set();
306
+ const nodes = [];
307
+ const ids = /* @__PURE__ */ new WeakMap();
308
+ const identify = (node) => {
309
+ if (node == null) return null;
310
+ if (typeof node !== "object") throw new TypeError("treeAdapter methods must return DOM node objects");
311
+ let id = ids.get(node);
312
+ if (id === void 0) {
313
+ id = nodes.length;
314
+ ids.set(node, id);
315
+ nodes.push(node);
316
+ }
317
+ return id;
318
+ };
319
+ const nodeArgs = {
320
+ appendChild: [0, 1],
321
+ insertBefore: [0, 1, 2],
322
+ setTemplateContent: [0, 1],
323
+ getTemplateContent: [0],
324
+ setDocumentType: [0],
325
+ setDocumentMode: [0],
326
+ getDocumentMode: [0],
327
+ detachNode: [0],
328
+ insertText: [0],
329
+ insertTextBefore: [0, 2],
330
+ adoptAttributes: [0],
331
+ getFirstChild: [0],
332
+ getChildNodes: [0],
333
+ getParentNode: [0],
334
+ getAttrList: [0],
335
+ getTagName: [0],
336
+ getNamespaceURI: [0],
337
+ getTextNodeContent: [0],
338
+ getCommentNodeContent: [0],
339
+ getDocumentTypeNodeName: [0],
340
+ getDocumentTypeNodePublicId: [0],
341
+ getDocumentTypeNodeSystemId: [0],
342
+ isTextNode: [0],
343
+ isCommentNode: [0],
344
+ isElementNode: [0],
345
+ isDocumentTypeNode: [0],
346
+ setNodeSourceCodeLocation: [0],
347
+ getNodeSourceCodeLocation: [0],
348
+ updateNodeSourceCodeLocation: [0],
349
+ onItemPop: [0, 1],
350
+ onItemPush: [0]
351
+ };
352
+ const nodeReturns = /* @__PURE__ */ new Set(["createDocument", "createDocumentFragment", "createElement", "createCommentNode", "createTextNode", "getTemplateContent", "getFirstChild", "getParentNode"]);
353
+ const invoke = (method, args) => {
354
+ const fn = adapter[method];
355
+ if (typeof fn !== "function") {
356
+ if (method === "onItemPop" || method === "onItemPush") return void 0;
357
+ throw new TypeError(`treeAdapter.${method} must be a function`);
358
+ }
359
+ return Reflect.apply(fn, adapter, args);
360
+ };
361
+ const snapshot = () => {
362
+ const records = [];
363
+ for (let id = 0; id < nodes.length; id++) {
364
+ const node = nodes[id];
365
+ const element = invoke("isElementNode", [node]);
366
+ const text = invoke("isTextNode", [node]);
367
+ const comment = invoke("isCommentNode", [node]);
368
+ const doctype = invoke("isDocumentTypeNode", [node]);
369
+ const name = element ? invoke("getTagName", [node]) : doctype ? "!doctype" : node.name;
370
+ const type = element ? name === "script" || name === "style" ? name : "tag" : text ? "text" : comment ? "comment" : doctype ? "directive" : node.type ?? "root";
371
+ const children2 = element || type === "root" || type === "cdata" ? invoke("getChildNodes", [node]) ?? [] : [];
372
+ const record = { id, type, children: Array.from(children2, identify), parent: identify(invoke("getParentNode", [node])) };
373
+ if (name !== void 0) record.name = name;
374
+ if (element) {
375
+ record.namespace = invoke("getNamespaceURI", [node]);
376
+ record.attribs = /* @__PURE__ */ Object.create(null);
377
+ record.attribsNamespace = /* @__PURE__ */ Object.create(null);
378
+ record.attribsPrefix = /* @__PURE__ */ Object.create(null);
379
+ for (const attr2 of invoke("getAttrList", [node])) {
380
+ Object.defineProperty(record.attribs, attr2.name, { value: attr2.value, enumerable: true, configurable: true, writable: true });
381
+ record.attribsNamespace[attr2.name] = attr2.namespace;
382
+ record.attribsPrefix[attr2.name] = attr2.prefix;
383
+ }
384
+ } else if (text || comment) record.data = invoke(text ? "getTextNodeContent" : "getCommentNodeContent", [node]);
385
+ else if (doctype) {
386
+ record.data = node.data;
387
+ for (const [field, method] of [["x-name", "getDocumentTypeNodeName"], ["x-publicId", "getDocumentTypeNodePublicId"], ["x-systemId", "getDocumentTypeNodeSystemId"]]) record[field] = invoke(method, [node]);
388
+ }
389
+ if (type === "root" && node["x-mode"] !== void 0) record["x-mode"] = invoke("getDocumentMode", [node]);
390
+ for (const field of ["startIndex", "endIndex", "sourceCodeLocation"]) if (node[field] !== void 0) record[field] = node[field];
391
+ records.push(record);
392
+ }
393
+ return records;
394
+ };
395
+ const bridge = (request) => {
396
+ const { method, args = [] } = JSON.parse(request);
397
+ if (method === "__parseError") {
398
+ deliveredErrors.add(JSON.stringify(args[0]));
399
+ options.onParseError?.(args[0]);
400
+ return "null";
401
+ }
402
+ if (method === "__snapshot") return JSON.stringify(snapshot());
403
+ if (method === "__locations") {
404
+ for (const entry of args[0]) invoke("setNodeSourceCodeLocation", [nodes[entry.id], hydrateLocation(entry.location)]);
405
+ return "null";
406
+ }
407
+ const values = args.slice();
408
+ if (method === "setNodeSourceCodeLocation" || method === "updateNodeSourceCodeLocation") hydrateLocation(values[1]);
409
+ for (const index of nodeArgs[method] ?? []) values[index] = values[index] == null ? null : nodes[values[index]];
410
+ const result = invoke(method, values);
411
+ return JSON.stringify(method === "getChildNodes" ? Array.from(result ?? [], identify) : nodeReturns.has(method) ? identify(result) : result ?? null);
412
+ };
413
+ return { bridge, nodes, deliveredErrors };
414
+ }
415
+ function bindAdapterDocument(document, options, adapter) {
416
+ if (options.onParseError) {
417
+ const errors = document.parserDiagnostics?.();
418
+ for (const error of errors ? JSON.parse(errors) : []) if (!adapter.deliveredErrors.has(JSON.stringify(error))) options.onParseError(error);
419
+ }
420
+ const routed = routeDocument(document, options);
421
+ const globalId = routed.localNodeId.bind(routed);
422
+ for (let id = 0; id < adapter.nodes.length; id++) getNode(routed, globalId(id), adapter.nodes[id]);
423
+ return routed;
424
+ }
425
+ function parseNativeDocument(source, options, isDocument2) {
426
+ const binding = requireNative();
427
+ const nativeOptions = parserOptions(source, options);
428
+ if (!options._useHtmlParser2 && options.treeAdapter) {
429
+ const parse2 = binding.parseWithTreeAdapter;
430
+ if (!parse2) throw new Error("This native addon does not support treeAdapter hooks; rebuild the Rust addon.");
431
+ const adapter = treeAdapterBridge(options.treeAdapter, options);
432
+ return bindAdapterDocument(parse2(source, isDocument2, JSON.stringify(nativeOptions), adapter.bridge), options, adapter);
433
+ }
434
+ const document = new binding.NativeDocument(source, isDocument2, JSON.stringify(nativeOptions));
435
+ deliverParseErrors(document, options);
436
+ return routeDocument(document, options);
437
+ }
438
+
439
+ // src/router.ts
440
+ var registryKey2 = /* @__PURE__ */ Symbol.for("rusteerio.native-handles.v2");
441
+ var globals2 = globalThis;
442
+ var registry2 = globals2[registryKey2] ??= (() => {
443
+ const handles = /* @__PURE__ */ new Map();
444
+ const byDocument = /* @__PURE__ */ new WeakMap();
445
+ const snapshots = /* @__PURE__ */ new WeakMap();
446
+ const pending = [];
447
+ let scheduled = false;
448
+ const flush = () => {
449
+ scheduled = false;
450
+ const batches = /* @__PURE__ */ new Map();
451
+ for (const pin of pending.splice(0)) {
452
+ const document = pin.document.deref();
453
+ if (!document) continue;
454
+ const entries = byDocument.get(document);
455
+ if (entries?.get(pin.local)?.pin === pin) entries.delete(pin.local);
456
+ const ids = batches.get(document) ?? [];
457
+ ids.push(pin.local);
458
+ batches.set(document, ids);
459
+ }
460
+ for (const [document, ids] of batches) {
461
+ snapshots.delete(document);
462
+ document.release?.(ids);
463
+ document.collectGarbage?.();
464
+ }
465
+ };
466
+ return { next: 1, space: {}, handles, byDocument, snapshots, finalizer: new FinalizationRegistry((pin) => {
467
+ if (!handles.get(pin.global)?.deref()) handles.delete(pin.global);
468
+ pending.push(pin);
469
+ if (!scheduled) {
470
+ scheduled = true;
471
+ queueMicrotask(flush);
472
+ }
473
+ }) };
474
+ })();
475
+ function rawOperation(document, command, args) {
476
+ const result = document.op(command, JSON.stringify(args));
477
+ return result === "" || result === void 0 ? void 0 : JSON.parse(result);
478
+ }
479
+ function localMap(document) {
480
+ let map = registry2.byDocument.get(document);
481
+ if (!map) registry2.byDocument.set(document, map = /* @__PURE__ */ new Map());
482
+ return map;
483
+ }
484
+ function handleFor(document, local) {
485
+ const map = localMap(document);
486
+ let handle = map.get(local)?.reference.deref();
487
+ if (!handle || handle.document !== document || handle.local !== local) {
488
+ const pin = { global: registry2.next++, document: new WeakRef(document), local };
489
+ handle = { global: pin.global, document, local, pin };
490
+ document.retain?.([local]);
491
+ const reference = new WeakRef(handle);
492
+ map.set(local, { reference, pin });
493
+ registry2.handles.set(handle.global, reference);
494
+ registry2.finalizer.register(handle, pin);
495
+ }
496
+ return handle;
497
+ }
498
+ function retainNodes(document, ids) {
499
+ return document.retainNodes?.(ids) ?? {};
500
+ }
501
+ var RoutedDocument = class _RoutedDocument {
502
+ nodeSpace = registry2.space;
503
+ options;
504
+ anchor;
505
+ get raw() {
506
+ return this.anchor.document;
507
+ }
508
+ constructor(document, options = {}, anchor) {
509
+ this.options = options;
510
+ this.anchor = anchor ?? handleFor(document, document.rootId());
511
+ }
512
+ keep(handle) {
513
+ return handle.global;
514
+ }
515
+ lookup(id) {
516
+ const handle = registry2.handles.get(id)?.deref();
517
+ if (!handle) throw new RangeError(`Unknown native node handle ${id}`);
518
+ return handle;
519
+ }
520
+ global(document, local) {
521
+ return this.keep(handleFor(document, local));
522
+ }
523
+ globals(document, ids) {
524
+ return ids.map((id) => this.global(document, id));
525
+ }
526
+ retainNode(id) {
527
+ this.lookup(id);
528
+ }
529
+ retainNodes(ids) {
530
+ return ids.filter((id) => id !== void 0).map((id) => this.lookup(id));
531
+ }
532
+ nodeDocument(id) {
533
+ return new _RoutedDocument(this.raw, this.options, this.lookup(id));
534
+ }
535
+ collectGarbage() {
536
+ registry2.snapshots.delete(this.raw);
537
+ return this.raw.collectGarbage?.();
538
+ }
539
+ retainNodeData(id, data2) {
540
+ this.lookup(id).data = data2;
541
+ }
542
+ nodeData(id) {
543
+ return this.lookup(id).data;
544
+ }
545
+ nodeDataOperation(id) {
546
+ const handle = this.lookup(id);
547
+ const options = this.options;
548
+ return (command, args) => rawOperation(handle.document, command, { ...args, ids: [handle.local], options });
549
+ }
550
+ localNodeId(id) {
551
+ return this.global(this.raw, id);
552
+ }
553
+ rootId() {
554
+ return this.global(this.raw, this.raw.rootId());
555
+ }
556
+ record(document, record) {
557
+ if (!record) return null;
558
+ const view = { ...record, id: this.global(document, record.id) };
559
+ Object.defineProperty(view, "children", { enumerable: true, get: () => this.globals(document, record.children ?? []) });
560
+ for (const key of ["parent", "prev", "next"]) Object.defineProperty(view, key, { enumerable: true, get: () => record[key] == null ? null : this.global(document, record[key]) });
561
+ return view;
562
+ }
563
+ groups(ids) {
564
+ const groups = [];
565
+ for (const id of ids) {
566
+ const handle = this.lookup(id);
567
+ const last = groups[groups.length - 1];
568
+ if (last?.document === handle.document) {
569
+ last.ids.push(handle.local);
570
+ last.global.push(id);
571
+ } else groups.push({ document: handle.document, ids: [handle.local], global: [id] });
572
+ }
573
+ return groups;
574
+ }
575
+ call(document, command, args) {
576
+ if (command === "extractPlan" && JSON.stringify(args.plan).includes("innerHTML")) registry2.snapshots.delete(document);
577
+ if (Object.hasOwn(args, "value") || ["create", "createNode", "setNode", "import", "insert", "clone", "remove", "removeAttr", "removeData", "addClass", "removeClass", "toggleClass"].includes(command)) registry2.snapshots.delete(document);
578
+ return rawOperation(document, command, { ...args, options: args.options ?? this.options });
579
+ }
580
+ move(target, ids, copy = false) {
581
+ if (!copy) {
582
+ const groups = /* @__PURE__ */ new Map();
583
+ for (const id of ids) {
584
+ const handle = this.lookup(id);
585
+ const group = groups.get(handle.document) ?? [];
586
+ group.push(handle);
587
+ groups.set(handle.document, group);
588
+ }
589
+ for (const [source, handles] of groups) {
590
+ if (source === target) continue;
591
+ if (!target.adopt) throw new Error("The native addon does not support cross-document adoption. Rebuild the Rust addon.");
592
+ registry2.snapshots.delete(source);
593
+ registry2.snapshots.delete(target);
594
+ const adopted = JSON.parse(target.adopt(source, handles.map((handle) => handle.local), true));
595
+ for (const [oldLocal, newLocal] of adopted.mapping) {
596
+ const entry = localMap(source).get(oldLocal);
597
+ if (!entry) continue;
598
+ const handle = entry.reference.deref();
599
+ if (handle && (handle.document !== source || handle.local !== oldLocal)) continue;
600
+ localMap(source).delete(oldLocal);
601
+ entry.pin.document = new WeakRef(target);
602
+ entry.pin.local = newLocal;
603
+ if (handle) {
604
+ handle.document = target;
605
+ handle.local = newLocal;
606
+ }
607
+ localMap(target).set(newLocal, entry);
608
+ }
609
+ }
610
+ return ids.map((id) => this.lookup(id).local);
611
+ }
612
+ const result = [];
613
+ for (const group of this.groups(ids)) {
614
+ if (copy && group.document === target) {
615
+ result.push(...this.call(target, "clone", { ids: group.ids, deep: true }));
616
+ continue;
617
+ }
618
+ if (!target.adopt) throw new Error("The native addon does not support cross-document adoption. Rebuild the Rust addon.");
619
+ registry2.snapshots.delete(target);
620
+ const adopted = JSON.parse(target.adopt(group.document, group.ids, !copy));
621
+ result.push(...adopted.roots);
622
+ }
623
+ return result;
624
+ }
625
+ scratch(command, args, ids) {
626
+ const documents = [...new Set(ids.map((id) => this.lookup(id).document))];
627
+ const scratch = new (requireNative()).NativeDocument("", false, JSON.stringify(args.options ?? this.options));
628
+ const toScratch = /* @__PURE__ */ new Map();
629
+ const fromScratch = /* @__PURE__ */ new Map();
630
+ for (const document of documents) {
631
+ const records = JSON.parse(document.exportTree());
632
+ const roots = records.filter((record) => record.parent == null).map((record) => record.id);
633
+ if (!scratch.adopt) throw new Error("The native addon does not support native document copies.");
634
+ const copied = JSON.parse(scratch.adopt(document, roots, false));
635
+ for (const [local, copy] of copied.mapping) {
636
+ const global = this.global(document, local);
637
+ toScratch.set(global, copy);
638
+ fromScratch.set(copy, global);
639
+ }
640
+ }
641
+ const translated = { ...args };
642
+ for (const key of ["ids", "contexts"]) if (Array.isArray(args[key])) translated[key] = args[key].map((id) => toScratch.get(id)).filter((id) => id !== void 0);
643
+ if (args.pseudoMatches) translated.pseudoMatches = Object.fromEntries(Object.entries(args.pseudoMatches).map(([key, values]) => [key, values.map((id) => toScratch.get(id)).filter((id) => id !== void 0)]));
644
+ const result = this.call(scratch, command, translated);
645
+ return ["select", "matches", "uniqueSort"].includes(command) ? result.map((id) => fromScratch.get(id)).filter((id) => id !== void 0) : result;
646
+ }
647
+ select(selector, contexts) {
648
+ const ids = contexts ?? [this.rootId()];
649
+ if (!ids.length) return this.call(this.raw, "select", { selector, contexts: [] });
650
+ const groups = this.groups(ids);
651
+ if (new Set(groups.map((group2) => group2.document)).size > 1) return this.scratch("select", { selector, contexts: ids }, ids);
652
+ const group = groups[0];
653
+ const found = group.document === this.raw ? group.document.select(selector, group.ids) : this.call(group.document, "select", { selector, contexts: group.ids });
654
+ return this.globals(group.document, found);
655
+ }
656
+ text(ids) {
657
+ return this.groups(ids).map((group) => group.document.text(group.ids)).join("");
658
+ }
659
+ innerHtml(id) {
660
+ const handle = this.lookup(id);
661
+ registry2.snapshots.delete(handle.document);
662
+ return handle.document === this.raw ? handle.document.innerHtml(handle.local) : this.call(handle.document, "html", { ids: [handle.local] });
663
+ }
664
+ outerHtml(ids) {
665
+ return this.groups(ids).map((group) => group.document === this.raw ? group.document.outerHtml(group.ids) : this.call(group.document, "render", { ids: group.ids })).join("");
666
+ }
667
+ attr(id, name) {
668
+ const handle = this.lookup(id);
669
+ return this.call(handle.document, "attr", { ids: [handle.local], name }) ?? void 0;
670
+ }
671
+ tagName(id) {
672
+ const handle = this.lookup(id);
673
+ return rawOperation(handle.document, "node", { id: handle.local })?.name;
674
+ }
675
+ exportTree() {
676
+ return JSON.stringify(JSON.parse(this.raw.exportTree()).map((record) => this.record(this.raw, record)));
677
+ }
678
+ create(html, contextId) {
679
+ return JSON.parse(this.op("create", JSON.stringify({ html, contextId })));
680
+ }
681
+ op(command, json) {
682
+ return JSON.stringify(this.operate(command, JSON.parse(json)) ?? null);
683
+ }
684
+ operate(command, args) {
685
+ const options = args.options ?? this.options;
686
+ let result;
687
+ if (command === "node") {
688
+ const handle = this.lookup(args.id);
689
+ let snapshots = registry2.snapshots.get(handle.document);
690
+ if (!snapshots) registry2.snapshots.set(handle.document, snapshots = /* @__PURE__ */ new Map());
691
+ if (!snapshots.has(handle.local)) snapshots.set(handle.local, rawOperation(handle.document, "node", { id: handle.local }));
692
+ result = this.record(handle.document, snapshots.get(handle.local));
693
+ } else if (command === "createNode") result = this.global(this.raw, this.call(this.raw, command, args));
694
+ else if (command === "create") {
695
+ const context = args.contextId == null ? void 0 : this.lookup(args.contextId);
696
+ const document = context?.document ?? this.raw;
697
+ if (hasParserHooks(options)) {
698
+ const contextRecord = context ? rawOperation(context.document, "node", { id: context.local }) : void 0;
699
+ const parsed = parseNativeDocument(args.html, { ...options, ...contextRecord ? { __contextName: contextRecord.name, __contextNamespace: contextRecord.namespace } : {} }, false);
700
+ const children2 = rawOperation(parsed, "node", { id: parsed.rootId() }).children;
701
+ this.move(document, children2);
702
+ result = children2;
703
+ } else result = this.globals(document, this.call(document, command, { ...args, contextId: context?.local }));
704
+ } else if (command === "import") result = this.globals(this.raw, this.call(this.raw, command, args));
705
+ else if (command === "setNode") {
706
+ let handle = this.lookup(args.id);
707
+ let value = args.value;
708
+ if (args.field === "children") value = this.move(handle.document, value ?? []);
709
+ else if (["parent", "parentNode", "prev", "previousSibling", "next", "nextSibling"].includes(args.field) && value != null) {
710
+ const pointer = this.lookup(value);
711
+ if (pointer.document !== handle.document) {
712
+ this.move(pointer.document, [args.id]);
713
+ handle = this.lookup(args.id);
714
+ }
715
+ value = this.lookup(args.value).local;
716
+ }
717
+ result = this.call(handle.document, command, { ...args, id: handle.local, value });
718
+ } else if (command === "insert") {
719
+ const targets = args.targetIds ?? [];
720
+ const nodes = args.nodeIds ?? [];
721
+ result = [];
722
+ for (let index = 0; index < targets.length; index++) {
723
+ const target = this.lookup(targets[index]);
724
+ const local = this.move(target.document, nodes, index + 1 < targets.length);
725
+ const inserted = this.call(target.document, command, { ...args, targetIds: [target.local], nodeIds: local });
726
+ result.push(...this.globals(target.document, inserted));
727
+ }
728
+ } else if (command === "html" && Object.hasOwn(args, "value") && hasParserHooks(options)) {
729
+ result = null;
730
+ for (const id of args.ids ?? []) {
731
+ const target = this.lookup(id);
732
+ const record = rawOperation(target.document, "node", { id: target.local });
733
+ if (!["root", "tag", "script", "style", "cdata"].includes(record.type)) continue;
734
+ const parsed = parseNativeDocument(String(args.value), { ...options, __contextName: record.name, __contextNamespace: record.namespace }, false);
735
+ const children2 = rawOperation(parsed, "node", { id: parsed.rootId() }).children;
736
+ const local = this.move(target.document, children2);
737
+ result = this.call(target.document, "setNode", { id: target.local, field: "children", value: local, options });
738
+ }
739
+ } else if (command === "contains") {
740
+ const parent = this.lookup(args.container ?? args.parent);
741
+ const child = this.lookup(args.contained ?? args.child);
742
+ result = parent.document === child.document && this.call(parent.document, command, { container: parent.local, contained: child.local });
743
+ } else if (command === "prop" && Object.hasOwn(args, "value") && ["children", "childNodes", "parent", "parentNode", "prev", "previousSibling", "next", "nextSibling"].includes(args.name)) {
744
+ result = null;
745
+ for (const id of args.ids ?? []) {
746
+ let handle = this.lookup(id);
747
+ let value = args.value;
748
+ if (args.name === "children" || args.name === "childNodes") value = this.move(handle.document, value ?? []);
749
+ else if (value != null) {
750
+ const pointer = this.lookup(value);
751
+ if (pointer.document !== handle.document) {
752
+ this.move(pointer.document, [id]);
753
+ handle = this.lookup(id);
754
+ }
755
+ value = this.lookup(args.value).local;
756
+ }
757
+ result = this.call(handle.document, command, { ...args, ids: [handle.local], value });
758
+ }
759
+ } else {
760
+ const ids = command === "select" ? args.contexts ?? [this.rootId()] : args.ids ?? [];
761
+ const groups = this.groups(ids);
762
+ const mixed = new Set(groups.map((group) => group.document)).size > 1;
763
+ if (mixed && ["select", "matches", "uniqueSort", "serializeArray", "serialize", "extractPlan"].includes(command)) result = this.scratch(command, { ...args, options }, ids);
764
+ else if (command === "extractPlan") {
765
+ const group = groups[0];
766
+ result = this.call(group?.document ?? this.raw, command, { ...args, options, ids: group?.ids ?? [] });
767
+ } else if (["select", "matches", "uniqueSort", "traverse", "clone"].includes(command)) {
768
+ result = [];
769
+ if (!groups.length && (command === "select" || command === "matches")) result = this.call(this.raw, command, { ...args, options, ids: [], ...command === "select" ? { contexts: [] } : {} });
770
+ for (const group of groups) {
771
+ const values = this.call(group.document, command, { ...args, options, ids: group.ids, ...command === "select" ? { contexts: group.ids } : {}, ...args.pseudoMatches ? { pseudoMatches: Object.fromEntries(Object.entries(args.pseudoMatches).map(([key, values2]) => [key, values2.map((id) => this.lookup(id)).filter((handle) => handle.document === group.document).map((handle) => handle.local)])) } : {} });
772
+ result.push(...this.globals(group.document, values));
773
+ }
774
+ } else if (["render", "outerHtml", "text"].includes(command) && !Object.hasOwn(args, "value")) result = groups.map((group) => this.call(group.document, command, { ...args, options, ids: group.ids })).join("");
775
+ else if (command === "hasClass") result = groups.some((group) => this.call(group.document, command, { ...args, options, ids: group.ids }));
776
+ else if (["serializeArray", "serialize"].includes(command)) result = groups.length ? this.call(groups[0].document, command, { ...args, options, ids: groups[0].ids }) : command === "serializeArray" ? [] : "";
777
+ else {
778
+ if (command === "html") for (const group of groups) registry2.snapshots.delete(group.document);
779
+ const writes = Object.hasOwn(args, "value") || ["remove", "removeAttr", "removeData", "addClass", "removeClass", "toggleClass"].includes(command);
780
+ const active = writes ? groups : groups.slice(0, 1);
781
+ result = null;
782
+ for (const group of active) result = this.call(group.document, command, { ...args, options, ids: group.ids });
783
+ }
784
+ }
785
+ return result ?? null;
786
+ }
787
+ };
788
+ function routeDocument(document, options = {}) {
789
+ return document.nodeSpace === registry2.space ? document : new RoutedDocument(document, options);
790
+ }
791
+ function sameNodeSpace(first, second) {
792
+ return first === second || !!first.nodeSpace && first.nodeSpace === second.nodeSpace;
793
+ }
794
+
795
+ // src/nodes.ts
796
+ var nodeStateKey = /* @__PURE__ */ Symbol.for("rusteerio.native-node-views.v2");
797
+ var nodeGlobals = globalThis;
798
+ var nodeState = nodeGlobals[nodeStateKey] ??= { views: /* @__PURE__ */ new WeakMap(), bindings: /* @__PURE__ */ new WeakMap(), caches: /* @__PURE__ */ new WeakMap(), finalizer: new FinalizationRegistry(({ cache, id }) => {
799
+ if (!cache.get(id)?.deref()) cache.delete(id);
800
+ }) };
801
+ var { bindings, caches } = nodeState;
802
+ var arrayIndex = /^(?:0|[1-9]\d*)$/;
803
+ function operation(document, command, args = {}) {
804
+ const direct = document.operate;
805
+ if (direct) return direct.call(document, command, args);
806
+ const value = document.op(command, JSON.stringify(args));
807
+ return value === void 0 || value === "" ? void 0 : JSON.parse(value);
808
+ }
809
+ function nodeBinding(node) {
810
+ return node && typeof node === "object" ? bindings.get(node) : void 0;
811
+ }
812
+ function nodeId(node, document) {
813
+ const binding = nodeBinding(node);
814
+ return binding && (!document || sameNodeSpace(document, binding.document)) ? binding.id : void 0;
815
+ }
816
+ function hydrateLocation(location) {
817
+ if (!location || typeof location !== "object") return location;
818
+ const value = location;
819
+ if (value.attrs && typeof value.attrs === "object") Object.setPrototypeOf(value.attrs, null);
820
+ if (value.startTag?.attrs && typeof value.startTag.attrs === "object") {
821
+ Object.setPrototypeOf(value.startTag.attrs, null);
822
+ if (value.attrs && JSON.stringify(value.attrs) === JSON.stringify(value.startTag.attrs)) value.startTag.attrs = value.attrs;
823
+ }
824
+ return location;
825
+ }
826
+ function nodeRecord(document, id) {
827
+ return operation(document, "node", { id });
828
+ }
829
+ function setField(document, id, field, value) {
830
+ operation(document, "setNode", { id, field, value });
831
+ }
832
+ function attributes(document, id, field = "attribs", prototype = document.options?._useHtmlParser2 === false ? null : Object.prototype) {
833
+ const read = () => nodeRecord(document, id)?.[field] ?? {};
834
+ const target = Object.create(prototype);
835
+ return new Proxy(target, {
836
+ get(_target, key) {
837
+ return typeof key === "symbol" ? Reflect.get(target, key) : Object.hasOwn(read(), key) ? read()[key] : Reflect.get(target, key);
838
+ },
839
+ set(_target, key, value) {
840
+ setField(document, id, field, { ...read(), [key]: String(value) });
841
+ return true;
842
+ },
843
+ deleteProperty(_target, key) {
844
+ const values = { ...read() };
845
+ delete values[key];
846
+ setField(document, id, field, values);
847
+ return true;
848
+ },
849
+ ownKeys() {
850
+ return Reflect.ownKeys(read());
851
+ },
852
+ has(_target, key) {
853
+ return Object.hasOwn(read(), key) || key in target;
854
+ },
855
+ getOwnPropertyDescriptor(_target, key) {
856
+ return Object.hasOwn(read(), key) ? { value: read()[key], writable: true, enumerable: true, configurable: true } : void 0;
857
+ },
858
+ defineProperty(_target, key, descriptor) {
859
+ const values = { ...read(), [key]: String(descriptor.value) };
860
+ setField(document, id, field, values);
861
+ return true;
862
+ }
863
+ });
864
+ }
865
+ function children(document, id) {
866
+ const read = () => nodeRecord(document, id)?.children ?? [];
867
+ const snapshot = () => read().map((child) => getNode(document, child));
868
+ const save = (nodes) => setField(document, id, "children", importNodes(document, nodes));
869
+ const mutating = /* @__PURE__ */ new Set(["push", "pop", "shift", "unshift", "splice", "sort", "reverse", "copyWithin", "fill"]);
870
+ const target = [];
871
+ return new Proxy(target, {
872
+ get(_target, key, receiver) {
873
+ if (key === "length") return read().length;
874
+ if (typeof key === "string" && arrayIndex.test(key)) {
875
+ const child = read()[Number(key)];
876
+ return child === void 0 ? void 0 : getNode(document, child);
877
+ }
878
+ if (typeof key === "string" && mutating.has(key)) return (...args) => {
879
+ const values = snapshot();
880
+ const result = Reflect.apply(Array.prototype[key], values, args);
881
+ save(values);
882
+ return result === values ? receiver : result;
883
+ };
884
+ return Reflect.get(target, key, receiver);
885
+ },
886
+ set(_target, key, value) {
887
+ const values = snapshot();
888
+ if (key === "length") values.length = value;
889
+ else if (typeof key === "string" && arrayIndex.test(key)) values[Number(key)] = value;
890
+ else return Reflect.set(target, key, value);
891
+ save(values);
892
+ return true;
893
+ },
894
+ deleteProperty(_target, key) {
895
+ if (typeof key === "string" && arrayIndex.test(key)) {
896
+ const values = snapshot();
897
+ values.splice(Number(key), 1);
898
+ save(values);
899
+ return true;
900
+ }
901
+ return Reflect.deleteProperty(target, key);
902
+ },
903
+ has(_target, key) {
904
+ return typeof key === "string" && arrayIndex.test(key) ? Number(key) < read().length : Reflect.has(target, key);
905
+ },
906
+ ownKeys() {
907
+ return [...read().map((_child, i) => String(i)), "length"];
908
+ },
909
+ getOwnPropertyDescriptor(_target, key) {
910
+ if (key === "length") return { ...Reflect.getOwnPropertyDescriptor(target, "length"), value: read().length };
911
+ if (typeof key === "string" && arrayIndex.test(key) && Number(key) < read().length) return { value: getNode(document, read()[Number(key)]), writable: true, enumerable: true, configurable: true };
912
+ return Reflect.getOwnPropertyDescriptor(target, key);
913
+ }
914
+ });
915
+ }
916
+ var parentAliases = { parentNode: "parent", previousSibling: "prev", nextSibling: "next" };
917
+ var sourceFields = /* @__PURE__ */ new Set(["type", "name", "data", "namespace", "prefix", "startIndex", "endIndex", "sourceCodeLocation", "x-name", "x-publicId", "x-systemId", "x-mode"]);
918
+ var tagTypes = /* @__PURE__ */ new Set(["tag", "script", "style"]);
919
+ var parentTypes = /* @__PURE__ */ new Set(["root", "tag", "script", "style", "cdata"]);
920
+ var dataTypes = /* @__PURE__ */ new Set(["text", "comment", "directive"]);
921
+ function viewKeys(record) {
922
+ const keys = ["parent", "prev", "next", "startIndex", "endIndex"];
923
+ if (parentTypes.has(record.type)) keys.push("children");
924
+ if (record.data !== void 0) keys.push("data");
925
+ if (record.name !== void 0) keys.push("name");
926
+ if (tagTypes.has(record.type)) keys.push("attribs");
927
+ keys.push("type");
928
+ for (const field of sourceFields) if (!keys.includes(field) && field in record) keys.push(field);
929
+ if (tagTypes.has(record.type)) {
930
+ if ("attribsNamespace" in record) keys.push("x-attribsNamespace");
931
+ if ("attribsPrefix" in record) keys.push("x-attribsPrefix");
932
+ }
933
+ return keys;
934
+ }
935
+ function viewValue(state, key, receiver) {
936
+ const { document, id } = state;
937
+ const record = nodeRecord(document, id);
938
+ if (key === "cloneNode") return cloneNode;
939
+ if (key === "nodeType") return { root: 9, text: 3, comment: 8, cdata: 4 }[record.type] ?? 1;
940
+ if (key === "tagName" && tagTypes.has(record.type)) return record.name;
941
+ if (key === "nodeValue" && dataTypes.has(record.type)) return record.data;
942
+ const pointer = parentAliases[key] ?? key;
943
+ if (["parent", "prev", "next"].includes(pointer)) return record[pointer] == null ? null : getNode(document, record[pointer]);
944
+ if (["children", "childNodes", "firstChild", "lastChild"].includes(key) && parentTypes.has(record.type)) {
945
+ const list = state.children ??= children(document, id);
946
+ return key === "firstChild" ? list[0] ?? null : key === "lastChild" ? list[list.length - 1] ?? null : list;
947
+ }
948
+ if (key === "attribs" && tagTypes.has(record.type)) return state.attributes ??= attributes(document, id);
949
+ if ((key === "x-attribsNamespace" && "attribsNamespace" in record || key === "x-attribsPrefix" && "attribsPrefix" in record) && tagTypes.has(record.type)) {
950
+ state.maps ??= {};
951
+ return state.maps[key] ??= attributes(document, id, key === "x-attribsNamespace" ? "attribsNamespace" : "attribsPrefix");
952
+ }
953
+ if (key === "attributes" && tagTypes.has(record.type)) {
954
+ const attrs = state.attributes ??= attributes(document, id);
955
+ return Object.keys(attrs).map((name) => ({ name, value: attrs[name], namespace: record.attribsNamespace?.[name], prefix: record.attribsPrefix?.[name] }));
956
+ }
957
+ if (key === "sourceCodeLocation") return hydrateLocation(record[key]);
958
+ if (sourceFields.has(key)) return record[key] ?? (key === "startIndex" || key === "endIndex" ? null : void 0);
959
+ return void 0;
960
+ }
961
+ function writeView(state, key, value) {
962
+ const { document, id } = state;
963
+ const record = nodeRecord(document, id);
964
+ if (key === "tagName" && tagTypes.has(record.type)) key = "name";
965
+ else if (key === "nodeValue" && dataTypes.has(record.type)) key = "data";
966
+ else if (key === "childNodes") key = "children";
967
+ else key = parentAliases[key] ?? key;
968
+ if (sourceFields.has(key) || ["attribs", "x-attribsNamespace", "x-attribsPrefix"].includes(key)) {
969
+ setField(document, id, key, value);
970
+ return true;
971
+ }
972
+ if (key === "children" && parentTypes.has(record.type)) {
973
+ setField(document, id, key, importNodes(document, value));
974
+ return true;
975
+ }
976
+ if (["parent", "prev", "next"].includes(key)) {
977
+ setField(document, id, key, value == null ? null : importNodes(document, [value])[0]);
978
+ return true;
979
+ }
980
+ return false;
981
+ }
982
+ var nodeHandler = {
983
+ get(target, key, receiver) {
984
+ if (Reflect.getOwnPropertyDescriptor(target, key)) return Reflect.get(target, key, receiver);
985
+ if (typeof key === "string") {
986
+ const state = nodeState.views.get(target);
987
+ if (key === "cloneNode" || key === "nodeType" || sourceFields.has(key) || ["tagName", "nodeValue", "parent", "prev", "next", "parentNode", "previousSibling", "nextSibling", "children", "childNodes", "firstChild", "lastChild", "attribs", "attributes", "x-attribsNamespace", "x-attribsPrefix"].includes(key)) return viewValue(state, key, receiver);
988
+ }
989
+ return Reflect.get(target, key, receiver);
990
+ },
991
+ set(target, key, value, receiver) {
992
+ if (Reflect.getOwnPropertyDescriptor(target, key)) return Reflect.set(target, key, value, receiver);
993
+ if (typeof key === "string" && writeView(nodeState.views.get(target), key, value)) return true;
994
+ return Reflect.set(target, key, value, receiver);
995
+ },
996
+ has(target, key) {
997
+ return Reflect.has(target, key) || typeof key === "string" && (viewKeys(nodeRecord(nodeState.views.get(target).document, nodeState.views.get(target).id)).includes(key) || ["cloneNode", "nodeType", "parentNode", "previousSibling", "nextSibling"].includes(key));
998
+ },
999
+ ownKeys(target) {
1000
+ const state = nodeState.views.get(target);
1001
+ return [.../* @__PURE__ */ new Set([...viewKeys(nodeRecord(state.document, state.id)), ...Reflect.ownKeys(target)])];
1002
+ },
1003
+ getOwnPropertyDescriptor(target, key) {
1004
+ const existing = Reflect.getOwnPropertyDescriptor(target, key);
1005
+ if (existing) return existing;
1006
+ const state = nodeState.views.get(target);
1007
+ if (typeof key === "string" && viewKeys(nodeRecord(state.document, state.id)).includes(key)) return { value: viewValue(state, key, void 0), configurable: true, enumerable: true, writable: true };
1008
+ return void 0;
1009
+ }
1010
+ };
1011
+ function getNode(document, id, original) {
1012
+ const cacheKey = document.nodeSpace ?? document;
1013
+ let cache = caches.get(cacheKey);
1014
+ if (!cache) caches.set(cacheKey, cache = /* @__PURE__ */ new Map());
1015
+ const existing = cache.get(id)?.deref();
1016
+ if (existing) return existing;
1017
+ document = document.nodeDocument?.(id) ?? document;
1018
+ const lease = document.retainNodes?.([id]);
1019
+ const record = nodeRecord(document, id);
1020
+ if (!record) return void 0;
1021
+ if (original === void 0) {
1022
+ const target = Object.create(nodePrototype(record.type));
1023
+ const node2 = new Proxy(target, nodeHandler);
1024
+ nodeState.views.set(target, { document, id, lease });
1025
+ cache.set(id, new WeakRef(node2));
1026
+ nodeState.finalizer.register(node2, { cache, id });
1027
+ bindings.set(node2, { document, id });
1028
+ return node2;
1029
+ }
1030
+ const node = original;
1031
+ cache.set(id, new WeakRef(node));
1032
+ nodeState.finalizer.register(node, { cache, id });
1033
+ bindings.set(node, { document, id });
1034
+ const read = () => {
1035
+ void lease;
1036
+ return nodeRecord(document, id);
1037
+ };
1038
+ const define = (key, get, set, enumerable = true) => {
1039
+ try {
1040
+ Object.defineProperty(node, key, { configurable: true, enumerable, get, ...set ? { set } : {} });
1041
+ } catch {
1042
+ }
1043
+ };
1044
+ for (const field of ["type", "name", "data", "namespace", "prefix", "startIndex", "endIndex", "sourceCodeLocation", "x-name", "x-publicId", "x-systemId", "x-mode"]) {
1045
+ if (field in record || ["type", "startIndex", "endIndex"].includes(field)) define(field, () => (field === "sourceCodeLocation" ? hydrateLocation(read()[field]) : read()[field]) ?? (field === "startIndex" || field === "endIndex" ? null : void 0), (value) => setField(document, id, field, value));
1046
+ }
1047
+ for (const field of ["parent", "prev", "next"]) define(field, () => {
1048
+ const value = read()[field];
1049
+ return value === null || value === void 0 ? null : getNode(document, value);
1050
+ }, (value) => setField(document, id, field, value == null ? null : importNodes(document, [value])[0]));
1051
+ for (const [alias, field] of [["parentNode", "parent"], ["previousSibling", "prev"], ["nextSibling", "next"]]) define(alias, () => node[field], (value) => {
1052
+ node[field] = value;
1053
+ }, false);
1054
+ if ("children" in record && ["root", "tag", "script", "style", "cdata"].includes(record.type)) {
1055
+ const list = children(document, id);
1056
+ define("children", () => list, (value) => setField(document, id, "children", importNodes(document, value)));
1057
+ define("childNodes", () => list, (value) => {
1058
+ node.children = value;
1059
+ }, false);
1060
+ define("firstChild", () => list[0] ?? null, void 0, false);
1061
+ define("lastChild", () => list[list.length - 1] ?? null, void 0, false);
1062
+ }
1063
+ if (["tag", "script", "style"].includes(record.type)) {
1064
+ const attrs = attributes(document, id, "attribs", Object.getPrototypeOf(original.attribs ?? {}));
1065
+ define("attribs", () => attrs, (value) => setField(document, id, "attribs", value));
1066
+ define("tagName", () => node.name, (value) => {
1067
+ node.name = value;
1068
+ }, false);
1069
+ for (const field of ["x-attribsNamespace", "x-attribsPrefix"]) {
1070
+ if (!((field === "x-attribsNamespace" ? "attribsNamespace" : "attribsPrefix") in record) && !Object.hasOwn(original, field)) continue;
1071
+ const values = attributes(document, id, field === "x-attribsNamespace" ? "attribsNamespace" : "attribsPrefix");
1072
+ define(field, () => values, (value) => setField(document, id, field, value));
1073
+ }
1074
+ define("attributes", () => Object.keys(attrs).map((name) => ({ name, value: attrs[name], namespace: read().attribsNamespace?.[name], prefix: read().attribsPrefix?.[name] })), void 0, false);
1075
+ }
1076
+ if (["text", "comment", "directive"].includes(record.type)) define("nodeValue", () => node.data, (value) => {
1077
+ node.data = value;
1078
+ }, false);
1079
+ define("nodeType", () => ({ root: 9, text: 3, comment: 8, cdata: 4 })[read().type] ?? 1, void 0, false);
1080
+ Object.defineProperty(node, "cloneNode", { configurable: true, enumerable: false, writable: true, value: cloneNode });
1081
+ return node;
1082
+ }
1083
+ function cloneNode(recursive = false) {
1084
+ const binding = nodeBinding(this);
1085
+ if (!binding) throw new TypeError("cloneNode requires a native DOM node receiver");
1086
+ return getNode(binding.document, operation(binding.document, "clone", { ids: [binding.id], deep: recursive })[0]);
1087
+ }
1088
+ function importNodes(document, input) {
1089
+ if (input == null || input === false) return [];
1090
+ const values = Array.isArray(input) || typeof input === "object" && "length" in input && !("type" in input) ? Array.from(input) : [input];
1091
+ const result = [];
1092
+ for (const node of values) {
1093
+ if (node == null) continue;
1094
+ const existing = nodeId(node, document);
1095
+ if (existing !== void 0) {
1096
+ document.retainNode?.(existing);
1097
+ result.push(existing);
1098
+ continue;
1099
+ }
1100
+ if (typeof node !== "object" || typeof node.type !== "string") continue;
1101
+ const records = [];
1102
+ const originals = /* @__PURE__ */ new Map();
1103
+ const visit = (value, parent) => {
1104
+ const id = records.length;
1105
+ const record = { id, type: value.type, children: [], ...parent === void 0 ? {} : { parent } };
1106
+ records.push(record);
1107
+ originals.set(id, value);
1108
+ for (const field of ["name", "data", "namespace", "prefix", "startIndex", "endIndex", "sourceCodeLocation", "x-name", "x-publicId", "x-systemId", "x-mode"]) if (value[field] !== void 0) record[field] = value[field];
1109
+ if (value.attribs) record.attribs = { ...value.attribs };
1110
+ if (value["x-attribsNamespace"]) record.attribsNamespace = { ...value["x-attribsNamespace"] };
1111
+ if (value["x-attribsPrefix"]) record.attribsPrefix = { ...value["x-attribsPrefix"] };
1112
+ record.children = (value.children ?? []).map((child) => visit(child, id));
1113
+ return id;
1114
+ };
1115
+ const root = visit(node);
1116
+ const imported = operation(document, "import", { nodes: records, roots: [root] });
1117
+ if (!imported.length) continue;
1118
+ const adopt = (oldId, newId) => {
1119
+ const source = originals.get(oldId);
1120
+ const oldChildren = records[oldId].children;
1121
+ const newChildren = nodeRecord(document, newId).children ?? [];
1122
+ getNode(document, newId, nodeBinding(source) ? void 0 : source);
1123
+ for (let i = 0; i < oldChildren.length; i++) if (newChildren[i] !== void 0) adopt(oldChildren[i], newChildren[i]);
1124
+ };
1125
+ adopt(root, imported[0]);
1126
+ result.push(imported[0]);
1127
+ }
1128
+ return result;
1129
+ }
1130
+
1131
+ // src/dom.ts
1132
+ var ElementType = Object.freeze({ Root: "root", Text: "text", Directive: "directive", Comment: "comment", Script: "script", Style: "style", Tag: "tag", CDATA: "cdata", Doctype: "doctype" });
1133
+ function initialize(node, type, fields, children2 = []) {
1134
+ const document = routeDocument(new (requireNative()).NativeDocument("", false));
1135
+ const id = operation(document, "createNode", { type, ...fields });
1136
+ if (children2.length) operation(document, "setNode", { id, field: "children", value: importNodes(document, children2) });
1137
+ return getNode(document, id, node);
1138
+ }
1139
+ var Node = class {
1140
+ static [Symbol.hasInstance](value) {
1141
+ const binding = nodeBinding(value);
1142
+ if (!binding) return Function.prototype[Symbol.hasInstance].call(this, value);
1143
+ const type = value.type;
1144
+ switch (this.name) {
1145
+ case "Node":
1146
+ return true;
1147
+ case "DataNode":
1148
+ return ["text", "comment", "directive"].includes(type);
1149
+ case "NodeWithChildren":
1150
+ return ["root", "tag", "script", "style", "cdata"].includes(type);
1151
+ case "Element":
1152
+ return ["tag", "script", "style"].includes(type);
1153
+ case "Document":
1154
+ return type === "root";
1155
+ case "CDATA":
1156
+ return type === "cdata";
1157
+ case "Text":
1158
+ return type === "text";
1159
+ case "Comment":
1160
+ return type === "comment";
1161
+ case "ProcessingInstruction":
1162
+ return type === "directive";
1163
+ default:
1164
+ return Function.prototype[Symbol.hasInstance].call(this, value);
1165
+ }
1166
+ }
1167
+ };
1168
+ var DataNode = class extends Node {
1169
+ };
1170
+ var NodeWithChildren = class extends Node {
1171
+ };
1172
+ var Text = class extends DataNode {
1173
+ constructor(data2) {
1174
+ super();
1175
+ return initialize(this, "text", { data: data2 });
1176
+ }
1177
+ };
1178
+ var Comment = class extends DataNode {
1179
+ constructor(data2) {
1180
+ super();
1181
+ return initialize(this, "comment", { data: data2 });
1182
+ }
1183
+ };
1184
+ var ProcessingInstruction = class extends DataNode {
1185
+ constructor(name, data2) {
1186
+ super();
1187
+ return initialize(this, "directive", { name, data: data2 });
1188
+ }
1189
+ };
1190
+ var Document = class extends NodeWithChildren {
1191
+ constructor(children2) {
1192
+ super();
1193
+ return initialize(this, "root", {}, children2);
1194
+ }
1195
+ };
1196
+ var CDATA = class extends NodeWithChildren {
1197
+ constructor(children2) {
1198
+ super();
1199
+ return initialize(this, "cdata", {}, children2);
1200
+ }
1201
+ };
1202
+ var Element = class extends NodeWithChildren {
1203
+ constructor(name, attribs, children2 = [], type) {
1204
+ super();
1205
+ return initialize(this, type ?? (name === "script" || name === "style" ? name : "tag"), { name, attribs }, children2);
1206
+ }
1207
+ };
1208
+ function nodePrototype(type) {
1209
+ return ({ root: Document, text: Text, comment: Comment, directive: ProcessingInstruction, cdata: CDATA, tag: Element, script: Element, style: Element }[type] ?? Node).prototype;
1210
+ }
1211
+ var isTag = (node) => ["tag", "script", "style"].includes(node.type);
1212
+ var isText = (node) => node.type === "text";
1213
+ var isComment = (node) => node.type === "comment";
1214
+ var isDirective = (node) => node.type === "directive";
1215
+ var isDocument = (node) => node.type === "root";
1216
+ var isCDATA = (node) => node.type === "cdata";
1217
+ var hasChildren = (node) => "children" in node;
1218
+ Object.defineProperties(Node.prototype, {
1219
+ cloneNode: { configurable: true, writable: true, value: cloneNode },
1220
+ parentNode: { configurable: true, get() {
1221
+ return this.parent;
1222
+ }, set(value) {
1223
+ this.parent = value;
1224
+ } },
1225
+ previousSibling: { configurable: true, get() {
1226
+ return this.prev;
1227
+ }, set(value) {
1228
+ this.prev = value;
1229
+ } },
1230
+ nextSibling: { configurable: true, get() {
1231
+ return this.next;
1232
+ }, set(value) {
1233
+ this.next = value;
1234
+ } },
1235
+ nodeType: { configurable: true, get() {
1236
+ return { root: 9, text: 3, comment: 8, cdata: 4 }[this.type] ?? 1;
1237
+ } }
1238
+ });
1239
+ Object.defineProperty(DataNode.prototype, "nodeValue", { configurable: true, get() {
1240
+ return this.data;
1241
+ }, set(value) {
1242
+ this.data = value;
1243
+ } });
1244
+ Object.defineProperties(NodeWithChildren.prototype, {
1245
+ childNodes: { configurable: true, get() {
1246
+ return this.children;
1247
+ }, set(value) {
1248
+ this.children = value;
1249
+ } },
1250
+ firstChild: { configurable: true, get() {
1251
+ return this.children[0] ?? null;
1252
+ } },
1253
+ lastChild: { configurable: true, get() {
1254
+ return this.children[this.children.length - 1] ?? null;
1255
+ } }
1256
+ });
1257
+ Object.defineProperties(Element.prototype, {
1258
+ tagName: { configurable: true, get() {
1259
+ return this.name;
1260
+ }, set(value) {
1261
+ this.name = value;
1262
+ } },
1263
+ attributes: { configurable: true, get() {
1264
+ return Object.keys(this.attribs).map((name) => ({ name, value: this.attribs[name], namespace: this["x-attribsNamespace"]?.[name], prefix: this["x-attribsPrefix"]?.[name] }));
1265
+ } }
1266
+ });
1267
+
1268
+ // src/extract-plan.ts
1269
+ var import_node_util = require("util");
1270
+ var scalarProperties = /* @__PURE__ */ new Set([
1271
+ "textContent",
1272
+ "innerText",
1273
+ "innerHTML",
1274
+ "outerHTML",
1275
+ "tagName",
1276
+ "nodeName",
1277
+ "nodeType",
1278
+ "id",
1279
+ "class",
1280
+ "className",
1281
+ "title",
1282
+ "href",
1283
+ "src",
1284
+ "alt",
1285
+ "name",
1286
+ "value",
1287
+ "type",
1288
+ "checked",
1289
+ "selected",
1290
+ "disabled",
1291
+ "multiple",
1292
+ "readOnly",
1293
+ "required",
1294
+ "hidden",
1295
+ "open",
1296
+ "autofocus",
1297
+ "controls",
1298
+ "loop",
1299
+ "muted"
1300
+ ]);
1301
+ function dataValue(object, key) {
1302
+ for (let current = object; current; current = Object.getPrototypeOf(current)) {
1303
+ if (import_node_util.types.isProxy(current)) return void 0;
1304
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
1305
+ if (descriptor) return "value" in descriptor ? { value: descriptor.value } : void 0;
1306
+ }
1307
+ return { value: void 0 };
1308
+ }
1309
+ function compileExtractPlan(map, options) {
1310
+ if (options.pseudos || options.treeAdapter || options.Tokenizer || options.xml && typeof options.xml === "object" && options.xml.Tokenizer) return void 0;
1311
+ const ancestors = /* @__PURE__ */ new Set();
1312
+ const compile = (input) => {
1313
+ if (!input || typeof input !== "object" || import_node_util.types.isProxy(input) || ancestors.has(input) || ancestors.size >= 64) return void 0;
1314
+ for (let current = Object.getPrototypeOf(input); current; current = Object.getPrototypeOf(current)) {
1315
+ if (import_node_util.types.isProxy(current)) return void 0;
1316
+ }
1317
+ ancestors.add(input);
1318
+ try {
1319
+ const entries2 = [];
1320
+ for (const key in input) {
1321
+ if (key === "__proto__") return void 0;
1322
+ const inherited = Object.getOwnPropertyDescriptor(Object.prototype, key);
1323
+ if (inherited && (!("value" in inherited) || !inherited.writable)) return void 0;
1324
+ const slot = dataValue(input, key);
1325
+ if (!slot) return void 0;
1326
+ const all = Array.isArray(slot.value);
1327
+ if (slot.value && typeof slot.value === "object" && import_node_util.types.isProxy(slot.value)) return void 0;
1328
+ const first = all ? dataValue(slot.value, "0") : slot;
1329
+ if (!first) return void 0;
1330
+ const descriptor = first.value;
1331
+ let selector;
1332
+ let value;
1333
+ if (typeof descriptor === "string") {
1334
+ selector = descriptor;
1335
+ value = "textContent";
1336
+ } else if (descriptor && typeof descriptor === "object") {
1337
+ if (import_node_util.types.isProxy(descriptor)) return void 0;
1338
+ const selectorSlot = dataValue(descriptor, "selector");
1339
+ const valueSlot = dataValue(descriptor, "value");
1340
+ if (!selectorSlot || !valueSlot) return void 0;
1341
+ selector = selectorSlot.value;
1342
+ value = valueSlot.value ?? "textContent";
1343
+ } else return void 0;
1344
+ if (typeof selector !== "string") return void 0;
1345
+ if (typeof value === "string") {
1346
+ if (!scalarProperties.has(value) && !/^(?:data-|aria-).+/.test(value)) return void 0;
1347
+ entries2.push({ key, selector, all, value: { kind: "property", name: value } });
1348
+ } else {
1349
+ const nested = compile(value);
1350
+ if (!nested) return void 0;
1351
+ entries2.push({ key, selector, all, value: { kind: "map", entries: nested } });
1352
+ }
1353
+ }
1354
+ return entries2;
1355
+ } finally {
1356
+ ancestors.delete(input);
1357
+ }
1358
+ };
1359
+ const entries = compile(map);
1360
+ return entries && { version: 1, entries };
1361
+ }
1362
+ function hydrateExtractResult(result, entries) {
1363
+ const values = entries.map((entry) => Object.hasOwn(result, entry.key) ? result[entry.key] : entry.all ? [] : void 0);
1364
+ for (const entry of entries) delete result[entry.key];
1365
+ for (let index = 0; index < entries.length; index += 1) {
1366
+ const entry = entries[index];
1367
+ Object.defineProperty(result, entry.key, { value: values[index], enumerable: true, configurable: true, writable: true });
1368
+ if (entry.value.kind !== "map") continue;
1369
+ const nested = result[entry.key];
1370
+ for (const value of entry.all && Array.isArray(nested) ? nested : [nested]) {
1371
+ if (value && typeof value === "object" && !Array.isArray(value)) hydrateExtractResult(value, entry.value.entries);
1372
+ }
1373
+ }
1374
+ }
1375
+
1376
+ // src/attributes.ts
1377
+ var dataObjects = /* @__PURE__ */ new WeakMap();
1378
+ var dataFinalizer = new FinalizationRegistry(({ cache, id, reference }) => {
1379
+ const records = cache.deref();
1380
+ if (records?.get(id) === reference) records.delete(id);
1381
+ });
1382
+ function isElement(selection, id) {
1383
+ return ["tag", "script", "style"].includes(nodeRecord(selection._document, id)?.type);
1384
+ }
1385
+ function nativeValue(value) {
1386
+ const seen = /* @__PURE__ */ new WeakSet();
1387
+ const json = JSON.stringify(value, (_key, value2) => {
1388
+ if (typeof value2 === "function" || typeof value2 === "symbol" || typeof value2 === "bigint" || value2 === void 0) return { __opaqueJavaScriptValue: true };
1389
+ if (typeof value2 === "number" && !Number.isFinite(value2)) return { __nativeNumber: String(value2) };
1390
+ if (value2 && typeof value2 === "object") {
1391
+ if (seen.has(value2)) return { __opaqueJavaScriptValue: true };
1392
+ seen.add(value2);
1393
+ }
1394
+ return value2;
1395
+ });
1396
+ return json === void 0 ? { __opaqueJavaScriptValue: true } : JSON.parse(json);
1397
+ }
1398
+ function hydrateValue(value) {
1399
+ if (value && typeof value === "object") {
1400
+ if (Object.keys(value).length === 1 && typeof value.__nativeNumber === "string") return Number(value.__nativeNumber);
1401
+ for (const key of Object.keys(value)) value[key] = hydrateValue(value[key]);
1402
+ }
1403
+ return value;
1404
+ }
1405
+ function dataObject(selection, id) {
1406
+ const document = selection._document;
1407
+ const cacheKey = document.nodeSpace ?? document;
1408
+ let documents = dataObjects.get(cacheKey);
1409
+ if (!documents) dataObjects.set(cacheKey, documents = /* @__PURE__ */ new Map());
1410
+ const existingReference = documents.get(id);
1411
+ let data2 = existingReference?.deref() ?? document.nodeData?.(id);
1412
+ if (!data2) {
1413
+ const documentReference = new WeakRef(document);
1414
+ const dispatch = document.nodeDataOperation?.(id) ?? ((command, args) => {
1415
+ const document2 = documentReference.deref();
1416
+ return document2 ? JSON.parse(document2.op(command, JSON.stringify(args))) : void 0;
1417
+ });
1418
+ const target = {};
1419
+ data2 = new Proxy(target, {
1420
+ set(object, name, value) {
1421
+ Reflect.set(object, name, value);
1422
+ if (typeof name === "string") dispatch("data", { ids: [id], name, value: nativeValue(value) });
1423
+ return true;
1424
+ },
1425
+ defineProperty(object, name, descriptor) {
1426
+ Reflect.defineProperty(object, name, descriptor);
1427
+ if (typeof name === "string" && "value" in descriptor) dispatch("data", { ids: [id], name, value: nativeValue(descriptor.value) });
1428
+ return true;
1429
+ },
1430
+ deleteProperty(object, name) {
1431
+ Reflect.deleteProperty(object, name);
1432
+ if (typeof name === "string") dispatch("removeData", { ids: [id], name });
1433
+ return true;
1434
+ }
1435
+ });
1436
+ const node = getNode(selection._document, id);
1437
+ Object.defineProperty(node, "data", { configurable: true, enumerable: true, get: () => data2, set: (value) => {
1438
+ for (const key of Object.keys(data2)) delete data2[key];
1439
+ for (const key of Object.keys(value ?? {})) data2[key] = value[key];
1440
+ } });
1441
+ }
1442
+ if (existingReference?.deref() !== data2) {
1443
+ const reference = new WeakRef(data2);
1444
+ documents.set(id, reference);
1445
+ dataFinalizer.register(data2, { cache: new WeakRef(documents), id, reference });
1446
+ }
1447
+ document.retainNodeData?.(id, data2);
1448
+ return data2;
1449
+ }
1450
+ function property(selection, id, name, raw = false) {
1451
+ const result = selection.op("prop", { ids: [id], name, ...raw ? { raw: true } : {} });
1452
+ if (name === "sourceCodeLocation") return hydrateLocation(result);
1453
+ return result?.__nativeNodeProperty ? getNode(selection._document, id)[result.__nativeNodeProperty] : result === null ? void 0 : result;
1454
+ }
1455
+ function propertyValue(selection, name, value) {
1456
+ if (name === "children" || name === "childNodes") return importNodes(selection._document, value);
1457
+ if (["parent", "parentNode", "prev", "previousSibling", "next", "nextSibling"].includes(name)) return value == null ? null : importNodes(selection._document, [value])[0] ?? null;
1458
+ return value;
1459
+ }
1460
+ function attr(name, value) {
1461
+ if (typeof name === "object" || value !== void 0) {
1462
+ if (typeof value === "function") {
1463
+ if (typeof name !== "string") throw new Error("Bad combination of arguments.");
1464
+ this.ids.forEach((id, index) => {
1465
+ if (!isElement(this, id)) return;
1466
+ const node = getNode(this._document, id);
1467
+ const current = node.attribs[name];
1468
+ const next = value.call(node, index, current);
1469
+ this.op("attr", { ids: [id], name, value: next === null ? null : String(next) });
1470
+ });
1471
+ } else if (typeof name === "object") {
1472
+ for (const key of Object.keys(name)) this.op("attr", { ids: this.ids, name: key, value: name[key] === null ? null : String(name[key]) });
1473
+ } else {
1474
+ this.op("attr", { ids: this.ids, name, value: value === null ? null : String(value) });
1475
+ }
1476
+ return this;
1477
+ }
1478
+ if (arguments.length > 1) return this;
1479
+ const result = this.op("attr", { ids: this.ids, ...typeof name === "string" ? { name } : {} });
1480
+ if (result === null) return void 0;
1481
+ return !name && this.ids.length ? getNode(this._document, this.ids[0]).attribs : result;
1482
+ }
1483
+ function prop(name, value) {
1484
+ if (typeof name === "string" && value === void 0) return this.ids.length ? property(this, this.ids[0], name) : void 0;
1485
+ if (typeof name === "object" || value !== void 0) {
1486
+ if (typeof value === "function") {
1487
+ if (typeof name === "object") throw new TypeError("Bad combination of arguments.");
1488
+ this.ids.forEach((id, index) => {
1489
+ if (!isElement(this, id)) return;
1490
+ const next = value.call(getNode(this._document, id), index, property(this, id, name, true));
1491
+ this.op("prop", { ids: [id], name, value: propertyValue(this, name, next) });
1492
+ });
1493
+ } else if (typeof name === "object") {
1494
+ for (const key of Object.keys(name)) this.op("prop", { ids: this.ids, name: key, value: propertyValue(this, key, name[key]) });
1495
+ } else {
1496
+ this.op("prop", { ids: this.ids, name, value: propertyValue(this, name, value) });
1497
+ }
1498
+ return this;
1499
+ }
1500
+ return void 0;
1501
+ }
1502
+ function data(name, value) {
1503
+ const first = this.ids[0];
1504
+ if (first === void 0 || !isElement(this, first)) return void 0;
1505
+ if (name != null && (typeof name === "object" || value !== void 0)) {
1506
+ for (const id of this.ids) {
1507
+ if (!isElement(this, id)) continue;
1508
+ const record2 = dataObject(this, id);
1509
+ if (typeof name === "object") for (const key of Object.keys(name)) record2[key] = name[key];
1510
+ else if (typeof name === "string") record2[name] = value;
1511
+ }
1512
+ return this;
1513
+ }
1514
+ const record = dataObject(this, first);
1515
+ if (typeof name === "string" && Object.hasOwn(record, name)) return record[name];
1516
+ const found = this.op("data", { ids: [first], ...name == null ? {} : { name } });
1517
+ if (!found.found) return void 0;
1518
+ if (name == null) {
1519
+ for (const key of Object.keys(found.value)) if (!Object.hasOwn(record, key)) record[key] = hydrateValue(found.value[key]);
1520
+ return record;
1521
+ }
1522
+ record[name] = hydrateValue(found.value);
1523
+ return record[name];
1524
+ }
1525
+ function css(name, value) {
1526
+ if (name != null && value != null || typeof name === "object" && !Array.isArray(name)) {
1527
+ if (typeof name === "object") {
1528
+ for (const [propertyIndex, key] of Object.keys(name).entries()) {
1529
+ if (typeof name[key] === "function") {
1530
+ for (const id of this.ids) {
1531
+ if (!isElement(this, id)) continue;
1532
+ const current = this.op("css", { ids: [id], name: key }) ?? void 0;
1533
+ const next = name[key].call(getNode(this._document, id), propertyIndex, current);
1534
+ this.op("css", { ids: [id], name: key, value: next == null ? null : String(next) });
1535
+ }
1536
+ } else this.op("css", { ids: this.ids, name: key, value: name[key] == null ? null : String(name[key]) });
1537
+ }
1538
+ } else if (typeof name === "string" && typeof value === "function") {
1539
+ this.ids.forEach((id, index) => {
1540
+ if (!isElement(this, id)) return;
1541
+ const current = this.op("css", { ids: [id], name }) ?? void 0;
1542
+ const next = value.call(getNode(this._document, id), index, current);
1543
+ this.op("css", { ids: [id], name, value: next == null ? null : String(next) });
1544
+ });
1545
+ } else if (typeof name === "string") this.op("css", { ids: this.ids, name, value: value == null ? null : String(value) });
1546
+ return this;
1547
+ }
1548
+ return this.op("css", { ids: this.ids, ...name === void 0 ? {} : { name } }) ?? void 0;
1549
+ }
1550
+ function classMethod(command) {
1551
+ return function(name, state) {
1552
+ if (typeof name === "function") {
1553
+ this.ids.forEach((id, index) => {
1554
+ if (!isElement(this, id)) return;
1555
+ const node = getNode(this._document, id);
1556
+ const next = command === "toggleClass" ? name.call(node, index, node.attribs.class ?? "", state) : name.call(node, index, node.attribs.class ?? "");
1557
+ if (typeof next === "string") this.op(command, { ids: [id], name: next, ...typeof state === "boolean" ? { state } : {} });
1558
+ });
1559
+ } else if (typeof name === "string" || command === "removeClass" && arguments.length === 0) {
1560
+ this.op(command, { ids: this.ids, ...typeof name === "string" ? { name } : { all: true }, ...typeof state === "boolean" ? { state } : {} });
1561
+ }
1562
+ return this;
1563
+ };
1564
+ }
1565
+ function installAttributes(CheerioClass) {
1566
+ Object.assign(CheerioClass.prototype, {
1567
+ attr,
1568
+ prop,
1569
+ data,
1570
+ css,
1571
+ removeAttr(name) {
1572
+ this.op("removeAttr", { ids: this.ids, name });
1573
+ return this;
1574
+ },
1575
+ hasClass(name) {
1576
+ return this.op("hasClass", { ids: this.ids, name });
1577
+ },
1578
+ addClass: classMethod("addClass"),
1579
+ removeClass: classMethod("removeClass"),
1580
+ toggleClass: classMethod("toggleClass"),
1581
+ val(value) {
1582
+ if (arguments.length === 0) return this.op("val", { ids: this.ids }) ?? void 0;
1583
+ const result = this.op("val", { ids: this.ids, value: value === void 0 ? { __undefinedJavaScriptValue: true } : value });
1584
+ return result?.chain === false ? result.returnValue : result === false ? void 0 : this;
1585
+ },
1586
+ serializeArray() {
1587
+ return this.op("serializeArray", { ids: this.ids });
1588
+ },
1589
+ serialize() {
1590
+ return this.op("serialize", { ids: this.ids });
1591
+ }
1592
+ });
1593
+ }
1594
+
1595
+ // src/parse.ts
1596
+ function parseWithNative(content, options, isDocument2, context) {
1597
+ if (!isDocument2 && context) {
1598
+ const document2 = nodeBinding(context)?.document ?? routeDocument(new (requireNative()).NativeDocument("", false, JSON.stringify(cleanParserOptions(options))), options);
1599
+ const contextId = importNodes(document2, [context])[0];
1600
+ const children2 = operation(document2, "create", { html: content, contextId, options });
1601
+ const root = operation(document2, "createNode", { type: "root", options });
1602
+ operation(document2, "setNode", { id: root, field: "children", value: children2, options });
1603
+ return getNode(document2, root);
1604
+ }
1605
+ const document = parseNativeDocument(content, options, isDocument2);
1606
+ return getNode(document, document.rootId());
1607
+ }
1608
+ function parseWithParse5(content, options, isDocument2, context) {
1609
+ return parseWithNative(content, { ...options, _useHtmlParser2: false, xml: false, xmlMode: false }, isDocument2, context);
1610
+ }
1611
+ function parseWithHtmlparser2(content, options) {
1612
+ return parseWithNative(content, { ...options, _useHtmlParser2: true }, false, null);
1613
+ }
1614
+ function getParse(parser) {
1615
+ return function parse2(content, options, isDocument2, context) {
1616
+ if (Buffer.isBuffer(content)) content = content.toString();
1617
+ if (typeof content === "string") return parser(content, options, isDocument2, context);
1618
+ if (!Array.isArray(content) && content.type === "root" && nodeBinding(content)) return content;
1619
+ const document = routeDocument(new (requireNative()).NativeDocument("", false, JSON.stringify(cleanParserOptions(options))), options);
1620
+ const ids = importNodes(document, content);
1621
+ if (!Array.isArray(content) && content.type === "root") return getNode(document, ids[0]);
1622
+ operation(document, "setNode", { id: document.rootId(), field: "children", value: ids, options });
1623
+ return getNode(document, document.rootId());
1624
+ };
1625
+ }
1626
+ var parse = getParse((content, options, isDocument2, context) => options._useHtmlParser2 ? parseWithHtmlparser2(content, options) : parseWithParse5(content, options, isDocument2, context));
1627
+
1628
+ // src/selection.ts
1629
+ var numeric = /^(?:0|[1-9]\d*)$/;
1630
+ var isMarkup = (value) => /<[a-zA-Z!/?]/.test(value);
1631
+ function* customPseudoArguments(selector, name) {
1632
+ let attributeDepth = 0;
1633
+ let quote = "";
1634
+ for (let index = 0; index < selector.length; index++) {
1635
+ const character = selector[index];
1636
+ if (character === "\\") {
1637
+ index++;
1638
+ continue;
1639
+ }
1640
+ if (quote) {
1641
+ if (character === quote)
1642
+ quote = "";
1643
+ continue;
1644
+ }
1645
+ if (character === '"' || character === "'") {
1646
+ quote = character;
1647
+ continue;
1648
+ }
1649
+ if (character === "[") {
1650
+ attributeDepth++;
1651
+ continue;
1652
+ }
1653
+ if (character === "]") {
1654
+ attributeDepth--;
1655
+ continue;
1656
+ }
1657
+ if (attributeDepth || character !== ":" || selector[index - 1] === ":")
1658
+ continue;
1659
+ const start = index + 1;
1660
+ let end = start;
1661
+ while (/[\w-]/.test(selector[end] ?? "") && end < selector.length)
1662
+ end++;
1663
+ if (selector.slice(start, end).toLowerCase() !== name.toLowerCase())
1664
+ continue;
1665
+ index = end - 1;
1666
+ if (selector[end] !== "(") {
1667
+ yield void 0;
1668
+ continue;
1669
+ }
1670
+ const argumentStart = end + 1;
1671
+ let depth = 1;
1672
+ let argumentQuote = "";
1673
+ for (end++; end < selector.length; end++) {
1674
+ const next = selector[end];
1675
+ if (next === "\\") {
1676
+ end++;
1677
+ continue;
1678
+ }
1679
+ if (argumentQuote) {
1680
+ if (next === argumentQuote)
1681
+ argumentQuote = "";
1682
+ continue;
1683
+ }
1684
+ if (next === '"' || next === "'") {
1685
+ argumentQuote = next;
1686
+ continue;
1687
+ }
1688
+ if (next === "(")
1689
+ depth++;
1690
+ else if (next === ")" && --depth === 0)
1691
+ break;
1692
+ }
1693
+ if (depth)
1694
+ continue;
1695
+ yield selector.slice(argumentStart, end);
1696
+ index = end;
1697
+ }
1698
+ }
1699
+ var Cheerio = class {
1700
+ cheerio = "[cheerio object]";
1701
+ constructor(api, document, ids = [], root = null, options = {}, values) {
1702
+ Object.defineProperties(this, {
1703
+ _document: { value: document, writable: true, configurable: true },
1704
+ _api: { value: api, writable: true, configurable: true },
1705
+ _ids: { value: ids, writable: true, configurable: true },
1706
+ _values: { value: values, writable: true, configurable: true },
1707
+ _lease: { value: retainNodes(document, ids), writable: true, configurable: true },
1708
+ options: { value: options, writable: true, configurable: true, enumerable: true },
1709
+ _root: { value: root, writable: true, configurable: true, enumerable: true },
1710
+ length: { configurable: true, enumerable: true, get: () => this._values?.length ?? this._ids.length, set: (value) => {
1711
+ if (this._values)
1712
+ this._values.length = value;
1713
+ else
1714
+ this._ids.length = value;
1715
+ this._lease = retainNodes(document, this._values ? [] : this._ids);
1716
+ } }
1717
+ });
1718
+ delete this.cheerio;
1719
+ return new Proxy(this, {
1720
+ get: (target, property2, receiver) => typeof property2 === "string" && numeric.test(property2) ? target._values ? target._values[Number(property2)] : target._ids[Number(property2)] === void 0 ? void 0 : getNode(document, target._ids[Number(property2)]) : Reflect.get(target, property2, receiver),
1721
+ set: (target, property2, value, receiver) => {
1722
+ if (typeof property2 === "string" && numeric.test(property2)) {
1723
+ if (target._values)
1724
+ target._values[Number(property2)] = value;
1725
+ else {
1726
+ const id = importNodes(document, [value])[0];
1727
+ if (id === void 0) {
1728
+ target._values = target._ids.map((existing) => getNode(document, existing));
1729
+ target._values[Number(property2)] = value;
1730
+ } else
1731
+ target._ids[Number(property2)] = id;
1732
+ }
1733
+ target._lease = retainNodes(document, target._values ? [] : target._ids);
1734
+ return true;
1735
+ }
1736
+ return Reflect.set(target, property2, value, receiver);
1737
+ },
1738
+ has: (target, property2) => typeof property2 === "string" && numeric.test(property2) ? Number(property2) < target.length : Reflect.has(target, property2),
1739
+ ownKeys: (target) => [...Array.from({ length: target.length }, (_, i) => String(i)), ...Reflect.ownKeys(target)],
1740
+ getOwnPropertyDescriptor: (target, property2) => typeof property2 === "string" && numeric.test(property2) && Number(property2) < target.length ? { value: target._values ? target._values[Number(property2)] : getNode(document, target._ids[Number(property2)]), writable: true, configurable: true, enumerable: true } : Reflect.getOwnPropertyDescriptor(target, property2),
1741
+ deleteProperty: (target, property2) => {
1742
+ if (typeof property2 === "string" && numeric.test(property2)) {
1743
+ if (target._values)
1744
+ delete target._values[Number(property2)];
1745
+ else
1746
+ delete target._ids[Number(property2)];
1747
+ target._lease = retainNodes(document, target._values ? [] : target._ids);
1748
+ return true;
1749
+ }
1750
+ return Reflect.deleteProperty(target, property2);
1751
+ }
1752
+ });
1753
+ }
1754
+ /** @internal */
1755
+ get ids() {
1756
+ return this._values ? importNodes(this._document, this._values) : this._ids;
1757
+ }
1758
+ /** @internal */
1759
+ op(command, args = {}) {
1760
+ const values = args;
1761
+ return operation(this._document, command, { ...values, options: values.options ?? this.options });
1762
+ }
1763
+ /** @internal */
1764
+ _query(command, args) {
1765
+ const callbacks = Object.entries(this.options.pseudos ?? {}).filter((entry) => typeof entry[1] === "function");
1766
+ if (!callbacks.length)
1767
+ return command === "select" && !args.options ? this._document.select(args.selector, args.contexts) : this.op(command, args);
1768
+ const pseudoMatches = {};
1769
+ const candidates = [.../* @__PURE__ */ new Set([...this._document.select("*"), ...args.ids ?? [], ...args.contexts ? this._document.select("*", args.contexts) : []])];
1770
+ for (const [name, callback] of callbacks) {
1771
+ for (const argument of customPseudoArguments(args.selector, name)) {
1772
+ if (argument !== void 0 && callback.length < 2)
1773
+ throw new Error(`Pseudo-class :${name} doesn't have any arguments`);
1774
+ if (argument === void 0 && callback.length >= 2)
1775
+ throw new Error(`Pseudo-class :${name} requires an argument`);
1776
+ pseudoMatches[`${name}(${argument ?? ""})`] = candidates.filter((id) => callback(getNode(this._document, id), argument ?? null));
1777
+ }
1778
+ }
1779
+ return this.op(command, { ...args, pseudoMatches });
1780
+ }
1781
+ /** @internal */
1782
+ _fromIds(ids) {
1783
+ const result = new this._api.fn.constructor(this._api, this._document, ids, this._root, this.options);
1784
+ result.prevObject = this;
1785
+ return result;
1786
+ }
1787
+ /** @internal */
1788
+ _fromValues(values) {
1789
+ const allNodes = values.every((value) => value && typeof value === "object" && typeof value.type === "string");
1790
+ const result = new this._api.fn.constructor(this._api, this._document, allNodes ? importNodes(this._document, values) : [], this._root, this.options, allNodes ? void 0 : values);
1791
+ result.prevObject = this;
1792
+ return result;
1793
+ }
1794
+ _make(value, context) {
1795
+ const result = typeof value === "string" || value?.cheerio ? this._api(value, context) : this._fromValues(value == null ? [] : typeof value === "object" && "length" in value && !value.type ? Array.from(value) : [value]);
1796
+ result.prevObject = this;
1797
+ return result;
1798
+ }
1799
+ _parse(content, options, isDocument2, context) {
1800
+ return parse(content, options, isDocument2, context);
1801
+ }
1802
+ _render(content) {
1803
+ return this._document.outerHtml(importNodes(this._document, content));
1804
+ }
1805
+ /** @internal */
1806
+ _domIds(content, contextId) {
1807
+ if (content == null || content === false)
1808
+ return [];
1809
+ if (typeof content === "string")
1810
+ return this.op("create", { html: content, contextId, options: this.options });
1811
+ if (content?.cheerio)
1812
+ return content._document && sameNodeSpace(this._document, content._document) ? content.ids : importNodes(this._document, content.toArray());
1813
+ if (typeof content === "object" && "length" in content && !content.type)
1814
+ return Array.from(content).flatMap((item) => this._domIds(item, contextId));
1815
+ return importNodes(this._document, [content]);
1816
+ }
1817
+ _makeDomArray(content, clone = false) {
1818
+ const ids = this._domIds(content);
1819
+ return (clone ? this.op("clone", { ids, deep: true }) : ids).map((id) => getNode(this._document, id));
1820
+ }
1821
+ find(selector) {
1822
+ if (!selector)
1823
+ return this._fromIds([]);
1824
+ if (typeof selector === "string")
1825
+ return this._findBySelector(selector, Infinity);
1826
+ const ids = importNodes(this._document, selector);
1827
+ return this._fromIds(ids.filter((id) => this.ids.some((container) => this.op("contains", { container, contained: id }))));
1828
+ }
1829
+ _findBySelector(selector, limit) {
1830
+ const ids = this._query("select", { selector, contexts: this.ids });
1831
+ return this._fromIds(Number.isFinite(limit) ? ids.slice(0, limit) : ids);
1832
+ }
1833
+ /** @internal */
1834
+ _filterIds(ids, selector) {
1835
+ if (!selector)
1836
+ return ids;
1837
+ if (typeof selector === "string")
1838
+ return this._query("matches", { ids, selector, options: this.options });
1839
+ return ids.filter((id, index) => this._predicate(selector, getNode(this._document, id), index));
1840
+ }
1841
+ /** @internal */
1842
+ _predicate(selector, node, index) {
1843
+ if (typeof selector === "function")
1844
+ return !!selector.call(node, index, node);
1845
+ if (typeof selector === "string")
1846
+ return this._query("matches", { ids: importNodes(this._document, [node]), selector, options: this.options }).length > 0;
1847
+ if (selector?.cheerio)
1848
+ return selector.toArray().includes(node);
1849
+ return node === selector;
1850
+ }
1851
+ /** @internal */
1852
+ _traverse(kind, selector) {
1853
+ let ids = this.op("traverse", { ids: this.ids, kind });
1854
+ ids = this._filterIds(ids, selector);
1855
+ if (this.length > 1 && ids.length > 1) {
1856
+ if (kind === "parents" || kind === "siblings")
1857
+ ids = this.op("uniqueSort", { ids });
1858
+ else if (!["next", "prev", "contents"].includes(kind))
1859
+ ids = [...new Set(ids)];
1860
+ if (kind === "parents")
1861
+ ids.reverse();
1862
+ }
1863
+ return this._fromIds(ids);
1864
+ }
1865
+ parent(selector) {
1866
+ return this._traverse("parent", selector);
1867
+ }
1868
+ parents(selector) {
1869
+ return this._traverse("parents", selector);
1870
+ }
1871
+ next(selector) {
1872
+ return this._traverse("next", selector);
1873
+ }
1874
+ prev(selector) {
1875
+ return this._traverse("prev", selector);
1876
+ }
1877
+ nextAll(selector) {
1878
+ return this._traverse("nextAll", selector);
1879
+ }
1880
+ prevAll(selector) {
1881
+ return this._traverse("prevAll", selector);
1882
+ }
1883
+ siblings(selector) {
1884
+ return this._traverse("siblings", selector);
1885
+ }
1886
+ children(selector) {
1887
+ return this._traverse("children", selector);
1888
+ }
1889
+ contents() {
1890
+ return this._traverse("contents");
1891
+ }
1892
+ /** @internal */
1893
+ _until(kind, until, filter) {
1894
+ let ids = [];
1895
+ for (const id of this.ids)
1896
+ for (const candidate of this.op("traverse", { ids: [id], kind })) {
1897
+ if (until && this._predicate(until, getNode(this._document, candidate), ids.length))
1898
+ break;
1899
+ ids.push(candidate);
1900
+ }
1901
+ ids = this._filterIds(ids, filter);
1902
+ if (this.length > 1 && ids.length > 1)
1903
+ ids = kind === "parents" ? this.op("uniqueSort", { ids }).reverse() : [...new Set(ids)];
1904
+ return this._fromIds(ids);
1905
+ }
1906
+ parentsUntil(until, filter) {
1907
+ return this._until("parents", until, filter);
1908
+ }
1909
+ nextUntil(until, filter) {
1910
+ return this._until("nextAll", until, filter);
1911
+ }
1912
+ prevUntil(until, filter) {
1913
+ return this._until("prevAll", until, filter);
1914
+ }
1915
+ closest(selector) {
1916
+ if (!selector)
1917
+ return this._fromIds([]);
1918
+ const result = [];
1919
+ for (const id of this.ids) {
1920
+ const record = nodeRecord(this._document, id);
1921
+ const candidates = [...["tag", "script", "style"].includes(record.type) ? [id] : [], ...this.op("traverse", { ids: [id], kind: "parents" })];
1922
+ const match = candidates.find((candidate) => this._predicate(selector, getNode(this._document, candidate), 0));
1923
+ if (match !== void 0 && !result.includes(match))
1924
+ result.push(match);
1925
+ }
1926
+ return this._fromIds(result);
1927
+ }
1928
+ each(callback) {
1929
+ const length = this.length;
1930
+ for (let i = 0; i < length; i++)
1931
+ if (callback.call(this[i], i, this[i]) === false)
1932
+ break;
1933
+ return this;
1934
+ }
1935
+ map(callback) {
1936
+ const result = [];
1937
+ for (let i = 0; i < this.length; i++) {
1938
+ const value = callback.call(this[i], i, this[i]);
1939
+ if (value != null)
1940
+ result.push(...Array.isArray(value) ? value : [value]);
1941
+ }
1942
+ return this._fromValues(result);
1943
+ }
1944
+ filter(selector) {
1945
+ return typeof selector === "string" ? this._fromIds(this._query("matches", { ids: this.ids, selector, options: this.options })) : this._fromValues(this.toArray().filter((node, i) => this._predicate(selector, node, i)));
1946
+ }
1947
+ filterArray(nodes, match, xmlMode, root) {
1948
+ const matcher = match;
1949
+ if (typeof match !== "string")
1950
+ return nodes.filter((node, index) => typeof matcher === "function" ? matcher.call(node, index, node) : matcher?.cheerio ? matcher.toArray().includes(node) : matcher === node);
1951
+ const document = this?._document ?? nodeBinding(root)?.document ?? nodeBinding(nodes[0])?.document ?? new (requireNative()).NativeDocument("", false);
1952
+ const ids = importNodes(document, nodes);
1953
+ const selected = new Set(operation(document, "matches", { ids, selector: match, options: { xmlMode } }));
1954
+ return nodes.filter((node) => {
1955
+ const id = nodeId(node, document);
1956
+ return id !== void 0 && selected.has(id);
1957
+ });
1958
+ }
1959
+ not(selector) {
1960
+ if (typeof selector === "string") {
1961
+ const matched = new Set(this._query("matches", { ids: this.ids, selector, options: this.options }));
1962
+ return this._fromIds(this.ids.filter((id) => !matched.has(id)));
1963
+ }
1964
+ return this._fromValues(this.toArray().filter((node, i) => !this._predicate(selector, node, i)));
1965
+ }
1966
+ is(selector) {
1967
+ return typeof selector === "string" ? this._query("matches", { ids: this.ids, selector, options: this.options }).length > 0 : !!selector && this.toArray().some((node, i) => this._predicate(selector, node, i));
1968
+ }
1969
+ has(selector) {
1970
+ return this.filter(((_i, node) => this._make(node).find(selector).length > 0));
1971
+ }
1972
+ first() {
1973
+ return this.length > 1 ? this.slice(0, 1) : this;
1974
+ }
1975
+ last() {
1976
+ return this.length > 0 ? this.slice(-1) : this;
1977
+ }
1978
+ eq(index) {
1979
+ index = +index;
1980
+ if (index === 0 && this.length <= 1)
1981
+ return this;
1982
+ if (index < 0)
1983
+ index += this.length;
1984
+ return this._fromValues(this[index] === void 0 ? [] : [this[index]]);
1985
+ }
1986
+ get(index) {
1987
+ return index == null ? this.toArray() : this[index < 0 ? this.length + index : index];
1988
+ }
1989
+ toArray() {
1990
+ return Array.from({ length: this.length }, (_unused, i) => this[i]);
1991
+ }
1992
+ slice(start, end) {
1993
+ return this._values ? this._fromValues(this._values.slice(start, end)) : this._fromIds(this._ids.slice(start, end));
1994
+ }
1995
+ end() {
1996
+ return this.prevObject ?? this._make([]);
1997
+ }
1998
+ add(other, context) {
1999
+ return this._fromIds(this.op("uniqueSort", { ids: [...this.ids, ...this._api(other, context).ids] }));
2000
+ }
2001
+ addBack(selector) {
2002
+ return this.prevObject ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject) : this;
2003
+ }
2004
+ index(selector) {
2005
+ const haystack = selector == null ? this.parent().children() : typeof selector === "string" ? this._api(selector) : this;
2006
+ const needle = selector == null || typeof selector === "string" ? this[0] : selector?.cheerio ? selector[0] : selector;
2007
+ return haystack.toArray().indexOf(needle);
2008
+ }
2009
+ splice(...args) {
2010
+ return Reflect.apply(Array.prototype.splice, this, args);
2011
+ }
2012
+ *[Symbol.iterator]() {
2013
+ for (let i = 0; i < this.length; i++)
2014
+ yield this[i];
2015
+ }
2016
+ /** @internal */
2017
+ _insert(position, content) {
2018
+ const targets = this.ids.filter((id) => ["root", "tag", "script", "style", "cdata"].includes(nodeRecord(this._document, id).type));
2019
+ if (!targets.length)
2020
+ return this;
2021
+ if (typeof content[0] === "function")
2022
+ return this.each((index, node) => {
2023
+ if (!targets.includes(this.ids[index]))
2024
+ return;
2025
+ if ((position === "before" || position === "after") && nodeRecord(this._document, this.ids[index]).parent == null)
2026
+ return;
2027
+ const value = content[0].call(node, index, this._document.innerHtml(this.ids[index]));
2028
+ let nodes2 = this._domIds(value);
2029
+ if (index < this.length - 1)
2030
+ nodes2 = this.op("clone", { ids: nodes2, deep: true });
2031
+ this.op("insert", { targetIds: [this.ids[index]], nodeIds: nodes2, position });
2032
+ });
2033
+ let nodes = this._domIds(content);
2034
+ if (targets[targets.length - 1] !== this.ids[this.ids.length - 1])
2035
+ nodes = this.op("clone", { ids: nodes, deep: true });
2036
+ this.op("insert", { targetIds: targets, nodeIds: nodes, position });
2037
+ return this;
2038
+ }
2039
+ append(...content) {
2040
+ return this._insert("append", content);
2041
+ }
2042
+ prepend(...content) {
2043
+ return this._insert("prepend", content);
2044
+ }
2045
+ before(...content) {
2046
+ return this._insert("before", content);
2047
+ }
2048
+ after(...content) {
2049
+ return this._insert("after", content);
2050
+ }
2051
+ appendTo(target) {
2052
+ this._api(target).append(this);
2053
+ return this;
2054
+ }
2055
+ prependTo(target) {
2056
+ this._api(target).prepend(this);
2057
+ return this;
2058
+ }
2059
+ /** @internal */
2060
+ _insertRelative(target, position) {
2061
+ const targets = this._api(target).ids;
2062
+ this.remove();
2063
+ const inserted = [];
2064
+ for (const id of targets) {
2065
+ if (nodeRecord(this._document, id).parent == null)
2066
+ continue;
2067
+ const clones = this.op("clone", { ids: this.ids, deep: true });
2068
+ this.op("insert", { targetIds: [id], nodeIds: clones, position });
2069
+ inserted.push(...clones);
2070
+ }
2071
+ return this._fromIds(inserted);
2072
+ }
2073
+ insertBefore(target) {
2074
+ return this._insertRelative(target, "before");
2075
+ }
2076
+ insertAfter(target) {
2077
+ return this._insertRelative(target, "after");
2078
+ }
2079
+ remove(selector) {
2080
+ this.op("remove", { ids: selector ? this.filter(selector).ids : this.ids });
2081
+ return this;
2082
+ }
2083
+ replaceWith(content) {
2084
+ return this.each((index, node) => {
2085
+ if (nodeRecord(this._document, this.ids[index]).parent == null)
2086
+ return;
2087
+ const value = typeof content === "function" ? content.call(node, index, node) : content;
2088
+ this.op("insert", { targetIds: [this.ids[index]], nodeIds: this._domIds(value), position: "replace" });
2089
+ });
2090
+ }
2091
+ empty() {
2092
+ for (const id of this.ids)
2093
+ this.op("setNode", { id, field: "children", value: [] });
2094
+ return this;
2095
+ }
2096
+ html(content) {
2097
+ if (content === void 0)
2098
+ return this.length && ["root", "tag", "script", "style", "cdata"].includes(nodeRecord(this._document, this.ids[0]).type) ? this._document.innerHtml(this.ids[0]) : null;
2099
+ if (!content?.cheerio) {
2100
+ this.op("html", { ids: this.ids, value: String(content) });
2101
+ return this;
2102
+ }
2103
+ for (const id of this.ids) {
2104
+ const nodes = content?.cheerio ? importNodes(this._document, content.toArray()) : this._domIds(String(content), id);
2105
+ this.op("setNode", { id, field: "children", value: nodes });
2106
+ }
2107
+ return this;
2108
+ }
2109
+ text(content) {
2110
+ if (content === void 0)
2111
+ return this._document.text(this.ids);
2112
+ if (typeof content !== "function") {
2113
+ this.op("text", { ids: this.ids, value: String(content) });
2114
+ return this;
2115
+ }
2116
+ for (let i = 0; i < this.ids.length; i++) {
2117
+ const id = this.ids[i];
2118
+ const value = typeof content === "function" ? content.call(getNode(this._document, id), i, this._document.text([id])) : content;
2119
+ this.op("text", { ids: [id], value: String(value) });
2120
+ }
2121
+ return this;
2122
+ }
2123
+ toString() {
2124
+ return this._document.outerHtml(this.ids);
2125
+ }
2126
+ clone() {
2127
+ return this._fromIds(this.op("clone", { ids: this.ids, deep: true }));
2128
+ }
2129
+ /** @internal */
2130
+ _deepest(id, tagsOnly = false) {
2131
+ for (; ; ) {
2132
+ const children2 = this.op("traverse", { ids: [id], kind: "children" });
2133
+ const child = tagsOnly ? children2.find((candidate) => nodeRecord(this._document, candidate).type === "tag") : children2[0];
2134
+ if (child === void 0)
2135
+ return id;
2136
+ id = child;
2137
+ }
2138
+ }
2139
+ /** @internal */
2140
+ _wrap(content, inner) {
2141
+ const lastParent = this.parents().last();
2142
+ for (let i = 0; i < this.length; i++) {
2143
+ const id = this.ids[i];
2144
+ const node = getNode(this._document, id);
2145
+ const value = typeof content === "function" ? content.call(node, i, node) : typeof content === "string" && !isMarkup(content) ? lastParent.find(content).clone() : content;
2146
+ let wrappers = this._domIds(value);
2147
+ if (i < this.length - 1)
2148
+ wrappers = this.op("clone", { ids: wrappers, deep: true });
2149
+ const wrapper = wrappers[0];
2150
+ if (wrapper === void 0 || !["root", "tag", "script", "style"].includes(nodeRecord(this._document, wrapper).type))
2151
+ continue;
2152
+ const deepest = this._deepest(wrapper);
2153
+ if (inner) {
2154
+ if (!["root", "tag", "script", "style", "cdata"].includes(nodeRecord(this._document, id).type))
2155
+ continue;
2156
+ const contents = this.op("traverse", { ids: [id], kind: "contents" });
2157
+ this.op("setNode", { id: deepest, field: "children", value: contents });
2158
+ this.op("setNode", { id, field: "children", value: [wrapper] });
2159
+ } else if (nodeRecord(this._document, id).parent != null) {
2160
+ this.op("insert", { targetIds: [id], nodeIds: [wrapper], position: "before" });
2161
+ this.op("setNode", { id: deepest, field: "children", value: [id] });
2162
+ }
2163
+ }
2164
+ return this;
2165
+ }
2166
+ wrap(content) {
2167
+ return this._wrap(content, false);
2168
+ }
2169
+ wrapInner(content) {
2170
+ return this._wrap(content, true);
2171
+ }
2172
+ unwrap(selector) {
2173
+ this.op("remove", { ids: this.parent(selector).not("body").ids, keepChildren: true });
2174
+ return this;
2175
+ }
2176
+ wrapAll(content) {
2177
+ if (!this.length)
2178
+ return this;
2179
+ const first = this[0];
2180
+ const wrappers = this._make(typeof content === "function" ? content.call(first, 0, first) : content).insertBefore(first);
2181
+ const root = [...wrappers.ids].reverse().find((id) => nodeRecord(this._document, id).type === "tag");
2182
+ if (root !== void 0)
2183
+ this.op("insert", { targetIds: [this._deepest(root, true)], nodeIds: this.ids, position: "append" });
2184
+ return this;
2185
+ }
2186
+ extract(map) {
2187
+ return extract.call(this, map);
2188
+ }
2189
+ };
2190
+ Object.defineProperty(Cheerio.prototype, "cheerio", { value: "[cheerio object]", writable: true, configurable: true });
2191
+ installAttributes(Cheerio);
2192
+ var nativeExtractionMethods = Object.freeze({
2193
+ make: Cheerio.prototype._make,
2194
+ find: Cheerio.prototype._findBySelector,
2195
+ prop: Cheerio.prototype.prop,
2196
+ extract: Cheerio.prototype.extract
2197
+ });
2198
+
2199
+ // src/extract.ts
2200
+ var import_node_util2 = require("util");
2201
+ function plainKeys(map) {
2202
+ return !import_node_util2.types.isProxy(map) && (Object.getPrototypeOf(map) === Object.prototype || Object.getPrototypeOf(map) === null) ? Object.keys(map) : void 0;
2203
+ }
2204
+ function nativePrefix(scope, map, keys, key) {
2205
+ if (!keys || scope._make !== nativeExtractionMethods.make || scope._findBySelector !== nativeExtractionMethods.find || scope.prop !== nativeExtractionMethods.prop || scope.extract !== nativeExtractionMethods.extract) return void 0;
2206
+ const prefix = /* @__PURE__ */ Object.create(null);
2207
+ let count = 0;
2208
+ let plan;
2209
+ const index = keys.indexOf(key);
2210
+ for (let position = index; position < keys.length; position++) {
2211
+ const name = keys[position];
2212
+ const slot = Object.getOwnPropertyDescriptor(map, name);
2213
+ if (!slot || !slot.enumerable || !("value" in slot)) break;
2214
+ Object.defineProperty(prefix, name, { value: slot.value, enumerable: true, configurable: true });
2215
+ const compiled = compileExtractPlan(prefix, scope.options);
2216
+ if (!compiled) {
2217
+ delete prefix[name];
2218
+ break;
2219
+ }
2220
+ plan = compiled;
2221
+ count++;
2222
+ }
2223
+ if (!plan || !count) return void 0;
2224
+ const values = scope.op("extractPlan", { ids: scope.ids, plan });
2225
+ hydrateExtractResult(values, plan.entries);
2226
+ return { keys: Object.keys(prefix), values };
2227
+ }
2228
+ function extract(map) {
2229
+ const result = {};
2230
+ const keys = plainKeys(map);
2231
+ const processed = /* @__PURE__ */ new Set();
2232
+ for (const key in map) {
2233
+ if (processed.has(key)) continue;
2234
+ const prefix = Object.getPrototypeOf(result) === Object.prototype ? nativePrefix(this, map, keys, key) : void 0;
2235
+ if (prefix) {
2236
+ for (const name of prefix.keys) {
2237
+ Object.defineProperty(result, name, { value: prefix.values[name], enumerable: true, configurable: true, writable: true });
2238
+ processed.add(name);
2239
+ }
2240
+ continue;
2241
+ }
2242
+ const entry = map[key];
2243
+ const all = Array.isArray(entry);
2244
+ const descriptor = all ? entry[0] : entry;
2245
+ const selector = typeof descriptor === "string" ? descriptor : descriptor.selector;
2246
+ const value = typeof descriptor === "string" ? "textContent" : descriptor.value ?? "textContent";
2247
+ const selection = this._findBySelector(selector, all ? Infinity : 1);
2248
+ const read = (index) => {
2249
+ if (typeof value === "function") return value(selection[index], key, result);
2250
+ const scope = this._make === nativeExtractionMethods.make ? this._fromIds([selection.ids[index]]) : this._make(selection[index]);
2251
+ return typeof value === "string" ? scope.prop(value) : scope.extract(value);
2252
+ };
2253
+ let extracted;
2254
+ if (all) {
2255
+ const values = [];
2256
+ for (let index = 0; index < selection.length; index += 1) {
2257
+ const value2 = read(index);
2258
+ if (value2 != null) values.push(...Array.isArray(value2) ? value2 : [value2]);
2259
+ }
2260
+ extracted = values;
2261
+ } else {
2262
+ extracted = selection.length ? read(0) : void 0;
2263
+ }
2264
+ result[key] = extracted;
2265
+ }
2266
+ return result;
2267
+ }
2268
+
2269
+ // src/index.ts
2270
+ var import_promises = require("timers/promises");
2271
+ var import_node_os = require("os");
2272
+
2273
+ // src/utils.ts
2274
+ function isHtml(value) {
2275
+ if (typeof value !== "string") return false;
2276
+ const start = value.indexOf("<");
2277
+ return start >= 0 && /[A-Za-z!]/.test(value[start + 1] ?? "") && value.indexOf(">", start + 2) >= 0;
2278
+ }
2279
+
2280
+ // src/io.ts
2281
+ var import_node_stream = require("stream");
2282
+ var import_node_http = require("http");
2283
+ var import_node_https = require("https");
2284
+ var import_node_querystring = require("querystring");
2285
+ var import_node_util3 = require("util");
2286
+
2287
+ // src/index.ts
2288
+ var dom = {
2289
+ Node,
2290
+ DataNode,
2291
+ NodeWithChildren,
2292
+ Document,
2293
+ Element,
2294
+ Text,
2295
+ Comment,
2296
+ ProcessingInstruction,
2297
+ CDATA,
2298
+ ElementType,
2299
+ isTag,
2300
+ isText,
2301
+ isComment,
2302
+ isDirective,
2303
+ isDocument,
2304
+ isCDATA,
2305
+ hasChildren
2306
+ };
2307
+ function flattenOptions(options, base) {
2308
+ const result = { _useHtmlParser2: false, ...base, ...options };
2309
+ if (options?.xml) {
2310
+ result._useHtmlParser2 = true;
2311
+ result.xmlMode = true;
2312
+ if (options.xml !== true) Object.assign(result, options.xml);
2313
+ } else if (options?.xmlMode) result._useHtmlParser2 = true;
2314
+ return result;
2315
+ }
2316
+ function createAPI(document, options, initialRoot = document.rootId()) {
2317
+ const internal = flattenOptions(options);
2318
+ class LoadedCheerio extends Cheerio {
2319
+ }
2320
+ let api;
2321
+ const initialize2 = function(selector, context, root, override) {
2322
+ if (selector?.cheerio) return selector;
2323
+ const opts = flattenOptions(override, internal);
2324
+ const rootIds = root === void 0 ? [initialRoot] : typeof root === "string" ? [makeRoot(document, operation(document, "create", { html: root, options: opts }))] : root?.cheerio ? importNodes(document, root.toArray()) : importNodes(document, root);
2325
+ const rootInstance = new LoadedCheerio(api, document, rootIds, null, opts);
2326
+ rootInstance._root = rootInstance;
2327
+ if (!selector) return new LoadedCheerio(api, document, [], rootInstance, opts);
2328
+ if (typeof selector === "string" && isHtml(selector)) return new LoadedCheerio(api, document, operation(document, "create", { html: selector, options: opts }), rootInstance, opts);
2329
+ if (typeof selector === "object") {
2330
+ const values = "length" in selector && !selector.type ? Array.from(selector) : [selector];
2331
+ const allNodes = values.every((value) => value && typeof value === "object" && typeof value.type === "string");
2332
+ return new LoadedCheerio(api, document, allNodes ? importNodes(document, values) : [], rootInstance, opts, allNodes ? void 0 : values);
2333
+ }
2334
+ if (typeof selector !== "string") throw new TypeError("Unexpected type of selector");
2335
+ let search = selector;
2336
+ let searchContext = rootInstance;
2337
+ if (context) {
2338
+ if (typeof context === "string") {
2339
+ if (isHtml(context)) searchContext = new LoadedCheerio(api, document, [makeRoot(document, operation(document, "create", { html: context, options: opts }))], rootInstance, opts);
2340
+ else search = `${context} ${search}`;
2341
+ } else if (context.cheerio) searchContext = context;
2342
+ else searchContext = new LoadedCheerio(api, document, importNodes(document, context), rootInstance, opts);
2343
+ }
2344
+ return searchContext.find(search);
2345
+ };
2346
+ api = Object.assign(initialize2, {
2347
+ load,
2348
+ _root: getNode(document, initialRoot),
2349
+ _options: internal,
2350
+ fn: LoadedCheerio.prototype,
2351
+ prototype: LoadedCheerio.prototype,
2352
+ root() {
2353
+ return this(this._root);
2354
+ },
2355
+ html(dom2, renderOptions) {
2356
+ if (!this) return "";
2357
+ if (dom2 && typeof dom2 === "object" && !("length" in dom2) && !("type" in dom2)) {
2358
+ renderOptions = dom2;
2359
+ dom2 = void 0;
2360
+ }
2361
+ const nodes = dom2 === void 0 ? [this._root] : this(dom2).toArray();
2362
+ const binding = nodeBinding(this._root);
2363
+ return operation(binding.document, "render", { ids: importNodes(binding.document, nodes), options: flattenOptions(renderOptions, this._options) });
2364
+ },
2365
+ xml(dom2) {
2366
+ const binding = nodeBinding(this._root);
2367
+ return operation(binding.document, "render", { ids: importNodes(binding.document, dom2 === void 0 ? [this._root] : this(dom2).toArray()), options: { ...this._options, xmlMode: true, _useHtmlParser2: true } });
2368
+ },
2369
+ text(elements) {
2370
+ if (!elements && !this) return "";
2371
+ const nodes = elements ?? [this._root];
2372
+ const binding = this ? nodeBinding(this._root) : nodeBinding(nodes[0]);
2373
+ if (binding) return binding.document.text(importNodes(binding.document, nodes));
2374
+ const doc = routeDocument(new (requireNative()).NativeDocument("", false));
2375
+ return doc.text(importNodes(doc, nodes));
2376
+ },
2377
+ parseHTML(data2, context, keepScripts = typeof context === "boolean" ? context : false) {
2378
+ if (!data2 || typeof data2 !== "string") return null;
2379
+ if (typeof context === "boolean") keepScripts = context;
2380
+ const parsed = this.load(data2, this._options, false);
2381
+ if (!keepScripts) parsed("script").remove();
2382
+ return parsed._root.children.slice();
2383
+ },
2384
+ extract(map) {
2385
+ return this.root().extract(map);
2386
+ },
2387
+ contains,
2388
+ merge
2389
+ });
2390
+ return api;
2391
+ }
2392
+ function makeRoot(document, children2) {
2393
+ const id = operation(document, "createNode", { type: "root" });
2394
+ operation(document, "setNode", { id, field: "children", value: children2 });
2395
+ return id;
2396
+ }
2397
+ function load(content, options, isDocument2 = true) {
2398
+ if (content == null) throw new Error("cheerio.load() expects a string");
2399
+ const opts = flattenOptions(options);
2400
+ const binding = requireNative();
2401
+ const string = Buffer.isBuffer(content) ? content.toString() : typeof content === "string" ? content : void 0;
2402
+ const document = string === void 0 ? routeDocument(new binding.NativeDocument("", false, JSON.stringify(cleanParserOptions(opts))), opts) : parseNativeDocument(string, opts, isDocument2);
2403
+ if (string !== void 0) return createAPI(document, opts);
2404
+ const nodes = importNodes(document, content);
2405
+ if (!Array.isArray(content) && content.type === "root") return createAPI(document, opts, nodes[0]);
2406
+ operation(document, "setNode", { id: document.rootId(), field: "children", value: nodes });
2407
+ return createAPI(routeDocument(document, opts), opts);
2408
+ }
2409
+ function contains(container, contained) {
2410
+ if (!container || !contained || container === contained) return false;
2411
+ let parent = nodeBinding(container);
2412
+ if (!parent) {
2413
+ const document = routeDocument(new (requireNative()).NativeDocument("", false));
2414
+ importNodes(document, [container]);
2415
+ parent = nodeBinding(container);
2416
+ }
2417
+ const child = nodeBinding(contained);
2418
+ return !!parent && !!child && sameNodeSpace(child.document, parent.document) && operation(parent.document, "contains", { container: parent.id, contained: child.id });
2419
+ }
2420
+ function merge(first, second) {
2421
+ const arrayLike = (value) => Array.isArray(value) || value && typeof value === "object" && typeof value.length === "number" && value.length >= 0 && Array.from({ length: value.length }, (_unused, i) => i in value).every(Boolean);
2422
+ if (!arrayLike(first) || !arrayLike(second)) return void 0;
2423
+ const writable = first;
2424
+ let length = first.length;
2425
+ for (let i = 0, count = +second.length; i < count; i++) writable[length++] = second[i];
2426
+ writable.length = length;
2427
+ return writable;
2428
+ }
2429
+
2430
+ // src/slim.ts
2431
+ function load2(content, options, _isDocument) {
2432
+ return load(content, { ...options, _useHtmlParser2: true }, false);
2433
+ }
2434
+ // Annotate the CommonJS export names for ESM import in node:
2435
+ 0 && (module.exports = {
2436
+ contains,
2437
+ dom,
2438
+ load,
2439
+ merge
2440
+ });
2441
+ //# sourceMappingURL=slim.cjs.map