visaljs 0.0.10 → 0.0.11

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 (221) hide show
  1. package/README.md +12 -4
  2. package/THIRD_PARTY_LICENSES +31 -1
  3. package/cli.js +962 -68
  4. package/node/include/js_node.h +11 -1
  5. package/node/prelude/_http_common.js +29 -0
  6. package/node/prelude/async_hooks.js +50 -11
  7. package/node/prelude/child_process.js +31 -4
  8. package/node/prelude/console.js +311 -143
  9. package/node/prelude/crypto.js +6 -4
  10. package/node/prelude/dgram.js +1169 -0
  11. package/node/prelude/diagnostics_channel.js +3 -1
  12. package/node/prelude/dns.js +250 -45
  13. package/node/prelude/dns_promises.js +8 -2
  14. package/node/prelude/fs_promises.js +9 -1
  15. package/node/prelude/http.js +395 -86
  16. package/node/prelude/https.js +13 -4
  17. package/node/prelude/internal/console_class.js +7 -0
  18. package/node/prelude/internal/console_global.js +25 -0
  19. package/node/prelude/internal/crypto/key_encryption.js +217 -0
  20. package/node/prelude/internal/crypto/keys.js +161 -26
  21. package/node/prelude/internal/crypto/random.js +24 -0
  22. package/node/prelude/internal/crypto/util.js +2 -1
  23. package/node/prelude/internal/crypto_x509.js +161 -0
  24. package/node/prelude/internal/dns_classes.js +6 -0
  25. package/node/prelude/internal/dns_resolver.js +371 -0
  26. package/node/prelude/internal/errors.js +9 -0
  27. package/node/prelude/internal/events_on.js +82 -37
  28. package/node/prelude/internal/features.js +8 -4
  29. package/node/prelude/internal/fs_filehandle.js +10 -4
  30. package/node/prelude/internal/perf_histogram.js +1 -1
  31. package/node/prelude/internal/process_more.js +32 -17
  32. package/node/prelude/internal/process_signals.js +8 -2
  33. package/node/prelude/internal/punycode.ts +163 -0
  34. package/node/prelude/internal/readline.js +648 -274
  35. package/node/prelude/internal/readline_editor.js +1240 -0
  36. package/node/prelude/internal/string_width.js +43 -0
  37. package/node/prelude/internal/tls/common.js +145 -33
  38. package/node/prelude/internal/tls/wrap.js +182 -49
  39. package/node/prelude/internal/tls/x509.js +4 -1
  40. package/node/prelude/internal/udp.js +177 -0
  41. package/node/prelude/net.js +13 -1
  42. package/node/prelude/os.js +24 -6
  43. package/node/prelude/perf_hooks.js +37 -2
  44. package/node/prelude/punycode.js +2 -130
  45. package/node/prelude/readline.js +113 -4
  46. package/node/prelude/readline_promises.js +56 -32
  47. package/node/prelude/tls.js +21 -4
  48. package/node/prelude/util.js +3 -16
  49. package/node/src/host_dns.c +623 -0
  50. package/node/src/host_http.c +12 -0
  51. package/node/src/host_net.c +46 -0
  52. package/node/src/host_os.c +1 -6
  53. package/node/src/host_sys.c +70 -0
  54. package/node/src/host_udp.c +418 -0
  55. package/node/third_party/c-ares/LICENSE.md +24 -0
  56. package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
  57. package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
  58. package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
  59. package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
  60. package/node/third_party/c-ares/include/ares.h +1237 -0
  61. package/node/third_party/c-ares/include/ares_build.h +202 -0
  62. package/node/third_party/c-ares/include/ares_dns.h +127 -0
  63. package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
  64. package/node/third_party/c-ares/include/ares_nameser.h +510 -0
  65. package/node/third_party/c-ares/include/ares_version.h +47 -0
  66. package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
  67. package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
  68. package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
  69. package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
  70. package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
  71. package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
  72. package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
  73. package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
  74. package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
  75. package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
  76. package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
  77. package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
  78. package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
  79. package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
  80. package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
  81. package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
  82. package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
  83. package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
  84. package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
  85. package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
  86. package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
  87. package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
  88. package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
  89. package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
  90. package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
  91. package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
  92. package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
  93. package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
  94. package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
  95. package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
  96. package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
  97. package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
  98. package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
  99. package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
  100. package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
  101. package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
  102. package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
  103. package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
  104. package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
  105. package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
  106. package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
  107. package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
  108. package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
  109. package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
  110. package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
  111. package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
  112. package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
  113. package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
  114. package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
  115. package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
  116. package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
  117. package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
  118. package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
  119. package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
  120. package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
  121. package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
  122. package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
  123. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  124. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  125. package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
  126. package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
  127. package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
  128. package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
  129. package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
  130. package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
  131. package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
  132. package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
  133. package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
  134. package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
  135. package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
  136. package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
  137. package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
  138. package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
  139. package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
  140. package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
  141. package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
  142. package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
  143. package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
  144. package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
  145. package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
  146. package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
  147. package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
  148. package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
  149. package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
  150. package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
  151. package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
  152. package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
  153. package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
  154. package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
  155. package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
  156. package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  157. package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  158. package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  159. package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  160. package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  161. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  162. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  163. package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  164. package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  165. package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  166. package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  167. package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
  168. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
  169. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
  170. package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
  171. package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
  172. package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
  173. package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
  174. package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
  175. package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
  176. package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
  177. package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
  178. package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
  179. package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  180. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
  181. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
  182. package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
  183. package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
  184. package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
  185. package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
  186. package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
  187. package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
  188. package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
  189. package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
  190. package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
  191. package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
  192. package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
  193. package/package.json +1 -1
  194. package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
  195. package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
  196. package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
  197. package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
  198. package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
  199. package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
  200. package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
  201. package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
  202. package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
  203. package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
  204. package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
  205. package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
  206. package/runtime/include/js_builtins.h +5 -0
  207. package/runtime/include/js_crypto.h +11 -0
  208. package/runtime/include/js_gc.h +13 -10
  209. package/runtime/include/js_jobs.h +2 -0
  210. package/runtime/include/js_object.h +58 -0
  211. package/runtime/include/jscontext.h +1 -0
  212. package/runtime/src/crypto_internal.h +1 -0
  213. package/runtime/src/crypto_subtle.c +66 -7
  214. package/runtime/src/crypto_tls.c +265 -19
  215. package/runtime/src/gc.c +73 -92
  216. package/runtime/src/inspect.c +18 -1
  217. package/runtime/src/jobs.c +37 -22
  218. package/runtime/src/object.c +49 -2
  219. package/runtime/src/os.c +16 -6
  220. package/runtime/src/os.h +2 -0
  221. package/runtime/src/process.c +97 -10
