diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.css" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.css" new file mode 100644 index 0000000..80dd2cc --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.css" @@ -0,0 +1,477 @@ +@import "./styles/reset.css"; + +@font-face { + font-family: 'Pretendard'; + src: url('assets/font/Pretendard-Medium.otf') format('opentype'); +} + +#asset { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 16px; + + padding: 20px; + border-radius: 12px; + + background-color: #ffffff; +} + +.subtitle { + font-size: 20px; +} + +#money { + font-size: 20px; +} + +#date>p { + vertical-align: middle; + line-height: 24px; +} + +#date>button { + font-size: 20px; + color: #505866; +} + +#prev-day { + transform: scaleX(-1); +} + +#today { + display: flex; + flex: 1; + justify-content: space-between; + align-items: center; + + width: 180px; +} + +#today img { + width: 16px; + height: 16px; +} + +.income { + color: #4d7cfe; +} + +.spending { + color: #fe4d4d; +} + +#main { + display: flex; + flex-direction: column; + flex-grow: 1; + + max-height: calc(100vh - 280px); + + padding: 20px; + border-radius: 12px; + + background-color: #ffffff; +} + +#date { + display: flex; + justify-content: space-between; + + width: 160px; + margin: 20px 0 10px; +} + +#date button { + border: none; + + background: transparent; +} + +#money-type { + display: flex; + justify-content: end; + + font-size: 14px; +} + +#money-type input { + display: none; +} + +#money-type label { + height: 28px; + margin-left: 10px; + + padding: 5px 20px; + + border-radius: 5px; + + background-color: #f2f2f2; + + line-height: 18px; + color: #777777; + + cursor: pointer; +} + +#money-type input[type=checkbox]:checked+label { + margin-left: 10px; + + padding: 5px 20px 5px 20px; + + background-color: #4880ee; + + color: #ffffff; +} + +#history { + overflow: scroll; + + margin-top: 15px; + height: 90%; + border-top: 1px solid #d9d9d9; +} + +#history ul { + display: flex; + flex-direction: column; + + padding-top: 5px; +} + +#history li { + display: flex; + align-items: center; + justify-content: start; + + height: 40px; +} + +#history li p { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +#history .category { + flex-basis: 20%; + + padding-left: 10px; +} + +#history .name { + flex-basis: 40%; + + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +#history .price { + flex-basis: 30%; + flex-grow: 1; + + text-align: end; +} + +#history .income::before { + content: '+'; +} + +#history .spending::before { + content: '-'; +} + +#history li button { + flex-basis: 10%; + + height: 20px; + border: 0; + + background-color: transparent; +} + +.delete::after { + content: "✕"; +} + +footer { + display: flex; + justify-content: center; +} + +footer #add { + position: absolute; + bottom: 10px; + + width: calc(50% - 20px); + height: 44px; + + + border: none; + border-radius: 10px; + + background-color: #4880ee; + + font-size: 16px; + line-height: 44px; + color: #ffffff; +} + +footer #manage-category { + position: absolute; + right: 10px; + bottom: 10px; + + width: calc(25% - 5px); + height: 44px; + + margin-top: 10px; + + border: none; + border-radius: 10px; + + background-color: #E1ECFC; + + font-size: 16px; + text-align: center; + text-decoration: none; + line-height: 44px; + color: #4880ee; +} + +#modal-background { + display: none; + + position: fixed; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + background-color: rgba(0, 0, 0, 0.6); +} + + +#add-history-modal { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + + position: absolute; + left: 0; + bottom: -60%; + + width: 100%; + height: 60%; + + padding: 20px 10px; + + border-radius: 20px 20px 0px 0px; + + background-color: #ffffff; + + transition: bottom 0.3s ease-in-out; +} + +#add-history-modal input[type=radio] { + display: none; +} + +#add-history-modal input[type=text] { + width: 70%; + + border: none; + border-bottom: 1px solid #f2f2f2; +} + +#add-history-modal p { + line-height: 40px; +} + +#type-selector { + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; + + width: 90%; + height: 40px; + + margin: 10px auto 5px; + padding: 4px; + + border-radius: 10px; + + background-color: #f2f2f2; +} + +#type-selector label { + width: 50%; + + border-radius: 7px; + + text-align: center; + line-height: 32px; +} + +.select-category { + width: 70%; +} + +.drop-down { + background-color: transparent; +} + +.select-category .selector { + display: flex; + justify-content: space-between; + align-items: center; + + height: 40px; + + padding: 20px; + + border-radius: 8px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); + + background: #ffffff; + + font-size: 18px; + font-weight: 400; + + cursor: pointer; +} + +.selector p { + font-size: 12px; +} + +.select-category.active .drop-down { + transform: rotate(-180deg); +} + +.select-category .categories { + display: none; + + position: absolute; + + overflow: scroll; + + width: 60%; + height: 150px; + + padding: 10px; + margin-top: 10px; + + border-radius: 8px; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); + + background-color: #ffffff; +} + +.select-category.active .categories { + display: block; +} + +.categories .category { + display: flex; + align-items: center; + + height: 40px; + + padding: 0 16px; + + border-radius: 8px; + + background-color: #ffffff; + + font-size: 14px; + color: #333333; + + cursor: pointer; +} + +.categories .category:hover { + background: #F2F2F2; +} + + + +#type-selector input[type=radio]:checked+label { + background-color: #ffffff; +} + +#category-selector, +#price-input, +#content-input, +#modal-button-wrapper { + display: flex; + justify-content: space-between; + + width: 90%; +} + +input { + outline: none; +} + +#modal-button-wrapper { + position: absolute; + bottom: 20px; + + gap: 10px; + + width: 90%; + height: 40px; +} + +#modal-button-wrapper button { + width: 50%; + height: 44px; + border: none; + border-radius: 5px; + + font-size: 16px; +} + +button#close, +button#cancel { + position: left; + + color: #333333; +} + +button#save, +button#confirm { + position: right; + + background-color: #4880ee; + + color: #ffffff; +} + +section>#delete-modal { + display: none; + flex-direction: column; + align-items: center; + + position: absolute; + z-index: 1; + top: calc((100% - 150px)/2); + left: calc((100% - 250px)/2); + + width: 250px; + height: 150px; + + padding-top: 40px; + + border-radius: 10px; + + background-color: #ffffff; + +} \ No newline at end of file diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.html" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.html" new file mode 100644 index 0000000..224be31 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.html" @@ -0,0 +1,104 @@ + + + + + + + + + + 수빈 | 가계부 + + + +
+

수빈이의 가계부

+
+
+

나의 자산

+ +
+ 위쪽화살표 +

+ 아래쪽화살표 +

+
+
+
+

내역 리스트

+
+ +

10월 9일

+ +
+
+ + + + +
+
+ +
+
+ +
+ +
+

내역추가

+
+ + + + +
+
+

카테고리

+
+
+

카테고리를 선택하세요

+ +
+
    + +
+
+
+
+

금액

+ +
+
+

내용

+ +
+ +
+
+
+ +
+

정말 삭제하시겠습니까?

