ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ช‡~~~~~๋‹ฌ ์ „์— ๋งŒ๋“ค์—ˆ๋˜ ๋…ธ๋งˆ๋“œ ์ฝ”๋”์˜ ํฌ๋กฌ ์•ฑ ๋งŒ๋“ค๊ธฐ๋ฅผ ์ด์ œ์•ผ ์˜ฌ๋ฆฐ๋‹ค^^..ใ…œใ…œ

์–ผ๋ฅธ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋„ ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๊ณ  ์ •์ฒ˜๊ธฐ ๊ณต๋ถ€๋„ ํ•ด์•ผํ–ˆ์–ด์„œ ์ •๋ฆฌํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ๋‹ค.

 

 

ํฌ๋กฌ ์•ฑ ๋งŒ๋“ค๊ธฐ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

โ—พ ์‹ค์‹œ๊ฐ„ ์‹œ๊ฐ„ ํ™•์ธํ•˜๊ธฐ

โ—พ ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๋ฉด Local Storage์— ์ €์žฅ๋˜๊ณ  ๊ธฐ์–ต

โ—พ ํ•  ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ / ์‚ญ์ œํ•˜๊ธฐ

โ—พ ์œ„์น˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์„œ ์ง€์—ญ๊ณผ ์˜จ๋„ ํ™•์ธํ•˜๊ธฐ

โ—พ ์ƒˆ๋กœ ๊ณ ์นจ ์‹œ, ๋ฐฐ๊ฒฝํ™”๋ฉด๊ณผ ๋ช…์–ธ ๋žœ๋ค ๋ณ€๊ฒฝํ•˜๊ธฐ

 


๋””๋ ‰ํ„ฐ๋ฆฌ ์„ค์ •

- css

- img

- js
  - background.js 
  - clock.js
  - greetings.js
  - quotes.js

  - todo.js

  - weather.js

- index.html

 

 

 

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <title>Hello! From JS!</title>
</head>

<body>

    <h3 id="clock">00:00:00</h3>
    <h2 id="calendar">00/00/0</h2>
    <form id="login-form" class="hidden">
        <input required maxlength="15" type="text" placeholder="What is your name?">
        <!--<input type="submit" value="Log In" />  submit์€ ์—”ํ„ฐ/๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ฐœ์ƒํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์žฌ์‹œ์ž‘๋œ๋‹ค. -->
    </form>

    <h1 id="greeting" class="hidden"></h1>
    <form id="todo-form">
        <input type="text" placeholder="Write a To Do here" required />
    </form>
    <ul id="todo-list"></ul>
    <div id="quote">
        <span></span>
        <span></span>
    </div>
    <div id="weather">
        <span></span>
        <span></span>
    </div>
    <script src="js/greetings.js"></script>
    <script src="js/clock.js"></script>
    <script src="js/quotes.js"></script>
    <script src="js/background.js"></script>
    <script src="js/todo.js"></script>
    <script src="js/weather.js"></script>
</body>

</html>

 

style.css

body {
    text-align: center;
    color: white;
    background-position:center;
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}

h3 {
    font-size: 80px;
    text-align: center;
    color: white;
    margin-bottom: auto;
}

h2 {
    margin-top: auto;
    color: white;
}
h1 {
    color: white;  
}
.hidden {
    display: none;
}

#login-form input {
    font-size: 20px;
    margin-bottom: 20px;
}

#todo-form input {
    font-size: 17px;;
}
input {
    border: none;
    border-bottom: 2px solid white;
    background: transparent;
    color: white;
    text-align: center;
}

input::placeholder {
    color: white;
  }

li {
      
    list-style: none;
  }

button {
    background: transparent;
    border: none;
  }

  #quote {
    position: absolute;
    bottom: 0;
    left: 0;
    font-size: 13px;
    font-style: italic;
  }

  #weather {
    position: absolute;
    top: 15px;
    width: 130px;
  }
img {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0px;
    top: 0px;
    right: 0px;
    bottom: 0px;
    z-index: -1;
    opacity: 80%;
    filter: brightness(70%);
}

 

 

background.js

