├── .gitignore ├── README.md ├── add.html ├── book.html ├── css ├── add.css ├── book.css ├── edit.css ├── index.css └── login.css ├── edit.html ├── index.html ├── js ├── add.js ├── book.js ├── edit.js ├── index.js └── login.js ├── login.html ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fast campus Online JavaScript Project 2 | 3 | [Slide](https://slides.com/woongjae/fc-javascript) 4 | 5 | ``` 6 | npm i 7 | npm start 8 | ``` 9 | -------------------------------------------------------------------------------- /add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Faborite Books 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |

Book Save Form

23 |

24 | Below is an example of a form that stores book information. Each 25 | required group of forms has a validation status that can be triggered 26 | by an attempt to submit a form without completing it. 27 |

28 |
29 | 30 |
31 |
32 |

Book Info

33 |
34 |
35 | 38 | 45 |
46 | 47 |
48 | 51 | 58 |
59 | 60 |
61 | 64 | 71 |
72 | 73 |
74 | 77 | 84 |
85 | 86 |
87 | 88 | 91 |
92 |
93 |
94 | 95 | 98 |
99 | 100 | 101 | 102 | 107 | 112 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /book.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Faborite Books 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 |
21 | 45 | 63 |
64 |
65 |
66 |
67 |

Book example

68 |

69 | This project is an example for beginners studying JavaScript.
70 | You can add your favorite book and check it out of the list.
71 | You can delete or modify the book that you add. 72 |

73 |

74 | Add Book 75 |

76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 85 | 103 | 104 | 105 | 106 | 111 | 116 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /css/add.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 960px; 3 | } 4 | 5 | .lh-condensed { 6 | line-height: 1.25; 7 | } 8 | -------------------------------------------------------------------------------- /css/book.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding-top: 3rem; 3 | padding-bottom: 3rem; 4 | margin-bottom: 0; 5 | background-color: #fff; 6 | } 7 | @media (min-width: 768px) { 8 | .jumbotron { 9 | padding-top: 6rem; 10 | padding-bottom: 6rem; 11 | } 12 | } 13 | 14 | .jumbotron p:last-child { 15 | margin-bottom: 0; 16 | } 17 | 18 | .jumbotron-heading { 19 | font-weight: 300; 20 | } 21 | 22 | .jumbotron .container { 23 | max-width: 40rem; 24 | } 25 | 26 | footer { 27 | padding-top: 3rem; 28 | padding-bottom: 3rem; 29 | } 30 | 31 | footer p { 32 | margin-bottom: 0.25rem; 33 | } 34 | -------------------------------------------------------------------------------- /css/edit.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 960px; 3 | } 4 | 5 | .lh-condensed { 6 | line-height: 1.25; 7 | } 8 | -------------------------------------------------------------------------------- /css/index.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding-top: 3rem; 3 | padding-bottom: 3rem; 4 | margin-bottom: 0; 5 | background-color: #fff; 6 | } 7 | @media (min-width: 768px) { 8 | .jumbotron { 9 | padding-top: 6rem; 10 | padding-bottom: 6rem; 11 | } 12 | } 13 | 14 | .jumbotron p:last-child { 15 | margin-bottom: 0; 16 | } 17 | 18 | .jumbotron-heading { 19 | font-weight: 300; 20 | } 21 | 22 | .jumbotron .container { 23 | max-width: 40rem; 24 | } 25 | 26 | footer { 27 | padding-top: 3rem; 28 | padding-bottom: 3rem; 29 | } 30 | 31 | footer p { 32 | margin-bottom: 0.25rem; 33 | } 34 | -------------------------------------------------------------------------------- /css/login.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | body { 7 | display: -ms-flexbox; 8 | display: flex; 9 | -ms-flex-align: center; 10 | align-items: center; 11 | padding-top: 40px; 12 | padding-bottom: 40px; 13 | background-color: #f5f5f5; 14 | } 15 | 16 | .form-signin { 17 | width: 100%; 18 | max-width: 330px; 19 | padding: 15px; 20 | margin: auto; 21 | } 22 | 23 | .form-signin .form-control { 24 | position: relative; 25 | box-sizing: border-box; 26 | height: auto; 27 | padding: 10px; 28 | font-size: 16px; 29 | } 30 | .form-signin .form-control:focus { 31 | z-index: 2; 32 | } 33 | .form-signin input[type='email'] { 34 | margin-bottom: -1px; 35 | border-bottom-right-radius: 0; 36 | border-bottom-left-radius: 0; 37 | } 38 | .form-signin input[type='password'] { 39 | margin-bottom: 10px; 40 | border-top-left-radius: 0; 41 | border-top-right-radius: 0; 42 | } 43 | -------------------------------------------------------------------------------- /edit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Faborite Books 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |

Book Save Form

23 |

24 | Below is an example of a form that stores book information. Each 25 | required group of forms has a validation status that can be triggered 26 | by an attempt to submit a form without completing it. 27 |

28 |
29 | 30 |
31 |
32 |

Book Edit

33 |
34 |
35 | 38 | 45 |
46 | 47 |
48 | 51 | 58 |
59 | 60 |
61 | 64 | 71 |
72 | 73 |
74 | 77 | 84 |
85 | 86 |
87 | 88 | 91 | 92 | 95 |
96 |
97 |
98 | 99 | 102 |
103 | 104 | 105 | 106 | 111 | 116 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Faborite Books 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 |
21 | 45 | 63 |
64 |
65 |
66 |
67 |

Book example

68 |

69 | This project is an example for beginners studying JavaScript.
70 | You can add your favorite book and check it out of the list.
71 | You can delete or modify the book that you add. 72 |

73 |

74 | Add Book 75 |

76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 85 | 103 | 104 | 105 | 106 | 111 | 116 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /js/add.js: -------------------------------------------------------------------------------- 1 | function getToken() { 2 | return localStorage.getItem('token'); 3 | } 4 | 5 | async function getUserByToken(token) { 6 | try { 7 | const res = await axios.get('https://api.marktube.tv/v1/me', { 8 | headers: { 9 | Authorization: `Bearer ${token}`, 10 | }, 11 | }); 12 | return res.data; 13 | } catch (error) { 14 | console.log('getUserByToken error', error); 15 | return null; 16 | } 17 | } 18 | 19 | async function save(event) { 20 | event.preventDefault(); 21 | event.stopPropagation(); 22 | event.target.classList.add('was-validated'); 23 | 24 | const titleElement = document.querySelector('#title'); 25 | const messageElement = document.querySelector('#message'); 26 | const authorElement = document.querySelector('#author'); 27 | const urlElement = document.querySelector('#url'); 28 | 29 | const title = titleElement.value; 30 | const message = messageElement.value; 31 | const author = authorElement.value; 32 | const url = urlElement.value; 33 | 34 | if (title === '' || message === '' || author === '' || url === '') { 35 | return; 36 | } 37 | 38 | const token = getToken(); 39 | if (token === null) { 40 | location.href = '/login'; 41 | return; 42 | } 43 | 44 | try { 45 | await axios.post( 46 | 'https://api.marktube.tv/v1/book', 47 | { 48 | title, 49 | message, 50 | author, 51 | url, 52 | }, 53 | { 54 | headers: { 55 | Authorization: `Bearer ${token}`, 56 | }, 57 | }, 58 | ); 59 | location.href = '/'; 60 | } catch (error) { 61 | console.log('save error', error); 62 | alert('책 추가 실패'); 63 | } 64 | } 65 | 66 | function bindSaveButton() { 67 | const form = document.querySelector('#form-add-book'); 68 | form.addEventListener('submit', save); 69 | } 70 | 71 | async function main() { 72 | // 버튼에 이벤트 연결 73 | bindSaveButton(); 74 | 75 | // 토큰 체크 76 | const token = getToken(); 77 | if (token === null) { 78 | location.href = '/login'; 79 | return; 80 | } 81 | 82 | // 토큰으로 서버에서 나의 정보 받아오기 83 | const user = await getUserByToken(token); 84 | if (user === null) { 85 | localStorage.clear(); 86 | location.href = '/login'; 87 | return; 88 | } 89 | } 90 | 91 | document.addEventListener('DOMContentLoaded', main); 92 | -------------------------------------------------------------------------------- /js/book.js: -------------------------------------------------------------------------------- 1 | function getToken() { 2 | return localStorage.getItem('token'); 3 | } 4 | 5 | async function getUserByToken(token) { 6 | try { 7 | const res = await axios.get('https://api.marktube.tv/v1/me', { 8 | headers: { 9 | Authorization: `Bearer ${token}`, 10 | }, 11 | }); 12 | return res.data; 13 | } catch (error) { 14 | console.log('getUserByToken error', error); 15 | return null; 16 | } 17 | } 18 | 19 | async function logout() { 20 | const token = getToken(); 21 | if (token === null) { 22 | location = '/login'; 23 | return; 24 | } 25 | try { 26 | await axios.delete('https://api.marktube.tv/v1/me', { 27 | headers: { 28 | Authorization: `Bearer ${token}`, 29 | }, 30 | }); 31 | } catch (error) { 32 | console.log('logout error', error); 33 | } finally { 34 | localStorage.clear(); 35 | window.location.href = '/login'; 36 | } 37 | } 38 | 39 | async function getBook(bookId) { 40 | const token = getToken(); 41 | if (token === null) { 42 | location.href = '/login'; 43 | return null; 44 | } 45 | try { 46 | const res = await axios.get(`https://api.marktube.tv/v1/book/${bookId}`, { 47 | headers: { 48 | Authorization: `Bearer ${token}`, 49 | }, 50 | }); 51 | return res.data; 52 | } catch (error) { 53 | console.log('getBook error', error); 54 | return null; 55 | } 56 | } 57 | 58 | async function deleteBook(bookId) { 59 | const token = getToken(); 60 | if (token === null) { 61 | location = '/login'; 62 | return; 63 | } 64 | await axios.delete(`https://api.marktube.tv/v1/book/${bookId}`, { 65 | headers: { 66 | Authorization: `Bearer ${token}`, 67 | }, 68 | }); 69 | } 70 | 71 | function bindLogoutButton() { 72 | const btnLogout = document.querySelector('#btn_logout'); 73 | btnLogout.addEventListener('click', logout); 74 | } 75 | 76 | function render(book) { 77 | const detailElement = document.querySelector('#detail'); 78 | 79 | detailElement.innerHTML = `
80 |

${book.title}

81 |
82 |
"${book.message}"
83 |

글쓴이 : ${book.author}

84 |

링크 : 바로 가기

87 | Edit 88 | 89 |
90 | 95 |
`; 96 | 97 | document.querySelector('#btn-delete').addEventListener('click', async () => { 98 | try { 99 | await deleteBook(book.bookId); 100 | location.href = '/'; 101 | } catch (error) { 102 | console.log(error); 103 | } 104 | }); 105 | } 106 | 107 | async function main() { 108 | // 버튼에 이벤트 연결 109 | bindLogoutButton(); 110 | 111 | // 브라우저에서 id 가져오기 112 | const bookId = new URL(location.href).searchParams.get('id'); 113 | 114 | // 토큰 체크 115 | const token = getToken(); 116 | if (token === null) { 117 | location.href = '/login'; 118 | return; 119 | } 120 | 121 | // 토큰으로 서버에서 나의 정보 받아오기 122 | const user = await getUserByToken(token); 123 | if (user === null) { 124 | localStorage.clear(); 125 | location.href = '/login'; 126 | return; 127 | } 128 | 129 | // 책을 서버에서 받아오기 130 | const book = await getBook(bookId); 131 | if (book === null) { 132 | alert('서버에서 책 가져오기 실패'); 133 | return; 134 | } 135 | 136 | // 받아온 책을 그리기 137 | render(book); 138 | } 139 | 140 | document.addEventListener('DOMContentLoaded', main); 141 | -------------------------------------------------------------------------------- /js/edit.js: -------------------------------------------------------------------------------- 1 | function getToken() { 2 | return localStorage.getItem('token'); 3 | } 4 | 5 | async function getUserByToken(token) { 6 | try { 7 | const res = await axios.get('https://api.marktube.tv/v1/me', { 8 | headers: { 9 | Authorization: `Bearer ${token}`, 10 | }, 11 | }); 12 | return res.data; 13 | } catch (error) { 14 | console.log('getUserByToken error', error); 15 | return null; 16 | } 17 | } 18 | 19 | async function logout() { 20 | const token = getToken(); 21 | if (token === null) { 22 | location = '/login'; 23 | return; 24 | } 25 | try { 26 | await axios.delete('https://api.marktube.tv/v1/me', { 27 | headers: { 28 | Authorization: `Bearer ${token}`, 29 | }, 30 | }); 31 | } catch (error) { 32 | console.log('logout error', error); 33 | } finally { 34 | localStorage.clear(); 35 | window.location.href = '/login'; 36 | } 37 | } 38 | 39 | async function getBook(bookId) { 40 | const token = getToken(); 41 | if (token === null) { 42 | location.href = '/login'; 43 | return null; 44 | } 45 | try { 46 | const res = await axios.get(`https://api.marktube.tv/v1/book/${bookId}`, { 47 | headers: { 48 | Authorization: `Bearer ${token}`, 49 | }, 50 | }); 51 | return res.data; 52 | } catch (error) { 53 | console.log('getBook error', error); 54 | return null; 55 | } 56 | } 57 | 58 | async function updateBook(bookId) { 59 | const titleElement = document.querySelector('#title'); 60 | const messageElement = document.querySelector('#message'); 61 | const authorElement = document.querySelector('#author'); 62 | const urlElement = document.querySelector('#url'); 63 | 64 | const title = titleElement.value; 65 | const message = messageElement.value; 66 | const author = authorElement.value; 67 | const url = urlElement.value; 68 | 69 | if (title === '' || message === '' || author === '' || url === '') { 70 | return; 71 | } 72 | 73 | const token = getToken(); 74 | if (token === null) { 75 | location = '/login'; 76 | return; 77 | } 78 | 79 | await axios.patch( 80 | `https://api.marktube.tv/v1/book/${bookId}`, 81 | { 82 | title, 83 | message, 84 | author, 85 | url, 86 | }, 87 | { 88 | headers: { 89 | Authorization: `Bearer ${token}`, 90 | }, 91 | }, 92 | ); 93 | } 94 | 95 | function bindLogoutButton() { 96 | const btnLogout = document.querySelector('#btn_logout'); 97 | btnLogout.addEventListener('click', logout); 98 | } 99 | 100 | function render(book) { 101 | const titleElement = document.querySelector('#title'); 102 | titleElement.value = book.title; 103 | 104 | const messageElement = document.querySelector('#message'); 105 | messageElement.value = book.message; 106 | 107 | const authorElement = document.querySelector('#author'); 108 | authorElement.value = book.author; 109 | 110 | const urlElement = document.querySelector('#url'); 111 | urlElement.value = book.url; 112 | 113 | const form = document.querySelector('#form-edit-book'); 114 | form.addEventListener('click', async event => { 115 | event.preventDefault(); 116 | event.stopPropagation(); 117 | event.target.classList.add('was-validated'); 118 | 119 | try { 120 | await updateBook(book.bookId); 121 | location.href = `book?id=${book.bookId}`; 122 | } catch (error) { 123 | console.log(error); 124 | } 125 | }); 126 | 127 | const cancelButtonElement = document.querySelector('#btn-cancel'); 128 | cancelButtonElement.addEventListener('click', event => { 129 | event.preventDefault(); 130 | event.stopPropagation(); 131 | 132 | location.href = `book?id=${book.bookId}`; 133 | }); 134 | } 135 | 136 | async function main() { 137 | // 브라우저에서 id 가져오기 138 | const bookId = new URL(location.href).searchParams.get('id'); 139 | 140 | // 토큰 체크 141 | const token = getToken(); 142 | if (token === null) { 143 | location.href = '/login'; 144 | return; 145 | } 146 | 147 | // 토큰으로 서버에서 나의 정보 받아오기 148 | const user = await getUserByToken(token); 149 | if (user === null) { 150 | localStorage.clear(); 151 | location = '/login'; 152 | return; 153 | } 154 | 155 | // 책을 서버에서 받아오기 156 | const book = await getBook(bookId); 157 | if (book === null) { 158 | alert('서버에서 책 가져오기 실패'); 159 | return; 160 | } 161 | 162 | // 받아온 책을 그리기 163 | render(book); 164 | } 165 | 166 | document.addEventListener('DOMContentLoaded', main); 167 | -------------------------------------------------------------------------------- /js/index.js: -------------------------------------------------------------------------------- 1 | function getToken() { 2 | return localStorage.getItem('token'); 3 | } 4 | 5 | async function getUserByToken(token) { 6 | try { 7 | const res = await axios.get('https://api.marktube.tv/v1/me', { 8 | headers: { 9 | Authorization: `Bearer ${token}`, 10 | }, 11 | }); 12 | return res.data; 13 | } catch (error) { 14 | console.log('getUserByToken error', error); 15 | return null; 16 | } 17 | } 18 | 19 | async function logout() { 20 | const token = getToken(); 21 | if (token === null) { 22 | location.assign('/login'); 23 | return; 24 | } 25 | try { 26 | await axios.delete('https://api.marktube.tv/v1/me', { 27 | headers: { 28 | Authorization: `Bearer ${token}`, 29 | }, 30 | }); 31 | } catch (error) { 32 | console.log('logout error', error); 33 | } finally { 34 | localStorage.clear(); 35 | location.assign('/login'); 36 | } 37 | } 38 | 39 | async function getBooks(token) { 40 | try { 41 | const res = await axios.get('https://api.marktube.tv/v1/book', { 42 | headers: { 43 | Authorization: `Bearer ${token}`, 44 | }, 45 | }); 46 | return res.data; 47 | } catch (error) { 48 | console.log('getBooks error', error); 49 | return null; 50 | } 51 | } 52 | 53 | async function deleteBook(bookId) { 54 | const token = getToken(); 55 | if (token === null) { 56 | location.assign('/login'); 57 | return; 58 | } 59 | await axios.delete(`https://api.marktube.tv/v1/book/${bookId}`, { 60 | headers: { 61 | Authorization: `Bearer ${token}`, 62 | }, 63 | }); 64 | return; 65 | } 66 | 67 | function bindLogoutButton() { 68 | const btnLogout = document.querySelector('#btn_logout'); 69 | btnLogout.addEventListener('click', logout); 70 | } 71 | 72 | function render(books) { 73 | const listElement = document.querySelector('#list'); 74 | for (let i = 0; i < books.length; i++) { 75 | const book = books[i]; 76 | const bookElement = document.createElement('div'); 77 | bookElement.classList.value = 'col-md-4'; 78 | bookElement.innerHTML = ` 79 |
80 |
81 |

${book.title === '' ? '제목 없음' : book.title}

82 |
83 |
84 | 85 | 91 | 92 | 99 |
100 | ${new Date( 101 | book.createdAt, 102 | ).toLocaleString()} 103 |
104 |
105 |
106 | `; 107 | listElement.append(bookElement); 108 | } 109 | document.querySelectorAll('.btn-delete').forEach(element => { 110 | element.addEventListener('click', async event => { 111 | const bookId = event.target.dataset.bookId; 112 | try { 113 | await deleteBook(bookId); 114 | location.reload(); 115 | } catch (error) { 116 | console.log(error); 117 | } 118 | }); 119 | }); 120 | } 121 | 122 | async function main() { 123 | // 버튼에 이벤트 연결 124 | bindLogoutButton(); 125 | 126 | // 토큰 체크 127 | const token = getToken(); 128 | if (token === null) { 129 | location.assign('/login'); 130 | return; 131 | } 132 | 133 | // 토큰으로 서버에서 나의 정보 받아오기 134 | const user = await getUserByToken(token); 135 | if (user === null) { 136 | localStorage.clear(); 137 | location.assign('/login'); 138 | return; 139 | } 140 | 141 | // 나의 책을 서버에서 받아오기 142 | const books = await getBooks(token); 143 | if (books === null) { 144 | return; 145 | } 146 | 147 | // 받아온 책을 그리기 148 | render(books); 149 | } 150 | 151 | document.addEventListener('DOMContentLoaded', main); 152 | -------------------------------------------------------------------------------- /js/login.js: -------------------------------------------------------------------------------- 1 | function getToken() { 2 | return localStorage.getItem('token'); 3 | } 4 | 5 | async function login(event) { 6 | event.preventDefault(); 7 | event.stopPropagation(); 8 | 9 | const emailElement = document.querySelector('#email'); 10 | const passwordElement = document.querySelector('#password'); 11 | 12 | const email = emailElement.value; 13 | const password = passwordElement.value; 14 | 15 | console.log(email, password); 16 | 17 | try { 18 | const res = await axios.post('https://api.marktube.tv/v1/me', { 19 | email, 20 | password, 21 | }); 22 | const { token } = res.data; 23 | if (token === undefined) { 24 | return; 25 | } 26 | localStorage.setItem('token', token); 27 | location = '/'; 28 | } catch (error) { 29 | const data = error.response.data; 30 | if (data) { 31 | const state = data.error; 32 | if (state === 'USER_NOT_EXIST') { 33 | alert('사용자가 존재하지 않습니다.'); 34 | } else if (state === 'PASSWORD_NOT_MATCH') { 35 | alert('비밀번호가 틀렸습니다.'); 36 | } 37 | } 38 | } 39 | } 40 | 41 | function bindLoginButton() { 42 | const form = document.querySelector('#form-login'); 43 | form.addEventListener('submit', login); 44 | } 45 | 46 | async function main() { 47 | // 버튼에 이벤트 연결 48 | bindLoginButton(); 49 | 50 | // 토큰 체크 51 | const token = getToken(); 52 | if (token !== null) { 53 | location.assign('/'); 54 | return; 55 | } 56 | } 57 | 58 | document.addEventListener('DOMContentLoaded', main); 59 | -------------------------------------------------------------------------------- /login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Faborite Books 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 |
21 |

Please sign in

22 | 23 | 31 | 32 | 39 | 42 |

© 2019

43 |
44 | 45 | 46 | 47 | 52 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fc-js-project", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@zeit/schemas": { 8 | "version": "2.6.0", 9 | "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", 10 | "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==" 11 | }, 12 | "accepts": { 13 | "version": "1.3.7", 14 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 15 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 16 | "requires": { 17 | "mime-types": "~2.1.24", 18 | "negotiator": "0.6.2" 19 | } 20 | }, 21 | "ajv": { 22 | "version": "6.5.3", 23 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", 24 | "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", 25 | "requires": { 26 | "fast-deep-equal": "^2.0.1", 27 | "fast-json-stable-stringify": "^2.0.0", 28 | "json-schema-traverse": "^0.4.1", 29 | "uri-js": "^4.2.2" 30 | } 31 | }, 32 | "ansi-align": { 33 | "version": "2.0.0", 34 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", 35 | "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", 36 | "requires": { 37 | "string-width": "^2.0.0" 38 | } 39 | }, 40 | "ansi-regex": { 41 | "version": "3.0.0", 42 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 43 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 44 | }, 45 | "ansi-styles": { 46 | "version": "3.2.1", 47 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 48 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 49 | "requires": { 50 | "color-convert": "^1.9.0" 51 | } 52 | }, 53 | "arch": { 54 | "version": "2.1.1", 55 | "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", 56 | "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==" 57 | }, 58 | "arg": { 59 | "version": "2.0.0", 60 | "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", 61 | "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==" 62 | }, 63 | "balanced-match": { 64 | "version": "1.0.0", 65 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 66 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 67 | }, 68 | "boxen": { 69 | "version": "1.3.0", 70 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", 71 | "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", 72 | "requires": { 73 | "ansi-align": "^2.0.0", 74 | "camelcase": "^4.0.0", 75 | "chalk": "^2.0.1", 76 | "cli-boxes": "^1.0.0", 77 | "string-width": "^2.0.0", 78 | "term-size": "^1.2.0", 79 | "widest-line": "^2.0.0" 80 | } 81 | }, 82 | "brace-expansion": { 83 | "version": "1.1.11", 84 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 85 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 86 | "requires": { 87 | "balanced-match": "^1.0.0", 88 | "concat-map": "0.0.1" 89 | } 90 | }, 91 | "bytes": { 92 | "version": "3.0.0", 93 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 94 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 95 | }, 96 | "camelcase": { 97 | "version": "4.1.0", 98 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 99 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 100 | }, 101 | "chalk": { 102 | "version": "2.4.1", 103 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 104 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 105 | "requires": { 106 | "ansi-styles": "^3.2.1", 107 | "escape-string-regexp": "^1.0.5", 108 | "supports-color": "^5.3.0" 109 | } 110 | }, 111 | "cli-boxes": { 112 | "version": "1.0.0", 113 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", 114 | "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" 115 | }, 116 | "clipboardy": { 117 | "version": "1.2.3", 118 | "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", 119 | "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", 120 | "requires": { 121 | "arch": "^2.1.0", 122 | "execa": "^0.8.0" 123 | }, 124 | "dependencies": { 125 | "execa": { 126 | "version": "0.8.0", 127 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", 128 | "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", 129 | "requires": { 130 | "cross-spawn": "^5.0.1", 131 | "get-stream": "^3.0.0", 132 | "is-stream": "^1.1.0", 133 | "npm-run-path": "^2.0.0", 134 | "p-finally": "^1.0.0", 135 | "signal-exit": "^3.0.0", 136 | "strip-eof": "^1.0.0" 137 | } 138 | } 139 | } 140 | }, 141 | "color-convert": { 142 | "version": "1.9.3", 143 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 144 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 145 | "requires": { 146 | "color-name": "1.1.3" 147 | } 148 | }, 149 | "color-name": { 150 | "version": "1.1.3", 151 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 152 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 153 | }, 154 | "compressible": { 155 | "version": "2.0.17", 156 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", 157 | "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", 158 | "requires": { 159 | "mime-db": ">= 1.40.0 < 2" 160 | } 161 | }, 162 | "compression": { 163 | "version": "1.7.3", 164 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", 165 | "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", 166 | "requires": { 167 | "accepts": "~1.3.5", 168 | "bytes": "3.0.0", 169 | "compressible": "~2.0.14", 170 | "debug": "2.6.9", 171 | "on-headers": "~1.0.1", 172 | "safe-buffer": "5.1.2", 173 | "vary": "~1.1.2" 174 | } 175 | }, 176 | "concat-map": { 177 | "version": "0.0.1", 178 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 179 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 180 | }, 181 | "content-disposition": { 182 | "version": "0.5.2", 183 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 184 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 185 | }, 186 | "cross-spawn": { 187 | "version": "5.1.0", 188 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 189 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 190 | "requires": { 191 | "lru-cache": "^4.0.1", 192 | "shebang-command": "^1.2.0", 193 | "which": "^1.2.9" 194 | } 195 | }, 196 | "debug": { 197 | "version": "2.6.9", 198 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 199 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 200 | "requires": { 201 | "ms": "2.0.0" 202 | } 203 | }, 204 | "deep-extend": { 205 | "version": "0.6.0", 206 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 207 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 208 | }, 209 | "escape-string-regexp": { 210 | "version": "1.0.5", 211 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 212 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 213 | }, 214 | "execa": { 215 | "version": "0.7.0", 216 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", 217 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", 218 | "requires": { 219 | "cross-spawn": "^5.0.1", 220 | "get-stream": "^3.0.0", 221 | "is-stream": "^1.1.0", 222 | "npm-run-path": "^2.0.0", 223 | "p-finally": "^1.0.0", 224 | "signal-exit": "^3.0.0", 225 | "strip-eof": "^1.0.0" 226 | } 227 | }, 228 | "fast-deep-equal": { 229 | "version": "2.0.1", 230 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 231 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 232 | }, 233 | "fast-json-stable-stringify": { 234 | "version": "2.0.0", 235 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 236 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 237 | }, 238 | "fast-url-parser": { 239 | "version": "1.1.3", 240 | "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", 241 | "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", 242 | "requires": { 243 | "punycode": "^1.3.2" 244 | }, 245 | "dependencies": { 246 | "punycode": { 247 | "version": "1.4.1", 248 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 249 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 250 | } 251 | } 252 | }, 253 | "get-stream": { 254 | "version": "3.0.0", 255 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", 256 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" 257 | }, 258 | "has-flag": { 259 | "version": "3.0.0", 260 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 261 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 262 | }, 263 | "ini": { 264 | "version": "1.3.5", 265 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 266 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 267 | }, 268 | "is-fullwidth-code-point": { 269 | "version": "2.0.0", 270 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 271 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 272 | }, 273 | "is-stream": { 274 | "version": "1.1.0", 275 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 276 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 277 | }, 278 | "isexe": { 279 | "version": "2.0.0", 280 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 281 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 282 | }, 283 | "json-schema-traverse": { 284 | "version": "0.4.1", 285 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 286 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 287 | }, 288 | "lru-cache": { 289 | "version": "4.1.5", 290 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 291 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 292 | "requires": { 293 | "pseudomap": "^1.0.2", 294 | "yallist": "^2.1.2" 295 | } 296 | }, 297 | "mime-db": { 298 | "version": "1.42.0", 299 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", 300 | "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" 301 | }, 302 | "mime-types": { 303 | "version": "2.1.25", 304 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", 305 | "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", 306 | "requires": { 307 | "mime-db": "1.42.0" 308 | } 309 | }, 310 | "minimatch": { 311 | "version": "3.0.4", 312 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 313 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 314 | "requires": { 315 | "brace-expansion": "^1.1.7" 316 | } 317 | }, 318 | "minimist": { 319 | "version": "1.2.0", 320 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 321 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 322 | }, 323 | "ms": { 324 | "version": "2.0.0", 325 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 326 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 327 | }, 328 | "negotiator": { 329 | "version": "0.6.2", 330 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 331 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 332 | }, 333 | "npm-run-path": { 334 | "version": "2.0.2", 335 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 336 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 337 | "requires": { 338 | "path-key": "^2.0.0" 339 | } 340 | }, 341 | "on-headers": { 342 | "version": "1.0.2", 343 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 344 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" 345 | }, 346 | "p-finally": { 347 | "version": "1.0.0", 348 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 349 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 350 | }, 351 | "path-is-inside": { 352 | "version": "1.0.2", 353 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 354 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" 355 | }, 356 | "path-key": { 357 | "version": "2.0.1", 358 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 359 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 360 | }, 361 | "path-to-regexp": { 362 | "version": "2.2.1", 363 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", 364 | "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" 365 | }, 366 | "pseudomap": { 367 | "version": "1.0.2", 368 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 369 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 370 | }, 371 | "punycode": { 372 | "version": "2.1.1", 373 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 374 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 375 | }, 376 | "range-parser": { 377 | "version": "1.2.0", 378 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 379 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 380 | }, 381 | "rc": { 382 | "version": "1.2.8", 383 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 384 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 385 | "requires": { 386 | "deep-extend": "^0.6.0", 387 | "ini": "~1.3.0", 388 | "minimist": "^1.2.0", 389 | "strip-json-comments": "~2.0.1" 390 | } 391 | }, 392 | "registry-auth-token": { 393 | "version": "3.3.2", 394 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", 395 | "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", 396 | "requires": { 397 | "rc": "^1.1.6", 398 | "safe-buffer": "^5.0.1" 399 | } 400 | }, 401 | "registry-url": { 402 | "version": "3.1.0", 403 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", 404 | "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", 405 | "requires": { 406 | "rc": "^1.0.1" 407 | } 408 | }, 409 | "safe-buffer": { 410 | "version": "5.1.2", 411 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 412 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 413 | }, 414 | "serve": { 415 | "version": "11.2.0", 416 | "resolved": "https://registry.npmjs.org/serve/-/serve-11.2.0.tgz", 417 | "integrity": "sha512-THZcLzDGk3vJqjhAbLkLag43tiE3V0B7wVe98Xtl+1KyAsr+4iShg+9hke4pLZmrCJu0pUg0TrbhJmdqn/MKoA==", 418 | "requires": { 419 | "@zeit/schemas": "2.6.0", 420 | "ajv": "6.5.3", 421 | "arg": "2.0.0", 422 | "boxen": "1.3.0", 423 | "chalk": "2.4.1", 424 | "clipboardy": "1.2.3", 425 | "compression": "1.7.3", 426 | "serve-handler": "6.1.2", 427 | "update-check": "1.5.2" 428 | } 429 | }, 430 | "serve-handler": { 431 | "version": "6.1.2", 432 | "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.2.tgz", 433 | "integrity": "sha512-RFh49wX7zJmmOVDcIjiDSJnMH+ItQEvyuYLYuDBVoA/xmQSCuj+uRmk1cmBB5QQlI3qOiWKp6p4DUGY+Z5AB2A==", 434 | "requires": { 435 | "bytes": "3.0.0", 436 | "content-disposition": "0.5.2", 437 | "fast-url-parser": "1.1.3", 438 | "mime-types": "2.1.18", 439 | "minimatch": "3.0.4", 440 | "path-is-inside": "1.0.2", 441 | "path-to-regexp": "2.2.1", 442 | "range-parser": "1.2.0" 443 | }, 444 | "dependencies": { 445 | "mime-db": { 446 | "version": "1.33.0", 447 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 448 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 449 | }, 450 | "mime-types": { 451 | "version": "2.1.18", 452 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 453 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 454 | "requires": { 455 | "mime-db": "~1.33.0" 456 | } 457 | } 458 | } 459 | }, 460 | "shebang-command": { 461 | "version": "1.2.0", 462 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 463 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 464 | "requires": { 465 | "shebang-regex": "^1.0.0" 466 | } 467 | }, 468 | "shebang-regex": { 469 | "version": "1.0.0", 470 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 471 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 472 | }, 473 | "signal-exit": { 474 | "version": "3.0.2", 475 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 476 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 477 | }, 478 | "string-width": { 479 | "version": "2.1.1", 480 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 481 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 482 | "requires": { 483 | "is-fullwidth-code-point": "^2.0.0", 484 | "strip-ansi": "^4.0.0" 485 | } 486 | }, 487 | "strip-ansi": { 488 | "version": "4.0.0", 489 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 490 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 491 | "requires": { 492 | "ansi-regex": "^3.0.0" 493 | } 494 | }, 495 | "strip-eof": { 496 | "version": "1.0.0", 497 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 498 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 499 | }, 500 | "strip-json-comments": { 501 | "version": "2.0.1", 502 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 503 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 504 | }, 505 | "supports-color": { 506 | "version": "5.5.0", 507 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 508 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 509 | "requires": { 510 | "has-flag": "^3.0.0" 511 | } 512 | }, 513 | "term-size": { 514 | "version": "1.2.0", 515 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", 516 | "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", 517 | "requires": { 518 | "execa": "^0.7.0" 519 | } 520 | }, 521 | "update-check": { 522 | "version": "1.5.2", 523 | "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", 524 | "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", 525 | "requires": { 526 | "registry-auth-token": "3.3.2", 527 | "registry-url": "3.1.0" 528 | } 529 | }, 530 | "uri-js": { 531 | "version": "4.2.2", 532 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 533 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 534 | "requires": { 535 | "punycode": "^2.1.0" 536 | } 537 | }, 538 | "vary": { 539 | "version": "1.1.2", 540 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 541 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 542 | }, 543 | "which": { 544 | "version": "1.3.1", 545 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 546 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 547 | "requires": { 548 | "isexe": "^2.0.0" 549 | } 550 | }, 551 | "widest-line": { 552 | "version": "2.0.1", 553 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", 554 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", 555 | "requires": { 556 | "string-width": "^2.1.1" 557 | } 558 | }, 559 | "yallist": { 560 | "version": "2.1.2", 561 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 562 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 563 | } 564 | } 565 | } 566 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fc-js-project", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "serve": "^11.2.0" 14 | } 15 | } 16 | --------------------------------------------------------------------------------