diff --git a/4-The Message/index.html b/4-The Message/index.html
new file mode 100644
index 0000000..b59eef6
--- /dev/null
+++ b/4-The Message/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ The message
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/4-The Message/src/css/reset.css b/4-The Message/src/css/reset.css
new file mode 100644
index 0000000..5bca465
--- /dev/null
+++ b/4-The Message/src/css/reset.css
@@ -0,0 +1,129 @@
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol,
+ul {
+ list-style: none;
+}
+blockquote,
+q {
+ quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+input:focus {
+ outline: none;
+}
+a {
+ color: inherit;
+ text-decoration: none;
+}
diff --git a/4-The Message/src/css/style.css b/4-The Message/src/css/style.css
new file mode 100644
index 0000000..8593d40
--- /dev/null
+++ b/4-The Message/src/css/style.css
@@ -0,0 +1,65 @@
+@import 'reset.css';
+
+html,
+body {
+ width: 100%;
+ height: 100vh;
+ overflow: hidden;
+}
+
+.msg_page {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background : linear-gradient(to bottom, #C0DEFC, #FCFEFF);
+}
+
+.msg_form {
+ width: 500px;
+ height: 250px;
+ border-radius: 10px;
+ background-color: #F5F5F5;
+ box-shadow: 0px 0px 4px 4px #E2E2E2;
+}
+
+.msg_form h2 {
+ font-size: 20px;
+ font-weight: bold;
+ padding: 30px 0px 15px calc(34%);
+}
+
+.msg_form p {
+ width: 90%;
+ margin-left: 25px;
+ border-bottom: 2px solid rgba(211, 211, 211, 0.5);
+}
+
+.msg_form h3 {
+ font-size: 15px;
+ padding: 20px 0px 15px calc(5%);
+}
+
+.msg_form_btn {
+ margin-left: 20px;
+ border: 2px gray;
+}
+
+.msg_form_input{
+ border: 2px gray;
+ width: 420px;
+ height: 30px;
+}
+
+.msg_form_submit {
+ margin-top: 30px;
+ margin-left: 10px;
+ width: 60px;
+ height: 30px;
+}
+
+.msg_view {
+ margin-top: 15px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/4-The Message/src/js/App.js b/4-The Message/src/js/App.js
new file mode 100644
index 0000000..86f21fc
--- /dev/null
+++ b/4-The Message/src/js/App.js
@@ -0,0 +1,49 @@
+import { TEXTS } from '../../utils/Constant.js'
+import MessageForm from './MessageForm.js'
+import MessageView from './MessageView.js'
+
+export default function App({ $target }) {
+ // 페이지는 전체 배경을 의미.
+ const $page = document.createElement('div')
+ $page.className = "msg_page"
+ $target.appendChild($page)
+
+ this.state = {
+ message : ''
+ }
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ messageView.setState(this.state.message)
+ }
+
+ const $container = document.createElement('div')
+ $container.className = 'msg_form'
+ $container.innerHTML = `
+ ${TEXTS.TITLE_TEXT}
+
+ ${TEXTS.INFO_TEXT}
+ `
+
+ new MessageForm({
+ $target:$container,
+ onSubmit : (message) => {
+ this.setState({
+ ...this.state,
+ message
+ })
+ }
+ })
+
+ const messageView = new MessageView({
+ $target: $container,
+ initialState: this.state.message
+ })
+
+
+ $page.appendChild($container)
+
+}
+
+// 전체 UI를 담당해주는 메세지 쪽?
+// 그리고 엔터를 받는 쪽을 해줘야하는건기?
\ No newline at end of file
diff --git a/4-The Message/src/js/MessageForm.js b/4-The Message/src/js/MessageForm.js
new file mode 100644
index 0000000..101bc13
--- /dev/null
+++ b/4-The Message/src/js/MessageForm.js
@@ -0,0 +1,38 @@
+export default function MessageForm({$target, onSubmit}) {
+ const $form = document.createElement('form')
+ $target.appendChild($form)
+
+ this.render = () => {
+ $form.innerHTML = `
+
+
+
+
+ `
+ }
+
+ this.render()
+
+ $form.addEventListener('submit', (e) => {
+ e.preventDefault()
+
+ const input = $form.querySelector('.msg_form_input')
+ onSubmit(input.value)
+
+ input.value = ''
+ })
+
+
+ window.addEventListener('Enter', (e) => {
+ e.preventDefault()
+
+ const input = $form.querySelector('.msg_form_input')
+ onSubmit(input.value)
+
+ input.value = ''
+ })
+
+
+}
\ No newline at end of file
diff --git a/4-The Message/src/js/MessageView.js b/4-The Message/src/js/MessageView.js
new file mode 100644
index 0000000..d48085e
--- /dev/null
+++ b/4-The Message/src/js/MessageView.js
@@ -0,0 +1,20 @@
+export default function MessageView({$target, initialState}) {
+ const $msgView = document.createElement('div')
+ $msgView.className = 'msg_view'
+ $target.appendChild($msgView)
+
+ this.state = initialState
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ this.render()
+ }
+
+ this.render = () => {
+ $msgView.style.display = this.state ? 'block' : 'none'
+ $msgView.textContent = this.state
+ }
+
+ this.render()
+
+}
\ No newline at end of file
diff --git a/4-The Message/src/main.js b/4-The Message/src/main.js
new file mode 100644
index 0000000..f34dcd5
--- /dev/null
+++ b/4-The Message/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('.app')
+
+new App({
+ $target: $app,
+})
diff --git a/4-The Message/utils/Constant.js b/4-The Message/utils/Constant.js
new file mode 100644
index 0000000..6df2a9e
--- /dev/null
+++ b/4-The Message/utils/Constant.js
@@ -0,0 +1,4 @@
+export const TEXTS = {
+ TITLE_TEXT : 'Pass the Message',
+ INFO_TEXT : 'Enter the Message'
+}
\ No newline at end of file
diff --git a/5-Counter/index.html b/5-Counter/index.html
new file mode 100644
index 0000000..c659f72
--- /dev/null
+++ b/5-Counter/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Counter
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/5-Counter/src/css/reset.css b/5-Counter/src/css/reset.css
new file mode 100644
index 0000000..5bca465
--- /dev/null
+++ b/5-Counter/src/css/reset.css
@@ -0,0 +1,129 @@
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol,
+ul {
+ list-style: none;
+}
+blockquote,
+q {
+ quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+input:focus {
+ outline: none;
+}
+a {
+ color: inherit;
+ text-decoration: none;
+}
diff --git a/5-Counter/src/css/style.css b/5-Counter/src/css/style.css
new file mode 100644
index 0000000..8aa169b
--- /dev/null
+++ b/5-Counter/src/css/style.css
@@ -0,0 +1,52 @@
+@import 'reset.css';
+
+html,
+body {
+ width: 100%;
+ height: 100vh;
+ overflow: hidden;
+}
+
+.count_page {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background : #FCFC62
+}
+
+.counter_container {
+ display: flex;
+ flex-direction: column;
+ width: 600px;
+ height: 330px;
+ background-color: #FEFFEA;
+ border: 4px solid black;
+ align-items: center;
+ justify-content: space-around;
+}
+
+.counter_container h2 {
+ font-size: 30px;
+ font-weight: bold;
+}
+
+.counter_container h3 {
+ font-size: 130px;
+ font-weight: bold;
+}
+
+.buttons_div button {
+ width: 80px;
+ height: 40px;
+ border-radius: 4px;
+ background-color: #FEFFEA;
+ font-size: 15px;
+}
+
+.buttons_div button:hover {
+ background-color: black;
+ color: white;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/5-Counter/src/js/App.js b/5-Counter/src/js/App.js
new file mode 100644
index 0000000..ad340a9
--- /dev/null
+++ b/5-Counter/src/js/App.js
@@ -0,0 +1,54 @@
+import { TEXTS } from '../../utils/Constant.js'
+import CountView from './CountView.js'
+import CountBtns from './CountBtns.js'
+
+export default function App({ $target }) {
+ // 페이지는 전체 배경을 의미.
+ const $page = document.createElement('div')
+ $page.className = "count_page"
+ $target.appendChild($page)
+
+ this.state = {
+ count : 0
+ }
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ countView.setState(this.state.count)
+ }
+
+ const $container = document.createElement('div')
+ $page.appendChild($container)
+ $container.className = 'counter_container'
+ $container.innerHTML = `
+ ${TEXTS.TITLE_TEXT}
+ `
+
+ const countView = new CountView({
+ $target: $container,
+ initialState: this.state.count
+ })
+
+ new CountBtns({
+ $target: $container,
+ onUpCount: () => {
+ const count = this.state.count + 1
+ this.setState({
+ ...this.state,
+ count
+ })
+ },
+ onDownCount : () => {
+ const count = this.state.count - 1
+ this.setState({
+ ...this.state,
+ count
+ })
+ }
+ })
+
+
+}
+
+// 전체 UI를 담당해주는 메세지 쪽?
+// 그리고 엔터를 받는 쪽을 해줘야하는건기?
\ No newline at end of file
diff --git a/5-Counter/src/js/CountBtns.js b/5-Counter/src/js/CountBtns.js
new file mode 100644
index 0000000..9930754
--- /dev/null
+++ b/5-Counter/src/js/CountBtns.js
@@ -0,0 +1,25 @@
+export default function CountBtns({$target, onUpCount, onDownCount}) {
+
+ const $buttons = document.createElement('div')
+ $buttons.className = 'buttons_div'
+
+ $buttons.innerHTML = `
+
+
+ `
+
+ $target.appendChild($buttons)
+
+ $buttons.addEventListener('click', (e) => {
+ const { className } = e.target
+
+ if ( className === 'increase_btn') {
+ onUpCount()
+ } else if ( className === 'decrease_btn') {
+ onDownCount()
+ }
+
+ })
+
+
+}
\ No newline at end of file
diff --git a/5-Counter/src/js/CountView.js b/5-Counter/src/js/CountView.js
new file mode 100644
index 0000000..007f645
--- /dev/null
+++ b/5-Counter/src/js/CountView.js
@@ -0,0 +1,17 @@
+export default function CountView({$target, initialState}) {
+ const $count = document.createElement('h3')
+ $target.appendChild($count)
+
+ this.state = initialState
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ this.render()
+ }
+
+ this.render = () => {
+ $count.textContent = this.state
+ }
+
+ this.render()
+}
\ No newline at end of file
diff --git a/5-Counter/src/main.js b/5-Counter/src/main.js
new file mode 100644
index 0000000..f34dcd5
--- /dev/null
+++ b/5-Counter/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('.app')
+
+new App({
+ $target: $app,
+})
diff --git a/5-Counter/utils/Constant.js b/5-Counter/utils/Constant.js
new file mode 100644
index 0000000..9cb61cc
--- /dev/null
+++ b/5-Counter/utils/Constant.js
@@ -0,0 +1,3 @@
+export const TEXTS = {
+ TITLE_TEXT : 'COUNTER',
+}
\ No newline at end of file
diff --git a/6-Carousel/index.html b/6-Carousel/index.html
new file mode 100644
index 0000000..50e40bc
--- /dev/null
+++ b/6-Carousel/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Carousel
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/6-Carousel/src/css/reset.css b/6-Carousel/src/css/reset.css
new file mode 100644
index 0000000..5bca465
--- /dev/null
+++ b/6-Carousel/src/css/reset.css
@@ -0,0 +1,129 @@
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol,
+ul {
+ list-style: none;
+}
+blockquote,
+q {
+ quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+input:focus {
+ outline: none;
+}
+a {
+ color: inherit;
+ text-decoration: none;
+}
diff --git a/6-Carousel/src/css/style.css b/6-Carousel/src/css/style.css
new file mode 100644
index 0000000..4c7c2f5
--- /dev/null
+++ b/6-Carousel/src/css/style.css
@@ -0,0 +1,53 @@
+.CarouselPage {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+ justify-content: center;
+ align-items: center;
+}
+
+.carouselImage {
+ width: 70%;
+ position: relative;
+}
+
+.carouselImage__image {
+ width: 100%;
+}
+
+.carouselImage__buttons {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+}
+
+.carouselImage__button {
+ color: white;
+ background: transparent;
+ border-radius: 0px;
+ border: 0;
+}
+
+.carouselImage__button:hover {
+ background-color: black;
+ opacity: 0.5;
+}
+
+.Carousel__indicators {
+ display: flex;
+ margin-top: 10px;
+}
+.Carousel__indicator-dot {
+ width: 10px;
+ height: 10px;
+ background-color: gray;
+ border-radius: 50%;
+ margin-right: 8px;
+}
+
+.Carousel__indicator-dot--selected {
+ background-color: black;
+}
\ No newline at end of file
diff --git a/6-Carousel/src/js/App.js b/6-Carousel/src/js/App.js
new file mode 100644
index 0000000..71e45cb
--- /dev/null
+++ b/6-Carousel/src/js/App.js
@@ -0,0 +1,62 @@
+import { images } from '../../utils/imageUrl.js'
+import CaroselImage from './CarouselImage.js'
+import Indicators from './Indicators.js';
+
+const IMAGES_LENGTH = images.length;
+export default function CarouselPage({ $target }) {
+ const $page = document.createElement('div')
+ $target.appendChild($page)
+ $page.className = 'CarouselPage'
+
+ this.state = {
+ index: 0,
+ }
+
+ const carouselImage = new CaroselImage({
+ $target: $page,
+ initialState: {
+ index: this.state.index,
+ image: images[this.state.index],
+ },
+ onPrevClick: () => {
+ const index =
+ this.state.index - 1 < 0 ? IMAGES_LENGTH - 1 : this.state.index - 1
+
+ this.setState({
+ ...this.state,
+ index,
+ })
+ },
+ onNextClick: () => {
+ const index = (this.state.index + 1) % IMAGES_LENGTH
+
+ this.setState({
+ ...this.state,
+ index,
+ })
+ },
+ })
+
+ const indicators = new Indicators({
+ $target: $page,
+ initialState: {
+ index: this.state.index,
+ },
+ length: IMAGES_LENGTH,
+ })
+
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ const { index } = this.state
+
+ carouselImage.setState({
+ index,
+ image: images[index],
+ })
+
+ indicators.setState({
+ index,
+ })
+ }
+}
\ No newline at end of file
diff --git a/6-Carousel/src/js/CarouselImage.js b/6-Carousel/src/js/CarouselImage.js
new file mode 100644
index 0000000..b2a4fbf
--- /dev/null
+++ b/6-Carousel/src/js/CarouselImage.js
@@ -0,0 +1,52 @@
+export default function ImageCarousel({$target, initialState, onPrevClick, onNextClick}) {
+ const $carouselImage = document.createElement('div')
+ $carouselImage.className = 'carouselImage'
+
+ this.state = initialState
+
+ $target.appendChild($carouselImage)
+
+ const $image = document.createElement('img')
+ $image.className = 'carouselImage__image'
+
+ const $buttons = document.createElement('div')
+ $buttons.className = 'carouselImage__buttons'
+
+ $buttons.innerHTML = `
+
+
+
+ `
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ this.render()
+ }
+
+ this.render = () => {
+ $carouselImage.innerHTML = ''
+
+ const { src, name } = this.state.image
+ $image.src = src
+ $image.alt = name
+
+ $carouselImage.appendChild($image)
+ $carouselImage.appendChild($buttons)
+ }
+
+ this.render()
+
+ $buttons.addEventListener('click', (e) => {
+ const {className} = e.target.closest('button')
+
+ if ( className === 'prevBtn') {
+ onPrevClick()
+ } else if ( className === 'nextBtn' ) {
+ onNextClick()
+ }
+ })
+}
\ No newline at end of file
diff --git a/6-Carousel/src/js/Indicators.js b/6-Carousel/src/js/Indicators.js
new file mode 100644
index 0000000..bdd2367
--- /dev/null
+++ b/6-Carousel/src/js/Indicators.js
@@ -0,0 +1,27 @@
+
+export default function Indicators({ $target, initialState, length }) {
+ const $indicators = document.createElement('div')
+ $indicators.className = 'Carousel__indicators'
+ $target.appendChild($indicators)
+
+ this.state = initialState
+
+ this.setState = (nextState) => {
+ this.state = nextState
+ this.render()
+ }
+
+ this.render = () => {
+ const checkedIndicators = Array.from(new Array(length), (_) => _)
+ .map((_, index) => ``,
+ )
+ .join('')
+
+ $indicators.innerHTML = checkedIndicators
+ }
+
+ this.render()
+}
\ No newline at end of file
diff --git a/6-Carousel/src/main.js b/6-Carousel/src/main.js
new file mode 100644
index 0000000..f34dcd5
--- /dev/null
+++ b/6-Carousel/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('.app')
+
+new App({
+ $target: $app,
+})
diff --git a/6-Carousel/utils/imageUrl.js b/6-Carousel/utils/imageUrl.js
new file mode 100644
index 0000000..35df98b
--- /dev/null
+++ b/6-Carousel/utils/imageUrl.js
@@ -0,0 +1,34 @@
+export const images = [
+ {
+ name: 'Lam0',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam0.jpg',
+ },
+ {
+ name: 'Lam1',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam1.jpg',
+ },
+ {
+ name: 'Lam2',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam2.jpg',
+ },
+ {
+ name: 'Lam3',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam3.jpg',
+ },
+ {
+ name: 'Lam4',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam4.jpg',
+ },
+ {
+ name: 'Lam5',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam5.jpg',
+ },
+ {
+ name: 'Lam5',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam6.jpg',
+ },
+ {
+ name: 'Lam7',
+ src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam7.jpg',
+ },
+]
\ No newline at end of file
diff --git a/README.md b/README.md
index 8e7c12a..e0cf3c4 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,18 @@
- [Project1/리아] 프로젝트명
- 예) [Project1/리아] Colors
+## 2회차(~9/21)
+### Project 4 The message
+
+### Project 5 Counter
+
+### Project 6 Image carousel
+
+### Project 7 Digital clock
+
+
+
+
## 1회차(~9/12)
### Project 1 Colors