+ +
+
+ + + + + \ No newline at end of file diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.js" new file mode 100644 index 0000000..f31f30a --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/index.js" @@ -0,0 +1,11 @@ +import { renderHistoryList } from "./js/History/HistoryView.js"; +import { renderAssetData } from "./js/Asset/AssetView.js"; +import { renderCategory } from "./js/Category/CategoryView.js"; + +function render() { + renderHistoryList(); + renderAssetData(); + renderCategory(); +} + +render(); diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Asset/AssetView.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Asset/AssetView.js" new file mode 100644 index 0000000..d8728d6 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Asset/AssetView.js" @@ -0,0 +1,55 @@ +import { + HISTORY_LIST, + INIT_BALANCE, + INIT_INCOME, + INIT_SPENDING, + TRANSACTION_TYPE, +} from "../utils/constants.js"; + +import { + TODY_TOTAL_INCOME, + TODY_TOTAL_SPENDING, + TOTAL_MONEY, +} from "../utils/documentElements.js"; + +import { changeFormat } from "../utils/moneyFormatter.js"; + +let total; +let income; +let spending; + +function resetMoney() { + total = INIT_BALANCE; + income = INIT_INCOME; + spending = INIT_SPENDING; +} + +function calculateMoney(history) { + switch (history.type) { + case TRANSACTION_TYPE.SPENDING: + total -= history.money; + spending += history.money; + break; + case TRANSACTION_TYPE.INCOME: + total += history.money; + income += history.money; + break; + default: + break; + } +} + +function setMoney() { + TOTAL_MONEY.innerHTML = total; + TODY_TOTAL_INCOME.innerHTML = income; + TODY_TOTAL_SPENDING.innerHTML = spending; +} + +export function renderAssetData() { + resetMoney(); + HISTORY_LIST.forEach((history) => { + calculateMoney(history); + }); + setMoney(); + changeFormat(); +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryController.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryController.js" new file mode 100644 index 0000000..eba7f57 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryController.js" @@ -0,0 +1,70 @@ +import { CATEGORY, ELEMENT, LOCAL_STORAGE, TRANSACTION_TYPE } from "../utils/constants.js"; +import { + HOME_BUTTON, + INCOME_CATEGORY_INPUT, + INCOME_CATEGORY_SECTION, + SPENDING_CATEGORY_INPUT, + SPENDING_CATEGORY_SECTION, +} from "../utils/documentElements.js"; + +HOME_BUTTON.addEventListener("click", () => { + window.location.href = "../index.html"; +}); + +function addToCategoryList(type, name) { + const categoryList = + type === TRANSACTION_TYPE.INCOME ? CATEGORY.INCOME : CATEGORY.SPENDING; + categoryList.push(name); +} + +function appendCategoryTagElement(name, categorySection) { + const CATEGORY_TAG = document.createElement(ELEMENT.HTMLTAG.DIV); + CATEGORY_TAG.className = ELEMENT.CLASSNAME.CATEGORY_TAG; + CATEGORY_TAG.innerHTML = name; + categorySection.appendChild(CATEGORY_TAG); +} + +function saveToLocalStorage(type) { + const storageKey = + type === TRANSACTION_TYPE.INCOME + ? LOCAL_STORAGE.INCOME + : LOCAL_STORAGE.SPENDING; + const categoryList = + type === TRANSACTION_TYPE.INCOME ? CATEGORY.INCOME : CATEGORY.SPENDING; + localStorage.setItem(storageKey, JSON.stringify(categoryList)); +} + +function handleCategoryInput(type, inputField, categorySection) { + inputField.addEventListener("keydown", (event) => { + if (event.isComposing) return; // 중복 입력 방지 + if (event.key === "Enter") { + const categoryName = event.target.value; + addToCategoryList(type, categoryName); + appendCategoryTagElement(categoryName, categorySection); + saveToLocalStorage(type); + inputField.value = ""; + } + }); +} + +function renderCategoryTag(type, categorySection) { + const categoryList = + type === TRANSACTION_TYPE.INCOME ? CATEGORY.INCOME : CATEGORY.SPENDING; + categoryList.forEach((category) => { + appendCategoryTagElement(category, categorySection); + }); +} + +renderCategoryTag(TRANSACTION_TYPE.INCOME, INCOME_CATEGORY_SECTION); +renderCategoryTag(TRANSACTION_TYPE.SPENDING, SPENDING_CATEGORY_SECTION); + +handleCategoryInput( + TRANSACTION_TYPE.INCOME, + INCOME_CATEGORY_INPUT, + INCOME_CATEGORY_SECTION +); +handleCategoryInput( + TRANSACTION_TYPE.SPENDING, + SPENDING_CATEGORY_INPUT, + SPENDING_CATEGORY_SECTION +); diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryView.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryView.js" new file mode 100644 index 0000000..40a78da --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/Category/CategoryView.js" @@ -0,0 +1,60 @@ +import { CATEGORY, ELEMENT, TRANSACTION_TYPE } from "../utils/constants.js"; +import { + DROP_DOWN_CATEGORIES, + SELECTED_CATEGORY, + SELECTOR_DIV, + SELECT_TYPE_INCOME, + SELECT_TYPE_SPENDING, +} from "../utils/documentElements.js"; + +function handleSelectChange() { + SELECT_TYPE_INCOME.addEventListener("change", () => { + renderCategory(TRANSACTION_TYPE.INCOME, CATEGORY.INCOME); + SELECTED_CATEGORY.innerText = CATEGORY.INCOME[0]; + }); + + SELECT_TYPE_SPENDING.addEventListener("change", () => { + renderCategory(TRANSACTION_TYPE.SPENDING, CATEGORY.SPENDING); + SELECTED_CATEGORY.innerText = CATEGORY.SPENDING[0]; + }); +} + +function handleCategoryClick() { + const categories = document.querySelectorAll(".categories .category"); + categories.forEach((category) => { + category.addEventListener("click", (event) => { + SELECTED_CATEGORY.innerText = event.target.innerText; + SELECTOR_DIV.classList.remove(ELEMENT.CLASSNAME.ACTIVE); + }); + }); +} + +function createCategoryList(type, category) { + const dropDownList = document.createElement(ELEMENT.HTMLTAG.LIST); + dropDownList.className = ELEMENT.CLASSNAME.CATEGORY; + type === TRANSACTION_TYPE.INCOME + ? dropDownList.classList.add(ELEMENT.CLASSNAME.TYPE_INCOME) + : dropDownList.classList.add(ELEMENT.CLASSNAME.TYPE_SPENDING); + dropDownList.innerHTML = category; + DROP_DOWN_CATEGORIES.appendChild(dropDownList); + handleCategoryClick(); +} + +function resetCategory() { + while (DROP_DOWN_CATEGORIES.firstChild) { + DROP_DOWN_CATEGORIES.removeChild(DROP_DOWN_CATEGORIES.firstChild); + } +} + +export function renderCategory(type, categoryList) { + if (!type & !categoryList) { + type = TRANSACTION_TYPE; + categoryList = CATEGORY.INCOME; + handleCategoryClick(); + } + resetCategory(); + categoryList.forEach((category) => { + createCategoryList(type, category); + }); + handleSelectChange(); +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryController.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryController.js" new file mode 100644 index 0000000..fd38e3e --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryController.js" @@ -0,0 +1,55 @@ +import { renderAssetData } from "../Asset/AssetView.js"; +import { ELEMENT, HISTORY_LIST } from "../utils/constants.js"; +import { MODAL_BACKGROUND, CANCEL_BUTTON, CONFIRM_BUTTON, MODAL_DELETE } from "../utils/documentElements.js"; + +let indexToDelete; +let listToDelete; +let isConfirmed = false; + +function findIndexToDelete() { + return HISTORY_LIST.findIndex((history) => indexToDelete === history.id); +} + +function deleteList() { + const index = findIndexToDelete(); + if (index !== -1) { + HISTORY_LIST.splice(index, 1); + listToDelete.remove(); + renderAssetData(); + } +} + +function handleConfirmClick() { + isConfirmed = true; + deleteList(); + closeModal(); +} + +function handleCancelClick() { + isConfirmed = false; + closeModal(); +} + +function openModal() { + MODAL_DELETE.style.display = ELEMENT.STYLE.DISPLAY.FLEX; + MODAL_BACKGROUND.style.display = ELEMENT.STYLE.DISPLAY.BLOCK; +} + +function closeModal() { + MODAL_DELETE.style.display = ELEMENT.STYLE.DISPLAY.NONE; + MODAL_BACKGROUND.style.display = ELEMENT.STYLE.DISPLAY.NONE; +} + +export function setDeleteEvent() { + const deleteButtons = document.querySelectorAll("button.delete"); + deleteButtons.forEach((button) => { + button.addEventListener("click", (event) => { + indexToDelete = parseInt(event.target.getAttribute(ELEMENT.ATTRIBUTE.DATA_INDEX)); + listToDelete = event.target.parentElement; + openModal(); + }); + }); + + CONFIRM_BUTTON.addEventListener("click", handleConfirmClick); + CANCEL_BUTTON.addEventListener("click", handleCancelClick); +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryListTemplate.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryListTemplate.js" new file mode 100644 index 0000000..b4b4ca7 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryListTemplate.js" @@ -0,0 +1,37 @@ +import { TRANSACTION_TYPE, ELEMENT } from "../utils/constants.js"; + +export function makeCategoryElement(category) { + const historyCategory = document.createElement(ELEMENT.HTMLTAG.TEXT); + historyCategory.className = ELEMENT.CLASSNAME.CATEGORY; + historyCategory.innerHTML = category; + return historyCategory; +} + +export function makeNameElement(name) { + const historyName = document.createElement(ELEMENT.HTMLTAG.TEXT); + historyName.className = ELEMENT.CLASSNAME.NAME; + historyName.innerHTML = name; + return historyName; +} + +export function makePriceElement(type, price) { + const historyPrice = document.createElement(ELEMENT.HTMLTAG.TEXT); + historyPrice.className = ELEMENT.CLASSNAME.PRICE; + if (type === TRANSACTION_TYPE.SPENDING) { + historyPrice.classList.add(ELEMENT.CLASSNAME.SPENDING, ELEMENT.CLASSNAME.MONEY); + } + if (type === TRANSACTION_TYPE.INCOME) { + historyPrice.classList.add(ELEMENT.CLASSNAME.INCOME, ELEMENT.CLASSNAME.MONEY); + } + historyPrice.innerText = price; + return historyPrice; +} + +export function makeDeleteButton(id) { + const deleteButton = document.createElement(ELEMENT.HTMLTAG.BUTTON); + deleteButton.className = ELEMENT.CLASSNAME.DELETE; + const attributeName = ELEMENT.ATTRIBUTE.DATA_INDEX; + const attributeValue = id; + deleteButton.setAttribute(attributeName, attributeValue); + return deleteButton; +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryView.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryView.js" new file mode 100644 index 0000000..9a35431 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/HistoryView.js" @@ -0,0 +1,38 @@ +import { ELEMENT, HISTORY_LIST } from "../utils/constants.js"; +import { HISTORY_DIV } from "../utils/documentElements.js"; +import { setDeleteEvent } from "./HistoryController.js"; +import { changeFormat } from "../utils/moneyFormatter.js"; +import { makeCategoryElement, makeDeleteButton, makeNameElement, makePriceElement } from "./HistoryListTemplate.js"; +import { handleModal } from "./ModalController.js"; + +function addList(history) { + const list = document.createElement(ELEMENT.HTMLTAG.LIST); + list.append( + makeCategoryElement(history.category), + makeNameElement(history.content), + makePriceElement(history.type, history.money), + makeDeleteButton(history.id) + ); + HISTORY_DIV.appendChild(list); + setDeleteEvent(); +} + +export function resetData() { + while (HISTORY_DIV.firstChild) { + HISTORY_DIV.removeChild(HISTORY_DIV.firstChild); + } +} + +export function renderHistoryList(list) { + if (list === undefined) { + //전체 데이터를 렌더링 하고자 호출했을 때 + list = HISTORY_LIST; + } + resetData(); + list.forEach((history) => { + addList(history); + }); + changeFormat(); +} + +handleModal(); diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/ModalController.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/ModalController.js" new file mode 100644 index 0000000..887f1ad --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/ModalController.js" @@ -0,0 +1,74 @@ +import { ELEMENT, HISTORY_LIST, MESSAGE, TRANSACTION_TYPE } from "../utils/constants.js"; +import { renderHistoryList } from "./HistoryView.js"; +import { renderAssetData } from "../Asset/AssetView.js"; +import { + ADD_HISTORY_BUTTON, + CLOSE_MODAL_BUTTON, + CONTENT_INPUT, + MODAL, + MODAL_BACKGROUND, + PRICE_INPUT, + SAVE_BUTTON, + SELECTED_CATEGORY, + SELECTOR, + SELECTOR_DIV, + SELECT_TYPE_SPENDING, +} from "../utils/documentElements.js"; + +function handleSelectorClick() { + SELECTOR_DIV.classList.add(ELEMENT.CLASSNAME.ACTIVE); +} + +function handleAddHistoryButtonClick() { + MODAL_BACKGROUND.style.display = ELEMENT.STYLE.DISPLAY.BLOCK; + MODAL.style.bottom = 0; +} + +function handleCloseModalButtonClick() { + MODAL_BACKGROUND.style.display = ELEMENT.STYLE.DISPLAY.NONE; + MODAL.style.bottom = "-60%"; +} + +function handleSaveButtonClick() { + const transactionType = SELECT_TYPE_SPENDING.checked ? TRANSACTION_TYPE.SPENDING : TRANSACTION_TYPE.INCOME; + const money = parseInt(PRICE_INPUT.value.replace(/,/g, "")); + const content = CONTENT_INPUT.value; + const category = SELECTED_CATEGORY.innerText; + + if (!money || !content || category === MESSAGE.CATEGORY_UNSELECTED) { + alert(MESSAGE.EMPTY_FIELD); + resetField(); + } else { + HISTORY_LIST.push({ + id: HISTORY_LIST.length - 1, + type: transactionType, + category: category, + content: content, + money: money, + }); + renderHistoryList(); + renderAssetData(); + alert(MESSAGE.ADD_LIST_SUCCESS); + resetField(); + } +} + +function handlePriceInputFieldInput(e) { + if (isNaN(e.data)) { + alert(MESSAGE.PRICE_IS_NOT_NUMBER); + PRICE_INPUT.value = ""; + } +} + +function resetField() { + PRICE_INPUT.value = ""; + CONTENT_INPUT.value = ""; +} + +export function handleModal() { + SELECTOR.addEventListener("click", handleSelectorClick); + ADD_HISTORY_BUTTON.addEventListener("click", handleAddHistoryButtonClick); + CLOSE_MODAL_BUTTON.addEventListener("click", handleCloseModalButtonClick); + SAVE_BUTTON.addEventListener("click", handleSaveButtonClick); + PRICE_INPUT.addEventListener("input", handlePriceInputFieldInput); +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/TransactionFilter.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/TransactionFilter.js" new file mode 100644 index 0000000..89b1945 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/History/TransactionFilter.js" @@ -0,0 +1,28 @@ +import { TRANSACTION_TYPE, HISTORY_LIST } from "../utils/constants.js"; +import { INCOME_BUTTON, SPENDING_BUTTON } from "../utils/documentElements.js"; +import { renderHistoryList, resetData } from "./HistoryView.js"; + +INCOME_BUTTON.addEventListener("click", handleButtonClick); +SPENDING_BUTTON.addEventListener("click", handleButtonClick); + +function handleButtonClick() { + const isIncomeChecked = INCOME_BUTTON.checked; + const isSpendingChecked = SPENDING_BUTTON.checked; + + if (!isIncomeChecked && !isSpendingChecked) { + // 둘 다 체크 안된 경우 + resetData(); + } else { + const selectedTypes = []; + + isIncomeChecked && selectedTypes.push(TRANSACTION_TYPE.INCOME); + isSpendingChecked && selectedTypes.push(TRANSACTION_TYPE.SPENDING); + + const filteredHistoryList = filterHistoryList(selectedTypes); + renderHistoryList(filteredHistoryList); + } +} + +function filterHistoryList(types) { + return HISTORY_LIST.filter((history) => types.includes(history.type)); +} diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/constants.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/constants.js" new file mode 100644 index 0000000..b94388e --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/constants.js" @@ -0,0 +1,94 @@ +export const INIT_BALANCE = 0; +export const INIT_INCOME = 0; +export const INIT_SPENDING = 0; + +export const TRANSACTION_TYPE = { + SPENDING: 0, + INCOME: 1, +}; + +export const LOCAL_STORAGE = { + SPENDING: "categories-spending", + INCOME: "categories-income", +}; + +export const CATEGORY = { + SPENDING: + localStorage.getItem(LOCAL_STORAGE.SPENDING) !== null //로컬스토리지에 값이 있는지 체크 + ? JSON.parse(localStorage.getItem(LOCAL_STORAGE.SPENDING)) + : ["쇼핑", "교통"], + INCOME: + localStorage.getItem(LOCAL_STORAGE.INCOME) !== null + ? JSON.parse(localStorage.getItem(LOCAL_STORAGE.INCOME)) + : ["이체", "용돈"], +}; + +export const ELEMENT = { + HTMLTAG: { + TEXT: "p", + LIST: "li", + BUTTON: "button", + DIV: "div", + }, + CLASSNAME: { + CATEGORY: "category", + NAME: "name", + PRICE: "price", + SPENDING: "spending", + INCOME: "income", + DELETE: "delete", + MONEY: "money", + TYPE_INCOME: "type-income", + TYPE_SPENDING: "type-spending", + CATEGORY_TAG: "category-tag", + ACTIVE: "active", + }, + ATTRIBUTE: { + DATA_INDEX: "data-index", + }, + STYLE: { + DISPLAY: { + FLEX: "flex", + BLOCK: "block", + NONE: "none", + }, + }, +}; + +export const MESSAGE = { + EMPTY_FIELD: "모든 필드를 입력해주세요", + CATEGORY_UNSELECTED: "카테고리를 선택하세요", + ADD_LIST_SUCCESS: "내역이 추가되었어요", + PRICE_IS_NOT_NUMBER: "금액은 숫자여야 합니다", +}; + +export const HISTORY_LIST = [ + { + id: 0, + type: TRANSACTION_TYPE.INCOME, + category: CATEGORY.INCOME[0], + content: "생활비", + money: 1200000, + }, + { + id: 1, + type: TRANSACTION_TYPE.SPENDING, + category: CATEGORY.INCOME[0], + content: "티머니", + money: 6200, + }, + { + id: 2, + type: TRANSACTION_TYPE.SPENDING, + category: CATEGORY.SPENDING[1], + content: "쿠팡환불", + money: 27000, + }, + { + id: 3, + type: TRANSACTION_TYPE.INCOME, + category: CATEGORY.INCOME[1], + content: "홍길동", + money: 3000, + }, +]; diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/documentElements.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/documentElements.js" new file mode 100644 index 0000000..532f975 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/documentElements.js" @@ -0,0 +1,33 @@ +export const HISTORY_DIV = document.querySelector("#history ul"); + +export const INCOME_BUTTON = document.querySelector("#money-type #type-income"); +export const SPENDING_BUTTON = document.querySelector("#money-type #type-spending"); +export const HOME_BUTTON = document.querySelector("#go-home-button"); +export const ADD_HISTORY_BUTTON = document.querySelector("button#add"); +export const SAVE_BUTTON = document.querySelector("#save"); + +export const TOTAL_MONEY = document.querySelector("#asset #money"); +export const TODY_TOTAL_INCOME = document.querySelector("#today .income"); +export const TODY_TOTAL_SPENDING = document.querySelector("#today .spending"); + +export const MODAL_BACKGROUND = document.querySelector("#modal-background"); +export const MODAL_DELETE = document.querySelector("#delete-modal"); +export const CONFIRM_BUTTON = document.querySelector("button#confirm"); +export const CANCEL_BUTTON = document.querySelector("button#cancel"); + +export const SELECTOR_DIV = document.querySelector(".select-category"); +export const SELECTOR = document.querySelector(".selector"); +export const SELECTED_CATEGORY = document.querySelector(".selected-category"); +export const SELECT_TYPE_INCOME = document.querySelector("#select-income"); +export const SELECT_TYPE_SPENDING = document.querySelector("#select-spending"); + +export const MODAL = document.querySelector("#add-history-modal"); +export const DROP_DOWN_CATEGORIES = document.querySelector("ul.categories"); +export const CLOSE_MODAL_BUTTON = document.querySelector("#close"); +export const PRICE_INPUT = document.querySelector("#input-price"); +export const CONTENT_INPUT = document.querySelector("#input-content"); + +export const INCOME_CATEGORY_INPUT = document.querySelector("#input-income-category"); +export const SPENDING_CATEGORY_INPUT = document.querySelector("#input-spending-category"); +export const INCOME_CATEGORY_SECTION = document.querySelector("#income-category"); +export const SPENDING_CATEGORY_SECTION = document.querySelector("#spending-category"); diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/moneyFormatter.js" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/moneyFormatter.js" new file mode 100644 index 0000000..76ce4dc --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/js/utils/moneyFormatter.js" @@ -0,0 +1,17 @@ +export function changeFormat() { + const money = document.querySelectorAll(".money"); + money.forEach((text) => { + let changedText = text.innerHTML + .toString() + .replace(/\B(? { + let value = e.target.value; + value = Number(value.replaceAll(",", "")); + const formatValue = value.toLocaleString("ko-KR"); + input.value = formatValue; +}); diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/pages/category.html" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/pages/category.html" new file mode 100644 index 0000000..9c2c3b5 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/pages/category.html" @@ -0,0 +1,39 @@ + + + + + + + + + + 수빈 | 가계부 | 카테고리 관리 + + + +
+

카테고리 관리

+
+
+

수입 카테고리

+
+
+
+

카테고리 추가

+ +
+
+
+

지출 카테고리

+
+
+
+

카테고리 추가

+ +
+
+ + + + + \ No newline at end of file diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/category.css" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/category.css" new file mode 100644 index 0000000..a331bb8 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/category.css" @@ -0,0 +1,67 @@ +@import "reset.css"; + +.category-manage-section { + display: flex; + flex-direction: column; + justify-content: center; + gap: 20px; + + padding: 20px; + + border-radius: 12px; + + background-color: #ffffff; +} + +.category-tag-wrapper { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.category-tag { + padding: 8px 16px; + + border-radius: 5px; + + background-color: #E1ECFC; + + color: #4880ee; +} + +.add-category { + display: flex; + justify-content: space-between; + + width: 100%; + + margin-top: 16px; +} + +.input-category { + width: 60%; + + padding-bottom: 5px; + + border: none; + border-bottom: 1px solid #f2f2f2; + outline: none; +} + +#go-home-button { + position: absolute; + bottom: 10px; + + width: calc(100% - 20px); + height: 44px; + + border: none; + border-radius: 6px; + + background-color: #4880ee; + + font-size: 16px; + line-height: 44px; + font-weight: 500; + color: #ffffff; +} \ No newline at end of file diff --git "a/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/reset.css" "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/reset.css" new file mode 100644 index 0000000..0fbdad1 --- /dev/null +++ "b/week2/assignment/\352\260\200\352\263\204\353\266\200 \360\237\222\270/styles/reset.css" @@ -0,0 +1,169 @@ +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, +ul, +li, +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-weight: 500; + 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; +} + +* { + margin: 0px; + padding: 0px; + font-family: Pretendard, sans-serif; + box-sizing: border-box; +} + +html { + background-color: #d9d9d9; +} + +body { + display: flex; + flex-direction: column; + gap: 10px; + width: 100vw; + min-height: 100vh; + margin: auto; + overflow: hidden; + padding: 10px; + background-color: #f8f8f8; +} + +button { + border: none; + cursor: pointer; +} + +header { + padding: 20px; + background-color: #ffffff; + border-radius: 10px; +} + +h1, +h2 { + font-size: 20px; +} \ No newline at end of file diff --git "a/week2/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" "b/week2/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" new file mode 100644 index 0000000..a4edaf6 --- /dev/null +++ "b/week2/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" @@ -0,0 +1,27 @@ +# 🫵🏻 명령형 프로그래밍 , ✋🏻 선언형 프로그래밍 + +## 🥊 명령형 프로그래밍 vs 선언형 프로그래밍 + + +### 🤔 명령형 프로그래밍과 선언형 프로그래밍은 무엇일까? + +명령형 프로그래밍은 컴퓨터에게 `어떻게 어떤 작업을 수행해야 하는지 세세하게 지시`하는 방식,
+프로그래머가 `프로그램 실행 순서`와 `데이터 상태`를 명시적으로 제어한다. + +선언형 프로그래밍은 어떤 작업을 어떻게 하는지에 대한 세부 사항을 명시하지 않고, `원하는 결과를 설명`하는 방식,
+프로그래머는 `무엇(What)`을 얻을 것인지만 명시하며, 시스템은 `어떻게(How)` 이루어져야 하는지 자동으로 결정한다. + +### 🗣️ 각각의 방식을 따르는 언어는 무엇이 있을까? + +명령형 프로그래밍 언어 : C, C++, Java 등
+선언형 프로그래밍 언어 : SQL, (HTML), CSS, 리액트 등 + + +### 🤷🏻 각각의 방식은 어떤 상황/유형에 쓰는 것이 적합할까? + +`목표에 대한 과정`(스텝 하나하나)이 명확히 명시돼어야 할때는 `명령형 언어`를 쓰는 것이 적합할 것 같다
+목표는 명확하지만 어떻게 할지는 중요하지 않은? (중요하지 않다기 보다는 ..) `결과 중심의 작업`을 할 때는 `선언형 언어`가 적합할 것이다 + +### 🍌 JavaScript 에서는 어떤 방식을 선택하는 것이 좋을까? + +자바스크립트에서는 선언형 프로그래밍을 통해 `가독성`이 좋고 `재사용성`성이 좋아지도록 하는 것이 좋을 것 같다 diff --git "a/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.html" "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.html" new file mode 100644 index 0000000..e43bb6d --- /dev/null +++ "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.html" @@ -0,0 +1,146 @@ + + + + + + + + + + 수빈 | 삿포로 여행 계획 + + + +
+

🍣 🍶 🧤 🍡  삿포로 여행 계획  🍣 🍶 🧤 🍡

+
+
+ + + +
+ +
+
+

DAY 1️⃣

+
+ +
+
+
+

DAY 2️⃣

+
+ +
+
+
+

DAY 3️⃣

+
+ +
+ + +
+ 위쪽화살표 +
+
+ + + + \ No newline at end of file diff --git "a/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.js" "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.js" new file mode 100644 index 0000000..f642de9 --- /dev/null +++ "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/index.js" @@ -0,0 +1,68 @@ +/* 스크롤에 따라 탑버튼을 점점 선명하게 만드는 함수 */ +document.addEventListener("scroll", () => { + const topButton = document.querySelector("#top div"); + const opacity = scrollY / (document.body.scrollHeight - window.innerHeight); + topButton.style.opacity = Math.min(opacity, 1); //opacity의 최댓값을 1로 설정하기 위함 +}); + +const detailBox = document.querySelectorAll(".detail"); +const details = document.querySelectorAll(".detail p"); + +function createDetailButton() { + const detailButton = document.createElement("button"); + detailButton.className = "read_more"; + detailButton.innerHTML = "더보기"; + return detailButton; +} + +/* 디테일의 폰트크기와 높이를 이용하여 디테일버튼을 만들어야 할 지 결정하는 함수 */ +function shouldShowButton(detail) { + const detailHeight = window.getComputedStyle(detail).height.split("px")[0]; + const fontSize = window.getComputedStyle(detail).fontSize.split("px")[0]; + return detailHeight > fontSize * 3; //디테일이 세 줄 이상인지를 계산 +} + +function hideButton(button) { + button.style.display = "none"; +} + +function showDetail(detail) { + detail.style.display = "inline"; +} + +/* 조건에 따라 디테일 버튼을 만들고 디테일 버튼의 클릭이벤트를 처리하는 기능 */ +detailBox.forEach((box, index) => { + const detail = details[index]; + if (shouldShowButton(detail)) { + const detailButton = createDetailButton(); + box.appendChild(detailButton); + + detailButton.addEventListener("click", () => { + hideButton(detailButton); + showDetail(detail); + }); + } +}); + +/* preview 섹션 양쪽 끝으로 이동하는 기능 */ +const startButton = document.querySelector(".start"); +const endButton = document.querySelector(".end"); +const previewSection = document.querySelector("#preview .gallery"); + +startButton.addEventListener("click", () => { + const scrollOptions = { + left: 0, + behavior: "smooth", + }; + + previewSection.scrollTo(scrollOptions); +}); + +endButton.addEventListener("click", () => { + const scrollOptions = { + left: previewSection.scrollWidth, + behavior: "smooth", + }; + + previewSection.scrollTo(scrollOptions); +}); diff --git "a/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/style.css" "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/style.css" new file mode 100644 index 0000000..49f1221 --- /dev/null +++ "b/week2/assignment/\354\233\250\353\271\204\354\235\230 \354\202\254\354\247\204\352\264\200 \360\237\223\270/style.css" @@ -0,0 +1,467 @@ +@font-face { + font-family: 'Pretendard'; + src: url('./font/Pretendard-Medium.otf') format('opentype'); +} + +* { + margin: 0px; + padding: 0px; + font-family: Pretendard, sans-serif; +} + +html { + background-color: #DCE4ED; + scroll-behavior: smooth; +} + +a { + text-decoration: none; + color: #000000; +} + +a:hover { + color: #5AB2FF; +} + +p { + background-color: transparent; +} + +img { + object-fit: cover; +} + +header { + width: 1000px; + height: 80px; + margin: 10px auto 10px auto; + text-align: center; + line-height: 80px; + background-color: #86B1E5; + border-radius: 10px; +} + +h1 { + font-size: 24px; + font-weight: 500; +} + +h2 { + font-size: 20px; + font-weight: 500; +} + +h4 { + font-size: 20px; + font-weight: 500; +} + +button { + border: none; + cursor: pointer; +} + +nav { + display: flex; + align-items: center; + justify-content: center; + width: 1000px; + height: 80px; + margin: 10px auto 10px auto; + font-size: 20px; + background-color: #B7CAE2; + border-radius: 10px; +} + +li { + list-style: none; +} + +#preview { + display: flex; + justify-content: space-between; + gap: 10px; + + overflow-x: scroll; + + position: relative; + + width: 1000px; + + margin: 0 auto 10px auto; + padding-bottom: 10px; +} + +#preview .gallery { + display: flex; + justify-content: space-between; + gap: 10px; + + overflow-x: scroll; + + width: 1000px; + + margin: 0 auto 10px auto; + padding-bottom: 10px; +} + +#preview .gallery::-webkit-scrollbar { + width: 10px; +} + +#preview .gallery::-webkit-scrollbar-thumb { + border-radius: 10px; + + background: #86B1E5; +} + +#preview .gallery::-webkit-scrollbar-track { + border-radius: 10px; + + background-color: #B7CAE2; +} + +#preview button { + position: absolute; + top: calc(50% - 90px); + + height: 100px; + width: 50px; +} + +button.start { + left: 0; + + background: no-repeat center/cover url('./img/start.png'); +} + +button.end { + right: 0; + + background: no-repeat center/cover url('./img/end.png'); +} + +#preview img { + width: 350px; + + border-radius: 10px; +} + +#preview img:last-child { + margin-right: 0px; +} + +nav { + display: flex; + align-items: center; + justify-content: center; + + width: 1000px; + height: 80px; + + border-radius: 10px; + + background-color: #B7CAE2; + + margin: 10px auto 10px auto; + font-size: 20px; +} + +nav p { + margin-right: 80px; +} + +nav ul { + display: flex; + justify-content: space-between; + + width: 240px; +} + +nav li { + color: #000000; +} + +nav li:hover { + color: #5AB2FF; + + text-decoration: underline; + + cursor: pointer; +} + +.index { + position: sticky; + top: 0; + z-index: 1; + + width: 1000px; + height: 60px; + + margin: 10px auto; + + border-radius: 8px; + + background-color: #AAC2DD; + + text-align: center; + line-height: 60px; +} + +#day1 .gallery { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 10px; + + max-width: 1000px; + + margin: 10px auto 0; + padding: 0 140px; +} + +#day1 .gallery .item { + flex-grow: 1; + + position: relative; + + width: 180px; + height: 180px; + + border-radius: 10px; + + transition: transform 1s ease, padding 1s ease; +} + +#day1 .gallery .item:hover { + transform: translate(0, -10px); +} + +#day1 .gallery .item:nth-child(1) { + background: no-repeat center/cover url('./img/biei.jpg'); +} + +#day1 .gallery .item:nth-child(2) { + background: no-repeat center/cover url('./img/otaru-canal.jpg'); +} + +#day1 .gallery .item:nth-child(3) { + background: no-repeat center/cover url('./img/ningle-terrace.jpg'); +} + +#day1 .gallery .item:nth-child(4) { + background: no-repeat center/cover url('./img/ski.jpg'); +} + +#day1 .gallery .item:nth-child(5) { + background: no-repeat center/cover url('./img/tv-tower.png'); +} + +#day1 .gallery .item:nth-child(6) { + background: no-repeat center/cover url('./img/sarutama.jpg'); +} + +#day1 .gallery .item:nth-child(7) { + background: no-repeat center/cover url('./img/beer-museum.jpg'); +} + +#day1 .gallery .item:nth-child(8) { + background: no-repeat center/cover url('./img/ferris.png'); +} + +#day1 .gallery .item:nth-child(9) { + background: no-repeat center/cover url('./img/nikka.png'); +} + +#day1 .gallery .item:nth-child(10) { + background: no-repeat center/cover url('./img/ryokan1.jpg'); +} + +#day1 .detail { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 20px; + + position: absolute; + + width: 100%; + height: 180px; + + border-radius: 10px; + text-align: center; + color: #FFFFFF; + + opacity: 0; + + transition: opacity 0.3s ease; +} + +#day1 .detail p { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + + overflow: hidden; + text-overflow: ellipsis; +} + +#day1 .detail button { + padding: 5px 10px; + + border-radius: 20px; +} + +#day1 .detail:hover { + background-color: rgba(0, 0, 0, 0.6); + + opacity: 1; +} + +#day2 .gallery { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + gap: 10px; + + max-width: 1000px; + + margin: 10px auto; + padding: 0 10%; +} + +#day2 .gallery .left { + display: flex; + flex-wrap: wrap; + flex-basis: 50%; + flex: 1; +} + +#day2 .gallery .right { + display: flex; + flex: 1; + flex-basis: 50%; + flex-wrap: wrap; + gap: 10px; + + min-width: 400px; +} + +#day2 .gallery img { + border-radius: 10px; + + transition: transform 1s ease, padding 1s ease; +} + +#day2 .gallery img:hover { + transform: translate(0, -10px); +} + +#day2 .gallery .left img { + flex-grow: 1; + + width: 400px; + height: 420px; +} + + +#day2 .gallery .right img { + flex-grow: 1; + + width: 200px; + height: 205px; +} + +#day3 .gallery { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-template-rows: repeat(4, 1fr); + gap: 10px; + + width: 1000px; + height: 500px; + + margin: 10px auto 0; +} + +#day3 .gallery .item { + border-radius: 10px; +} + +#day3 .gallery .item:nth-child(1) { + grid-column: span 2; + grid-row: span 1; + + background: no-repeat center/cover url('./img/nikka.png'); +} + +#day3 .gallery .item:nth-child(2) { + grid-column: span 2; + grid-row: span 2; + + background: no-repeat center/cover url('./img/ryokan1.jpg'); +} + +#day3 .gallery .item:nth-child(3) { + grid-column: span 2; + grid-row: span 1; + + background: no-repeat center/cover url('./img/beer-museum.jpg'); +} + +#day3 .gallery .item:nth-child(4) { + grid-column: span 3; + grid-row: span 2; + + background: no-repeat center/cover url('./img/ferris.png'); +} + +#day3 .gallery .item:nth-child(5) { + grid-column: span 1; + grid-row: span 2; + + background: no-repeat center/cover url('./img/vending.JPG'); +} + +footer { + display: flex; + justify-content: center; + align-items: center; + + width: 1000px; + height: 150px; + + margin: 10px auto; + + border-radius: 10px; + + background-color: #86B1E5; + + font-size: 24px; + text-align: center; +} + +#top div { + display: flex; + justify-content: center; + align-items: center; + + position: fixed; + bottom: 30px; + right: 30px; + + width: 80px; + height: 80px; + + border-radius: 100%; + + background-color: #FFFFFF; + + opacity: 0; +} + +#top img { + width: 40px; + height: 40px; +} \ No newline at end of file diff --git a/week2/practice/index.css b/week2/practice/index.css new file mode 100644 index 0000000..610f667 --- /dev/null +++ b/week2/practice/index.css @@ -0,0 +1,26 @@ +body { + display: flex; + flex-direction: column; + align-items: center; + background-color: beige; +} + +h1 { + text-align: center; +} + +ul { + font-size: 20px; +} + +.count { + cursor: pointer; +} + +.red { + color: red; +} + +.blue { + color: blue; +} \ No newline at end of file diff --git a/week2/practice/index.html b/week2/practice/index.html new file mode 100644 index 0000000..f513a5a --- /dev/null +++ b/week2/practice/index.html @@ -0,0 +1,25 @@ + + + + + + + + 2차 세미나 실습 + + + +

my favorite fruit list

+ + + + + + + \ No newline at end of file diff --git a/week2/practice/index.js b/week2/practice/index.js new file mode 100644 index 0000000..f68a6bc --- /dev/null +++ b/week2/practice/index.js @@ -0,0 +1,23 @@ +const mango = document.createElement("li"); +const mangoText = document.createTextNode("mango"); // or mango.innerText = "mango" + +mango.appendChild(mangoText); +const fruitList = document.querySelector("ul"); +fruitList.appendChild(mango); + +const redFruit = document.querySelectorAll(".red"); +redFruit.forEach((fruit) => { + fruit.remove(); +}); + +const thirdFruit = document.querySelector("li:nth-child(3)"); +thirdFruit.classList.add("blue"); + +const lengthButton = document.querySelector("button.count"); +lengthButton.addEventListener("click", showLength); + +const allList = document.querySelectorAll("li"); + +function showLength() { + alert(`과일 개수는 ${allList.length}개 입니다`); +} diff --git "a/week3/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" "b/week3/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" new file mode 100644 index 0000000..8d77c92 --- /dev/null +++ "b/week3/assignment/\354\203\235\352\260\201\352\263\274\354\240\234 \360\237\222\255/thinking.md" @@ -0,0 +1,48 @@ +# 🤓 리액트에 대하여 + +## 📁 컴포넌트는 어떤 기준과 방법으로 분리하는 것이 좋을까? + +### ☝🏻 단일 책임 원칙 + +`하나의 컴포넌트`는 `하나의 기능` 또는 역할을 가져야 컴포넌트가 `간단하게 유지`되며 `재사용성이 증가`한다 + +### ♻ 재사용성 + +`다른 곳에서도 사용될 가능성`이 있는 기능은 별도의 컴포넌트로 분리하는 것이 좋은 것 같다
+이렇게 함으로써 `중복`을 피하고 `일관성`을 유지할 수 있다 + +### 🚧 가독성 및 유지보수 + +코드의 `가독성`을 높이고 `유지보수`를 쉽게 하기 위해 `비슷한 기능과 역할`을 가진 코드를 `그룹화`하여 컴포넌트로 분리하는 것이 좋다고 생각한다 + +저는 보통 `UI 단위`로 나누기는 하는데, 컴포넌트가 너무 길어서 `가독성`이 떨어지거나 다른 컴포넌트에서 `재사용`될 수 있다면 +컴포넌트로 분리하는 편이에요 🐝 + +## 🗣️ 좋은 상태 관리란 무엇일까? + +### 🤯 무분별한 전역상태관리는 지양 + +합성 컴포넌트를 적절히 활용하여 `Prop Drilling`을 해소하자! + +### 👥 응집성 + +상태 코드는 연관 컴포넌트들과 `최대한 가까이 배치`하자! => `State Colocation` + +## 🖍️ 렌더링을 효과적으로 관리하는 방법은 무엇이 있을까? + +### 🧠 메모이제이션 + +`Memoization`은 결과를 캐시하여 동일한 입력에 대해 이전에 계산한 값을 `재사용`함으로써 성능을 `최적화`한다
+`React.memo`나 `useMemo`이나 `useCallback`을 사용하여 `중복된 렌더링`을 피할 수 있다 + +## Props Drilling이란 무엇이고 이를 어떻게 해결할 수 있는가? + +`Props Drilling`은 컴포넌트 간에 필요한 데이터를 전달하기 위해 `중간 단계의 컴포넌트`를 거쳐야 하는 상황을 말한다 + +### 🌏 Context API 사용 + +`Context API`를 활용하여 `전역적`으로 데이터를 관리하고 컴포넌트 간에 `직접적`으로 데이터를 전달할 수 있다 + +### 👨🏻‍💼 상태 관리 라이브러리 활용 + +`Redux`나 `recoil`이나 `MobX`와 같은 상태 관리 라이브러리를 사용하여 상태를 `중앙에서 관리`하고 필요한 컴포넌트에 데이터를 제공한다 diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.eslintrc.cjs" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.eslintrc.cjs" new file mode 100644 index 0000000..bb4f312 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.eslintrc.cjs" @@ -0,0 +1,21 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react/jsx-runtime", + "plugin:react-hooks/recommended", + ], + ignorePatterns: ["dist", ".eslintrc.cjs"], + parserOptions: { ecmaVersion: "latest", sourceType: "module" }, + settings: { react: { version: "18.2" } }, + plugins: ["react-refresh"], + rules: { + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + "react/prop-types": "off", + }, +}; diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.gitignore" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.gitignore" new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/.gitignore" @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/README.md" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/README.md" new file mode 100644 index 0000000..f768e33 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/README.md" @@ -0,0 +1,8 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/index.html" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/index.html" new file mode 100644 index 0000000..10df5c5 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/index.html" @@ -0,0 +1,16 @@ + + + + + + + + 수빈 | 오늘의 점메추 🍚 + + + +
+ + + + \ No newline at end of file diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/package.json" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/package.json" new file mode 100644 index 0000000..8477c9a --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/package.json" @@ -0,0 +1,27 @@ +{ + "name": "vite-project", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "styled-components": "^6.1.0" + }, + "devDependencies": { + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@vitejs/plugin-react": "^4.0.3", + "eslint": "^8.45.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "vite": "^4.4.5" + } +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/pnpm-lock.yaml" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/pnpm-lock.yaml" new file mode 100644 index 0000000..05b5765 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/pnpm-lock.yaml" @@ -0,0 +1,2327 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + styled-components: + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.2.0)(react@18.2.0) + +devDependencies: + '@types/react': + specifier: ^18.2.15 + version: 18.2.34 + '@types/react-dom': + specifier: ^18.2.7 + version: 18.2.14 + '@vitejs/plugin-react': + specifier: ^4.0.3 + version: 4.1.1(vite@4.5.0) + eslint: + specifier: ^8.45.0 + version: 8.52.0 + eslint-plugin-react: + specifier: ^7.32.2 + version: 7.33.2(eslint@8.52.0) + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.0(eslint@8.52.0) + eslint-plugin-react-refresh: + specifier: ^0.4.3 + version: 0.4.4(eslint@8.52.0) + vite: + specifier: ^4.4.5 + version: 4.5.0 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@babel/code-frame@7.22.13: + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.20 + chalk: 2.4.2 + dev: true + + /@babel/compat-data@7.23.2: + resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.23.2: + resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helpers': 7.23.2 + '@babel/parser': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.23.0: + resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.2 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.22.1 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.23.2: + resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.22.20: + resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + dev: true + + /@babel/traverse@7.23.2: + resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.23.0: + resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@emotion/is-prop-valid@1.2.1: + resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + dev: false + + /@emotion/unitless@0.8.1: + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + dev: false + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.52.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.23.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.52.0: + resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@types/babel__core@7.20.3: + resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==} + dependencies: + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + '@types/babel__generator': 7.6.6 + '@types/babel__template': 7.4.3 + '@types/babel__traverse': 7.20.3 + dev: true + + /@types/babel__generator@7.6.6: + resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@types/babel__template@7.4.3: + resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==} + dependencies: + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + dev: true + + /@types/babel__traverse@7.20.3: + resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@types/prop-types@15.7.9: + resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} + dev: true + + /@types/react-dom@18.2.14: + resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} + dependencies: + '@types/react': 18.2.34 + dev: true + + /@types/react@18.2.34: + resolution: {integrity: sha512-U6eW/alrRk37FU/MS2RYMjx0Va2JGIVXELTODaTIYgvWGCV4Y4TfTUzG8DdmpDNIT0Xpj/R7GfyHOJJrDttcvg==} + dependencies: + '@types/prop-types': 15.7.9 + '@types/scheduler': 0.16.5 + csstype: 3.1.2 + dev: true + + /@types/scheduler@0.16.5: + resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} + dev: true + + /@types/stylis@4.2.2: + resolution: {integrity: sha512-Rm17MsTpQQP5Jq4BF7CdrxJsDufoiL/q5IbJZYZmOZAJALyijgF7BzLgobXUqraNcQdqFYLYGeglDp6QzaxPpg==} + dev: false + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /@vitejs/plugin-react@4.1.1(vite@4.5.0): + resolution: {integrity: sha512-Jie2HERK+uh27e+ORXXwEP5h0Y2lS9T2PRGbfebiHGlwzDO0dEnd2aNtOR/qjBlPb1YgxwAONeblL1xqLikLag==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.2) + '@types/babel__core': 7.20.3 + react-refresh: 0.14.0 + vite: 4.5.0 + transitivePeerDependencies: + - supports-color + dev: true + + /acorn-jsx@5.3.2(acorn@8.11.2): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.2 + dev: true + + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.5 + is-array-buffer: 3.0.2 + dev: true + + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-string: 1.0.7 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.2: + resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + get-intrinsic: 1.2.2 + dev: true + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + + /asynciterator.prototype@1.0.0: + resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} + dependencies: + has-symbols: 1.0.3 + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /browserslist@4.22.1: + resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001559 + electron-to-chromium: 1.4.575 + node-releases: 2.0.13 + update-browserslist-db: 1.0.13(browserslist@4.22.1) + dev: true + + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + + /caniuse-lite@1.0.30001559: + resolution: {integrity: sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA==} + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 + object-keys: 1.1.1 + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /electron-to-chromium@1.4.575: + resolution: {integrity: sha512-kY2BGyvgAHiX899oF6xLXSIf99bAvvdPhDoJwG77nxCSyWYuRH6e9a9a3gpXBvCs6lj4dQZJkfnW2hdKWHEISg==} + dev: true + + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.2 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + internal-slot: 1.0.6 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.13 + dev: true + + /es-iterator-helpers@1.0.15: + resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} + dependencies: + asynciterator.prototype: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-set-tostringtag: 2.0.2 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + globalthis: 1.0.3 + has-property-descriptors: 1.0.1 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.6 + iterator.prototype: 1.1.2 + safe-array-concat: 1.0.1 + dev: true + + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + has-tostringtag: 1.0.0 + hasown: 2.0.0 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.0 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@8.52.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.52.0 + dev: true + + /eslint-plugin-react-refresh@0.4.4(eslint@8.52.0): + resolution: {integrity: sha512-eD83+65e8YPVg6603Om2iCIwcQJf/y7++MWm4tACtEswFLYMwxwVWAfwN+e19f5Ad/FOyyNg9Dfi5lXhH3Y3rA==} + peerDependencies: + eslint: '>=7' + dependencies: + eslint: 8.52.0 + dev: true + + /eslint-plugin-react@7.33.2(eslint@8.52.0): + resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.2 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.15 + eslint: 8.52.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + object.hasown: 1.1.3 + object.values: 1.1.7 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.10 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.52.0: + resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.52.0 + '@humanwhocodes/config-array': 0.11.13 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.23.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.1.1 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.1.1: + resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==} + engines: {node: '>=12.0.0'} + dependencies: + flatted: 3.2.9 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + dependencies: + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.23.0: + resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + hasown: 2.0.0 + side-channel: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.13 + dev: true + + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.4 + set-function-name: 2.0.1 + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.7 + array.prototype.flat: 1.3.2 + object.assign: 4.1.4 + object.values: 1.1.7 + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.7: + resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.hasown@1.1.3: + resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: false + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: false + + /reflect.getprototypeof@1.0.4: + resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + globalthis: 1.0.3 + which-builtin-type: 1.1.3 + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-regex: 1.1.4 + dev: true + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + + /shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /string.prototype.matchall@4.0.10: + resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + internal-slot: 1.0.6 + regexp.prototype.flags: 1.5.1 + set-function-name: 2.0.1 + side-channel: 1.0.4 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /styled-components@6.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VWNfYYBuXzuLS/QYEeoPgMErP26WL+dX9//rEh80B2mmlS1yRxRxuL5eax4m6ybYEUoHWlTy2XOU32767mlMkg==} + engines: {node: '>= 16'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + dependencies: + '@emotion/is-prop-valid': 1.2.1 + '@emotion/unitless': 0.8.1 + '@types/stylis': 4.2.2 + css-to-react-native: 3.2.0 + csstype: 3.1.2 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + shallowequal: 1.1.0 + stylis: 4.3.0 + tslib: 2.6.2 + dev: false + + /stylis@4.3.0: + resolution: {integrity: sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.5 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.1): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.1 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /vite@4.5.0: + resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.18.20 + postcss: 8.4.31 + rollup: 3.29.4 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.0 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.13 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/public/vite.svg" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/public/vite.svg" new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/public/vite.svg" @@ -0,0 +1 @@ + \ No newline at end of file diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/App.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/App.jsx" new file mode 100644 index 0000000..13015c5 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/App.jsx" @@ -0,0 +1,254 @@ +import { useReducer } from "react"; + +import TypeSelectPage from "./pages/TypeSelectPage"; +import StartPage from "./pages/StartPage"; +import ResultPage from "./pages/ResultPage"; +import TypeQuestionPage from "./pages/TypeQuestionPage"; +import RandomRecommendPage from "./pages/CountdownPage"; +import { PAGE } from "./utils/page"; +import { RECOMMEND_BY } from "./utils/recommendType"; +import { foodData } from "./utils/foodData"; +import { amountOptions, regionOptions, tasteOptions } from "./utils/options"; + +const initialState = { + page: 0, + selectedRecommendType: "", + selectedRegion: "", + selectedAmount: "", + selectedTaste: "", + result: "", +}; + +const reducer = (state, action) => { + switch (action.type) { + case "MOVE_TO_PREV_PAGE": // 이전 페이지로 이동 + return { ...state, page: state.page - 1 }; + case "MOVE_TO_NEXT_PAGE": // 다음 페이지로 이동 + return { ...state, page: state.page + 1 }; + case "MOVE_TO_PAGE": // 특정 페이지로 이동 + return { ...state, page: action.payload }; + case "SET_SELECTED_RECOMMEND_TYPE": + return { ...state, selectedRecommendType: action.payload }; + case "SET_SELECTED_REGION": + return { ...state, selectedRegion: action.payload }; + case "SET_SELECTED_AMOUNT": + return { ...state, selectedAmount: action.payload }; + case "SET_SELECTED_TASTE": + return { ...state, selectedTaste: action.payload }; + case "SET_RESULT": + return { ...state, result: action.payload }; + default: + return state; + } +}; + +function App() { + const [state, dispatch] = useReducer(reducer, initialState); + + /* 이전 페이지로 */ + const prevPage = () => { + dispatch({ type: "MOVE_TO_PREV_PAGE" }); + }; + + /* 다음 페이지로 */ + const nextPage = (currentPage, selectedType) => { + switch (currentPage) { + /* 타입 선택 페이지 */ + case PAGE.TYPE_SELECT: + dispatch({ + type: "SET_SELECTED_RECOMMEND_TYPE", + payload: selectedType, + }); + dispatch({ type: "MOVE_TO_NEXT_PAGE" }); + break; + + /* 시작 페이지 */ + case PAGE.START: + selectedType === RECOMMEND_BY.TYPE //취향대로 추천인지 랜덤추천인지에 따라 페이지 이동 + ? dispatch({ + type: "MOVE_TO_PAGE", + payload: PAGE.RECOMMEND_BY_TYPE_QUESTION_1, + }) + : dispatch({ + type: "MOVE_TO_PAGE", + payload: PAGE.RECOMMEND_BY_RANDOM, + }); + break; + + /* 취향대로 - 1 */ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_1: + dispatch({ type: "MOVE_TO_NEXT_PAGE" }); + break; + + /* 취향대로 - 2 */ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_2: + dispatch({ type: "MOVE_TO_NEXT_PAGE" }); + break; + + /* 취향대로 - 3 */ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_3: + resultPage(); + break; + + default: + dispatch({ type: "MOVE_TO_NEXT_PAGE" }); + break; + } + }; + + /* 선택된 답변에 해당하는 음식의 점수를 증가 시킨 후 가장 점수가 높은 음식을 찾아 결과 화면으로 이동 */ + const resultPage = () => { + Object.keys(foodData).forEach((food) => { + foodData[food].region === state.selectedRegion && foodData[food].score++; + foodData[food].amount === state.selectedAmount && foodData[food].score++; + foodData[food].taste === state.selectedTaste && foodData[food].score++; + }); + + findBestFood(); + + dispatch({ type: "MOVE_TO_NEXT_PAGE" }); + }; + + /* 가장 점수가 높은 음식을 찾는 함수 */ + const findBestFood = () => { + let bestFoods = []; + let maxCount = -1; + + for (const food in foodData) { + if (foodData[food].score > maxCount) { + bestFoods = [food]; + maxCount = foodData[food].score; + } else if (foodData[food].score === maxCount) { + bestFoods.push(food); + } + } + + const randomIndex = Math.floor(Math.random() * bestFoods.length); + + dispatch({ + type: "SET_RESULT", + payload: foodData[bestFoods[randomIndex]].image, + }); + }; + + /* 답변 저장 */ + const saveAnswer = (value, questionNumber) => { + switch (questionNumber) { + case PAGE.RECOMMEND_BY_TYPE_QUESTION_1: + dispatch({ type: "SET_SELECTED_REGION", payload: value }); + break; + + case PAGE.RECOMMEND_BY_TYPE_QUESTION_2: + dispatch({ type: "SET_SELECTED_AMOUNT", payload: value }); + break; + + case PAGE.RECOMMEND_BY_TYPE_QUESTION_3: + dispatch({ type: "SET_SELECTED_TASTE", payload: value }); + break; + + default: + break; + } + }; + + /* 답변 초기화 */ + const resetAnswer = () => { + dispatch({ type: "SET_SELECTED_REGION", payload: "" }); + dispatch({ type: "SET_SELECTED_AMOUNT", payload: "" }); + dispatch({ type: "SET_SELECTED_TASTE", payload: "" }); + dispatch({ type: "SET_RESULT", payload: "" }); + Object.keys(foodData).forEach((food) => { + foodData[food].score = 0; + }); + }; + + /* 다시하기 */ + const retry = () => { + resetAnswer(); + dispatch({ type: "MOVE_TO_PAGE", payload: PAGE.START }); + }; + + /* 처음으로 */ + const restart = () => { + resetAnswer(); + dispatch({ type: "MOVE_TO_PAGE", payload: PAGE.TYPE_SELECT }); + }; + + { + switch (state.page) { + /* 추천 방식 선택 화면 */ + case PAGE.TYPE_SELECT: + return ; + + /* 선택된 추천 방식 확인 & 시작 화면 */ + case PAGE.START: + return ( + + ); + + /* 취향대로 추천 - 첫번째 질문 - 나는 지금 __ 이 땡긴다!*/ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_1: + return ( + + ); + + /* 취향대로 추천 - 두번째 질문 - 나는 지금 ___ 하게 먹고 싶다! */ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_2: + return ( + + ); + + /* 취향대로 추천 - 세번째 질문 - 나는 지금 __ 맛이 땡긴다! */ + case PAGE.RECOMMEND_BY_TYPE_QUESTION_3: + return ( + + ); + + /* 취향대로 추천 - 결과 페이지 */ + case PAGE.RECOMMEND_BY_TYPE_RESULT: + return ( + + ); + + /* 랜덤 추천 페이지 */ + case PAGE.RECOMMEND_BY_RANDOM: + return ; + + default: + break; + } + } +} + +export default App; diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/assets/react.svg" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/assets/react.svg" new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/assets/react.svg" @@ -0,0 +1 @@ + \ No newline at end of file diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Header.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Header.jsx" new file mode 100644 index 0000000..3bcb6d7 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Header.jsx" @@ -0,0 +1,22 @@ +import { Button } from "../styles/commonStyle"; +import { styled } from "styled-components"; + +const HeaderWrapper = styled.header` + display: flex; + justify-content: space-between; + + padding: 20px 0; +`; + +const Title = styled.h1` + font-size: ${({ theme }) => theme.fontSize.md}; +`; + +export default function Header({ isTypeSelectPage, restart }) { + return ( + + 오늘의 점메추 + {!isTypeSelectPage && } + + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainCharacter.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainCharacter.jsx" new file mode 100644 index 0000000..72fee23 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainCharacter.jsx" @@ -0,0 +1,10 @@ +import mainCharacter from "../assets/img/character.png"; +import { styled } from "styled-components"; + +const Character = styled.img` + width: 150px; +`; + +export default function MainCharacter() { + return ; +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainSection.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainSection.jsx" new file mode 100644 index 0000000..67e53fe --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/MainSection.jsx" @@ -0,0 +1,57 @@ +import { useEffect } from "react"; +import { useMemo, useState } from "react"; +import { Answer, Quetion, Section } from "../styles/commonStyle"; +import { PAGE } from "../utils/page"; +import { QUESTION } from "../utils/question"; +import Header from "./Header"; +import MainCharacter from "./MainCharacter"; +import ProgressBar from "./ProgressBar"; + +const MainSection = ({ page, nav, restart, contents }) => { + const mainCharacter = useMemo(() => , []); + const [question, setQuestion] = useState(""); + const isQuestionPage = + page === PAGE.RECOMMEND_BY_TYPE_QUESTION_1 || + page === PAGE.RECOMMEND_BY_TYPE_QUESTION_2 || + page === PAGE.RECOMMEND_BY_TYPE_QUESTION_3; + useEffect(() => { + switch (page) { + case PAGE.TYPE_SELECT: + setQuestion(QUESTION.type.question); + break; + case PAGE.START: + setQuestion(QUESTION.type.question); + break; + case PAGE.RECOMMEND_BY_TYPE_QUESTION_1: + setQuestion(QUESTION.region.question); + break; + case PAGE.RECOMMEND_BY_TYPE_QUESTION_2: + setQuestion(QUESTION.amount.question); + break; + case PAGE.RECOMMEND_BY_TYPE_QUESTION_3: + setQuestion(QUESTION.taste.question); + break; + case PAGE.RECOMMEND_BY_TYPE_RESULT: + setQuestion(QUESTION.result.title); + } + }, [page]); + + return ( + <> + {page === PAGE.TYPE_SELECT ? ( +
+ ) : ( +
+ )} +
+ {} + {isQuestionPage && } + {question} + {contents} + {mainCharacter} + {nav} +
+ + ); +}; +export default MainSection; diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Option.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Option.jsx" new file mode 100644 index 0000000..4f6435c --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/Option.jsx" @@ -0,0 +1,20 @@ +import { BalloonText, RadioBalloon, RadioInput } from "../styles/commonStyle"; + +export const Option = ({ option, saveAnswer, currentPage, selectedValue }) => { + const { id, name, label } = option; + + return ( +
+ saveAnswer(id, currentPage)} + checked={selectedValue === id} + > + + {label} + +
+ ); +}; diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/PageMoveButton.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/PageMoveButton.jsx" new file mode 100644 index 0000000..9629edf --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/PageMoveButton.jsx" @@ -0,0 +1,30 @@ +import { + ActiveNextButton, + ButtonSection, + DisabledNextButton, + PrevButton, +} from "../styles/commonStyle"; + +export default function PageMoveButton({ + currentPage, + isSelected, + prevPage, + nextPage, +}) { + return ( + + prevPage()}> + 이전으로 + + {isSelected ? ( + nextPage(currentPage)}> + 다음으로 + + ) : ( + + 다음으로 + + )} + + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/ProgressBar.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/ProgressBar.jsx" new file mode 100644 index 0000000..ef5a89e --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/components/ProgressBar.jsx" @@ -0,0 +1,31 @@ +import { styled } from "styled-components"; + +const Wrapper = styled.div` + height: 1rem; + width: 90%; + + margin-bottom: 30px; + + border-radius: 20px; + + background-color: ${({ theme }) => theme.colors.grey}; +`; + +const Progress = styled.div` + height: 1rem; + width: ${({ page }) => page * 33.3}%; + + border-radius: 20px; + + background-color: ${({ theme }) => theme.colors.secondary}; + + transition: width 0.5s ease; +`; + +export default function ProgressBar({ page }) { + return ( + + + + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/main.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/main.jsx" new file mode 100644 index 0000000..956096e --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/main.jsx" @@ -0,0 +1,15 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.jsx"; +import GlobalStyle from "./styles/GlobalStyle.js"; +import { ThemeProvider } from "styled-components"; +import theme from "./styles/theme.js"; + +ReactDOM.createRoot(document.getElementById("root")).render( + + + + + + +); diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/CountdownPage.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/CountdownPage.jsx" new file mode 100644 index 0000000..5e4102b --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/CountdownPage.jsx" @@ -0,0 +1,111 @@ +import { Section, WhiteBox } from "../styles/commonStyle"; +import Header from "../components/Header"; +import spinner1 from "../assets/img/spinner1.png"; +import spinner2 from "../assets/img/spinner2.png"; +import spinner3 from "../assets/img/spinner3.png"; +import { styled } from "styled-components"; +import { useState, useEffect, useRef } from "react"; +import ResultPage from "./ResultPage"; +import { foodData } from "../utils/foodData"; + +const LoadingBox = styled(WhiteBox)` + width: 500px; + height: 500px; +`; + +const CountNumber = styled.p` + color: ${({ theme }) => theme.colors.black}; + font-size: ${({ theme }) => theme.fontSize.lg}; +`; + +const Spinner = styled.img` + position: absolute; + + width: 400px; + + animation: rotate_image 5s linear infinite; + transform-origin: 50% 50%; + @keyframes rotate_image { + 100% { + transform: rotate(360deg); + } + } +`; + +export default function CountdownPage({ retry, restart }) { + const [count, setCount] = useState(3); + const [image, setImage] = useState(spinner1); + const [isFinish, setIsFinish] = useState(false); + const [result, setResult] = useState(""); + + function useInterval(callback, delay) { + const savedCallback = useRef(); + useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + useEffect(() => { + function tick() { + savedCallback.current(); + } + if (delay !== null) { + let id = setInterval(tick, delay); + return () => clearInterval(id); + } + }, [delay]); + } + + const makeRandomResult = () => { + const foodArray = Object.keys(foodData); + const randomIndex = Math.floor(Math.random() * foodArray.length); + const randomFood = foodData[foodArray[randomIndex]].image; + setResult(randomFood); + }; + + useInterval(() => { + if (count === 1) { + setIsFinish(true); + } else { + setCount(count - 1); + } + }, 1000); + + useEffect(() => { + makeRandomResult(); + }, []); + + useEffect(() => { + const changeSpinner = () => { + switch (count) { + case 3: + setImage(spinner1); + break; + case 2: + setImage(spinner2); + break; + case 1: + setImage(spinner3); + break; + default: + setImage(spinner1); + break; + } + }; + + changeSpinner(); + }, [count]); + + return isFinish ? ( //랜덤 추천 결과 페이지 + + ) : ( + <> +
+
+ + {count} + + +
+ + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/ResultPage.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/ResultPage.jsx" new file mode 100644 index 0000000..701a840 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/ResultPage.jsx" @@ -0,0 +1,31 @@ +import { Button, WhiteBox } from "../styles/commonStyle"; +import { styled } from "styled-components"; +import MainSection from "../components/MainSection"; +import { PAGE } from "../utils/page"; + +const FoodImg = styled.img` + width: 150px; +`; + +export default function ResultPage({ type, result, retry, restart }) { + const contents = ( + + + + ); + + const nav = ( + + ); + + return ( + + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/StartPage.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/StartPage.jsx" new file mode 100644 index 0000000..a7cf8db --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/StartPage.jsx" @@ -0,0 +1,24 @@ +import MainSection from "../components/MainSection"; +import { BalloonText, Button, WhiteBox } from "../styles/commonStyle"; +import { PAGE } from "../utils/page"; + +export default function StartPage({ answer, nextPage, restart }) { + const contents = ( + + {answer} + + ); + const nav = ( + + ); + return ( + <> + + + ); +} diff --git "a/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/TypeQuestionPage.jsx" "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/TypeQuestionPage.jsx" new file mode 100644 index 0000000..a9a0da1 --- /dev/null +++ "b/week3/assignment/\354\240\220\353\251\224\354\266\224 \360\237\215\232/src/pages/TypeQuestionPage.jsx" @@ -0,0 +1,52 @@ +import PageMoveButton from "../components/PageMoveButton"; +import ProgressBar from "../components/ProgressBar"; +import { Option } from "../components/Option"; +import MainSection from "../components/MainSection"; + +const TypeQuestionPage = ({ + page, + options, + selectedValue, + saveAnswer, + currentPage, + prevPage, + nextPage, + restart, +}) => { + const contents = ( + <> + {options.map((option) => ( +