권주희

Merge branch 'develop' into 'master'

Develop



See merge request !7
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
2 2
3 # dependencies 3 # dependencies
4 frontend/node_modules/* 4 frontend/node_modules/*
5 +backend/node_modules/*
5 /.pnp 6 /.pnp
6 .pnp.js 7 .pnp.js
7 8
...@@ -21,3 +22,4 @@ frontend/node_modules/* ...@@ -21,3 +22,4 @@ frontend/node_modules/*
21 npm-debug.log* 22 npm-debug.log*
22 yarn-debug.log* 23 yarn-debug.log*
23 yarn-error.log* 24 yarn-error.log*
25 +secrets.json
...\ No newline at end of file ...\ No newline at end of file
......
1 -var createError = require('http-errors'); 1 +var createError = require("http-errors");
2 -var express = require('express'); 2 +var express = require("express");
3 -var path = require('path'); 3 +var cors = require("cors");
4 -var cookieParser = require('cookie-parser'); 4 +var path = require("path");
5 -var logger = require('morgan'); 5 +var cookieParser = require("cookie-parser");
6 +var logger = require("morgan");
6 7
7 -var indexRouter = require('./routes/index'); 8 +var indexRouter = require("./routes/index");
8 -var usersRouter = require('./routes/users'); 9 +var usersRouter = require("./routes/users");
10 +var airConditionRouter = require("./routes/airCondition");
9 11
10 var app = express(); 12 var app = express();
13 +app.use(cors());
11 14
12 // view engine setup 15 // view engine setup
13 -app.set('views', path.join(__dirname, 'views')); 16 +app.set("views", path.join(__dirname, "views"));
14 -app.set('view engine', 'pug'); 17 +app.set("view engine", "pug");
15 18
16 -app.use(logger('dev')); 19 +app.use(logger("dev"));
17 app.use(express.json()); 20 app.use(express.json());
18 app.use(express.urlencoded({ extended: false })); 21 app.use(express.urlencoded({ extended: false }));
19 app.use(cookieParser()); 22 app.use(cookieParser());
20 -app.use(express.static(path.join(__dirname, 'public'))); 23 +app.use(express.static(path.join(__dirname, "public")));
21 24
22 -app.use('/', indexRouter); 25 +app.use("/", indexRouter);
23 -app.use('/users', usersRouter); 26 +app.use("/users", usersRouter);
27 +app.use("/airCondition", airConditionRouter);
24 28
25 // catch 404 and forward to error handler 29 // catch 404 and forward to error handler
26 -app.use(function(req, res, next) { 30 +app.use(function (req, res, next) {
27 next(createError(404)); 31 next(createError(404));
28 }); 32 });
29 33
30 // error handler 34 // error handler
31 -app.use(function(err, req, res, next) { 35 +app.use(function (err, req, res, next) {
32 // set locals, only providing error in development 36 // set locals, only providing error in development
33 res.locals.message = err.message; 37 res.locals.message = err.message;
34 - res.locals.error = req.app.get('env') === 'development' ? err : {}; 38 + res.locals.error = req.app.get("env") === "development" ? err : {};
35 39
36 // render the error page 40 // render the error page
37 res.status(err.status || 500); 41 res.status(err.status || 500);
38 - res.render('error'); 42 + res.render("error");
39 }); 43 });
40 44
41 module.exports = app; 45 module.exports = app;
......
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
4 * Module dependencies. 4 * Module dependencies.
5 */ 5 */
6 6
7 -var app = require('../app'); 7 +var app = require("../app");
8 -var debug = require('debug')('backend:server'); 8 +var debug = require("debug")("backend:server");
9 -var http = require('http'); 9 +var http = require("http");
10 10
11 /** 11 /**
12 * Get port from environment and store in Express. 12 * Get port from environment and store in Express.
13 */ 13 */
14 14
15 -var port = normalizePort(process.env.PORT || '3000'); 15 +var port = normalizePort(process.env.PORT || "3001");
16 -app.set('port', port); 16 +app.set("port", port);
17 17
18 /** 18 /**
19 * Create HTTP server. 19 * Create HTTP server.
...@@ -26,8 +26,8 @@ var server = http.createServer(app); ...@@ -26,8 +26,8 @@ var server = http.createServer(app);
26 */ 26 */
27 27
28 server.listen(port); 28 server.listen(port);
29 -server.on('error', onError); 29 +server.on("error", onError);
30 -server.on('listening', onListening); 30 +server.on("listening", onListening);
31 31
32 /** 32 /**
33 * Normalize a port into a number, string, or false. 33 * Normalize a port into a number, string, or false.
...@@ -54,22 +54,20 @@ function normalizePort(val) { ...@@ -54,22 +54,20 @@ function normalizePort(val) {
54 */ 54 */
55 55
56 function onError(error) { 56 function onError(error) {
57 - if (error.syscall !== 'listen') { 57 + if (error.syscall !== "listen") {
58 throw error; 58 throw error;
59 } 59 }
60 60
61 - var bind = typeof port === 'string' 61 + var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
62 - ? 'Pipe ' + port
63 - : 'Port ' + port;
64 62
65 // handle specific listen errors with friendly messages 63 // handle specific listen errors with friendly messages
66 switch (error.code) { 64 switch (error.code) {
67 - case 'EACCES': 65 + case "EACCES":
68 - console.error(bind + ' requires elevated privileges'); 66 + console.error(bind + " requires elevated privileges");
69 process.exit(1); 67 process.exit(1);
70 break; 68 break;
71 - case 'EADDRINUSE': 69 + case "EADDRINUSE":
72 - console.error(bind + ' is already in use'); 70 + console.error(bind + " is already in use");
73 process.exit(1); 71 process.exit(1);
74 break; 72 break;
75 default: 73 default:
...@@ -83,8 +81,6 @@ function onError(error) { ...@@ -83,8 +81,6 @@ function onError(error) {
83 81
84 function onListening() { 82 function onListening() {
85 var addr = server.address(); 83 var addr = server.address();
86 - var bind = typeof addr === 'string' 84 + var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
87 - ? 'pipe ' + addr 85 + debug("Listening on " + bind);
88 - : 'port ' + addr.port;
89 - debug('Listening on ' + bind);
90 } 86 }
......
This diff is collapsed. Click to expand it.
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
6 "start": "node ./bin/www" 6 "start": "node ./bin/www"
7 }, 7 },
8 "dependencies": { 8 "dependencies": {
9 + "axios": "^0.19.2",
9 "cookie-parser": "~1.4.3", 10 "cookie-parser": "~1.4.3",
11 + "cors": "^2.8.5",
10 "debug": "~2.6.9", 12 "debug": "~2.6.9",
11 "express": "~4.16.0", 13 "express": "~4.16.0",
12 "http-errors": "~1.6.2", 14 "http-errors": "~1.6.2",
......
1 +var express = require("express");
2 +var router = express.Router();
3 +var axios = require("axios");
4 +
5 +const openAPIKey = require("./secrets.json").openAPIKey;
6 +const googleMapKey = require("./secrets.json").googleAPIKey;
7 +const weatherAPIKey = require("./secrets.json").weatherAPIKey;
8 +
9 +axios.create({
10 + // TODO : 웹을 AWS에 올릴때, 해당 baseURL이 달라져야할 수 있음
11 + baseURL: "http://localhost:3001",
12 + responseType: "json",
13 +});
14 +
15 +/* GET airCondition listing. */
16 +router.get("/", async function (req, res, next) {
17 + console.log("경도:", req.query.latitude);
18 + console.log("경도:", req.query.longitude);
19 + let airCondition = "";
20 + let response = await getPosition(req.query.latitude, req.query.longitude)
21 + .then((encodedStation) => getCondition(encodedStation))
22 + .then((result) => {
23 + airCondition = result;
24 + });
25 +
26 + res.send(airCondition);
27 +});
28 +
29 +router.get("/weather", async function (req, res, next) {
30 + console.log("경도:", req.query.latitude);
31 + console.log("경도:", req.query.longitude);
32 +
33 + let airCondition = "";
34 + let response = await getEnglishPosition(
35 + req.query.latitude,
36 + req.query.longitude
37 + )
38 + .then((encodedStation) => getWeather(encodedStation))
39 + .then((result) => {
40 + airCondition = result;
41 + });
42 +
43 + res.send(airCondition);
44 +});
45 +
46 +const getWeather = (encodedStation) => {
47 + return axios
48 + .get(
49 + "https://api.openweathermap.org/data/2.5/weather?q=" +
50 + encodedStation +
51 + "&appid=" +
52 + weatherAPIKey
53 + )
54 + .then(function (response) {
55 + return response["data"];
56 + })
57 + .catch(function (error) {
58 + console.log(error.response);
59 + });
60 +};
61 +
62 +const getPosition = (lat, lon) => {
63 + return axios
64 + .get(
65 + "https://maps.googleapis.com/maps/api/geocode/json?latlng=" +
66 + lat +
67 + "," +
68 + lon +
69 + "&location_type=ROOFTOP&result_type=street_address&key=" +
70 + googleMapKey +
71 + "&language=ko"
72 + )
73 + .then(function (response) {
74 + console.log("KEY : ", googleMapKey);
75 + let stationName = "";
76 + for (
77 + let i = 0;
78 + i < response["data"].results[0]["address_components"].length;
79 + i++
80 + ) {
81 + let temp =
82 + response["data"].results[0]["address_components"][i]["long_name"];
83 + if (temp[temp.length - 1] == "구") {
84 + stationName = temp;
85 + break;
86 + }
87 + }
88 + console.log("STATION : ", stationName);
89 + return (encodedStation = encodeURI(stationName));
90 + })
91 + .catch(function (error) {
92 + console.log(error.response);
93 + });
94 +};
95 +
96 +const getEnglishPosition = (lat, lon) => {
97 + return axios
98 + .get(
99 + "https://maps.googleapis.com/maps/api/geocode/json?latlng=" +
100 + lat +
101 + "," +
102 + lon +
103 + "&location_type=ROOFTOP&result_type=street_address&key=" +
104 + googleMapKey +
105 + "&language=en"
106 + )
107 + .then(function (response) {
108 + let stationName =
109 + response["data"].results[0]["address_components"][3]["long_name"];
110 + console.log("STATION : ", stationName);
111 + return (encodedStation = encodeURI(stationName));
112 + })
113 + .catch(function (error) {
114 + console.log(error.response);
115 + });
116 +};
117 +
118 +/* GET route airCondition listing. */
119 +router.get("/route", async function (req, res, next) {
120 + console.log("출발지:", req.query.departure);
121 + console.log("도착지:", req.query.arrival);
122 +
123 + let dep = JSON.parse(req.query.departure);
124 + let depLat = dep["Ha"];
125 + let depLon = dep["Ga"];
126 +
127 + let arr = JSON.parse(req.query.arrival);
128 + let arrLat = arr["Ha"];
129 + let arrLon = arr["Ga"];
130 + let airCondition = "";
131 +
132 + let response = await getRoute(depLat, depLon, arrLat, arrLon)
133 + .then((routeInformation) =>
134 + routeAirCondition(depLat, depLon, routeInformation)
135 + )
136 + .then((routeInformation) => {
137 + airCondition = routeInformation;
138 + });
139 +
140 + res.send(airCondition);
141 +});
142 +
143 +const getCondition = (encodedStation) => {
144 + return axios
145 + .get(
146 + "http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty?serviceKey=" +
147 + openAPIKey +
148 + "&numOfRows=10&pageNo=1&stationName=" +
149 + encodedStation +
150 + "&dataTerm=DAILY&ver=1.3&_returnType=json"
151 + )
152 + .then(function (response) {
153 + // console.log("RES :: ", response);
154 + result = response["data"]["list"][0];
155 + return result;
156 + })
157 + .catch(function (error) {
158 + console.log(error.response);
159 + });
160 +};
161 +
162 +const getRoute = (depLat, depLon, arrLat, arrLon) => {
163 + return axios
164 + .get(
165 + "https://maps.googleapis.com/maps/api/directions/json?origin=" +
166 + depLat +
167 + "," +
168 + depLon +
169 + "&destination=" +
170 + arrLat +
171 + "," +
172 + arrLon +
173 + "&mode=transit&departure_time=now&key=" +
174 + googleMapKey +
175 + "&language=ko"
176 + )
177 + .then(function (response) {
178 + console.log(response["data"]);
179 + let routeInformation = [];
180 + for (
181 + let i = 0;
182 + i < response["data"].routes[0]["legs"][0]["steps"].length;
183 + i++
184 + ) {
185 + let info = {};
186 + info["instruction"] =
187 + response["data"].routes[0]["legs"][0]["steps"][i][
188 + "html_instructions"
189 + ];
190 + info["location"] =
191 + response["data"].routes[0]["legs"][0]["steps"][i]["end_location"];
192 + info["duration"] =
193 + response["data"].routes[0]["legs"][0]["steps"][i]["duration"]["text"];
194 + info["travel_mode"] =
195 + response["data"].routes[0]["legs"][0]["steps"][i]["travel_mode"];
196 + routeInformation.push(info);
197 + }
198 + // console.log(routeInformation);
199 + return routeInformation;
200 + })
201 + .catch(function (error) {
202 + console.log(error.response);
203 + });
204 +};
205 +
206 +const routeAirCondition = async (depLat, depLon, routeInformation) => {
207 + await getPosition(depLat, depLon)
208 + .then((encodedStation) => getCondition(encodedStation))
209 + .then((result) => {
210 + let info = {};
211 + info["airCondition"] = result;
212 + routeInformation.push(info);
213 + });
214 + for (let i = 0; i < routeInformation.length - 1; i++) {
215 + await getPosition(
216 + routeInformation[i]["location"]["lat"],
217 + routeInformation[i]["location"]["lng"]
218 + )
219 + .then((encodedStation) => getCondition(encodedStation))
220 + .then((result) => {
221 + routeInformation[i]["airCondition"] = result;
222 + });
223 + }
224 + console.log(routeInformation);
225 + return routeInformation;
226 +};
227 +
228 +module.exports = router;
1 -var express = require('express'); 1 +var express = require("express");
2 var router = express.Router(); 2 var router = express.Router();
3 3
4 /* GET home page. */ 4 /* GET home page. */
5 -router.get('/', function(req, res, next) { 5 +router.get("/", function (req, res, next) {
6 - res.render('index', { title: 'Express' }); 6 + res.render("index", { title: "Express" });
7 }); 7 });
8 8
9 module.exports = router; 9 module.exports = router;
......
...@@ -3,3 +3,4 @@ extends layout ...@@ -3,3 +3,4 @@ extends layout
3 block content 3 block content
4 h1= title 4 h1= title
5 p Welcome to #{title} 5 p Welcome to #{title}
6 + p This is HowsTheWeather Backend
......
This diff could not be displayed because it is too large.
...@@ -6,8 +6,14 @@ ...@@ -6,8 +6,14 @@
6 "@testing-library/jest-dom": "^4.2.4", 6 "@testing-library/jest-dom": "^4.2.4",
7 "@testing-library/react": "^9.3.2", 7 "@testing-library/react": "^9.3.2",
8 "@testing-library/user-event": "^7.1.2", 8 "@testing-library/user-event": "^7.1.2",
9 + "axios": "^0.19.2",
10 + "bootstrap": "^3.4.1",
11 + "daum-map-api": "^1.0.2",
9 "react": "^16.13.1", 12 "react": "^16.13.1",
13 + "react-bootstrap": "^1.0.1",
10 "react-dom": "^16.13.1", 14 "react-dom": "^16.13.1",
15 + "react-kakao-maps": "0.0.13",
16 + "react-router-dom": "^5.2.0",
11 "react-scripts": "3.4.1" 17 "react-scripts": "3.4.1"
12 }, 18 },
13 "scripts": { 19 "scripts": {
......
...@@ -10,6 +10,16 @@ ...@@ -10,6 +10,16 @@
10 content="Web site created using create-react-app" 10 content="Web site created using create-react-app"
11 /> 11 />
12 <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> 12 <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13 + <script
14 + type="text/javascript"
15 + src="//dapi.kakao.com/v2/maps/sdk.js?appkey=61abec34d0855ba1d434ea222263d4a5&libraries=services,clusterer,drawing"
16 + ></script>
17 + <link
18 + rel="stylesheet"
19 + href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
20 + integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
21 + crossorigin="anonymous"
22 + />
13 <!-- 23 <!--
14 manifest.json provides metadata used when your web app is installed on a 24 manifest.json provides metadata used when your web app is installed on a
15 user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ 25 user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
...@@ -24,7 +34,7 @@ ...@@ -24,7 +34,7 @@
24 work correctly both with client-side routing and a non-root public URL. 34 work correctly both with client-side routing and a non-root public URL.
25 Learn how to configure a non-root public URL by running `npm run build`. 35 Learn how to configure a non-root public URL by running `npm run build`.
26 --> 36 -->
27 - <title>React App</title> 37 + <title>HowsTheWeather</title>
28 </head> 38 </head>
29 <body> 39 <body>
30 <noscript>You need to enable JavaScript to run this app.</noscript> 40 <noscript>You need to enable JavaScript to run this app.</noscript>
......
1 +import axios from "axios";
2 +
3 +export default axios.create({
4 + baseURL: "http://localhost:3001",
5 + responseType: "json",
6 +});
...@@ -15,13 +15,14 @@ ...@@ -15,13 +15,14 @@
15 15
16 .App-header { 16 .App-header {
17 background-color: #282c34; 17 background-color: #282c34;
18 - min-height: 100vh; 18 + min-height: 13vh;
19 display: flex; 19 display: flex;
20 flex-direction: column; 20 flex-direction: column;
21 align-items: center; 21 align-items: center;
22 justify-content: center; 22 justify-content: center;
23 font-size: calc(10px + 2vmin); 23 font-size: calc(10px + 2vmin);
24 color: white; 24 color: white;
25 + font-weight: bold;
25 } 26 }
26 27
27 .App-link { 28 .App-link {
......
1 -import React from 'react'; 1 +import React, { Component } from "react";
2 -import logo from './logo.svg'; 2 +import { HashRouter, Route } from "react-router-dom";
3 -import './App.css'; 3 +import ScrollToTop from "./ScrollToTop";
4 +import Home from "./home";
4 5
5 -function App() { 6 +class App extends Component {
6 - return ( 7 + constructor(props) {
7 - <div className="App"> 8 + super(props);
8 - <header className="App-header"> 9 + }
9 - <img src={logo} className="App-logo" alt="logo" /> 10 + render() {
10 - <p> 11 + return (
11 - Edit <code>src/App.js</code> and save to reload. 12 + <HashRouter basename={process.env.PUBLIC_URL}>
12 - </p> 13 + <ScrollToTop>
13 - <a 14 + <div className="App">
14 - className="App-link" 15 + <Route exact path="/" component={Home} />
15 - href="https://reactjs.org" 16 + </div>
16 - target="_blank" 17 + </ScrollToTop>
17 - rel="noopener noreferrer" 18 + </HashRouter>
18 - > 19 + );
19 - Learn React 20 + }
20 - </a>
21 - </header>
22 - </div>
23 - );
24 } 21 }
25 22
26 export default App; 23 export default App;
......
1 +import { Component } from "react";
2 +import { withRouter } from "react-router-dom";
3 +
4 +class ScrollToTop extends Component {
5 + componentDidUpdate(prevProps) {
6 + if (this.props.location !== prevProps.location) {
7 + window.scrollTo(0, 0);
8 + }
9 + }
10 +
11 + render() {
12 + return this.props.children;
13 + }
14 +}
15 +
16 +export default withRouter(ScrollToTop);
1 +.Home {
2 + text-align: center;
3 +}
4 +
5 +.Home-logo {
6 + height: 40vmin;
7 + pointer-events: none;
8 +}
9 +
10 +@media (prefers-reduced-motion: no-preference) {
11 + .Home-logo {
12 + animation: Home-logo-spin infinite 20s linear;
13 + }
14 +}
15 +
16 +.Home-header {
17 + background-color: #282c34;
18 + min-height: 13vh;
19 + display: flex;
20 + flex-direction: column;
21 + align-items: center;
22 + justify-content: center;
23 + font-size: calc(10px + 2vmin);
24 + color: white;
25 + font-weight: bold;
26 +}
27 +
28 +.Home-link {
29 + color: #61dafb;
30 +}
31 +
32 +@keyframes Home-logo-spin {
33 + from {
34 + transform: rotate(0deg);
35 + }
36 + to {
37 + transform: rotate(360deg);
38 + }
39 +}
40 +
41 +.strong {
42 + font-size: calc(10px + 1vmin);
43 + font-weight: bold;
44 +}
45 +.map_wrap,
46 +.map_wrap * {
47 + margin: 0;
48 + padding: 0;
49 + font-family: "Malgun Gothic", dotum, "돋움", sans-serif;
50 + font-size: 12px;
51 +}
52 +.map_wrap a,
53 +.map_wrap a:hover,
54 +.map_wrap a:active {
55 + color: #000;
56 + text-decoration: none;
57 +}
58 +.map_wrap {
59 + position: relative;
60 + width: 100%;
61 + height: 500px;
62 +}
63 +
64 +#menu_wrap {
65 + position: absolute;
66 + top: 0;
67 + left: 0;
68 + bottom: 0;
69 + width: 250px;
70 + margin: 10px 0 30px 10px;
71 + padding: 5px;
72 + overflow-y: auto;
73 + background: rgba(53, 53, 53, 0.8);
74 + z-index: 1;
75 + font-size: 12px;
76 + border-radius: 10px;
77 +}
78 +.bg_white {
79 + background: #fff;
80 +}
81 +x #menu_wrap hr {
82 + display: block;
83 + height: 1px;
84 + border: 0;
85 + border-top: 2px solid #5f5f5f;
86 + margin: 3px 0;
87 +}
88 +#menu_wrap .option {
89 + text-align: center;
90 + color: #ffffff;
91 + font-weight: bold;
92 +}
93 +#menu_wrap .option p {
94 + margin: 10px 0;
95 +}
96 +#menu_wrap .option button {
97 + margin-left: 5px;
98 +}
99 +
100 +#placesList li {
101 + list-style: none;
102 +}
103 +#placesList .item {
104 + position: relative;
105 + border-bottom: 1px solid #888;
106 + overflow: hidden;
107 + cursor: pointer;
108 + min-height: 65px;
109 +}
110 +#placesList .item span {
111 + display: block;
112 + margin-top: 4px;
113 +}
114 +#placesList .item h5,
115 +#placesList .item .info {
116 + text-overflow: ellipsis;
117 + overflow: hidden;
118 + white-space: nowrap;
119 +}
120 +#placesList .item .info {
121 + padding: 10px 0 10px 55px;
122 + color: #ffffff;
123 +}
124 +#placesList .info .gray {
125 + color: #eaeaea;
126 +}
127 +#placesList .info .jibun {
128 + padding-left: 26px;
129 + background: url(http://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_jibun.png)
130 + no-repeat;
131 +}
132 +#placesList .info .tel {
133 + color: #ffbb00;
134 + font-weight: bold;
135 +}
136 +#placesList .item .markerbg {
137 + float: left;
138 + position: absolute;
139 + width: 36px;
140 + height: 37px;
141 + margin: 10px 0 0 10px;
142 + background: url(http://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png)
143 + no-repeat;
144 +}
145 +#placesList .item .marker_1 {
146 + background-position: 0 -10px;
147 +}
148 +#placesList .item .marker_2 {
149 + background-position: 0 -56px;
150 +}
151 +#placesList .item .marker_3 {
152 + background-position: 0 -102px;
153 +}
154 +#placesList .item .marker_4 {
155 + background-position: 0 -148px;
156 +}
157 +#placesList .item .marker_5 {
158 + background-position: 0 -194px;
159 +}
160 +#placesList .item .marker_6 {
161 + background-position: 0 -240px;
162 +}
163 +#placesList .item .marker_7 {
164 + background-position: 0 -286px;
165 +}
166 +#placesList .item .marker_8 {
167 + background-position: 0 -332px;
168 +}
169 +#placesList .item .marker_9 {
170 + background-position: 0 -378px;
171 +}
172 +#placesList .item .marker_10 {
173 + background-position: 0 -423px;
174 +}
175 +#placesList .item .marker_11 {
176 + background-position: 0 -470px;
177 +}
178 +#placesList .item .marker_12 {
179 + background-position: 0 -516px;
180 +}
181 +#placesList .item .marker_13 {
182 + background-position: 0 -562px;
183 +}
184 +#placesList .item .marker_14 {
185 + background-position: 0 -608px;
186 +}
187 +#placesList .item .marker_15 {
188 + background-position: 0 -654px;
189 +}
190 +#pagination {
191 + margin: 10px auto;
192 + text-align: center;
193 +}
194 +#pagination a {
195 + display: inline-block;
196 + margin-right: 10px;
197 +}
198 +#pagination .on {
199 + font-weight: bold;
200 + cursor: default;
201 + color: #777;
202 +}
203 +
204 +.wraps {
205 + position: absolute;
206 + left: 0;
207 + bottom: 40px;
208 + width: 288px;
209 + height: 132px;
210 + margin-left: -144px;
211 + text-align: left;
212 + overflow: hidden;
213 + font-size: 12px;
214 + font-family: "Malgun Gothic", dotum, "돋움", sans-serif;
215 + line-height: 1.5;
216 +}
217 +.wraps * {
218 + padding: 0;
219 + margin: 0;
220 +}
221 +.wraps .infos {
222 + width: 286px;
223 + height: 120px;
224 + border-radius: 5px;
225 + border-bottom: 2px solid #ccc;
226 + border-right: 1px solid #ccc;
227 + overflow: hidden;
228 + background: #fff;
229 +}
230 +.wraps .infos:nth-child(1) {
231 + border: 0;
232 + box-shadow: 0px 1px 2px #888;
233 +}
234 +.infos .title {
235 + padding: 5px 0 0 10px;
236 + height: 30px;
237 + background: #eee;
238 + border-bottom: 1px solid #ddd;
239 + font-size: 18px;
240 + font-weight: bold;
241 +}
242 +.infos .close {
243 + position: absolute;
244 + top: 10px;
245 + right: 10px;
246 + color: #888;
247 + width: 17px;
248 + height: 17px;
249 + background: url("http://t1.daumcdn.net/localimg/localimages/07/mapapidoc/overlay_close.png");
250 +}
251 +.infos .close:hover {
252 + cursor: pointer;
253 +}
254 +.infos .body {
255 + position: relative;
256 + overflow: hidden;
257 +}
258 +.infos .desc {
259 + position: relative;
260 + margin: 13px 0 0 90px;
261 + height: 75px;
262 +}
263 +.desc .ellipsis {
264 + overflow: hidden;
265 + text-overflow: ellipsis;
266 + white-space: nowrap;
267 +}
268 +.desc .jibun {
269 + font-size: 11px;
270 + color: #888;
271 + margin-top: -2px;
272 +}
273 +.infos .img {
274 + position: absolute;
275 + top: 6px;
276 + left: 5px;
277 + width: 73px;
278 + height: 71px;
279 + border: 1px solid #ddd;
280 + color: #888;
281 + overflow: hidden;
282 +}
283 +.infos:after {
284 + content: "";
285 + position: absolute;
286 + margin-left: -12px;
287 + left: 50%;
288 + bottom: 0;
289 + width: 22px;
290 + height: 12px;
291 + background: url("http://t1.daumcdn.net/localimg/localimages/07/mapapidoc/vertex_white.png");
292 +}
293 +.infos .link {
294 + color: #5085bb;
295 +}
296 +
297 +#footer {
298 + position: absolute;
299 + bottom: 0;
300 + width: 100%;
301 + height: 100px;
302 + background: #ccc;
303 +}
304 +
305 +.left-box {
306 + float: left;
307 + width: 20%;
308 +}
309 +.left-box h5 {
310 + font-size: 1rem;
311 + font-style: italic;
312 + padding-left: 10px;
313 +}
314 +.right-box {
315 + float: right;
316 + width: 80%;
317 +}
318 +.right-box h5 {
319 + font-size: 1rem;
320 + font-style: italic;
321 + padding-left: 10px;
322 +}
323 +#middle {
324 + text-align: center;
325 +}
326 +.info-button {
327 + border-radius: 4px;
328 + background-color: #4641d9;
329 + width: 100px;
330 + color: white;
331 +}
This diff is collapsed. Click to expand it.