@sayue_ltr/fleq 1.50.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/README.md +42 -6
  3. package/dist/config.js +37 -4
  4. package/dist/dmdata/rest-client.js +58 -3
  5. package/dist/dmdata/telegram-parser.js +115 -64
  6. package/dist/dmdata/ws-client.js +49 -18
  7. package/dist/engine/cli/cli-run.js +88 -3
  8. package/dist/engine/cli/cli.js +12 -0
  9. package/dist/engine/eew/eew-tracker.js +41 -15
  10. package/dist/engine/filter/compile-filter.js +21 -0
  11. package/dist/engine/filter/compiler.js +188 -0
  12. package/dist/engine/filter/errors.js +41 -0
  13. package/dist/engine/filter/field-registry.js +78 -0
  14. package/dist/engine/filter/index.js +15 -0
  15. package/dist/engine/filter/parser.js +137 -0
  16. package/dist/engine/filter/rank-maps.js +34 -0
  17. package/dist/engine/filter/tokenizer.js +121 -0
  18. package/dist/engine/filter/type-checker.js +104 -0
  19. package/dist/engine/filter/types.js +2 -0
  20. package/dist/engine/filter-template/pipeline-controller.js +73 -0
  21. package/dist/engine/filter-template/pipeline.js +16 -0
  22. package/dist/engine/messages/display-callbacks.js +7 -0
  23. package/dist/engine/messages/message-router.js +114 -182
  24. package/dist/engine/messages/summary-tracker.js +106 -0
  25. package/dist/engine/messages/telegram-stats.js +103 -0
  26. package/dist/engine/messages/volcano-route-handler.js +122 -0
  27. package/dist/engine/monitor/monitor.js +52 -4
  28. package/dist/engine/monitor/shutdown.js +1 -0
  29. package/dist/engine/notification/notifier.js +21 -4
  30. package/dist/engine/notification/sound-player.js +398 -36
  31. package/dist/engine/presentation/diff-store.js +158 -0
  32. package/dist/engine/presentation/diff-types.js +2 -0
  33. package/dist/engine/presentation/events/from-earthquake.js +53 -0
  34. package/dist/engine/presentation/events/from-eew.js +72 -0
  35. package/dist/engine/presentation/events/from-lg-observation.js +58 -0
  36. package/dist/engine/presentation/events/from-nankai-trough.js +39 -0
  37. package/dist/engine/presentation/events/from-raw.js +35 -0
  38. package/dist/engine/presentation/events/from-seismic-text.js +37 -0
  39. package/dist/engine/presentation/events/from-tsunami.js +51 -0
  40. package/dist/engine/presentation/events/from-volcano.js +88 -0
  41. package/dist/engine/presentation/events/to-presentation-event.js +32 -0
  42. package/dist/engine/presentation/level-helpers.js +118 -0
  43. package/dist/engine/presentation/processors/process-earthquake.js +36 -0
  44. package/dist/engine/presentation/processors/process-eew.js +105 -0
  45. package/dist/engine/presentation/processors/process-lg-observation.js +30 -0
  46. package/dist/engine/presentation/processors/process-message.js +53 -0
  47. package/dist/engine/presentation/processors/process-nankai-trough.js +30 -0
  48. package/dist/engine/presentation/processors/process-raw.js +22 -0
  49. package/dist/engine/presentation/processors/process-seismic-text.js +30 -0
  50. package/dist/engine/presentation/processors/process-tsunami.js +42 -0
  51. package/dist/engine/presentation/processors/process-volcano.js +41 -0
  52. package/dist/engine/presentation/types.js +2 -0
  53. package/dist/engine/startup/config-resolver.js +2 -0
  54. package/dist/engine/template/compile-template.js +18 -0
  55. package/dist/engine/template/compiler.js +105 -0
  56. package/dist/engine/template/field-accessor.js +31 -0
  57. package/dist/engine/template/filters.js +100 -0
  58. package/dist/engine/template/index.js +5 -0
  59. package/dist/engine/template/parser.js +185 -0
  60. package/dist/engine/template/tokenizer.js +96 -0
  61. package/dist/engine/template/types.js +2 -0
  62. package/dist/types.js +3 -2
  63. package/dist/ui/display-adapter.js +60 -0
  64. package/dist/ui/earthquake-formatter.js +22 -5
  65. package/dist/ui/eew-formatter.js +25 -10
  66. package/dist/ui/formatter.js +116 -32
  67. package/dist/ui/minimap/grid-layout.js +91 -0
  68. package/dist/ui/minimap/index.js +16 -0
  69. package/dist/ui/minimap/minimap-renderer.js +277 -0
  70. package/dist/ui/minimap/pref-mapping.js +82 -0
  71. package/dist/ui/minimap/types.js +2 -0
  72. package/dist/ui/night-overlay.js +56 -0
  73. package/dist/ui/repl-handlers/command-definitions.js +327 -0
  74. package/dist/ui/repl-handlers/index.js +11 -0
  75. package/dist/ui/repl-handlers/info-handlers.js +633 -0
  76. package/dist/ui/repl-handlers/operation-handlers.js +233 -0
  77. package/dist/ui/repl-handlers/settings-handlers.js +927 -0
  78. package/dist/ui/repl-handlers/types.js +10 -0
  79. package/dist/ui/repl.js +81 -1752
  80. package/dist/ui/statistics-formatter.js +258 -0
  81. package/dist/ui/status-line.js +80 -0
  82. package/dist/ui/summary/index.js +5 -0
  83. package/dist/ui/summary/summary-line.js +18 -0
  84. package/dist/ui/summary/summary-model.js +31 -0
  85. package/dist/ui/summary/token-builders.js +317 -0
  86. package/dist/ui/summary/types.js +2 -0
  87. package/dist/ui/summary/width-fit.js +41 -0
  88. package/dist/ui/summary-interval-formatter.js +72 -0
  89. package/dist/ui/test-samples.js +6 -0
  90. package/dist/ui/theme.js +43 -5
  91. package/dist/ui/tip-shuffler.js +81 -0
  92. package/dist/ui/volcano-formatter.js +15 -13
  93. package/dist/ui/waiting-tips-eew.js +63 -0
  94. package/dist/ui/waiting-tips-info-systems.js +81 -0
  95. package/dist/ui/waiting-tips-seismology.js +97 -0
  96. package/dist/ui/waiting-tips-tsunami.js +72 -0
  97. package/dist/ui/waiting-tips-weather.js +189 -0
  98. package/dist/ui/waiting-tips.js +420 -249
  99. package/package.json +1 -1
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.formatStatsDuration = formatStatsDuration;
37
+ exports.displayStatistics = displayStatistics;
38
+ const formatter_1 = require("./formatter");
39
+ const theme = __importStar(require("./theme"));
40
+ // ── 定数 ──
41
+ const TYPE_LABELS = {
42
+ VXSE43: "緊急地震速報(警報)",
43
+ VXSE44: "緊急地震速報(予報)",
44
+ VXSE45: "緊急地震速報(地震動予報)",
45
+ VXSE51: "震度速報",
46
+ VXSE52: "震源に関する情報",
47
+ VXSE53: "震源・震度に関する情報",
48
+ VXSE56: "地震の活動状況等に関する情報",
49
+ VXSE60: "地震解説",
50
+ VXSE61: "顕著な地震の震度速報",
51
+ VXSE62: "長周期地震動に関する観測情報",
52
+ VZSE40: "地震回数に関する情報",
53
+ VTSE41: "津波警報・注意報・予報",
54
+ VTSE51: "津波情報",
55
+ VTSE52: "沖合の津波観測に関する情報",
56
+ VYSE50: "南海トラフ地震臨時情報",
57
+ VYSE51: "南海トラフ地震関連解説情報(臨時)",
58
+ VYSE52: "南海トラフ地震関連解説情報(定例)",
59
+ VYSE60: "南海トラフ地震関連解説情報(経過)",
60
+ VFVO50: "噴火警報・予報",
61
+ VFVO51: "火山の状況に関する解説情報",
62
+ VFVO52: "噴火に関する火山観測報",
63
+ VFVO53: "降灰予報(定時)",
64
+ VFVO54: "降灰予報(速報)",
65
+ VFVO55: "降灰予報(詳細)",
66
+ VFVO56: "噴火速報",
67
+ VFVO60: "推定噴煙流向報",
68
+ VFSVii: "火山現象に関する海上警報",
69
+ VZVO40: "火山に関するお知らせ",
70
+ };
71
+ const CATEGORY_LABELS = {
72
+ eew: "EEW",
73
+ earthquake: "地震",
74
+ tsunami: "津波",
75
+ volcano: "火山",
76
+ nankaiTrough: "南海トラフ",
77
+ other: "その他",
78
+ };
79
+ const CATEGORY_ROLE = {
80
+ eew: "statsCategoryEew",
81
+ earthquake: "statsCategoryEarthquake",
82
+ tsunami: "statsCategoryTsunami",
83
+ volcano: "statsCategoryVolcano",
84
+ nankaiTrough: "statsCategoryNankaiTrough",
85
+ other: "statsCategoryOther",
86
+ };
87
+ const CATEGORY_ORDER = [
88
+ "eew",
89
+ "earthquake",
90
+ "tsunami",
91
+ "volcano",
92
+ "nankaiTrough",
93
+ "other",
94
+ ];
95
+ const INTENSITY_ORDER = ["1", "2", "3", "4", "5-", "5+", "6-", "6+", "7"];
96
+ const FRAME_LEVEL = "info";
97
+ // ── chalk ショートカット ──
98
+ function muted(s) {
99
+ return theme.getRoleChalk("statsMuted")(s);
100
+ }
101
+ function count(s) {
102
+ return theme.getRoleChalk("statsCount")(s);
103
+ }
104
+ // ── 公開関数 ──
105
+ /** 経過時間をミリ秒から日本語の文字列に変換する */
106
+ function formatStatsDuration(ms) {
107
+ const totalMinutes = Math.floor(ms / (60 * 1000));
108
+ const totalHours = Math.floor(totalMinutes / 60);
109
+ const totalDays = Math.floor(totalHours / 24);
110
+ if (totalDays >= 1) {
111
+ const remainHours = totalHours - totalDays * 24;
112
+ if (remainHours === 0)
113
+ return `${totalDays}日`;
114
+ return `${totalDays}日${remainHours}時間`;
115
+ }
116
+ if (totalHours >= 1) {
117
+ const remainMinutes = totalMinutes - totalHours * 60;
118
+ if (remainMinutes === 0)
119
+ return `${totalHours}時間`;
120
+ return `${totalHours}時間${remainMinutes}分`;
121
+ }
122
+ return `${totalMinutes}分`;
123
+ }
124
+ /** 電文受信統計をフレームボックス形式で標準出力に表示する */
125
+ function displayStatistics(snapshot, now) {
126
+ const effectiveNow = now ?? new Date();
127
+ const elapsedMs = effectiveNow.getTime() - snapshot.startTime.getTime();
128
+ if (snapshot.totalCount === 0) {
129
+ const title = "統計";
130
+ const msg = muted("まだ電文を受信していません");
131
+ const width = calcWidth([title, msg]);
132
+ console.log((0, formatter_1.frameTop)(FRAME_LEVEL, width));
133
+ console.log((0, formatter_1.frameLine)(FRAME_LEVEL, title, width));
134
+ console.log((0, formatter_1.frameLine)(FRAME_LEVEL, msg, width));
135
+ console.log((0, formatter_1.frameBottom)(FRAME_LEVEL, width));
136
+ return;
137
+ }
138
+ // カテゴリ別に headType を分類
139
+ const typesByCategory = new Map();
140
+ for (const [headType, category] of snapshot.categoryByType) {
141
+ if (!typesByCategory.has(category)) {
142
+ typesByCategory.set(category, []);
143
+ }
144
+ typesByCategory.get(category).push(headType);
145
+ }
146
+ // 表示するカテゴリ(件数 > 0 のもの)
147
+ const activeCategories = CATEGORY_ORDER.filter((cat) => (typesByCategory.get(cat)?.some((t) => (snapshot.countByType.get(t) ?? 0) > 0)) ?? false);
148
+ // 最大カウント値を取得してカウント列の幅を決定
149
+ let maxCount = 0;
150
+ for (const count of snapshot.countByType.values()) {
151
+ if (count > maxCount)
152
+ maxCount = count;
153
+ }
154
+ const countWidth = Math.max(4, String(maxCount).length);
155
+ // 全コンテンツ行を収集してフレーム幅を動的計算
156
+ const allContentLines = buildAllContentLines(snapshot, activeCategories, typesByCategory, elapsedMs, countWidth);
157
+ const width = calcWidth(["統計", ...allContentLines]);
158
+ // 出力
159
+ console.log((0, formatter_1.frameTop)(FRAME_LEVEL, width));
160
+ console.log((0, formatter_1.frameLine)(FRAME_LEVEL, "統計", width));
161
+ for (const line of allContentLines) {
162
+ if (line === "__DIVIDER__") {
163
+ console.log((0, formatter_1.frameDivider)(FRAME_LEVEL, width));
164
+ }
165
+ else {
166
+ console.log((0, formatter_1.frameLine)(FRAME_LEVEL, line, width));
167
+ }
168
+ }
169
+ console.log((0, formatter_1.frameBottom)(FRAME_LEVEL, width));
170
+ }
171
+ // ── 内部ヘルパー ──
172
+ /** フレーム幅をコンテンツ行の最大幅から計算する (最小40、最大200) */
173
+ function calcWidth(contentLines) {
174
+ let maxContentWidth = 0;
175
+ for (const line of contentLines) {
176
+ if (line === "__DIVIDER__")
177
+ continue;
178
+ const w = (0, formatter_1.visualWidth)(line);
179
+ if (w > maxContentWidth)
180
+ maxContentWidth = w;
181
+ }
182
+ // frameLine adds 4 chars overhead (│ + space + space + │)
183
+ return Math.max(40, Math.min(200, maxContentWidth + 4));
184
+ }
185
+ /** 最大震度内訳行を構築する(色付き) */
186
+ function buildIntBreakdownLine(earthquakeMaxIntByEvent) {
187
+ const intCounts = new Map();
188
+ for (const maxInt of earthquakeMaxIntByEvent.values()) {
189
+ intCounts.set(maxInt, (intCounts.get(maxInt) ?? 0) + 1);
190
+ }
191
+ const parts = [];
192
+ for (const intensity of INTENSITY_ORDER) {
193
+ const cnt = intCounts.get(intensity);
194
+ if (cnt != null && cnt > 0) {
195
+ const intStyle = (0, formatter_1.intensityColor)(intensity);
196
+ parts.push(`${intStyle(intensity)}${muted(":")}${cnt}`);
197
+ }
198
+ }
199
+ return ` ${muted("最大震度内訳")} ${parts.join(" ")}`;
200
+ }
201
+ /** 全コンテンツ行を構築する (__DIVIDER__ はフレーム区切り線のセンチネル) */
202
+ function buildAllContentLines(snapshot, activeCategories, typesByCategory, elapsedMs, countWidth) {
203
+ const lines = [];
204
+ // ヘッダー行
205
+ const startStr = snapshot.startTime.toLocaleString("ja-JP", {
206
+ year: "numeric",
207
+ month: "2-digit",
208
+ day: "2-digit",
209
+ hour: "2-digit",
210
+ minute: "2-digit",
211
+ });
212
+ lines.push(`${muted("開始:")} ${startStr} ${muted("経過:")} ${formatStatsDuration(elapsedMs)} ${muted("合計:")} ${count(String(snapshot.totalCount))}件`);
213
+ // カテゴリセクション
214
+ for (const category of activeCategories) {
215
+ lines.push("__DIVIDER__");
216
+ // カテゴリヘッダー
217
+ const types = typesByCategory.get(category) ?? [];
218
+ const categoryCount = types.reduce((sum, t) => sum + (snapshot.countByType.get(t) ?? 0), 0);
219
+ const catLabel = CATEGORY_LABELS[category];
220
+ const catStyle = theme.getRoleChalk(CATEGORY_ROLE[category]);
221
+ let catHeader;
222
+ if (category === "eew") {
223
+ catHeader = `${catStyle(`[${catLabel}]`)} ${count(String(categoryCount))}件 / ${count(String(snapshot.eewEventCount))}イベント`;
224
+ }
225
+ else {
226
+ catHeader = `${catStyle(`[${catLabel}]`)} ${count(String(categoryCount))}件`;
227
+ }
228
+ lines.push(catHeader);
229
+ // タイプ行
230
+ // タイプ列の幅を揃えるため最長タイプ名を求める
231
+ let maxTypeWidth = 0;
232
+ for (const headType of types) {
233
+ if ((0, formatter_1.visualWidth)(headType) > maxTypeWidth)
234
+ maxTypeWidth = (0, formatter_1.visualWidth)(headType);
235
+ }
236
+ let maxLabelWidth = 0;
237
+ for (const headType of types) {
238
+ const label = TYPE_LABELS[headType] ?? headType;
239
+ if ((0, formatter_1.visualWidth)(label) > maxLabelWidth)
240
+ maxLabelWidth = (0, formatter_1.visualWidth)(label);
241
+ }
242
+ for (const headType of types) {
243
+ const cnt = snapshot.countByType.get(headType) ?? 0;
244
+ if (cnt === 0)
245
+ continue;
246
+ const label = TYPE_LABELS[headType] ?? headType;
247
+ const typePad = " ".repeat(Math.max(0, maxTypeWidth - (0, formatter_1.visualWidth)(headType)));
248
+ const labelPad = " ".repeat(Math.max(0, maxLabelWidth - (0, formatter_1.visualWidth)(label)));
249
+ const countStr = String(cnt).padStart(countWidth);
250
+ lines.push(` ${muted(headType)}${typePad} ${label}${labelPad} ${muted(":")} ${count(countStr)}`);
251
+ }
252
+ // 地震カテゴリの場合は最大震度内訳を追加
253
+ if (category === "earthquake" && snapshot.earthquakeMaxIntByEvent.size > 0) {
254
+ lines.push(buildIntBreakdownLine(snapshot.earthquakeMaxIntByEvent));
255
+ }
256
+ }
257
+ return lines;
258
+ }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StatusLine = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const formatter_1 = require("../ui/formatter");
9
+ /** 現在時刻を HH:mm:ss 形式で返す */
10
+ function formatCurrentTime() {
11
+ const now = new Date();
12
+ const pad = (n) => String(n).padStart(2, "0");
13
+ return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
14
+ }
15
+ class StatusLine {
16
+ pulseOn = true;
17
+ connectedAt = null;
18
+ lastMessageTime = null;
19
+ clockMode = "elapsed";
20
+ tick() {
21
+ this.pulseOn = !this.pulseOn;
22
+ }
23
+ setConnected(connected) {
24
+ if (connected) {
25
+ this.connectedAt = Date.now();
26
+ this.lastMessageTime = null;
27
+ }
28
+ else {
29
+ this.connectedAt = null;
30
+ this.lastMessageTime = null;
31
+ }
32
+ }
33
+ markMessageReceived() {
34
+ this.lastMessageTime = Date.now();
35
+ }
36
+ setClockMode(mode) {
37
+ this.clockMode = mode;
38
+ }
39
+ getClockMode() {
40
+ return this.clockMode;
41
+ }
42
+ /**
43
+ * プロンプト用プレフィックスを生成する。
44
+ * @param options.noSuffix true のときは末尾の "]> " を付与しない
45
+ */
46
+ buildPrefix(options) {
47
+ const suffix = options?.noSuffix ? "" : chalk_1.default.gray("]> ");
48
+ // uptime モードは接続状態に依存しない
49
+ if (this.clockMode === "uptime") {
50
+ const dot = this.connectedAt == null
51
+ ? chalk_1.default.gray("○")
52
+ : this.pulseOn ? chalk_1.default.cyan("●") : chalk_1.default.gray("○");
53
+ return (chalk_1.default.gray("FlEq [") +
54
+ dot +
55
+ chalk_1.default.gray(" ") +
56
+ (0, formatter_1.formatUptime)(process.uptime() * 1000) +
57
+ suffix);
58
+ }
59
+ if (this.connectedAt == null) {
60
+ return (chalk_1.default.gray("FlEq [") + chalk_1.default.gray("○ --:--:--") + suffix);
61
+ }
62
+ const dot = this.pulseOn ? chalk_1.default.cyan("●") : chalk_1.default.gray("○");
63
+ const timeStr = this.clockMode === "clock"
64
+ ? formatCurrentTime()
65
+ : (0, formatter_1.formatElapsedTime)(Date.now() - (this.lastMessageTime ?? this.connectedAt));
66
+ return (chalk_1.default.gray("FlEq [") +
67
+ dot +
68
+ chalk_1.default.gray(" ") +
69
+ chalk_1.default.white(timeStr) +
70
+ suffix);
71
+ }
72
+ getLastMessageTime() {
73
+ return this.lastMessageTime;
74
+ }
75
+ /** プロンプト経過時間の基準時刻を返す (lastMessageTime ?? connectedAt) */
76
+ getElapsedBase() {
77
+ return this.lastMessageTime ?? this.connectedAt;
78
+ }
79
+ }
80
+ exports.StatusLine = StatusLine;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderSummaryLine = void 0;
4
+ var summary_line_1 = require("./summary-line");
5
+ Object.defineProperty(exports, "renderSummaryLine", { enumerable: true, get: function () { return summary_line_1.renderSummaryLine; } });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderSummaryLine = renderSummaryLine;
4
+ const summary_model_1 = require("./summary-model");
5
+ const token_builders_1 = require("./token-builders");
6
+ const width_fit_1 = require("./width-fit");
7
+ /**
8
+ * PresentationEvent → 幅適応1行文字列を生成する。
9
+ * @param event PresentationEvent
10
+ * @param maxWidth 最大幅(デフォルト: ターミナル幅)
11
+ * @returns 着色済み1行文字列
12
+ */
13
+ function renderSummaryLine(event, maxWidth) {
14
+ const width = maxWidth ?? (process.stdout.columns || 80);
15
+ const model = (0, summary_model_1.buildSummaryModel)(event);
16
+ const tokens = (0, token_builders_1.buildSummaryTokens)(event, model);
17
+ return (0, width_fit_1.fitTokensToWidth)(tokens, width);
18
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSummaryModel = buildSummaryModel;
4
+ const SEVERITY_MAP = {
5
+ critical: "[緊急]",
6
+ warning: "[警告]",
7
+ normal: "[情報]",
8
+ info: "[通知]",
9
+ cancel: "[取消]",
10
+ };
11
+ function buildSummaryModel(event) {
12
+ const severity = SEVERITY_MAP[event.frameLevel];
13
+ const areaNames = event.areaNames.length > 0
14
+ ? event.areaNames
15
+ : event.forecastAreaNames.length > 0
16
+ ? event.forecastAreaNames
17
+ : undefined;
18
+ return {
19
+ domain: event.domain,
20
+ severity,
21
+ title: event.title,
22
+ location: event.hypocenterName ?? event.volcanoName ?? undefined,
23
+ magnitude: event.magnitude ? `M${event.magnitude}` : undefined,
24
+ maxInt: event.maxInt ? `震度${event.maxInt}` : undefined,
25
+ maxLgInt: event.maxLgInt ? `長周期${event.maxLgInt}` : undefined,
26
+ headline: event.headline ?? undefined,
27
+ volcanoName: event.volcanoName ?? undefined,
28
+ serial: event.serial ? `#${event.serial}` : undefined,
29
+ areaNames,
30
+ };
31
+ }