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