nadesiko3 3.3.45 → 3.3.49

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 (329) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +143 -132
  3. package/batch/browsers.template.md +3 -3
  4. package/batch/build_browsers.nako3 +72 -72
  5. package/batch/build_command.nako3 +44 -44
  6. package/batch/build_nako_version.nako3 +42 -42
  7. package/batch/calc_hash.nako3 +29 -29
  8. package/batch/cmd_txt2json.nako3 +74 -74
  9. package/batch/command.txt +270 -338
  10. package/batch/command_nakopad.txt +9 -69
  11. package/batch/download-extlib.nako3 +43 -43
  12. package/batch/gen_command_nakopad.nako3 +57 -57
  13. package/batch/jsplugin2text.nako3 +285 -285
  14. package/batch/pickup_command.nako3 +110 -110
  15. package/batch/pickup_reserved_words.nako3 +11 -11
  16. package/batch/publish_version.nako3 +46 -46
  17. package/batch/show_agents.js +14 -14
  18. package/batch/turtle2js.nako3 +21 -21
  19. package/bin/cnako3 +10 -10
  20. package/core/.editorconfig +6 -0
  21. package/core/.eslintrc.cjs +33 -0
  22. package/core/.github/dependabot.yml +7 -0
  23. package/core/.github/workflows/nodejs.yml +37 -0
  24. package/core/.github/workflows/super-linter.yml +61 -0
  25. package/core/.github/workflows/textlint.yml +199 -0
  26. package/core/LICENSE +21 -0
  27. package/core/README.md +66 -0
  28. package/core/batch/build_nako_version.nako3 +42 -0
  29. package/core/command/snako.mjs +105 -0
  30. package/core/command/snako.mts +116 -0
  31. package/core/index.mjs +21 -0
  32. package/core/index.mts +21 -0
  33. package/core/package.json +47 -0
  34. package/core/sample/hello.nako3 +7 -0
  35. package/core/sample/hoge.mjs +4 -0
  36. package/core/sample/hoge.mts +6 -0
  37. package/core/src/nako3.mjs +858 -0
  38. package/core/src/nako3.mts +967 -0
  39. package/core/src/nako_colors.mjs +78 -0
  40. package/core/src/nako_colors.mts +86 -0
  41. package/core/src/nako_core_version.mjs +8 -0
  42. package/core/src/nako_core_version.mts +19 -0
  43. package/core/src/nako_csv.mjs +185 -0
  44. package/core/src/nako_csv.mts +188 -0
  45. package/core/src/nako_errors.mjs +173 -0
  46. package/core/src/nako_errors.mts +197 -0
  47. package/core/src/nako_from_dncl.mjs +255 -0
  48. package/core/src/nako_from_dncl.mts +250 -0
  49. package/core/src/nako_gen.mjs +1648 -0
  50. package/core/src/nako_gen.mts +1719 -0
  51. package/core/src/nako_gen_async.mjs +1659 -0
  52. package/core/src/nako_gen_async.mts +1732 -0
  53. package/core/src/nako_global.mjs +107 -0
  54. package/core/src/nako_global.mts +138 -0
  55. package/core/src/nako_indent.mjs +445 -0
  56. package/core/src/nako_indent.mts +492 -0
  57. package/core/src/nako_josi_list.mjs +38 -0
  58. package/core/src/nako_josi_list.mts +45 -0
  59. package/core/src/nako_lex_rules.mjs +253 -0
  60. package/core/src/nako_lex_rules.mts +260 -0
  61. package/core/src/nako_lexer.mjs +609 -0
  62. package/core/src/nako_lexer.mts +612 -0
  63. package/core/src/nako_logger.mjs +199 -0
  64. package/core/src/nako_logger.mts +232 -0
  65. package/core/src/nako_parser3.mjs +2439 -0
  66. package/core/src/nako_parser3.mts +2195 -0
  67. package/core/src/nako_parser_base.mjs +370 -0
  68. package/core/src/nako_parser_base.mts +370 -0
  69. package/core/src/nako_parser_const.mjs +37 -0
  70. package/core/src/nako_parser_const.mts +37 -0
  71. package/core/src/nako_prepare.mjs +304 -0
  72. package/core/src/nako_prepare.mts +315 -0
  73. package/core/src/nako_reserved_words.mjs +38 -0
  74. package/core/src/nako_reserved_words.mts +38 -0
  75. package/core/src/nako_source_mapping.mjs +207 -0
  76. package/core/src/nako_source_mapping.mts +262 -0
  77. package/core/src/nako_test.mjs +37 -0
  78. package/core/src/nako_types.mjs +25 -0
  79. package/core/src/nako_types.mts +151 -0
  80. package/core/src/plugin_csv.mjs +49 -0
  81. package/core/src/plugin_csv.mts +50 -0
  82. package/core/src/plugin_math.mjs +328 -0
  83. package/core/src/plugin_math.mts +326 -0
  84. package/core/src/plugin_promise.mjs +91 -0
  85. package/core/src/plugin_promise.mts +91 -0
  86. package/core/src/plugin_system.mjs +2832 -0
  87. package/core/src/plugin_system.mts +2690 -0
  88. package/core/src/plugin_test.mjs +34 -0
  89. package/core/src/plugin_test.mts +34 -0
  90. package/core/test/array_test.mjs +34 -0
  91. package/core/test/basic_test.mjs +344 -0
  92. package/core/test/calc_test.mjs +140 -0
  93. package/core/test/core_module_test.mjs +23 -0
  94. package/core/test/debug_test.mjs +16 -0
  95. package/core/test/dncl_test.mjs +94 -0
  96. package/core/test/error_message_test.mjs +210 -0
  97. package/core/test/error_test.mjs +16 -0
  98. package/core/test/flow_test.mjs +373 -0
  99. package/core/test/func_call.mjs +160 -0
  100. package/core/test/func_test.mjs +149 -0
  101. package/core/test/indent_test.mjs +364 -0
  102. package/core/test/lex_test.mjs +168 -0
  103. package/core/test/literal_test.mjs +73 -0
  104. package/core/test/nako_lexer_test.mjs +35 -0
  105. package/core/test/nako_logger_test.mjs +76 -0
  106. package/core/test/nako_logger_test.mts +78 -0
  107. package/core/test/plugin_csv_test.mjs +38 -0
  108. package/core/test/plugin_promise_test.mjs +18 -0
  109. package/core/test/plugin_system_test.mjs +630 -0
  110. package/core/test/prepare_test.mjs +96 -0
  111. package/core/test/re_test.mjs +22 -0
  112. package/core/test/side_effects_test.mjs +92 -0
  113. package/core/test/variable_scope_test.mjs +149 -0
  114. package/core/tsconfig.json +101 -0
  115. package/demo/ace_editor.html +89 -89
  116. package/demo/ace_editor_tabs.html +161 -161
  117. package/demo/basic.html +71 -71
  118. package/demo/browsers.html +9 -10
  119. package/demo/css/basic.css +3 -3
  120. package/demo/css/common.css +157 -157
  121. package/demo/css/editor.css +8 -8
  122. package/demo/css/flow.css +3 -3
  123. package/demo/css/index.css +3 -3
  124. package/demo/flow.html +98 -98
  125. package/demo/graph.html +53 -53
  126. package/demo/image/nakopad-icon256.png +0 -0
  127. package/demo/index.html +133 -133
  128. package/demo/js/common.js +17 -17
  129. package/demo/js/turtle3d_test.js +44 -44
  130. package/demo/js/turtle_test.js +45 -45
  131. package/demo/nako3/calc.nako3 +4 -4
  132. package/demo/runscript.html +47 -47
  133. package/demo/runscript2.html +33 -33
  134. package/demo/runscript3.html +35 -35
  135. package/demo/runscript4.html +33 -33
  136. package/demo/turtle.html +58 -58
  137. package/demo/turtle2.html +141 -141
  138. package/demo/turtle3.html +279 -279
  139. package/demo/turtle3d.html +58 -58
  140. package/demo/turtle3d2.html +107 -107
  141. package/demo/version.html +24 -24
  142. package/doc/SETUP.md +157 -157
  143. package/doc/about.md +17 -17
  144. package/doc/browsers.md +26 -26
  145. package/doc/docgen.md +21 -21
  146. package/doc/editor.md +44 -44
  147. package/doc/files.md +39 -39
  148. package/doc/plugins.md +234 -234
  149. package/doc/release.md +79 -79
  150. package/doc/textlint.md +43 -43
  151. package/doc/win32.md +57 -57
  152. package/package.json +195 -192
  153. package/release/_hash.txt +28 -28
  154. package/release/_script-tags.txt +14 -14
  155. package/release/command.json +1 -1
  156. package/release/command.json.js +1 -1
  157. package/release/command_cnako3.json +1 -1
  158. package/release/command_list.json +1 -1
  159. package/release/editor.js +1 -1
  160. package/release/nako_gen_async.js +1 -1
  161. package/release/plugin_csv.js +1 -1
  162. package/release/stats.json +1 -1
  163. package/release/version.js +1 -1
  164. package/release/wnako3.js +1 -1
  165. package/release/wnako3webworker.js +1 -1
  166. package/src/browsers.txt +11 -12
  167. package/src/browsers_agents.json +2 -2
  168. package/src/browsers_agents.mjs +1 -1
  169. package/src/cnako3.mjs +17 -10
  170. package/src/cnako3.mts +18 -12
  171. package/src/cnako3mod.mjs +707 -687
  172. package/src/cnako3mod.mts +712 -696
  173. package/src/commander_ja.mjs +164 -164
  174. package/src/commander_ja.mts +161 -161
  175. package/src/enako3.mjs +68 -69
  176. package/src/era.mjs +22 -22
  177. package/src/image_turtle-elephant.mjs +2 -5
  178. package/src/image_turtle-panda.mjs +2 -5
  179. package/src/image_turtle64.mjs +2 -5
  180. package/src/index.mjs +9 -9
  181. package/src/index.mts +10 -11
  182. package/src/nako3editorfix.sfd +106 -106
  183. package/src/nako_version.mjs +8 -8
  184. package/src/nako_version.mts +2 -2
  185. package/src/plugin_browser.mjs +213 -212
  186. package/src/plugin_browser.mts +206 -205
  187. package/src/plugin_browser_ajax.mjs +399 -399
  188. package/src/plugin_browser_audio.mjs +109 -109
  189. package/src/plugin_browser_canvas.mjs +449 -449
  190. package/src/plugin_browser_chart.mjs +294 -294
  191. package/src/plugin_browser_color.mjs +49 -49
  192. package/src/plugin_browser_crypto.mjs +26 -26
  193. package/src/plugin_browser_dialog.mjs +53 -53
  194. package/src/plugin_browser_dom_basic.mjs +336 -336
  195. package/src/plugin_browser_dom_event.mjs +193 -193
  196. package/src/plugin_browser_dom_parts.mjs +396 -396
  197. package/src/plugin_browser_geolocation.mjs +51 -51
  198. package/src/plugin_browser_hotkey.mjs +25 -25
  199. package/src/plugin_browser_html.mjs +59 -59
  200. package/src/plugin_browser_in_worker.mjs +45 -45
  201. package/src/plugin_browser_location.mjs +21 -21
  202. package/src/plugin_browser_speech.mjs +111 -111
  203. package/src/plugin_browser_storage.mjs +121 -121
  204. package/src/plugin_browser_system.mjs +31 -31
  205. package/src/plugin_browser_websocket.mjs +73 -73
  206. package/src/plugin_caniuse.mjs +29 -29
  207. package/src/plugin_datetime.mjs +394 -394
  208. package/src/plugin_httpserver.mjs +277 -0
  209. package/src/plugin_httpserver.mts +286 -0
  210. package/src/plugin_kansuji.mjs +224 -224
  211. package/src/plugin_keigo.mjs +55 -55
  212. package/src/plugin_markup.mjs +32 -32
  213. package/src/plugin_node.mjs +1047 -1047
  214. package/src/plugin_node.mts +980 -980
  215. package/src/plugin_turtle.mjs +647 -647
  216. package/src/plugin_webworker.mjs +334 -334
  217. package/src/plugin_weykturtle3d.mjs +1214 -1214
  218. package/src/plugin_worker.mjs +95 -95
  219. package/src/repl.nako3 +63 -63
  220. package/src/wnako3.mjs +12 -12
  221. package/src/wnako3.mts +11 -11
  222. package/src/wnako3_editor.css +215 -215
  223. package/src/wnako3_editor.mjs +1542 -1542
  224. package/src/wnako3_editor.mts +1657 -1656
  225. package/src/wnako3mod.mjs +213 -213
  226. package/src/wnako3mod.mts +214 -214
  227. package/src/wnako3webworker.mjs +69 -68
  228. package/test/ace_editor/karma.config.js +94 -94
  229. package/test/ace_editor/test/.babelrc.json +3 -3
  230. package/test/ace_editor/test/ace_editor_test.js +178 -178
  231. package/test/ace_editor/test/html/custom_context.html +139 -139
  232. package/test/async/async_basic_test.mjs +122 -122
  233. package/test/browser/karma.config.js +221 -221
  234. package/test/browser/test/.babelrc.json +3 -3
  235. package/test/browser/test/compare_util.js +50 -50
  236. package/test/browser/test/html/div_basic.html +2 -2
  237. package/test/browser/test/html/event_dom_form.html +4 -4
  238. package/test/browser/test/html/event_dom_scrolldiv.html +5 -5
  239. package/test/browser/test/import_plugin_checker.js +24 -24
  240. package/test/browser/test/plugin_browser_test.js +51 -51
  241. package/test/browser/test/plugin_browser_test_ajax.js +123 -123
  242. package/test/browser/test/plugin_browser_test_color.js +18 -18
  243. package/test/browser/test/plugin_browser_test_dialog.js +72 -72
  244. package/test/browser/test/plugin_browser_test_dom_event.js +598 -598
  245. package/test/browser/test/plugin_browser_test_dom_parts.js +125 -125
  246. package/test/browser/test/plugin_browser_test_system.js +9 -9
  247. package/test/browser/test/plugin_turtle_test.js +817 -817
  248. package/test/browser/test/plugin_webworker_test.js +86 -86
  249. package/test/browser/test/require_test.js +68 -68
  250. package/test/bundled/karma.config.base.js +117 -117
  251. package/test/bundled/karma.config.js +86 -86
  252. package/test/bundled/test/.babelrc.json +3 -3
  253. package/test/bundled/test/bundled_test.js +69 -69
  254. package/test/bundled/test/html/custom_context.html +65 -65
  255. package/test/bundled/test/html/custom_debug.html +66 -66
  256. package/test/bundled/test4b.cmd +52 -52
  257. package/test/bundled/test_base/.babelrc.json +3 -3
  258. package/test/bundled/test_base/_checktool_test.js +25 -25
  259. package/test/bundled/test_base/basic_ajax_test.js +56 -56
  260. package/test/bundled/test_base/basic_async_test.js +18 -18
  261. package/test/bundled/test_base/basic_test.js +153 -153
  262. package/test/bundled/test_base/calc_test.js +132 -132
  263. package/test/bundled/test_base/css/browsers_box.css +114 -114
  264. package/test/bundled/test_base/html/custom_context.html +69 -69
  265. package/test/bundled/test_base/html/custom_debug.html +71 -71
  266. package/test/bundled/test_base/js/browsers_box.js +72 -72
  267. package/test/bundled/test_base/plugin_csv_test.js +37 -37
  268. package/test/bundled/test_base/plugin_datetime_test.js +115 -115
  269. package/test/bundled/test_base/plugin_kansuji_test.js +49 -49
  270. package/test/bundled/test_base/plugin_system_test.js +410 -410
  271. package/test/bundled/test_base/plugin_webworker_test.js +53 -53
  272. package/test/bundled/test_base/test_utils.js +191 -191
  273. package/test/common/plugin_browser_test.mjs +22 -24
  274. package/test/common/plugin_browser_ut_audio_test.mjs +108 -108
  275. package/test/common/plugin_browser_ut_color_test.mjs +21 -21
  276. package/test/common/plugin_browser_ut_dialog_test.mjs +100 -100
  277. package/test/common/plugin_browser_ut_html_test.mjs +13 -13
  278. package/test/common/plugin_browser_ut_system_test.mjs +10 -10
  279. package/test/common/plugin_markup_test.mjs +23 -23
  280. package/test/jsconfig.json +19 -19
  281. package/test/karma.config.js +91 -91
  282. package/test/node/async_test.mjs +96 -82
  283. package/test/node/commander_ja_test.mjs +89 -89
  284. package/test/node/error_message_test.mjs +243 -253
  285. package/test/node/kai_test.nako3 +6 -6
  286. package/test/node/node_test.mjs +60 -60
  287. package/test/node/plugin_broken.js.txt +3 -3
  288. package/test/node/plugin_browser_ut_ajax_test.mjs.todo +357 -357
  289. package/test/node/plugin_browser_ut_location_test.mjs +42 -42
  290. package/test/node/plugin_markup_test.mjs +47 -46
  291. package/test/node/plugin_math_test.mjs +45 -44
  292. package/test/node/plugin_node_test.mjs +98 -97
  293. package/test/node/plugin_test.mjs +44 -43
  294. package/test/node/relative_import_test_1.nako3 +1 -1
  295. package/test/node/relative_import_test_2.nako3 +2 -2
  296. package/test/node/require_nako3_test.mjs +67 -66
  297. package/test/node/requiretest.nako3 +4 -4
  298. package/test/node/requiretest_indirect.nako3 +1 -1
  299. package/test/node/requiretest_name.nako3 +5 -5
  300. package/test/node/runtime_error.nako3 +2 -2
  301. package/test/node/scope1.nako3 +10 -10
  302. package/test/node/scope2.nako3 +12 -12
  303. package/test/node/side_effects_test.mjs +39 -119
  304. package/test/node/sjis.txt +5 -5
  305. package/test/node/syntax_error.nako3 +1 -1
  306. package/test/node/wnako3_editor_test.mjs +384 -384
  307. package/tools/README.md +12 -7
  308. package/tools/check_new_version.nako3 +25 -25
  309. package/tools/nako3edit/html/daisyui/LICENSE +22 -22
  310. package/tools/nako3edit/html/daisyui/version_2.14.1 +1 -1
  311. package/tools/nako3edit/html/edit.html +170 -170
  312. package/tools/nako3edit/html/edit_plugin.js +6 -6
  313. package/tools/nako3edit/html/files.html +125 -125
  314. package/tools/nako3edit/html/nako3edit.css +65 -65
  315. package/tools/nako3edit/index.mjs +248 -244
  316. package/tools/nako3server/index.html +10 -0
  317. package/tools/nako3server/index.mjs +116 -116
  318. package/tools/nako3server/index.nako3 +34 -0
  319. package/release/nako_gen_async.js.LICENSE.txt +0 -35
  320. package/release/plugin_caniuse.js.LICENSE.txt +0 -11
  321. package/release/plugin_csv.js.LICENSE.txt +0 -15
  322. package/release/plugin_datetime.js.LICENSE.txt +0 -15
  323. package/release/plugin_kansuji.js.LICENSE.txt +0 -3
  324. package/release/plugin_markup.js.LICENSE.txt +0 -11
  325. package/release/plugin_turtle.js.LICENSE.txt +0 -15
  326. package/release/plugin_webworker.js.LICENSE.txt +0 -3
  327. package/release/plugin_weykturtle3d.js.LICENSE.txt +0 -3
  328. package/release/wnako3webworker.js.LICENSE.txt +0 -131
  329. package/tools/nako3edit/a.sqlite3 +0 -0
