koffi 2.12.0 → 2.12.2
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.
- package/CHANGELOG.md +17 -0
- package/LICENSE.txt +2 -2
- package/README.md +8 -8
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.exp +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.exp +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.exp +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/assets.ini +3 -3
- package/doc/develop.sh +4 -3
- package/doc/pages/platforms.md +1 -1
- package/doc/static/highlight.js +1 -1
- package/doc/static/koffi.css +3 -2
- package/doc/static/print.css +1 -1
- package/doc/templates/code.html +5 -5
- package/doc/templates/page.html +4 -4
- package/index.d.ts +2 -2
- package/index.js +25 -25
- package/indirect.js +25 -5
- package/package.json +2 -2
- package/src/cnoke/LICENSE.txt +2 -2
- package/src/cnoke/README.md +2 -0
- package/src/cnoke/assets/FindCNoke.cmake +12 -2
- package/src/cnoke/assets/win_delay_hook.c +4 -4
- package/src/cnoke/cnoke.js +4 -2
- package/src/cnoke/package.json +1 -1
- package/src/cnoke/src/builder.js +11 -14
- package/src/cnoke/src/index.js +2 -2
- package/src/cnoke/src/tools.js +34 -2
- package/src/core/{libcc/libcc.cc → base/base.cc} +3092 -1674
- package/src/core/{libcc/libcc.hh → base/base.hh} +3059 -2432
- package/src/core/{libcc → base}/mimetypes.inc +42 -4
- package/src/core/{libcc → base}/mimetypes_gen.py +3 -3
- package/src/core/unicode/generate.py +124 -0
- package/src/core/unicode/xid.cc +52 -0
- package/src/core/unicode/xid.hh +29 -0
- package/src/core/unicode/xid.inc +465 -0
- package/src/koffi/CMakeLists.txt +8 -5
- package/src/koffi/cmake/raylib.cmake +6 -2
- package/src/koffi/cmake/{sqlite.cmake → sqlite3.cmake} +3 -3
- package/src/koffi/examples/electron-forge/forge.config.js +23 -3
- package/src/koffi/examples/electron-forge/package.json +18 -16
- package/src/koffi/src/abi_arm32.cc +8 -21
- package/src/koffi/src/abi_arm32_asm.S +2 -2
- package/src/koffi/src/abi_arm64.cc +46 -59
- package/src/koffi/src/abi_arm64_asm.S +4 -4
- package/src/koffi/src/abi_arm64_asm.asm +2 -2
- package/src/koffi/src/abi_loong64_asm.S +2 -2
- package/src/koffi/src/abi_riscv64.cc +6 -19
- package/src/koffi/src/abi_riscv64_asm.S +2 -2
- package/src/koffi/src/abi_x64_sysv.cc +4 -17
- package/src/koffi/src/abi_x64_sysv_asm.S +5 -5
- package/src/koffi/src/abi_x64_win.cc +4 -17
- package/src/koffi/src/abi_x64_win_asm.asm +2 -2
- package/src/koffi/src/abi_x86.cc +9 -22
- package/src/koffi/src/abi_x86_asm.S +2 -2
- package/src/koffi/src/abi_x86_asm.asm +2 -2
- package/src/koffi/src/call.cc +49 -42
- package/src/koffi/src/call.hh +9 -8
- package/src/koffi/src/errno.inc +152 -152
- package/src/koffi/src/ffi.cc +45 -39
- package/src/koffi/src/ffi.hh +6 -6
- package/src/koffi/src/init.js +1 -1
- package/src/koffi/src/parser.cc +6 -5
- package/src/koffi/src/parser.hh +3 -3
- package/src/koffi/src/trampolines/armasm.inc +2 -2
- package/src/koffi/src/trampolines/gnu.inc +2 -2
- package/src/koffi/src/trampolines/masm32.inc +2 -2
- package/src/koffi/src/trampolines/masm64.inc +2 -2
- package/src/koffi/src/trampolines/prototypes.inc +2 -2
- package/src/koffi/src/util.cc +9 -9
- package/src/koffi/src/util.hh +3 -3
- package/src/koffi/src/win32.cc +5 -5
- package/src/koffi/src/win32.hh +9 -9
- package/vendor/node-addon-api/CHANGELOG.md +97 -2
- package/vendor/node-addon-api/CONTRIBUTING.md +117 -7
- package/vendor/node-addon-api/README.md +25 -249
- package/vendor/node-addon-api/common.gypi +1 -0
- package/vendor/node-addon-api/doc/README.md +145 -0
- package/vendor/node-addon-api/doc/array_buffer.md +15 -15
- package/vendor/node-addon-api/doc/basic_env.md +200 -0
- package/vendor/node-addon-api/doc/buffer.md +24 -26
- package/vendor/node-addon-api/doc/cmake-js.md +19 -0
- package/vendor/node-addon-api/doc/{creating_a_release.md → contributing/creating_a_release.md} +16 -4
- package/vendor/node-addon-api/doc/env.md +11 -131
- package/vendor/node-addon-api/doc/error_handling.md +12 -0
- package/vendor/node-addon-api/doc/external.md +13 -4
- package/vendor/node-addon-api/doc/finalization.md +153 -0
- package/vendor/node-addon-api/doc/memory_management.md +1 -1
- package/vendor/node-addon-api/doc/object_wrap.md +19 -3
- package/vendor/node-addon-api/doc/promises.md +51 -0
- package/vendor/node-addon-api/doc/setup.md +29 -6
- package/vendor/node-addon-api/doc/value.md +13 -0
- package/vendor/node-addon-api/doc/version_management.md +2 -2
- package/vendor/node-addon-api/eslint.config.js +5 -0
- package/vendor/node-addon-api/index.js +2 -0
- package/vendor/node-addon-api/napi-inl.h +592 -166
- package/vendor/node-addon-api/napi.h +167 -59
- package/vendor/node-addon-api/node_addon_api.gyp +10 -0
- package/vendor/node-addon-api/noexcept.gypi +1 -1
- package/vendor/node-addon-api/package.json +10 -13
- package/vendor/node-addon-api/release-please-config.json +15 -0
- package/vendor/node-addon-api/test/addon_build/tpl/binding.gyp +2 -1
- package/vendor/node-addon-api/test/array_buffer.js +1 -1
- package/vendor/node-addon-api/test/async_context.js +2 -2
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +3 -3
- package/vendor/node-addon-api/test/async_progress_worker.js +3 -3
- package/vendor/node-addon-api/test/async_worker.cc +15 -13
- package/vendor/node-addon-api/test/async_worker.js +5 -5
- package/vendor/node-addon-api/test/basic_types/value.cc +6 -0
- package/vendor/node-addon-api/test/basic_types/value.js +17 -0
- package/vendor/node-addon-api/test/binding.cc +8 -0
- package/vendor/node-addon-api/test/binding.gyp +23 -1
- package/vendor/node-addon-api/test/buffer.js +1 -2
- package/vendor/node-addon-api/test/common/index.js +1 -1
- package/vendor/node-addon-api/test/except_all.cc +22 -0
- package/vendor/node-addon-api/test/except_all.js +14 -0
- package/vendor/node-addon-api/test/exports.js +19 -0
- package/vendor/node-addon-api/test/finalizer_order.cc +152 -0
- package/vendor/node-addon-api/test/finalizer_order.js +98 -0
- package/vendor/node-addon-api/test/function.js +2 -2
- package/vendor/node-addon-api/test/function_reference.js +2 -2
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.cc +4 -4
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.cc +4 -4
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.cc +3 -3
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.cc +5 -5
- package/vendor/node-addon-api/test/name.cc +10 -8
- package/vendor/node-addon-api/test/object/delete_property.cc +5 -5
- package/vendor/node-addon-api/test/object/get_property.cc +5 -5
- package/vendor/node-addon-api/test/object/has_own_property.cc +4 -4
- package/vendor/node-addon-api/test/object/has_property.cc +5 -5
- package/vendor/node-addon-api/test/object/object.cc +1 -1
- package/vendor/node-addon-api/test/object/set_property.cc +5 -5
- package/vendor/node-addon-api/test/object/subscript_operator.cc +3 -3
- package/vendor/node-addon-api/test/object_reference.cc +18 -18
- package/vendor/node-addon-api/test/promise.cc +75 -0
- package/vendor/node-addon-api/test/promise.js +23 -0
- package/vendor/node-addon-api/test/require_basic_finalizers/index.js +38 -0
- package/vendor/node-addon-api/test/require_basic_finalizers/tpl/addon.cc +12 -0
- package/vendor/node-addon-api/test/require_basic_finalizers/tpl/binding.gyp +48 -0
- package/vendor/node-addon-api/test/require_basic_finalizers/tpl/index.js +3 -0
- package/vendor/node-addon-api/test/require_basic_finalizers/tpl/package.json +11 -0
- package/vendor/node-addon-api/test/run_script.cc +1 -1
- package/vendor/node-addon-api/test/type_taggable.cc +1 -1
- package/vendor/node-addon-api/test/type_taggable.js +3 -4
- package/vendor/node-addon-api/test/typedarray.cc +28 -24
- package/vendor/node-addon-api/tools/conversion.js +1 -1
- package/vendor/node-api-headers/CHANGELOG.md +29 -0
- package/vendor/node-api-headers/CREATING_A_RELEASE.md +12 -2
- package/vendor/node-api-headers/def/js_native_api.def +6 -1
- package/vendor/node-api-headers/def/node_api.def +7 -1
- package/vendor/node-api-headers/include/js_native_api.h +56 -24
- package/vendor/node-api-headers/include/js_native_api_types.h +27 -0
- package/vendor/node-api-headers/include/node_api.h +38 -29
- package/vendor/node-api-headers/lib/parse-utils.js +92 -0
- package/vendor/node-api-headers/package.json +7 -7
- package/vendor/node-api-headers/release-please-config.json +12 -0
- package/vendor/node-api-headers/scripts/update-headers.js +63 -12
- package/vendor/node-api-headers/scripts/write-symbols.js +1 -1
- package/vendor/node-api-headers/symbols.js +17 -1
- package/vendor/node-api-headers/test/parse-utils.js +21 -0
- package/doc/flat/flat.css +0 -27
- package/doc/flat/normal.css +0 -429
- package/doc/flat/print.css +0 -29
- package/doc/flat/reset.css +0 -41
- package/doc/flat/small.css +0 -104
- package/doc/flat/static.js +0 -161
- package/src/core/libcc/brotli.cc +0 -186
- package/src/core/libcc/lz4.cc +0 -197
- package/src/core/libcc/miniz.cc +0 -353
- package/vendor/node-addon-api/tools/eslint-format.js +0 -79
- /package/vendor/node-api-headers/{scripts → lib}/clang-utils.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
2
|
//
|
|
3
3
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
// this software and associated documentation files (the “Software”), to deal in
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
5
|
// the Software without restriction, including without limitation the rights to use,
|
|
6
6
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
7
|
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
20
|
// OTHER DEALINGS IN THE SOFTWARE.
|
|
21
21
|
|
|
22
|
-
#
|
|
22
|
+
#if !defined(MIMETYPE)
|
|
23
23
|
#error Please define MIMETYPE() before including mimetypes.inc
|
|
24
24
|
#endif
|
|
25
25
|
|
|
26
26
|
MIMETYPE(".123", "application/vnd.lotus-1-2-3")
|
|
27
27
|
MIMETYPE(".1km", "application/vnd.1000minds.decision-model+xml")
|
|
28
|
+
MIMETYPE(".210", "model/step")
|
|
28
29
|
MIMETYPE(".3dml", "text/vnd.in3d.3dml")
|
|
29
30
|
MIMETYPE(".3ds", "image/x-3ds")
|
|
30
31
|
MIMETYPE(".3g2", "video/3gpp2")
|
|
@@ -91,15 +92,18 @@ MIMETYPE(".azs", "application/vnd.airzip.filesecure.azs")
|
|
|
91
92
|
MIMETYPE(".azv", "image/vnd.airzip.accelerator.azv")
|
|
92
93
|
MIMETYPE(".azw", "application/vnd.amazon.ebook")
|
|
93
94
|
MIMETYPE(".b16", "image/vnd.pco.b16")
|
|
95
|
+
MIMETYPE(".bary", "model/vnd.bary")
|
|
94
96
|
MIMETYPE(".bat", "application/x-msdownload")
|
|
95
97
|
MIMETYPE(".bcpio", "application/x-bcpio")
|
|
96
98
|
MIMETYPE(".bdf", "application/x-font-bdf")
|
|
97
99
|
MIMETYPE(".bdm", "application/vnd.syncml.dm+wbxml")
|
|
100
|
+
MIMETYPE(".bdo", "application/vnd.nato.bindingdataobject+xml")
|
|
98
101
|
MIMETYPE(".bdoc", "application/bdoc")
|
|
99
102
|
MIMETYPE(".bed", "application/vnd.realvnc.bed")
|
|
100
103
|
MIMETYPE(".bh2", "application/vnd.fujitsu.oasysprs")
|
|
101
104
|
MIMETYPE(".bin", "application/octet-stream")
|
|
102
105
|
MIMETYPE(".blb", "application/x-blorb")
|
|
106
|
+
MIMETYPE(".blend", "application/x-blender")
|
|
103
107
|
MIMETYPE(".blorb", "application/x-blorb")
|
|
104
108
|
MIMETYPE(".bmi", "application/vnd.bmi")
|
|
105
109
|
MIMETYPE(".bmml", "application/vnd.balsamiq.bmml+xml")
|
|
@@ -108,6 +112,8 @@ MIMETYPE(".book", "application/vnd.framemaker")
|
|
|
108
112
|
MIMETYPE(".box", "application/vnd.previewsystems.box")
|
|
109
113
|
MIMETYPE(".boz", "application/x-bzip2")
|
|
110
114
|
MIMETYPE(".bpk", "application/octet-stream")
|
|
115
|
+
MIMETYPE(".brush", "application/vnd.procreate.brush")
|
|
116
|
+
MIMETYPE(".brushset", "application/vnd.procrate.brushset")
|
|
111
117
|
MIMETYPE(".bsp", "model/vnd.valve.source.compiled-map")
|
|
112
118
|
MIMETYPE(".btf", "image/prs.btif")
|
|
113
119
|
MIMETYPE(".btif", "image/prs.btif")
|
|
@@ -205,6 +211,8 @@ MIMETYPE(".dataless", "application/vnd.fdsn.seed")
|
|
|
205
211
|
MIMETYPE(".davmount", "application/davmount+xml")
|
|
206
212
|
MIMETYPE(".dbf", "application/vnd.dbf")
|
|
207
213
|
MIMETYPE(".dbk", "application/docbook+xml")
|
|
214
|
+
MIMETYPE(".dcm", "application/dicom")
|
|
215
|
+
MIMETYPE(".dcmp", "application/vnd.dcmp+xml")
|
|
208
216
|
MIMETYPE(".dcr", "application/x-director")
|
|
209
217
|
MIMETYPE(".dcurl", "text/vnd.curl.dcurl")
|
|
210
218
|
MIMETYPE(".dd2", "application/vnd.oma.dd2+xml")
|
|
@@ -231,6 +239,7 @@ MIMETYPE(".dmg", "application/octet-stream")
|
|
|
231
239
|
MIMETYPE(".dmp", "application/vnd.tcpdump.pcap")
|
|
232
240
|
MIMETYPE(".dms", "application/octet-stream")
|
|
233
241
|
MIMETYPE(".dna", "application/vnd.dna")
|
|
242
|
+
MIMETYPE(".dng", "image/x-adobe-dng")
|
|
234
243
|
MIMETYPE(".doc", "application/msword")
|
|
235
244
|
MIMETYPE(".docm", "application/vnd.ms-word.document.macroenabled.12")
|
|
236
245
|
MIMETYPE(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
|
|
@@ -242,6 +251,7 @@ MIMETYPE(".dpg", "application/vnd.dpgraph")
|
|
|
242
251
|
MIMETYPE(".dpx", "image/dpx")
|
|
243
252
|
MIMETYPE(".dra", "audio/vnd.dra")
|
|
244
253
|
MIMETYPE(".drle", "image/dicom-rle")
|
|
254
|
+
MIMETYPE(".drm", "application/vnd.procreate.dream")
|
|
245
255
|
MIMETYPE(".dsc", "text/prs.lines.tag")
|
|
246
256
|
MIMETYPE(".dssc", "application/dssc+der")
|
|
247
257
|
MIMETYPE(".dtb", "application/x-dtbook+xml")
|
|
@@ -296,6 +306,7 @@ MIMETYPE(".f4v", "video/x-f4v")
|
|
|
296
306
|
MIMETYPE(".f77", "text/x-fortran")
|
|
297
307
|
MIMETYPE(".f90", "text/x-fortran")
|
|
298
308
|
MIMETYPE(".fbs", "image/vnd.fastbidsheet")
|
|
309
|
+
MIMETYPE(".fbx", "application/vnd.autodesk.fbx")
|
|
299
310
|
MIMETYPE(".fcdt", "application/vnd.adobe.formscentral.fcdt")
|
|
300
311
|
MIMETYPE(".fcs", "application/vnd.isac.fcs")
|
|
301
312
|
MIMETYPE(".fdf", "application/fdf")
|
|
@@ -340,17 +351,22 @@ MIMETYPE(".gbr", "application/rpki-ghostbusters")
|
|
|
340
351
|
MIMETYPE(".gca", "application/x-gca-compressed")
|
|
341
352
|
MIMETYPE(".gdl", "model/vnd.gdl")
|
|
342
353
|
MIMETYPE(".gdoc", "application/vnd.google-apps.document")
|
|
354
|
+
MIMETYPE(".gdraw", "application/vnd.google-apps.drawing")
|
|
343
355
|
MIMETYPE(".ged", "text/vnd.familysearch.gedcom")
|
|
344
356
|
MIMETYPE(".geo", "application/vnd.dynageo")
|
|
345
357
|
MIMETYPE(".geojson", "application/geo+json")
|
|
346
358
|
MIMETYPE(".gex", "application/vnd.geometry-explorer")
|
|
359
|
+
MIMETYPE(".gform", "application/vnd.google-apps.form")
|
|
347
360
|
MIMETYPE(".ggb", "application/vnd.geogebra.file")
|
|
361
|
+
MIMETYPE(".ggs", "application/vnd.geogebra.slides")
|
|
348
362
|
MIMETYPE(".ggt", "application/vnd.geogebra.tool")
|
|
349
363
|
MIMETYPE(".ghf", "application/vnd.groove-help")
|
|
350
364
|
MIMETYPE(".gif", "image/gif")
|
|
351
365
|
MIMETYPE(".gim", "application/vnd.groove-identity-message")
|
|
366
|
+
MIMETYPE(".gjam", "application/vnd.google-apps.jam")
|
|
352
367
|
MIMETYPE(".glb", "model/gltf-binary")
|
|
353
368
|
MIMETYPE(".gltf", "model/gltf+json")
|
|
369
|
+
MIMETYPE(".gmap", "application/vnd.google-apps.map")
|
|
354
370
|
MIMETYPE(".gml", "application/gml+xml")
|
|
355
371
|
MIMETYPE(".gmx", "application/vnd.gmx")
|
|
356
372
|
MIMETYPE(".gnumeric", "application/x-gnumeric")
|
|
@@ -363,8 +379,10 @@ MIMETYPE(".gramps", "application/x-gramps-xml")
|
|
|
363
379
|
MIMETYPE(".gre", "application/vnd.geometry-explorer")
|
|
364
380
|
MIMETYPE(".grv", "application/vnd.groove-injector")
|
|
365
381
|
MIMETYPE(".grxml", "application/srgs+xml")
|
|
382
|
+
MIMETYPE(".gscript", "application/vnd.google-apps.script")
|
|
366
383
|
MIMETYPE(".gsf", "application/x-font-ghostscript")
|
|
367
384
|
MIMETYPE(".gsheet", "application/vnd.google-apps.spreadsheet")
|
|
385
|
+
MIMETYPE(".gsite", "application/vnd.google-apps.site")
|
|
368
386
|
MIMETYPE(".gslides", "application/vnd.google-apps.presentation")
|
|
369
387
|
MIMETYPE(".gtar", "application/x-gtar")
|
|
370
388
|
MIMETYPE(".gtm", "application/vnd.groove-tool-message")
|
|
@@ -395,7 +413,6 @@ MIMETYPE(".hpgl", "application/vnd.hp-hpgl")
|
|
|
395
413
|
MIMETYPE(".hpid", "application/vnd.hp-hpid")
|
|
396
414
|
MIMETYPE(".hps", "application/vnd.hp-hps")
|
|
397
415
|
MIMETYPE(".hqx", "application/mac-binhex40")
|
|
398
|
-
MIMETYPE(".hsj2", "image/hsj2")
|
|
399
416
|
MIMETYPE(".htc", "text/x-component")
|
|
400
417
|
MIMETYPE(".htke", "application/vnd.kenameaapp")
|
|
401
418
|
MIMETYPE(".htm", "text/html")
|
|
@@ -429,6 +446,7 @@ MIMETYPE(".install", "application/x-install-instructions")
|
|
|
429
446
|
MIMETYPE(".iota", "application/vnd.astraea-software.iota")
|
|
430
447
|
MIMETYPE(".ipfix", "application/ipfix")
|
|
431
448
|
MIMETYPE(".ipk", "application/vnd.shana.informed.package")
|
|
449
|
+
MIMETYPE(".ipynb", "application/x-ipynb+json")
|
|
432
450
|
MIMETYPE(".irm", "application/vnd.ibm.rights-management")
|
|
433
451
|
MIMETYPE(".irp", "application/vnd.irepository.package+xml")
|
|
434
452
|
MIMETYPE(".iso", "application/octet-stream")
|
|
@@ -438,10 +456,13 @@ MIMETYPE(".ivp", "application/vnd.immervision-ivp")
|
|
|
438
456
|
MIMETYPE(".ivu", "application/vnd.immervision-ivu")
|
|
439
457
|
MIMETYPE(".jad", "text/vnd.sun.j2me.app-descriptor")
|
|
440
458
|
MIMETYPE(".jade", "text/jade")
|
|
459
|
+
MIMETYPE(".jaii", "image/jaii")
|
|
460
|
+
MIMETYPE(".jais", "image/jais")
|
|
441
461
|
MIMETYPE(".jam", "application/vnd.jam")
|
|
442
462
|
MIMETYPE(".jar", "application/java-archive")
|
|
443
463
|
MIMETYPE(".jardiff", "application/x-java-archive-diff")
|
|
444
464
|
MIMETYPE(".java", "text/x-java-source")
|
|
465
|
+
MIMETYPE(".jfif", "image/pjpeg")
|
|
445
466
|
MIMETYPE(".jhc", "image/jphc")
|
|
446
467
|
MIMETYPE(".jisp", "application/vnd.jisp")
|
|
447
468
|
MIMETYPE(".jls", "image/jls")
|
|
@@ -467,6 +488,7 @@ MIMETYPE(".jsonld", "application/ld+json")
|
|
|
467
488
|
MIMETYPE(".jsonml", "application/jsonml+json")
|
|
468
489
|
MIMETYPE(".jsx", "text/jsx")
|
|
469
490
|
MIMETYPE(".jt", "model/jt")
|
|
491
|
+
MIMETYPE(".jxl", "image/jxl")
|
|
470
492
|
MIMETYPE(".jxr", "image/jxr")
|
|
471
493
|
MIMETYPE(".jxra", "image/jxra")
|
|
472
494
|
MIMETYPE(".jxrs", "image/jxrs")
|
|
@@ -511,6 +533,7 @@ MIMETYPE(".litcoffee", "text/coffeescript")
|
|
|
511
533
|
MIMETYPE(".lnk", "application/x-ms-shortcut")
|
|
512
534
|
MIMETYPE(".log", "text/plain")
|
|
513
535
|
MIMETYPE(".lostxml", "application/lost+xml")
|
|
536
|
+
MIMETYPE(".lottie", "application/zip+dotlottie")
|
|
514
537
|
MIMETYPE(".lrf", "application/octet-stream")
|
|
515
538
|
MIMETYPE(".lrm", "application/vnd.ms-lrm")
|
|
516
539
|
MIMETYPE(".ltf", "application/vnd.frogans.ltf")
|
|
@@ -524,11 +547,14 @@ MIMETYPE(".m14", "application/x-msmediaview")
|
|
|
524
547
|
MIMETYPE(".m1v", "video/mpeg")
|
|
525
548
|
MIMETYPE(".m21", "application/mp21")
|
|
526
549
|
MIMETYPE(".m2a", "audio/mpeg")
|
|
550
|
+
MIMETYPE(".m2t", "video/mp2t")
|
|
551
|
+
MIMETYPE(".m2ts", "video/mp2t")
|
|
527
552
|
MIMETYPE(".m2v", "video/mpeg")
|
|
528
553
|
MIMETYPE(".m3a", "audio/mpeg")
|
|
529
554
|
MIMETYPE(".m3u", "audio/x-mpegurl")
|
|
530
555
|
MIMETYPE(".m3u8", "application/vnd.apple.mpegurl")
|
|
531
556
|
MIMETYPE(".m4a", "audio/mp4")
|
|
557
|
+
MIMETYPE(".m4b", "audio/mp4")
|
|
532
558
|
MIMETYPE(".m4p", "application/mp4")
|
|
533
559
|
MIMETYPE(".m4s", "video/iso.segment")
|
|
534
560
|
MIMETYPE(".m4u", "video/vnd.mpegurl")
|
|
@@ -563,6 +589,8 @@ MIMETYPE(".mfm", "application/vnd.mfmp")
|
|
|
563
589
|
MIMETYPE(".mft", "application/rpki-manifest")
|
|
564
590
|
MIMETYPE(".mgp", "application/vnd.osgeo.mapguide.package")
|
|
565
591
|
MIMETYPE(".mgz", "application/vnd.proteus.magazine")
|
|
592
|
+
MIMETYPE(".mht", "message/rfc822")
|
|
593
|
+
MIMETYPE(".mhtml", "message/rfc822")
|
|
566
594
|
MIMETYPE(".mid", "audio/midi")
|
|
567
595
|
MIMETYPE(".midi", "audio/midi")
|
|
568
596
|
MIMETYPE(".mie", "application/x-mie")
|
|
@@ -685,6 +713,8 @@ MIMETYPE(".ogg", "audio/ogg")
|
|
|
685
713
|
MIMETYPE(".ogv", "video/ogg")
|
|
686
714
|
MIMETYPE(".ogx", "application/ogg")
|
|
687
715
|
MIMETYPE(".omdoc", "application/omdoc+xml")
|
|
716
|
+
MIMETYPE(".one", "application/onenote")
|
|
717
|
+
MIMETYPE(".onea", "application/onenote")
|
|
688
718
|
MIMETYPE(".onepkg", "application/onenote")
|
|
689
719
|
MIMETYPE(".onetmp", "application/onenote")
|
|
690
720
|
MIMETYPE(".onetoc", "application/onenote")
|
|
@@ -713,6 +743,7 @@ MIMETYPE(".oxt", "application/vnd.openofficeorg.extension")
|
|
|
713
743
|
MIMETYPE(".p", "text/x-pascal")
|
|
714
744
|
MIMETYPE(".p10", "application/pkcs10")
|
|
715
745
|
MIMETYPE(".p12", "application/x-pkcs12")
|
|
746
|
+
MIMETYPE(".p21", "model/step")
|
|
716
747
|
MIMETYPE(".p7b", "application/x-pkcs7-certificates")
|
|
717
748
|
MIMETYPE(".p7c", "application/pkcs7-mime")
|
|
718
749
|
MIMETYPE(".p7m", "application/pkcs7-mime")
|
|
@@ -935,10 +966,13 @@ MIMETYPE(".ssml", "application/ssml+xml")
|
|
|
935
966
|
MIMETYPE(".st", "application/vnd.sailingtracker.track")
|
|
936
967
|
MIMETYPE(".stc", "application/vnd.sun.xml.calc.template")
|
|
937
968
|
MIMETYPE(".std", "application/vnd.sun.xml.draw.template")
|
|
969
|
+
MIMETYPE(".step", "model/step")
|
|
938
970
|
MIMETYPE(".stf", "application/vnd.wt.stf")
|
|
939
971
|
MIMETYPE(".sti", "application/vnd.sun.xml.impress.template")
|
|
940
972
|
MIMETYPE(".stk", "application/hyperstudio")
|
|
941
973
|
MIMETYPE(".stl", "application/vnd.ms-pki.stl")
|
|
974
|
+
MIMETYPE(".stp", "model/step")
|
|
975
|
+
MIMETYPE(".stpnc", "model/step")
|
|
942
976
|
MIMETYPE(".stpx", "model/step+xml")
|
|
943
977
|
MIMETYPE(".stpxz", "model/step-xml+zip")
|
|
944
978
|
MIMETYPE(".stpz", "model/step+zip")
|
|
@@ -1072,6 +1106,7 @@ MIMETYPE(".vcs", "text/x-vcalendar")
|
|
|
1072
1106
|
MIMETYPE(".vcx", "application/vnd.vcx")
|
|
1073
1107
|
MIMETYPE(".vdi", "application/x-virtualbox-vdi")
|
|
1074
1108
|
MIMETYPE(".vds", "model/vnd.sap.vds")
|
|
1109
|
+
MIMETYPE(".vdx", "application/vnd.ms-visio.viewer")
|
|
1075
1110
|
MIMETYPE(".vhd", "application/x-virtualbox-vhd")
|
|
1076
1111
|
MIMETYPE(".vis", "application/vnd.visionary")
|
|
1077
1112
|
MIMETYPE(".viv", "video/vnd.vivo")
|
|
@@ -1081,6 +1116,7 @@ MIMETYPE(".vor", "application/vnd.stardivision.writer")
|
|
|
1081
1116
|
MIMETYPE(".vox", "application/x-authorware-bin")
|
|
1082
1117
|
MIMETYPE(".vrml", "model/vrml")
|
|
1083
1118
|
MIMETYPE(".vsd", "application/vnd.visio")
|
|
1119
|
+
MIMETYPE(".vsdx", "application/vnd.visio")
|
|
1084
1120
|
MIMETYPE(".vsf", "application/vnd.vsf")
|
|
1085
1121
|
MIMETYPE(".vss", "application/vnd.visio")
|
|
1086
1122
|
MIMETYPE(".vst", "application/vnd.visio")
|
|
@@ -1088,6 +1124,7 @@ MIMETYPE(".vsw", "application/vnd.visio")
|
|
|
1088
1124
|
MIMETYPE(".vtf", "image/vnd.valve.source.texture")
|
|
1089
1125
|
MIMETYPE(".vtt", "text/vtt")
|
|
1090
1126
|
MIMETYPE(".vtu", "model/vnd.vtu")
|
|
1127
|
+
MIMETYPE(".vtx", "application/vnd.visio")
|
|
1091
1128
|
MIMETYPE(".vxml", "application/voicexml+xml")
|
|
1092
1129
|
MIMETYPE(".w3d", "application/x-director")
|
|
1093
1130
|
MIMETYPE(".wad", "application/x-doom")
|
|
@@ -1154,6 +1191,7 @@ MIMETYPE(".xbd", "application/vnd.fujixerox.docuworks.binder")
|
|
|
1154
1191
|
MIMETYPE(".xbm", "image/x-xbitmap")
|
|
1155
1192
|
MIMETYPE(".xca", "application/xcap-caps+xml")
|
|
1156
1193
|
MIMETYPE(".xcs", "application/calendar+xml")
|
|
1194
|
+
MIMETYPE(".xdcf", "application/vnd.gov.sk.xmldatacontainer+xml")
|
|
1157
1195
|
MIMETYPE(".xdf", "application/xcap-diff+xml")
|
|
1158
1196
|
MIMETYPE(".xdm", "application/vnd.syncml.dm+xml")
|
|
1159
1197
|
MIMETYPE(".xdp", "application/vnd.adobe.xdp+xml")
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
|
-
# Copyright
|
|
3
|
+
# Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
4
4
|
#
|
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
-
# this software and associated documentation files (the “Software”), to deal in
|
|
6
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
7
7
|
# the Software without restriction, including without limitation the rights to use,
|
|
8
8
|
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
9
9
|
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
@@ -65,7 +65,7 @@ if __name__ == "__main__":
|
|
|
65
65
|
f.write(line)
|
|
66
66
|
|
|
67
67
|
print('', file = f)
|
|
68
|
-
print('#
|
|
68
|
+
print('#if !defined(MIMETYPE)', file = f)
|
|
69
69
|
print(' #error Please define MIMETYPE() before including mimetypes.inc', file = f)
|
|
70
70
|
print('#endif', file = f)
|
|
71
71
|
print('', file = f)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
4
|
+
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
7
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
8
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
9
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
# subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
import sys
|
|
25
|
+
import re
|
|
26
|
+
import argparse
|
|
27
|
+
import urllib.request
|
|
28
|
+
import os.path
|
|
29
|
+
from collections import namedtuple
|
|
30
|
+
|
|
31
|
+
DEFAULT_URL = 'https://unicode.org/Public/16.0.0'
|
|
32
|
+
|
|
33
|
+
LICENSE_HEADER = """// Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
34
|
+
|
|
35
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
36
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
37
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
38
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
39
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
40
|
+
// subject to the following conditions:
|
|
41
|
+
|
|
42
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
43
|
+
// copies or substantial portions of the Software.
|
|
44
|
+
|
|
45
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
46
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
47
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
48
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
49
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
50
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
51
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
52
|
+
// OTHER DEALINGS IN THE SOFTWARE."""
|
|
53
|
+
|
|
54
|
+
XidResult = namedtuple('XidResult', ['version', 'id_start', 'id_continue'])
|
|
55
|
+
|
|
56
|
+
def parse_properties_xid(text):
|
|
57
|
+
id_start = []
|
|
58
|
+
id_continue = []
|
|
59
|
+
|
|
60
|
+
lines = iter(text.splitlines())
|
|
61
|
+
version = next(lines).strip("\n\r \t#") + ' -- ' + next(lines).strip("\n\r \t#")
|
|
62
|
+
|
|
63
|
+
for line in lines:
|
|
64
|
+
line = line.strip()
|
|
65
|
+
|
|
66
|
+
if not line or line[0] == '#':
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
parts = [part.strip() for part in re.split('[;#]', line)]
|
|
70
|
+
if len(parts) < 3:
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
if '..' in parts[0]:
|
|
74
|
+
start, end = parts[0].split('..')
|
|
75
|
+
else:
|
|
76
|
+
start, end = parts[0], parts[0]
|
|
77
|
+
start, end = int(start, 16), int(end, 16)
|
|
78
|
+
|
|
79
|
+
if parts[1] == 'ID_Start':
|
|
80
|
+
id_start.append((start, end + 1))
|
|
81
|
+
elif parts[1] == 'ID_Continue':
|
|
82
|
+
id_continue.append((start, end + 1))
|
|
83
|
+
|
|
84
|
+
return XidResult(version = version, id_start = id_start, id_continue = id_continue)
|
|
85
|
+
|
|
86
|
+
def write_xid_header(xid, f):
|
|
87
|
+
f.write(f"""{LICENSE_HEADER}
|
|
88
|
+
|
|
89
|
+
// This file is autogenerated by generator.py
|
|
90
|
+
// Version: {xid.version}
|
|
91
|
+
|
|
92
|
+
namespace RG {{
|
|
93
|
+
|
|
94
|
+
static const int32_t XidStartTable[] = {{""")
|
|
95
|
+
for i, v in enumerate(xid.id_start):
|
|
96
|
+
if i % 5 == 0: f.write('\n ')
|
|
97
|
+
f.write(f' 0x{v[0]:05X}, 0x{v[1]:05X}{"," if i + 1 < len(xid.id_start) else ""}')
|
|
98
|
+
f.write("""
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
static const int32_t XidContinueTable[] = {""")
|
|
102
|
+
for i, v in enumerate(xid.id_continue):
|
|
103
|
+
if i % 5 == 0: f.write('\n ')
|
|
104
|
+
f.write(f' 0x{v[0]:05X}, 0x{v[1]:05X}{"," if i + 1 < len(xid.id_continue) else ""}')
|
|
105
|
+
f.write("""
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
""")
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
parser = argparse.ArgumentParser(description = 'Extract xid and wcwidth information from Unicode standard')
|
|
113
|
+
parser.add_argument('url', metavar = 'url', type = str, nargs = '?', help = 'URL of Unicode standard', default = DEFAULT_URL)
|
|
114
|
+
parser.add_argument('-O', '--output_dir', metavar = 'directory', type = str, help = 'output directory for generated files', default = '.')
|
|
115
|
+
args = parser.parse_args()
|
|
116
|
+
|
|
117
|
+
url = args.url.strip('/') + '/ucd/'
|
|
118
|
+
|
|
119
|
+
# XID
|
|
120
|
+
with urllib.request.urlopen(url + 'DerivedCoreProperties.txt') as f:
|
|
121
|
+
text = f.read().decode('UTF-8')
|
|
122
|
+
xid = parse_properties_xid(text)
|
|
123
|
+
with open(os.path.join(args.output_dir, 'xid.inc'), 'w') as f:
|
|
124
|
+
write_xid_header(xid, f)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
#include "src/core/base/base.hh"
|
|
23
|
+
#include "xid.inc"
|
|
24
|
+
|
|
25
|
+
namespace RG {
|
|
26
|
+
|
|
27
|
+
static bool TestUnicodeTable(Span<const int32_t> table, int32_t uc)
|
|
28
|
+
{
|
|
29
|
+
RG_ASSERT(table.len > 0);
|
|
30
|
+
RG_ASSERT(table.len % 2 == 0);
|
|
31
|
+
|
|
32
|
+
auto it = std::upper_bound(table.begin(), table.end(), uc,
|
|
33
|
+
[](int32_t uc, int32_t x) { return uc < x; });
|
|
34
|
+
Size idx = it - table.ptr;
|
|
35
|
+
|
|
36
|
+
// Each pair of value in table represents a valid interval
|
|
37
|
+
return idx & 0x1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
bool IsXidStart(int32_t uc)
|
|
41
|
+
{
|
|
42
|
+
bool match = IsAsciiAlpha(uc) || uc == '_' || TestUnicodeTable(XidStartTable, uc);
|
|
43
|
+
return match;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bool IsXidContinue(int32_t uc)
|
|
47
|
+
{
|
|
48
|
+
bool match = IsAsciiAlphaOrDigit(uc) || uc == '_' || TestUnicodeTable(XidContinueTable, uc);
|
|
49
|
+
return match;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
#include "src/core/base/base.hh"
|
|
23
|
+
|
|
24
|
+
namespace RG {
|
|
25
|
+
|
|
26
|
+
bool IsXidStart(int32_t uc);
|
|
27
|
+
bool IsXidContinue(int32_t uc);
|
|
28
|
+
|
|
29
|
+
}
|