From 58d17dc1bbfc642cce66ec71bf76ab5255e7284d Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 19:19:07 +0900 Subject: [PATCH 01/14] docs: add README.md --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13420b29..e1c318fb 100644 --- a/README.md +++ b/README.md @@ -1 +1,70 @@ -# javascript-calculator-precourse \ No newline at end of file +# javascript-calculator-precourse + +# ๐Ÿงฎ ๋ฌธ์ž์—ด ๋ง์…ˆ ๊ณ„์‚ฐ๊ธฐ + +## ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก + +> ๊ฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค AngularJS ์ปค๋ฐ‹ ์ปจ๋ฒค์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปค๋ฐ‹. +> ์ปค๋ฐ‹ ๋‹จ์œ„๋Š” โ€œํ•œ ๊ธฐ๋Šฅ = ํ•œ ์ปค๋ฐ‹โ€ + +--- + +### 1. ์ž…๋ ฅ ์•ˆ๋‚ด ์ถœ๋ ฅ + +- [x] `Console.print('๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.')` ์ถœ๋ ฅ + +--- + +### 2. ๋ฌธ์ž์—ด ์ž…๋ ฅ ๋ฐ›๊ธฐ + +- [x] `Console.readLineAsync()`๋กœ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฌธ์ž์—ด ํ•œ ์ค„์„ ์ž…๋ ฅ๋ฐ›์Œ + +--- + +### 3. ๋นˆ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ + +- [x] ๋นˆ ๋ฌธ์ž์—ด(`""` ๋˜๋Š” ๊ณต๋ฐฑ๋งŒ ํฌํ•จ) ์ž…๋ ฅ ์‹œ ๊ฒฐ๊ณผ `0` ๋ฐ˜ํ™˜ + +--- + +### 4. ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž ํŒŒ์‹ฑ + +- [x] ์ž…๋ ฅ ๋ฌธ์ž์—ด์ด "//"๋กœ ์‹œ์ž‘ํ•˜๊ณ  "\n"์„ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ, "//"์™€ "\n" ์‚ฌ์ด์— ์žˆ๋Š” ๋ฌธ์ž๋ฅผ ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๋กœ ์‚ฌ์šฉ +- [x] ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ๊ตฌ๋ถ„์ž `,`์™€ `:` ์‚ฌ์šฉ + +--- + +### 5. ์ˆซ์ž ๋ถ„๋ฆฌ ๋กœ์ง + +- [x] ๊ตฌ๋ถ„์ž(๊ธฐ๋ณธ/์ปค์Šคํ…€)๋กœ ๋ฌธ์ž์—ด์„ ๋‚˜๋ˆ„์–ด ๊ฐ ์ˆซ์ž๋ฅผ ์–ป๊ธฐ +- [x] ๊ฐ ์ˆซ์ž ์•ž๋’ค ๊ณต๋ฐฑ(`trim()`) ์ œ๊ฑฐ + +--- + +### 6. ์œ ํšจ์„ฑ ๊ฒ€์ฆ + +- [x] ๋ถ„๋ฆฌ๋œ ๋ชจ๋“  ๊ฐ’์ด ์ •์ˆ˜ ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด์ธ์ง€ ํ™•์ธ +- [x] ์–‘์˜ ์ •์ˆ˜๋งŒ ํ—ˆ์šฉ (0 ๋ฐ ์Œ์ˆ˜ ๊ธˆ์ง€) +- [x] ์—ฐ์† ๊ตฌ๋ถ„์ž(`"1,,2"`, `"1:"`) ๋“ฑ ์ž˜๋ชป๋œ ํ˜•์‹์˜ ์ž…๋ ฅ์„ ํ™•์ธ +- [x] ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ `[ERROR]`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ `Error` ๋ฐœ์ƒ์‹œํ‚จ ํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ข…๋ฃŒ + +--- + +### 7. ํ•ฉ๊ณ„ ๊ณ„์‚ฐ + +- [x] ๊ฒ€์ฆ ํ†ต๊ณผํ•œ ์ •์ˆ˜๋“ค์„ ํ•ฉ์‚ฐํ•˜์—ฌ `Number`๋กœ ๋ฐ˜ํ™˜ + +--- + +### 8. ์ถœ๋ ฅ ํ˜•์‹ ์ค€์ˆ˜ + +- [x] ๊ฒฐ๊ณผ ์ถœ๋ ฅ ์‹œ ํ˜•์‹์„ ์ •ํ™•ํžˆ ๋งž์ถค +- [x] ๊ณต๋ฐฑ ๋ฐ ์ฝœ๋ก (`:`) ์œ„์น˜ ์ •ํ™•ํžˆ ์œ ์ง€ + +--- + +### 9. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐ ์ข…๋ฃŒ ํ๋ฆ„ + +- [x] `run()` ๋‚ด๋ถ€์—์„œ ์˜ค๋ฅ˜๋ฅผ `try/catch`๋กœ ์ฒ˜๋ฆฌ +- [x] `[ERROR]` ๋ฉ”์‹œ์ง€๋ฅผ `Console.print()`๋กœ ์ถœ๋ ฅ +- [x] `process.exit()` ํ˜ธ์ถœ ์—†์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ข…๋ฃŒ From ab6d630443f2631a27d5750b6ebdcbae92964560 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 19:25:47 +0900 Subject: [PATCH 02/14] feat(app): print input prompt using mission-utils Console --- src/App.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5..2d820d55 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,8 @@ class App { - async run() {} + async run() { + const { Console } = await import("@woowacourse/mission-utils"); + Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + } } export default App; From b7354bc7ba54263476badcc84f6ce88b2eaba494 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 19:26:47 +0900 Subject: [PATCH 03/14] chore: add custom type declarations for @woowacourse/mission-utils --- types/woowacourse__mission-utils.d.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 types/woowacourse__mission-utils.d.ts diff --git a/types/woowacourse__mission-utils.d.ts b/types/woowacourse__mission-utils.d.ts new file mode 100644 index 00000000..00574645 --- /dev/null +++ b/types/woowacourse__mission-utils.d.ts @@ -0,0 +1,6 @@ +declare module "@woowacourse/mission-utils" { + export const Console: { + readLineAsync(prompt?: string): Promise; + print(message: string): void; + }; +} From d60a9c74586f3c8809cfce2bd0a76d7541ffcb51 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 19:30:06 +0900 Subject: [PATCH 04/14] feat(app): read user input from console --- src/App.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/App.js b/src/App.js index 2d820d55..091e0ee0 100644 --- a/src/App.js +++ b/src/App.js @@ -2,6 +2,8 @@ class App { async run() { const { Console } = await import("@woowacourse/mission-utils"); Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + + const input = await Console.readLineAsync(); } } From 568594dc67295757ff3ff9fc30ec461ea9b4a55e Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 20:50:25 +0900 Subject: [PATCH 05/14] feat(calculator): implement add function to handle input and return sum --- src/App.js | 2 ++ src/StringCalculator.js | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 src/StringCalculator.js diff --git a/src/App.js b/src/App.js index 091e0ee0..25cf6783 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,8 @@ class App { Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); const input = await Console.readLineAsync(); + + const result = add(input); } } diff --git a/src/StringCalculator.js b/src/StringCalculator.js new file mode 100644 index 00000000..de2520bb --- /dev/null +++ b/src/StringCalculator.js @@ -0,0 +1,4 @@ +export function add(input) { + const trimmed = (input ?? "").trim(); + if (trimmed === "") return 0; +} From f030549a9bab4709333d8dca91b3ca8e63847f92 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 21:23:33 +0900 Subject: [PATCH 06/14] feat(calculator): add support for custom delimiters in input parsing --- src/StringCalculator.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/StringCalculator.js b/src/StringCalculator.js index de2520bb..39e5302e 100644 --- a/src/StringCalculator.js +++ b/src/StringCalculator.js @@ -1,4 +1,27 @@ +const DEFAULT_DELIMS = [",", ":"]; + +function parseDelimiterAndBody(input) { + if (input.startsWith("//")) { + const idx = input.indexOf("\n"); + if (idx === -1) { + throw new Error("[ERROR] ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž ๋’ค์— ์ค„๋ฐ”๊ฟˆ(\\n)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค."); + } + const delim = input.slice(2, idx); + if (!delim || delim.length !== 1) { + throw new Error( + "[ERROR] ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๋Š” '//'์™€ '\\n' ์‚ฌ์ด์˜ ๋ฌธ์ž 1๊ฐœ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." + ); + } + // ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๊ฐ€ ์กด์žฌํ•  ๋•Œ + return { delims: [delim], body: input.slice(idx + 1) }; + } + // ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๊ฐ€ ์—†์„ ๋•Œ + return { delims: DEFAULT_DELIMS, body: input }; +} + export function add(input) { const trimmed = (input ?? "").trim(); if (trimmed === "") return 0; + + const { delims, body } = parseDelimiterAndBody(trimmed); } From db773d92ba7acf35374948253c8dae481837b880 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 21:47:43 +0900 Subject: [PATCH 07/14] feat(calculator): implement token splitting for input parsing with custom delimiters --- src/StringCalculator.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/StringCalculator.js b/src/StringCalculator.js index 39e5302e..f2873e28 100644 --- a/src/StringCalculator.js +++ b/src/StringCalculator.js @@ -1,5 +1,9 @@ const DEFAULT_DELIMS = [",", ":"]; +function escapeRegexChar(ch) { + return ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + function parseDelimiterAndBody(input) { if (input.startsWith("//")) { const idx = input.indexOf("\n"); @@ -19,9 +23,19 @@ function parseDelimiterAndBody(input) { return { delims: DEFAULT_DELIMS, body: input }; } +function splitTokens(body, delims) { + if (body === "") return []; + const escaped = delims.map(escapeRegexChar).join(""); + const re = new RegExp(`[${escaped}]`, "g"); + const raw = body.split(re).map((t) => t.trim()); + return raw; +} + export function add(input) { const trimmed = (input ?? "").trim(); if (trimmed === "") return 0; const { delims, body } = parseDelimiterAndBody(trimmed); + + const tokens = splitTokens(body, delims); } From f80da9318a144ef0463baac511d2aeeae2441f16 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 22:08:00 +0900 Subject: [PATCH 08/14] feat(calculator): add validation for token splitting and convert tokens to positive integers --- src/StringCalculator.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/StringCalculator.js b/src/StringCalculator.js index f2873e28..a0cff4d3 100644 --- a/src/StringCalculator.js +++ b/src/StringCalculator.js @@ -28,9 +28,29 @@ function splitTokens(body, delims) { const escaped = delims.map(escapeRegexChar).join(""); const re = new RegExp(`[${escaped}]`, "g"); const raw = body.split(re).map((t) => t.trim()); + + // split์œผ๋กœ ๋‚˜๋ˆˆ ๊ฒฐ๊ณผ๊ฐ€ ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌ + if (raw.some((t) => t === "")) { + throw new Error("[ERROR] ๊ตฌ๋ถ„์ž ์‚ฌ์ด์— ์ˆซ์ž๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค."); + } return raw; } +function toPositiveIntegers(tokens) { + return tokens.map((t) => { + // ์ •๊ทœ์‹ ๊ฒ€์‚ฌ + if (!/^\d+$/.test(t)) { + throw new Error("[ERROR] ์ˆซ์ž ์ด์™ธ์˜ ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + } + // ์ˆซ์ž ๋ณ€ํ™˜ ๋ฐ ์Œ์ˆ˜/0 ๊ฒ€์‚ฌ + const num = Number(t); + if (num <= 0) { + throw new Error("[ERROR] 0 ๋˜๋Š” ์Œ์ˆ˜๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + return num; + }); +} + export function add(input) { const trimmed = (input ?? "").trim(); if (trimmed === "") return 0; @@ -38,4 +58,6 @@ export function add(input) { const { delims, body } = parseDelimiterAndBody(trimmed); const tokens = splitTokens(body, delims); + + const numbers = toPositiveIntegers(tokens); } From 0a1790d9b712fa4000b933ad7597d24366b2933f Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 22:11:49 +0900 Subject: [PATCH 09/14] feat(calculator): calculate sum of positive integers from split strings --- src/StringCalculator.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/StringCalculator.js b/src/StringCalculator.js index a0cff4d3..2f950c49 100644 --- a/src/StringCalculator.js +++ b/src/StringCalculator.js @@ -60,4 +60,9 @@ export function add(input) { const tokens = splitTokens(body, delims); const numbers = toPositiveIntegers(tokens); + + // ํ•ฉ์‚ฐ + return numbers.reduce((acc, n) => acc + n, 0); + + r; } From ba191bd2cea295c9b2b08f56e1e95c3bd907739c Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 22:14:17 +0900 Subject: [PATCH 10/14] feat(app): display calculation result in console output --- src/App.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/App.js b/src/App.js index 25cf6783..bb968053 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,8 @@ class App { const input = await Console.readLineAsync(); const result = add(input); + + Console.print(`๊ฒฐ๊ณผ : ${result}`); } } From a51252afe87dac4b089570ec941ed8695a79d466 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 22:38:50 +0900 Subject: [PATCH 11/14] feat(app): add error handling for user input in console --- src/App.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index bb968053..bec89bb3 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,21 @@ class App { async run() { - const { Console } = await import("@woowacourse/mission-utils"); - Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + // ์˜ˆ์™ธ ์ฒ˜๋ฆฌ + try { + const { Console } = await import("@woowacourse/mission-utils"); + Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); - const input = await Console.readLineAsync(); + const input = await Console.readLineAsync(); - const result = add(input); + const result = add(input); - Console.print(`๊ฒฐ๊ณผ : ${result}`); + Console.print(`๊ฒฐ๊ณผ : ${result}`); + } catch (error) { + const { Console } = await import("@woowacourse/mission-utils"); + const message = + error?.message ?? "[ERROR] ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."; + Console.print(message); + } } } From 0bdb072685b51280d144273fe9e878b53f4bcf36 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 22:44:40 +0900 Subject: [PATCH 12/14] refactor(app): simplify Console import and improve error handling --- src/App.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/App.js b/src/App.js index bec89bb3..eaeb3e10 100644 --- a/src/App.js +++ b/src/App.js @@ -1,20 +1,20 @@ +import { Console } from "@woowacourse/mission-utils"; +import { add } from "./StringCalculator"; class App { async run() { + Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + // ์˜ˆ์™ธ ์ฒ˜๋ฆฌ try { - const { Console } = await import("@woowacourse/mission-utils"); - Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); - const input = await Console.readLineAsync(); - const result = add(input); - Console.print(`๊ฒฐ๊ณผ : ${result}`); } catch (error) { - const { Console } = await import("@woowacourse/mission-utils"); const message = error?.message ?? "[ERROR] ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."; Console.print(message); + + throw error; } } } From 8bc9ca55770cfda639922d3990a0b6a7ea8a7d0d Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 23:05:04 +0900 Subject: [PATCH 13/14] fix(calculator): properly parse custom delimiters containing newline characters --- src/StringCalculator.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/StringCalculator.js b/src/StringCalculator.js index 2f950c49..b1fa3406 100644 --- a/src/StringCalculator.js +++ b/src/StringCalculator.js @@ -6,7 +6,19 @@ function escapeRegexChar(ch) { function parseDelimiterAndBody(input) { if (input.startsWith("//")) { - const idx = input.indexOf("\n"); + const realNewlineIdx = input.indexOf("\n"); + const literalNewlineIdx = input.indexOf("\\n"); + + let idx = -1; + let useLiteral = false; + + if (realNewlineIdx !== -1) { + idx = realNewlineIdx; + } else if (literalNewlineIdx !== -1) { + idx = literalNewlineIdx; + useLiteral = true; + } + if (idx === -1) { throw new Error("[ERROR] ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž ๋’ค์— ์ค„๋ฐ”๊ฟˆ(\\n)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค."); } @@ -16,8 +28,11 @@ function parseDelimiterAndBody(input) { "[ERROR] ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๋Š” '//'์™€ '\\n' ์‚ฌ์ด์˜ ๋ฌธ์ž 1๊ฐœ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." ); } + + const body = useLiteral ? input.slice(idx + 2) : input.slice(idx + 1); + // ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๊ฐ€ ์กด์žฌํ•  ๋•Œ - return { delims: [delim], body: input.slice(idx + 1) }; + return { delims: [delim], body }; } // ์ปค์Šคํ…€ ๊ตฌ๋ถ„์ž๊ฐ€ ์—†์„ ๋•Œ return { delims: DEFAULT_DELIMS, body: input }; @@ -63,6 +78,4 @@ export function add(input) { // ํ•ฉ์‚ฐ return numbers.reduce((acc, n) => acc + n, 0); - - r; } From ee70eb3cb35524fac643509dffb5037b334806a1 Mon Sep 17 00:00:00 2001 From: Youna Joo Date: Mon, 20 Oct 2025 23:07:20 +0900 Subject: [PATCH 14/14] fix(app): fix console input error caused by missing prompt argument --- src/App.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/App.js b/src/App.js index eaeb3e10..4aec972d 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,10 @@ import { Console } from "@woowacourse/mission-utils"; -import { add } from "./StringCalculator"; +import { add } from "./StringCalculator.js"; class App { async run() { Console.print("๋ง์…ˆํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); - - // ์˜ˆ์™ธ ์ฒ˜๋ฆฌ try { - const input = await Console.readLineAsync(); + const input = await Console.readLineAsync(""); const result = add(input); Console.print(`๊ฒฐ๊ณผ : ${result}`); } catch (error) {