@@ -607,3 +607,49 @@ HOST_FN(js_host_dns_lookup) {
607
607
  return js_int32(r);
608
608
  }
609
609
 
610
+ /* ---- dns.lookupService --------------------------------------------------------------------- */
611
+
612
+ typedef struct NameInfo {
613
+ uv_getnameinfo_t req;
614
+ JSValue cb; /* a root */
615
+ } NameInfo;
616
+
617
+ static void on_nameinfo(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) {
618
+ NameInfo *n = (NameInfo *)req;
619
+ JSContext *ctx = js_uv_context();
620
+ JSValue args[4] = { js_int32(status), JS_NULL, JS_NULL, JS_NULL };
621
+ if (status == 0) {
622
+ args[1] = js_new_string_cstr(ctx, hostname);
623
+ args[2] = js_new_string_cstr(ctx, service);
624
+ } else {
625
+ args[3] = js_new_string_cstr(ctx, uv_err_name(status));
626
+ }
627
+ JSValue cb = n->cb;
628
+ js_remove_root(ctx->rt, &n->cb);
629
+ free(n);
630
+ (void)js_uv_call(cb, 4, args, NULL);
631
+ }
632
+
633
+ /* dnsLookupService(ip, port, cb) → 0 | -errno; cb(errno, hostname | null, service | null, code | null): getnameinfo, a
634
+ * name required (NI_NAMEREQD), as Node's */
635
+ HOST_FN(js_host_dns_lookup_service) {
636
+ UNUSED;
637
+ if (argc < 3 || !js_is_string(argv[0]) || !js_is_number(argv[1])) return js_throw_type_error(ctx, "dnsLookupService: (ip, port, cb) expected");
638
+ char ip[64];
639
+ size_t len = js_view_to_utf8(js_string_view(ctx, argv[0]), ip, sizeof ip - 1);
640
+ ip[len] = '\0';
641
+ int port = (int)js_as_number(argv[1]);
642
+ struct sockaddr_storage addr;
643
+ if (uv_ip4_addr(ip, port, (struct sockaddr_in *)&addr) != 0 && uv_ip6_addr(ip, port, (struct sockaddr_in6 *)&addr) != 0) return js_int32(UV_EINVAL);
644
+ NameInfo *n = malloc(sizeof *n);
645
+ if (!n) js_fatal("out of memory in dns");
646
+ n->cb = argv[2];
647
+ js_add_root(ctx->rt, &n->cb);
648
+ int r = uv_getnameinfo(js_uv_loop(ctx), &n->req, on_nameinfo, (const struct sockaddr *)&addr, NI_NAMEREQD);
649
+ if (r < 0) {
650
+ js_remove_root(ctx->rt, &n->cb);
651
+ free(n);
652
+ }
653
+ return js_int32(r);
654
+ }
655
+
@@ -98,7 +98,7 @@ static JSValue path_result(JSContext *ctx, PathFn fn) {
98
98
  return e ? js_int32(e) : js_new_string_utf8(ctx, buf, n);
99
99
  }