@@ -0,0 +1,2690 @@
1
+ import { NakoRuntimeError } from './nako_errors.mjs'
2
+
3
+ export default {
4
+ 'meta': {
5
+ type: 'const',
6
+ value: {
7
+ pluginName: 'plugin_system', // プラグインの名前
8
+ pluginVersion: '3.3.38', // プラグインのバージョン
9
+ nakoRuntime: ['wnako', 'cnako', 'phpnako'], // 対象ランタイム
10
+ nakoVersion: '^3.3.38' // 要求なでしこバージョン
11
+ }
12
+ },
13
+ '初期化': {
14
+ type: 'func',
15
+ josi: [],
16
+ pure: false,
17
+ fn: function (sys: any) {
18
+ // 言語バージョンを設定
19
+ sys.__v0['ナデシコバージョン'] = sys.version
20
+ sys.__v0['ナデシコ言語バージョン'] = sys.coreVersion
21
+ // なでしこの関数や変数を探して返す
22
+ sys.__findVar = function (nameStr: any, def: any): any {
23
+ if (typeof nameStr === 'function') { return nameStr }
24
+ if (sys.__locals[nameStr]) { return sys.__locals[nameStr] }
25
+ const modName = ((typeof sys.__modName) !== 'undefined') ? sys.__modName : 'inline'
26
+ const gname = (nameStr.indexOf('__') >= 0) ? nameStr : modName + '__' + nameStr
27
+ for (let i = 2; i >= 0; i--) {
28
+ const scope = sys.__varslist[i]
29
+ if (scope[gname]) { return scope[gname] }
30
+ }
31
+ return def
32
+ }
33
+ // 文字列から関数を探す
34
+ sys.__findFunc = function (nameStr: any, parentFunc: string): any {
35
+ const f = sys.__findVar(nameStr)
36
+ if (typeof f === 'function') { return f }
37
+ throw new Error(`『${parentFunc}』に実行できない関数が指定されました。`)
38
+ }
39
+ // システム関数を実行
40
+ sys.__exec = function (func: string, params: any[]): any {
41
+ // システム命令を優先
42
+ const f0 = sys.__v0[func]
43
+ if (f0) { return f0.apply(this, params) }
44
+ // グローバル・ローカルを探す
45
+ const f = sys.__findVar(func)
46
+ if (!f) { throw new Error('システム関数でエイリアスの指定ミス:' + func) }
47
+ return f.apply(this, params)
48
+ }
49
+ // タイマーに関する処理(タイマーは「!クリア」で全部停止する)
50
+ sys.__timeout = []
51
+ sys.__interval = []
52
+ // 日付処理などに使う
53
+ const z2 = sys.__zero2 = (s: string|number): string => {
54
+ s = '00' + s
55
+ return s.substring(s.length - 2)
56
+ }
57
+ sys.__zero = (s: string, keta: number): string => {
58
+ let zeroS = ''
59
+ for (let i = 0; i < keta; i++) { zeroS += '0' }
60
+ s = zeroS + s
61
+ return s.substring(s.length - keta)
62
+ }
63
+ sys.__formatDate = (t: Date): string => {
64
+ return t.getFullYear() + '/' + z2(t.getMonth() + 1) + '/' + z2(t.getDate())
65
+ }
66
+ sys.__formatTime = (t: Date): string => {
67
+ return z2(t.getHours()) + ':' + z2(t.getSeconds()) + ':' + z2(t.getMinutes())
68
+ }
69
+ sys.__formatDateTime = (t: Date, fmt: string): string => {
70
+ const dateStr = t.getFullYear() + '/' + z2(t.getMonth() + 1) + '/' + z2(t.getDate())
71
+ const timeStr = z2(t.getHours()) + ':' + z2(t.getMinutes()) + ':' + z2(t.getSeconds())
72
+ if (fmt.match(/^\d+\/\d+\/\d+\s+\d+:\d+:\d+$/)) {
73
+ return dateStr + ' ' + timeStr
74
+ }
75
+ if (fmt.match(/^\d+\/\d+\/\d+$/)) {
76
+ return dateStr
77
+ }
78
+ if (fmt.match(/^\d+:\d+:\d+$/)) {
79
+ return timeStr
80
+ }
81
+ return dateStr + ' ' + timeStr
82
+ }
83
+ sys.__str2date = (s: string): Date => {
84
+ // trim
85
+ s = ('' + s).replace(/(^\s+|\s+$)/, '')
86
+ // is unix time
87
+ if (s.match(/^(\d+|\d+\.\d+)$/)) {
88
+ return new Date(parseFloat(s) * 1000)
89
+ }
90
+ // is time ?
91
+ if (s.match(/^\d+:\d+(:\d+)?$/)) {
92
+ const t = new Date()
93
+ const a = (s + ':0').split(':')
94
+ return new Date(
95
+ t.getFullYear(), t.getMonth(), t.getDate(),
96
+ parseInt(a[0]), parseInt(a[1]), parseInt(a[2]))
97
+ }
98
+ // replace splitter to '/'
99
+ s = s.replace(/[\s:-]/g, '/')
100
+ s += '/0/0/0' // 日付だけのときのために時間分を足す
101
+ const a = s.split('/')
102
+ return new Date(parseInt(a[0]), parseInt(a[1]) - 1, parseInt(a[2]),
103
+ parseInt(a[3]), parseInt(a[4]), parseInt(a[5]))
104
+ }
105
+ // 『継続表示』のための一時変数(『表示』実行で初期化)
106
+ sys.__printPool = ''
107
+ }
108
+ },
109
+ '!クリア': {
110
+ type: 'func',
111
+ josi: [],
112
+ pure: false,
113
+ fn: function (sys: any) {
114
+ sys.__exec('全タイマー停止', [sys])
115
+ if (sys.__genMode === '非同期モード') { sys.__stopAsync(sys) }
116
+ sys.__v0['表示ログ'] = ''
117
+ }
118
+ },
119
+
120
+ // @システム定数
121
+ 'ナデシコバージョン': { type: 'const', value: '?' }, // @なでしこばーじょん
122
+ 'ナデシコ言語バージョン': { type: 'const', value: '?' }, // @なでしこげんごばーじょん
123
+ 'ナデシコエンジン': { type: 'const', value: 'nadesi.com/v3' }, // @なでしこえんじん
124
+ 'ナデシコ種類': { type: 'const', value: '?' }, // @なでしこしゅるい
125
+ 'はい': { type: 'const', value: 1 }, // @はい
126
+ 'いいえ': { type: 'const', value: 0 }, // @いいえ
127
+ '真': { type: 'const', value: 1 }, // @しん
128
+ '偽': { type: 'const', value: 0 }, // @ぎ
129
+ '永遠': { type: 'const', value: 1 }, // @えいえん
130
+ 'オン': { type: 'const', value: 1 }, // @おん
131
+ 'オフ': { type: 'const', value: 0 }, // @おふ
132
+ '改行': { type: 'const', value: '\n' }, // @かいぎょう
133
+ 'タブ': { type: 'const', value: '\t' }, // @たぶ
134
+ 'カッコ': { type: 'const', value: '「' }, // @かっこ
135
+ 'カッコ閉': { type: 'const', value: '」' }, // @かっことじ
136
+ '波カッコ': { type: 'const', value: '{' }, // @なみかっこ
137
+ '波カッコ閉': { type: 'const', value: '}' }, // @なみかっことじ
138
+ 'OK': { type: 'const', value: true }, // @OK
139
+ 'NG': { type: 'const', value: false }, // @NG
140
+ 'キャンセル': { type: 'const', value: 0 }, // @きゃんせる
141
+ 'PI': { type: 'const', value: Math.PI }, // @PI
142
+ '空': { type: 'const', value: '' }, // @から
143
+ 'NULL': { type: 'const', value: null }, // @NULL
144
+ 'undefined': { type: 'const', value: undefined }, // @undefined
145
+ '未定義': { type: 'const', value: undefined }, // @みていぎ
146
+ 'エラーメッセージ': { type: 'const', value: '' }, // @えらーめっせーじ
147
+ '対象': { type: 'const', value: '' }, // @たいしょう
148
+ '対象キー': { type: 'const', value: '' }, // @たいしょうきー
149
+ '回数': { type: 'const', value: '' }, // @かいすう
150
+ 'CR': { type: 'const', value: '\r' }, // @CR
151
+ 'LF': { type: 'const', value: '\n' }, // @LF
152
+ '非数': { type: 'const', value: NaN }, // @ひすう
153
+ '無限大': { type: 'const', value: Infinity }, // @むげんだい
154
+ '空配列': { // @空の配列を返す。『[]』と同義。 // @からはいれつ
155
+ type: 'func',
156
+ josi: [],
157
+ pure: true,
158
+ fn: function (): any {
159
+ return []
160
+ }
161
+ },
162
+ '空辞書': { // @空の辞書型を返す。『{}』と同義。 // @からじしょ
163
+ type: 'func',
164
+ josi: [],
165
+ pure: true,
166
+ fn: function (): any {
167
+ return {}
168
+ }
169
+ },
170
+ '空ハッシュ': { // @空のハッシュを返す(v3.2以降非推奨) // @からはっしゅ
171
+ type: 'func',
172
+ josi: [],
173
+ pure: true,
174
+ fn: function (): any {
175
+ return {}
176
+ }
177
+ },
178
+ '空オブジェクト': { // @空のオブジェクトを返す(v3.2以降非推奨) // @からおぶじぇくと
179
+ type: 'func',
180
+ josi: [],
181
+ pure: false,
182
+ fn: function (sys: any): any {
183
+ return sys.__exec('空ハッシュ', [sys])
184
+ }
185
+ },
186
+
187
+ // @標準出力
188
+ '表示': { // @Sを表示 // @ひょうじ
189
+ type: 'func',
190
+ josi: [['を', 'と']],
191
+ pure: true,
192
+ fn: function (s: string, sys: any) {
193
+ // 継続表示の一時プールを出力
194
+ s = sys.__printPool + s
195
+ sys.__printPool = ''
196
+ //
197
+ sys.__varslist[0]['表示ログ'] += (s + '\n')
198
+ sys.logger.send('stdout', s + '')
199
+ },
200
+ return_none: true
201
+ },
202
+ '継続表示': { // @Sを改行なしで表示(ただし「表示」命令を使うことで画面出力される) // @けいぞくひょうじ
203
+ type: 'func',
204
+ josi: [['を', 'と']],
205
+ pure: true,
206
+ fn: function (s: string, sys: any) {
207
+ sys.__printPool += s
208
+ },
209
+ return_none: true
210
+ },
211
+ '連続表示': { // @引数に指定した引数を全て表示する // @れんぞく表示
212
+ type: 'func',
213
+ josi: [['と', 'を']],
214
+ isVariableJosi: true,
215
+ pure: true,
216
+ fn: function (...a:any) {
217
+ const sys = a.pop()
218
+ const v = a.join('')
219
+ sys.__exec('表示', [v, sys])
220
+ },
221
+ return_none: true
222
+ },
223
+ '連続無改行表示': { // @引数に指定した引数を全て表示する(改行しない) // @れんぞくむかいぎょうひょうじ
224
+ type: 'func',
225
+ josi: [['と', 'を']],
226
+ isVariableJosi: true,
227
+ pure: true,
228
+ fn: function (...a:any) {
229
+ const sys = a.pop()
230
+ const v = a.join('')
231
+ sys.__exec('継続表示', [v, sys])
232
+ },
233
+ return_none: true
234
+ },
235
+ '表示ログ': { type: 'const', value: '' }, // @ひょうじろぐ
236
+ '表示ログクリア': { // @表示ログを空にする // @ひょうじろぐくりあ
237
+ type: 'func',
238
+ josi: [],
239
+ pure: true,
240
+ fn: function (sys: any) {
241
+ sys.__varslist[0]['表示ログ'] = ''
242
+ },
243
+ return_none: true
244
+ },
245
+ '言': { // @Sを表示 // @いう
246
+ type: 'func',
247
+ josi: [['を', 'と']],
248
+ pure: true,
249
+ fn: function (s: string, sys: any) {
250
+ sys.logger.send('stdout', s + '')
251
+ },
252
+ return_none: true
253
+ },
254
+ 'コンソール表示': { // @Sをコンソール表示する(console.log) // @こんそーるひょうじ
255
+ type: 'func',
256
+ josi: [['を', 'と']],
257
+ pure: true,
258
+ fn: function (s: string) {
259
+ console.log(s)
260
+ },
261
+ return_none: true
262
+ },
263
+
264
+ // @四則演算
265
+ '足': { // @AとBを足す // @たす
266
+ type: 'func',
267
+ josi: [['に', 'と'], ['を']],
268
+ isVariableJosi: false,
269
+ pure: true,
270
+ fn: function (a: any, b: any) {
271
+ return a + b
272
+ }
273
+ },
274
+ '引': { // @AからBを引く // @ひく
275
+ type: 'func',
276
+ josi: [['から'], ['を']],
277
+ pure: true,
278
+ fn: function (a: any, b: any) {
279
+ return a - b
280
+ }
281
+ },
282
+ '掛': { // @AにBを掛ける // @かける
283
+ type: 'func',
284
+ josi: [['に', 'と'], ['を']],
285
+ pure: true,
286
+ fn: function (a: any, b: any) {
287
+ return a * b
288
+ }
289
+ },
290
+ '倍': { // @AのB倍を求める // @ばい
291
+ type: 'func',
292
+ josi: [['の'], ['']],
293
+ pure: true,
294
+ fn: function (a: any, b: any) {
295
+ return a * b
296
+ }
297
+ },
298
+ '割': { // @AをBで割る // @わる
299
+ type: 'func',
300
+ josi: [['を'], ['で']],
301
+ pure: true,
302
+ fn: function (a: any, b: any) {
303
+ return a / b
304
+ }
305
+ },
306
+ '割余': { // @AをBで割った余りを求める // @わったあまり
307
+ type: 'func',
308
+ josi: [['を'], ['で']],
309
+ pure: true,
310
+ fn: function (a: any, b: any) {
311
+ return a % b
312
+ }
313
+ },
314
+ '偶数': { // @Aが偶数なら真を返す // @ぐうすう
315
+ type: 'func',
316
+ josi: [['が']],
317
+ pure: true,
318
+ fn: function (a: any) {
319
+ return (parseInt(a) % 2 === 0)
320
+ }
321
+ },
322
+ '奇数': { // @Aが奇数なら真を返す // @きすう
323
+ type: 'func',
324
+ josi: [['が']],
325
+ pure: true,
326
+ fn: function (a: any) {
327
+ return (parseInt(a) % 2 === 1)
328
+ }
329
+ },
330
+ '二乗': { // @Aを二乗する // @にじょう
331
+ type: 'func',
332
+ josi: [['の', 'を']],
333
+ pure: true,
334
+ fn: function (a: any) {
335
+ return a * a
336
+ }
337
+ },
338
+ 'べき乗': { // @AのB乗を求める // @べきじょう
339
+ type: 'func',
340
+ josi: [['の'], ['の']],
341
+ pure: true,
342
+ fn: function (a: any, b: any) {
343
+ return Math.pow(a, b)
344
+ }
345
+ },
346
+ '以上': { // @AがB以上か // @いじょう
347
+ type: 'func',
348
+ josi: [['が'], ['']],
349
+ pure: true,
350
+ fn: function (a: any, b: any) {
351
+ return a >= b
352
+ }
353
+ },
354
+ '以下': { // @AがB以下か // @いか
355
+ type: 'func',
356
+ josi: [['が'], ['']],
357
+ pure: true,
358
+ fn: function (a: any, b: any) {
359
+ return a <= b
360
+ }
361
+ },
362
+ '未満': { // @AがB未満か // @みまん
363
+ type: 'func',
364
+ josi: [['が'], ['']],
365
+ pure: true,
366
+ fn: function (a: any, b: any) {
367
+ return a < b
368
+ }
369
+ },
370
+ '超': { // @AがB超か // @ちょう
371
+ type: 'func',
372
+ josi: [['が'], ['']],
373
+ pure: true,
374
+ fn: function (a: any, b: any) {
375
+ return a > b
376
+ }
377
+ },
378
+ '等': { // @AがBと等しいか // @ひとしい
379
+ type: 'func',
380
+ josi: [['が'], ['と']],
381
+ pure: true,
382
+ fn: function (a: any, b: any) {
383
+ return a === b
384
+ }
385
+ },
386
+ '等無': { // @AがBと等しくないか // @ひとしくない
387
+ type: 'func',
388
+ josi: [['が'], ['と']],
389
+ pure: true,
390
+ fn: function (a: any, b: any) {
391
+ return a !== b
392
+ }
393
+ },
394
+ '一致': { // @AがBと一致するか(配列や辞書も比較可能) // @いっち
395
+ type: 'func',
396
+ josi: [['が'], ['と']],
397
+ pure: true,
398
+ fn: function (a: any, b: any) {
399
+ // オブジェクトの場合、JSONに変換して比較
400
+ if (typeof (a) === 'object') {
401
+ const jsonA = JSON.stringify(a)
402
+ const jsonB = JSON.stringify(b)
403
+ return jsonA === jsonB
404
+ }
405
+ return a === b
406
+ }
407
+ },
408
+ '不一致': { // @AがBと不一致か(配列や辞書も比較可能) // @ふいっち
409
+ type: 'func',
410
+ josi: [['が'], ['と']],
411
+ pure: true,
412
+ fn: function (a: any, b: any) {
413
+ // オブジェクトの場合、JSONに変換して比較
414
+ if (typeof (a) === 'object') {
415
+ const jsonA = JSON.stringify(a)
416
+ const jsonB = JSON.stringify(b)
417
+ return jsonA !== jsonB
418
+ }
419
+ return a !== b
420
+ }
421
+ },
422
+ '範囲内': { // @VがAからBの範囲内か // @はんいない
423
+ type: 'func',
424
+ josi: [['が'], ['から'], ['の']],
425
+ pure: true,
426
+ fn: function (v: any, a: any, b: any) {
427
+ return (a <= v) && (v <= b)
428
+ }
429
+ },
430
+ '連続加算': { // @A1+A2+A3...にBを足す // @れんぞくかさん
431
+ type: 'func',
432
+ josi: [['を'], ['に', 'と']],
433
+ isVariableJosi: true,
434
+ pure: true,
435
+ fn: function (b: any, ...a: any) {
436
+ a.pop() // 必ず末尾に sys があるので、末尾のシステム変数を除外
437
+ a.push(b)
438
+ return a.reduce((p: any, c: any) => p + c)
439
+ }
440
+ },
441
+
442
+ // @敬語
443
+ 'ください': { // @敬語対応のため // @ください
444
+ type: 'func',
445
+ josi: [],
446
+ pure: true,
447
+ fn: function (sys: any) {
448
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
449
+ sys.__reisetu++
450
+ },
451
+ return_none: true
452
+ },
453
+ 'お願': { // @ソースコードを読む人を気持ちよくする // @おねがいします
454
+ type: 'func',
455
+ josi: [],
456
+ pure: true,
457
+ fn: function (sys: any) {
458
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
459
+ sys.__reisetu++
460
+ },
461
+ return_none: true
462
+ },
463
+ 'です': { // @ソースコードを読む人を気持ちよくする // @です
464
+ type: 'func',
465
+ josi: [],
466
+ pure: true,
467
+ fn: function (sys: any) {
468
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
469
+ sys.__reisetu++
470
+ },
471
+ return_none: true
472
+ },
473
+ '拝啓': { // @ソースコードを読む人を気持ちよくする // @はいけい
474
+ type: 'func',
475
+ josi: [],
476
+ pure: true,
477
+ fn: function (sys: any) {
478
+ sys.__reisetu = 0
479
+ },
480
+ return_none: true
481
+ },
482
+ '敬具': { // @ソースコードを読む人を気持ちよくする // @けいぐ
483
+ type: 'func',
484
+ josi: [],
485
+ pure: true,
486
+ fn: function (sys: any) {
487
+ sys.__reisetu += 100 // bonus point
488
+ },
489
+ return_none: true
490
+ },
491
+ '礼節レベル取得': { // @(お遊び)敬語を何度使ったか返す // @おねがいします
492
+ type: 'func',
493
+ josi: [],
494
+ pure: true,
495
+ fn: function (sys: any) {
496
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
497
+ return sys.__reisetu
498
+ }
499
+ },
500
+
501
+ // @特殊命令
502
+ 'JS実行': { // @JavaScriptのコードSRCを実行する(変数sysでなでしこシステムを参照できる) // @JSじっこう
503
+ type: 'func',
504
+ josi: [['を', 'で']],
505
+ pure: true,
506
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
507
+ fn: function (src: string, sys: any) {
508
+ // [メモ] ↑のsys は eval の中でも有効なので消さない!!
509
+ // https://github.com/kujirahand/nadesiko3/issues/1237
510
+ return eval(src) // eslint-disable-line
511
+ }
512
+ },
513
+ 'JSオブジェクト取得': { // @なでしこで定義した関数や変数nameのJavaScriptオブジェクトを取得する // @JSおぶじぇくとしゅとく
514
+ type: 'func',
515
+ josi: [['の']],
516
+ pure: false,
517
+ fn: function (name: string, sys: any) {
518
+ return sys.__findVar(name, null)
519
+ }
520
+ },
521
+ 'JS関数実行': { // @JavaScriptの関数NAMEを引数ARGS(配列)で実行する // @JSかんすうしゅとく
522
+ type: 'func',
523
+ josi: [['を'], ['で']],
524
+ fn: function (name: any, args: any) {
525
+ // nameが文字列ならevalして関数を得る
526
+ // eslint-disable-next-line no-eval
527
+ if (typeof name === 'string') { name = eval(name) }
528
+ if (typeof name !== 'function') { throw new Error('JS関数取得で実行できません。') }
529
+
530
+ // argsがArrayでなければArrayに変換する
531
+ if (!(args instanceof Array)) { args = [args] }
532
+
533
+ // 実行
534
+ return name.apply(null, args)
535
+ }
536
+ },
537
+ 'JSメソッド実行': { // @JavaScriptのオブジェクトOBJのメソッドMを引数ARGS(配列)で実行する // @JSめそっどじっこう
538
+ type: 'func',
539
+ josi: [['の'], ['を'], ['で']],
540
+ fn: function (obj: any, m: any, args: any) {
541
+ // objが文字列ならevalして関数を得る
542
+ // eslint-disable-next-line no-eval
543
+ if (typeof obj === 'string') { obj = eval(obj) }
544
+ if (typeof obj !== 'object') { throw new Error('JSオブジェクトを取得できませんでした。') }
545
+
546
+ // method を求める
547
+ if (typeof m !== 'function') {
548
+ m = obj[m]
549
+ }
550
+
551
+ // argsがArrayでなければArrayに変換する
552
+ if (!(args instanceof Array)) { args = [args] }
553
+
554
+ // 実行
555
+ return m.apply(obj, args)
556
+ }
557
+ },
558
+
559
+ 'ナデシコ': { // @なでしこのコードCODEを実行する // @なでしこする
560
+ type: 'func',
561
+ josi: [['を', 'で']],
562
+ pure: false,
563
+ fn: function (code: string, sys: any) {
564
+ if (sys.__genMode === '非同期モード') {
565
+ throw new Error('非同期モードでは「ナデシコ」は利用できません。')
566
+ }
567
+ sys.__varslist[0]['表示ログ'] = ''
568
+ sys.__self.runEx(code, sys.__modName, { resetEnv: false, resetLog: true })
569
+ const out = sys.__varslist[0]['表示ログ'] + ''
570
+ if (out) {
571
+ sys.logger.trace(out)
572
+ }
573
+ return out
574
+ }
575
+ },
576
+ 'ナデシコ続': { // @なでしこのコードCODEを実行する // @なでしこつづける
577
+ type: 'func',
578
+ josi: [['を', 'で']],
579
+ fn: function (code: string, sys: any) {
580
+ if (sys.__genMode === '非同期モード') {
581
+ throw new Error('非同期モードでは「ナデシコ続」は利用できません。')
582
+ }
583
+ sys.__self.runEx(code, sys.__modName, { resetEnv: false, resetLog: false })
584
+ const out = sys.__varslist[0]['表示ログ'] + ''
585
+ if (out) {
586
+ sys.logger.trace(out)
587
+ }
588
+ return out
589
+ }
590
+ },
591
+ '実行': { // @ 無名関数(あるいは、文字列で関数名を指定)Fを実行する(Fが関数でなければ無視する) // @じっこう
592
+ type: 'func',
593
+ josi: [['を', 'に', 'で']],
594
+ pure: false,
595
+ fn: function (f: any, sys: any) {
596
+ // #938 の規則に従って処理
597
+ // 引数が関数なら実行
598
+ if (typeof f === 'function') { return f(sys) }
599
+ // 文字列なら関数に変換できるか判定して実行
600
+ if (typeof f === 'string') {
601
+ const tf = sys.__findFunc(f, '実行')
602
+ if (typeof tf === 'function') {
603
+ return tf(sys)
604
+ }
605
+ }
606
+ // それ以外ならそのまま値を返す
607
+ return f
608
+ }
609
+ },
610
+ '実行時間計測': { // @ 関数Fを実行して要した時間をミリ秒で返す // @じっこうじかんけいそく
611
+ type: 'func',
612
+ josi: [['の']],
613
+ pure: false,
614
+ fn: function (f: any, sys: any) {
615
+ if (typeof f === 'string') { f = sys.__findFunc(f, '実行時間計測') }
616
+ //
617
+ if (performance && performance.now) {
618
+ const t1 = performance.now()
619
+ f(sys)
620
+ const t2 = performance.now()
621
+ return (t2 - t1)
622
+ } else {
623
+ const t1 = Date.now()
624
+ f(sys)
625
+ const t2 = Date.now()
626
+ return (t2 - t1)
627
+ }
628
+ }
629
+ },
630
+
631
+ // @型変換
632
+ '変数型確認': { // @変数Vの型を返す // @へんすうかたかくにん
633
+ type: 'func',
634
+ josi: [['の']],
635
+ pure: true,
636
+ fn: function (v: any) {
637
+ return (typeof v)
638
+ }
639
+ },
640
+ 'TYPEOF': { // @変数Vの型を返す // @TYPEOF
641
+ type: 'func',
642
+ josi: [['の']],
643
+ pure: true,
644
+ fn: function (v: any) {
645
+ return (typeof v)
646
+ }
647
+ },
648
+ '文字列変換': { // @値Vを文字列に変換 // @もじれつへんかん
649
+ type: 'func',
650
+ josi: [['を']],
651
+ pure: true,
652
+ fn: function (v: any): string {
653
+ return String(v)
654
+ }
655
+ },
656
+ 'TOSTR': { // @値Vを文字列に変換 // @TOSTR
657
+ type: 'func',
658
+ josi: [['を']],
659
+ pure: true,
660
+ fn: function (v: any): string {
661
+ return String(v)
662
+ }
663
+ },
664
+ '整数変換': { // @値Vを整数に変換 // @せいすうへんかん
665
+ type: 'func',
666
+ josi: [['を']],
667
+ pure: true,
668
+ fn: function (v: any): number {
669
+ return parseInt(v)
670
+ }
671
+ },
672
+ 'TOINT': { // @値Vを整数に変換 // @TOINT
673
+ type: 'func',
674
+ josi: [['を']],
675
+ pure: true,
676
+ fn: function (v: any): number {
677
+ return parseInt(v)
678
+ }
679
+ },
680
+ '実数変換': { // @値Vを実数に変換 // @じっすうへんかん
681
+ type: 'func',
682
+ josi: [['を']],
683
+ pure: true,
684
+ fn: function (v: any): number {
685
+ return parseFloat(v)
686
+ }
687
+ },
688
+ 'TOFLOAT': { // @値Vを実数に変換 // @TOFLOAT
689
+ type: 'func',
690
+ josi: [['を']],
691
+ pure: true,
692
+ fn: function (v: any): number {
693
+ return parseFloat(v)
694
+ }
695
+ },
696
+ 'INT': { // @値Vを整数に変換 // @INT
697
+ type: 'func',
698
+ josi: [['の']],
699
+ pure: true,
700
+ fn: function (v: any): number {
701
+ return parseInt(v)
702
+ }
703
+ },
704
+ 'FLOAT': { // @値Vを実数に変換 // @FLOAT
705
+ type: 'func',
706
+ josi: [['の']],
707
+ pure: true,
708
+ fn: function (v: any): number {
709
+ return parseFloat(v)
710
+ }
711
+ },
712
+ 'NAN判定': { // @値VがNaNかどうかを判定(命令『非数判定』を使う事を推奨) // @NANはんてい
713
+ type: 'func',
714
+ josi: [['を']],
715
+ pure: true,
716
+ fn: function (v: any): boolean {
717
+ return isNaN(v)
718
+ }
719
+ },
720
+ '非数判定': { // @値Vが非数かどうかを判定(NAN判定より堅牢) // @ひすうはんてい
721
+ type: 'func',
722
+ josi: [['を']],
723
+ pure: true,
724
+ fn: function (v: any): boolean {
725
+ // https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
726
+ return Number.isNaN(v)
727
+ }
728
+ },
729
+ 'HEX': { // @値Vを16進数に変換 // @HEX
730
+ type: 'func',
731
+ josi: [['の']],
732
+ pure: true,
733
+ fn: function (a: any): string {
734
+ return parseInt(a).toString(16)
735
+ }
736
+ },
737
+ '進数変換': { // @値VをN進数に変換 // @しんすうへんかん
738
+ type: 'func',
739
+ josi: [['を', 'の'], ['']],
740
+ pure: true,
741
+ fn: function (v: any, n: number): string {
742
+ return parseInt(v).toString(n)
743
+ }
744
+ },
745
+ '二進': { // @値Vを2進数に変換 // @にしん
746
+ type: 'func',
747
+ josi: [['を', 'の', 'から']],
748
+ pure: true,
749
+ fn: function (v: any): string {
750
+ return parseInt(v).toString(2)
751
+ }
752
+ },
753
+ '二進表示': { // @値Vを2進数に変換して表示 // @にしんひょうじ
754
+ type: 'func',
755
+ josi: [['を', 'の', 'から']],
756
+ pure: true,
757
+ fn: function (v: any, sys: any) {
758
+ const s = parseInt(v).toString(2)
759
+ sys.__exec('表示', [s, sys])
760
+ }
761
+ },
762
+ 'RGB': { // @HTML用のカラーコードを返すRGB(R,G,B)で各値は0-255 // @RGB
763
+ type: 'func',
764
+ josi: [['と'], ['の'], ['で']],
765
+ pure: true,
766
+ fn: function (r: any, g: any, b: any): string {
767
+ const z2 = (v: any): string => {
768
+ const v2: string = '00' + (parseInt('' + v).toString(16))
769
+ return v2.substring(v2.length - 2, v2.length)
770
+ }
771
+ return '#' + z2(r) + z2(g) + z2(b)
772
+ }
773
+ },
774
+
775
+ // @論理演算
776
+ '論理OR': { // @(ビット演算で)AとBの論理和を返す(v1非互換)。 // @ろんりOR
777
+ type: 'func',
778
+ josi: [['と'], ['の']],
779
+ pure: true,
780
+ fn: function (a: any, b: any) {
781
+ return (a || b)
782
+ }
783
+ },
784
+ '論理AND': { // @(ビット演算で)AとBの論理積を返す(v1非互換)。日本語の「AかつB」に相当する // @ろんりAND
785
+ type: 'func',
786
+ josi: [['と'], ['の']],
787
+ pure: true,
788
+ fn: function (a: any, b: any) {
789
+ return (a && b)
790
+ }
791
+ },
792
+ '論理NOT': { // @値Vが0ならば1、それ以外ならば0を返す(v1非互換) // @ろんりNOT
793
+ type: 'func',
794
+ josi: [['の']],
795
+ pure: true,
796
+ fn: function (v: any): number {
797
+ return (!v) ? 1 : 0
798
+ }
799
+ },
800
+
801
+ // @ビット演算
802
+ 'OR': { // @(ビット演算で)AとBの論理和を返す。 // @OR
803
+ type: 'func',
804
+ josi: [['と'], ['の']],
805
+ pure: true,
806
+ fn: function (a: any, b: any) {
807
+ return (a | b)
808
+ }
809
+ },
810
+ 'AND': { // @(ビット演算で)AとBの論理積を返す。日本語の「AかつB」に相当する // @AND
811
+ type: 'func',
812
+ josi: [['と'], ['の']],
813
+ pure: true,
814
+ fn: function (a: any, b: any) {
815
+ return (a & b)
816
+ }
817
+ },
818
+ 'XOR': { // @(ビット演算で)AとBの排他的論理和を返す。// @XOR
819
+ type: 'func',
820
+ josi: [['と'], ['の']],
821
+ pure: true,
822
+ fn: function (a: any, b: any) {
823
+ return (a ^ b)
824
+ }
825
+ },
826
+ 'NOT': { // @(ビット演算で)vの各ビットを反転して返す。// @NOT
827
+ type: 'func',
828
+ josi: [['の']],
829
+ pure: true,
830
+ fn: function (v: any) {
831
+ return (~v)
832
+ }
833
+ },
834
+ 'SHIFT_L': { // @VをAビット左へシフトして返す // @SHIFT_L
835
+ type: 'func',
836
+ josi: [['を'], ['で']],
837
+ pure: true,
838
+ fn: function (a: any, b: any) {
839
+ return (a << b)
840
+ }
841
+ },
842
+ 'SHIFT_R': { // @VをAビット右へシフトして返す(符号を維持する) // @SHIFT_R
843
+ type: 'func',
844
+ josi: [['を'], ['で']],
845
+ pure: true,
846
+ fn: function (a: any, b: any) {
847
+ return (a >> b)
848
+ }
849
+ },
850
+ 'SHIFT_UR': { // @VをAビット右へシフトして返す(符号を維持しない、0で埋める) // @SHIFT_UR
851
+ type: 'func',
852
+ josi: [['を'], ['で']],
853
+ pure: true,
854
+ fn: function (a: any, b: any) {
855
+ return (a >>> b)
856
+ }
857
+ },
858
+
859
+ // @文字列処理
860
+ '文字数': { // @文字列Vの文字数を返す // @もじすう
861
+ type: 'func',
862
+ josi: [['の']],
863
+ pure: true,
864
+ fn: function (v: any) {
865
+ if (!Array.from) { return String(v).length }
866
+ return Array.from(v).length
867
+ }
868
+ },
869
+ '何文字目': { // @文字列SでAが何文字目にあるか調べて返す // @なんもじめ
870
+ type: 'func',
871
+ josi: [['で', 'の'], ['が']],
872
+ pure: true,
873
+ fn: function (s: string, a: string): number {
874
+ return String(s).indexOf(a) + 1
875
+ }
876
+ },
877
+ 'CHR': { // @文字コードから文字を返す // @CHR
878
+ type: 'func',
879
+ josi: [['の']],
880
+ pure: true,
881
+ fn: function (v: any) {
882
+ if (!String.fromCodePoint) { return String.fromCharCode(v) }
883
+ return String.fromCodePoint(v)
884
+ }
885
+ },
886
+ 'ASC': { // @文字列Vの最初の文字の文字コードを返す // @ASC
887
+ type: 'func',
888
+ josi: [['の']],
889
+ pure: true,
890
+ fn: function (v: any) {
891
+ if (!String.prototype.codePointAt) { return String(v).charCodeAt(0) }
892
+ return String(v).codePointAt(0)
893
+ }
894
+ },
895
+ '文字挿入': { // @文字列SのI文字目に文字列Aを挿入する // @もじそうにゅう
896
+ type: 'func',
897
+ josi: [['で', 'の'], ['に', 'へ'], ['を']],
898
+ pure: true,
899
+ fn: function (s: string, i: number, a: string): string {
900
+ if (i <= 0) { i = 1 }
901
+ const ss = String(s)
902
+ const mae = ss.substring(0, i - 1)
903
+ const usi = ss.substring(i - 1)
904
+ return mae + a + usi
905
+ }
906
+ },
907
+ '文字検索': { // @文字列SでA文字目から文字列Bを検索。見つからなければ0を返す。(類似命令に『何文字目』がある)(v1非互換) // @もじけんさく
908
+ type: 'func',
909
+ josi: [['で', 'の'], ['から'], ['を']],
910
+ pure: true,
911
+ fn: function (s: string, a: number, b: string): number {
912
+ let str = String(s)
913
+ str = str.substring(a)
914
+ const res: number = str.indexOf(b)
915
+ if (res === -1) { return 0 }
916
+ return res + 1 + a
917
+ }
918
+ },
919
+ '追加': { // @文字列または配列SにAを追加して返す(v1非互換) // @ついか
920
+ type: 'func',
921
+ josi: [['で', 'に', 'へ'], ['を']],
922
+ pure: true,
923
+ fn: function (s: any, a: any): any {
924
+ if (s instanceof Array) {
925
+ s.push(a)
926
+ return s
927
+ }
928
+ return String(s) + String(a)
929
+ }
930
+ },
931
+ '一行追加': { // @文字列または配列SにAと改行を追加して返す(v1非互換) // @いちぎょうついか
932
+ type: 'func',
933
+ josi: [['で', 'に', 'へ'], ['を']],
934
+ pure: true,
935
+ fn: function (s: any, a: any): any {
936
+ if (s instanceof Array) {
937
+ s.push(a)
938
+ return s
939
+ }
940
+ return String(s) + String(a) + '\n'
941
+ }
942
+ },
943
+ '文字列分解': { // @文字列Vを一文字ずつに分解して返す // @もじれつぶんかい
944
+ type: 'func',
945
+ josi: [['を', 'の', 'で']],
946
+ pure: true,
947
+ fn: function (v: any) {
948
+ if (!Array.from) { return String(v).split('') }
949
+ return Array.from(v)
950
+ }
951
+ },
952
+ 'リフレイン': { // @文字列VをCNT回繰り返す(v1非互換) // @りふれいん
953
+ type: 'func',
954
+ josi: [['を', 'の'], ['で']],
955
+ pure: true,
956
+ fn: function (v: any, cnt: number): string {
957
+ let s = ''
958
+ for (let i = 0; i < cnt; i++) { s += String(v) }
959
+ return s
960
+ }
961
+ },
962
+ '出現回数': { // @文字列SにAが何回出現するか数える // @しゅつげんかいすう
963
+ type: 'func',
964
+ josi: [['で'], ['の']],
965
+ pure: true,
966
+ fn: function (s: string, a: string) {
967
+ s = '' + s
968
+ a = '' + a
969
+ return s.split(a).length - 1
970
+ }
971
+ },
972
+ 'MID': { // @文字列SのA文字目からCNT文字を抽出する // @MID
973
+ type: 'func',
974
+ josi: [['で', 'の'], ['から'], ['を']],
975
+ pure: true,
976
+ fn: function (s: any, a: any, cnt: number) {
977
+ cnt = cnt || 1
978
+ return (String(s).substring(a - 1, a + cnt - 1))
979
+ }
980
+ },
981
+ '文字抜出': { // @文字列SのA文字目からCNT文字を抽出する // @もじぬきだす
982
+ type: 'func',
983
+ josi: [['で', 'の'], ['から'], ['を', '']],
984
+ pure: true,
985
+ fn: function (s: any, a: any, cnt: number) {
986
+ cnt = cnt || 1
987
+ return (String(s).substring(a - 1, a + cnt - 1))
988
+ }
989
+ },
990
+ 'LEFT': { // @文字列Sの左端からCNT文字を抽出する // @LEFT
991
+ type: 'func',
992
+ josi: [['の', 'で'], ['だけ']],
993
+ pure: true,
994
+ fn: function (s: string, cnt: number): string {
995
+ return (String(s).substring(0, cnt))
996
+ }
997
+ },
998
+ '文字左部分': { // @文字列Sの左端からCNT文字を抽出する // @もじひだりぶぶん
999
+ type: 'func',
1000
+ josi: [['の', 'で'], ['だけ', '']],
1001
+ pure: true,
1002
+ fn: function (s: string, cnt: number): string {
1003
+ return (String(s).substring(0, cnt))
1004
+ }
1005
+ },
1006
+ 'RIGHT': { // @文字列Sの右端からCNT文字を抽出する // @RIGHT
1007
+ type: 'func',
1008
+ josi: [['の', 'で'], ['だけ']],
1009
+ pure: true,
1010
+ fn: function (s: string, cnt: number): string {
1011
+ s = '' + s
1012
+ return (s.substring(s.length - cnt, s.length))
1013
+ }
1014
+ },
1015
+ '文字右部分': { // @文字列Sの右端からCNT文字を抽出する // @もじみぎぶぶん
1016
+ type: 'func',
1017
+ josi: [['の', 'で'], ['だけ', '']],
1018
+ pure: true,
1019
+ fn: function (s: string, cnt: number): string {
1020
+ s = '' + s
1021
+ return (s.substring(s.length - cnt, s.length))
1022
+ }
1023
+ },
1024
+ '区切': { // @文字列Sを区切り文字Aで区切って配列で返す // @くぎる
1025
+ type: 'func',
1026
+ josi: [['の', 'を'], ['で']],
1027
+ pure: true,
1028
+ fn: function (s: any, a: any) {
1029
+ return ('' + s).split('' + a)
1030
+ }
1031
+ },
1032
+ '文字列分割': { // @文字列Sを区切り文字Aで分割して配列で返す // @もじれつぶんかつ
1033
+ type: 'func',
1034
+ josi: [['を'], ['で']],
1035
+ pure: true,
1036
+ fn: function (s: any, a: any) {
1037
+ s = '' + s
1038
+ a = '' + a
1039
+ const i = s.indexOf(a)
1040
+ if (i < 0) {
1041
+ return [s]
1042
+ }
1043
+ return [s.substring(0, i), s.substring(i + a.length)]
1044
+ }
1045
+ },
1046
+ '切取': { // @文字列Sから文字列Aまでの部分を抽出する。切り取った残りは特殊変数『対象』に代入される。(v1非互換) // @きりとる
1047
+ type: 'func',
1048
+ josi: [['から', 'の'], ['まで', 'を']],
1049
+ pure: true,
1050
+ fn: function (s: any, a: any, sys: any) {
1051
+ s = String(s)
1052
+ const i = s.indexOf(a)
1053
+ if (i < 0) {
1054
+ sys.__v0['対象'] = ''
1055
+ return s
1056
+ }
1057
+ sys.__v0['対象'] = s.substring(i + a.length)
1058
+ return s.substring(0, i)
1059
+ }
1060
+ },
1061
+ '文字削除': { // @文字列SのA文字目からB文字分を削除して返す // @もじさくじょ
1062
+ type: 'func',
1063
+ josi: [['の'], ['から'], ['だけ', 'を', '']],
1064
+ pure: true,
1065
+ fn: function (s: string, a: number, b: number): string {
1066
+ s = '' + s
1067
+ const mae = s.substring(0, a - 1)
1068
+ const usi = s.substring((a - 1 + b))
1069
+ return mae + usi
1070
+ }
1071
+ },
1072
+
1073
+ // @置換・トリム
1074
+ '置換': { // @文字列Sのうち文字列AをBに全部置換して返す // @ちかん
1075
+ type: 'func',
1076
+ josi: [['の', 'で'], ['を', 'から'], ['に', 'へ']],
1077
+ pure: true,
1078
+ fn: function (s: string, a: string, b: string) {
1079
+ return String(s).split(a).join(b)
1080
+ }
1081
+ },
1082
+ '単置換': { // @文字列Sのうち、最初に出現するAだけをBに置換して返す // @たんちかん
1083
+ type: 'func',
1084
+ josi: [['の', 'で'], ['を'], ['に', 'へ']],
1085
+ pure: true,
1086
+ fn: function (s: string, a: string, b: string) {
1087
+ // replaceは最初の一度だけ置換する
1088
+ return String(s).replace(a, b)
1089
+ }
1090
+ },
1091
+ 'トリム': { // @文字列Sの前後にある空白を削除する // @とりむ
1092
+ type: 'func',
1093
+ josi: [['の', 'を']],
1094
+ pure: true,
1095
+ fn: function (s: string): string {
1096
+ s = String(s).replace(/^\s+/, '').replace(/\s+$/, '')
1097
+ return s
1098
+ }
1099
+ },
1100
+ '空白除去': { // @文字列Sの前後にある空白を削除する // @くうはくじょきょ
1101
+ type: 'func',
1102
+ josi: [['の', 'を']],
1103
+ pure: true,
1104
+ fn: function (s: string): string {
1105
+ s = String(s).replace(/^\s+/, '').replace(/\s+$/, '')
1106
+ return s
1107
+ }
1108
+ },
1109
+
1110
+ // @文字変換
1111
+ '大文字変換': { // @アルファベットの文字列Sを大文字に変換 // @おおもじへんかん
1112
+ type: 'func',
1113
+ josi: [['の', 'を']],
1114
+ pure: true,
1115
+ fn: function (s: string): string {
1116
+ return String(s).toUpperCase()
1117
+ }
1118
+ },
1119
+ '小文字変換': { // @アルファベットの文字列Sを小文字に変換 // @こもじへんかん
1120
+ type: 'func',
1121
+ josi: [['の', 'を']],
1122
+ pure: true,
1123
+ fn: function (s: string): string {
1124
+ return String(s).toLowerCase()
1125
+ }
1126
+ },
1127
+ '平仮名変換': { // @文字列Sのカタカナをひらがなに変換 // @ひらがなへんかん
1128
+ type: 'func',
1129
+ josi: [['の', 'を']],
1130
+ pure: true,
1131
+ fn: function (s: string): string {
1132
+ const kanaToHira = (str: string) => {
1133
+ return String(str).replace(/[\u30a1-\u30f6]/g, function (m) {
1134
+ const chr = m.charCodeAt(0) - 0x60
1135
+ return String.fromCharCode(chr)
1136
+ })
1137
+ }
1138
+ return kanaToHira('' + s)
1139
+ }
1140
+ },
1141
+ 'カタカナ変換': { // @文字列Sのひらがなをカタカナに変換 // @かたかなへんかん
1142
+ type: 'func',
1143
+ josi: [['の', 'を']],
1144
+ pure: true,
1145
+ fn: function (s: string): string {
1146
+ const hiraToKana = (str: string) => {
1147
+ return String(str).replace(/[\u3041-\u3096]/g, function (m) {
1148
+ const chr = m.charCodeAt(0) + 0x60
1149
+ return String.fromCharCode(chr)
1150
+ })
1151
+ }
1152
+ return hiraToKana('' + s)
1153
+ }
1154
+ },
1155
+ '英数全角変換': { // @文字列Sの半角英数文字を全角に変換 // @えいすうぜんかくへんかん
1156
+ type: 'func',
1157
+ josi: [['の', 'を']],
1158
+ pure: true,
1159
+ fn: function (s: string): string {
1160
+ return String(s).replace(/[A-Za-z0-9]/g, function (v: any) {
1161
+ return String.fromCharCode(v.charCodeAt(0) + 0xFEE0)
1162
+ })
1163
+ }
1164
+ },
1165
+ '英数半角変換': { // @文字列Sの全角英数文字を半角に変換 // @えいすうはんかくへんかん
1166
+ type: 'func',
1167
+ josi: [['の', 'を']],
1168
+ pure: true,
1169
+ fn: function (s: string): string {
1170
+ return String(s).replace(/[A-Za-z0-9]/g, function (v: any) {
1171
+ return String.fromCharCode(v.charCodeAt(0) - 0xFEE0)
1172
+ })
1173
+ }
1174
+ },
1175
+ '英数記号全角変換': { // @文字列Sの半角英数記号文字を全角に変換 // @えいすうきごうぜんかくへんかん
1176
+ type: 'func',
1177
+ josi: [['の', 'を']],
1178
+ pure: true,
1179
+ fn: function (s: string): string {
1180
+ return String(s).replace(/[\x20-\x7F]/g, function (v: any) {
1181
+ return String.fromCharCode(v.charCodeAt(0) + 0xFEE0)
1182
+ })
1183
+ }
1184
+ },
1185
+ '英数記号半角変換': { // @文字列Sの記号文字を半角に変換 // @えいすうきごうはんかくへんかん
1186
+ type: 'func',
1187
+ josi: [['の', 'を']],
1188
+ pure: true,
1189
+ fn: function (s: string): string {
1190
+ return String(s).replace(/[\uFF00-\uFF5F]/g, function (v: any) {
1191
+ return String.fromCharCode(v.charCodeAt(0) - 0xFEE0)
1192
+ })
1193
+ }
1194
+ },
1195
+ 'カタカナ全角変換': { // @文字列Sの半角カタカナを全角に変換 // @かたかなぜんかくへんかん
1196
+ type: 'func',
1197
+ josi: [['の', 'を']],
1198
+ pure: true,
1199
+ fn: function (s: string, sys: any) {
1200
+ // 半角カタカナ
1201
+ const zen1 = sys.__v0['全角カナ一覧']
1202
+ const han1 = sys.__v0['半角カナ一覧']
1203
+ const zen2 = sys.__v0['全角カナ濁音一覧']
1204
+ const han2 = sys.__v0['半角カナ濁音一覧']
1205
+ let str = ''
1206
+ let i = 0
1207
+ while (i < s.length) {
1208
+ // 濁点の変換
1209
+ const c2 = s.substring(i, i + 2)
1210
+ const n2 = han2.indexOf(c2)
1211
+ if (n2 >= 0) {
1212
+ str += zen2.charAt(n2 / 2)
1213
+ i += 2
1214
+ continue
1215
+ }
1216
+ // 濁点以外の変換
1217
+ const c = s.charAt(i)
1218
+ const n = han1.indexOf(c)
1219
+ if (n >= 0) {
1220
+ str += zen1.charAt(n)
1221
+ i++
1222
+ continue
1223
+ }
1224
+ str += c
1225
+ i++
1226
+ }
1227
+ return str
1228
+ }
1229
+ },
1230
+ 'カタカナ半角変換': { // @文字列Sの全角カタカナを半角に変換 // @かたかなはんかくへんかん
1231
+ type: 'func',
1232
+ josi: [['の', 'を']],
1233
+ pure: true,
1234
+ fn: function (s: string, sys: any) {
1235
+ // 半角カタカナ
1236
+ const zen1 = sys.__v0['全角カナ一覧']
1237
+ const han1 = sys.__v0['半角カナ一覧']
1238
+ const zen2 = sys.__v0['全角カナ濁音一覧']
1239
+ const han2 = sys.__v0['半角カナ濁音一覧']
1240
+ return s.split('').map((c) => {
1241
+ const i = zen1.indexOf(c)
1242
+ if (i >= 0) {
1243
+ return han1.charAt(i)
1244
+ }
1245
+ const j = zen2.indexOf(c)
1246
+ if (j >= 0) {
1247
+ return han2.substring(j * 2, j * 2 + 2)
1248
+ }
1249
+ return c
1250
+ }).join('')
1251
+ }
1252
+ },
1253
+ '全角変換': { // @文字列Sの半角文字を全角に変換 // @ぜんかくへんかん
1254
+ type: 'func',
1255
+ josi: [['の', 'を']],
1256
+ pure: false,
1257
+ fn: function (s: string, sys: any) {
1258
+ let result = s
1259
+ result = sys.__exec('カタカナ全角変換', [result, sys])
1260
+ result = sys.__exec('英数記号全角変換', [result, sys])
1261
+ return result
1262
+ }
1263
+ },
1264
+ '半角変換': { // @文字列Sの全角文字を半角に変換 // @はんかくへんかん
1265
+ type: 'func',
1266
+ josi: [['の', 'を']],
1267
+ pure: false,
1268
+ fn: function (s: string, sys: any) {
1269
+ let result = s
1270
+ result = sys.__exec('カタカナ半角変換', [result, sys])
1271
+ result = sys.__exec('英数記号半角変換', [result, sys])
1272
+ return result
1273
+ }
1274
+ },
1275
+ '全角カナ一覧': { type: 'const', value: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ、。ー「」' }, // @ぜんかくかないちらん
1276
+ '全角カナ濁音一覧': { type: 'const', value: 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ' }, // @ぜんかくかなだくおんいちらん
1277
+ '半角カナ一覧': { type: 'const', value: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ、。ー「」゙゚' }, // @はんかくかないちらん
1278
+ '半角カナ濁音一覧': { type: 'const', value: 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ' }, // @はんかくかなだくおんいちらん
1279
+
1280
+ // @JSON
1281
+ 'JSONエンコード': { // @オブジェクトVをJSON形式にエンコードして返す // @JSONえんこーど
1282
+ type: 'func',
1283
+ josi: [['を', 'の']],
1284
+ pure: true,
1285
+ fn: function (v: any) {
1286
+ return JSON.stringify(v)
1287
+ }
1288
+ },
1289
+ 'JSONエンコード整形': { // @オブジェクトVをJSON形式にエンコードして整形して返す // @JSONえんこーどせいけい
1290
+ type: 'func',
1291
+ josi: [['を', 'の']],
1292
+ pure: true,
1293
+ fn: function (v: any) {
1294
+ return JSON.stringify(v, null, 2)
1295
+ }
1296
+ },
1297
+ 'JSONデコード': { // @JSON文字列Sをオブジェクトにデコードして返す // @JSONでこーど
1298
+ type: 'func',
1299
+ josi: [['を', 'の', 'から']],
1300
+ pure: true,
1301
+ fn: function (s: string): string {
1302
+ return JSON.parse(s)
1303
+ }
1304
+ },
1305
+
1306
+ // @正規表現
1307
+ '正規表現マッチ': { // @文字列Aを正規表現パターンBでマッチして結果を返す(パターンBは「/pat/opt」の形式で指定。optにgの指定がなければ部分マッチが『抽出文字列』に入る) // @せいきひょうげんまっち
1308
+ type: 'func',
1309
+ josi: [['を', 'が'], ['で', 'に']],
1310
+ pure: true,
1311
+ fn: function (a: any, b: any, sys: any): string {
1312
+ let re
1313
+ const f = ('' + b).match(/^\/(.+)\/([a-zA-Z]*)$/)
1314
+ // パターンがない場合
1315
+ if (f === null) { re = new RegExp(b, 'g') } else { re = new RegExp(f[1], f[2]) }
1316
+
1317
+ const sa: any[] = sys.__varslist[0]['抽出文字列'] = []
1318
+ const m = String(a).match(re)
1319
+ let result: any = m
1320
+ if (re.global) {
1321
+ // no groups
1322
+ } else if (m) {
1323
+ // has group?
1324
+ if (m.length > 0) {
1325
+ result = m[0]
1326
+ for (let i = 1; i < m.length; i++) { sa[i - 1] = m[i] }
1327
+ }
1328
+ }
1329
+ return result
1330
+ }
1331
+ },
1332
+ '抽出文字列': { type: 'const', value: [] }, // @ちゅうしゅつもじれつ
1333
+ '正規表現置換': { // @文字列Sの正規表現パターンAをBに置換して結果を返す(パターンAは/pat/optで指定) // @せいきひょうげんちかん
1334
+ type: 'func',
1335
+ josi: [['の'], ['を', 'から'], ['で', 'に', 'へ']],
1336
+ pure: true,
1337
+ fn: function (s: string, a: string, b: string): string {
1338
+ let re
1339
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
1340
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
1341
+
1342
+ return String(s).replace(re, b)
1343
+ }
1344
+ },
1345
+ '正規表現区切': { // @文字列Sを正規表現パターンAで区切って配列で返す(パターンAは/pat/optで指定) // @せいきひょうげんくぎる
1346
+ type: 'func',
1347
+ josi: [['を'], ['で']],
1348
+ pure: true,
1349
+ fn: function (s: any, a: any) {
1350
+ let re
1351
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
1352
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
1353
+
1354
+ return String(s).split(re)
1355
+ }
1356
+ },
1357
+
1358
+ // @指定形式
1359
+ '通貨形式': { // @数値Vを三桁ごとにカンマで区切る // @つうかけいしき
1360
+ type: 'func',
1361
+ josi: [['を', 'の']],
1362
+ pure: true,
1363
+ fn: function (v: any) {
1364
+ return String(v).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
1365
+ }
1366
+ },
1367
+ 'ゼロ埋': { // @数値VをA桁の0で埋める // @ぜろうめ
1368
+ type: 'func',
1369
+ josi: [['を'], ['で']],
1370
+ pure: true,
1371
+ fn: function (v: any, a: any): string {
1372
+ v = String(v)
1373
+ let z = '0'
1374
+ for (let i = 0; i < a; i++) { z += '0' }
1375
+ a = parseInt(a)
1376
+ if (a < v.length) { a = v.length }
1377
+ const s = z + String(v)
1378
+ return s.substring(s.length - a, s.length)
1379
+ }
1380
+ },
1381
+ '空白埋': { // @文字列VをA桁の空白で埋める // @くうはくうめ
1382
+ type: 'func',
1383
+ josi: [['を'], ['で']],
1384
+ pure: true,
1385
+ fn: function (v: any, a: any): string {
1386
+ v = String(v)
1387
+ let z = ' '
1388
+ for (let i = 0; i < a; i++) { z += ' ' }
1389
+ a = parseInt(a)
1390
+ if (a < v.length) { a = v.length }
1391
+ const s = z + String(v)
1392
+ return s.substring(s.length - a, s.length)
1393
+ }
1394
+ },
1395
+
1396
+ // @文字種類
1397
+ 'かなか判定': { // @文字列Sの1文字目がひらがなか判定 // @かなかはんてい
1398
+ type: 'func',
1399
+ josi: [['を', 'の', 'が']],
1400
+ pure: true,
1401
+ fn: function (s: any): boolean {
1402
+ const c = String(s).charCodeAt(0)
1403
+ return (c >= 0x3041 && c <= 0x309F)
1404
+ }
1405
+ },
1406
+ 'カタカナ判定': { // @文字列Sの1文字目がカタカナか判定 // @かたかなかはんてい
1407
+ type: 'func',
1408
+ josi: [['を', 'の', 'が']],
1409
+ pure: true,
1410
+ fn: function (s: any): boolean {
1411
+ const c = String(s).charCodeAt(0)
1412
+ return (c >= 0x30A1 && c <= 0x30FA)
1413
+ }
1414
+ },
1415
+ '数字判定': { // @文字列Sの1文字目が数字か判定 // @すうじかはんてい
1416
+ type: 'func',
1417
+ josi: [['を', 'が']],
1418
+ pure: true,
1419
+ fn: function (s: any): boolean {
1420
+ const c = String(s).charAt(0)
1421
+ return ((c >= '0' && c <= '9') || (c >= '0' && c <= '9'))
1422
+ }
1423
+ },
1424
+ '数列判定': { // @文字列S全部が数字か判定 // @すうれつかはんてい
1425
+ type: 'func',
1426
+ josi: [['を', 'が']],
1427
+ pure: true,
1428
+ fn: function (s: any): boolean {
1429
+ return (String(s).match(/^[0-9.]+$/) !== null)
1430
+ }
1431
+ },
1432
+
1433
+ // @配列操作
1434
+ '配列結合': { // @配列Aを文字列Sでつなげて文字列で返す // @はいれつけつごう
1435
+ type: 'func',
1436
+ josi: [['を'], ['で']],
1437
+ pure: true,
1438
+ fn: function (a: any, s: string): string {
1439
+ // 配列ならOK
1440
+ if (a instanceof Array) { return a.join('' + s) }
1441
+
1442
+ const a2 = String(a).split('\n') // 配列でなければ無理矢理改行で区切ってみる
1443
+ return a2.join('' + s)
1444
+ }
1445
+ },
1446
+ '配列検索': { // @配列Aから文字列Sを探してインデックス番号(0起点)を返す。見つからなければ-1を返す。 // @はいれつけんさく
1447
+ type: 'func',
1448
+ josi: [['の', 'から'], ['を']],
1449
+ pure: true,
1450
+ fn: function (a: any, s: any) {
1451
+ if (a instanceof Array) { return a.indexOf(s) }// 配列ならOK
1452
+
1453
+ return -1
1454
+ }
1455
+ },
1456
+ '配列要素数': { // @配列Aの要素数を返す // @はいれつようそすう
1457
+ type: 'func',
1458
+ josi: [['の']],
1459
+ pure: true,
1460
+ fn: function (a: any) {
1461
+ if (a instanceof Array) { return a.length }// 配列ならOK
1462
+
1463
+ if (a instanceof Object) { return Object.keys(a).length }
1464
+
1465
+ return 1
1466
+ }
1467
+ },
1468
+ '要素数': { // @配列Aの要素数を返す // @ようそすう
1469
+ type: 'func',
1470
+ josi: [['の']],
1471
+ pure: false,
1472
+ fn: function (a: any, sys: any) {
1473
+ return sys.__exec('配列要素数', [a])
1474
+ }
1475
+ },
1476
+ '配列挿入': { // @配列AのI番目(0起点)に要素Sを追加して返す(v1非互換) // @はいれつそうにゅう
1477
+ type: 'func',
1478
+ josi: [['の'], ['に', 'へ'], ['を']],
1479
+ pure: true,
1480
+ fn: function (a: any, i: any, s: any) {
1481
+ if (a instanceof Array) { return a.splice(i, 0, s) } // 配列ならOK
1482
+
1483
+ throw new Error('『配列挿入』で配列以外の要素への挿入。')
1484
+ }
1485
+ },
1486
+ '配列一括挿入': { // @配列AのI番目(0起点)に配列bを追加して返す(v1非互換) // @はいれついっかつそうにゅう
1487
+ type: 'func',
1488
+ josi: [['の'], ['に', 'へ'], ['を']],
1489
+ pure: true,
1490
+ fn: function (a: any, i: any, b: any) {
1491
+ if (a instanceof Array && b instanceof Array) { // 配列ならOK
1492
+ for (let j = 0; j < b.length; j++) { a.splice(i + j, 0, b[j]) }
1493
+
1494
+ return a
1495
+ }
1496
+ throw new Error('『配列一括挿入』で配列以外の要素への挿入。')
1497
+ }
1498
+ },
1499
+ '配列ソート': { // @配列Aをソートして返す(A自体を変更) // @はいれつそーと
1500
+ type: 'func',
1501
+ josi: [['の', 'を']],
1502
+ pure: true,
1503
+ fn: function (a: any) {
1504
+ if (a instanceof Array) { return a.sort() } // 配列ならOK
1505
+
1506
+ throw new Error('『配列ソート』で配列以外が指定されました。')
1507
+ }
1508
+ },
1509
+ '配列数値ソート': { // @配列Aをソートして返す(A自体を変更) // @はいれつすうちそーと
1510
+ type: 'func',
1511
+ josi: [['の', 'を']],
1512
+ pure: true,
1513
+ fn: function (a: any) {
1514
+ // 配列ならOK
1515
+ if (a instanceof Array) {
1516
+ return a.sort((a, b) => {
1517
+ return parseFloat(a) - parseFloat(b)
1518
+ })
1519
+ }
1520
+
1521
+ throw new Error('『配列数値ソート』で配列以外が指定されました。')
1522
+ }
1523
+ },
1524
+ '配列カスタムソート': { // @関数Fで配列Aをソートして返す(引数A自体を変更) // @はいれつかすたむそーと
1525
+ type: 'func',
1526
+ josi: [['で'], ['の', 'を']],
1527
+ pure: false,
1528
+ fn: function (f: any, a: any, sys: any) {
1529
+ let ufunc = f
1530
+ if (typeof f === 'string') {
1531
+ ufunc = sys.__findFunc(f, '配列カスタムソート')
1532
+ }
1533
+ if (a instanceof Array) {
1534
+ return a.sort(ufunc)
1535
+ }
1536
+ throw new Error('『配列カスタムソート』で配列以外が指定されました。')
1537
+ }
1538
+ },
1539
+ '配列逆順': { // @配列Aを逆にして返す。Aを書き換える(A自体を変更)。 // @はいれつぎゃくじゅん
1540
+ type: 'func',
1541
+ josi: [['の', 'を']],
1542
+ pure: true,
1543
+ fn: function (a: any) {
1544
+ if (a instanceof Array) { return a.reverse() } // 配列ならOK
1545
+ throw new Error('『配列ソート』で配列以外が指定されました。')
1546
+ }
1547
+ },
1548
+ '配列シャッフル': { // @配列Aをシャッフルして返す。Aを書き換える // @はいれつしゃっふる
1549
+ type: 'func',
1550
+ josi: [['の', 'を']],
1551
+ pure: true,
1552
+ fn: function (a: any) {
1553
+ if (a instanceof Array) { // 配列ならOK
1554
+ for (let i = a.length - 1; i > 0; i--) {
1555
+ const r = Math.floor(Math.random() * (i + 1))
1556
+ const tmp = a[i]
1557
+ a[i] = a[r]
1558
+ a[r] = tmp
1559
+ }
1560
+ return a
1561
+ }
1562
+ throw new Error('『配列シャッフル』で配列以外が指定されました。')
1563
+ }
1564
+ },
1565
+ '配列削除': { // @配列AのI番目(0起点)の要素を削除して返す。Aの内容を書き換える。辞書型変数ならキーIを削除する。 // @はいれつさくじょ
1566
+ type: 'func',
1567
+ josi: [['の', 'から'], ['を']],
1568
+ pure: false,
1569
+ fn: function (a: any, i: any, sys: any) {
1570
+ return sys.__exec('配列切取', [a, i, sys])
1571
+ }
1572
+ },
1573
+ '配列切取': { // @配列AのI番目(0起点)の要素を切り取って返す。Aの内容を書き換える。辞書型変数ならキーIを削除する。 // @はいれつきりとる
1574
+ type: 'func',
1575
+ josi: [['の', 'から'], ['を']],
1576
+ pure: true,
1577
+ fn: function (a: any, i: any) {
1578
+ // 配列変数のとき
1579
+ if (a instanceof Array) {
1580
+ const b = a.splice(i, 1)
1581
+ if (b instanceof Array) { return b[0] } // 切り取った戻り値は必ずArrayになるので。
1582
+ return null
1583
+ }
1584
+ // 辞書型変数のとき
1585
+ if (a instanceof Object && typeof (i) === 'string') { // 辞書型変数も許容
1586
+ if (a[i]) {
1587
+ const old = a[i]
1588
+ delete a[i]
1589
+ return old
1590
+ }
1591
+ return undefined
1592
+ }
1593
+ throw new Error('『配列切取』で配列以外を指定。')
1594
+ }
1595
+ },
1596
+ '配列取出': { // @配列AのI番目(0起点)からCNT個の要素を取り出して返す。Aの内容を書き換える // @はいれつとりだし
1597
+ type: 'func',
1598
+ josi: [['の'], ['から'], ['を']],
1599
+ pure: true,
1600
+ fn: function (a: any, i: any, cnt: any) {
1601
+ if (a instanceof Array) { return a.splice(i, cnt) }
1602
+ throw new Error('『配列取出』で配列以外を指定。')
1603
+ }
1604
+ },
1605
+ '配列ポップ': { // @配列Aの末尾を取り出して返す。Aの内容を書き換える。 // @はいれつぽっぷ
1606
+ type: 'func',
1607
+ josi: [['の', 'から']],
1608
+ pure: true,
1609
+ fn: function (a: any) {
1610
+ if (a instanceof Array) { return a.pop() }
1611
+ throw new Error('『配列ポップ』で配列以外の処理。')
1612
+ }
1613
+ },
1614
+ '配列追加': { // @配列Aの末尾にBを追加して返す。Aの内容を書き換える。 // @はいれつついか
1615
+ type: 'func',
1616
+ josi: [['に', 'へ'], ['を']],
1617
+ pure: true,
1618
+ fn: function (a: any, b: any) {
1619
+ if (a instanceof Array) { // 配列ならOK
1620
+ a.push(b)
1621
+ return a
1622
+ }
1623
+ throw new Error('『配列追加』で配列以外の処理。')
1624
+ }
1625
+ },
1626
+ '配列複製': { // @配列Aを複製して返す。 // @はいれつふくせい
1627
+ type: 'func',
1628
+ josi: [['を']],
1629
+ pure: true,
1630
+ fn: function (a: any) {
1631
+ return JSON.parse(JSON.stringify(a))
1632
+ }
1633
+ },
1634
+ '配列足': { // @配列Aに配列Bを足し合わせて返す。 // @はいれつたす
1635
+ type: 'func',
1636
+ josi: [['に', 'へ', 'と'], ['を']],
1637
+ pure: true,
1638
+ fn: function (a: any, b: any) {
1639
+ if (a instanceof Array) {
1640
+ return a.concat(b)
1641
+ }
1642
+ return JSON.parse(JSON.stringify(a))
1643
+ }
1644
+ },
1645
+ '配列最大値': { // @配列Aの値の最大値を調べて返す。 // @はいれつさいだいち
1646
+ type: 'func',
1647
+ josi: [['の']],
1648
+ pure: true,
1649
+ fn: function (a: any) {
1650
+ return a.reduce((x: any, y: any) => Math.max(x, y))
1651
+ }
1652
+ },
1653
+ '配列最小値': { // @配列Aの値の最小値を調べて返す。 // @はいれつさいしょうち
1654
+ type: 'func',
1655
+ josi: [['の']],
1656
+ pure: true,
1657
+ fn: function (a: any) {
1658
+ return a.reduce((x: any, y: any) => Math.min(x, y))
1659
+ }
1660
+ },
1661
+ '配列合計': { // @配列Aの値を全て足して返す。配列の各要素を数値に変換して計算する。数値に変換できない文字列は0になる。 // @はいれつごうけい
1662
+ type: 'func',
1663
+ josi: [['の']],
1664
+ pure: true,
1665
+ fn: function (a: any) {
1666
+ if (a instanceof Array) {
1667
+ let v = 0
1668
+ a.forEach((n) => {
1669
+ const nn = parseFloat(n)
1670
+ if (isNaN(nn)) { return }
1671
+ v += nn
1672
+ })
1673
+ return v
1674
+ }
1675
+ throw new Error('『配列合計』で配列変数以外の値が指定されました。')
1676
+ }
1677
+ },
1678
+ // @二次元配列処理
1679
+ '表ソート': { // @二次元配列AでB列目(0起点)(あるいはキー名)をキーに文字列順にソートする。Aの内容を書き換える。 // @ひょうそーと
1680
+ type: 'func',
1681
+ josi: [['の'], ['を']],
1682
+ pure: true,
1683
+ fn: function (a: any, no: any) {
1684
+ if (!(a instanceof Array)) {
1685
+ throw new Error('『表ソート』には配列を指定する必要があります。')
1686
+ }
1687
+ a.sort((n, m) => {
1688
+ const ns = n[no]
1689
+ const ms = m[no]
1690
+
1691
+ if (ns === ms) {
1692
+ return 0
1693
+ } else if (ns < ms) {
1694
+ return -1
1695
+ } else {
1696
+ return 1
1697
+ }
1698
+ })
1699
+ return a
1700
+ }
1701
+ },
1702
+ '表数値ソート': { // @二次元配列AでB列目(0起点)(あるいはキー名)をキーに数値順にソートする。Aの内容を書き換える。 // @ひょうすうちそーと
1703
+ type: 'func',
1704
+ josi: [['の'], ['を']],
1705
+ pure: true,
1706
+ fn: function (a: any, no: number) {
1707
+ if (!(a instanceof Array)) {
1708
+ throw new Error('『表数値ソート』には配列を指定する必要があります。')
1709
+ }
1710
+ a.sort((n, m) => {
1711
+ const ns = n[no]
1712
+ const ms = m[no]
1713
+ return ns - ms
1714
+ })
1715
+ return a
1716
+ }
1717
+ },
1718
+ '表ピックアップ': { // @配列Aの列番号B(0起点)(あるいはキー名)で検索文字列Sを含む行を返す // @ひょうぴっくあっぷ
1719
+ type: 'func',
1720
+ josi: [['の'], ['から'], ['を', 'で']],
1721
+ pure: true,
1722
+ fn: function (a: any, no: number, s: any) {
1723
+ if (!(a instanceof Array)) { throw new Error('『表ピックアップ』には配列を指定する必要があります。') }
1724
+ return a.filter((row) => String(row[no]).indexOf(s) >= 0)
1725
+ }
1726
+ },
1727
+ '表完全一致ピックアップ': { // @配列Aの列番号B(0起点)(あるいはキー名)で検索文字列Sと一致する行を返す // @ひょうぴっくあっぷ
1728
+ type: 'func',
1729
+ josi: [['の'], ['から'], ['を', 'で']],
1730
+ pure: true,
1731
+ fn: function (a: any, no: number, s: any) {
1732
+ if (!(a instanceof Array)) { throw new Error('『表完全ピックアップ』には配列を指定する必要があります。') }
1733
+ return a.filter((row) => row[no] === s)
1734
+ }
1735
+ },
1736
+ '表検索': { // @二次元配列AでCOL列目(0起点)からキーSを含む行をROW行目から検索して何行目にあるか返す。見つからなければ-1を返す。 // @ひょうけんさく
1737
+ type: 'func',
1738
+ josi: [['の'], ['で', 'に'], ['から'], ['を']],
1739
+ pure: true,
1740
+ fn: function (a: any, col: number, row: number, s: any) {
1741
+ if (!(a instanceof Array)) { throw new Error('『表検索』には配列を指定する必要があります。') }
1742
+ for (let i = row; i < a.length; i++) {
1743
+ if (a[i][col] === s) { return i }
1744
+ }
1745
+ return -1
1746
+ }
1747
+ },
1748
+ '表列数': { // @二次元配列Aの列数を調べて返す。 // @ひょうれつすう
1749
+ type: 'func',
1750
+ josi: [['の']],
1751
+ pure: true,
1752
+ fn: function (a: any) {
1753
+ if (!(a instanceof Array)) { throw new Error('『表列数』には配列を指定する必要があります。') }
1754
+ let cols = 1
1755
+ for (let i = 0; i < a.length; i++) {
1756
+ if (a[i].length > cols) { cols = a[i].length }
1757
+ }
1758
+ return cols
1759
+ }
1760
+ },
1761
+ '表行数': { // @二次元配列Aの行数を調べて返す。 // @ひょうぎょうすう
1762
+ type: 'func',
1763
+ josi: [['の']],
1764
+ pure: true,
1765
+ fn: function (a: any) {
1766
+ if (!(a instanceof Array)) { throw new Error('『表行数』には配列を指定する必要があります。') }
1767
+ return a.length
1768
+ }
1769
+ },
1770
+ '表行列交換': { // @二次元配列Aの行と列を交換して返す。 // @ひょうぎょうれつこうかん
1771
+ type: 'func',
1772
+ josi: [['の', 'を']],
1773
+ pure: false,
1774
+ fn: function (a: any, sys: any) {
1775
+ if (!(a instanceof Array)) { throw new Error('『表行列交換』には配列を指定する必要があります。') }
1776
+ const cols = sys.__exec('表列数', [a])
1777
+ const rows = a.length
1778
+ const res = []
1779
+ for (let r = 0; r < cols; r++) {
1780
+ const row: any[] = []
1781
+ res.push(row)
1782
+ for (let c = 0; c < rows; c++) {
1783
+ row[c] = (a[c][r] !== undefined) ? a[c][r] : ''
1784
+ }
1785
+ }
1786
+ return res
1787
+ }
1788
+ },
1789
+ '表右回転': { // @二次元配列Aを90度回転して返す。 // @ひょうみぎかいてん
1790
+ type: 'func',
1791
+ josi: [['の', 'を']],
1792
+ pure: false,
1793
+ fn: function (a: any, sys: any) {
1794
+ if (!(a instanceof Array)) { throw new Error('『表右回転』には配列を指定する必要があります。') }
1795
+ const cols = sys.__exec('表列数', [a])
1796
+ const rows = a.length
1797
+ const res = []
1798
+ for (let r = 0; r < cols; r++) {
1799
+ const row: any[] = []
1800
+ res.push(row)
1801
+ for (let c = 0; c < rows; c++) {
1802
+ row[c] = a[rows - c - 1][r]
1803
+ }
1804
+ }
1805
+ return res
1806
+ }
1807
+ },
1808
+ '表重複削除': { // @二次元配列AのI列目にある重複項目を削除して返す。 // @ひょうじゅうふくさくじょ
1809
+ type: 'func',
1810
+ josi: [['の'], ['を', 'で']],
1811
+ pure: true,
1812
+ fn: function (a: any, i: any) {
1813
+ if (!(a instanceof Array)) { throw new Error('『表重複削除』には配列を指定する必要があります。') }
1814
+ const res: any[] = []
1815
+ const keys:{[key: string]: boolean} = {}
1816
+ for (let n = 0; n < a.length; n++) {
1817
+ const k = a[n][i]
1818
+ if (undefined === keys[k]) {
1819
+ keys[k] = true
1820
+ res.push(a[n])
1821
+ }
1822
+ }
1823
+ return res
1824
+ }
1825
+ },
1826
+ '表列取得': { // @二次元配列AのI列目を返す。 // @ひょうれつしゅとく
1827
+ type: 'func',
1828
+ josi: [['の'], ['を']],
1829
+ pure: true,
1830
+ fn: function (a: any, i: number) {
1831
+ if (!(a instanceof Array)) { throw new Error('『表列取得』には配列を指定する必要があります。') }
1832
+ const res = a.map(row => row[i])
1833
+ return res
1834
+ }
1835
+ },
1836
+ '表列挿入': { // @二次元配列Aの(0から数えて)I列目に配列Sを挿入して返す // @ひょうれつそうにゅう
1837
+ type: 'func',
1838
+ josi: [['の'], ['に', 'へ'], ['を']],
1839
+ pure: true,
1840
+ fn: function (a: any, i: any, s: any) {
1841
+ if (!(a instanceof Array)) { throw new Error('『表列挿入』には配列を指定する必要があります。') }
1842
+ const res: any[] = []
1843
+ a.forEach((row, idx) => {
1844
+ let nr: any[] = []
1845
+ if (i > 0) { nr = nr.concat(row.slice(0, i)) }
1846
+ nr.push(s[idx])
1847
+ nr = nr.concat(row.slice(i))
1848
+ res.push(nr)
1849
+ })
1850
+ return res
1851
+ }
1852
+ },
1853
+ '表列削除': { // @二次元配列Aの(0から数えて)I列目削除して返す // @ひょうれつそうにゅう
1854
+ type: 'func',
1855
+ josi: [['の'], ['を']],
1856
+ pure: true,
1857
+ fn: function (a: any, i: any) {
1858
+ if (!(a instanceof Array)) { throw new Error('『表列削除』には配列を指定する必要があります。') }
1859
+ const res: any[] = []
1860
+ a.forEach((row) => {
1861
+ const nr = row.slice(0)
1862
+ nr.splice(i, 1)
1863
+ res.push(nr)
1864
+ })
1865
+ return res
1866
+ }
1867
+ },
1868
+ '表列合計': { // @二次元配列Aの(0から数えて)I列目を合計して返す。 // @ひょうれつごうけい
1869
+ type: 'func',
1870
+ josi: [['の'], ['を', 'で']],
1871
+ pure: true,
1872
+ fn: function (a: any, i: any) {
1873
+ if (!(a instanceof Array)) { throw new Error('『表列合計』には配列を指定する必要があります。') }
1874
+ let sum = 0
1875
+ a.forEach((row) => { sum += row[i] })
1876
+ return sum
1877
+ }
1878
+ },
1879
+ '表曖昧検索': { // @二次元配列AのROW行目からCOL列目(0起点)で正規表現Sにマッチする行を検索して何行目にあるか返す。見つからなければ-1を返す。(v1非互換) // @ひょうれつあいまいけんさく
1880
+ type: 'func',
1881
+ josi: [['の'], ['から'], ['で'], ['を']],
1882
+ pure: true,
1883
+ fn: function (a: any, row: any, col: any, s: any) {
1884
+ if (!(a instanceof Array)) { throw new Error('『表曖昧検索』には配列を指定する必要があります。') }
1885
+ const re = new RegExp(s)
1886
+ for (let i = row; i < a.length; i++) {
1887
+ const line = a[i]
1888
+ if (re.test(line[col])) { return i }
1889
+ }
1890
+ return -1
1891
+ }
1892
+ },
1893
+ '表正規表現ピックアップ': { // @二次元配列AでI列目(0起点)から正規表現パターンSにマッチする行をピックアップして返す。 // @ひょうせいきひょうげんぴっくあっぷ
1894
+ type: 'func',
1895
+ josi: [['の', 'で'], ['から'], ['を']],
1896
+ pure: true,
1897
+ fn: function (a: any, col: any, s: any) {
1898
+ if (!(a instanceof Array)) { throw new Error('『表正規表現ピックアップ』には配列を指定する必要があります。') }
1899
+ const re = new RegExp(s)
1900
+ const res = []
1901
+ for (let i = 0; i < a.length; i++) {
1902
+ const row = a[i]
1903
+ if (re.test(row[col])) { res.push(row.slice(0)) }
1904
+ }
1905
+ return res
1906
+ }
1907
+ },
1908
+ // @辞書型変数の操作
1909
+ '辞書キー列挙': { // @辞書型変数Aのキーの一覧を配列で返す。 // @じしょきーれっきょ
1910
+ type: 'func',
1911
+ josi: [['の']],
1912
+ pure: true,
1913
+ fn: function (a: any) {
1914
+ const keys = []
1915
+ if (a instanceof Object) { // オブジェクトのキーを返す
1916
+ for (const key in a) { keys.push(key) }
1917
+ return keys
1918
+ }
1919
+ if (a instanceof Array) { // 配列なら数字を返す
1920
+ for (let i = 0; i < a.length; i++) { keys.push(i) }
1921
+ return keys
1922
+ }
1923
+ throw new Error('『辞書キー列挙』でハッシュ以外が与えられました。')
1924
+ }
1925
+ },
1926
+ '辞書キー削除': { // @辞書型変数AからキーKEYを削除して返す(A自体を変更する)。 // @じしょきーさくじょ
1927
+ type: 'func',
1928
+ josi: [['から', 'の'], ['を']],
1929
+ pure: true,
1930
+ fn: function (a: any, key: any) {
1931
+ if (a instanceof Object) { // オブジェクトのキーを返す
1932
+ if (a[key]) { delete a[key] }
1933
+ return a
1934
+ }
1935
+ throw new Error('『辞書キー削除』でハッシュ以外が与えられました。')
1936
+ }
1937
+ },
1938
+ '辞書キー存在': { // @辞書型変数AのキーKEYが存在するか確認 // @じしょきーそんざい
1939
+ type: 'func',
1940
+ josi: [['の', 'に'], ['が']],
1941
+ pure: true,
1942
+ fn: function (a: any, key: any) {
1943
+ return key in a
1944
+ }
1945
+ },
1946
+ // @ハッシュ
1947
+ 'ハッシュキー列挙': { // @ハッシュAのキー一覧を配列で返す。 // @はっしゅきーれっきょ
1948
+ type: 'func',
1949
+ josi: [['の']],
1950
+ pure: false,
1951
+ fn: function (a: any, sys: any) {
1952
+ return sys.__exec('辞書キー列挙', [a, sys])
1953
+ }
1954
+ },
1955
+ 'ハッシュ内容列挙': { // @ハッシュAの内容一覧を配列で返す。 // @はっしゅないようれっきょ
1956
+ type: 'func',
1957
+ josi: [['の']],
1958
+ pure: true,
1959
+ fn: function (a: any) {
1960
+ const body = []
1961
+ if (a instanceof Object) { // オブジェクトのキーを返す
1962
+ for (const key in a) { body.push(a[key]) }
1963
+ return body
1964
+ }
1965
+ throw new Error('『ハッシュ内容列挙』でハッシュ以外が与えられました。')
1966
+ }
1967
+ },
1968
+ 'ハッシュキー削除': { // @ハッシュAからキーKEYを削除して返す。 // @はっしゅきーさくじょ
1969
+ type: 'func',
1970
+ josi: [['から', 'の'], ['を']],
1971
+ pure: false,
1972
+ fn: function (a: any, key: any, sys: any) {
1973
+ return sys.__exec('辞書キー削除', [a, key, sys])
1974
+ }
1975
+ },
1976
+ 'ハッシュキー存在': { // @ハッシュAのキーKEYが存在するか確認 // @はっしゅきーそんざい
1977
+ type: 'func',
1978
+ josi: [['の', 'に'], ['が']],
1979
+ pure: true,
1980
+ fn: function (a: any, key: any) {
1981
+ return key in a
1982
+ }
1983
+ },
1984
+ // @タイマー
1985
+ '秒待': { // @ N秒の間待機する // @びょうまつ
1986
+ type: 'func',
1987
+ josi: [['']],
1988
+ pure: true,
1989
+ asyncFn: true,
1990
+ fn: function (n: any): Promise<void> {
1991
+ return new Promise((resolve, reject) => {
1992
+ try {
1993
+ setTimeout(() => { resolve() }, parseFloat(n) * 1000)
1994
+ } catch (err: any) {
1995
+ reject(err)
1996
+ }
1997
+ })
1998
+ },
1999
+ return_none: true
2000
+ },
2001
+ '秒待機': { // @ 「!非同期モード」または「逐次実行構文」にて、N秒の間待機する(将来的に『秒待』と同じになる予定) // @びょうたいき
2002
+ type: 'func',
2003
+ josi: [['']],
2004
+ pure: true,
2005
+ fn: function (n: any, sys: any) {
2006
+ if (sys.__genMode === '非同期モード') {
2007
+ const sysenv = sys.setAsync(sys)
2008
+ setTimeout(() => {
2009
+ sys.compAsync(sys, sysenv)
2010
+ }, n * 1000)
2011
+ return
2012
+ }
2013
+ if (sys.resolve === undefined) {
2014
+ throw new Error('『秒待機』命令は『!非同期モード』で使ってください。')
2015
+ }
2016
+ sys.__exec('秒逐次待機', [n, sys])
2017
+ },
2018
+ return_none: true
2019
+ },
2020
+ '秒逐次待機': { // @ (非推奨) 逐次実行構文にて、N秒の間待機する // @びょうちくじたいき
2021
+ type: 'func',
2022
+ josi: [['']],
2023
+ pure: true,
2024
+ fn: function (n: any, sys: any) {
2025
+ if (sys.resolve === undefined) { throw new Error('『秒逐次待機』命令は『逐次実行』構文と一緒に使ってください。') }
2026
+ const resolve = sys.resolve
2027
+ // const reject = sys.reject
2028
+ sys.resolveCount++
2029
+ const timerId = setTimeout(function () {
2030
+ const idx = sys.__timeout.indexOf(timerId)
2031
+ if (idx >= 0) { sys.__timeout.splice(idx, 1) }
2032
+ resolve()
2033
+ }, n * 1000)
2034
+ sys.__timeout.unshift(timerId)
2035
+ },
2036
+ return_none: true
2037
+ },
2038
+ '秒後': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒後に実行する。変数『対象』にタイマーIDを代入する。 // @びょうご
2039
+ type: 'func',
2040
+ josi: [['を'], ['']],
2041
+ pure: false,
2042
+ fn: function (f: any, n: any, sys: any) {
2043
+ // 文字列で指定された関数をオブジェクトに変換
2044
+ if (typeof f === 'string') { f = sys.__findFunc(f, '秒後') }
2045
+ // 1回限りのタイマーをセット
2046
+ const timerId = setTimeout(() => {
2047
+ // 使用中リストに追加したIDを削除
2048
+ const i = sys.__timeout.indexOf(timerId)
2049
+ if (i >= 0) { sys.__timeout.splice(i, 1) }
2050
+ if (sys.__genMode === '非同期モード') { sys.newenv = true }
2051
+ try {
2052
+ f(timerId, sys)
2053
+ } catch (e: any) {
2054
+ let err = e
2055
+ if (!(e instanceof NakoRuntimeError)) {
2056
+ err = new NakoRuntimeError(e, sys.__varslist[0].line)
2057
+ }
2058
+ sys.logger.error(err)
2059
+ }
2060
+ }, parseFloat(n) * 1000)
2061
+ sys.__timeout.unshift(timerId)
2062
+ sys.__v0['対象'] = timerId
2063
+ return timerId
2064
+ }
2065
+ },
2066
+ '秒毎': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒ごとに実行する(『タイマー停止』で停止できる)。変数『対象』にタイマーIDを代入する。 // @びょうごと
2067
+ type: 'func',
2068
+ josi: [['を'], ['']],
2069
+ pure: false,
2070
+ fn: function (f: any, n: any, sys: any) {
2071
+ // 文字列で指定された関数をオブジェクトに変換
2072
+ if (typeof f === 'string') { f = sys.__findFunc(f, '秒毎') }
2073
+ // タイマーをセット
2074
+ const timerId = setInterval(() => {
2075
+ if (sys.__genMode === '非同期モード') { sys.newenv = true }
2076
+ f(timerId, sys)
2077
+ }, parseFloat(n) * 1000)
2078
+ // タイマーIDを追加
2079
+ sys.__interval.unshift(timerId)
2080
+ sys.__v0['対象'] = timerId
2081
+ return timerId
2082
+ }
2083
+ },
2084
+ '秒タイマー開始時': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒ごとに実行する(『秒毎』と同じ) // @びょうたいまーかいししたとき
2085
+ type: 'func',
2086
+ josi: [['を'], ['']],
2087
+ pure: false,
2088
+ fn: function (f: any, n: any, sys: any) {
2089
+ return sys.__exec('秒毎', [f, n, sys])
2090
+ }
2091
+ },
2092
+ 'タイマー停止': { // @『秒毎』『秒後』や『秒タイマー開始』で開始したタイマーを停止する // @たいまーていし
2093
+ type: 'func',
2094
+ josi: [['の', 'で']],
2095
+ pure: true,
2096
+ fn: function (timerId: any, sys: any) {
2097
+ const i = sys.__interval.indexOf(timerId)
2098
+ if (i >= 0) {
2099
+ sys.__interval.splice(i, 1)
2100
+ clearInterval(timerId)
2101
+ return true
2102
+ }
2103
+ const j = sys.__timeout.indexOf(timerId)
2104
+ if (j >= 0) {
2105
+ sys.__timeout.splice(j, 1)
2106
+ clearTimeout(timerId)
2107
+ return true
2108
+ }
2109
+ return false
2110
+ },
2111
+ return_none: false
2112
+ },
2113
+ '全タイマー停止': { // @『秒毎』『秒後』や『秒タイマー開始』で開始したタイマーを全部停止する // @ぜんたいまーていし
2114
+ type: 'func',
2115
+ josi: [],
2116
+ pure: true,
2117
+ fn: function (sys: any) {
2118
+ // clearInterval
2119
+ for (let i = 0; i < sys.__interval.length; i++) {
2120
+ const timerId = sys.__interval[i]
2121
+ clearInterval(timerId)
2122
+ }
2123
+ sys.__interval = []
2124
+ // clearTimeout
2125
+ for (let i = 0; i < sys.__timeout.length; i++) {
2126
+ const timerId = sys.__timeout[i]
2127
+ clearTimeout(timerId)
2128
+ }
2129
+ sys.__timeout = []
2130
+ },
2131
+ return_none: true
2132
+ },
2133
+ // @日時処理(簡易)
2134
+ '元号データ': { type: 'const', value: [{ '元号': '令和', '改元日': '2019/05/01' }, { '元号': '平成', '改元日': '1989/01/08' }, { '元号': '昭和', '改元日': '1926/12/25' }, { '元号': '大正', '改元日': '1912/07/30' }, { '元号': '明治', '改元日': '1868/10/23' }] }, // @げんごうでーた
2135
+ '今': { // @現在時刻を「HH:mm:ss」の形式で返す // @いま
2136
+ type: 'func',
2137
+ josi: [],
2138
+ pure: true,
2139
+ fn: function () {
2140
+ const z2 = (n: any) => {
2141
+ n = '00' + n
2142
+ return n.substring(n.length - 2, n.length)
2143
+ }
2144
+ const t = new Date()
2145
+ return z2(t.getHours()) + ':' + z2(t.getMinutes()) + ':' + z2(t.getSeconds())
2146
+ }
2147
+ },
2148
+ 'システム時間': { // @現在のUNIX時間 (UTC(1970/1/1)からの経過秒数) を返す // @しすてむじかん
2149
+ type: 'func',
2150
+ josi: [],
2151
+ pure: true,
2152
+ fn: function () {
2153
+ const now = new Date()
2154
+ return Math.floor(now.getTime() / 1000)
2155
+ }
2156
+ },
2157
+ 'システム時間ミリ秒': { // @現在のUNIX時間 (UTC(1970/1/1)からの経過秒数) をミリ秒で返す // @しすてむじかんみりびょう
2158
+ type: 'func',
2159
+ josi: [],
2160
+ pure: true,
2161
+ fn: function () {
2162
+ const now = new Date()
2163
+ return now.getTime()
2164
+ }
2165
+ },
2166
+ '今日': { // @今日の日付を「YYYY/MM/DD」の形式で返す // @きょう
2167
+ type: 'func',
2168
+ josi: [],
2169
+ pure: true,
2170
+ fn: function (sys: any) {
2171
+ return sys.__formatDate(new Date())
2172
+ }
2173
+ },
2174
+ '明日': { // @明日の日付を「YYYY/MM/DD」の形式で返す // @あした
2175
+ type: 'func',
2176
+ josi: [],
2177
+ pure: true,
2178
+ fn: function (sys: any) {
2179
+ const t = Date.now() + (24 * 60 * 60 * 1000)
2180
+ return sys.__formatDate(new Date(t))
2181
+ }
2182
+ },
2183
+ '昨日': { // @昨日の日付を「YYYY/MM/DD」の形式で返す // @きのう
2184
+ type: 'func',
2185
+ josi: [],
2186
+ pure: true,
2187
+ fn: function (sys: any) {
2188
+ const t = Date.now() - (24 * 60 * 60 * 1000)
2189
+ return sys.__formatDate(new Date(t))
2190
+ }
2191
+ },
2192
+ '今年': { // @今年が何年かを西暦で返す // @ことし
2193
+ type: 'func',
2194
+ josi: [],
2195
+ pure: true,
2196
+ fn: function () {
2197
+ return (new Date()).getFullYear()
2198
+ }
2199
+ },
2200
+ '来年': { // @来年が何年かを西暦で返す // @らいねん
2201
+ type: 'func',
2202
+ josi: [],
2203
+ pure: true,
2204
+ fn: function () {
2205
+ return (new Date()).getFullYear() + 1
2206
+ }
2207
+ },
2208
+ '去年': { // @去年が何年かを西暦で返す // @きょねん
2209
+ type: 'func',
2210
+ josi: [],
2211
+ pure: true,
2212
+ fn: function () {
2213
+ return (new Date()).getFullYear() - 1
2214
+ }
2215
+ },
2216
+ '今月': { // @今月が何月かを返す // @こんげつ
2217
+ type: 'func',
2218
+ josi: [],
2219
+ pure: true,
2220
+ fn: function () {
2221
+ return (new Date()).getMonth() + 1
2222
+ }
2223
+ },
2224
+ '来月': { // @来月が何月かを返す // @らいげつ
2225
+ type: 'func',
2226
+ josi: [],
2227
+ pure: true,
2228
+ fn: function () {
2229
+ return (new Date()).getMonth() + 2
2230
+ }
2231
+ },
2232
+ '先月': { // @先月が何月かをかえす // @せんげつ
2233
+ type: 'func',
2234
+ josi: [],
2235
+ pure: true,
2236
+ fn: function () {
2237
+ return (new Date()).getMonth()
2238
+ }
2239
+ },
2240
+ '曜日': { // @Sに指定した日付の曜日をで返す。不正な日付の場合は今日の曜日番号を返す。 // @ようび
2241
+ type: 'func',
2242
+ josi: [['の']],
2243
+ pure: true,
2244
+ fn: function (s: string, sys: any) {
2245
+ const d = sys.__str2date(s)
2246
+ return '日月火水木金土'.charAt(d.getDay() % 7)
2247
+ }
2248
+ },
2249
+ '曜日番号取得': { // @Sに指定した日付の曜日番号をで返す。不正な日付の場合は今日の曜日番号を返す。(0=日/1=月/2=火/3=水/4=木/5=金/6=土) // @ようびばんごうしゅとく
2250
+ type: 'func',
2251
+ josi: [['の']],
2252
+ pure: true,
2253
+ fn: function (s: any) {
2254
+ const a = s.split('/')
2255
+ const t = new Date(a[0], a[1] - 1, a[2])
2256
+ return t.getDay()
2257
+ }
2258
+ },
2259
+ 'UNIXTIME変換': { // @日時SをUNIX時間 (UTC(1970/1/1)からの経過秒数) に変換して返す(v1非互換) // @UNIXTIMEへんかん
2260
+ type: 'func',
2261
+ josi: [['の', 'を', 'から']],
2262
+ pure: true,
2263
+ fn: function (s: string, sys: any) {
2264
+ const d = sys.__str2date(s)
2265
+ return d.getTime() / 1000
2266
+ }
2267
+ },
2268
+ 'UNIX時間変換': { // @日時SをUNIX時間 (UTC(1970/1/1)からの経過秒数) に変換して返す(v1非互換) // @UNIXじかんへんかん
2269
+ type: 'func',
2270
+ josi: [['の', 'を', 'から']],
2271
+ pure: true,
2272
+ fn: function (s: string, sys: any) {
2273
+ const d = sys.__str2date(s)
2274
+ return d.getTime() / 1000
2275
+ }
2276
+ },
2277
+ '日時変換': { // @UNIX時間 (UTC(1970/1/1)からの経過秒数) を「YYYY/MM/DD HH:mm:ss」の形式に変換 // @にちじへんかん
2278
+ type: 'func',
2279
+ josi: [['を', 'から']],
2280
+ pure: true,
2281
+ fn: function (tm: any, sys: any) {
2282
+ const t = tm * 1000
2283
+ return sys.__formatDateTime(new Date(t), '2022/01/01 00:00:00')
2284
+ }
2285
+ },
2286
+ '日時書式変換': { // @UNIX時間TM(または日付文字列)を「YYYY/MM/DD HH:mm:ss」または「YY-M-D H:m:s」その他、W:曜日、WWW:曜日英、MMM:月英、ccc:ミリ秒の書式に変換 // @にちじしょしきへんかん
2287
+ type: 'func',
2288
+ josi: [['を'], ['で']],
2289
+ pure: true,
2290
+ fn: function (tm: any, fmt: any, sys: any) {
2291
+ const t = sys.__str2date(tm)
2292
+ fmt = fmt.replace(/(YYYY|ccc|WWW|MMM|YY|MM|DD|HH|mm|ss|[MDHmsW])/g, (m: string) => {
2293
+ switch (m) {
2294
+ case 'YYYY': return t.getFullYear()
2295
+ case 'YY': return ('' + t.getFullYear()).substring(2)
2296
+ case 'MM': return sys.__zero2(t.getMonth() + 1)
2297
+ case 'DD': return sys.__zero2(t.getDate())
2298
+ case 'M': return (t.getMonth() + 1)
2299
+ case 'D': return (t.getDate())
2300
+ case 'HH': return sys.__zero2(t.getHours())
2301
+ case 'mm': return sys.__zero2(t.getMinutes())
2302
+ case 'ss': return sys.__zero2(t.getSeconds())
2303
+ case 'ccc': return sys.__zero(t.getMilliseconds(), 3)
2304
+ case 'H': return (t.getHours())
2305
+ case 'm': return (t.getMinutes())
2306
+ case 's': return (t.getSeconds())
2307
+ case 'W': return '日月火水木金土'.charAt(t.getDay() % 7)
2308
+ case 'WWW': return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][t.getDay() % 7]
2309
+ case 'MMM': return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][t.getMonth()]
2310
+ }
2311
+ return m
2312
+ })
2313
+ return fmt
2314
+ }
2315
+ },
2316
+ '和暦変換': { // @Sを和暦に変換する。Sは明治以降の日付が有効。 // @われきへんかん
2317
+ type: 'func',
2318
+ josi: [['を']],
2319
+ pure: true,
2320
+ fn: function (s: string, sys: any) {
2321
+ const d = sys.__str2date(s)
2322
+ const t = d.getTime()
2323
+ for (const era of sys.__v0['元号データ']) {
2324
+ const gengo = era['元号']
2325
+ const d2 = sys.__str2date(era['改元日'])
2326
+ const t2 = d2.getTime()
2327
+ if (t2 <= t) {
2328
+ let y: any = (d.getFullYear() - d2.getFullYear()) + 1
2329
+ if (y === 1) { y = '元' }
2330
+ return gengo + y + '年' + sys.__zero2(d.getMonth() + 1) + '月' + sys.__zero2(d.getDate()) + '日'
2331
+ }
2332
+ }
2333
+ throw new Error('『和暦変換』は明示以前の日付には対応していません。')
2334
+ }
2335
+ },
2336
+ '年数差': { // @日付AとBの差を年数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す (v1非互換)。 // @ねんすうさ
2337
+ type: 'func',
2338
+ josi: [['と', 'から'], ['の', 'までの']],
2339
+ pure: true,
2340
+ fn: function (a: any, b: any, sys: any) {
2341
+ const t1 = sys.__str2date(a)
2342
+ const t2 = sys.__str2date(b)
2343
+ return (t2.getFullYear() - t1.getFullYear())
2344
+ }
2345
+ },
2346
+ '月数差': { // @日付AとBの差を月数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す (v1非互換)。 // @げっすうさ
2347
+ type: 'func',
2348
+ josi: [['と', 'から'], ['の', 'までの']],
2349
+ pure: true,
2350
+ fn: function (a: any, b: any, sys: any) {
2351
+ const t1 = sys.__str2date(a)
2352
+ const t2 = sys.__str2date(b)
2353
+ return ((t2.getFullYear() * 12 + t2.getMonth()) -
2354
+ (t1.getFullYear() * 12 + t1.getMonth()))
2355
+ }
2356
+ },
2357
+ '日数差': { // @日付AとBの差を日数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @にっすうさ
2358
+ type: 'func',
2359
+ josi: [['と', 'から'], ['の', 'までの']],
2360
+ pure: true,
2361
+ fn: function (a: any, b: any, sys: any) {
2362
+ const t1 = Math.ceil(sys.__str2date(a).getTime() / 1000)
2363
+ const t2 = Math.ceil(sys.__str2date(b).getTime() / 1000)
2364
+ const days = Math.ceil((t2 - t1) / (60 * 60 * 24))
2365
+ return days
2366
+ }
2367
+ },
2368
+ '時間差': { // @時間AとBの時間の差を求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @じかんさ
2369
+ type: 'func',
2370
+ josi: [['と', 'から'], ['の', 'までの']],
2371
+ pure: true,
2372
+ fn: function (a: any, b: any, sys: any) {
2373
+ const t1 = Math.ceil(sys.__str2date(a).getTime() / 1000)
2374
+ const t2 = Math.ceil(sys.__str2date(b).getTime() / 1000)
2375
+ const hours = Math.ceil((t2 - t1) / (60 * 60))
2376
+ return hours
2377
+ }
2378
+ },
2379
+ '分差': { // @時間AとBの分数の差を求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @ふんさ
2380
+ type: 'func',
2381
+ josi: [['と', 'から'], ['の', 'までの']],
2382
+ pure: true,
2383
+ fn: function (a: any, b: any, sys: any) {
2384
+ const t1 = Math.ceil(sys.__str2date(a).getTime() / 1000)
2385
+ const t2 = Math.ceil(sys.__str2date(b).getTime() / 1000)
2386
+ const min = Math.ceil((t2 - t1) / (60))
2387
+ return min
2388
+ }
2389
+ },
2390
+ '秒差': { // @時間AとBの差を秒差で求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @びょうさ
2391
+ type: 'func',
2392
+ josi: [['と', 'から'], ['の', 'までの']],
2393
+ pure: true,
2394
+ fn: function (a: any, b: any, sys: any) {
2395
+ const t1 = Math.ceil(sys.__str2date(a).getTime() / 1000)
2396
+ const t2 = Math.ceil(sys.__str2date(b).getTime() / 1000)
2397
+ const sec = Math.ceil((t2 - t1))
2398
+ return sec
2399
+ }
2400
+ },
2401
+ '日時差': { // @日時AとBの差を種類unitで返す。A<Bなら正の数、そうでないなら負の数を返す (v1非互換)。 // @にちじさ
2402
+ type: 'func',
2403
+ josi: [['と', 'から'], ['の', 'までの'], ['による']],
2404
+ pure: true,
2405
+ fn: function (a: any, b: any, unit: string, sys: any): string {
2406
+ switch (unit) {
2407
+ case '年': return sys.__exec('年数差', [a, b, sys])
2408
+ case '月': return sys.__exec('月数差', [a, b, sys])
2409
+ case '日': return sys.__exec('日数差', [a, b, sys])
2410
+ case '時間': return sys.__exec('時間差', [a, b, sys])
2411
+ case '分': return sys.__exec('分差', [a, b, sys])
2412
+ case '秒': return sys.__exec('秒差', [a, b, sys])
2413
+ }
2414
+ throw new Error('『日時差』で不明な単位です。')
2415
+ }
2416
+ },
2417
+ '時間加算': { // @時間SにAを加えて返す。Aには「(+|-)hh:nn:dd」で指定する。 // @じかんかさん
2418
+ type: 'func',
2419
+ josi: [['に'], ['を']],
2420
+ pure: true,
2421
+ fn: function (s: any, a: any, sys: any) {
2422
+ const op = a.charAt(0)
2423
+ if (op === '-' || op === '+') {
2424
+ a = a.substring(1)
2425
+ }
2426
+ const d = sys.__str2date(s)
2427
+ const aa = (a + ':0:0').split(':')
2428
+ let sec = parseInt(aa[0]) * 60 * 60 +
2429
+ parseInt(aa[1]) * 60 +
2430
+ parseInt(aa[2])
2431
+ if (op === '-') { sec *= -1 }
2432
+ const rd = new Date(d.getTime() + (sec * 1000))
2433
+ return sys.__formatDateTime(rd, s)
2434
+ }
2435
+ },
2436
+ '日付加算': { // @日付SにAを加えて返す。Aには「(+|-)yyyy/mm/dd」で指定する。 // @ひづけかさん
2437
+ type: 'func',
2438
+ josi: [['に'], ['を']],
2439
+ pure: true,
2440
+ fn: function (s: any, a: any, sys: any) {
2441
+ let op = 1
2442
+ const opc = a.charAt(0)
2443
+ if (opc === '-' || opc === '+') {
2444
+ a = a.substring(1)
2445
+ if (opc === '-') { op *= -1 }
2446
+ }
2447
+ const d = sys.__str2date(s)
2448
+ const aa = (a + '/0/0').split('/')
2449
+ const addY = parseInt(aa[0]) * op
2450
+ const addM = parseInt(aa[1]) * op
2451
+ const addD = parseInt(aa[2]) * op
2452
+ d.setFullYear(d.getFullYear() + addY)
2453
+ d.setMonth(d.getMonth() + addM)
2454
+ d.setDate(d.getDate() + addD)
2455
+ return sys.__formatDateTime(d, s)
2456
+ }
2457
+ },
2458
+ '日時加算': { // @日時SにAを加えて返す。Aは「(+|-)1(年|ヶ月|日|週|時間|分|秒)」のように指定する (v1非互換)。 // @にちじかさん
2459
+ type: 'func',
2460
+ josi: [['に'], ['を']],
2461
+ pure: true,
2462
+ fn: function (s: any, a: any, sys: any) {
2463
+ const r = ('' + a).match(/([+|-]?)(\d+)(年|ヶ月|日|週間|時間|分|秒)$/)
2464
+ if (!r) { throw new Error('『日付加算』は『(+|-)1(年|ヶ月|日|時間|分|秒)』の書式で指定します。') }
2465
+ switch (r[3]) {
2466
+ case '年': return sys.__exec('日付加算', [s, `${r[1]}${r[2]}/0/0`, sys])
2467
+ case 'ヶ月': return sys.__exec('日付加算', [s, `${r[1]}0/${r[2]}/0`, sys])
2468
+ case '週間': return sys.__exec('日付加算', [s, `${r[1]}0/0/${parseInt(r[2]) * 7}`, sys])
2469
+ case '日': return sys.__exec('日付加算', [s, `${r[1]}0/0/${r[2]}`, sys])
2470
+ case '時間': return sys.__exec('時間加算', [s, `${r[1]}${r[2]}:0:0`, sys])
2471
+ case '分': return sys.__exec('時間加算', [s, `${r[1]}0:${r[2]}:0`, sys])
2472
+ case '秒': return sys.__exec('時間加算', [s, `${r[1]}0:0:${r[2]}`, sys])
2473
+ }
2474
+ }
2475
+ },
2476
+ '時間ミリ秒取得': { // @ミリ秒単位の時間を数値で返す。結果は実装に依存する。 // @じかんみりびょうしゅとく
2477
+ type: 'func',
2478
+ josi: [],
2479
+ pure: true,
2480
+ fn: function () {
2481
+ if (performance && performance.now) {
2482
+ return performance.now()
2483
+ } else if (Date.now) {
2484
+ return Date.now()
2485
+ } else {
2486
+ const now = new Date()
2487
+ return now.getTime()
2488
+ }
2489
+ }
2490
+ },
2491
+ // @デバッグ支援
2492
+ 'エラー発生': { // @故意にエラーSを発生させる // @えらーはっせい
2493
+ type: 'func',
2494
+ josi: [['の', 'で']],
2495
+ pure: true,
2496
+ fn: function (s: any) {
2497
+ throw new Error(s)
2498
+ }
2499
+ },
2500
+ 'グローバル関数一覧取得': { // @グローバル変数にある関数一覧を取得 // @ぐろーばるかんすういちらんしゅとく
2501
+ type: 'func',
2502
+ josi: [],
2503
+ pure: true,
2504
+ fn: function (sys: any) {
2505
+ const vars: any = sys.__varslist[1]
2506
+ const res: string[] = []
2507
+ for (const key in vars) {
2508
+ if (Object.prototype.hasOwnProperty.call(vars, key)) {
2509
+ res.push(key)
2510
+ }
2511
+ }
2512
+ return res
2513
+ }
2514
+ },
2515
+ 'システム関数一覧取得': { // @システム関数の一覧を取得 // @しすてむかんすういちらんしゅとく
2516
+ type: 'func',
2517
+ josi: [],
2518
+ pure: true,
2519
+ fn: function (sys: any) {
2520
+ const vars: any = sys.__varslist[0]
2521
+ const res: string[] = []
2522
+ for (const key in vars) {
2523
+ if (Object.prototype.hasOwnProperty.call(vars, key)) {
2524
+ res.push(key)
2525
+ }
2526
+ }
2527
+ return res
2528
+ }
2529
+ },
2530
+ 'システム関数存在': { // @文字列で関数名を指定してシステム関数が存在するかを調べる // @しすてむかんすうそんざい
2531
+ type: 'func',
2532
+ josi: [['が', 'の']],
2533
+ pure: true,
2534
+ fn: function (fname: string, sys: any) {
2535
+ return (typeof sys.__v0[fname] !== 'undefined')
2536
+ }
2537
+ },
2538
+ 'プラグイン一覧取得': { // @利用中のプラグイン一覧を得る // @ぷらぐいんいちらんしゅとく
2539
+ type: 'func',
2540
+ josi: [],
2541
+ pure: true,
2542
+ fn: function (sys: any) {
2543
+ const a = []
2544
+ for (const f in sys.pluginfiles) { a.push(f) }
2545
+
2546
+ return a
2547
+ }
2548
+ },
2549
+ 'モジュール一覧取得': { // @取り込んだモジュール一覧を得る // @もじゅーるいちらんしゅとく
2550
+ type: 'func',
2551
+ josi: [],
2552
+ pure: true,
2553
+ fn: function (sys: any) {
2554
+ const a = []
2555
+ for (const f in sys.__module) { a.push(f) }
2556
+
2557
+ return a
2558
+ }
2559
+ },
2560
+ '助詞一覧取得': { // @文法として定義されている助詞の一覧を取得する // @じょしいちらんしゅとく
2561
+ type: 'func',
2562
+ josi: [],
2563
+ pure: true,
2564
+ asyncFn: true,
2565
+ fn: function () {
2566
+ return new Promise((resolve, reject) => {
2567
+ import('./nako_josi_list.mjs')
2568
+ .then((mod) => {
2569
+ const obj = Object.assign({}, mod)
2570
+ resolve(obj.josiList)
2571
+ })
2572
+ .catch((err) => {
2573
+ reject(err)
2574
+ })
2575
+ })
2576
+ }
2577
+ },
2578
+ '予約語一覧取得': { // @文法として定義されている予約語の一覧を取得する // @よやくごいちらんしゅとく
2579
+ type: 'func',
2580
+ josi: [],
2581
+ pure: true,
2582
+ asyncFn: true,
2583
+ fn: function () {
2584
+ // const words = require('./nako_reserved_words.mjs')
2585
+ return new Promise((resolve, reject) => {
2586
+ import('./nako_reserved_words.mjs')
2587
+ .then((mod) => {
2588
+ const obj = Object.assign({}, mod)
2589
+ const w = []
2590
+ for (const key in obj.default) {
2591
+ w.push(key)
2592
+ }
2593
+ resolve(w)
2594
+ })
2595
+ .catch((err) => {
2596
+ reject(err)
2597
+ })
2598
+ })
2599
+ }
2600
+ },
2601
+ // @プラグイン管理
2602
+ 'プラグイン名': { type: 'const', value: 'メイン' }, // @ぷらぐいんめい
2603
+ 'プラグイン名設定': { // @プラグイン名をSに変更する // @プラグインめいせってい
2604
+ type: 'func',
2605
+ josi: [['に', 'へ']],
2606
+ pure: true,
2607
+ fn: function (s: string, sys: any) {
2608
+ sys.__v0['プラグイン名'] = s
2609
+ },
2610
+ return_none: true
2611
+ },
2612
+
2613
+ // @URLエンコードとパラメータ
2614
+ 'URLエンコード': { // @URLエンコードして返す // @URLえんこーど
2615
+ type: 'func',
2616
+ josi: [['を', 'から']],
2617
+ pure: true,
2618
+ fn: function (text: any) {
2619
+ return encodeURIComponent(text)
2620
+ }
2621
+ },
2622
+ 'URLデコード': { // @URLデコードして返す // @URLでこーど
2623
+ type: 'func',
2624
+ josi: [['を', 'へ', 'に']],
2625
+ pure: true,
2626
+ fn: function (text: any) {
2627
+ return decodeURIComponent(text)
2628
+ }
2629
+ },
2630
+ 'URLパラメータ解析': { // @URLパラメータを解析してハッシュで返す // @URLぱらめーたかいせき
2631
+ type: 'func',
2632
+ josi: [['を', 'の', 'から']],
2633
+ pure: true,
2634
+ fn: function (url: string, sys: any) {
2635
+ const res: any = {}
2636
+ if (typeof url !== 'string') {
2637
+ return res
2638
+ }
2639
+ const p = url.split('?')
2640
+ if (p.length <= 1) {
2641
+ return res
2642
+ }
2643
+ const params = p[1].split('&')
2644
+ for (const line of params) {
2645
+ const line2 = line + '='
2646
+ const kv = line2.split('=')
2647
+ const k = sys.__exec('URLデコード', [kv[0]])
2648
+ res[k] = sys.__exec('URLデコード', [kv[1]])
2649
+ }
2650
+ return res
2651
+ }
2652
+ },
2653
+ // @BASE64
2654
+ 'BASE64エンコード': { // @BASE64エンコードして返す // @BASE64えんこーど
2655
+ type: 'func',
2656
+ josi: [['を', 'から']],
2657
+ pure: true,
2658
+ fn: function (text: any) {
2659
+ // browser?
2660
+ if (typeof (window) !== 'undefined' && (window as any).btoa) {
2661
+ const u8a: any = new TextEncoder().encode(text)
2662
+ const utf8str = String.fromCharCode.apply(null, u8a)
2663
+ return btoa(utf8str)
2664
+ }
2665
+ // Node?
2666
+ if (typeof (Buffer) !== 'undefined') {
2667
+ return Buffer.from(text).toString('base64')
2668
+ }
2669
+ throw new Error('『BASE64エンコード』は利用できません。')
2670
+ }
2671
+ },
2672
+ 'BASE64デコード': { // @BASE64デコードして返す // @BASE64でこーど
2673
+ type: 'func',
2674
+ josi: [['を', 'へ', 'に']],
2675
+ pure: true,
2676
+ fn: function (text: any) {
2677
+ if (typeof (window) !== 'undefined' && (window as any).atob) {
2678
+ const decodedUtf8str = atob(text)
2679
+ const dec: any = Array.prototype.map.call(decodedUtf8str, c => c.charCodeAt())
2680
+ const decodedArray = new Uint8Array(dec)
2681
+ return new TextDecoder('UTF-8').decode(decodedArray)
2682
+ }
2683
+ // Node?
2684
+ if (typeof (Buffer) !== 'undefined') {
2685
+ return Buffer.from(text, 'base64').toString()
2686
+ }
2687
+ throw new Error('『BASE64デコード』は利用できません。')
2688
+ }
2689
+ }
2690
+ }