const images = [
  "0.jpg",
  "1.jpg",
  "2.jpg",
  "3.jpg",
  "4.jpg",
  "5.jpg",
  "6.jpg",
  "7.jpg",
  "8.jpg",
  "9.jpg",
  "10.jpg",
];

const chosenImage = images[Math.floor(Math.random() * images.length)];

const bgImage = document.createElement("img");

bgImage.src = `img/${chosenImage}`;

document.body.appendChild(bgImage); // body์˜ ๋งจ ๋’ค์— ๋„ฃ๋Š”๋‹ค.

/* 
appendChild : ๋งจ ๋’ค์— ์ถ”๊ฐ€
prependChild : ๋งจ ์•ž์— ์ถ”๊ฐ€
*/

 

์ด๋ฏธ์ง€๊ฐ€ ์ƒˆ๊ณ ๋กœ์นจ์ด ๋  ๋•Œ๋งˆ๋‹ค ๋žœ๋ค์œผ๋กœ ์ถœ๋ ฅ๋˜๋„๋ก ํ•œ๋‹ค.

 

 

clock.js

const calendar = document.querySelector("h2#calendar");
const clock = document.querySelector("h3#clock");

function getClock() {
  const dateDefine = new Date();
  const year = dateDefine.getFullYear();
  const month = String(dateDefine.getMonth() + 1).padStart(2, "0");
  const date = String(dateDefine.getDate()).padStart(2, "0");
  const hours = String(dateDefine.getHours()).padStart(2, "0");
  const minutes = String(dateDefine.getMinutes()).padStart(2, "0");
  //const seconds = String(dateDefine.getSeconds()).padStart(2, "0");
  calendar.innerText = `${year}.${month}.${date}`;
  clock.innerText = `${hours}:${minutes}`;
}

//setInterval(sayHello, 5000); 5์ดˆ ํ›„ ๋งˆ๋‹ค ํ•จ์ˆ˜ ์‹คํ–‰
//setTimeout(getClock, 1000); // 5์ดˆ ํ›„์— ํ•จ์ˆ˜ ์‹คํ–‰

getClock(); // 1์ดˆ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ์ถœ๋ ฅ๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๋ฐ”๋กœ ์ถœ๋ ฅํ•˜๊ณ  setInterval์ด ๋Œ์•„๊ฐ€๋„๋ก ํ•œ๋‹ค.
setInterval(getClock, 1000); // ๋งค ์ดˆ๋งˆ๋‹ค ์ƒˆ๋กœ์šด Date object๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ์Œ

// "1".padStart(2, "0") -> string์˜ ์‹œ์ž‘๋ถ€๋ถ„์— padding์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ธธ์ด 2๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด "0"์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ธธ์ด๋ฅผ 2๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

 

 

greeting.js

const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");

const HIDDEN_CLASSNAME = "hidden"; // ๋ณ„๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฑด ๋ณ€์ˆ˜ ๋ช…์„ ๋Œ€๋ฌธ์ž๋กœ ์ ๋Š”๋‹ค.
const USERNAME_KEY = "username"; // ๋ฐ˜๋ณต๋˜๋Š” string์€ ๋ณ€์ˆ˜์— ์ €์žฅํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๊ฐœ๋ฐœ์ž์˜ ์˜คํƒ€ ์˜ค๋ฅ˜๋กœ ์ธํ•œ ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

function onLoginSubmit(e) {
  e.preventDefault(); //event์˜ ๊ธฐ๋ณธ ํ–‰๋™์ด ๋ฐœ์ƒ๋˜์ง€ ์•Š๋„๋ก ํ•จ. ์—ฌ๊ธฐ์„œ๋Š” form์„ submitํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒˆ๋กœ๊ณ ์นจ ํ•˜๋Š” ๊ธฐ๋ณธ ๋™์ž‘์„ ํ•˜๋Š”๋ฐ ๊ทธ๊ฒƒ์„ ๋ง‰์•„์ค€๋‹ค.
  loginForm.classList.add(HIDDEN_CLASSNAME); // form์„ ์ˆจ๊ฒจ์ค€๋‹ค.
  const username = loginInput.value; //input์— ์ž…๋ ฅํ•œ ๊ฐ’์„ username์— ์ €์žฅํ•œ๋‹ค.
  localStorage.setItem(USERNAME_KEY, username); //์ž…๋ ฅํ•œ ์œ ์ €๋ช…์„ ์ €์žฅํ•ด์„œ ๊ธฐ์–ตํ•ด์คŒ.
  paintGreetings(username);
}

