├── .dockerignore
├── .gitignore
├── .idea
├── dbnavigator.xml
├── markdown-navigator.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── shorturl.iml
└── terminal.xml
├── .nvmrc
├── .well-known
└── .gitkeep
├── Dockerfile
├── README.md
├── app.json
├── config.json
├── docker-compose.yml
├── docs
└── shortlr.gif
├── logo.png
├── package-lock.json
├── package.json
├── routes
├── api_v1.js
├── auth.js
└── shortcode.js
├── secrets-sample.json
├── server.js
├── static
└── admin
│ ├── css
│ ├── bootstrap.min.css
│ ├── index.css
│ ├── stylesheet.css
│ └── symentic.css
│ ├── img
│ ├── cblogo.png
│ └── logo.png
│ ├── includes
│ └── nav-container.html
│ ├── index.html
│ ├── js
│ ├── analytics.js
│ ├── bootstrap.min.js
│ ├── index.js
│ ├── jquery.min.js
│ └── search.js
│ ├── search
│ └── index.html
│ └── stats
│ ├── index.html
│ └── index_ui.html
├── utils
├── db.js
├── shortner.js
└── validator.js
└── wait-for-it.sh
/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | .idea/
3 | .idea/workspace.xml
4 | .idea/tasks.xml
5 | .idea/dictionaries
6 | .idea/vcs.xml
7 | .idea/jsLibraryMappings.xml
8 | .idea/dataSources.ids
9 | .idea/dataSources.xml
10 | .idea/dataSources.local.xml
11 | .idea/sqlDataSources.xml
12 | .idea/dynamic.xml
13 | .idea/uiDesigner.xml
14 | .idea/gradle.xml
15 | .idea/libraries
16 | .idea/mongoSettings.xml
17 | *.iws
18 | /out/
19 | .idea_modules/
20 | atlassian-ide-plugin.xml
21 | com_crashlytics_export_strings.xml
22 | crashlytics.properties
23 | crashlytics-build.properties
24 | fabric.properties
25 | logs
26 | *.log
27 | npm-debug.log*
28 | pids
29 | *.pid
30 | *.seed
31 | lib-cov
32 | coverage
33 | .nyc_output
34 | .grunt
35 | .lock-wscript
36 | build/Release
37 | node_modules
38 | jspm_packages
39 | .npm
40 | .node_repl_history
41 | secrets.json
42 |
--------------------------------------------------------------------------------
/.idea/dbnavigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Code style issuesJavaScript
15 |
16 |
17 | Dart
18 |
19 |
20 | Data flow issuesJavaScript
21 |
22 |
23 | General
24 |
25 |
26 | GeneralJavaScript
27 |
28 |
29 | JSON
30 |
31 |
32 | JavaScript
33 |
34 |
35 | JavaScript validity issuesJavaScript
36 |
37 |
38 | Node.jsJavaScript
39 |
40 |
41 | Potentially confusing code constructsJavaScript
42 |
43 |
44 | Probable bugsJavaScript
45 |
46 |
47 | TypeScript
48 |
49 |
50 |
51 |
52 | AngularJS
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/shorturl.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/terminal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 8
2 |
--------------------------------------------------------------------------------
/.well-known/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coding-blocks/shortlr/d2c6c8c1c18164afef47b8e015e569c5dd0d0aca/.well-known/.gitkeep
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | RUN apt-get update
4 |
5 | RUN mkdir /shortlr
6 | ADD . /shortlr
7 | WORKDIR /shortlr
8 |
9 | RUN chmod +x ./wait-for-it.sh
10 |
11 | # install dependencies
12 | RUN npm install
13 |
14 | # Expose port where node server running
15 | EXPOSE 4000
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | # shortlr
3 |
4 | An URL shortening service written in **_express_**
5 |
6 |
7 | ## Getting Started
8 |
9 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
10 |
11 | ### Prerequisites
12 |
13 | * NodeJS
14 | * Node Package Manager(NPM)
15 | * Git
16 | * PostgreSQL
17 |
18 |
19 | ### Installing
20 |
21 | A step by step series of examples that tell you have to get a development environment running
22 |
23 | 1. Download ZIP file or clone the repository to create your own copy.
24 | ```
25 | git clone https://github.com/coding-blocks/shortlr
26 | ```
27 | 2. Move to the shortlr repository
28 |
29 | ```
30 | cd ./shortlr
31 | ```
32 | 3. Install all project dependency packages via NPM
33 |
34 | ```
35 | npm install
36 | ```
37 | 4. Set up PostgreSQL
38 | * If you don't have PostgreSQL setup on you machine you can download it from [here](https://www.postgresql.org/download/).
39 |
40 | * After Installation is complete create a new PostgreSQL user **shorturl** with password as **shorturl**.
41 |
42 | * Create a new database in PostgreSQL server with name **shorturl**.
43 |
44 | 5. Start the server.
45 | ```
46 | npm start
47 | ```
48 | And see it working on http://localhost:4000/admin
49 |
50 |
51 | ## Deploying to Heroku
52 |
53 | ```
54 | heroku create
55 | git push heroku master
56 | heroku open
57 | ```
58 |
59 | Alternatively, you can deploy your own copy of the app using this button:
60 |
61 | [](https://heroku.com/deploy)
62 |
63 | ## Authors
64 | * Arnav Gupta -- [championswimmer](https://github.com/championswimmer)
65 |
66 | See also the list of [contributors](https://github.com/coding-blocks/shortlr/graphs/contributors) who are participating in this project.
67 |
68 |
69 | ### Demo
70 |
71 | 
72 |
73 |
74 | [](https://nodei.co/npm/shortlr/)
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Shortlr",
3 | "description": "An URL shortening service written in express",
4 | "keywords": [
5 | "nodejs",
6 | "HTML5",
7 | "express"
8 | ],
9 | "website": "https://codingblocks.com/",
10 | "repository": "https://github.com/coding-blocks/shortlr",
11 | "addons": ["heroku-postgresql:hobby-dev"]
12 | }
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "FORCE_HTTPS": true,
3 | "TRUST_HTTPS_PROXY": true ,
4 | "ENABLE_301_HTTPS_REDIRECT": true,
5 | "NON_HTTPS_REQUEST_ERRMSG": "SSL is required on this path",
6 | "PAGINATION_SIZE" : 30
7 | }
8 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 | services:
3 | web:
4 | build: .
5 | ports:
6 | - "4000:4000"
7 | volumes:
8 | - .:/shortlr
9 | depends_on:
10 | - postgres
11 | environment:
12 | - NODE_MYSQL_HOST=postgres
13 | command: ["./wait-for-it.sh","postgres:5432", "--", "npm", "start"]
14 | postgres:
15 | image: "postgres:latest"
16 | environment:
17 | POSTGRES_USER: shorturl
18 | POSTGRES_DB: shorturl
19 | POSTGRES_PASSWORD: shorturl
20 |
--------------------------------------------------------------------------------
/docs/shortlr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coding-blocks/shortlr/d2c6c8c1c18164afef47b8e015e569c5dd0d0aca/docs/shortlr.gif
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coding-blocks/shortlr/d2c6c8c1c18164afef47b8e015e569c5dd0d0aca/logo.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shortlr",
3 | "version": "0.0.5",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/geojson": {
8 | "version": "1.0.6",
9 | "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz",
10 | "integrity": "sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w=="
11 | },
12 | "accepts": {
13 | "version": "1.3.4",
14 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
15 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
16 | "requires": {
17 | "mime-types": "2.1.16",
18 | "negotiator": "0.6.1"
19 | }
20 | },
21 | "ajv": {
22 | "version": "5.5.2",
23 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
24 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
25 | "requires": {
26 | "co": "4.6.0",
27 | "fast-deep-equal": "1.0.0",
28 | "fast-json-stable-stringify": "2.0.0",
29 | "json-schema-traverse": "0.3.1"
30 | }
31 | },
32 | "array-flatten": {
33 | "version": "1.1.1",
34 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
35 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
36 | },
37 | "asn1": {
38 | "version": "0.2.3",
39 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
40 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
41 | },
42 | "assert-plus": {
43 | "version": "1.0.0",
44 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
45 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
46 | },
47 | "async": {
48 | "version": "1.2.1",
49 | "resolved": "https://registry.npmjs.org/async/-/async-1.2.1.tgz",
50 | "integrity": "sha1-pIFqF81f9RbfosdpikUzabl5DeA="
51 | },
52 | "asynckit": {
53 | "version": "0.4.0",
54 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
55 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
56 | },
57 | "aws-sign2": {
58 | "version": "0.7.0",
59 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
60 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
61 | },
62 | "aws4": {
63 | "version": "1.6.0",
64 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
65 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
66 | },
67 | "axios": {
68 | "version": "0.16.2",
69 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.16.2.tgz",
70 | "integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=",
71 | "requires": {
72 | "follow-redirects": "1.2.4",
73 | "is-buffer": "1.1.5"
74 | }
75 | },
76 | "bcrypt-pbkdf": {
77 | "version": "1.0.1",
78 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
79 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
80 | "optional": true,
81 | "requires": {
82 | "tweetnacl": "0.14.5"
83 | }
84 | },
85 | "bluebird": {
86 | "version": "3.5.1",
87 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
88 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
89 | },
90 | "body-parser": {
91 | "version": "1.17.2",
92 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
93 | "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
94 | "requires": {
95 | "bytes": "2.4.0",
96 | "content-type": "1.0.2",
97 | "debug": "2.6.7",
98 | "depd": "1.1.1",
99 | "http-errors": "1.6.2",
100 | "iconv-lite": "0.4.15",
101 | "on-finished": "2.3.0",
102 | "qs": "6.4.0",
103 | "raw-body": "2.2.0",
104 | "type-is": "1.6.15"
105 | },
106 | "dependencies": {
107 | "debug": {
108 | "version": "2.6.7",
109 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
110 | "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=",
111 | "requires": {
112 | "ms": "2.0.0"
113 | }
114 | }
115 | }
116 | },
117 | "boom": {
118 | "version": "4.3.1",
119 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
120 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
121 | "requires": {
122 | "hoek": "4.2.0"
123 | }
124 | },
125 | "buffer-writer": {
126 | "version": "1.0.1",
127 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz",
128 | "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg="
129 | },
130 | "bytes": {
131 | "version": "2.4.0",
132 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
133 | "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
134 | },
135 | "caseless": {
136 | "version": "0.12.0",
137 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
138 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
139 | },
140 | "co": {
141 | "version": "4.6.0",
142 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
143 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
144 | },
145 | "combined-stream": {
146 | "version": "1.0.5",
147 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
148 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
149 | "requires": {
150 | "delayed-stream": "1.0.0"
151 | }
152 | },
153 | "content-disposition": {
154 | "version": "0.5.2",
155 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
156 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
157 | },
158 | "content-type": {
159 | "version": "1.0.2",
160 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
161 | "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0="
162 | },
163 | "convert-radix64": {
164 | "version": "0.2.0",
165 | "resolved": "https://registry.npmjs.org/convert-radix64/-/convert-radix64-0.2.0.tgz",
166 | "integrity": "sha1-zjdU+f9H2cReFD222WpV6okCStA="
167 | },
168 | "cookie": {
169 | "version": "0.3.1",
170 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
171 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
172 | },
173 | "cookie-signature": {
174 | "version": "1.0.6",
175 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
176 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
177 | },
178 | "core-util-is": {
179 | "version": "1.0.2",
180 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
181 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
182 | },
183 | "cors": {
184 | "version": "2.8.4",
185 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
186 | "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
187 | "requires": {
188 | "object-assign": "4.1.1",
189 | "vary": "1.1.2"
190 | }
191 | },
192 | "cryptiles": {
193 | "version": "3.1.2",
194 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
195 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
196 | "requires": {
197 | "boom": "5.2.0"
198 | },
199 | "dependencies": {
200 | "boom": {
201 | "version": "5.2.0",
202 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
203 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
204 | "requires": {
205 | "hoek": "4.2.0"
206 | }
207 | }
208 | }
209 | },
210 | "dashdash": {
211 | "version": "1.14.1",
212 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
213 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
214 | "requires": {
215 | "assert-plus": "1.0.0"
216 | }
217 | },
218 | "debug": {
219 | "version": "2.6.8",
220 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
221 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
222 | "requires": {
223 | "ms": "2.0.0"
224 | }
225 | },
226 | "delayed-stream": {
227 | "version": "1.0.0",
228 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
229 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
230 | },
231 | "depd": {
232 | "version": "1.1.1",
233 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
234 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
235 | },
236 | "destroy": {
237 | "version": "1.0.4",
238 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
239 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
240 | },
241 | "dottie": {
242 | "version": "1.1.1",
243 | "resolved": "https://registry.npmjs.org/dottie/-/dottie-1.1.1.tgz",
244 | "integrity": "sha1-RcKj9IvWUo7u0memmoSOqspvqmo="
245 | },
246 | "ecc-jsbn": {
247 | "version": "0.1.1",
248 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
249 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
250 | "optional": true,
251 | "requires": {
252 | "jsbn": "0.1.1"
253 | }
254 | },
255 | "ee-first": {
256 | "version": "1.1.1",
257 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
258 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
259 | },
260 | "encodeurl": {
261 | "version": "1.0.2",
262 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
263 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
264 | },
265 | "escape-html": {
266 | "version": "1.0.3",
267 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
268 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
269 | },
270 | "etag": {
271 | "version": "1.8.1",
272 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
273 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
274 | },
275 | "express": {
276 | "version": "4.15.4",
277 | "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
278 | "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
279 | "requires": {
280 | "accepts": "1.3.4",
281 | "array-flatten": "1.1.1",
282 | "content-disposition": "0.5.2",
283 | "content-type": "1.0.2",
284 | "cookie": "0.3.1",
285 | "cookie-signature": "1.0.6",
286 | "debug": "2.6.8",
287 | "depd": "1.1.1",
288 | "encodeurl": "1.0.2",
289 | "escape-html": "1.0.3",
290 | "etag": "1.8.1",
291 | "finalhandler": "1.0.4",
292 | "fresh": "0.5.0",
293 | "merge-descriptors": "1.0.1",
294 | "methods": "1.1.2",
295 | "on-finished": "2.3.0",
296 | "parseurl": "1.3.2",
297 | "path-to-regexp": "0.1.7",
298 | "proxy-addr": "1.1.5",
299 | "qs": "6.5.0",
300 | "range-parser": "1.2.0",
301 | "send": "0.15.4",
302 | "serve-static": "1.12.4",
303 | "setprototypeof": "1.0.3",
304 | "statuses": "1.3.1",
305 | "type-is": "1.6.15",
306 | "utils-merge": "1.0.0",
307 | "vary": "1.1.2"
308 | },
309 | "dependencies": {
310 | "qs": {
311 | "version": "6.5.0",
312 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
313 | "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg=="
314 | },
315 | "statuses": {
316 | "version": "1.3.1",
317 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
318 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
319 | }
320 | }
321 | },
322 | "express-force-ssl": {
323 | "version": "0.3.2",
324 | "resolved": "https://registry.npmjs.org/express-force-ssl/-/express-force-ssl-0.3.2.tgz",
325 | "integrity": "sha1-AbK0mK5v0uQRUrIrV6Phc3c69n4=",
326 | "requires": {
327 | "lodash.assign": "3.2.0"
328 | }
329 | },
330 | "express-ga-middleware": {
331 | "version": "0.1.5",
332 | "resolved": "https://registry.npmjs.org/express-ga-middleware/-/express-ga-middleware-0.1.5.tgz",
333 | "integrity": "sha512-tCczTaf9aYhwWcfbunk1vbfJm/jiym7lxziOLb0+Qpija2TLNC2BehBQbSaPpt/zarA5LXLdDwEzCbUYWfpj6A==",
334 | "requires": {
335 | "universal-analytics": "0.4.15"
336 | }
337 | },
338 | "extend": {
339 | "version": "3.0.1",
340 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
341 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
342 | },
343 | "extsprintf": {
344 | "version": "1.3.0",
345 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
346 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
347 | },
348 | "fast-deep-equal": {
349 | "version": "1.0.0",
350 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
351 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
352 | },
353 | "fast-json-stable-stringify": {
354 | "version": "2.0.0",
355 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
356 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
357 | },
358 | "finalhandler": {
359 | "version": "1.0.4",
360 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz",
361 | "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==",
362 | "requires": {
363 | "debug": "2.6.8",
364 | "encodeurl": "1.0.2",
365 | "escape-html": "1.0.3",
366 | "on-finished": "2.3.0",
367 | "parseurl": "1.3.2",
368 | "statuses": "1.3.1",
369 | "unpipe": "1.0.0"
370 | },
371 | "dependencies": {
372 | "statuses": {
373 | "version": "1.3.1",
374 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
375 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
376 | }
377 | }
378 | },
379 | "follow-redirects": {
380 | "version": "1.2.4",
381 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.4.tgz",
382 | "integrity": "sha512-Suw6KewLV2hReSyEOeql+UUkBVyiBm3ok1VPrVFRZnQInWpdoZbbiG5i8aJVSjTr0yQ4Ava0Sh6/joCg1Brdqw==",
383 | "requires": {
384 | "debug": "2.6.8"
385 | }
386 | },
387 | "forever-agent": {
388 | "version": "0.6.1",
389 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
390 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
391 | },
392 | "form-data": {
393 | "version": "2.3.1",
394 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
395 | "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
396 | "requires": {
397 | "asynckit": "0.4.0",
398 | "combined-stream": "1.0.5",
399 | "mime-types": "2.1.16"
400 | }
401 | },
402 | "forwarded": {
403 | "version": "0.1.2",
404 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
405 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
406 | },
407 | "fresh": {
408 | "version": "0.5.0",
409 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
410 | "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
411 | },
412 | "generic-pool": {
413 | "version": "2.4.3",
414 | "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.4.3.tgz",
415 | "integrity": "sha1-eAw29p360FpaBF3Te+etyhGk9v8="
416 | },
417 | "getpass": {
418 | "version": "0.1.7",
419 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
420 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
421 | "requires": {
422 | "assert-plus": "1.0.0"
423 | }
424 | },
425 | "har-schema": {
426 | "version": "2.0.0",
427 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
428 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
429 | },
430 | "har-validator": {
431 | "version": "5.0.3",
432 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
433 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
434 | "requires": {
435 | "ajv": "5.5.2",
436 | "har-schema": "2.0.0"
437 | }
438 | },
439 | "hawk": {
440 | "version": "6.0.2",
441 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
442 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
443 | "requires": {
444 | "boom": "4.3.1",
445 | "cryptiles": "3.1.2",
446 | "hoek": "4.2.0",
447 | "sntp": "2.1.0"
448 | }
449 | },
450 | "hoek": {
451 | "version": "4.2.0",
452 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
453 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
454 | },
455 | "http-errors": {
456 | "version": "1.6.2",
457 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
458 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
459 | "requires": {
460 | "depd": "1.1.1",
461 | "inherits": "2.0.3",
462 | "setprototypeof": "1.0.3",
463 | "statuses": "1.4.0"
464 | }
465 | },
466 | "http-signature": {
467 | "version": "1.2.0",
468 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
469 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
470 | "requires": {
471 | "assert-plus": "1.0.0",
472 | "jsprim": "1.4.1",
473 | "sshpk": "1.13.1"
474 | }
475 | },
476 | "iconv-lite": {
477 | "version": "0.4.15",
478 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
479 | "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
480 | },
481 | "inflection": {
482 | "version": "1.12.0",
483 | "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
484 | "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
485 | },
486 | "inherits": {
487 | "version": "2.0.3",
488 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
489 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
490 | },
491 | "ipaddr.js": {
492 | "version": "1.4.0",
493 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
494 | "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA="
495 | },
496 | "is-buffer": {
497 | "version": "1.1.5",
498 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
499 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
500 | },
501 | "is-typedarray": {
502 | "version": "1.0.0",
503 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
504 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
505 | },
506 | "isstream": {
507 | "version": "0.1.2",
508 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
509 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
510 | },
511 | "jquery": {
512 | "version": "3.2.1",
513 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
514 | "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
515 | },
516 | "jsbn": {
517 | "version": "0.1.1",
518 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
519 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
520 | "optional": true
521 | },
522 | "json-schema": {
523 | "version": "0.2.3",
524 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
525 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
526 | },
527 | "json-schema-traverse": {
528 | "version": "0.3.1",
529 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
530 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
531 | },
532 | "json-stringify-safe": {
533 | "version": "5.0.1",
534 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
535 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
536 | },
537 | "jsprim": {
538 | "version": "1.4.1",
539 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
540 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
541 | "requires": {
542 | "assert-plus": "1.0.0",
543 | "extsprintf": "1.3.0",
544 | "json-schema": "0.2.3",
545 | "verror": "1.10.0"
546 | }
547 | },
548 | "lodash": {
549 | "version": "4.12.0",
550 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz",
551 | "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg="
552 | },
553 | "lodash._baseassign": {
554 | "version": "3.2.0",
555 | "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
556 | "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
557 | "requires": {
558 | "lodash._basecopy": "3.0.1",
559 | "lodash.keys": "3.1.2"
560 | }
561 | },
562 | "lodash._basecopy": {
563 | "version": "3.0.1",
564 | "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
565 | "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY="
566 | },
567 | "lodash._bindcallback": {
568 | "version": "3.0.1",
569 | "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
570 | "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4="
571 | },
572 | "lodash._createassigner": {
573 | "version": "3.1.1",
574 | "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz",
575 | "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=",
576 | "requires": {
577 | "lodash._bindcallback": "3.0.1",
578 | "lodash._isiterateecall": "3.0.9",
579 | "lodash.restparam": "3.6.1"
580 | }
581 | },
582 | "lodash._getnative": {
583 | "version": "3.9.1",
584 | "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
585 | "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
586 | },
587 | "lodash._isiterateecall": {
588 | "version": "3.0.9",
589 | "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
590 | "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw="
591 | },
592 | "lodash.assign": {
593 | "version": "3.2.0",
594 | "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz",
595 | "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=",
596 | "requires": {
597 | "lodash._baseassign": "3.2.0",
598 | "lodash._createassigner": "3.1.1",
599 | "lodash.keys": "3.1.2"
600 | }
601 | },
602 | "lodash.isarguments": {
603 | "version": "3.1.0",
604 | "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
605 | "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
606 | },
607 | "lodash.isarray": {
608 | "version": "3.0.4",
609 | "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
610 | "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
611 | },
612 | "lodash.keys": {
613 | "version": "3.1.2",
614 | "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
615 | "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
616 | "requires": {
617 | "lodash._getnative": "3.9.1",
618 | "lodash.isarguments": "3.1.0",
619 | "lodash.isarray": "3.0.4"
620 | }
621 | },
622 | "lodash.restparam": {
623 | "version": "3.6.1",
624 | "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
625 | "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU="
626 | },
627 | "media-typer": {
628 | "version": "0.3.0",
629 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
630 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
631 | },
632 | "merge-descriptors": {
633 | "version": "1.0.1",
634 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
635 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
636 | },
637 | "methods": {
638 | "version": "1.1.2",
639 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
640 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
641 | },
642 | "mime": {
643 | "version": "1.3.4",
644 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
645 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
646 | },
647 | "mime-db": {
648 | "version": "1.29.0",
649 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz",
650 | "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg="
651 | },
652 | "mime-types": {
653 | "version": "2.1.16",
654 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz",
655 | "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=",
656 | "requires": {
657 | "mime-db": "1.29.0"
658 | }
659 | },
660 | "moment": {
661 | "version": "2.20.1",
662 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz",
663 | "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg=="
664 | },
665 | "moment-timezone": {
666 | "version": "0.5.14",
667 | "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz",
668 | "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=",
669 | "requires": {
670 | "moment": "2.20.1"
671 | }
672 | },
673 | "ms": {
674 | "version": "2.0.0",
675 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
676 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
677 | },
678 | "negotiator": {
679 | "version": "0.6.1",
680 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
681 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
682 | },
683 | "oauth-sign": {
684 | "version": "0.8.2",
685 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
686 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
687 | },
688 | "object-assign": {
689 | "version": "4.1.1",
690 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
691 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
692 | },
693 | "on-finished": {
694 | "version": "2.3.0",
695 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
696 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
697 | "requires": {
698 | "ee-first": "1.1.1"
699 | }
700 | },
701 | "packet-reader": {
702 | "version": "0.3.1",
703 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz",
704 | "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc="
705 | },
706 | "parseurl": {
707 | "version": "1.3.2",
708 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
709 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
710 | },
711 | "path-to-regexp": {
712 | "version": "0.1.7",
713 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
714 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
715 | },
716 | "performance-now": {
717 | "version": "2.1.0",
718 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
719 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
720 | },
721 | "pg": {
722 | "version": "6.4.1",
723 | "resolved": "https://registry.npmjs.org/pg/-/pg-6.4.1.tgz",
724 | "integrity": "sha1-PqvYygVoFEN8dp8X/3oMNqxwI8U=",
725 | "requires": {
726 | "buffer-writer": "1.0.1",
727 | "packet-reader": "0.3.1",
728 | "pg-connection-string": "0.1.3",
729 | "pg-pool": "1.8.0",
730 | "pg-types": "1.13.0",
731 | "pgpass": "1.0.2",
732 | "semver": "4.3.2"
733 | }
734 | },
735 | "pg-connection-string": {
736 | "version": "0.1.3",
737 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz",
738 | "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc="
739 | },
740 | "pg-hstore": {
741 | "version": "2.3.2",
742 | "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.2.tgz",
743 | "integrity": "sha1-9+8FPnubiSrphq8vfL6GQy388k8=",
744 | "requires": {
745 | "underscore": "1.8.3"
746 | }
747 | },
748 | "pg-int8": {
749 | "version": "1.0.1",
750 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
751 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
752 | },
753 | "pg-pool": {
754 | "version": "1.8.0",
755 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-1.8.0.tgz",
756 | "integrity": "sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc=",
757 | "requires": {
758 | "generic-pool": "2.4.3",
759 | "object-assign": "4.1.0"
760 | },
761 | "dependencies": {
762 | "object-assign": {
763 | "version": "4.1.0",
764 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
765 | "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A="
766 | }
767 | }
768 | },
769 | "pg-types": {
770 | "version": "1.13.0",
771 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz",
772 | "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==",
773 | "requires": {
774 | "pg-int8": "1.0.1",
775 | "postgres-array": "1.0.2",
776 | "postgres-bytea": "1.0.0",
777 | "postgres-date": "1.0.3",
778 | "postgres-interval": "1.1.1"
779 | }
780 | },
781 | "pgpass": {
782 | "version": "1.0.2",
783 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz",
784 | "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=",
785 | "requires": {
786 | "split": "1.0.1"
787 | }
788 | },
789 | "postgres-array": {
790 | "version": "1.0.2",
791 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz",
792 | "integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg="
793 | },
794 | "postgres-bytea": {
795 | "version": "1.0.0",
796 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
797 | "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
798 | },
799 | "postgres-date": {
800 | "version": "1.0.3",
801 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz",
802 | "integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g="
803 | },
804 | "postgres-interval": {
805 | "version": "1.1.1",
806 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.1.tgz",
807 | "integrity": "sha512-OkuCi9t/3CZmeQreutGgx/OVNv9MKHGIT5jH8KldQ4NLYXkvmT9nDVxEuCENlNwhlGPE374oA/xMqn05G49pHA==",
808 | "requires": {
809 | "xtend": "4.0.1"
810 | }
811 | },
812 | "proxy-addr": {
813 | "version": "1.1.5",
814 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
815 | "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
816 | "requires": {
817 | "forwarded": "0.1.2",
818 | "ipaddr.js": "1.4.0"
819 | }
820 | },
821 | "punycode": {
822 | "version": "1.4.1",
823 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
824 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
825 | },
826 | "qs": {
827 | "version": "6.4.0",
828 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
829 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
830 | },
831 | "range-parser": {
832 | "version": "1.2.0",
833 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
834 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
835 | },
836 | "raw-body": {
837 | "version": "2.2.0",
838 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
839 | "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=",
840 | "requires": {
841 | "bytes": "2.4.0",
842 | "iconv-lite": "0.4.15",
843 | "unpipe": "1.0.0"
844 | }
845 | },
846 | "request": {
847 | "version": "2.83.0",
848 | "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
849 | "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
850 | "requires": {
851 | "aws-sign2": "0.7.0",
852 | "aws4": "1.6.0",
853 | "caseless": "0.12.0",
854 | "combined-stream": "1.0.5",
855 | "extend": "3.0.1",
856 | "forever-agent": "0.6.1",
857 | "form-data": "2.3.1",
858 | "har-validator": "5.0.3",
859 | "hawk": "6.0.2",
860 | "http-signature": "1.2.0",
861 | "is-typedarray": "1.0.0",
862 | "isstream": "0.1.2",
863 | "json-stringify-safe": "5.0.1",
864 | "mime-types": "2.1.17",
865 | "oauth-sign": "0.8.2",
866 | "performance-now": "2.1.0",
867 | "qs": "6.5.1",
868 | "safe-buffer": "5.1.1",
869 | "stringstream": "0.0.5",
870 | "tough-cookie": "2.3.3",
871 | "tunnel-agent": "0.6.0",
872 | "uuid": "3.2.1"
873 | },
874 | "dependencies": {
875 | "mime-db": {
876 | "version": "1.30.0",
877 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
878 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
879 | },
880 | "mime-types": {
881 | "version": "2.1.17",
882 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
883 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
884 | "requires": {
885 | "mime-db": "1.30.0"
886 | }
887 | },
888 | "qs": {
889 | "version": "6.5.1",
890 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
891 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
892 | }
893 | }
894 | },
895 | "retry-as-promised": {
896 | "version": "2.3.0",
897 | "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-2.3.0.tgz",
898 | "integrity": "sha1-J79czZmZMrMWZWloJc82MMJ8Vi0=",
899 | "requires": {
900 | "bluebird": "3.5.1",
901 | "debug": "2.6.8"
902 | }
903 | },
904 | "safe-buffer": {
905 | "version": "5.1.1",
906 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
907 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
908 | },
909 | "semver": {
910 | "version": "4.3.2",
911 | "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
912 | "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c="
913 | },
914 | "send": {
915 | "version": "0.15.4",
916 | "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz",
917 | "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=",
918 | "requires": {
919 | "debug": "2.6.8",
920 | "depd": "1.1.1",
921 | "destroy": "1.0.4",
922 | "encodeurl": "1.0.2",
923 | "escape-html": "1.0.3",
924 | "etag": "1.8.1",
925 | "fresh": "0.5.0",
926 | "http-errors": "1.6.2",
927 | "mime": "1.3.4",
928 | "ms": "2.0.0",
929 | "on-finished": "2.3.0",
930 | "range-parser": "1.2.0",
931 | "statuses": "1.3.1"
932 | },
933 | "dependencies": {
934 | "statuses": {
935 | "version": "1.3.1",
936 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
937 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
938 | }
939 | }
940 | },
941 | "sequelize": {
942 | "version": "3.30.4",
943 | "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-3.30.4.tgz",
944 | "integrity": "sha1-vaLfHjGFSwmeQUmhEen8Clyh0aQ=",
945 | "requires": {
946 | "bluebird": "3.5.1",
947 | "depd": "1.1.1",
948 | "dottie": "1.1.1",
949 | "generic-pool": "2.4.2",
950 | "inflection": "1.12.0",
951 | "lodash": "4.12.0",
952 | "moment": "2.20.1",
953 | "moment-timezone": "0.5.14",
954 | "retry-as-promised": "2.3.0",
955 | "semver": "5.4.1",
956 | "shimmer": "1.1.0",
957 | "terraformer-wkt-parser": "1.1.2",
958 | "toposort-class": "1.0.1",
959 | "uuid": "3.2.1",
960 | "validator": "5.7.0",
961 | "wkx": "0.2.0"
962 | },
963 | "dependencies": {
964 | "generic-pool": {
965 | "version": "2.4.2",
966 | "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.4.2.tgz",
967 | "integrity": "sha1-iGvFvwvrfblugby7oHiBjeWmJoM="
968 | },
969 | "semver": {
970 | "version": "5.4.1",
971 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
972 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
973 | }
974 | }
975 | },
976 | "serve-static": {
977 | "version": "1.12.4",
978 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz",
979 | "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=",
980 | "requires": {
981 | "encodeurl": "1.0.2",
982 | "escape-html": "1.0.3",
983 | "parseurl": "1.3.2",
984 | "send": "0.15.4"
985 | }
986 | },
987 | "setprototypeof": {
988 | "version": "1.0.3",
989 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
990 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
991 | },
992 | "shimmer": {
993 | "version": "1.1.0",
994 | "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.1.0.tgz",
995 | "integrity": "sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU="
996 | },
997 | "sntp": {
998 | "version": "2.1.0",
999 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
1000 | "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
1001 | "requires": {
1002 | "hoek": "4.2.0"
1003 | }
1004 | },
1005 | "split": {
1006 | "version": "1.0.1",
1007 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
1008 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
1009 | "requires": {
1010 | "through": "2.3.8"
1011 | }
1012 | },
1013 | "sshpk": {
1014 | "version": "1.13.1",
1015 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
1016 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
1017 | "requires": {
1018 | "asn1": "0.2.3",
1019 | "assert-plus": "1.0.0",
1020 | "bcrypt-pbkdf": "1.0.1",
1021 | "dashdash": "1.14.1",
1022 | "ecc-jsbn": "0.1.1",
1023 | "getpass": "0.1.7",
1024 | "jsbn": "0.1.1",
1025 | "tweetnacl": "0.14.5"
1026 | }
1027 | },
1028 | "statuses": {
1029 | "version": "1.4.0",
1030 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
1031 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
1032 | },
1033 | "stringstream": {
1034 | "version": "0.0.5",
1035 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
1036 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
1037 | },
1038 | "terraformer": {
1039 | "version": "1.0.8",
1040 | "resolved": "https://registry.npmjs.org/terraformer/-/terraformer-1.0.8.tgz",
1041 | "integrity": "sha1-UeCtiXRvzyFh3G9lqnDkI3fItZM=",
1042 | "requires": {
1043 | "@types/geojson": "1.0.6"
1044 | }
1045 | },
1046 | "terraformer-wkt-parser": {
1047 | "version": "1.1.2",
1048 | "resolved": "https://registry.npmjs.org/terraformer-wkt-parser/-/terraformer-wkt-parser-1.1.2.tgz",
1049 | "integrity": "sha1-M2oMj8gglKWv+DKI9prt7NNpvww=",
1050 | "requires": {
1051 | "terraformer": "1.0.8"
1052 | }
1053 | },
1054 | "through": {
1055 | "version": "2.3.8",
1056 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1057 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
1058 | },
1059 | "toposort-class": {
1060 | "version": "1.0.1",
1061 | "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
1062 | "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
1063 | },
1064 | "tough-cookie": {
1065 | "version": "2.3.3",
1066 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
1067 | "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
1068 | "requires": {
1069 | "punycode": "1.4.1"
1070 | }
1071 | },
1072 | "tunnel-agent": {
1073 | "version": "0.6.0",
1074 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1075 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1076 | "requires": {
1077 | "safe-buffer": "5.1.1"
1078 | }
1079 | },
1080 | "tweetnacl": {
1081 | "version": "0.14.5",
1082 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1083 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
1084 | "optional": true
1085 | },
1086 | "type-is": {
1087 | "version": "1.6.15",
1088 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
1089 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
1090 | "requires": {
1091 | "media-typer": "0.3.0",
1092 | "mime-types": "2.1.16"
1093 | }
1094 | },
1095 | "uid2": {
1096 | "version": "0.0.3",
1097 | "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
1098 | "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
1099 | },
1100 | "underscore": {
1101 | "version": "1.8.3",
1102 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
1103 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
1104 | },
1105 | "universal-analytics": {
1106 | "version": "0.4.15",
1107 | "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.15.tgz",
1108 | "integrity": "sha512-9Dt6WBWsHsmv74G+N/rmEgi6KFZxVvQXkVhr0disegeUryybQAUQwMD1l5EtqaOu+hSOGbhL/hPPQYisZIqPRw==",
1109 | "requires": {
1110 | "async": "1.2.1",
1111 | "request": "2.83.0",
1112 | "underscore": "1.8.3",
1113 | "uuid": "3.2.1"
1114 | }
1115 | },
1116 | "unpipe": {
1117 | "version": "1.0.0",
1118 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1119 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
1120 | },
1121 | "utils-merge": {
1122 | "version": "1.0.0",
1123 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
1124 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
1125 | },
1126 | "uuid": {
1127 | "version": "3.2.1",
1128 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
1129 | "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
1130 | },
1131 | "validator": {
1132 | "version": "5.7.0",
1133 | "resolved": "https://registry.npmjs.org/validator/-/validator-5.7.0.tgz",
1134 | "integrity": "sha1-eoelgUa2laxIYHEUHAxJ1n2gXlw="
1135 | },
1136 | "vary": {
1137 | "version": "1.1.2",
1138 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1139 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
1140 | },
1141 | "verror": {
1142 | "version": "1.10.0",
1143 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1144 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1145 | "requires": {
1146 | "assert-plus": "1.0.0",
1147 | "core-util-is": "1.0.2",
1148 | "extsprintf": "1.3.0"
1149 | }
1150 | },
1151 | "wkx": {
1152 | "version": "0.2.0",
1153 | "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.2.0.tgz",
1154 | "integrity": "sha1-dsJPFqzQzY+TzTSqMx4PeWElboQ="
1155 | },
1156 | "xtend": {
1157 | "version": "4.0.1",
1158 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
1159 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
1160 | }
1161 | }
1162 | }
1163 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shortlr",
3 | "version": "0.0.5",
4 | "description": "",
5 | "main": "shortner.js",
6 | "repository": "http://github.com/coding-blocks/shorturl",
7 | "scripts": {
8 | "start": "node server.js"
9 | },
10 | "author": "",
11 | "license": "GPL-2.0",
12 | "dependencies": {
13 | "axios": "^0.16.2",
14 | "body-parser": "^1.17.2",
15 | "convert-radix64": "^0.2.0",
16 | "cors": "^2.8.4",
17 | "express": "^4.15.4",
18 | "express-force-ssl": "^0.3.2",
19 | "express-ga-middleware": "^0.1.5",
20 | "jquery": "^3.2.1",
21 | "merge-descriptors": "^1.0.1",
22 | "pg": "^6.4.1",
23 | "pg-hstore": "^2.3.2",
24 | "sequelize": "^3.30.4",
25 | "uid2": "0.0.3",
26 | "universal-analytics": "^0.4.15"
27 | },
28 | "engines": {
29 | "node": "8",
30 | "npm": "5",
31 | "yarn": "1"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/routes/api_v1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by championswimmer on 14/12/16.
3 | */
4 | const express = require('express')
5 | const config = require('../config.json')
6 | const secrets = require('../secrets')
7 | const route = express.Router()
8 | const models = require('./../utils/db').models
9 |
10 | const validUrl = require('../utils/validator').validUrl
11 | const shortner = require('../utils/shortner')
12 | const SHORTENER_SECRET =
13 | process.env.SHORTURL_SECRET || secrets.SHORTURL_SECRET || 'cb@123'
14 |
15 | const SHORTENER_LONGURL_SECRET =
16 | process.env.SHORTURL_LONGURL_SECRET || secrets.SHORTURL_LONGURL_SECRET || 'cb@123'
17 | const db = require('./../utils/db')
18 | const SHORTENER_GROUP_SECRET =
19 | process.env.SHORTURL_GROUP_SECRET || secrets.SHORTURL_GROUP_SECRET || 'cb@321'
20 |
21 | route.post('/shorten', function (req, res) {
22 | let url = req.body.url
23 | var http = /^https?:\/\//i
24 | if (!http.test(url)) {
25 | url = 'http://' + url
26 | }
27 | let secret = req.body.secret
28 | let code = null
29 |
30 | if (!validUrl(url)) {
31 | return res.send('Unsupported link')
32 | }
33 | if (secret !== SHORTENER_SECRET && secret !== SHORTENER_GROUP_SECRET) {
34 | return res.send('No more making links without secret')
35 | }
36 |
37 |
38 | let shortCode = req.body.code.split('/')
39 | if (shortCode.length === 1 && secret === SHORTENER_SECRET) {
40 | console.log('Using secret')
41 | code = req.body.code
42 | if (code && code.length > 9) {
43 | console.log('Too long code')
44 | return res.send('We do not support larger than 9 character')
45 | }
46 | shortner.shorten(url, code, function (shortcode, existed, longURL) {
47 | return res.send({
48 | shortcode, existed, longURL
49 | })
50 | })
51 | } else if (secret === SHORTENER_GROUP_SECRET) {
52 | console.log('Creating Group Secret')
53 | const groupName = shortCode[0]
54 | let tempCode = shortCode[1]
55 |
56 | models.Group.findOrCreate({
57 | where: {groupName: groupName},
58 | defaults: {
59 | groupName: groupName
60 | }
61 | }).spread(function (group, created) {
62 | tempCode = group.id + tempCode
63 | while (tempCode.length < 9) {
64 | tempCode = tempCode + '0'
65 | }
66 | code = tempCode
67 |
68 | if (code && code.length > 9) {
69 | console.log('Too long code')
70 | return res.send('We do not support larger than 9 character')
71 | }
72 | shortner.shorten(url, code, function (shortcode, existed, longURL) {
73 | if (shortcode === code) {
74 | return res.send({
75 | shortcode: req.body.code, existed, longURL
76 | })
77 | }
78 | return res.send({
79 | shortcode, existed, longURL
80 | })
81 | })
82 | }).catch(function (err) {
83 | console.log(err)
84 | return res.send('Internal Server Error')
85 | })
86 |
87 | } else {
88 | shortner.shorten(url, code, function (shortcode, existed, longURL) {
89 | res.send({
90 | shortcode, existed, longURL
91 | })
92 | })
93 | }
94 |
95 | })
96 |
97 | route.get('/expand/:shortcode', function (req, res) {
98 | if (req.params.shortcode.length > 9) {
99 | res.redirect(200, 'http://www.codingblocks.com')
100 | }
101 |
102 | if (!req.params.shortcode || req.params.shortcode.length == 0) {
103 | res.send({
104 | status: 501,
105 | message: 'Wrong shortcode, or no shortcode given'
106 | })
107 | } else {
108 | shortner.expand(req.params.shortcode, req.headers.referer, function (URL) {
109 | if (URL) {
110 | res.send({
111 | status: 200,
112 | url: URL
113 | })
114 | } else {
115 | res.send({
116 | status: 501,
117 | message: 'Server error'
118 | })
119 | }
120 | })
121 | }
122 |
123 | })
124 |
125 | route.post('/search', function (req, res) {
126 | if (req.body.secret !== SHORTENER_LONGURL_SECRET) {
127 | return res.send({
128 | status: 401,
129 | message: 'Wrong secret Code'
130 | })
131 | }
132 | db.fetchLongUrl(req.body.longcode, function (urls) {
133 | if (urls.length === 0) {
134 | return res.send({
135 | status: 404,
136 | message: 'No Shortlinks found for this URL'
137 | })
138 | } else {
139 | return res.send({
140 | status: 200,
141 | urls: urls
142 | })
143 | }
144 | })
145 |
146 | })
147 |
148 |
149 | route.get('/stats', function (req, res) {
150 | const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl.split('?').shift()
151 |
152 | let {page, size} = req.query
153 | page = parseInt(page) || 1
154 | size = parseInt(size) || config.PAGINATION_SIZE
155 |
156 | shortner.stats(page, size, fullUrl).then(({urls, prevPage, nextPage, lastPage}) => {
157 | const meta = {prevPage, nextPage, lastPage}
158 | res.json({urls, meta})
159 | }).catch(err => {
160 | console.error(err)
161 | res.send({
162 | code: 501,
163 | message: 'Error occured'
164 | })
165 | })
166 | })
167 |
168 | route.use((req, res) => {
169 | res.send('This is not the way to use the api')
170 | })
171 |
172 | module.exports = route
173 |
--------------------------------------------------------------------------------
/routes/auth.js:
--------------------------------------------------------------------------------
1 | const router = require('express').Router();
2 | const models = require('../utils/db');
3 | const axios = require('axios');
4 | const uid = require('uid2');
5 |
6 | var secrets;
7 | try {
8 | secrets = require('./../secrets.json');
9 | } catch (e) {
10 | secrets = require('./../secrets-sample.json');
11 | }
12 |
13 | router.post('/', function (req, res) {
14 |
15 | axios.post(secrets.BASE_URL+'/oauth/token',
16 | {
17 | "client_id": secrets.CLIENT_ID,
18 | "redirect_uri": secrets.REDIRECT_URI,
19 | "client_secret": secrets.CLIENT_SECRET,
20 | "grant_type": secrets.GRANT_TYPE,
21 | "code": req.body.code
22 | })
23 | .then(function(authtoken){
24 |
25 | models.authFunction(authtoken, function (oneauth) {
26 | if(oneauth.success === true)
27 | res.status(200).send(oneauth);
28 | else
29 | res.status(500).send(oneauth);
30 | })}).catch(function (err) {
31 | console.log(err);
32 | res.status(500).send({
33 | success: false
34 | , code: "500"
35 | , error: {
36 | message: "Could not post data to Oneauth API(Internal Server Error)."
37 | }
38 | })
39 | })
40 | });
41 |
42 | module.exports = router;
--------------------------------------------------------------------------------
/routes/shortcode.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by championswimmer on 14/12/16.
3 | */
4 | const express = require('express')
5 | const route = express.Router()
6 |
7 | const models = require('./../utils/db').models
8 |
9 | const shortner = require('../utils/shortner')
10 |
11 | route.get('/:groupName/:shortcode', (req, res, next) => {
12 | let code = req.params.shortcode
13 | if (!req.params.shortcode || req.params.shortcode.length === 0) {
14 | next()
15 | }
16 | const groupName = req.params.groupName
17 | let tempCode = req.params.shortcode
18 |
19 | models.Group.findOne({
20 | where: {groupName: groupName},
21 | }).then(function (group) {
22 | if (group) {
23 | tempCode = "" + group.id + tempCode
24 | while (tempCode.length < 9) {
25 | tempCode = tempCode + "0"
26 | }
27 | code = tempCode
28 | shortner.expand(code, req.headers.referer, function (URL) {
29 | if (!URL) {
30 | next()
31 | } else {
32 | res.redirect(URL)
33 | }
34 | })
35 | } else {
36 | next()
37 | }
38 | }).catch(function (err) {
39 | console.log(err)
40 | return res.send("Internal Server Error")
41 | })
42 |
43 | })
44 |
45 | route.get('/:shortcode', (req, res, next) => {
46 |
47 | if (!req.params.shortcode || req.params.shortcode.length === 0) {
48 | return next()
49 | }
50 |
51 | req.params.shortcode = req.params.shortcode.trim()
52 |
53 | if (req.params.shortcode.length > 9) {
54 | return next()
55 | }
56 |
57 | shortner.expand(req.params.shortcode, req.headers.referer, function (URL) {
58 | if (!URL) {
59 | next()
60 | } else {
61 | res.redirect(URL)
62 | }
63 | })
64 |
65 | })
66 |
67 | module.exports = route
--------------------------------------------------------------------------------
/secrets-sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "CLIENT_ID": 1234567890,
3 | "REDIRECT_URI": "http://localhost:4000/login/callback",
4 | "CLIENT_SECRET": "abcdef",
5 | "GRANT_TYPE": "authorization_code",
6 | "SHORTURL_SECRET": "cb@123",
7 | "SHORTURL_LONGURL_SECRET": "cb@123",
8 | "SHORTURL_GROUP_SECRET": "cb@321",
9 | "DB": {
10 | "HOST": "localhost",
11 | "PORT": 5432,
12 | "USERNAME": "shorturl",
13 | "DB_NAME": "shorturl",
14 | "PASSWORD": "shorturl"
15 | }
16 | }
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by championswimmer on 24/11/16.
3 | */
4 | const express = require('express');
5 | const bodyParser = require('body-parser');
6 | const forceSSL = require('express-force-ssl');
7 | const config = require('./config.json');
8 | const cors = require('cors');
9 |
10 | const app = express();
11 |
12 | app.set('forceSSLOptions', {
13 | enable301Redirects: config.ENABLE_301_HTTPS_REDIRECT,
14 | trustXFPHeader: config.TRUST_HTTPS_PROXY,
15 | sslRequiredMessage: config.NON_HTTPS_REQUEST_ERRMSG
16 | });
17 |
18 | const shortner = require('./utils/shortner');
19 | const expressGa = require('express-ga-middleware');
20 |
21 | const route = {
22 | api_v1: require('./routes/api_v1'),
23 | shortcode: require('./routes/shortcode'),
24 | auth: require('./routes/auth')
25 | };
26 |
27 | app.use(bodyParser.json());
28 | app.use(bodyParser.urlencoded({extended: true}));
29 | app.use(bodyParser.raw({
30 | inflate: true,
31 | limit: '100kb',
32 | type: '*/*'
33 | }));
34 |
35 |
36 | const redirectToHome = function (req, res) {
37 | res.redirect('http://codingblocks.com')
38 | };
39 |
40 |
41 | if (config.FORCE_HTTPS) {
42 | app.use('/admin', forceSSL)
43 | }
44 | app.use('/admin', express.static(__dirname + "/static/admin"));
45 | app.use('/.well-known', express.static(__dirname + "/.well-known"));
46 |
47 | app.use(expressGa('UA-83327907-4'));
48 | app.use('/api/v1', cors(), route.api_v1);
49 | app.use('/', route.shortcode);
50 | app.use('/auth', route.auth);
51 |
52 | // Redirects the user to IDE home page if no ID is provided
53 | app.get('/ide', (req, res) => {
54 | res.redirect('http://ide.codingblocks.com');
55 | })
56 |
57 | // Redirects user to a particular place in IDE if he provides the ID
58 | app.get('/ide/:id', (req, res) => {
59 | res.redirect(`http://ide.codingblocks.com/#/s/${req.params.id}`);
60 | });
61 |
62 | app.use(redirectToHome);
63 |
64 |
65 | app.listen( process.env.PORT || 4000, () => {
66 | console.log("Listening on http://localhost:" + (process.env.PORT || "4000") + "/");
67 | });
--------------------------------------------------------------------------------
/static/admin/css/index.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by bhavyaagg on 27/08/17.
3 | */
4 |
5 | #homeHeading {
6 | top: 6%;
7 | transform: translateY(-6%);
8 | }
9 |
10 | #shortcodeform {
11 | background: rgba(256, 256, 256, 0.6);
12 | }
13 |
14 | #shortcodeform > div.form-group.row {
15 | margin-top: 5%;
16 | padding: 0 30px 10px;
17 | }
18 |
19 | #shortcodeform > p {
20 | padding: 0 30px;
21 | }
22 |
23 | #shortcodeform > p > a {
24 | color: #666 !important;
25 | font-weight: normal;
26 | }
27 |
28 | #shortCodeContainer {
29 | padding: 0 30px 10px;
30 | }
31 |
32 | #submit {
33 | padding: 0 30px 0;
34 | display: block;
35 | margin-left: auto;
36 | margin-right: auto;
37 | }
38 |
39 | #shortForm {
40 | padding: 0 30px 0;
41 | transition: all 300ms linear;
42 | }
--------------------------------------------------------------------------------
/static/admin/css/stylesheet.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 64px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | .form-wrap {
7 | background: url(https://codingblocks.com/ide/cblogo.png) no-repeat center !important;
8 | height: 100%;
9 | }
10 |
11 | html, body {
12 | height: 100%;
13 | }
14 |
15 | .bggrad {
16 | background: linear-gradient(325deg, #dd5e89, #f7bb97) fixed;
17 | }
18 |
19 | .top-buffer {
20 | margin-top: 20px;
21 | }
22 |
23 | .panel-heading {
24 | text-align: left!important;
25 | }
26 |
27 |
28 | /*!---------- 7. NAVIGATION ----------*/
29 |
30 | .nav-container {
31 | -webkit-backface-visibility: hidden;
32 | max-width: 100%;
33 | }
34 |
35 | nav {
36 | background: #3d4c5a;
37 | -webkit-backface-visibility: hidden;
38 | max-width: 100%;
39 | }
40 |
41 | nav ul {
42 | margin-bottom: 0;
43 | }
44 |
45 | .module {
46 | display: inline-block;
47 | padding: 0 32px;
48 | }
49 |
50 | .module-group {
51 | display: inline-block;
52 | }
53 |
54 | .module.left, .module-group.left {
55 | float: left;
56 | }
57 |
58 | .module.right, .module-group.right {
59 | float: right;
60 | }
61 |
62 | nav .btn, .nav-bar .btn {
63 | margin: 0;
64 | height: auto;
65 | }
66 |
67 | .nav-utility {
68 | height: 45px;
69 | line-height: 43px;
70 | border-bottom: 1px solid #ccc;
71 | overflow: hidden;
72 | }
73 |
74 | .nav-utility i {
75 | position: relative;
76 | top: 1px;
77 | }
78 |
79 | .nav-bar {
80 | height: 64px;
81 | max-height: 64px;
82 | line-height: 60px;
83 | border-bottom: 1px solid #3d4c5a;
84 | }
85 |
86 | .nav-bar .module, .nav-bar .module-group {
87 | height: 55px;
88 | }
89 |
90 | .nav-bar a {
91 | display: inline-block;
92 | height: 55px;
93 | }
94 |
95 | .nav-bar h2 {
96 | color: #fff;
97 | text-transform: uppercase;
98 | font-size: 20px;
99 | line-height: 60px;
100 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif!important;
101 | font-weight: 500;
102 | }
103 |
104 | .logo {
105 | max-height: 80%;
106 | }
107 |
108 | .logo-light {
109 | display: none;
110 | }
111 |
112 | nav.nav-centered .logo {
113 | max-height: 64px;
114 | margin: 64px 0 40px 0;
115 | }
116 |
117 | nav.bg-dark .logo-light {
118 | display: inline;
119 | }
120 |
121 | nav.bg-dark .logo-dark {
122 | display: none;
123 | }
124 |
125 | .has-dropdown {
126 | padding-right: 18px;
127 | }
128 |
129 | .has-dropdown:after {
130 | position: absolute;
131 | top: 0;
132 | right: 0;
133 | font-size: 11px;
134 | content: "\e64b";
135 | font-family: 'themify';
136 | speak: none;
137 | font-style: normal;
138 | font-weight: normal;
139 | font-variant: normal;
140 | text-transform: none;
141 | }
142 |
143 | .menu {
144 | width: 100%;
145 | height: 55px;
146 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
147 | }
148 |
149 | .menu.inline-block {
150 | width: auto;
151 | }
152 |
153 | .menu li a {
154 | font-size: 11px;
155 | text-transform: uppercase;
156 | font-weight: 600;
157 | letter-spacing: 1px;
158 | color: #fff;
159 | opacity: 0.5;
160 | transition: all 0.3s ease;
161 | -webkit-transition: all 0.3s ease;
162 | -moz-transition: all 0.3s ease;
163 | max-width: 100%;
164 | white-space: normal;
165 | }
166 |
167 | .menu li a:hover {
168 | opacity: 1 !important;
169 | color: #f7bb97;
170 | }
171 |
172 | .menu>li {
173 | margin-right: 32px;
174 | float: left;
175 | position: relative;
176 | transition: all 0.3s ease;
177 | -webkit-transition: all 0.3s ease;
178 | -moz-transition: all 0.3s ease;
179 | opacity: 1;
180 | }
181 |
182 | .menu>li:last-child {
183 | margin-right: 0;
184 | }
185 |
186 | .menu>li:last-child>ul {
187 | right: 0;
188 | }
189 |
190 | .menu>li:last-child>ul ul {
191 | left: auto;
192 | right: 100%;
193 | }
194 |
195 | .menu>li ul {
196 | width: 200px;
197 | padding: 8px 0;
198 | background: #292929;
199 | position: absolute;
200 | z-index: 99;
201 | opacity: 0;
202 | transition: all 0.3s ease;
203 | -webkit-transition: all 0.3s ease;
204 | -moz-transition: all 0.3s ease;
205 | transform: translate3d(0, 10px, 0);
206 | -webkit-transform: translate3d(0, 10px, 0);
207 | -moz-transform: translate3d(0, 10px, 0);
208 | visibility: hidden;
209 | margin-top: -1px;
210 | }
211 |
212 | .menu>li>ul>li {
213 | position: relative;
214 | line-height: 24px;
215 | width: 100%;
216 | vertical-align: top;
217 | }
218 |
219 | .menu>li>ul>li i {
220 | display: inline-block;
221 | margin-right: 2px;
222 | }
223 |
224 | .menu>li>ul>.has-dropdown:after {
225 | color: #fff;
226 | top: 5px;
227 | right: 24px;
228 | content: "\e649";
229 | }
230 |
231 | .menu>li>ul li a {
232 | color: #fff;
233 | height: auto;
234 | padding: 6px 24px;
235 | }
236 |
237 | .menu>li>ul>li>ul {
238 | left: 100%;
239 | top: 0;
240 | }
241 |
242 | .menu>li:hover>ul {
243 | opacity: 1;
244 | transform: translate3d(0, 0px, 0);
245 | -webkit-transform: translate3d(0, 0px, 0);
246 | -moz-transform: translate3d(0, 0px, 0);
247 | visibility: visible;
248 | }
249 |
250 | .menu>li>ul>li:hover>ul, .has-dropdown:hover .mega-menu ul {
251 | opacity: 1;
252 | transform: translate3d(0, 0px, 0);
253 | -webkit-transform: translate3d(0, 0px, 0);
254 | -moz-transform: translate3d(0, 0px, 0);
255 | visibility: visible;
256 | }
257 |
258 | .mega-menu {
259 | width: auto !important;
260 | white-space: nowrap;
261 | line-height: 24px;
262 | }
263 |
264 | .mega-menu ul {
265 | position: relative !important;
266 | left: auto !important;
267 | padding: 0 !important;
268 | }
269 |
270 | .mega-menu>li {
271 | width: 200px !important;
272 | overflow: hidden;
273 | display: inline-block;
274 | }
275 |
276 | .mega-menu .title {
277 | letter-spacing: 1px;
278 | color: #fff;
279 | display: inline-block;
280 | padding: 6px 24px;
281 | text-transform: uppercase;
282 | font-size: 11px;
283 | font-weight: 600;
284 | }
285 |
286 | .make-right {
287 | right: 0;
288 | }
289 |
290 | .module.widget-handle {
291 | border-left: 1px solid #ccc;
292 | padding: 0 24px;
293 | cursor: pointer;
294 | position: relative;
295 | -webkit-touch-callout: none;
296 | -webkit-user-select: none;
297 | -khtml-user-select: none;
298 | -moz-user-select: none;
299 | -ms-user-select: none;
300 | user-select: none;
301 | margin: 0;
302 | }
303 |
304 | nav.nav-centered .module.widget-handle {
305 | border: none !important;
306 | }
307 |
308 | @media all and (max-width: 1100px) {
309 | .module.widget-handle {
310 | padding: 0 16px;
311 | }
312 | }
313 |
314 | .module.widget-handle i {
315 | font-size: 20px;
316 | line-height: 53px;
317 | opacity: 0.5;
318 | transition: all 0.3s ease;
319 | -webkit-transition: all 0.3s ease;
320 | -moz-transition: all 0.3s ease;
321 | }
322 |
323 | .module.widget-handle:hover i, .module.active i {
324 | opacity: 1;
325 | }
326 |
327 | .widget-handle .function {
328 | -webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
329 | -moz-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
330 | box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
331 | cursor: default;
332 | width: 200px;
333 | background: #292929;
334 | position: absolute;
335 | z-index: 99;
336 | opacity: 0;
337 | transition: all 0.3s ease;
338 | -webkit-transition: all 0.3s ease;
339 | -moz-transition: all 0.3s ease;
340 | transform: translate3d(0, 10px, 0);
341 | -webkit-transform: translate3d(0, 10px, 0);
342 | -moz-transform: translate3d(0, 10px, 0);
343 | visibility: hidden;
344 | margin-top: -2px;
345 | right: 0;
346 | }
347 |
348 | .module.widget-handle:hover .function {
349 | opacity: 1;
350 | transform: translate3d(0, 0px, 0);
351 | -webkit-transform: translate3d(0, 0px, 0);
352 | -moz-transform: translate3d(0, 0px, 0);
353 | visibility: visible;
354 | }
355 |
356 | .module.widget-handle .title {
357 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
358 | letter-spacing: 1px;
359 | text-transform: uppercase;
360 | font-size: 11px;
361 | font-weight: 600;
362 | display: none;
363 | opacity: .5;
364 | transition: all 0.3s ease;
365 | -webkit-transition: all 0.3s ease;
366 | -moz-transition: all 0.3s ease;
367 | }
368 |
369 | .module.widget-handle .title:hover {
370 | opacity: 1;
371 | }
372 |
373 | .widget-handle .cart {
374 | position: relative;
375 | }
376 |
377 | .widget-handle .cart .label {
378 | width: 17px;
379 | height: 17px;
380 | font-size: 10px;
381 | line-height: 17px;
382 | padding: 0;
383 | text-align: center;
384 | position: absolute;
385 | background: #fc4f4f;
386 | top: 10px;
387 | right: -10px;
388 | border-radius: 50%;
389 | }
390 |
391 | .widget-handle .search-form {
392 | padding: 8px;
393 | display: inline-block;
394 | width: 100%;
395 | line-height: 50px;
396 | }
397 |
398 | .widget-handle .search-form input {
399 | margin: 0;
400 | font-size: 16px;
401 | }
402 |
403 | nav .widget {
404 | margin: 0;
405 | padding: 24px;
406 | }
407 |
408 | nav .widget .title {
409 | display: none !important;
410 | }
411 |
412 | nav .widget, nav .widget a:not(.btn) {
413 | color: #fff;
414 | }
415 |
416 | nav .widget hr {
417 | border-color: #777;
418 | margin-bottom: 16px;
419 | }
420 |
421 | nav .widget hr:first-of-type {
422 | display: none;
423 | }
424 |
425 | .cart-widget-handle .function {
426 | width: auto;
427 | background: #fff;
428 | }
429 |
430 | .cart-widget-handle .function span {
431 | color: #222 !important;
432 | }
433 |
434 | nav .cart-overview {
435 | min-width: 300px;
436 | margin-bottom: 16px;
437 | }
438 |
439 | nav .cart-overview a {
440 | height: auto;
441 | }
442 |
443 | .language .menu>li ul {
444 | max-width: 150px;
445 | }
446 |
447 | .nav-open {
448 | max-height: 10000px !important;
449 | height: auto !important;
450 | }
451 |
452 | .nav-open .mobile-toggle {
453 | border-bottom: 1px solid #ccc;
454 | }
455 |
456 | @media all and (max-width: 1120px) {
457 | .menu>li {
458 | margin-right: 24px;
459 | }
460 | }
461 |
462 | .has-offscreen-nav .main-container {
463 | transition: all 0.4s ease;
464 | -webkit-transition: all 0.4s ease;
465 | -moz-transition: all 0.4s ease;
466 | }
467 |
468 | .offscreen-container {
469 | position: fixed;
470 | transform: translate3d(200%, 0, 0);
471 | -webkit-transform: translate3d(200%, 0, 0);
472 | -moz-transform: translate3d(200%, 0, 0);
473 | width: 50%;
474 | top: 0;
475 | height: 100%;
476 | min-height: 100vh;
477 | z-index: 20;
478 | transition: all 0.4s ease;
479 | -webkit-transition: all 0.4s ease;
480 | -moz-transition: all 0.4s ease;
481 | overflow: hidden;
482 | }
483 |
484 | .offscreen-container.reveal-nav {
485 | transform: translate3d(100%, 0, 0);
486 | -webkit-transform: translate3d(100%, 0, 0);
487 | -moz-transform: translate3d(100%, 0, 0);
488 | }
489 |
490 | .main-container.reveal-nav {
491 | transform: translate3d(-50%, 0, 0);
492 | -webkit-transform: translate3d(-50%, 0, 0);
493 | -moz-transform: translate3d(-50%, 0, 0);
494 | }
495 |
496 | .offscreen-left .offscreen-container {
497 | transform: translate3d(-50%, 0, 0);
498 | -webkit-transform: translate3d(-50%, 0, 0);
499 | -moz-transform: translate3d(-50%, 0, 0);
500 | }
501 |
502 | .offscreen-left .offscreen-container.reveal-nav {
503 | transform: translate3d(0%, 0, 0);
504 | -webkit-transform: translate3d(0%, 0, 0);
505 | -moz-transform: translate3d(0%, 0, 0);
506 | }
507 |
508 | .offscreen-left .main-container.reveal-nav, .offscreen-left nav.reveal-nav {
509 | transform: translate3d(50%, 0, 0) !important;
510 | -webkit-transform: translate3d(50%, 0, 0) !important;
511 | -moz-transform: translate3d(50%, 0, 0) !important;
512 | }
513 |
514 | .offscreen-container .close-nav {
515 | position: absolute;
516 | right: 24px;
517 | top: 16px;
518 | z-index: 24;
519 | font-size: 20px;
520 | transition: all 0.3s ease;
521 | -webkit-transition: all 0.3s ease;
522 | -moz-transition: all 0.3s ease;
523 | opacity: .5;
524 | }
525 |
526 | .offscreen-container .close-nav:hover {
527 | opacity: 1;
528 | }
529 |
530 | .offscreen-container.bg-dark .close-nav i {
531 | color: #fff;
532 | }
533 |
534 | @media all and (max-width: 990px) {
535 | .offscreen-container {
536 | width: 100vw;
537 | }
538 | .offscreen-container.reveal-nav {
539 | transform: translate3d(0vw, 0, 0);
540 | -webkit-transform: translate3d(0vw, 0, 0);
541 | -moz-transform: translate3d(0vw, 0, 0);
542 | }
543 | .main-container.reveal-nav {
544 | transform: none !important;
545 | }
546 | }
547 |
548 | @media all and (max-width: 990px) {
549 | nav.fixed {
550 | position: absolute !important;
551 | opacity: 1 !important;
552 | visibility: visible !important;
553 | }
554 | nav.outOfSight {
555 | transform: translate3d(0, 0px, 0) !important;
556 | -webkit-transform: translate3d(0, 0px, 0) !important;
557 | -moz-transform: translate3d(0, 0px, 0) !important;
558 | }
559 | .nav-bar, .nav-bar .module-group, .nav-bar .module {
560 | height: auto;
561 | overflow: hidden;
562 | }
563 | .nav-bar .module {
564 | padding: 0 16px;
565 | }
566 | .nav-bar .module-group {
567 | width: 100%;
568 | padding: 16px 0;
569 | }
570 | .nav-bar .module-group .module {
571 | display: block;
572 | float: none;
573 | width: 100%;
574 | }
575 | nav.nav-centered .logo {
576 | margin: 24px 0 16px 0;
577 | max-height: 40px;
578 | }
579 | .menu {
580 | height: auto;
581 | }
582 | .menu.inline-block {
583 | width: 100%;
584 | }
585 | .menu a {
586 | height: auto;
587 | line-height: 24px;
588 | padding: 4px 0;
589 | }
590 | .menu li {
591 | line-height: 24px;
592 | float: none;
593 | display: block;
594 | width: 100%;
595 | max-width: 100%;
596 | }
597 | .menu>li ul {
598 | position: relative;
599 | width: 100%;
600 | opacity: 1;
601 | visibility: visible;
602 | transform: translate3d(0, 0px, 0);
603 | -webkit-transform: translate3d(0, 0px, 0);
604 | -moz-transform: translate3d(0, 0px, 0);
605 | left: 0;
606 | }
607 | .menu>li>ul {
608 | position: relative;
609 | opacity: 1;
610 | visibility: visible;
611 | display: none;
612 | transform: translate3d(0, 0px, 0);
613 | -webkit-transform: translate3d(0, 0px, 0);
614 | -moz-transform: translate3d(0, 0px, 0);
615 | }
616 | .menu>li>ul>.has-dropdown:after {
617 | content: "\e64b";
618 | }
619 | .menu>li>ul>li>ul {
620 | left: 0;
621 | display: none;
622 | padding: 0;
623 | }
624 | .menu>li>ul li a, .mega-menu .title {
625 | padding: 4px 16px;
626 | }
627 | .has-dropdown .has-dropdown li {
628 | padding-left: 18px;
629 | }
630 | .has-dropdown {
631 | padding-right: 0;
632 | }
633 | .mega-menu {
634 | margin-left: 0 !important;
635 | }
636 | .mega-menu li {
637 | width: 100% !important;
638 | }
639 | .toggle-sub>ul, .toggle-sub .mega-menu ul {
640 | display: block !important;
641 | }
642 | .module.widget-handle {
643 | border-left: none;
644 | border-top: 1px solid #ccc;
645 | line-height: 40px;
646 | min-height: 40px;
647 | }
648 | .module.widget-handle .menu {
649 | line-height: 40px;
650 | }
651 | .module.widget-handle .menu li {
652 | line-height: 40px;
653 | }
654 | .module.widget-handle i {
655 | line-height: 40px;
656 | }
657 | .module.widget-handle .title {
658 | display: inline-block;
659 | position: relative;
660 | bottom: 3px;
661 | margin-left: 8px;
662 | }
663 | .widget-handle .function {
664 | width: 100%;
665 | position: relative;
666 | opacity: 1;
667 | transform: translate3d(0, 0px, 0);
668 | -webkit-transform: translate3d(0, 0px, 0);
669 | -moz-transform: translate3d(0, 0px, 0);
670 | visibility: visible;
671 | margin-top: 0;
672 | display: none;
673 | box-shadow: none !important;
674 | }
675 | .toggle-widget-handle .function {
676 | display: block !important;
677 | }
678 | .widget-handle .cart .label {
679 | width: 22px;
680 | height: 22px;
681 | font-size: 12px;
682 | line-height: 22px;
683 | top: 18px;
684 | }
685 | .mobile-toggle {
686 | border-left: 1px solid #ccc !important;
687 | border-bottom: none !important;
688 | }
689 | .mobile-toggle i {
690 | line-height: 53px !important;
691 | }
692 | .mobile-toggle.absolute-xs {
693 | position: absolute;
694 | top: 0;
695 | }
696 | nav.nav-centered .mobile-toggle {
697 | width: 100%;
698 | }
699 | nav.bg-dark .module.widget-handle {
700 | border-top: 1px solid #444;
701 | }
702 | nav.bg-dark .mobile-toggle {
703 | border-left: 1px solid #444 !important;
704 | }
705 | nav.bg-dark .nav-open .mobile-toggle {
706 | border-bottom: 1px solid #444;
707 | }
708 | }
709 |
710 | nav.outOfSight {
711 | transform: translate3d(0, -200px, 0);
712 | -webkit-transform: translate3d(0, -200px, 0);
713 | -moz-transform: translate3d(0, -200px, 0);
714 | }
715 |
716 | nav.scrolled {
717 | transform: translate3d(0, 0px, 0);
718 | -webkit-transform: translate3d(0, 0px, 0);
719 | -moz-transform: translate3d(0, 0px, 0);
720 | transition: all 0.3s ease;
721 | -webkit-transition: all 0.3s ease;
722 | -moz-transition: all 0.3s ease;
723 | }
724 |
725 | nav.fixed, nav.absolute {
726 | top: 0;
727 | width: 100%;
728 | z-index: 999;
729 | left: 0;
730 | right: 0;
731 | }
732 |
733 | nav.absolute {
734 | position: absolute;
735 | }
736 |
737 | nav.fixed {
738 | position: fixed;
739 | visibility: hidden;
740 | opacity: 0;
741 | }
742 |
743 | nav.fixed .nav-utility {
744 | display: none;
745 | }
746 |
747 | nav.fixed.scrolled {
748 | visibility: visible;
749 | opacity: 1;
750 | }
751 |
752 | nav.transparent .menu>li>a, nav.transparent .module.widget-handle i, nav.transparent .nav-utility {
753 | color: #fff;
754 | }
755 |
756 | nav.transparent .nav-utility, nav.transparent .nav-bar {
757 | border-bottom: 1px solid rgba(255, 255, 255, 0.2);
758 | }
759 |
760 | nav.transparent .module.widget-handle {
761 | border-left: 1px solid rgba(255, 255, 255, 0.2) !important;
762 | }
763 |
764 | nav.transparent .menu>li>a, nav.transparent .module.widget-handle i {
765 | opacity: 1;
766 | }
767 |
768 | nav.transparent .has-dropdown:after {
769 | color: #fff;
770 | }
771 |
772 | nav.transparent .logo-dark {
773 | display: none;
774 | }
775 |
776 | nav.transparent .logo-light {
777 | display: inline;
778 | }
779 |
780 | nav.transparent {
781 | background: none;
782 | }
783 |
784 | .has-offscreen-nav>nav.fixed {
785 | opacity: 1;
786 | transform: none;
787 | visibility: visible;
788 | }
789 |
790 | @media all and (max-width: 990px) {
791 | nav.transparent .nav-open {
792 | background: #fff;
793 | }
794 | nav.transparent .nav-open .menu>li>a, nav.transparent .nav-open .module.widget-handle i, nav.transparent .nav-open .nav-utility {
795 | color: #292929;
796 | }
797 | nav.transparent .nav-open .logo-dark {
798 | display: inline;
799 | }
800 | nav.transparent .nav-open .logo-light {
801 | display: none;
802 | }
803 | nav.transparent .nav-open .has-dropdown:after {
804 | color: #292929;
805 | }
806 | .menu>li:last-child>ul ul {
807 | right: 0;
808 | }
809 | }
810 |
811 | nav.transparent.fixed {
812 | background: #fff;
813 | }
814 |
815 | nav.transparent.fixed .logo-light {
816 | display: none;
817 | }
818 |
819 | nav.transparent.fixed .logo-dark {
820 | display: inline;
821 | }
822 |
823 | nav.transparent.fixed .menu>li>a, nav.transparent.fixed .module.widget-handle i {
824 | color: #292929;
825 | }
826 |
827 | nav.transparent.fixed .menu>.has-dropdown:after {
828 | color: #fff;
829 | color: #292929;
830 | }
831 |
832 | nav.transparent.fixed .module.widget-handle {
833 | border-left: 1px solid #ccc;
834 | }
835 |
836 | nav.transparent.fixed .menu>li>a, nav.transparent.fixed .module.widget-handle i {
837 | opacity: .5;
838 | }
839 |
840 | nav.bg-dark .menu>li>a, nav.bg-dark .module.widget-handle i, nav.bg-dark .nav-utility {
841 | color: #fff;
842 | opacity: .7;
843 | }
844 |
845 | nav.bg-dark .module.widget-handle {
846 | border-left: 1px solid rgba(255, 255, 255, 0.2);
847 | }
848 |
849 | nav.bg-dark .nav-utility, nav.bg-dark .nav-bar {
850 | border-bottom: 1px solid rgba(255, 255, 255, 0.2);
851 | }
852 |
853 | nav.transparent.fixed.bg-dark {
854 | background: #292929;
855 | }
856 |
857 | nav.transparent.fixed.bg-dark .menu>li>a, nav.transparent.fixed.bg-dark .module.widget-handle i {
858 | color: #fff;
859 | }
860 |
861 | nav.nav-centered.outOfSight .logo {
862 | display: none;
863 | }
864 |
865 | .vnu {
866 | display: inline;
867 | }
868 |
869 | .logo {
870 | max-height: 80%;
871 | }
872 |
873 |
874 | /*!---------- 6. BUTTONS ----------*/
875 |
876 | .btn {
877 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
878 | border: 2px solid #5bc0de;
879 | padding: 0 26px;
880 | height: 40px;
881 | min-width: 150px;
882 | line-height: 36px;
883 | font-size: 12px;
884 | font-weight: 700;
885 | text-transform: uppercase;
886 | letter-spacing: 1px;
887 | text-align: center;
888 | transition: all 0.3s ease;
889 | -webkit-transition: all 0.3s ease;
890 | -moz-transition: all 0.3s ease;
891 | margin-right: 8px;
892 | margin-bottom: 24px;
893 | }
894 |
895 | .btn:last-child, .btn:last-of-type {
896 | margin-right: 0;
897 | }
898 |
899 | .btn:hover {
900 | color: #fff;
901 | }
902 |
903 | .btn-icon {
904 | width: 40px;
905 | height: 40px;
906 | font-size: 20px;
907 | min-width: 0;
908 | padding: 0;
909 | line-height: 38px;
910 | }
911 |
912 | .btn-lg {
913 | height: 50px;
914 | line-height: 46px;
915 | min-width: 200px;
916 | }
917 |
918 | .btn-icon.btn-lg {
919 | width: 50px;
920 | height: 50px;
921 | line-height: 49px;
922 | font-size: 24px;
923 | min-width: 0;
924 | }
925 |
926 | .btn-icon.btn-sm {
927 | width: 30px;
928 | height: 30px;
929 | line-height: 29px;
930 | font-size: 13px;
931 | min-width: 0;
932 | padding: 0 0 0 1px!important;
933 | }
934 |
935 | .btn-sm {
936 | height: 30px;
937 | font-size: 11px;
938 | line-height: 27px;
939 | min-width: 0;
940 | }
941 |
942 | .btn-filled {
943 | background: #5bc0de;
944 | color: #fff;
945 | }
946 |
947 | .btn-white, .image-bg .btn, .image-bg .btn:visited {
948 | color: #fff;
949 | border-color: #fff;
950 | }
951 |
952 | .btn-white:hover, .image-bg .btn:hover, .image-bg .btn:visited:hover {
953 | background: #fff;
954 | color: #222;
955 | }
956 |
957 | .image-bg .btn.btn-filled, .image-bg .btn-filled:visited {
958 | border-color: #5bc0de;
959 | }
960 |
961 | .image-bg .btn-filled:hover {
962 | border-color: #fff;
963 | }
964 |
965 | .btn-rounded {
966 | border-radius: 25px;
967 | }
968 |
969 | body.btn-rounded .btn {
970 | border-radius: 25px !important;
971 | }
972 |
973 | .bg-light .btn {
974 | border-color: #222;
975 | color: #222;
976 | }
977 |
978 | .bg-light .btn:visited, .bg-light .btn:visited:hover {
979 | color: #222;
980 | }
981 |
982 | .bg-light .btn-filled, .bg-light .btn-filled:visited {
983 | color: #fff;
984 | }
985 |
986 | .btn:visited {
987 | color: #5bc0de;
988 | }
989 |
990 | .btn-white:visited, .btn:visited:hover {
991 | color: #fff;
992 | }
993 |
994 | .btn-white:visited:hover {
995 | color: #222;
996 | }
997 |
998 | .btn-filled:visited {
999 | color: #fff;
1000 | }
1001 |
1002 | .btn.bg-dark {
1003 | color: #fff;
1004 | border-color: #333;
1005 | background: #333;
1006 | }
1007 |
1008 | .btn.bg-dark:hover {
1009 | background: #434343;
1010 | border-color: #434343;
1011 | }
1012 |
1013 | .bg-primary .btn {
1014 | color: #fff;
1015 | border-color: #fff;
1016 | }
1017 |
1018 | .bg-primary .btn:hover {
1019 | background: #fff;
1020 | color: #5bc0de;
1021 | }
1022 |
1023 | .li {
1024 | display: list-item!important;
1025 | }
1026 |
1027 |
1028 | /*!---------- 1. GLOBAL STYLES ----------*/
1029 |
1030 | body {
1031 | -webkit-font-smoothing: antialiased;
1032 | -moz-osx-font-smoothing: grayscale;
1033 | font-size: 13px;
1034 | line-height: 24px;
1035 | font-family: "Nunito", "Helvetica Neue", Helvetica, Arial, sans-serif;
1036 | color: #666;
1037 | overflow-x: hidden;
1038 | }
1039 |
1040 | body.boxed-layout {
1041 | background: #eee;
1042 | }
1043 |
1044 | body.boxed-layout .main-container {
1045 | background: #fff;
1046 | }
1047 |
1048 | body.boxed-layout, .boxed-layout .nav-container, .boxed-layout .main-container, .boxed-layout nav {
1049 | max-width: 1366px;
1050 | margin: 0 auto;
1051 | left: 0;
1052 | right: 0;
1053 | }
1054 |
1055 | ul {
1056 | list-style: none;
1057 | }
1058 |
1059 | ul.bullets {
1060 | list-style: inside;
1061 | }
1062 |
1063 | .main-container {
1064 | clear: both;
1065 | }
1066 |
1067 | hr {
1068 | border: none;
1069 | border-top: 1px solid #ccc;
1070 | margin: 0 0 24px 0;
1071 | width: 100%;
1072 | }
1073 |
1074 | hr.short-thick {
1075 | max-width: 50px;
1076 | border-top: 5px solid #ccc;
1077 | opacity: 1 !important;
1078 | }
1079 |
1080 | .image-bg hr {
1081 | border-color: #fff;
1082 | opacity: .6;
1083 | }
1084 |
1085 | .image-bg.bg-light hr {
1086 | border-color: #ccc;
1087 | opacity: 1;
1088 | }
1089 |
1090 | .bg-dark hr {
1091 | border-color: #555;
1092 | }
1093 |
1094 | .inline-block {
1095 | display: inline-block;
1096 | }
1097 |
1098 | .list-inline {
1099 | margin-left: 0;
1100 | }
1101 |
1102 | .list-inline>li {
1103 | padding: 0 8px;
1104 | }
1105 |
1106 | .list-inline>li:last-child {
1107 | padding-right: 0;
1108 | }
1109 |
1110 | .list-inline>li:first-child {
1111 | padding-left: 0;
1112 | }
1113 |
1114 | .bg-primary .list-inline i {
1115 | color: #feb3b3;
1116 | }
1117 |
1118 | .overflow-hidden {
1119 | overflow: hidden;
1120 | }
1121 |
1122 | .display-block {
1123 | display: block;
1124 | }
1125 |
1126 | .show-grid {
1127 | border: 1px dashed rgba(255, 255, 255, 0);
1128 | padding: 8px;
1129 | transition: all 0.2s ease;
1130 | -webkit-transition: all 0.2s ease;
1131 | -moz-transition: all 0.2s ease;
1132 | cursor: default;
1133 | }
1134 |
1135 | .show-grid:hover {
1136 | border-color: #222;
1137 | }
1138 |
1139 | .right {
1140 | right: 0;
1141 | }
1142 |
1143 | .relative {
1144 | position: relative;
1145 | z-index: 2;
1146 | }
1147 |
1148 | .clearboth {
1149 | clear: both;
1150 | }
1151 |
1152 | .spread-children * {
1153 | display: inline-block;
1154 | margin-left: 12px;
1155 | margin-right: 12px;
1156 | }
1157 |
1158 | .spread-children-large * {
1159 | display: inline-block;
1160 | margin-left: 24px;
1161 | margin-right: 24px;
1162 | }
1163 |
1164 | .container {
1165 | position: relative;
1166 | }
1167 |
1168 | .vnu {
1169 | display: inline;
1170 | }
1171 |
1172 | .row-gapless>div[class*='col-'] {
1173 | padding: 0;
1174 | }
1175 |
1176 | @media all and (max-width: 1100px) {
1177 | .col-md-push-1 {
1178 | left: 0;
1179 | }
1180 | }
1181 |
1182 | @media all and (max-width: 768px) {
1183 | .pull-left-sm {
1184 | float: left !important;
1185 | }
1186 | .overflow-hidden-xs {
1187 | overflow: hidden;
1188 | }
1189 | }
1190 |
1191 | @media all and (max-width: 767px) {
1192 | .spread-children * {
1193 | margin-left: 6px;
1194 | margin-right: 6px;
1195 | }
1196 | }
1197 |
1198 |
1199 | /*!---------- 3. TYPOGRAPHY ----------*/
1200 |
1201 | @media all and (max-width: 767px) {
1202 | .text-center-xs {
1203 | text-align: center !important;
1204 | }
1205 | }
1206 |
1207 | .bold {
1208 | font-weight: 600 !important;
1209 | }
1210 |
1211 | .thin {
1212 | font-weight: 100 !important;
1213 | }
1214 |
1215 | @media all and (max-width: 767px) {
1216 | .thin {
1217 | font-weight: 300 !important;
1218 | }
1219 | }
1220 |
1221 | h1, h2, h3, h4, h5, h6, p, ul, ol, table, blockquote, input, button, select, textarea {
1222 | margin-bottom: 24px;
1223 | margin-top: 0;
1224 | padding: 0;
1225 | }
1226 |
1227 | h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
1228 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
1229 | }
1230 |
1231 | h1, h2, h3, h4, h5, h6 {
1232 | font-weight: 300;
1233 | color: #292929;
1234 | }
1235 |
1236 | h1, .h1 {
1237 | font-size: 56px;
1238 | line-height: 64px;
1239 | }
1240 |
1241 | h1.large {
1242 | font-size: 72px;
1243 | line-height: 80px;
1244 | font-weight: 100;
1245 | }
1246 |
1247 | @media all and (max-width: 990px) {
1248 | h1.large {
1249 | font-size: 56px;
1250 | line-height: 64px;
1251 | }
1252 | }
1253 |
1254 | h2 {
1255 | font-size: 40px;
1256 | line-height: 48px;
1257 | }
1258 |
1259 | h3 {
1260 | font-size: 32px;
1261 | line-height: 40px;
1262 | }
1263 |
1264 | h4 {
1265 | font-size: 24px;
1266 | line-height: 32px;
1267 | }
1268 |
1269 | h5 {
1270 | font-size: 16px;
1271 | line-height: 24px;
1272 | font-weight: 400;
1273 | }
1274 |
1275 | h6, .h6 {
1276 | font-size: 12px;
1277 | line-height: 24px;
1278 | font-weight: 700;
1279 | }
1280 |
1281 | @media all and (max-width: 767px) {
1282 | h1, h1.large, .h1 {
1283 | font-size: 32px;
1284 | line-height: 40px;
1285 | font-weight: 300;
1286 | }
1287 | h2 {
1288 | font-size: 32px;
1289 | line-height: 40px;
1290 | }
1291 | h3 {
1292 | font-size: 24px;
1293 | line-height: 32px;
1294 | }
1295 | h4 {
1296 | font-size: 18px;
1297 | line-height: 26px;
1298 | }
1299 | h5 {
1300 | font-size: 16px;
1301 | line-height: 24px;
1302 | font-weight: 400;
1303 | }
1304 | h6, .h6 {
1305 | font-size: 12px;
1306 | line-height: 24px;
1307 | font-weight: 700;
1308 | }
1309 | }
1310 |
1311 | .uppercase {
1312 | font-weight: 400;
1313 | text-transform: uppercase;
1314 | }
1315 |
1316 | h1.uppercase {
1317 | letter-spacing: 17px;
1318 | margin-right: -17px;
1319 | }
1320 |
1321 | h2.uppercase {
1322 | letter-spacing: 10px;
1323 | margin-right: -10px;
1324 | }
1325 |
1326 | h3.uppercase {
1327 | letter-spacing: 6px;
1328 | margin-right: -6px;
1329 | }
1330 |
1331 | h4.uppercase {
1332 | letter-spacing: 3px;
1333 | margin-right: -3px;
1334 | }
1335 |
1336 | h5.uppercase {
1337 | letter-spacing: 2px;
1338 | margin-right: -2px;
1339 | }
1340 |
1341 | h6.uppercase, .h6-u {
1342 | letter-spacing: 2px;
1343 | font-weight: 700;
1344 | }
1345 |
1346 | .bold-h6 {
1347 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
1348 | font-size: 12px;
1349 | line-height: 24px;
1350 | font-weight: 400;
1351 | text-transform: uppercase;
1352 | letter-spacing: 2px;
1353 | font-weight: 700;
1354 | }
1355 |
1356 | p, span {
1357 | font-weight: 400;
1358 | }
1359 |
1360 | p.lead {
1361 | font-size: 16px;
1362 | font-weight: 400;
1363 | line-height: 28px;
1364 | }
1365 |
1366 | .sub {
1367 | font-size: 12px;
1368 | }
1369 |
1370 | @media all and (max-width: 767px) {
1371 | p.lead {
1372 | font-size: 13px;
1373 | line-height: 24px;
1374 | }
1375 | p {
1376 | font-size: 12px;
1377 | }
1378 | }
1379 |
1380 | a, a:visited, a:focus, a:active, a:hover {
1381 | text-decoration: none;
1382 | outline: none;
1383 | }
1384 |
1385 | a {
1386 | font-weight: 600;
1387 | color: #5bc0de;
1388 | transition: all 0.3s ease;
1389 | -webkit-transition: all 0.3s ease;
1390 | -moz-transition: all 0.3s ease;
1391 | cursor: poitner;
1392 | }
1393 |
1394 | .image-bg a, .bg-primary a {
1395 | color: #fff;
1396 | }
1397 |
1398 | .image-bg a:hover, .bg-primary a:hover {
1399 | color: #fff;
1400 | opacity: .9;
1401 | }
1402 |
1403 | .bg-light a {
1404 | color: #5bc0de;
1405 | }
1406 |
1407 | .bg-light a:hover {
1408 | color: #5bc0de;
1409 | opacity: 1;
1410 | }
1411 |
1412 | .label {
1413 | font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
1414 | font-size: 12px;
1415 | line-height: 24px;
1416 | font-weight: 400;
1417 | text-transform: uppercase;
1418 | letter-spacing: 2px;
1419 | font-weight: 700;
1420 | letter-spacing: 1px;
1421 | background: #5bc0de;
1422 | border-radius: 0;
1423 | padding: 6px 12px;
1424 | font-size: 10px;
1425 | vertical-align: middle;
1426 | }
1427 |
1428 | blockquote {
1429 | overflow: hidden;
1430 | font-family: "Merriweather", "Georgia", Times New Roman, Times, serif;
1431 | font-size: 20px;
1432 | line-height: 40px;
1433 | font-style: italic;
1434 | background: #f5f5f5;
1435 | padding: 32px;
1436 | color: #777;
1437 | font-weight: 300;
1438 | }
1439 |
1440 | .bg-secondary blockquote {
1441 | background: #fff;
1442 | border-color: #fc4f4f;
1443 | }
1444 |
1445 | blockquote .author {
1446 | font-size: 12px;
1447 | display: block;
1448 | float: right;
1449 | margin-top: 16px;
1450 | }
1451 |
1452 | .number {
1453 | font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
1454 | }
1455 |
1456 | .columns-2 {
1457 | column-count: 2;
1458 | -webkit-column-count: 2;
1459 | }
1460 |
1461 | @media all and (max-width: 767px) {
1462 | br {
1463 | display: none;
1464 | }
1465 | blockquote {
1466 | font-size: 16px;
1467 | line-height: 32px;
1468 | }
1469 | .columns-2 {
1470 | column-count: 1;
1471 | -webkit-column-count: 1;
1472 | }
1473 | }
1474 |
1475 | .text-left {
1476 | text-align: left !important;
1477 | }
1478 |
1479 | @media all and (max-width: 767px) {
1480 | .text-left-xs {
1481 | text-align: left !important;
1482 | }
1483 | }
1484 |
1485 |
1486 | /*!---------- 3.1. TYPOGRAPHY - LISTS ----------*/
1487 |
1488 | ul[data-bullet] li {
1489 | line-height: 32px;
1490 | }
1491 |
1492 | ul[data-bullet] li i:first-child {
1493 | margin-right: 16px;
1494 | transform: scale(1.5);
1495 | -webkit-transform: scale(1.5);
1496 | display: inline-block;
1497 | }
1498 |
1499 | ul.lead li {
1500 | font-size: 16px;
1501 | line-height: 40px;
1502 | }
1503 |
1504 |
1505 | /*!---------- 4. COLOURS ----------*/
1506 |
1507 | .bg-primary {
1508 | background: #fc4f4f !important;
1509 | }
1510 |
1511 | .bg-secondary {
1512 | background: #f8f8f8;
1513 | }
1514 |
1515 | .bg-white {
1516 | background: #fff;
1517 | }
1518 |
1519 | .bg-dark {
1520 | background: #292929;
1521 | }
1522 |
1523 | .color-body {
1524 | color: #666;
1525 | }
1526 |
1527 | .color-primary {
1528 | color: #5bc0de !important;
1529 | }
1530 |
1531 | .color-red {
1532 | color: #e31d3b !important;
1533 | }
1534 |
1535 | .color-white {
1536 | color: #fff;
1537 | }
1538 |
1539 | .hovercard:hover {
1540 | box-shadow: 0 1px 5px 5px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .5);
1541 | transition: all 300ms linear
1542 | }
1543 |
1544 | .hovercard {
1545 | box-shadow: 0 1px 5px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .2);
1546 | transition: all 300ms linear
1547 | }
1548 |
1549 | .hovercard-light:hover {
1550 | box-shadow: 0 1px 5px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .05);
1551 | transition: all 300ms linear
1552 | }
1553 |
1554 | .hovercard-light {
1555 | transition: all 300ms linear
1556 | }
1557 |
1558 | .hover-light {
1559 | box-shadow: 0 1px 5px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .05);
1560 | transition: all 300ms linear
1561 | }
1562 |
1563 | .hover-light:hover {
1564 | box-shadow: 0 1px 5px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .4);
1565 | transition: all 300ms linear
1566 | }
1567 |
1568 | .shortcode {
1569 | height: 35px!important;
1570 | display: block;
1571 | width: 100%;
1572 | padding: 6px 12px;
1573 | font-size: 16px;
1574 | font-weight: 500;
1575 | line-height: 1.42857143;
1576 | color: #5bc0de;
1577 | background-color: #fff;
1578 | border: 1px solid #f5f5f5;
1579 | font-family: inherit;
1580 | border-radius:4px;
1581 | }
1582 |
1583 | .form-control {
1584 | height: 35px!important;
1585 | width: 90%;
1586 | border-color: #f5f5f5!important;
1587 | }
1588 |
1589 | .colw70 {
1590 | max-width: 70%;
1591 | margin-left: 15%;
1592 | margin-right: 15%;
1593 | }
1594 | .table{
1595 | background: rgba(256,256,256,0.6)!important;
1596 | box-shadow: 0 1px 5px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .2);
1597 | transition: all 300ms linear
1598 | }
1599 | .ui.red.table {
1600 | border-top: .2em solid #5bc0de!important;
1601 | }
1602 | .table:hover {
1603 | box-shadow: 0 1px 5px 5px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .5);
1604 | transition: all 300ms linear
1605 | }
1606 |
1607 | .btn.copy{
1608 | float: right;
1609 | margin-top: -7px;
1610 | margin-right: -13px;
1611 | min-width: 10px;
1612 | }
1613 | .home_heading{
1614 | color: #fff;
1615 | font-size: 44px;
1616 | font-weight: 900;
1617 | text-align: center;
1618 | text-transform: uppercase;
1619 | text-shadow: 6px 6px 7px rgba(0, 0, 0, 0.2);
1620 | }
1621 |
1622 | .home_subheading{
1623 | color: #fff;
1624 | font-size: 22px;
1625 | font-weight: normal;
1626 | text-align: center;
1627 | text-shadow: 3px 3px 4px rgba(0, 0, 0, 0.2);
1628 | }
1629 | .formbox{
1630 | width:30%;
1631 | margin-left:36%;
1632 | margin-right:36%;
1633 | margin-top: calc(8% - 64px);
1634 | }
1635 |
1636 | .mimg {
1637 | background: #f81f27;
1638 | width: 100%;
1639 | padding-left: 40px;
1640 | padding-right: 40px;
1641 | }
1642 |
1643 | .formbox {
1644 | padding-left: 0px !important;
1645 | padding-right: 0px !important;
1646 | }
1647 |
1648 | @media (max-width: 1024px)
1649 | {
1650 | .container{
1651 | padding: 0px 0px!important;
1652 | margin-right: 0px!important;
1653 | margin-left: 0px!important;
1654 | width: 100%!important;
1655 | }
1656 | .formbox{
1657 | width: 100%!important;
1658 | margin-top: calc(30% - 64px);
1659 | margin-left:0%;
1660 | margin-right:0%;
1661 | }
1662 | .form-control{
1663 | height: 60px!important;
1664 | width: 90%;
1665 | margin-bottom: 5%;
1666 | font-size: 20px!important;
1667 | }
1668 | .mimg{
1669 | width: 100%;
1670 | }
1671 | .menu li a{
1672 | font-size: 20px!important;
1673 | }
1674 | .nav-bar h2{
1675 | font-size: 30px!important;
1676 | }
1677 | .btn{
1678 | font-size: 20px!important;
1679 | }
1680 | .colw70 {
1681 | max-width: 100%;
1682 | margin-left: 0%;
1683 | margin-right: 0%;
1684 | }
1685 | }
1686 |
--------------------------------------------------------------------------------
/static/admin/img/cblogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coding-blocks/shortlr/d2c6c8c1c18164afef47b8e015e569c5dd0d0aca/static/admin/img/cblogo.png
--------------------------------------------------------------------------------
/static/admin/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coding-blocks/shortlr/d2c6c8c1c18164afef47b8e015e569c5dd0d0aca/static/admin/img/logo.png
--------------------------------------------------------------------------------
/static/admin/includes/nav-container.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
URL SHORTNER
9 |
10 |
11 |
12 |
37 |
38 |
65 |
66 |
--------------------------------------------------------------------------------
/static/admin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Coding Blocks | URL Shortener
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
A Link Contains a lot more than you think
22 | Shorten and Share your links with Coding Blocks URL Shortner
23 |
24 |
25 |
26 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/static/admin/js/analytics.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by bhavyaagg on 27/08/17.
3 | */
4 |
5 | (function (i, s, o, g, r, a, m) {
6 | i['GoogleAnalyticsObject'] = r;
7 | i[r] = i[r] || function () {
8 | (i[r].q = i[r].q || []).push(arguments)
9 | }, i[r].l = 1 * new Date();
10 | a = s.createElement(o),
11 | m = s.getElementsByTagName(o)[0];
12 | a.async = 1;
13 | a.src = g;
14 | m.parentNode.insertBefore(a, m)
15 | })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
16 |
17 | ga('create', 'UA-83327907-4', 'auto');
18 | ga('send', 'pageview');
19 |
--------------------------------------------------------------------------------
/static/admin/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.3.7 (http://getbootstrap.com)
3 | * Copyright 2011-2016 Twitter, Inc.
4 | * Licensed under the MIT license
5 | */
6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
--------------------------------------------------------------------------------
/static/admin/js/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by bhavyaagg on 27/08/17.
3 | */
4 |
5 | $(function () {
6 |
7 | var $location = $(location);
8 | var arr = $location.attr('href').split("=");
9 | var $loginButton = $('#login-button');
10 | var $menu = $('#menu');
11 | var $shortCode = $('#shortcode');
12 | var $LongURL = $('#url');
13 |
14 | if (arr.length === 2) {
15 | $.post('/auth', {code: arr[1]}, function (authtoken) {
16 | if (authtoken.success === true) {
17 | localStorage.setItem("authtoken", authtoken.token);
18 | $loginButton.remove();
19 | $menu.append('' + authtoken.user + ' ');
20 | } else {
21 | $location[0].replace("/admin");
22 | }
23 | })
24 | }
25 |
26 | $('.nav-container').load('/admin/includes/nav-container.html');
27 |
28 | $('#submit').click(function () {
29 |
30 | var URLregex = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/g;
31 |
32 | if ($LongURL.val().length === 0) {
33 |
34 | $shortCode.html('URL field is empty
');
35 | $LongURL.css('border-color', 'red');
36 |
37 | } else if (URLregex.test($LongURL.val()) === false) {
38 |
39 | $shortCode.html('Invalid URL format The URL must be of form \"www.example.com"\ \"https://example.com\" \"mailto:foo@bar.com\"
');
40 | $LongURL.css('border-color', 'red');
41 |
42 | } else {
43 |
44 | $.post('/api/v1/shorten', {
45 | url: $LongURL.val(),
46 | secret: $('#secret').val(),
47 | code: $('#code').val()
48 | }, function (data) {
49 |
50 | if (typeof data === 'string') {
51 | $shortCode.html(data)
52 | } else {
53 | $shortCode.html("'
61 | );
62 | $('.shortcode.hovercard-light').append(` Copy `);
63 | }
64 | }) //post request ends here
65 | } //end of if else block
66 | });
67 |
68 | $shortCode.on('click', '.shortcode button', function () {
69 |
70 | var range = document.createRange();
71 | range.selectNode($('.shortcode a')[0]);
72 | window.getSelection().addRange(range);
73 | document.execCommand("Copy");
74 | window.alert('Link Copied to your clipboard')
75 | });
76 |
77 | var $heading = $('#homeHeading');
78 | var $form = $('#shortcodeform');
79 | $("#shortForm").click(function () {
80 | $heading.css('display', 'none');
81 | $form.css('display', "block");
82 | });
83 |
84 |
85 | });
--------------------------------------------------------------------------------
/static/admin/js/search.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by bhavyaagg on 27/08/17.
3 | */
4 |
5 | $(function () {
6 | $('.nav-container').load('/admin/includes/nav-container.html', function () {
7 | let search = $('#searchByLongUrl');
8 | search.attr('title', 'Shorten');
9 | search.attr('href', '/admin');
10 | search.text('Shorten');
11 |
12 | });
13 |
14 | $('#submit').click(function () {
15 | $.post('/api/v1/search', {
16 | longcode: $('#url').val(),
17 | secret: $('#secret').val()
18 | }).done(function (data) {
19 | if (data.status === 200) {
20 | let $shortcode = $('#shortcode');
21 | let str= "";
22 | for(let i =0;icb.lk/${data.urls[i].codeStr} `
24 | }
25 | $shortcode.append(""+str+"
");
26 |
27 | }
28 | }).fail(function (err) {
29 | console.log(err);
30 | })
31 | });
32 |
33 |
34 |
35 | var $heading = $('#homeHeading');
36 | var $form = $('#shortcodeform');
37 | $("#shortForm").click(function () {
38 | $heading.css('display', 'none');
39 | $form.css('display', "block");
40 | });
41 |
42 | });
--------------------------------------------------------------------------------
/static/admin/search/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Coding Blocks | URL Shortener
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
A Link Contains a lot more than you think
21 | Shorten and Share your links with Coding Blocks URL Shortner
22 |
23 |
24 |
25 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/static/admin/stats/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Statistics
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Refresh
28 |
29 |
30 |
31 |
32 |
33 | Short URL
34 | Target
35 | Hits
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
71 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/static/admin/stats/index_ui.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cb.lk | URL Shortener
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
43 |
44 |
45 |
46 |
A Link Contains a lot more than you think
47 |
Shorten & share your links with Coding Blocks URL shortener.
48 |
70 |
71 |
72 |
73 |
74 |
75 |
Shorten Your Links
76 |
77 | Most links are too long to be shared? Don't you think? Make your links look neat. Shorten and share them with CB.lk.
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
89 |
90 |
91 |
92 |
93 |
"Difficult Problems now a CakeWalk !"
94 |
95 | "I had no background in coding. After the course, I feel more confident. Sumeet sir made difficult algorithms look like a cakewalk.I also enrolled for Android Course, and its amazing too. Coding Blocks defined my love for Coding."
96 |
97 |
98 |
99 |
100 |
101 |
102 | Piyush Ajmani - via quora
103 |
104 |
105 | Student DTU
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
"Cracked Amazon the next day!"
116 |
117 | I used to lag in C++ basics, but with Prateek Bhayia as my mentor I saw great improvement in coding style and problem solving approach.Just after the day of my course completion, I got internship offer from Amazon.
118 |
119 |
120 |
121 |
122 |
123 | Manish Mittal - via Facebook
124 |
125 |
126 | Student NSIT Internship at Amazon
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
"Really Good Experience!"
137 |
138 | I had a really good experience studying at Coding Blocks. Coding Blocks helped in a shaping solution building approach. Classes are held regularly and we practiced a lot. My only regret is not joining Coding Blocks earlier.
139 |
140 |
141 |
142 |
143 |
144 | Bhavyaa Bansal - via Facebook
145 |
146 |
147 | Student DTU Placed at Amazon
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
197 |
198 |
199 |
213 |
214 |
215 |
216 |
217 |
223 |
224 |
364 |
365 |
366 |
367 |
--------------------------------------------------------------------------------
/utils/db.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by championswimmer on 25/11/16.
3 | */
4 | const Sequelize = require('sequelize');
5 | const r = require('convert-radix64');
6 | const axios = require('axios');
7 | const uid = require('uid2');
8 | const secrets = require('../secrets');
9 |
10 | //This is so that BIGINT is treated at integer in JS
11 | require('pg').defaults.parseInt8 = true;
12 | //We have made sure that we do not use integers larger than 2^53 in our logic
13 |
14 | const DB_HOST = secrets.DB.HOST || "localhost";
15 | const DB_USER = secrets.DB.USERNAME || "shorturl";
16 | const DB_PASS = secrets.DB.PASSWORD || "shorturl";
17 | const DB_NAME = secrets.DB.DB_NAME || "shorturl";
18 | const DB_PORT = secrets.DB.PORT || 5432;
19 |
20 | const DATABASE_URL = process.env.SHORTLR_DATABASE_URL ||
21 | (`postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`);
22 |
23 | const sequelize = new Sequelize(DATABASE_URL, {
24 | host: DB_HOST,
25 | dialect: 'postgres',
26 |
27 | pool: {
28 | max: 5,
29 | min: 0,
30 | idle: 10000
31 | },
32 | });
33 |
34 |
35 | const URL = sequelize.define('url', {
36 | code: {type: Sequelize.BIGINT, primaryKey: true},
37 | codeStr: {type: Sequelize.STRING, unique: true},
38 | longURL: {type: Sequelize.STRING},
39 | hits: {type: Sequelize.INTEGER, defaultValue: 0}
40 | });
41 |
42 | const Event = sequelize.define('event', {
43 | time: {type: Sequelize.DATE},
44 | from: {type: Sequelize.STRING}
45 | });
46 |
47 | const Alias = sequelize.define('alias', {});
48 |
49 | const User = sequelize.define('user', {
50 | name: {type: Sequelize.STRING},
51 | email: {type: Sequelize.STRING}
52 | });
53 |
54 | Event.belongsTo(URL);
55 |
56 |
57 | const OneAuth = sequelize.define('authtoken', {
58 | id: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
59 | oneauthId: Sequelize.INTEGER,
60 | oneauthToken: Sequelize.STRING,
61 | token: Sequelize.STRING
62 | });
63 |
64 | OneAuth.belongsTo(User);
65 | User.hasMany(OneAuth);
66 |
67 | const Group = sequelize.define('group', {
68 | id: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
69 | groupName: Sequelize.STRING
70 | });
71 |
72 |
73 | sequelize.sync(); //Normal case
74 | //sequelize.sync({force: true}); //If schema changes NOTE: It will drop/delete old data
75 |
76 |
77 | module.exports = {
78 | addUrl: function (code, longURL, alias, done, failed) {
79 | if (!alias) {
80 | URL.findOrCreate({
81 | where: {
82 | code: code
83 | },
84 | defaults: {
85 | code: code,
86 | codeStr: r.to64(code),
87 | longURL: longURL
88 | }
89 |
90 | }).spread(function (url, created) {
91 | done(url.codeStr, !created, url.longURL);
92 | }).catch(function (error) {
93 | console.log(error);
94 | failed(error);
95 | })
96 | } else {
97 | //TODO: handle longer than 9 with alias map
98 | }
99 | },
100 | fetchUrl: function (code, from, done, failed) {
101 | URL.findById(code).then(function (url) {
102 | done(url.longURL);
103 | Event.create({
104 | from: from,
105 | time: new Date(),
106 | urlCode: url.code
107 | }).then(function () {
108 | url.increment('hits')
109 | });
110 | }).catch(function (error) {
111 | failed(error)
112 | })
113 | },
114 | fetchLongUrl: function (longURL, done, failed) {
115 | URL.findAll({
116 | where: {
117 | longURL: longURL
118 | }
119 | }).then(function (urls) {
120 | done(urls);
121 | }).catch(function (err) {
122 | console.log(err);
123 | failed(err);
124 | })
125 | },
126 | urlStats: function ({page, size}) {
127 |
128 | const offset = (page - 1) * size;
129 | return URL.findAndCountAll({
130 | order: [['hits', 'DESC']],
131 | limit: size,
132 | offset: offset
133 | }).then(data => {
134 | if (offset > data.count || offset < 0)
135 | throw new Error('Pagination Error : Out of Error Range');
136 |
137 | const lastPage = Math.ceil(data.count / size);
138 | return {urls: data.rows, lastPage};
139 | });
140 | },
141 | authFunction: function (authtoken, done) {
142 | OneAuth.findOne({
143 | where: {
144 | oneauthToken: authtoken.data.access_token
145 | },
146 | include: User
147 | }).then(function (oneauth) {
148 | if (oneauth !== null) {
149 | done({
150 | success: true,
151 | token: oneauth.token,
152 | user: oneauth.user.name
153 | })
154 | }
155 | else {
156 | axios.get('https://account.codingblocks.com/api/users/me', {
157 | headers: {'Authorization': `Bearer ${authtoken.data.access_token}`}
158 | }).then(function (user) {
159 | OneAuth.create({
160 | user: {
161 | name: user.data.firstname + " " + user.data.lastname,
162 | email: user.data.email
163 | }
164 | , oneauthToken: authtoken.data.access_token
165 | , token: uid(30)
166 | }, {
167 | include: [User]
168 | }).then(function (oneauthFinal) {
169 | done({
170 | success: true,
171 | token: oneauthFinal.token,
172 | user: user.data.firstname + " " + user.data.lastname
173 | })
174 | }).catch(function (err) {
175 | console.log(err);
176 | done({
177 | success: false
178 | , code: "500"
179 | , error: {
180 | message: "Could not create in Oneauth Table(Internal Server Error)."
181 | }
182 | })
183 | })
184 | }).catch(function (err) {
185 | console.log(err);
186 | done({
187 | success: false
188 | , code: "500"
189 | , error: {
190 | message: "Could not get details from Oneauth API(Internal Server Error)."
191 | }
192 | })
193 | })
194 | }
195 | }).catch(function (err) {
196 | console.log(err);
197 | done({
198 | success: false
199 | , code: "500"
200 | , error: {
201 | message: "Could not find in Oneauth(Internal Server Error)."
202 | }
203 | })
204 | })
205 | },
206 | models:
207 | {
208 | Group
209 | }
210 |
211 | };
--------------------------------------------------------------------------------
/utils/shortner.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by championswimmer on 24/11/16.
3 | */
4 |
5 | const db = require('./db');
6 | const r = require('convert-radix64');
7 |
8 |
9 | const getRandomCode = function () {
10 | let randCode =
11 | // 2 digit number with 6 zeros
12 | (((Math.random() * 100) << 0) * 1000000)
13 | +
14 | //current milliseconds (cutting off last 2 digits), 6-digit
15 | (((new Date().getTime() / 100) << 0) % 1000000);
16 | return randCode;
17 |
18 | };
19 |
20 |
21 | module.exports = {
22 | shorten: function (url, code, done) {
23 |
24 | let alias = null;
25 |
26 | if (!code) {
27 | code = getRandomCode();
28 |
29 | } else {
30 | if (code.length <= 9) {
31 | code = r.from64(code);
32 | } else {
33 | alias = code;
34 | code = getRandomCode();
35 | }
36 | }
37 |
38 | db.addUrl(code, url, alias, function (shortcode, existed, longURL) {
39 | done(shortcode, existed, longURL);
40 | }, function (error) {
41 | console.log(error);
42 | done(null)
43 | });
44 |
45 | },
46 | expand: function(shortcode, from, done) {
47 | db.fetchUrl(r.from64(shortcode), from, function (url) {
48 | done(url);
49 | }, function (error) {
50 | console.log(error);
51 | done(null)
52 | });
53 | },
54 | stats: function (page,size,fullUrl) {
55 | return db.urlStats({page,size}).then( ({urls,lastPage})=>{
56 | let nextPage= page==lastPage ? null : page+1;
57 | let prevPage = page==1 ? null : page-1 ;
58 |
59 | if(nextPage)
60 | nextPage = fullUrl + `?page=${nextPage}&size=${size}`;
61 | if(prevPage)
62 | prevPage = fullUrl + `?page=${prevPage}&size=${size}`;
63 |
64 | return {urls,prevPage,nextPage,lastPage};
65 | })
66 | }
67 | };
--------------------------------------------------------------------------------
/utils/validator.js:
--------------------------------------------------------------------------------
1 | exports = module.exports = {
2 | validUrl(longUrl) {
3 | if (longUrl.indexOf('x.co') !== -1) {
4 | return false
5 | }
6 | if (longUrl.indexOf('paypal') !== -1) {
7 | return false
8 | }
9 | if (longUrl.indexOf('go2l.ink') !== -1) {
10 | return false
11 | }
12 | if (longUrl.indexOf('bit.ly') !== -1) {
13 | return false
14 | }
15 | if (longUrl.indexOf('goo.gl') !== -1) {
16 | return false
17 | }
18 |
19 | return true
20 | }
21 | }
--------------------------------------------------------------------------------
/wait-for-it.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Use this script to test if a given TCP host/port are available
3 |
4 | cmdname=$(basename $0)
5 |
6 | echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
7 |
8 | usage()
9 | {
10 | cat << USAGE >&2
11 | Usage:
12 | $cmdname host:port [-s] [-t timeout] [-- command args]
13 | -h HOST | --host=HOST Host or IP under test
14 | -p PORT | --port=PORT TCP port under test
15 | Alternatively, you specify the host and port as host:port
16 | -s | --strict Only execute subcommand if the test succeeds
17 | -q | --quiet Don't output any status messages
18 | -t TIMEOUT | --timeout=TIMEOUT
19 | Timeout in seconds, zero for no timeout
20 | -- COMMAND ARGS Execute command with args after the test finishes
21 | USAGE
22 | exit 1
23 | }
24 |
25 | wait_for()
26 | {
27 | if [[ $TIMEOUT -gt 0 ]]; then
28 | echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
29 | else
30 | echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
31 | fi
32 | start_ts=$(date +%s)
33 | while :
34 | do
35 | (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
36 | result=$?
37 | if [[ $result -eq 0 ]]; then
38 | end_ts=$(date +%s)
39 | echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
40 | break
41 | fi
42 | sleep 1
43 | done
44 | return $result
45 | }
46 |
47 | wait_for_wrapper()
48 | {
49 | # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
50 | if [[ $QUIET -eq 1 ]]; then
51 | timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
52 | else
53 | timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
54 | fi
55 | PID=$!
56 | trap "kill -INT -$PID" INT
57 | wait $PID
58 | RESULT=$?
59 | if [[ $RESULT -ne 0 ]]; then
60 | echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
61 | fi
62 | return $RESULT
63 | }
64 |
65 | # process arguments
66 | while [[ $# -gt 0 ]]
67 | do
68 | case "$1" in
69 | *:* )
70 | hostport=(${1//:/ })
71 | HOST=${hostport[0]}
72 | PORT=${hostport[1]}
73 | shift 1
74 | ;;
75 | --child)
76 | CHILD=1
77 | shift 1
78 | ;;
79 | -q | --quiet)
80 | QUIET=1
81 | shift 1
82 | ;;
83 | -s | --strict)
84 | STRICT=1
85 | shift 1
86 | ;;
87 | -h)
88 | HOST="$2"
89 | if [[ $HOST == "" ]]; then break; fi
90 | shift 2
91 | ;;
92 | --host=*)
93 | HOST="${1#*=}"
94 | shift 1
95 | ;;
96 | -p)
97 | PORT="$2"
98 | if [[ $PORT == "" ]]; then break; fi
99 | shift 2
100 | ;;
101 | --port=*)
102 | PORT="${1#*=}"
103 | shift 1
104 | ;;
105 | -t)
106 | TIMEOUT="$2"
107 | if [[ $TIMEOUT == "" ]]; then break; fi
108 | shift 2
109 | ;;
110 | --timeout=*)
111 | TIMEOUT="${1#*=}"
112 | shift 1
113 | ;;
114 | --)
115 | shift
116 | CLI="$@"
117 | break
118 | ;;
119 | --help)
120 | usage
121 | ;;
122 | *)
123 | echoerr "Unknown argument: $1"
124 | usage
125 | ;;
126 | esac
127 | done
128 |
129 | if [[ "$HOST" == "" || "$PORT" == "" ]]; then
130 | echoerr "Error: you need to provide a host and port to test."
131 | usage
132 | fi
133 |
134 | TIMEOUT=${TIMEOUT:-15}
135 | STRICT=${STRICT:-0}
136 | CHILD=${CHILD:-0}
137 | QUIET=${QUIET:-0}
138 |
139 | if [[ $CHILD -gt 0 ]]; then
140 | wait_for
141 | RESULT=$?
142 | exit $RESULT
143 | else
144 | if [[ $TIMEOUT -gt 0 ]]; then
145 | wait_for_wrapper
146 | RESULT=$?
147 | else
148 | wait_for
149 | RESULT=$?
150 | fi
151 | fi
152 |
153 | if [[ $CLI != "" ]]; then
154 | if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
155 | echoerr "$cmdname: strict mode, refusing to execute subprocess"
156 | exit $RESULT
157 | fi
158 | exec $CLI
159 | else
160 | exit $RESULT
161 | fi
162 |
--------------------------------------------------------------------------------