├── .gitignore
├── frontend
├── src
│ ├── img
│ │ ├── business.jpg
│ │ └── 45.svg
│ ├── app.js
│ ├── templates.js
│ ├── utils.js
│ ├── scss
│ │ └── app.scss
│ └── JobSearch.js
├── package.json
├── .cache
│ ├── 14
│ │ └── 4a9a7180a17ec674ebdbc158ad5ce6.json
│ ├── 94
│ │ └── b4209ada9b3069fbf5fb0c811b446c.json
│ ├── c3
│ │ └── 395c7d7428ec73498eb7e0798ccd7a.json
│ ├── 0e
│ │ └── 9ed2ee4108341553c6c33d91d5cce7.json
│ ├── 9b
│ │ └── 3966e0131e408256dff65fff8c9b07.json
│ └── d3
│ │ └── d633b5f1caf367b2188ffb60a62787.json
├── index.html
└── dist
│ ├── index.html
│ ├── app.a6a4d504.js.map
│ └── app.a6a4d504.js
└── api
├── config.js
├── package.json
├── server.js
└── package-lock.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | .cache
4 | dist
5 |
--------------------------------------------------------------------------------
/frontend/src/img/business.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codebubb/job-search-app/HEAD/frontend/src/img/business.jpg
--------------------------------------------------------------------------------
/frontend/src/app.js:
--------------------------------------------------------------------------------
1 | import { JobSearch } from './JobSearch';
2 |
3 | const jobSearch = new JobSearch('#search-form', '.result-container', '.loading-element');
4 | jobSearch.setCountryCode();
5 | jobSearch.configureFormListener();
6 |
--------------------------------------------------------------------------------
/api/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | APP_ID: process.env.APP_ID,
3 | API_KEY: process.env.API_KEY,
4 | BASE_URL: 'https://api.adzuna.com/v1/api/jobs',
5 | BASE_PARAMS: 'search/1?&results_per_page=20&content-type=application/json',
6 | };
7 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "job-search",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.0",
14 | "chalk": "^2.4.2"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/templates.js:
--------------------------------------------------------------------------------
1 | export const jobTemplate = (job, currency) => `
2 |
3 |
4 |
${job.title} up to ${currency}${job.salary_max}
5 |
${job.location.display_name}
6 |
${job.description}
7 |
View Job
8 |
9 |
10 | `;
--------------------------------------------------------------------------------
/frontend/src/utils.js:
--------------------------------------------------------------------------------
1 | export const extractFormData = form => Array
2 | .from(form.elements)
3 | .reduce((acc, { id, value }) => ({ [id]: value, ...acc }), {});
4 |
5 | export const getCurrencySymbol = country => {
6 | const currencies = {
7 | gb: '£',
8 | us: '$',
9 | au: '$',
10 | ca: '$',
11 | };
12 | return currencies[country];
13 | }
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "start": "node ./node_modules/parcel/bin/cli index.html",
8 | "build": "node ./node_modules/parcel/bin/cli build index.html"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "parcel": "^1.12.3"
15 | },
16 | "devDependencies": {
17 | "sass": "^1.22.12"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/src/scss/app.scss:
--------------------------------------------------------------------------------
1 | header {
2 | padding: 50px;
3 | background-image: url(../img/business.jpg);
4 | background-repeat: no-repeat;
5 | height: 400px;
6 |
7 | h2 {
8 | font-size: 1.2rem;
9 | }
10 |
11 | form {
12 | margin-top: 50px;
13 | max-width: 400px;
14 | }
15 | }
16 |
17 | .card {
18 | margin: 25px 0;
19 | }
20 |
21 | .loading-element {
22 | width: 100px;
23 | height: 100px;
24 | margin: 0 auto;
25 | display: none;
26 | &.loading {
27 | display: block;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/src/img/45.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/.cache/c3/395c7d7428ec73498eb7e0798ccd7a.json:
--------------------------------------------------------------------------------
1 | {"id":"index.html","dependencies":[{"name":"./src/app.js","dynamic":true,"resolved":"/home/bubb/dev/job-search/frontend/src/app.js","parent":"/home/bubb/dev/job-search/frontend/index.html"}],"generated":{"html":"\n\n\n \n \n \n Job Search\n\n\n \n \n \n\n"},"sourceMaps":null,"error":null,"hash":"8beeb98c67be1d565a9a0c3bcefb8bed","cacheData":{}}
--------------------------------------------------------------------------------
/frontend/.cache/94/b4209ada9b3069fbf5fb0c811b446c.json:
--------------------------------------------------------------------------------
1 | {"id":"src/app.js","dependencies":[{"name":"/home/bubb/dev/job-search/frontend/package.json","includedInParent":true,"mtime":1568645081763},{"name":"./JobSearch","loc":{"line":1,"column":26},"parent":"/home/bubb/dev/job-search/frontend/src/app.js","resolved":"/home/bubb/dev/job-search/frontend/src/JobSearch.js"}],"generated":{"js":"\"use strict\";\n\nvar _JobSearch = require(\"./JobSearch\");\n\nnew _JobSearch.JobSearch();"},"sourceMaps":{"js":{"mappings":[{"generated":{"line":3,"column":0},"source":"src/app.js","original":{"line":1,"column":0}},{"generated":{"line":5,"column":0},"source":"src/app.js","original":{"line":3,"column":0}},{"name":"JobSearch","generated":{"line":5,"column":4},"source":"src/app.js","original":{"line":3,"column":4}},{"generated":{"line":5,"column":24},"source":"src/app.js","original":{"line":3,"column":0}}],"sources":{"src/app.js":"import { JobSearch } from './JobSearch';\n\nnew JobSearch();"},"lineCount":null}},"error":null,"hash":"4cc5b2f780be11202df45020dae8adea","cacheData":{"env":{}}}
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Job Search
10 |
11 |
12 |
23 |
24 |
25 |
26 |

27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/frontend/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Job Search
10 |
11 |
12 |
23 |
24 |
25 |
26 |

27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/api/server.js:
--------------------------------------------------------------------------------
1 | const createServer = require('http').createServer;
2 | const url = require('url');
3 | const axios = require('axios');
4 | const chalk = require('chalk');
5 | const config = require('./config');
6 |
7 | const headers = {
8 | 'Content-Type': 'application/json',
9 | 'Access-Control-Allow-Origin': '*',
10 | 'Access-Control-Allow-Methods': 'GET',
11 | };
12 |
13 | const server = createServer((req, res) => {
14 | const requestURL = url.parse(req.url);
15 | const decodedParams = decodeParams(new URLSearchParams(requestURL.search));
16 | const { search, location, country = 'gb' } = decodedParams;
17 |
18 | const targetURL = `${config.BASE_URL}/${country.toLowerCase()}/${config.BASE_PARAMS}&app_id=${config.APP_ID}&app_key=${config.API_KEY}&what=${search}&where=${location}`;
19 | if (req.method === 'GET') {
20 | console.log(chalk.green(`Proxy GET request to : ${targetURL}`));
21 | axios.get(targetURL)
22 | .then(response => {
23 | res.writeHead(200, headers);
24 | res.end(JSON.stringify(response.data));
25 | })
26 | .catch(response => {
27 | console.log(chalk.red(response));
28 | res.writeHead(500, headers);
29 | res.end(JSON.stringify(response));
30 | });
31 | }
32 | });
33 |
34 |
35 | server.listen(3000, () => {
36 | console.log(chalk.green('Server listening'));
37 | } );
38 |
39 |
40 | const decodeParams = searchParams => Array
41 | .from(searchParams.keys())
42 | .reduce((acc, key) => ({ ...acc, [key]: searchParams.get(key) }), {});
--------------------------------------------------------------------------------
/frontend/src/JobSearch.js:
--------------------------------------------------------------------------------
1 | import { jobTemplate } from './templates';
2 | import { extractFormData, getCurrencySymbol } from './utils';
3 |
4 |
5 | export class JobSearch {
6 |
7 | constructor(searchFormSelector, resultsContainerSelector, loadingElementSelector) {
8 | this.searchForm = document.querySelector(searchFormSelector);
9 | this.resultsContainer = document.querySelector(resultsContainerSelector);
10 | this.loadingElement = document.querySelector(loadingElementSelector);
11 | }
12 |
13 | setCountryCode() {
14 | this.countryCode = 'gb';
15 | this.setCurrencySymbol();
16 |
17 | fetch('http://ip-api.com/json')
18 | .then(results => results.json())
19 | .then(results => {
20 | this.countryCode = results.countryCode.toLowerCase();
21 | this.setCurrencySymbol();
22 | });
23 | }
24 |
25 | setCurrencySymbol() {
26 | this.currencySymbol = getCurrencySymbol(this.countryCode);
27 | }
28 |
29 | configureFormListener() {
30 | this.searchForm.addEventListener('submit', (event) => {
31 | event.preventDefault();
32 | this.startLoading();
33 | this.resultsContainer.innerHTML = '';
34 | const { search, location } = extractFormData(this.searchForm);
35 | fetch(`http://localhost:3000/?search=${search}&location=${location}&country=${this.countryCode}`)
36 | .then(response => response.json())
37 | .then(({ results }) => {
38 | this.stopLoading();
39 | return results
40 | .map(job => jobTemplate(job, this.currencySymbol))
41 | .join('');
42 | })
43 | .then(jobs => this.resultsContainer.innerHTML = jobs)
44 | .catch(() => this.stopLoading());
45 | });
46 | }
47 |
48 | startLoading() {
49 | this.loadingElement.classList.add('loading');
50 | }
51 |
52 | stopLoading() {
53 | this.loadingElement.classList.remove('loading');
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/frontend/.cache/0e/9ed2ee4108341553c6c33d91d5cce7.json:
--------------------------------------------------------------------------------
1 | {"id":"src/templates.js","dependencies":[{"name":"/home/bubb/dev/job-search/frontend/package.json","includedInParent":true,"mtime":1568645081763}],"generated":{"js":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.jobTemplate = void 0;\n\nvar jobTemplate = function jobTemplate(job) {\n return \"\\n \".concat(job.title, \"
\\n\");\n};\n\nexports.jobTemplate = jobTemplate;"},"sourceMaps":{"js":{"mappings":[{"generated":{"line":8,"column":0},"source":"src/templates.js","original":{"line":1,"column":7}},{"name":"jobTemplate","generated":{"line":8,"column":4},"source":"src/templates.js","original":{"line":1,"column":13}},{"generated":{"line":8,"column":15},"source":"src/templates.js","original":{"line":1,"column":24}},{"generated":{"line":8,"column":18},"source":"src/templates.js","original":{"line":1,"column":27}},{"name":"jobTemplate","generated":{"line":8,"column":27},"source":"src/templates.js","original":{"line":1,"column":13}},{"generated":{"line":8,"column":38},"source":"src/templates.js","original":{"line":1,"column":27}},{"name":"job","generated":{"line":8,"column":39},"source":"src/templates.js","original":{"line":1,"column":27}},{"generated":{"line":8,"column":42},"source":"src/templates.js","original":{"line":1,"column":30}},{"generated":{"line":9,"column":0},"source":"src/templates.js","original":{"line":1,"column":30}},{"name":"job","generated":{"line":9,"column":27},"source":"src/templates.js","original":{"line":2,"column":8}},{"generated":{"line":9,"column":30},"source":"src/templates.js","original":{"line":2,"column":11}},{"name":"title","generated":{"line":9,"column":31},"source":"src/templates.js","original":{"line":2,"column":12}},{"generated":{"line":9,"column":36},"source":"src/templates.js","original":{"line":1,"column":30}},{"generated":{"line":10,"column":0},"source":"src/templates.js","original":{"line":1,"column":30}},{"generated":{"line":10,"column":1},"source":"src/templates.js","original":{"line":1,"column":7}}],"sources":{"src/templates.js":"export const jobTemplate = job => `\n ${job.title}
\n`;"},"lineCount":null}},"error":null,"hash":"cace8e648554db110569dfb16af140b3","cacheData":{"env":{}}}
--------------------------------------------------------------------------------
/api/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "job-search",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "ansi-styles": {
8 | "version": "3.2.1",
9 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
10 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
11 | "requires": {
12 | "color-convert": "^1.9.0"
13 | }
14 | },
15 | "axios": {
16 | "version": "0.19.0",
17 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
18 | "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
19 | "requires": {
20 | "follow-redirects": "1.5.10",
21 | "is-buffer": "^2.0.2"
22 | }
23 | },
24 | "chalk": {
25 | "version": "2.4.2",
26 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
27 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
28 | "requires": {
29 | "ansi-styles": "^3.2.1",
30 | "escape-string-regexp": "^1.0.5",
31 | "supports-color": "^5.3.0"
32 | }
33 | },
34 | "color-convert": {
35 | "version": "1.9.3",
36 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
37 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
38 | "requires": {
39 | "color-name": "1.1.3"
40 | }
41 | },
42 | "color-name": {
43 | "version": "1.1.3",
44 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
45 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
46 | },
47 | "debug": {
48 | "version": "3.1.0",
49 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
50 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
51 | "requires": {
52 | "ms": "2.0.0"
53 | }
54 | },
55 | "escape-string-regexp": {
56 | "version": "1.0.5",
57 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
58 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
59 | },
60 | "follow-redirects": {
61 | "version": "1.5.10",
62 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
63 | "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
64 | "requires": {
65 | "debug": "=3.1.0"
66 | }
67 | },
68 | "has-flag": {
69 | "version": "3.0.0",
70 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
71 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
72 | },
73 | "is-buffer": {
74 | "version": "2.0.3",
75 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
76 | "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
77 | },
78 | "ms": {
79 | "version": "2.0.0",
80 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
81 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
82 | },
83 | "supports-color": {
84 | "version": "5.5.0",
85 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
86 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
87 | "requires": {
88 | "has-flag": "^3.0.0"
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/frontend/dist/app.a6a4d504.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["src/templates.js","src/utils.js","src/JobSearch.js","src/app.js"],"names":["jobTemplate","job","currency","title","salary_max","location","display_name","description","redirect_url","extractFormData","form","Array","from","elements","reduce","acc","id","value","getCurrencySymbol","country","currencies","gb","us","au","ca","JobSearch","searchFormSelector","resultsContainerSelector","loadingElementSelector","searchForm","document","querySelector","resultsContainer","loadingElement","countryCode","setCurrencySymbol","fetch","then","results","json","toLowerCase","currencySymbol","addEventListener","event","preventDefault","startLoading","innerHTML","search","response","stopLoading","map","join","jobs","catch","classList","add","remove","jobSearch","setCountryCode","configureFormListener"],"mappings":"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","file":"app.a6a4d504.js","sourceRoot":"..","sourcesContent":["export const jobTemplate = (job, currency) => `\n\n
\n
${job.title} up to ${currency}${job.salary_max}
\n
${job.location.display_name}
\n
${job.description}
\n
View Job\n
\n
\n`;","export const extractFormData = form => Array\n .from(form.elements)\n .reduce((acc, { id, value }) => ({ [id]: value, ...acc }), {});\n\nexport const getCurrencySymbol = country => {\n const currencies = {\n gb: '£',\n us: '$',\n au: '$',\n ca: '$',\n };\n return currencies[country];\n}","import { jobTemplate } from './templates';\nimport { extractFormData, getCurrencySymbol } from './utils';\n\n\nexport class JobSearch {\n\n constructor(searchFormSelector, resultsContainerSelector, loadingElementSelector) {\n this.searchForm = document.querySelector(searchFormSelector);\n this.resultsContainer = document.querySelector(resultsContainerSelector);\n this.loadingElement = document.querySelector(loadingElementSelector);\n }\n\n setCountryCode() {\n this.countryCode = 'gb';\n this.setCurrencySymbol();\n\n fetch('http://ip-api.com/json')\n .then(results => results.json())\n .then(results => {\n this.countryCode = results.countryCode.toLowerCase();\n this.setCurrencySymbol();\n });\n }\n\n setCurrencySymbol() {\n this.currencySymbol = getCurrencySymbol(this.countryCode);\n }\n\n configureFormListener() {\n this.searchForm.addEventListener('submit', (event) => {\n event.preventDefault();\n this.startLoading();\n this.resultsContainer.innerHTML = '';\n const { search, location } = extractFormData(this.searchForm);\n fetch(`http://localhost:3000/?search=${search}&location=${location}&country=${this.countryCode}`)\n .then(response => response.json())\n .then(({ results }) => {\n this.stopLoading();\n return results\n .map(job => jobTemplate(job, this.currencySymbol))\n .join('');\n })\n .then(jobs => this.resultsContainer.innerHTML = jobs)\n .catch(() => this.stopLoading());\n });\n }\n\n startLoading() {\n this.loadingElement.classList.add('loading');\n }\n\n stopLoading() {\n this.loadingElement.classList.remove('loading');\n }\n}\n\n","import { JobSearch } from './JobSearch';\n\nconst jobSearch = new JobSearch('#search-form', '.result-container', '.loading-element');\njobSearch.setCountryCode();\njobSearch.configureFormListener();\n"]}
--------------------------------------------------------------------------------
/frontend/.cache/9b/3966e0131e408256dff65fff8c9b07.json:
--------------------------------------------------------------------------------
1 | {"id":"src/utils.js","dependencies":[{"name":"/home/bubb/dev/job-search/frontend/package.json","includedInParent":true,"mtime":1568645081763}],"generated":{"js":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.extractFormData = void 0;\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar extractFormData = function extractFormData(form) {\n return Array.from(form.elements).reduce(function (acc, _ref) {\n var id = _ref.id,\n value = _ref.value;\n return _objectSpread(_defineProperty({}, id, value), acc);\n }, {});\n};\n\nexports.extractFormData = extractFormData;"},"sourceMaps":{"js":{"mappings":[{"generated":{"line":14,"column":0},"source":"src/utils.js","original":{"line":1,"column":7}},{"name":"extractFormData","generated":{"line":14,"column":4},"source":"src/utils.js","original":{"line":1,"column":13}},{"generated":{"line":14,"column":19},"source":"src/utils.js","original":{"line":1,"column":28}},{"generated":{"line":14,"column":22},"source":"src/utils.js","original":{"line":1,"column":31}},{"name":"extractFormData","generated":{"line":14,"column":31},"source":"src/utils.js","original":{"line":1,"column":13}},{"generated":{"line":14,"column":46},"source":"src/utils.js","original":{"line":1,"column":31}},{"name":"form","generated":{"line":14,"column":47},"source":"src/utils.js","original":{"line":1,"column":31}},{"generated":{"line":14,"column":51},"source":"src/utils.js","original":{"line":1,"column":35}},{"generated":{"line":15,"column":0},"source":"src/utils.js","original":{"line":1,"column":35}},{"name":"Array","generated":{"line":15,"column":9},"source":"src/utils.js","original":{"line":1,"column":39}},{"generated":{"line":15,"column":14},"source":"src/utils.js","original":{"line":1,"column":44}},{"name":"from","generated":{"line":15,"column":15},"source":"src/utils.js","original":{"line":2,"column":1}},{"generated":{"line":15,"column":19},"source":"src/utils.js","original":{"line":1,"column":39}},{"name":"form","generated":{"line":15,"column":20},"source":"src/utils.js","original":{"line":2,"column":6}},{"generated":{"line":15,"column":24},"source":"src/utils.js","original":{"line":2,"column":10}},{"name":"elements","generated":{"line":15,"column":25},"source":"src/utils.js","original":{"line":2,"column":11}},{"generated":{"line":15,"column":33},"source":"src/utils.js","original":{"line":1,"column":39}},{"name":"reduce","generated":{"line":15,"column":35},"source":"src/utils.js","original":{"line":3,"column":1}},{"generated":{"line":15,"column":41},"source":"src/utils.js","original":{"line":1,"column":39}},{"generated":{"line":15,"column":42},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"acc","generated":{"line":15,"column":52},"source":"src/utils.js","original":{"line":3,"column":9}},{"generated":{"line":15,"column":55},"source":"src/utils.js","original":{"line":3,"column":8}},{"generated":{"line":16,"column":0},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"id","generated":{"line":16,"column":8},"source":"src/utils.js","original":{"line":3,"column":16}},{"generated":{"line":16,"column":10},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"id","generated":{"line":16,"column":18},"source":"src/utils.js","original":{"line":3,"column":16}},{"generated":{"line":16,"column":20},"source":"src/utils.js","original":{"line":3,"column":8}},{"generated":{"line":17,"column":0},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"value","generated":{"line":17,"column":8},"source":"src/utils.js","original":{"line":3,"column":20}},{"generated":{"line":17,"column":13},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"value","generated":{"line":17,"column":21},"source":"src/utils.js","original":{"line":3,"column":20}},{"generated":{"line":17,"column":26},"source":"src/utils.js","original":{"line":3,"column":8}},{"generated":{"line":18,"column":0},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"id","generated":{"line":18,"column":45},"source":"src/utils.js","original":{"line":3,"column":36}},{"generated":{"line":18,"column":47},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"value","generated":{"line":18,"column":49},"source":"src/utils.js","original":{"line":3,"column":41}},{"generated":{"line":18,"column":54},"source":"src/utils.js","original":{"line":3,"column":8}},{"name":"acc","generated":{"line":18,"column":57},"source":"src/utils.js","original":{"line":3,"column":51}},{"generated":{"line":18,"column":60},"source":"src/utils.js","original":{"line":3,"column":8}},{"generated":{"line":19,"column":0},"source":"src/utils.js","original":{"line":3,"column":8}},{"generated":{"line":19,"column":3},"source":"src/utils.js","original":{"line":1,"column":39}},{"generated":{"line":19,"column":5},"source":"src/utils.js","original":{"line":3,"column":59}},{"generated":{"line":19,"column":7},"source":"src/utils.js","original":{"line":1,"column":39}},{"generated":{"line":19,"column":8},"source":"src/utils.js","original":{"line":1,"column":35}},{"generated":{"line":20,"column":0},"source":"src/utils.js","original":{"line":1,"column":35}},{"generated":{"line":20,"column":1},"source":"src/utils.js","original":{"line":1,"column":7}}],"sources":{"src/utils.js":"export const extractFormData = form => Array\n.from(form.elements)\n.reduce((acc, { id, value }) => ({ [id]: value, ...acc }), {});"},"lineCount":null}},"error":null,"hash":"c639f8a9c00cefaf896ddc60010b9936","cacheData":{"env":{}}}
--------------------------------------------------------------------------------
/frontend/.cache/d3/d633b5f1caf367b2188ffb60a62787.json:
--------------------------------------------------------------------------------
1 | {"id":"src/JobSearch.js","dependencies":[{"name":"/home/bubb/dev/job-search/frontend/package.json","includedInParent":true,"mtime":1568645081763},{"name":"./templates","loc":{"line":1,"column":28},"parent":"/home/bubb/dev/job-search/frontend/src/JobSearch.js","resolved":"/home/bubb/dev/job-search/frontend/src/templates.js"},{"name":"./utils","loc":{"line":2,"column":32},"parent":"/home/bubb/dev/job-search/frontend/src/JobSearch.js","resolved":"/home/bubb/dev/job-search/frontend/src/utils.js"}],"generated":{"js":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.JobSearch = void 0;\n\nvar _templates = require(\"./templates\");\n\nvar _utils = require(\"./utils\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar JobSearch =\n/*#__PURE__*/\nfunction () {\n function JobSearch() {\n _classCallCheck(this, JobSearch);\n\n this.searchForm = document.querySelector('#search-form');\n this.resultContainer = document.querySelector('.result-container');\n this.configureFormListener();\n }\n\n _createClass(JobSearch, [{\n key: \"configureFormListener\",\n value: function configureFormListener() {\n var _this = this;\n\n this.searchForm.addEventListener('submit', function (event) {\n event.preventDefault();\n\n var _extractFormData = (0, _utils.extractFormData)(_this.searchForm),\n search = _extractFormData.search,\n location = _extractFormData.location;\n\n fetch(\"http://localhost:3000/?search=\".concat(search, \"&location=\").concat(location)).then(function (response) {\n return response.json();\n }).then(function (_ref) {\n var results = _ref.results;\n return results.map(_templates.jobTemplate).join('');\n }).then(function (jobs) {\n return _this.resultContainer.innerHTML = jobs;\n });\n });\n }\n }]);\n\n return JobSearch;\n}();\n\nexports.JobSearch = JobSearch;"},"sourceMaps":{"js":{"mappings":[{"generated":{"line":8,"column":0},"source":"src/JobSearch.js","original":{"line":1,"column":0}},{"generated":{"line":10,"column":0},"source":"src/JobSearch.js","original":{"line":2,"column":0}},{"name":"JobSearch","generated":{"line":18,"column":4},"source":"src/JobSearch.js","original":{"line":5,"column":13}},{"generated":{"line":21,"column":0},"source":"src/JobSearch.js","original":{"line":7,"column":2}},{"generated":{"line":21,"column":23},"source":"src/JobSearch.js","original":{"line":7,"column":16}},{"generated":{"line":22,"column":0},"source":"src/JobSearch.js","original":{"line":7,"column":16}},{"generated":{"line":24,"column":0},"source":"src/JobSearch.js","original":{"line":8,"column":4}},{"name":"searchForm","generated":{"line":24,"column":9},"source":"src/JobSearch.js","original":{"line":8,"column":9}},{"generated":{"line":24,"column":19},"source":"src/JobSearch.js","original":{"line":8,"column":4}},{"name":"document","generated":{"line":24,"column":22},"source":"src/JobSearch.js","original":{"line":8,"column":22}},{"generated":{"line":24,"column":30},"source":"src/JobSearch.js","original":{"line":8,"column":30}},{"name":"querySelector","generated":{"line":24,"column":31},"source":"src/JobSearch.js","original":{"line":8,"column":31}},{"generated":{"line":24,"column":44},"source":"src/JobSearch.js","original":{"line":8,"column":22}},{"generated":{"line":24,"column":45},"source":"src/JobSearch.js","original":{"line":8,"column":45}},{"generated":{"line":24,"column":59},"source":"src/JobSearch.js","original":{"line":8,"column":22}},{"generated":{"line":24,"column":60},"source":"src/JobSearch.js","original":{"line":8,"column":4}},{"generated":{"line":25,"column":0},"source":"src/JobSearch.js","original":{"line":9,"column":4}},{"name":"resultContainer","generated":{"line":25,"column":9},"source":"src/JobSearch.js","original":{"line":9,"column":9}},{"generated":{"line":25,"column":24},"source":"src/JobSearch.js","original":{"line":9,"column":4}},{"name":"document","generated":{"line":25,"column":27},"source":"src/JobSearch.js","original":{"line":9,"column":27}},{"generated":{"line":25,"column":35},"source":"src/JobSearch.js","original":{"line":9,"column":35}},{"name":"querySelector","generated":{"line":25,"column":36},"source":"src/JobSearch.js","original":{"line":9,"column":36}},{"generated":{"line":25,"column":49},"source":"src/JobSearch.js","original":{"line":9,"column":27}},{"generated":{"line":25,"column":50},"source":"src/JobSearch.js","original":{"line":9,"column":50}},{"generated":{"line":25,"column":69},"source":"src/JobSearch.js","original":{"line":9,"column":27}},{"generated":{"line":25,"column":70},"source":"src/JobSearch.js","original":{"line":9,"column":4}},{"generated":{"line":26,"column":0},"source":"src/JobSearch.js","original":{"line":10,"column":4}},{"name":"configureFormListener","generated":{"line":26,"column":9},"source":"src/JobSearch.js","original":{"line":10,"column":9}},{"generated":{"line":26,"column":30},"source":"src/JobSearch.js","original":{"line":10,"column":4}},{"generated":{"line":27,"column":0},"source":"src/JobSearch.js","original":{"line":11,"column":3}},{"generated":{"line":31,"column":44},"source":"src/JobSearch.js","original":{"line":13,"column":24}},{"generated":{"line":32,"column":0},"source":"src/JobSearch.js","original":{"line":13,"column":24}},{"generated":{"line":34,"column":0},"source":"src/JobSearch.js","original":{"line":14,"column":2}},{"name":"searchForm","generated":{"line":34,"column":11},"source":"src/JobSearch.js","original":{"line":14,"column":7}},{"generated":{"line":34,"column":21},"source":"src/JobSearch.js","original":{"line":14,"column":2}},{"name":"addEventListener","generated":{"line":34,"column":22},"source":"src/JobSearch.js","original":{"line":14,"column":18}},{"generated":{"line":34,"column":38},"source":"src/JobSearch.js","original":{"line":14,"column":2}},{"generated":{"line":34,"column":39},"source":"src/JobSearch.js","original":{"line":14,"column":35}},{"generated":{"line":34,"column":47},"source":"src/JobSearch.js","original":{"line":14,"column":2}},{"generated":{"line":34,"column":49},"source":"src/JobSearch.js","original":{"line":14,"column":45}},{"name":"event","generated":{"line":34,"column":59},"source":"src/JobSearch.js","original":{"line":14,"column":46}},{"generated":{"line":34,"column":64},"source":"src/JobSearch.js","original":{"line":14,"column":45}},{"generated":{"line":34,"column":66},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"event","generated":{"line":35,"column":0},"source":"src/JobSearch.js","original":{"line":15,"column":4}},{"name":"event","generated":{"line":35,"column":8},"source":"src/JobSearch.js","original":{"line":15,"column":4}},{"generated":{"line":35,"column":13},"source":"src/JobSearch.js","original":{"line":15,"column":9}},{"name":"preventDefault","generated":{"line":35,"column":14},"source":"src/JobSearch.js","original":{"line":15,"column":10}},{"generated":{"line":35,"column":28},"source":"src/JobSearch.js","original":{"line":15,"column":4}},{"generated":{"line":37,"column":0},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"generated":{"line":37,"column":31},"source":"src/JobSearch.js","original":{"line":16,"column":33}},{"generated":{"line":37,"column":59},"source":"src/JobSearch.js","original":{"line":16,"column":49}},{"generated":{"line":37,"column":64},"source":"src/JobSearch.js","original":{"line":16,"column":53}},{"name":"searchForm","generated":{"line":37,"column":65},"source":"src/JobSearch.js","original":{"line":16,"column":54}},{"generated":{"line":37,"column":75},"source":"src/JobSearch.js","original":{"line":16,"column":33}},{"generated":{"line":37,"column":76},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"generated":{"line":38,"column":0},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"search","generated":{"line":38,"column":12},"source":"src/JobSearch.js","original":{"line":16,"column":12}},{"generated":{"line":38,"column":18},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"search","generated":{"line":38,"column":38},"source":"src/JobSearch.js","original":{"line":16,"column":12}},{"generated":{"line":38,"column":44},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"generated":{"line":39,"column":0},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"location","generated":{"line":39,"column":12},"source":"src/JobSearch.js","original":{"line":16,"column":20}},{"generated":{"line":39,"column":20},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"location","generated":{"line":39,"column":40},"source":"src/JobSearch.js","original":{"line":16,"column":20}},{"generated":{"line":39,"column":48},"source":"src/JobSearch.js","original":{"line":14,"column":56}},{"name":"fetch","generated":{"line":41,"column":0},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"name":"fetch","generated":{"line":41,"column":8},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"generated":{"line":41,"column":13},"source":"src/JobSearch.js","original":{"line":17,"column":9}},{"name":"search","generated":{"line":41,"column":54},"source":"src/JobSearch.js","original":{"line":17,"column":43}},{"generated":{"line":41,"column":60},"source":"src/JobSearch.js","original":{"line":17,"column":9}},{"name":"location","generated":{"line":41,"column":83},"source":"src/JobSearch.js","original":{"line":17,"column":62}},{"generated":{"line":41,"column":91},"source":"src/JobSearch.js","original":{"line":17,"column":9}},{"generated":{"line":41,"column":93},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"name":"then","generated":{"line":41,"column":94},"source":"src/JobSearch.js","original":{"line":18,"column":5}},{"generated":{"line":41,"column":98},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"generated":{"line":41,"column":99},"source":"src/JobSearch.js","original":{"line":18,"column":10}},{"name":"response","generated":{"line":41,"column":109},"source":"src/JobSearch.js","original":{"line":18,"column":10}},{"generated":{"line":41,"column":117},"source":"src/JobSearch.js","original":{"line":18,"column":18}},{"generated":{"line":42,"column":0},"source":"src/JobSearch.js","original":{"line":18,"column":18}},{"name":"response","generated":{"line":42,"column":17},"source":"src/JobSearch.js","original":{"line":18,"column":22}},{"generated":{"line":42,"column":25},"source":"src/JobSearch.js","original":{"line":18,"column":30}},{"name":"json","generated":{"line":42,"column":26},"source":"src/JobSearch.js","original":{"line":18,"column":31}},{"generated":{"line":42,"column":30},"source":"src/JobSearch.js","original":{"line":18,"column":22}},{"generated":{"line":42,"column":32},"source":"src/JobSearch.js","original":{"line":18,"column":18}},{"generated":{"line":43,"column":0},"source":"src/JobSearch.js","original":{"line":18,"column":18}},{"generated":{"line":43,"column":9},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"name":"then","generated":{"line":43,"column":11},"source":"src/JobSearch.js","original":{"line":19,"column":5}},{"generated":{"line":43,"column":15},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"generated":{"line":43,"column":16},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"generated":{"line":44,"column":0},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"name":"results","generated":{"line":44,"column":14},"source":"src/JobSearch.js","original":{"line":19,"column":13}},{"generated":{"line":44,"column":21},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"name":"results","generated":{"line":44,"column":29},"source":"src/JobSearch.js","original":{"line":19,"column":13}},{"generated":{"line":44,"column":36},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"generated":{"line":45,"column":0},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"name":"results","generated":{"line":45,"column":17},"source":"src/JobSearch.js","original":{"line":19,"column":27}},{"generated":{"line":45,"column":24},"source":"src/JobSearch.js","original":{"line":19,"column":34}},{"name":"map","generated":{"line":45,"column":25},"source":"src/JobSearch.js","original":{"line":19,"column":35}},{"generated":{"line":45,"column":28},"source":"src/JobSearch.js","original":{"line":19,"column":27}},{"name":"jobTemplate","generated":{"line":45,"column":29},"source":"src/JobSearch.js","original":{"line":19,"column":39}},{"generated":{"line":45,"column":51},"source":"src/JobSearch.js","original":{"line":19,"column":27}},{"name":"join","generated":{"line":45,"column":53},"source":"src/JobSearch.js","original":{"line":19,"column":52}},{"generated":{"line":45,"column":57},"source":"src/JobSearch.js","original":{"line":19,"column":27}},{"generated":{"line":45,"column":58},"source":"src/JobSearch.js","original":{"line":19,"column":57}},{"generated":{"line":45,"column":60},"source":"src/JobSearch.js","original":{"line":19,"column":27}},{"generated":{"line":45,"column":61},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"generated":{"line":46,"column":0},"source":"src/JobSearch.js","original":{"line":19,"column":10}},{"generated":{"line":46,"column":9},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"name":"then","generated":{"line":46,"column":11},"source":"src/JobSearch.js","original":{"line":20,"column":5}},{"generated":{"line":46,"column":15},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"generated":{"line":46,"column":16},"source":"src/JobSearch.js","original":{"line":20,"column":10}},{"name":"jobs","generated":{"line":46,"column":26},"source":"src/JobSearch.js","original":{"line":20,"column":10}},{"generated":{"line":46,"column":30},"source":"src/JobSearch.js","original":{"line":20,"column":14}},{"generated":{"line":47,"column":0},"source":"src/JobSearch.js","original":{"line":20,"column":14}},{"generated":{"line":47,"column":17},"source":"src/JobSearch.js","original":{"line":20,"column":18}},{"generated":{"line":47,"column":22},"source":"src/JobSearch.js","original":{"line":20,"column":22}},{"name":"resultContainer","generated":{"line":47,"column":23},"source":"src/JobSearch.js","original":{"line":20,"column":23}},{"generated":{"line":47,"column":38},"source":"src/JobSearch.js","original":{"line":20,"column":18}},{"name":"innerHTML","generated":{"line":47,"column":39},"source":"src/JobSearch.js","original":{"line":20,"column":39}},{"generated":{"line":47,"column":48},"source":"src/JobSearch.js","original":{"line":20,"column":18}},{"name":"jobs","generated":{"line":47,"column":51},"source":"src/JobSearch.js","original":{"line":20,"column":51}},{"generated":{"line":47,"column":55},"source":"src/JobSearch.js","original":{"line":20,"column":14}},{"generated":{"line":48,"column":0},"source":"src/JobSearch.js","original":{"line":20,"column":14}},{"generated":{"line":48,"column":9},"source":"src/JobSearch.js","original":{"line":17,"column":4}},{"generated":{"line":49,"column":0},"source":"src/JobSearch.js","original":{"line":21,"column":3}},{"generated":{"line":49,"column":7},"source":"src/JobSearch.js","original":{"line":14,"column":2}},{"generated":{"line":50,"column":0},"source":"src/JobSearch.js","original":{"line":22,"column":1}}],"sources":{"src/JobSearch.js":"import { jobTemplate } from './templates';\nimport { extractFormData } from './utils';\n\n\nexport class JobSearch {\n \n constructor() {\n this.searchForm = document.querySelector('#search-form');\n this.resultContainer = document.querySelector('.result-container');\n this.configureFormListener();\n }\n\nconfigureFormListener() {\n this.searchForm.addEventListener('submit', (event) => {\n event.preventDefault();\n const { search, location } = extractFormData(this.searchForm);\n fetch(`http://localhost:3000/?search=${search}&location=${location}`)\n .then(response => response.json())\n .then(({ results }) => results.map(jobTemplate).join(''))\n .then(jobs => this.resultContainer.innerHTML = jobs);\n });\n}\n}\n\n"},"lineCount":null}},"error":null,"hash":"b27e51f6c91611e81a87b94db262b55a","cacheData":{"env":{}}}
--------------------------------------------------------------------------------
/frontend/dist/app.a6a4d504.js:
--------------------------------------------------------------------------------
1 | // modules are defined as an array
2 | // [ module function, map of requires ]
3 | //
4 | // map of requires is short require name -> numeric require
5 | //
6 | // anything defined in a previous bundle is accessed via the
7 | // orig method which is the require for previous bundles
8 | parcelRequire = (function (modules, cache, entry, globalName) {
9 | // Save the require from previous bundle to this closure if any
10 | var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
11 | var nodeRequire = typeof require === 'function' && require;
12 |
13 | function newRequire(name, jumped) {
14 | if (!cache[name]) {
15 | if (!modules[name]) {
16 | // if we cannot find the module within our internal map or
17 | // cache jump to the current global require ie. the last bundle
18 | // that was added to the page.
19 | var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
20 | if (!jumped && currentRequire) {
21 | return currentRequire(name, true);
22 | }
23 |
24 | // If there are other bundles on this page the require from the
25 | // previous one is saved to 'previousRequire'. Repeat this as
26 | // many times as there are bundles until the module is found or
27 | // we exhaust the require chain.
28 | if (previousRequire) {
29 | return previousRequire(name, true);
30 | }
31 |
32 | // Try the node require function if it exists.
33 | if (nodeRequire && typeof name === 'string') {
34 | return nodeRequire(name);
35 | }
36 |
37 | var err = new Error('Cannot find module \'' + name + '\'');
38 | err.code = 'MODULE_NOT_FOUND';
39 | throw err;
40 | }
41 |
42 | localRequire.resolve = resolve;
43 | localRequire.cache = {};
44 |
45 | var module = cache[name] = new newRequire.Module(name);
46 |
47 | modules[name][0].call(module.exports, localRequire, module, module.exports, this);
48 | }
49 |
50 | return cache[name].exports;
51 |
52 | function localRequire(x){
53 | return newRequire(localRequire.resolve(x));
54 | }
55 |
56 | function resolve(x){
57 | return modules[name][1][x] || x;
58 | }
59 | }
60 |
61 | function Module(moduleName) {
62 | this.id = moduleName;
63 | this.bundle = newRequire;
64 | this.exports = {};
65 | }
66 |
67 | newRequire.isParcelRequire = true;
68 | newRequire.Module = Module;
69 | newRequire.modules = modules;
70 | newRequire.cache = cache;
71 | newRequire.parent = previousRequire;
72 | newRequire.register = function (id, exports) {
73 | modules[id] = [function (require, module) {
74 | module.exports = exports;
75 | }, {}];
76 | };
77 |
78 | var error;
79 | for (var i = 0; i < entry.length; i++) {
80 | try {
81 | newRequire(entry[i]);
82 | } catch (e) {
83 | // Save first error but execute all entries
84 | if (!error) {
85 | error = e;
86 | }
87 | }
88 | }
89 |
90 | if (entry.length) {
91 | // Expose entry point to Node, AMD or browser globals
92 | // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
93 | var mainExports = newRequire(entry[entry.length - 1]);
94 |
95 | // CommonJS
96 | if (typeof exports === "object" && typeof module !== "undefined") {
97 | module.exports = mainExports;
98 |
99 | // RequireJS
100 | } else if (typeof define === "function" && define.amd) {
101 | define(function () {
102 | return mainExports;
103 | });
104 |
105 | //