function paintGreetings(username) {
  greeting.innerText = `Hello ${username}!`; // "Hello + username" ๋ณด๋‹ค ํ›จ์”ฌ ์ข‹์Œ!
  greeting.classList.remove(HIDDEN_CLASSNAME); //hidden ํด๋ž˜์Šค๋ฅผ ์‚ญ์ œํ•œ๋‹ค. (h1 ํƒœ๊ทธ๊ฐ€ ๋ณด์—ฌ์•ผ ํ•˜๋‹ˆ๊นŒ form์€ ์•ˆ๋ณด์ด๊ฒŒ ํ•จ.)
}
const savedUsername = localStorage.getItem(USERNAME_KEY);

if (savedUsername === null) {
  //show the form (๋งŒ์•ฝ ์ €์žฅ๋œ username์ด ์—†์œผ๋ฉด hidden ํด๋ž˜์Šค ์‚ญ์ œํ•˜๊ณ  ํผ์„ ๋„์šด๋‹ค.)
  loginForm.classList.remove(HIDDEN_CLASSNAME);
  loginForm.addEventListener("submit", onLoginSubmit); //submit ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ onLoginSubmit ํ•จ์ˆ˜ ์‹คํ–‰
} else {
  // show the greetings (๋งŒ์•ฝ ์ €์žฅ๋œ username์ด ์žˆ์œผ๋ฉด h1ํƒœ๊ทธ์— username ๋„ฃ์–ด์„œ ๋„์šด๋‹ค.)
  paintGreetings(savedUsername);
}

/* 
์ •๋ฆฌ
: ์ฒ˜์Œ์—๋Š” form๊ณผ h1์€ hidden ํด๋ž˜์Šค๋•Œ๋ฌธ์— ์ˆจ๊ฒจ์ ธ ์žˆ์Œ.
js๊ฐ€ username_key๋ฅผ ๊ฐ€์ง€๊ณ  localStorage ํ™•์ธํ•จ.
์ฒ˜์Œ์—” ์—†์œผ๋‹ˆ๊นŒ form์„ ๋ณด์—ฌ์คŒ. (hidden ํด๋ž˜์Šค ์‚ญ์ œ)
์„œ๋ธŒ๋ฐ‹ ๊ธฐ๋‹ค๋ ท๋‹ค๊ฐ€ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ onLoginSubmit ํ•จ์ˆ˜ ์‹คํ–‰.
๊ธฐ๋ณธ ๋™์ž‘ ๋ชปํ•˜๊ฒŒ ๋ง‰๊ณ  from์„ ๋‹ค์‹œ ์ˆจ๊ธด ํ›„, input์— ์ ์€ ๊ฐ’์„ username์— ์ €์žฅ.
์ž…๋ ฅํ•œ ์œ ์ €๋ช…์„ ์ €์žฅํ•˜๊ณ  paintGretings ํ•จ์ˆ˜ ์‹คํ–‰.

h1ํƒœ๊ทธ์— text ์ ์–ด์ฃผ๊ณ  ๋„์›Œ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— hidden ํด๋ž˜์Šค ์‚ญ์ œํ•จ.

๊ทธ๋Ÿผ localStorage์—์„œ username์ด key์ธ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ savedUsername์— ๋„ฃ๊ณ  ๋‹ค์‹œ if๋ฌธ ๋Œ๋ฆผ.
๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์—์„œ ๊ฐ’ ๋ฐ›์•„์™€์„œ null์ด ์•„๋‹ˆ๋‹ˆ๊นŒ paintGreetings ํ•จ์ˆ˜ ์‹คํ–‰ (h1 ํƒœ๊ทธ ๋ณด์—ฌ์คŒ)


*/

 

 

quotes.js