100
100
 
101
- /* osHostname(), osHomedir(), osTmpdir(): a string, or -errno. */
101
+ /* osHostname(), osHomedir(): a string, or -errno. */
102
102
  PRIMITIVE(js_host_os_hostname) {
103
103
  UNUSED_PRIMITIVE_ARGS;
104
104
  return path_result(ctx, uv_os_gethostname);
@@ -109,11 +109,6 @@ PRIMITIVE(js_host_os_homedir) {
109
109
  return path_result(ctx, uv_os_homedir);
110
110
  }
111
111
 
112
- PRIMITIVE(js_host_os_tmpdir) {
113
- UNUSED_PRIMITIVE_ARGS;
114
- return path_result(ctx, uv_os_tmpdir);
115
- }
116
-
117
112
  /* osMemory(): [total, free] in bytes. */
118
113
  PRIMITIVE(js_host_os_memory) {
119
114
  UNUSED_PRIMITIVE_ARGS;
@@ -75,6 +75,58 @@ static const struct { int code, uv; const char *name, *message; } ERRORS[] = {
75
75
  E(ENXIO, "no such device or address"),
76
76
  E(EMLINK, "too many links"),
77
77
  E(ENOTTY, "inappropriate ioctl for device"),
78
+ /* the rest of libuv's: some C libraries (Windows') lack a few */
79
+ #ifdef EALREADY
80
+ E(EALREADY, "connection already in progress"),
81
+ #endif
82
+ #ifdef EDESTADDRREQ
83
+ E(EDESTADDRREQ, "destination address required"),
84
+ #endif
85
+ #ifdef EISCONN
86
+ E(EISCONN, "socket is already connected"),
87
+ #endif
88
+ #ifdef ENETDOWN
89
+ E(ENETDOWN, "network is down"),
90
+ #endif
91
+ #ifdef ENODEV
92
+ E(ENODEV, "no such device"),
93
+ #endif
94
+ #ifdef ENONET
95
+ E(ENONET, "machine is not on the network"),
96
+ #endif
97
+ #ifdef ENOPROTOOPT
98
+ E(ENOPROTOOPT, "protocol not available"),
99
+ #endif
100
+ #ifdef EPROTONOSUPPORT
101
+ E(EPROTONOSUPPORT, "protocol not supported"),
102
+ #endif
103
+ #ifdef EPROTOTYPE
104
+ E(EPROTOTYPE, "protocol wrong type for socket"),
105
+ #endif
106
+ #ifdef ESHUTDOWN
107
+ E(ESHUTDOWN, "cannot send after transport endpoint shutdown"),
108
+ #endif
109
+ #ifdef EHOSTDOWN
110
+ E(EHOSTDOWN, "host is down"),
111
+ #endif
112
+ #ifdef EREMOTEIO
113
+ E(EREMOTEIO, "remote I/O error"),
114
+ #endif
115
+ #ifdef EILSEQ
116
+ E(EILSEQ, "illegal byte sequence"),
117
+ #endif
118
+ #ifdef ESOCKTNOSUPPORT
119
+ E(ESOCKTNOSUPPORT, "socket type not supported"),
120
+ #endif
121
+ #ifdef ENODATA
122
+ E(ENODATA, "no data available"),
123
+ #endif
124
+ #ifdef EUNATCH
125
+ E(EUNATCH, "protocol driver not attached"),
126
+ #endif
127
+ #ifdef ENOEXEC
128
+ E(ENOEXEC, "exec format error"),
129
+ #endif
78
130
  };
79
131
  #undef E
80
132
 
@@ -225,3 +277,21 @@ JSValue js_host_process_memory(JSContext *ctx, JSValue callee, JSValue this_val,
225
277
  js_number((double)(h->live_after_gc + h->allocated_since_gc)) };
226
278
  return js_new_array_from(ctx, items, 3);
227
279
  }
280
+
281
+ /* previewEntries(value, isIterator): Node's util binding: a Map's, Set's or iterator's entries,
282
+ * the iterator not advanced ([k1, v1, …] for a Map or an entries iterator, else the values);
283
+ * with isIterator, [entries, isKeyValue]. Undefined for any other value, or when the program
284
+ * has no collections. */
285
+ JSValue js_host_preview_entries(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv,
286
+ JSValue new_target) {
287
+ (void)callee, (void)this_val, (void)new_target;
288
+ if (argc < 1 || !ctx->rt->collection_preview) return JS_UNDEFINED;
289
+ JSCollectionPreview what = JS_PREVIEW_MAP;
290
+ JSValue entries = ctx->rt->collection_preview(ctx, argv[0], &what);
291
+ if (js_is_exception(entries)) return entries;
292
+ if (js_is_empty(entries)) return JS_UNDEFINED;
293
+ if (argc < 2 || !js_truthy(argv[1])) return entries;
294
+ bool pairs = what == JS_PREVIEW_MAP || what == JS_PREVIEW_MAP_ENTRIES || what == JS_PREVIEW_SET_ENTRIES;
295
+ JSValue items[2] = { entries, js_bool(pairs) };
296
+ return js_new_array_from(ctx, items, 2);
297
+ }
@@ -0,0 +1,418 @@
1
+ /* Host primitives for node:dgram: UDP handles on libuv, the calls Node's UDPWrap makes. The
2
+ * prelude's internal/udp.js is Node's UDP binding over them, and dgram.js Node's own. Handles are
3
+ * numbered; each has one JS callback (a root), called as cb(event, …) from the loop:
4
+ *
5
+ * UDP_MESSAGE cb(0, bytes, address, family, port): a datagram (a Uint8Array); or cb(0, -errno)
6
+ * UDP_SENT cb(1, status, bytes): the oldest pending send finished (in order)
7
+ * UDP_CLOSE cb(2): the handle is closed and its id free
8
+ *
9
+ * udpOpen(cb) → id
10
+ * udpOpenFd(id, fd), udpFd(id) → fd | -errno
11
+ * udpBind(id, ip, port, flags), udpConnect(id, ip, port), udpDisconnect(id) → 0 | -errno
12
+ * flags: libuv's (UV_UDP_IPV6ONLY 1, UV_UDP_REUSEADDR 4, UV_UDP_REUSEPORT 64)
13
+ * udpSend(id, [bytes, …], ip | null, port) → length + 1 (sent now) | 0 (a UDP_SENT follows) | -errno
14
+ * udpRecvStart(id), udpRecvStop(id) → 0 | -errno
15
+ * udpAddress(id, peer) → [address, family, port] | -errno
16
+ * udpSetBroadcast(id, on), udpSetTTL(id, ttl), udpSetMulticastTTL(id, ttl), udpSetMulticastLoopback(id, on),
17
+ * udpSetMulticastInterface(id, ip), udpMembership(id, group, iface | null, join),
18
+ * udpSourceMembership(id, source, group, iface | null, join) → 0 | -errno
19
+ * udpBufferSize(id, size, recv) → size | -errno (size 0 reads it)
20
+ * udpSendQueue(id, count) → bytes | requests waiting to go out
21
+ * udpClose(id), udpRef(id, ref), udpHasRef(id) → bool */
22
+ #define _POSIX_C_SOURCE 200809L /* libuv's headers: pthread_rwlock_t, struct addrinfo */
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+
26
+ #include "js_buffer.h"
27
+ #include "js_convert.h"
28
+ #include "js_exception.h"
29
+ #include "js_gc.h"
30
+ #include "js_node.h"
31
+ #include "js_ops.h"
32
+ #include "js_uv.h"
33
+ #include "jscontext.h"
34
+ #include "jsstring.h"
35
+
36
+ enum { UDP_MESSAGE, UDP_SENT, UDP_CLOSE };
37
+
38
+ typedef struct UdpHandle {
39
+ uv_udp_t udp;
40
+ int id;
41
+ bool closing;
42
+ JSValue cb; /* a root */
43
+ } UdpHandle;
44
+
45
+ static UdpHandle **handles;
46
+ static size_t nhandles;
47
+
48
+ static void emit(UdpHandle *h, uint32_t argc, JSValue *args) {
49
+ if (js_is_callable(h->cb)) (void)js_uv_call(h->cb, argc, args, NULL);
50
+ }
51
+
52
+ static UdpHandle *open_handle(int32_t id) {
53
+ UdpHandle *h = id >= 0 && (size_t)id < nhandles ? handles[id] : NULL;
54
+ return h && !h->closing ? h : NULL;
55
+ }
56
+
57
+ static UdpHandle *handle_arg(uint32_t argc, const JSValue *argv) {
58
+ return argc > 0 && js_is_int32(argv[0]) ? open_handle(js_as_int32(argv[0])) : NULL;
59
+ }
60
+
61
+ static size_t string_arg(JSContext *ctx, JSValue v, char *buf, size_t size) {
62
+ size_t n = js_is_string(v) ? js_view_to_utf8(js_string_view(ctx, v), buf, size - 1) : 0;
63
+ buf[n] = '\0';
64
+ return n;
65
+ }
66
+
67
+ static int sockaddr_arg(JSContext *ctx, JSValue ip, JSValue port, struct sockaddr_storage *addr) {
68
+ char host[64];
69
+ string_arg(ctx, ip, host, sizeof host);
70
+ int p = js_is_int32(port) ? js_as_int32(port) : 0;
71
+ return strchr(host, ':') ? uv_ip6_addr(host, p, (struct sockaddr_in6 *)addr) : uv_ip4_addr(host, p, (struct sockaddr_in *)addr);
72
+ }
73
+
74
+ static int32_t int_arg(uint32_t argc, const JSValue *argv, uint32_t i) {
75
+ return argc > i && js_is_number(argv[i]) ? (int32_t)js_as_number(argv[i]) : 0;
76
+ }
77
+
78
+ /* [address, family, port] of a socket address */
79
+ static JSValue address_value(JSContext *ctx, const struct sockaddr *sa) {
80
+ char ip[64] = "";
81
+ int port = 0;
82
+ const char *family = "IPv4";
83
+ if (sa->sa_family == AF_INET6) {
84
+ const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)sa;
85
+ uv_ip6_name(a, ip, sizeof ip);
86
+ port = ntohs(a->sin6_port);
87
+ family = "IPv6";
88
+ } else {
89
+ const struct sockaddr_in *a = (const struct sockaddr_in *)sa;
90
+ uv_ip4_name(a, ip, sizeof ip);
91
+ port = ntohs(a->sin_port);
92
+ }
93
+ JSValue out = js_new_array(ctx, 3);
94
+ if (js_array_append(ctx, out, js_new_string_cstr(ctx, ip)) < 0 || js_array_append(ctx, out, js_new_string_cstr(ctx, family)) < 0 ||
95
+ js_array_append(ctx, out, js_int32(port)) < 0)
96
+ js_fatal("out of memory in dgram");
97
+ return out;
98
+ }
99
+
100
+ #define HOST_FN(name) JSValue name(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target)
101
+ #define UNUSED (void)ctx, (void)callee, (void)this_val, (void)new_target
102
+
103
+ /* ---- Handles ----------------------------------------------------------------------------------- */
104
+
105
+ HOST_FN(js_host_udp_open) {
106
+ UNUSED;
107
+ UdpHandle *h = calloc(1, sizeof *h);
108
+ if (!h) js_fatal("out of memory in dgram");
109
+ uv_udp_init(js_uv_loop(ctx), &h->udp);
110
+ size_t id = 0;
111
+ while (id < nhandles && handles[id]) id++;
112
+ if (id == nhandles) {
113
+ size_t n = nhandles ? nhandles * 2 : 8;
114
+ UdpHandle **v = realloc(handles, n * sizeof *v);
115
+ if (!v) js_fatal("out of memory in dgram");
116
+ memset(v + nhandles, 0, (n - nhandles) * sizeof *v);
117
+ handles = v;
118
+ nhandles = n;
119
+ }
120
+ handles[id] = h;
121
+ h->id = (int)id;
122
+ h->cb = argc > 0 ? argv[0] : JS_UNDEFINED;
123
+ js_add_root(ctx->rt, &h->cb);
124
+ return js_int32(h->id);
125
+ }
126
+
127
+ static void on_closed(uv_handle_t *uh) {
128
+ UdpHandle *h = (UdpHandle *)uh;
129
+ handles[h->id] = NULL;
130
+ JSValue args[1] = { js_int32(UDP_CLOSE) };
131
+ emit(h, 1, args);
132
+ js_remove_root(js_uv_context()->rt, &h->cb);
133
+ free(h);
134
+ }
135
+
136
+ HOST_FN(js_host_udp_close) {
137
+ UNUSED;
138
+ UdpHandle *h = handle_arg(argc, argv);
139
+ if (h) {
140
+ h->closing = true;
141
+ uv_close((uv_handle_t *)&h->udp, on_closed);
142
+ }
143
+ return JS_UNDEFINED;
144
+ }
145
+
146
+ HOST_FN(js_host_udp_open_fd) {
147
+ UNUSED;
148
+ UdpHandle *h = handle_arg(argc, argv);
149
+ if (!h || argc < 2 || !js_is_int32(argv[1])) return js_int32(UV_EBADF);
150
+ return js_int32(uv_udp_open(&h->udp, (uv_os_sock_t)js_as_int32(argv[1])));
151
+ }
152
+
153
+ HOST_FN(js_host_udp_fd) {
154
+ UNUSED;
155
+ UdpHandle *h = handle_arg(argc, argv);
156
+ if (!h) return js_int32(UV_EBADF);
157
+ #ifdef _WIN32
158
+ return js_int32(-1);
159
+ #else
160
+ uv_os_fd_t fd;
161
+ int r = uv_fileno((uv_handle_t *)&h->udp, &fd);
162
+ return js_int32(r < 0 ? r : fd);
163
+ #endif
164
+ }
165
+
166
+ HOST_FN(js_host_udp_ref) {
167
+ UNUSED;
168
+ UdpHandle *h = handle_arg(argc, argv);
169
+ if (h && argc > 1) {
170
+ if (js_truthy(argv[1])) uv_ref((uv_handle_t *)&h->udp);
171
+ else uv_unref((uv_handle_t *)&h->udp);
172
+ }
173
+ return JS_UNDEFINED;
174
+ }
175
+
176
+ HOST_FN(js_host_udp_has_ref) {
177
+ UNUSED;
178
+ UdpHandle *h = handle_arg(argc, argv);
179
+ return js_bool(h && uv_has_ref((uv_handle_t *)&h->udp));
180
+ }
181
+
182
+ /* ---- Binding and connecting -------------------------------------------------------------------- */
183
+
184
+ HOST_FN(js_host_udp_bind) {
185
+ UNUSED;
186
+ UdpHandle *h = handle_arg(argc, argv);
187
+ if (!h || argc < 2) return js_int32(UV_EBADF);
188
+ struct sockaddr_storage addr;
189
+ int r = sockaddr_arg(ctx, argv[1], argc > 2 ? argv[2] : JS_UNDEFINED, &addr);
190
+ if (r < 0) return js_int32(r);
191
+ return js_int32(uv_udp_bind(&h->udp, (const struct sockaddr *)&addr, (unsigned)int_arg(argc, argv, 3)));
192
+ }
193
+
194
+ HOST_FN(js_host_udp_connect) {
195
+ UNUSED;
196
+ UdpHandle *h = handle_arg(argc, argv);
197
+ if (!h || argc < 2) return js_int32(UV_EBADF);
198
+ struct sockaddr_storage addr;
199
+ int r = sockaddr_arg(ctx, argv[1], argc > 2 ? argv[2] : JS_UNDEFINED, &addr);
200
+ if (r < 0) return js_int32(r);
201
+ return js_int32(uv_udp_connect(&h->udp, (const struct sockaddr *)&addr));
202
+ }
203
+
204
+ HOST_FN(js_host_udp_disconnect) {
205
+ UNUSED;
206
+ UdpHandle *h = handle_arg(argc, argv);
207
+ return js_int32(h ? uv_udp_connect(&h->udp, NULL) : UV_EBADF);
208
+ }
209
+
210
+ HOST_FN(js_host_udp_address) {
211
+ UNUSED;
212
+ UdpHandle *h = handle_arg(argc, argv);
213
+ if (!h) return js_int32(UV_EBADF);
214
+ struct sockaddr_storage addr;
215
+ int len = sizeof addr;
216
+ int r = argc > 1 && js_truthy(argv[1]) ? uv_udp_getpeername(&h->udp, (struct sockaddr *)&addr, &len)
217
+ : uv_udp_getsockname(&h->udp, (struct sockaddr *)&addr, &len);
218
+ return r < 0 ? js_int32(r) : address_value(ctx, (const struct sockaddr *)&addr);
219
+ }
220
+
221
+ /* ---- Sending ----------------------------------------------------------------------------------- */
222
+
223
+ typedef struct SendReq {
224
+ uv_udp_send_t req;
225
+ size_t length;
226
+ char data[];
227
+ } SendReq;
228
+
229
+ static void on_sent(uv_udp_send_t *req, int status) {
230
+ UdpHandle *h = (UdpHandle *)req->handle;
231
+ SendReq *s = (SendReq *)req;
232
+ JSValue args[3] = { js_int32(UDP_SENT), js_int32(status), js_number((double)s->length) };
233
+ free(s);
234
+ emit(h, 3, args);
235
+ }
236
+
237
+ /* udpSend(id, chunks, ip | null, port): as Node's UDPWrap::DoSend, tried at once (length + 1 when it
238
+ * all went), else queued with a copy of the bytes */
239
+ HOST_FN(js_host_udp_send) {
240
+ UNUSED;
241
+ UdpHandle *h = handle_arg(argc, argv);
242
+ if (!h || argc < 2 || !js_is_object(argv[1])) return js_int32(UV_EBADF);
243
+ struct sockaddr_storage addr;
244
+ const struct sockaddr *to = NULL;
245
+ if (argc > 2 && js_is_string(argv[2])) {
246
+ int r = sockaddr_arg(ctx, argv[2], argc > 3 ? argv[3] : JS_UNDEFINED, &addr);
247
+ if (r < 0) return js_int32(r);
248
+ to = (const struct sockaddr *)&addr;
249
+ }
250
+ uint32_t count = js_array_length(js_as_object(argv[1]));
251
+ uv_buf_t small[8];
252
+ uv_buf_t *bufs = count <= 8 ? small : malloc(count * sizeof *bufs);
253
+ if (!bufs) js_fatal("out of memory in dgram");
254
+ size_t total = 0;
255
+ for (uint32_t i = 0; i < count; i++) {
256
+ JSValue chunk = js_get_index(ctx, argv[1], js_int32((int32_t)i));
257
+ uint8_t *p;
258
+ size_t n;
259
+ if (!js_buffer_source_bytes(chunk, &p, &n)) {
260
+ if (bufs != small) free(bufs);
261
+ return js_throw_type_error(ctx, "udpSend: bytes expected");
262
+ }
263
+ bufs[i] = uv_buf_init((char *)p, (unsigned)n);
264
+ total += n;
265
+ }
266
+ int r = uv_udp_try_send(&h->udp, bufs, count, to);
267
+ if (r >= 0 && (size_t)r == total) {
268
+ if (bufs != small) free(bufs);
269
+ return js_number((double)total + 1);
270
+ }
271
+ if (r < 0 && r != UV_EAGAIN && r != UV_ENOSYS) {
272
+ if (bufs != small) free(bufs);
273
+ return js_int32(r);
274
+ }
275
+ /* a datagram goes whole or not at all: a partial r doesn't happen, queue all of it */
276
+ SendReq *s = malloc(sizeof *s + (total ? total : 1));
277
+ if (!s) js_fatal("out of memory in dgram");
278
+ s->length = total;
279
+ size_t off = 0;
280
+ for (uint32_t i = 0; i < count; i++) {
281
+ memcpy(s->data + off, bufs[i].base, bufs[i].len);
282
+ off += bufs[i].len;
283
+ }
284
+ if (bufs != small) free(bufs);
285
+ uv_buf_t one = uv_buf_init(s->data, (unsigned)total);
286
+ r = uv_udp_send(&s->req, &h->udp, &one, 1, to, on_sent);
287
+ if (r < 0) {
288
+ free(s);
289
+ return js_int32(r);
290
+ }
291
+ return js_int32(0);
292
+ }
293
+
294
+ HOST_FN(js_host_udp_send_queue) {
295
+ UNUSED;
296
+ UdpHandle *h = handle_arg(argc, argv);
297
+ if (!h) return js_int32(0);
298
+ return js_number((double)(argc > 1 && js_truthy(argv[1]) ? uv_udp_get_send_queue_count(&h->udp) : uv_udp_get_send_queue_size(&h->udp)));
299
+ }
300
+
301
+ /* ---- Receiving --------------------------------------------------------------------------------- */
302
+
303
+ static void on_alloc(uv_handle_t *uh, size_t suggested, uv_buf_t *buf) {
304
+ (void)uh;
305
+ buf->base = malloc(suggested);
306
+ buf->len = buf->base ? suggested : 0;
307
+ }
308
+
309
+ static void on_recv(uv_udp_t *u, ssize_t n, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
310
+ (void)flags;
311
+ UdpHandle *h = (UdpHandle *)u;
312
+ if (n == 0 && addr == NULL) { /* nothing more to read for now */
313
+ free(buf->base);
314
+ return;
315
+ }
316
+ JSContext *ctx = js_uv_context();
317
+ if (n < 0) {
318
+ free(buf->base);
319
+ JSValue args[2] = { js_int32(UDP_MESSAGE), js_int32((int32_t)n) };
320
+ emit(h, 2, args);
321
+ return;
322
+ }
323
+ JSValue chunk = js_new_uint8_array(ctx, (size_t)n);
324
+ if (js_is_exception(chunk)) js_fatal("out of memory in dgram");
325
+ uint8_t *data;
326
+ size_t len;
327
+ js_buffer_source_bytes(chunk, &data, &len);
328
+ memcpy(data, buf->base, (size_t)n);
329
+ free(buf->base);
330
+ JSValue args[3] = { js_int32(UDP_MESSAGE), chunk, address_value(ctx, addr) };
331
+ emit(h, 3, args);
332
+ }
333
+
334
+ HOST_FN(js_host_udp_recv_start) {
335
+ UNUSED;
336
+ UdpHandle *h = handle_arg(argc, argv);
337
+ if (!h) return js_int32(UV_EBADF);
338
+ int r = uv_udp_recv_start(&h->udp, on_alloc, on_recv);
339
+ return js_int32(r == UV_EALREADY ? 0 : r); /* as Node's: starting twice is fine */
340
+ }
341
+
342
+ HOST_FN(js_host_udp_recv_stop) {
343
+ UNUSED;
344
+ UdpHandle *h = handle_arg(argc, argv);
345
+ return js_int32(h ? uv_udp_recv_stop(&h->udp) : UV_EBADF);
346
+ }
347
+
348
+ /* ---- Options ----------------------------------------------------------------------------------- */
349
+
350
+ HOST_FN(js_host_udp_set_broadcast) {
351
+ UNUSED;
352
+ UdpHandle *h = handle_arg(argc, argv);
353
+ return js_int32(h ? uv_udp_set_broadcast(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
354
+ }
355
+
356
+ HOST_FN(js_host_udp_set_ttl) {
357
+ UNUSED;
358
+ UdpHandle *h = handle_arg(argc, argv);
359
+ return js_int32(h ? uv_udp_set_ttl(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
360
+ }
361
+
362
+ HOST_FN(js_host_udp_set_multicast_ttl) {
363
+ UNUSED;
364
+ UdpHandle *h = handle_arg(argc, argv);
365
+ return js_int32(h ? uv_udp_set_multicast_ttl(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
366
+ }
367
+
368
+ HOST_FN(js_host_udp_set_multicast_loopback) {
369
+ UNUSED;
370
+ UdpHandle *h = handle_arg(argc, argv);
371
+ return js_int32(h ? uv_udp_set_multicast_loop(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
372
+ }
373
+
374
+ HOST_FN(js_host_udp_set_multicast_interface) {
375
+ UNUSED;
376
+ UdpHandle *h = handle_arg(argc, argv);
377
+ if (!h) return js_int32(UV_EBADF);
378
+ char iface[64];
379
+ string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, iface, sizeof iface);
380
+ return js_int32(uv_udp_set_multicast_interface(&h->udp, iface));
381
+ }
382
+
383
+ HOST_FN(js_host_udp_membership) {
384
+ UNUSED;
385
+ UdpHandle *h = handle_arg(argc, argv);
386
+ if (!h) return js_int32(UV_EBADF);
387
+ char group[64], iface[64];
388
+ string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, group, sizeof group);
389
+ bool has_iface = argc > 2 && js_is_string(argv[2]);
390
+ if (has_iface) string_arg(ctx, argv[2], iface, sizeof iface);
391
+ return js_int32(uv_udp_set_membership(&h->udp, group, has_iface ? iface : NULL,
392
+ argc > 3 && js_truthy(argv[3]) ? UV_JOIN_GROUP : UV_LEAVE_GROUP));
393
+ }
394
+
395
+ HOST_FN(js_host_udp_source_membership) {
396
+ UNUSED;
397
+ UdpHandle *h = handle_arg(argc, argv);
398
+ if (!h) return js_int32(UV_EBADF);
399
+ char source[64], group[64], iface[64];
400
+ string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, source, sizeof source);
401
+ string_arg(ctx, argc > 2 ? argv[2] : JS_UNDEFINED, group, sizeof group);
402
+ bool has_iface = argc > 3 && js_is_string(argv[3]);
403
+ if (has_iface) string_arg(ctx, argv[3], iface, sizeof iface);
404
+ return js_int32(uv_udp_set_source_membership(&h->udp, group, has_iface ? iface : NULL, source,
405
+ argc > 4 && js_truthy(argv[4]) ? UV_JOIN_GROUP : UV_LEAVE_GROUP));
406
+ }
407
+
408
+ /* udpBufferSize(id, size, recv): the kernel's buffer size, set when size isn't 0 (Linux reports it
409
+ * doubled, as Node shows it) */
410
+ HOST_FN(js_host_udp_buffer_size) {
411
+ UNUSED;
412
+ UdpHandle *h = handle_arg(argc, argv);
413
+ if (!h) return js_int32(UV_EBADF);
414
+ int size = int_arg(argc, argv, 1);
415
+ int r = argc > 2 && js_truthy(argv[2]) ? uv_recv_buffer_size((uv_handle_t *)&h->udp, &size)
416
+ : uv_send_buffer_size((uv_handle_t *)&h->udp, &size);
417
+ return js_int32(r < 0 ? r : size);
418
+ }
@@ -0,0 +1,24 @@
1
+ MIT License
2
+
3
+ Copyright (c) 1998 Massachusetts Institute of Technology
4
+ Copyright (c) 2007 - 2023 Daniel Stenberg with many contributors, see AUTHORS
5
+ file.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ this software and associated documentation files (the "Software"), to deal in
9
+ the Software without restriction, including without limitation the rights to
10
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
+ the Software, and to permit persons to whom the Software is furnished to do so,
12
+ subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice (including the next
15
+ paragraph) shall be included in all copies or substantial portions of the
16
+ Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.