오윤석

Merge branch 'develop'

...@@ -37,7 +37,7 @@ services: ...@@ -37,7 +37,7 @@ services:
37 volumes: 37 volumes:
38 - ./node:/app 38 - ./node:/app
39 - ./config:/app/config 39 - ./config:/app/config
40 - command: bash -c "npm install && node app.js" 40 + command: bash -c "npm install && node_modules/.bin/nodemon app.js"
41 environment: 41 environment:
42 - NODE_ENV=production 42 - NODE_ENV=production
43 restart: on-failure 43 restart: on-failure
......
...@@ -6,6 +6,6 @@ let routes = require('./routes'); ...@@ -6,6 +6,6 @@ let routes = require('./routes');
6 app.use(bodyParser.urlencoded({ extended: false })); 6 app.use(bodyParser.urlencoded({ extended: false }));
7 app.use(bodyParser.json()); 7 app.use(bodyParser.json());
8 8
9 -app.get('/api/home', routes.home); 9 +app.get('/api/character', routes.character.getCharacter);
10 10
11 let server = app.listen(80); 11 let server = app.listen(80);
...\ No newline at end of file ...\ No newline at end of file
......
This diff is collapsed. Click to expand it.
1 +module.exports = {
2 + 'STR': {
3 + 'korean': '힘'
4 + },
5 + 'DEX': {
6 + 'korean': '민첩성'
7 + },
8 + 'INT': {
9 + 'korean': '지력'
10 + },
11 + 'LUK': {
12 + 'korean': '운'
13 + }
14 +}
...\ No newline at end of file ...\ No newline at end of file
1 +module.exports = {
2 + '한손검': 1.2,
3 + '한손도끼': 1.2,
4 + '한손둔기': 1.2,
5 + '스태프': 1,
6 + '완드': 1,
7 + '샤이닝 로드': 1.2,
8 + '단검': 1.3,
9 + '케인': 1.3,
10 + '데스페라도': 1.3,
11 + '에너지소드': 1.5,
12 + '소울 슈터': 1.7,
13 + 'ESP 리미터': 1.2,
14 + '체인': 1.3,
15 + '매직 건틀렛': 1.2,
16 + '부채': 1.3,
17 + '튜너': 1.3,
18 + '두손검': 1.34,
19 + '두손도끼': 1.34,
20 + '두손둔기': 1.34,
21 + '창': 1.34,
22 + '폴암': 1.49,
23 + '태도': 1.34,
24 + '건틀렛 리볼버': 1.7,
25 + '활': 1.3,
26 + '석궁': 1.35,
27 + '듀얼 보우건': 1.3,
28 + '에인션트 보우': 1.3,
29 + '아대': 1.75,
30 + '건': 1.5,
31 + '너클': 1.7,
32 + '핸드캐논': 1.5
33 +}
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
...@@ -9,7 +9,11 @@ ...@@ -9,7 +9,11 @@
9 "author": "", 9 "author": "",
10 "license": "ISC", 10 "license": "ISC",
11 "dependencies": { 11 "dependencies": {
12 + "axios": "^0.19.2",
12 "express": "^4.17.1", 13 "express": "^4.17.1",
13 - "http": "0.0.1-security" 14 + "http": "0.0.1-security",
15 + "jquery": "^3.5.1",
16 + "jsdom": "^16.2.2",
17 + "nodemon": "^2.0.4"
14 } 18 }
15 } 19 }
......
This diff is collapsed. Click to expand it.
1 -module.exports = function(req, res) {
2 - res.send('this is home');
3 -}
...\ No newline at end of file ...\ No newline at end of file
1 let routes = {}; 1 let routes = {};
2 -routes.home = require('./home'); 2 +routes.character = require('./character');
3 3
4 module.exports = routes; 4 module.exports = routes;
...\ No newline at end of file ...\ No newline at end of file
......
This diff is collapsed. Click to expand it.
...@@ -10,12 +10,13 @@ ...@@ -10,12 +10,13 @@
10 "@rollup/plugin-commonjs": "11.0.2", 10 "@rollup/plugin-commonjs": "11.0.2",
11 "@rollup/plugin-node-resolve": "^7.0.0", 11 "@rollup/plugin-node-resolve": "^7.0.0",
12 "rollup": "^1.20.0", 12 "rollup": "^1.20.0",
13 - "rollup-plugin-livereload": "^1.0.0",
14 "rollup-plugin-svelte": "^5.0.3", 13 "rollup-plugin-svelte": "^5.0.3",
15 "rollup-plugin-terser": "^5.1.2", 14 "rollup-plugin-terser": "^5.1.2",
16 "svelte": "^3.0.0" 15 "svelte": "^3.0.0"
17 }, 16 },
18 "dependencies": { 17 "dependencies": {
18 + "@lottiefiles/svelte-lottie-player": "^0.1.4",
19 + "axios": "^0.19.2",
19 "rollup-plugin-copy": "^3.3.0", 20 "rollup-plugin-copy": "^3.3.0",
20 "sirv-cli": "^0.4.4", 21 "sirv-cli": "^0.4.4",
21 "svelte-spa-router": "^2.1.0" 22 "svelte-spa-router": "^2.1.0"
......
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <html lang="en"> 2 <html lang="en">
3 -<head>
4 - <meta charset='utf-8'>
5 - <meta name='viewport' content='width=device-width,initial-scale=1'>
6 3
7 - <title>Svelte app</title> 4 +<head lang="ko">
5 + <meta charset='utf-8'>
6 + <meta name='viewport' content='width=device-width,initial-scale=1'>
8 7
9 - <link rel='icon' type='image/png' href='/favicon.png'> 8 + <title>::메이플스토리 스펙 계산기::</title>
10 - <link rel='stylesheet' href='/global.css'>
11 - <link rel='stylesheet' href='/build/bundle.css'>
12 9
13 - <script defer src='/build/bundle.js'></script> 10 + <link rel='icon' type='shortcut icon' href='./build/static/images/favicon.ico'>
11 + <link rel='stylesheet' href='./static/css/global.css'>
12 + <link rel='stylesheet' href='/build/bundle.css'>
13 + <meta property="og:image" content="./build/static/images/ogimage.png">
14 + <meta property="og:title" content="::메이플스토리 스펙 계산기::">
15 + <meta property="og:description" content="당신의 메이플스토리 스펙 효율을 빠르게 계산해보세요!">
16 +
17 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
18 + <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
19 + <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
20 +
21 + <script defer src='/build/bundle.js'></script>
14 </head> 22 </head>
15 23
16 <body> 24 <body>
17 </body> 25 </body>
18 -</html> 26 +
27 +</html>
...\ No newline at end of file ...\ No newline at end of file
......
1 -html, body { 1 +html,
2 - position: relative; 2 +body {
3 - width: 100%; 3 + position: relative;
4 - height: 100%; 4 + width: 100%;
5 + height: 100%;
6 + background-color: #ffebee;
5 } 7 }
6 8
7 body { 9 body {
8 - color: #333; 10 + color: #333;
9 - margin: 0; 11 + margin: 0;
10 - padding: 8px; 12 + box-sizing: border-box;
11 - box-sizing: border-box; 13 + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
12 - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
13 } 14 }
14 15
15 a { 16 a {
16 - color: rgb(0,100,200); 17 + color: rgb(0, 100, 200);
17 - text-decoration: none; 18 + text-decoration: none;
18 } 19 }
19 20
20 a:hover { 21 a:hover {
21 - text-decoration: underline; 22 + text-decoration: underline;
22 } 23 }
23 24
24 a:visited { 25 a:visited {
25 - color: rgb(0,80,160); 26 + color: rgb(0, 80, 160);
26 } 27 }
27 28
28 label { 29 label {
29 - display: block; 30 + display: block;
30 } 31 }
31 32
32 -input, button, select, textarea { 33 +input,
33 - font-family: inherit; 34 +button,
34 - font-size: inherit; 35 +select,
35 - padding: 0.4em; 36 +textarea {
36 - margin: 0 0 0.5em 0; 37 + font-family: inherit;
37 - box-sizing: border-box; 38 + font-size: inherit;
38 - border: 1px solid #ccc; 39 + padding: 0.4em;
39 - border-radius: 2px; 40 + margin: 0 0 0.5em 0;
41 + box-sizing: border-box;
42 + border: 1px solid #ccc;
43 + border-radius: 2px;
40 } 44 }
41 45
42 input:disabled { 46 input:disabled {
43 - color: #ccc; 47 + color: #ccc;
44 } 48 }
45 49
46 input[type="range"] { 50 input[type="range"] {
47 - height: 0; 51 + height: 0;
48 } 52 }
49 53
50 button { 54 button {
51 - color: #333; 55 + color: #333;
52 - background-color: #f4f4f4; 56 + background-color: #f4f4f4;
53 - outline: none; 57 + outline: none;
54 } 58 }
55 59
56 button:disabled { 60 button:disabled {
57 - color: #999; 61 + color: #999;
58 } 62 }
59 63
60 button:not(:disabled):active { 64 button:not(:disabled):active {
61 - background-color: #ddd; 65 + background-color: #ddd;
62 } 66 }
63 67
64 button:focus { 68 button:focus {
65 - border-color: #666; 69 + border-color: #666;
66 -} 70 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 import svelte from 'rollup-plugin-svelte'; 1 import svelte from 'rollup-plugin-svelte';
2 import resolve from '@rollup/plugin-node-resolve'; 2 import resolve from '@rollup/plugin-node-resolve';
3 import commonjs from '@rollup/plugin-commonjs'; 3 import commonjs from '@rollup/plugin-commonjs';
4 -import livereload from 'rollup-plugin-livereload';
5 import { terser } from 'rollup-plugin-terser'; 4 import { terser } from 'rollup-plugin-terser';
6 import copy from 'rollup-plugin-copy'; 5 import copy from 'rollup-plugin-copy';
7 6
8 const production = !process.env.ROLLUP_WATCH; 7 const production = !process.env.ROLLUP_WATCH;
9 8
10 export default { 9 export default {
11 - input: 'src/main.js', 10 + input: 'src/main.js',
12 - output: { 11 + output: {
13 - sourcemap: true, 12 + sourcemap: true,
14 - format: 'iife', 13 + format: 'iife',
15 - name: 'app', 14 + name: 'app',
16 - file: 'public/build/bundle.js' 15 + file: 'public/build/bundle.js'
17 - }, 16 + },
18 - plugins: [ 17 + plugins: [
19 - svelte({ 18 + svelte({
20 - // enable run-time checks when not in production 19 + // enable run-time checks when not in production
21 - dev: !production, 20 + dev: !production,
22 - // we'll extract any component CSS out into 21 + // we'll extract any component CSS out into
23 - // a separate file - better for performance 22 + // a separate file - better for performance
24 - css: css => { 23 + css: css => {
25 - css.write('public/build/bundle.css'); 24 + css.write('public/build/bundle.css');
26 - } 25 + }
27 - }), 26 + }),
28 27
29 - // If you have external dependencies installed from 28 + // If you have external dependencies installed from
30 - // npm, you'll most likely need these plugins. In 29 + // npm, you'll most likely need these plugins. In
31 - // some cases you'll need additional configuration - 30 + // some cases you'll need additional configuration -
32 - // consult the documentation for details: 31 + // consult the documentation for details:
33 - // https://github.com/rollup/plugins/tree/master/packages/commonjs 32 + // https://github.com/rollup/plugins/tree/master/packages/commonjs
34 - resolve({ 33 + resolve({
35 - browser: true, 34 + browser: true,
36 - dedupe: ['svelte'] 35 + dedupe: ['svelte']
37 - }), 36 + }),
38 - commonjs(), 37 + commonjs(),
39 38
40 - copy({ 39 + copy({
41 - targets:[ 40 + targets: [
42 - { src:'src/images', dest:'public' } 41 + { src: 'src/images', dest: 'public/build/static' }
43 - ] 42 + ]
44 - }), 43 + }),
45 44
46 - // In dev mode, call `npm run start` once 45 + // In dev mode, call `npm run start` once
47 - // the bundle has been generated 46 + // the bundle has been generated
48 - !production && serve(), 47 + !production && serve(),
49 48
50 - // Watch the `public` directory and refresh the 49 + // If we're building for production (npm run build
51 - // browser on changes when not in production 50 + // instead of npm run dev), minify
52 - !production && livereload('public'), 51 + production && terser()
53 - 52 + ],
54 - // If we're building for production (npm run build 53 + watch: {
55 - // instead of npm run dev), minify 54 + clearScreen: false
56 - production && terser() 55 + }
57 - ],
58 - watch: {
59 - clearScreen: false
60 - }
61 }; 56 };
62 57
63 function serve() { 58 function serve() {
64 - let started = false; 59 + let started = false;
65 60
66 - return { 61 + return {
67 - writeBundle() { 62 + writeBundle() {
68 - if (!started) { 63 + if (!started) {
69 - started = true; 64 + started = true;
70 65
71 - require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { 66 + require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
72 - stdio: ['ignore', 'inherit', 'inherit'], 67 + stdio: ['ignore', 'inherit', 'inherit'],
73 - shell: true 68 + shell: true
74 - }); 69 + });
75 - } 70 + }
76 - } 71 + }
77 - }; 72 + };
78 -} 73 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 +<script>
2 + import {LottiePlayer} from '@lottiefiles/svelte-lottie-player';
3 +
4 + export let count = 0;
5 +</script>
6 +
7 +<div id="loading" class:show={count > 0}>
8 + <LottiePlayer
9 + src="https://assets5.lottiefiles.com/packages/lf20_kblbXu.json" background="transparent" speed="1" width={300} height={300} controls={false} controlsLayout={null} loop autoplay>
10 + </LottiePlayer>
11 +</div>
12 +
13 +<style>
14 +#loading { position:fixed; width:100%; height:100%; z-index:9999; background-color:rgba(0,0,0,0.3); align-items:center; justify-content:center; display:none; }
15 +#loading.show { display:flex; }
16 +</style>
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 -import App from './App.svelte'; 1 +import App from './App.svelte';
2 2
3 const app = new App({ 3 const app = new App({
4 - target: document.body, 4 + target: document.body
5 - props: {
6 - name: 'world'
7 - }
8 }); 5 });
9 6
10 export default app; 7 export default app;
...\ No newline at end of file ...\ No newline at end of file
......
1 -import Home from './routes/Home.svelte'; 1 +import Search from './routes/Search.svelte';
2 +import Character from './routes/Character.svelte';
2 3
3 const routes = { 4 const routes = {
4 - '/': Home, 5 + '/': Search,
6 + '/character': Character,
7 + '/character/:character': Character,
5 }; 8 };
6 9
7 export default routes; 10 export default routes;
...\ No newline at end of file ...\ No newline at end of file
......
1 +<script>
2 + export let params = {};
3 +
4 + import {push} from 'svelte-spa-router';
5 + import axios from 'axios';
6 + import Loading from '../components/Loading.svelte';
7 +
8 + let callCount = 0;
9 + let isBuff = false;
10 + let isCharacterLoading = false;
11 + let stats;
12 +
13 + let character = {
14 + info:{
15 + avatar:'',
16 + nickname:'',
17 + characterCode:'',
18 + job:'',
19 + majorName:'',
20 + attackPowerName:'',
21 + server:{
22 + name:'',
23 + icon:''
24 + },
25 + level:237
26 + },
27 + analysis:{
28 + default:{
29 + stats:{
30 + major:{
31 + pure:0,
32 + percent:0,
33 + added:0,
34 + },
35 + minor:0,
36 + damage:{
37 + all:0,
38 + boss:0
39 + },
40 + finalDamage:0,
41 + criticalDamage:0,
42 + attackPower:{
43 + pure:0,
44 + percent:0,
45 + },
46 + ignoreGuard:0
47 + },
48 + efficiency:{
49 + major:{
50 + pure:1,
51 + percent:1
52 + },
53 + attackPower:{
54 + pure:1,
55 + percent:1
56 + },
57 + damage:1,
58 + criticalDamage:1,
59 + ignoreGuard:1
60 + }
61 + }
62 + },
63 + buff:{
64 + stats:{
65 + major:{
66 + pure:0,
67 + percent:0,
68 + added:0,
69 + },
70 + minor:0,
71 + damage:{
72 + all:0,
73 + boss:0
74 + },
75 + finalDamage:0,
76 + criticalDamage:0,
77 + attackPower:{
78 + pure:0,
79 + percent:0,
80 + },
81 + ignoreGuard:0
82 + },
83 + efficiency:{
84 + major:{
85 + pure:1,
86 + percent:1
87 + },
88 + attackPower:{
89 + pure:1,
90 + percent:1
91 + },
92 + damage:1,
93 + criticalDamage:1,
94 + ignoreGuard:1
95 + }
96 + }
97 + }
98 +
99 + function init() {
100 + let nickname;
101 +
102 + if(!params.character) {
103 + M.toast({html:"캐릭터명을 입력해주세요."});
104 + push("/");
105 + }
106 +
107 + nickname = decodeURI(params.character);
108 +
109 + callCount++;
110 + axios.get('/api/character', {
111 + params:{
112 + nickname:nickname
113 + }
114 + }).then(function(response) {
115 + character = response.data;
116 + isCharacterLoading = true;
117 + }).catch(function(error) {
118 + switch(error.response.status) {
119 + case 404:
120 + M.toast({html:"존재하지 않는 캐릭터입니다."});
121 + break;
122 + case 403:
123 + M.toast({html:"캐릭터 정보 공개설정이 필요합니다."});
124 + setTimeout(function() {
125 + window.open("https://maplestory.nexon.com/MyMaple/Account/Character/Visibility");
126 + }, 2000);
127 + break;
128 + case 503:
129 + M.toast({html:"메이플스토리가 점검중입니다."});
130 + break;
131 + default:
132 + M.toast({html:"서버와의 통신이 원활하지 않습니다.<br><br>잠시 후에 시도해주세요."});
133 + break;
134 + }
135 + push('/');
136 + }).finally(function() {
137 + callCount--;
138 + });
139 + }
140 +
141 + function showValue(value) {
142 + return parseFloat(value).toFixed(2);
143 + }
144 +
145 + function goBack() {
146 + push('/');
147 + }
148 +
149 + $:
150 + if(isCharacterLoading && isBuff) {
151 + stats = character.analysis.buff;
152 + } else {
153 + stats = character.analysis.default;
154 + }
155 +
156 + init();
157 +</script>
158 +
159 +<svelte:head>
160 +
161 +</svelte:head>
162 +
163 +<Loading count={callCount} />
164 +<section>
165 + {#if isCharacterLoading}
166 + <article class="info-box">
167 + <div class="row">
168 + <div class="col s12 m10 l8 offset-m1 offset-l2">
169 + <div class="row">
170 + <div class="col s12 m4 l3">
171 + <div class="card character-card">
172 + <div class="card-stacked">
173 + <div class="card-content">
174 + <div class="character-img">
175 + <img src={character.info.avatar} class="responsive-img" alt="캐릭터">
176 + </div>
177 + <h6 class="pink-text text-accent-3">
178 + <img src={character.info.server.icon} alt={character.info.server.name}>
179 + {character.info.nickname}
180 + </h6>
181 + <div class="job grey-text text-darken-2">
182 + {character.info.job}
183 + </div>
184 + <div class="level grey-text text-darken-2">
185 + Lv.{character.info.level}
186 + </div>
187 + </div>
188 + </div>
189 + </div>
190 + <div class="back-button-box">
191 + <button class="btn waves-light btn red accent-2" on:click={goBack}>
192 + <i class="material-icons">arrow_back</i>
193 + <span>뒤로가기</span>
194 + </button>
195 + </div>
196 + </div>
197 + <div class="col s12 m8 l9">
198 + <div class="card character-card">
199 + <div class="card-stacked">
200 + <div class="card-content">
201 + <div class="buff-switch">
202 + <div class="switch">
203 + <label>
204 + 노버프
205 + <input type="checkbox" bind:checked={isBuff}>
206 + <span class="lever"></span>
207 + 버프(자벞,링크,노블,영메)
208 + </label>
209 + </div>
210 + </div>
211 + <table class="table-efficiency">
212 + <thead>
213 + <tr>
214 + <th>스탯</th>
215 + <th>효율</th>
216 + </tr>
217 + </thead>
218 + <tbody>
219 + <tr>
220 + <th rowspan="2">{character.info.majorName} 1%</th>
221 + <td>{character.info.majorName} {showValue(stats.efficiency.major.percent)}</td>
222 + </tr>
223 + <tr>
224 + <td>{character.info.attackPowerName} {showValue(stats.efficiency.major.percent / stats.efficiency.attackPower.pure)}</td>
225 + </tr>
226 + <tr>
227 + <th>{character.info.attackPowerName} 1</th>
228 + <td>{character.info.majorName} {showValue(stats.efficiency.attackPower.pure)}</td>
229 + </tr>
230 + <tr>
231 + <th rowspan="5">{character.info.attackPowerName} 1%</th>
232 + <td>{character.info.majorName} {showValue(stats.efficiency.attackPower.percent)}</td>
233 + </tr>
234 + <tr>
235 + <td>{character.info.majorName} {showValue(stats.efficiency.attackPower.percent / stats.efficiency.major.percent)}%</td>
236 + </tr>
237 + <tr>
238 + <td>{character.info.attackPowerName} {showValue(stats.efficiency.attackPower.percent / stats.efficiency.attackPower.pure)}</td>
239 + </tr>
240 + <tr>
241 + <td>데미지(보공) {showValue(stats.efficiency.attackPower.percent / stats.efficiency.damage)}%</td>
242 + </tr>
243 + <tr>
244 + <td>방무 {showValue(stats.efficiency.attackPower.percent / stats.efficiency.ignoreGuard)}%</td>
245 + </tr>
246 + <tr>
247 + <th rowspan="2">데미지(보공) 1%</th>
248 + <td>{character.info.majorName} {showValue(stats.efficiency.damage)}</td>
249 + </tr>
250 + <tr>
251 + <td>방무 {showValue(stats.efficiency.damage / stats.efficiency.ignoreGuard)}%</td>
252 + </tr>
253 + <tr>
254 + <th rowspan="2">크뎀 1%</th>
255 + <td>{character.info.majorName} {showValue(stats.efficiency.criticalDamage)}</td>
256 + </tr>
257 + <tr>
258 + <td>{character.info.majorName} {showValue(stats.efficiency.criticalDamage / stats.efficiency.major.percent)}%</td>
259 + </tr>
260 + <tr>
261 + <th>방무 1%</th>
262 + <td>{character.info.majorName} {showValue(stats.efficiency.ignoreGuard)}</td>
263 + </tr>
264 + </tbody>
265 + </table>
266 + </div>
267 + </div>
268 + </div>
269 + </div>
270 + </div>
271 + </div>
272 + </div>
273 + </article>
274 + {/if}
275 +</section>
276 +
277 +<style>
278 +section { width:100%; height:100%; display:flex; flex-direction:column; padding:20px 0; }
279 +.info-box { margin:auto 0; }
280 +.info-box > .row > .col > .row > .col { margin-bottom:.5rem; }
281 +.character-card .card-content { text-align:center; }
282 +.character-card .card-content .job { font-size:0.8em }
283 +.character-card .card-content .level { font-size:0.8em }
284 +.character-card .card-content h6 img { width:14px; height:14px; }
285 +.character-card .card-content h6 { font-weight:bold; }
286 +.table-efficiency td, .table-efficiency th { text-align:left; }
287 +.back-button-box button { width:100%; display:block; height:48px; line-height:48px; }
288 +.back-button-box button i.material-icons { vertical-align:middle; }
289 +.back-button-box button span { vertical-align:middle; }
290 +.buff-switch .switch label input[type=checkbox]:checked+.lever:after { background-color:#e57373; }
291 +.buff-switch .switch label input[type=checkbox]:not(:checked)+.lever { background-color:#ffcdd2; }
292 +.buff-switch .switch label input[type=checkbox]:checked+.lever { background-color:#ef9a9a ; }
293 +</style>
...\ No newline at end of file ...\ No newline at end of file
1 -<main>
2 - <h1>Hello, This is Home!</h1>
3 - <p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
4 -</main>
5 -
6 -<style>
7 - main {
8 - text-align: center;
9 - padding: 1em;
10 - max-width: 240px;
11 - margin: 0 auto;
12 - }
13 -
14 - h1 {
15 - color: #ff3e00;
16 - text-transform: uppercase;
17 - font-size: 4em;
18 - font-weight: 100;
19 - }
20 -
21 - @media (min-width: 640px) {
22 - main {
23 - max-width: none;
24 - }
25 - }
26 -</style>
...\ No newline at end of file ...\ No newline at end of file
1 +<script>
2 + import {push} from 'svelte-spa-router';
3 +
4 + let character;
5 +
6 + function searchCharacter() {
7 + if(!character) {
8 + M.toast({html:"캐릭터명을 입력해주세요."});
9 + return false;
10 + }
11 +
12 + push('/character/' + character);
13 + }
14 +</script>
15 +
16 +<svelte:head>
17 +
18 +</svelte:head>
19 +
20 +<section>
21 + <article class="search-box row">
22 + <div class="col l4 m6 s12 offset-l4 offset-m3">
23 + <div class="card">
24 + <div class="card-stacked">
25 + <div class="card-content">
26 + <h4>내 캐릭터 분석하기</h4>
27 + <form class="search-form" on:submit={searchCharacter} onsubmit="return false;">
28 + <div class="input-field">
29 + <label>캐릭터명</label>
30 + <input type="text" bind:value={character}>
31 + <button class="btn waves-effect waves-light red darken-1">확인</button>
32 + </div>
33 + </form>
34 + </div>
35 + <div class="card-action">
36 + <p class="teal-text text-lighten-2">
37 + 메이플스토리 스펙 계산기를 이용하기 위해서는 캐릭터 정보 공개(기본정보, 장비, 스킬)가 필요합니다.
38 + </p>
39 + <p>
40 + <a href="https://maplestory.nexon.com/MyMaple/Account/Character/Visibility" target="_BLANK">공개설정하러 가기</a>
41 + </p>
42 + <p class="red-text text-accent-1">
43 + <i class="material-icons">info_outline</i>
44 + <span>제논, 데몬어벤져는 지원하지 않습니다.</span>
45 + </p>
46 + </div>
47 + </div>
48 + </div>
49 + </div>
50 + </article>
51 +</section>
52 +
53 +<style>
54 +section { width:100%; height:100%; display:flex; flex-direction:column; }
55 +.search-box { width:100%; margin:auto 0; }
56 +h4 { font-size:20px; text-align:center; }
57 +.input-field { padding-right:70px; }
58 +.input-field button { position:absolute; right:0; top:7px; }
59 +.card-action i.material-icons { font-size:1.1em; vertical-align:middle; }
60 +.card-action i.material-icons ~ span { vertical-align:middle; }
61 +</style>
...\ No newline at end of file ...\ No newline at end of file