const quotes = [
  {
    quote: "I never dreamed about success, I worked for it",
    author: "Estee Lauder",
  },
  {
    quote: "Do not try to be original, just try to be good.",
    author: "Paul Rand",
  },
  {
    quote: "Do not be afraid to give up the good to go for the great",
    author: "John D. Rockefeller",
  },
  {
    quote:
      "If you cannot fly then run. If you cannot run, then walk. And if you cannot walk, then crawl, but whatever you do, you have to keep moving forward.",
    author: "Martin Luther King Jr.",
  },
  {
    quote:
      "Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.",
    author: "Thomas Edison",
  },
  {
    quote:
      "The fastest way to change yourself is to hang out with people who are already the way you want to be",
    author: "REid Hoffman",
  },
  {
    quote:
      "Money is like gasoline during a road trip. You do not want to run out of gas on your trip, but you are not doing a tour of gas stations",
    author: "Tim O Reilly",
  },
  {
    quote:
      "Some people dream of success, while other people get up every morning and make it happen",
    author: "Wayne Huizenga",
  },
  {
    quote:
      "The only thing worse than starting something and falling.. is not starting something",
    author: "SEth Godin",
  },
  {
    quote:
      "If you really want to do something, you will find a way. If you do not, you will find an excuse.",
    author: "Jim Rohn",
  },
];

const quote = document.querySelector("#quote span:first-child");
const author = document.querySelector("#quote span:last-child");

/* ์ •๋ฆฌ
 * Math.random() : 0~1 ์‚ฌ์ด์˜ ์ˆซ์ž๋ฅผ ๋žœ๋ค์œผ๋กœ ์ถœ๋ ฅ
 * Math.random() * 10 ํ•˜๋ฉด 0~9 ์‚ฌ์ด ์ˆซ์ž ๋žœ๋ค ์ถœ๋ ฅ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์†Œ์ˆ˜์ ์ด ๋ถ™์Œ.
 * Math.round(์ˆซ์ž) : ์‹ค์ˆ˜๋ฅผ ์ •์ˆ˜๋กœ ๋ฐ˜์˜ฌ๋ฆผํ•ด์คŒ.
 * Math.ceil(์ˆซ์ž) : ์‹ค์ˆ˜๋ฅผ ๊ฐ€์žฅ ์œ„์˜ ์ˆซ์ž๋กœ ์˜ฌ๋ ค์คŒ. (ex. 1.1์„ 2๋กœ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. 1.0๋งŒ 1์ด ๋  ์ˆ˜ ์žˆ์Œ)
 * Math.floor(์ˆซ์ž) : ์‹ค์ˆ˜๋ฅผ ๊ฐ€์žฅ ๋ฐ”๋‹ฅ์˜ ์ˆซ์ž๋กœ ๋‚ด๋ ค์คŒ. (ex. 1.999๋ฅผ 1๋กœ ๋‚ด๋ ค์คŒ.)
 */

// console.log(quotes[Math.floor(Math.random() * 10)]);  quotes ๋ฐฐ์—ด์˜ 0~9 ์‚ฌ์ด์˜ ๊ฐ’์„ ๋žœ๋ค์œผ๋กœ ์ถœ๋ ฅ. ๊ทผ๋ฐ ์ด๊ฑด ๋”ฑ 10๊ฐœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ์—๋งŒ ๊ฐ€๋Šฅ. ๋ฐฐ์—ด์˜ ๊ธธ์ด๋งŒํผ ๋žœ๋ค๋˜๊ฒŒ ํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ.
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)];

quote.innerText = todaysQuote.quote;
author.innerText = `<${todaysQuote.author}>`;

quotes ์—ญ์‹œ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋„ฃ์–ด๋‘๊ณ  ๋žœ๋ค์œผ๋กœ ์ถœ๋ ฅ๋˜๋„๋ก ํ•œ๋‹ค.

 

todo.js

const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";

let toDos = [];

function saveTodos() {
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos)); //  JSON.stringify : ๋ฐฐ์—ด ๋˜๋Š” ๊ฐ์ฒด ๋“ฑ์„ string์œผ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.
}

function deleteToDo(event) {
  const li = event.target.parentElement;
  li.remove();
  toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id)); // ์‚ญ์ œํ•˜๋ ค๊ณ  ๋ˆ„๋ฅธ liํƒœ๊ทธ์˜ id์™€ ๊ฐ™์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์„œ ๋ณด์—ฌ์ค€๋‹ค. ์ด๋Œ€ li.id๋Š” string์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜•๋ณ€ํ™˜์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
  saveTodos(); // ์‚ญ์ œ ํ›„์— ํ•œ๋ฒˆ ๋” ๋ฐฐ์—ด์„ ์ €์žฅํ•ด์ค€๋‹ค.
}

function paintTodo(newTodo) {
  const todo = document.createElement("li");
  todo.id = newTodo.id;
  const span = document.createElement("span");
  span.innerText = newTodo.text;
  const button = document.createElement("button");
  button.innerText = "โŒ";
  button.addEventListener("click", deleteToDo);
  todo.appendChild(span); // li์˜ ์ž์‹ span
  todo.appendChild(button);
  toDoList.appendChild(todo);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value; // input ๊ฐ’ ์ €์žฅ
  toDoInput.value = ""; // input ์ฐฝ ๋น„์šฐ๊ธฐ
  const newTodoObj = {
    text: newTodo,
    id: Date.now(),
  }; // ๊ฐ๊ฐ์˜ todo์— id๋ฅผ ๋ถ€์—ฌํ•ด์„œ ํŠน์ • todo๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
  toDos.push(newTodoObj); // ๋ฐฐ์—ด์— input ๋‚ด์šฉ๋“ค์„ ์ €์žฅ
  paintTodo(newTodoObj);
  saveTodos(); // ๋ฐฐ์—ด์— ๋‚ด์šฉ์„ ๋„ฃ์€ ํ›„ localStorage์— ์ €์žฅํ•œ๋‹ค.
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos !== null) {
  const parsedToDos = JSON.parse(savedToDos);
  toDos = parsedToDos;
  parsedToDos.forEach(paintTodo); // forEach : ๋ฐฐ์—ด์˜ ๊ฐ ์•„์ดํ…œ๋“ค์— ๋Œ€ํ•ด์„œ function ์„ ์‹คํ–‰ํ•˜๊ฒŒ ํ•จ.
}

 

weather.js

const API_KEY = "๊ฐ์ž ์ž์‹ ์˜ ํ‚ค ์‚ฌ์šฉ!";
function onGeoOk(position) {
  const lat = position.coords.latitude; // ์œ„๋„ ๊ฒฝ๋„๋ฅผ ํ‘œ์‹œํ•ด์คŒ
  const lon = position.coords.longitude;
  const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
  fetch(url)
    .then((response) => response.json())
    .then((data) => {
      const weather = document.querySelector("#weather span:first-child");
      const city = document.querySelector("#weather span:last-child");
      city.innerText = data.name;
      weather.innerText = `${data.main.temp}°`;
    });
}

function onGeoError() {
  alert("Can't find you. No weather for you.");
}

navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);

 

 


 

โœจ ๊ฒฐ๊ณผ๋ฌผ โœจ

 

์ด๋ฆ„๊ณผ ํˆฌ๋‘๋ฆฌ์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ๋ชจ์Šต์ด๋‹ค!

์™ผ์ชฝ ์ƒ๋‹จ์—๋Š” ์ž์‹ ์˜ ์œ„์น˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์„œ ์ง€์—ญ๊ณผ ๋‚ ์”จ๋ฅผ ํ‘œ์‹œํ•˜๊ณ ,

์™ผ์ชฝ ํ•˜๋‹จ์—๋Š” ๋ฐฐ๊ฒฝํ™”๋ฉด๊ณผ ๊ฐ™์ด ๋žœ๋ค์œผ๋กœ quote๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

 

 

์ƒˆ๋กœ ๊ณ ์นจํ•˜๋ฉด ๋ฐฐ๊ฒฝํ™”๋ฉด์ด ๋ฐ”๋€๋‹ค.

์œ„์˜ ์›€์งค์€ ํ™”๋ฉด์ด ๋ฐ”๋€Œ๋Š” ๋ชจ์Šต, ์ด๋ฆ„๊ณผ ํˆฌ๋‘๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๋ชจ์Šต์ด๋‹ค.

๋Œ“๊ธ€