From 6e0cd18923913fd754d69457543787251162d31c Mon Sep 17 00:00:00 2001 From: LFeh Date: Tue, 25 Sep 2018 19:35:48 -0300 Subject: [PATCH] Add new project using webpack --- .editorconfig | 13 +++ .eslintrc.js | 26 ++++++ .gitignore | 6 +- .stylintrc | 62 +++++++++++++ .travis.yml | 10 +++ README.md | 82 ++++++++++++----- app.config.json | 10 +++ license | 21 +++++ package.json | 75 ++++++++++++++++ postcss.config.js | 22 +++++ src/app.js | 12 +++ src/app.styl | 2 + src/favicon.ico | Bin 0 -> 1150 bytes src/images/logo.png | Bin 0 -> 22932 bytes src/index.pug | 40 +++++++++ src/js/main.js | 0 src/styles/base.styl | 31 +++++++ src/styles/core.styl | 2 + src/styles/core/variables.styl | 73 +++++++++++++++ webpack.config.js | 157 +++++++++++++++++++++++++++++++++ 20 files changed, 619 insertions(+), 25 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintrc.js create mode 100644 .stylintrc create mode 100644 .travis.yml create mode 100644 app.config.json create mode 100644 license create mode 100644 package.json create mode 100644 postcss.config.js create mode 100644 src/app.js create mode 100644 src/app.styl create mode 100644 src/favicon.ico create mode 100644 src/images/logo.png create mode 100644 src/index.pug create mode 100644 src/js/main.js create mode 100644 src/styles/base.styl create mode 100644 src/styles/core.styl create mode 100644 src/styles/core/variables.styl create mode 100644 webpack.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6e87a00 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..375b9af --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,26 @@ +module.exports = { + env: { + browser: true, + es6: true, + jquery: true + }, + globals: { + "fetch": false, + "window": true, + "document": true + }, + extends: 'eslint:recommended', + parserOptions: { + sourceType: 'module' + }, + rules: { + indent: ['error', 2], + 'no-unused-vars': [1, { vars: 'local', args: 'none' }], + 'linebreak-style': 'off', + quotes: ['error', 'single'], + semi: ['error', 'always'] + }, + env: { + node: true + } +}; diff --git a/.gitignore b/.gitignore index 40b878d..ec26407 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -node_modules/ \ No newline at end of file +dist +node_modules +package-lock.json +.DS_Store +.vscode/settings.json diff --git a/.stylintrc b/.stylintrc new file mode 100644 index 0000000..021eb5c --- /dev/null +++ b/.stylintrc @@ -0,0 +1,62 @@ +{ + "blocks": false, + "brackets": { + "expect": "never", + "error": true + }, + "colons": { + "expect": "never", + "error": true + }, + "colors": "always", + "commaSpace": "aways", + "commentSpace": "always", + "cssLiteral": "never", + "customProperties": [], + "depthLimit": { + "expect": 3, + "error": true + }, + "duplicates": true, + "efficient": "always", + "extendPref": false, + "globalDupe": false, + "groupOutputByFile": true, + "indentPref": { + "expect": 2, + "error": true + }, + "leadingZero": "never", + "maxErrors": false, + "maxWarnings": false, + "mixed": false, + "mixins": [], + "namingConvention": false, + "namingConventionStrict": false, + "none": "never", + "noImportant": false, + "parenSpace": false, + "placeholders": "always", + "prefixVarsWithDollar": "always", + "quotePref": false, + "reporterOptions": { + "columns": ["lineData", "severity", "description", "rule"], + "columnSplitter": " ", + "showHeaders": false, + "truncate": true + }, + "semicolons": { + "expect": "never", + "error": true + }, + "sortOrder": { + "expect": "alphabetical", + "error": true + }, + "stackedProperties": "never", + "trailingWhitespace": false, + "universal": false, + "valid": false, + "zeroUnits": "never", + "zIndexNormalize": false +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9ba9abc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - "7" +before_script: + - npm i +cache: + directories: + - "node_modules" +script: + - npm run deploy diff --git a/README.md b/README.md index c3a90dd..d3b52c4 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,73 @@ -Survey - Front-End -======= +

+ +

-Pesquisa de mercado realizada entre front-end developers do Brasil. +# Survey Front-end Brasil -[Visualizar o projeto](http://www.felipefialho.com/survey) +> Pesquisa salarial entre frontenders do Brasil -## Contribuição +[![license](https://img.shields.io/github/license/LFeh/survey.svg)](./license.md) +[![GitHub contributors](https://img.shields.io/github/contributors/LFeh/survey.svg)](https://github.com/LFeh/survey/graphs/contributors) -Por favor leia o [Coding Style](https://github.com/LFeh/coding-style/) para [Issues](https://github.com/LFeh/survey/issues) e as regras de código. +## Getting Started -Todas as alterações devem ser feitas na pasta `/dev`. O CSS precisa ser modificado usando o pré-processador **LESS**. +```sh +# install dependencies +$ npm i -Issues e commits devem ser enviados em pt-BR. +# Run the project +$ npm start +``` - ```bash +With the commands above, you have everything to start. + +## About CSS + +### Post CSS libs - # Getting Started - # --------------- +For grid system uses [Autoprefixer](https://github.com/postcss/autoprefixer) to make easy use browser prefixes, [Lost](https://github.com/peterramsing/lost) with some help from, [Rucksack](http://simplaio.github.io/rucksack/) for animations, reset and a lot of great mixins, [Rupture](https://github.com/jenius/rupture) for responsive utilities. And [Font Magician](https://github.com/jonathantneal/postcss-font-magician/) to get the webfonts. - # 1. Fork esse repositório e clone - git clone https://github.com//survey.git +### CSS Modules - # 2. Navegue até a nova pasta - cd survey +To make easier create your components and avoid a lot of problems, it boilerplate use [CSS Modules](https://github.com/css-modules/css-modules). - # 3. Instale as dependências - npm install +Example +```css +.host + text-align center - # Development - # ----------- +.title + font-size 4rem - # Para assistir as alterações no .less e no .js rode o comando - grunt w +.description + font-size 2rem +``` - # Build o projeto para deploy - grunt build - ``` +After the transformation it will become like this + +```css +._host_4897k_1 { + text-align: center; +} + +._title_4897k_9 { + font-size: 4rem; +} + +._description_4897k_12 { + font-size: 2rem; +} +``` + +## Tasks + +- `npm start`: run all tasks and initialize watch for changes and a server +- `npm run build`: run all production tasks create a `dist` folder to deploy +- `npm run lint`: lint javascript and css +- `npm run fix`: command to fix all eslint errors +- `npm run deploy`: run all tasks to build and deploy on gh-pages + +## License + +MIT License © Felipe Fialho diff --git a/app.config.json b/app.config.json new file mode 100644 index 0000000..20395c7 --- /dev/null +++ b/app.config.json @@ -0,0 +1,10 @@ +{ + "title": "Survey - Front-End Brasil 2018", + "description": "Pesquisa salarial entre frontenders do Brasil", + "url": "https://github.com/LFeh/survey", + "logo": "images/logo.png", + "theme_color": "#333333", + "short_name": "Survey 2018", + "ga": "UA-40410936-3", + "twitter": "@lfeh" +} diff --git a/license b/license new file mode 100644 index 0000000..6afa163 --- /dev/null +++ b/license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Felipe Fialho + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..6501f06 --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "survey", + "version": "2.0.0", + "title": "Survey", + "description": "Pesquisa salarial entre frontenders do Brasil", + "homepage": "https://github.com/LFeh/survey", + "browserslist": [ + "> 1%", + "last 2 versions" + ], + "author": { + "name": "Felipe Fialho", + "email": "hi@felipefialho.com", + "url": "http://www.felipefialho.com" + }, + "scripts": { + "start": "webpack-dev-server --mode development", + "build": "webpack --mode production", + "deploy": "gh-pages-deploy", + "analyzer": "npm run build && webpack-bundle-analyzer ./dist/stats.json", + "lint": "npm run lint:js && npm run lint:styl", + "lint:styl": "stylint src/**/*.styl", + "lint:scss": "sass-lint -c sass-lint.json 'src/**/*.scss' -v -q", + "lint:js": "eslint ./src/", + "fix:js": "eslint ./src/ --fix", + "precommit": "npm run lint" + }, + "gh-pages-deploy": { + "staticpath": "dist", + "prep": [ + "build" + ], + "noprompt": true + }, + "dependencies": {}, + "devDependencies": { + "autoprefixer": "^9.0.0", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.5", + "babel-preset-env": "^1.7.0", + "clean-webpack-plugin": "^0.1.19", + "copy-webpack-plugin": "^4.5.2", + "css-loader": "^1.0.0", + "cssnano": "^4.0.2", + "eslint": "^5.1.0", + "file-loader": "1.1.11", + "gh-pages-deploy": "^0.5.0", + "html-webpack-plugin": "^3.2.0", + "imagemin-webpack-plugin": "^2.1.5", + "lost": "^8.3.0", + "mini-css-extract-plugin": "^0.4.1", + "node-sass": "^4.9.2", + "offline-plugin": "^5.0.5", + "postcss-font-magician": "^2.2.1", + "postcss-loader": "^2.1.6", + "postcss-modules": "^1.1.0", + "pug": "^2.0.3", + "pug-loader": "^2.4.0", + "rucksack-css": "^1.0.2", + "rupture": "^0.7.1", + "rupture-sass": "^0.3.0", + "sass-lint": "^1.12.1", + "sass-loader": "^7.0.3", + "style-loader": "^0.21.0", + "stylint": "^1.5.9", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "uglifyjs-webpack-plugin": "^1.2.7", + "webpack": "^4.16.1", + "webpack-bundle-analyzer": "^2.13.1", + "webpack-cli": "^3.0.8", + "webpack-dev-server": "^3.1.4", + "webpack-pwa-manifest": "^3.6.2" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..e698775 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,22 @@ +module.exports = { + plugins: { + 'autoprefixer': {}, + 'rucksack-css': {}, + 'lost': {}, + 'postcss-font-magician': {}, + 'cssnano': {}, + 'postcss-modules': { + getJSON: function(cssFileName, json, outputFileName) { + const fs = require('fs'); + const path = require('path'); + const isComponent = /components/.test(path.dirname(cssFileName)); + + if (isComponent) { + const cssName = path.basename(`${cssFileName}`); + const jsonFileName = path.resolve(`${path.dirname(cssFileName)}/${cssName.split('.')[0]}-css.json`); + fs.writeFileSync(jsonFileName, JSON.stringify(json)); + } + } + } + } +}; diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..7525b69 --- /dev/null +++ b/src/app.js @@ -0,0 +1,12 @@ +import * as offline from 'offline-plugin/runtime'; +import './app.styl'; +import './components/welcome/welcome.js'; +import './components/introduction/introduction.js'; +import './components/footer/footer.js'; + + +offline.install({ + onUpdateReady: function() { + offline.applyUpdate(); + } +}); diff --git a/src/app.styl b/src/app.styl new file mode 100644 index 0000000..5fb1b16 --- /dev/null +++ b/src/app.styl @@ -0,0 +1,2 @@ +@import 'styles/core'; +@import 'styles/base'; diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4f131def63261334f847e12f4fdc2a7629f2760c GIT binary patch literal 1150 zcmc&z&rcIk5Z=;~NW3&^8YMBon+dcBNgAy{VmS2=F?cf^YmhenBJo1f3y7p}@uoye z1pzI!loVs)K?q8J(b53bO47!(yKh_iIq$8nDT$su_%`!)ciwz6^Ua%46casGt3rF1 za?7G9Hbqe`laPuuhMr!ELT6`A8zTN`1Fc4*fqZ@snM@kG&bX?%_*uDpgrgsaU`%W3 zTR#|M7#QeB=Y{h~r_tBa$A|N2KfkMD3e(B9sTWHKpiPU2?}Uhoor=dXCX-42Vz@?Y?rzl<;W*XwnW ztE%e6U*<3Q8?_Y%wCTFu#HUgzp_cqLR>#KLtl*#DGiuXXf3;dcsdR*%o*uz}YwI&= zHAZ*MpjN9W6uu+2I!*QW;mh_X>V==ER4OtwhK6pUv(tu-j#Dt1Ot{o_k^0~qrluyb zy%|C9`3P2*#t>b3gyql}LUTU6TYB~z-+;&Cfy;FrR;v|lZEfi5>xa|n#N^}zQac-1 z3r`>x9w+=m#NR)~dgKY#qc58AIZrO~{&TsUIIGoa&@_fpS)=;Riu`vo2{0YRO&2{c zop4*%wX4LR_n*-tvVKgjQ~w6=_Vp-|iA@1%t)IN72lsv8<1{>c8->Gtq*DoGcQeBN z`u~@|7ydNu}5xfcB z!&1;o^Yj?yQt3oK2M7D`dGEsQb_?G|l+O@IU+qLQlef(xudq^j+U~^nXG*d^USR z`NyqI!Y4_6-w*w;A=z%X!!W>i;0LQu_4_UjTur!?vNSI*@IS85eh-%ye&jDqSsD3P z{(&nf7Za97R%hZH3qM8D)q%^{^CH2QNtcJ7HCJyfxbI}!BJfAFG-Yk*A6TCOe)P`O z>AxmEVd;3K8IQBdBmhN_$cpPy`TJ@=(eLA*PUQ(^2T|QTaSqcQ!!*fT@ZhiT>4B<8 z13Vku8+PS&S^gx5@~18z6K^5gjek^rSzwtBp5vxbB z!XM)*>hB9dwCsJ_-xD6yd>iS67MTdL{L4jquHkc`MJLgs)2Kk@KY`j7IL9ByVM1(~_Xk^6} zK|)XJyELV4L~AIGBbZX%D-bOY z=r^L6QpqqM?OP6_+0K#rJ%7#xS|~!*diY&AJ;gMgM?H_=!H63_3rNMjHT5ayX$)qa z(oz%TCcURyoE4U49W#M@yWg@ZzRGJI6Pf1?r2g^ zG_4xC%Oioo2rd)(OKjSjVx_<5EtS=KDyaTc25{wE>#CR~sD?fMHxoGF{DdQO&o}sz z-AM65So0BrvR;C+KyE9r7A@d}#}V(N;4{WT+QoWx&O+%QW#}%v0ddyokmG-|zzI!KqKIBto|Th;9l;Qt)f-&Z z$xG%*IEjhx8L|8)xJ<-A2x*k)|FnY7>a4AFW#T_WLSkSQ?`$^Qg)?erIkXE@&)o_i zv@Uwg*gBD}EBwGj2PiHOAEHd@v3-M=xg1h~kEl@eW-%cOUxY{HB)5q7szq7lX8kjL zOCil1$vi60A9*{0nWgPrthQl9LIkZr@( z4J-`)w%D^VI?d$38J+Dc7==G#l#&*WrbY2N2(kG696G`$Ub&p@;uX!$+S{x&y0KPF zaqjrzuxXt`*>cmw%QuVpl#I_m(aibNAX>OtRcE^DY=9CugeUZlmFM%X=jUI)2&B(1 zq*&?ag3_!3m}B&uoePsGXo064_JM6$SQLh5rv$rINBSxJ)aDtS8P~AgaNe ziM-{}xUK=W0~kJihdAZ14xFTjIbEGoP}=`d`cvJNiCq^ydilo74B#XSiu5PK6YvT0 zOgHpMUtUO&?j?H0&*v;Oe?h$itU5uJwnCJ)QeYD&xq#cc6-wYW#Yxbl@S4WjwhwTM zJm{94g;Uu~TiOeo&7Aw*D3GN3`OZM~EV{CBa$L$i!*b>=j!Yi?qIjW-&*FQK^MK%l zhciCJj|vcr#?%&DSJ9M7v!M#js6|QHvXM;2GWnl~(!|dhYRf4XwHff~$crH(E0T5F z#Q+c;yQwD|jd$7r|HC4V!-m7z6C9&`7>Wh(wX|pnQZp<`_Np^^y~&D2=LWPT=}*Sy z&tE@(5>9`<{DN=4?A6?5>c>v~I$|C@KC2*}QjY$YlUc7ZuBSt=5}@Bf-AQ_Lg8}d@ z<|u3*wk*4chsV8qA~||w18-5M&RY(*510_ztRE_(OmwQhEuTjbZGDe%kl_Mj#4c?KjhA-e@o!_W|0|Uxh9*yCw^x~_}o2{{`~n9@yP;Tp(1@Ihzd&g!p=IBz7j>qLLrt_U3!=r zy*$PbvzA5eiTEUNK0LsUeCa1 zWF{+D&uBE7XF@5whdDAz13`3(eFR;a;1dm92l(8>I^y~ae8NXwV)A27&pGLT3lLVR zSh-5c;vFDrQ#1M`cMLfpjC{V(m(N7nvJ3i)g~0ja$B$n>MVEs4yL(}Xic@N~S=MZX zqfs9`s&g@o4tUzv33o{(BNfVqtswIe<>7H>_~hHDF$oJs2tI{9?z^13k6D)^2LUrR zlf&oE)<_6jIz5>kAe8R$a-#viXQMZhzm0BWmSASeVqWHulspw|MxSAn3$GhIxl9cA(0vmV1>gF)&$&PS z^z1(~GW}t^40EfVVh^XJbV^ny-U%k%?U^Z}XC{ddqCb8hNExEc8}Xlygwn|;GrS5> zcU~9TPc11qvSWBH3Q|FotXjY)AoG!sxznvJ49dQMbkaa9AJRRh@`5J|+q=6_dSI2M zcq~yw5}|c@m;&GFCup-Yx6^VK1siOZ2p&i6^dv}h!DhjeR>%j4m|;94xk z;ddR=BztVm*;~EL>CPID=J$Z+u0WJLURVi$=#2SAm}{h_O$Xo{i^cQmUi$11U8Exm z`{HuSHGE8=r%coWF|;qj0I4ui8MV7T{?r+|OyxckN?9oULcfAqlr|5?NU8Q^u_=#A zJo#)q0#US3Dey4OKJsZ09Yqg0&B`GnxF!fu*a{o4lZOfET{I56n=Q?ul;3d>9TlQT z)Db>k_^prRQBUJ;5^$38M724Jam%?uNWd~gYX_2jO38wcOBKFciBk-T%9C=8LX}Ju zV|H&Pa%vG>>Lk1rd8i>sk_DPZQ_s#eSqH-TznTy8c_F&UJ+SjePMwnH5sW8koD>1*Moc^g=A|P9e$`FQqI{+QP4AhBM=nAuwv_1(N~w%=-ZL#cg+160zhM z5*IcaM2VYbZ9h}_Oh+noyWKo&w|rh-@eMB`OtwJwWyu_32SnqXWR6e52)BN?o${{wM^l1Zm*>MWn%@>OPvgW{@_;R?|F z@#7y8vR{8bKQkl|qLwuOvQwvZ#}@GOi=-B@b{d6+896RGeGE8RW>P({1;(_G#>OZm zhEy)T@h!R9FX*SD!@P$dvkC?M`S|$2pJ5Rwx*~aQ$sv5d4p%-v$xz=hL`j#vsOL$M z6?8k95E^qNSf(ivNy?YPlHEC?!r)9y>T*OghLb(*eEP33Ch1-@av_W1r9o46@_uFp zC_ca_7rCmlWHwOlG(a>1MDrGpAxS96d`Ga=jxN-aeY-4sMl5bV3e4h{DRRPZraVH5 zMWfX{&*qgSWN!o62rhJ#&+vynsiAAh?h@IaW+O$!JRZ{lmk< zx2JDAg(&A3-zo~Nt22()$zbvskeIhTbA)r=AxZ(C6KMPwRh|e=B7}qrO2Pryy$&w%!UMO3}n5uwXqB5N!KBc$?sS{`2=g|0R6>hXfu1Vi}@4$-K4a zU=YssuU3yubFB)(waVr%y9ksV6bOM*Fy7OD`#q+tY~=95O_0)N7=ArGAbCyZz(fSn zbrTnA4o{Y*9DI7TnaLvws|-jmb^xV#n_ti?L&t35{VL^Pl7>LuW)-B0T3TQJk6Pwp z$-0ZaC!O}+duD^DEjfgV&md}a0APiwJ1BFr3%!F zNV6{_4ms3;zPysl^ud=x>ar1w*jq)qs<0n};h8iQ>tYg0ZLShx{I0r%C*sXr^GUQ? zg=ssuApKw1?y6j9U5!Gnov_ zRLtloxf8rhFDcjfqUn5aI%|Ul?ln@#Ak6<8mn@fwTEg zh0<<1toeL3Tj&npJod&)O<77@#e#``J?GmGTn)oTYrbt~^r!y25xc0ubL|qR(x^>y zp^y!lGUxH3=A@V>g3}TbqBJGJnykp&Pt3{#g>YIZC4cN1X|_UnY(+7OPd;IY^2Kw8 ziczV?P5tUBk2wB@ana!D_3TnTXF8a7L=I{8`!CLb|A!#T0nxuvdHw_6mf}z5PRJ4r zpTNC*FKz=Dlwxr(rrA@L{S(V0%L6sn-3-(z$r>-@tLhP*5W4J?R_AdLyoY!3TWLR{VKy z`ctOSTQ36Vlu{z@9<=9A;&1=99EBhMa0rwW;^F?6mVHjHS6KM{J9nT0=foFoQ{3O$6XApRL?@`=QDIe)p<(WXK+I>az20j1cV|dMD8cY zKPll>6Z)9N)%5qfaXwcCr**Xl_%S}8zCHc*{rkV*M)DUz^c#E|v@7aS>NM#B9EWzmeb6knedC&7>e}7ai6<#vuYq zLr=x$i8Lys^z;|~d|K4mqov&mLv&9N{rN+qp#LG})>0Itf`XFZB|RwIAbfu}lnO+# zQjJyUU*G>?fWrOv@897YPh{+Zn(bAKUW+=a`>gv+z-(QVI7Y9QE#^jz+P8K#h)QL9 z%vz_pqC&6XJiifBIfPw&8<{bzl`>f?KqY>q2?O9W#39iQbZHcn{@zVGjUVzIs76(x zn2Y<2QBY3x`!B)t2SL=B+fh3fvHy8Rt2?d|@z-In-&PfB<)WvFrKFFbGS$olbh54c z?djq15v<^$AG|MmP5*OV)HqnLCMoY6Gh4Qi?ORKT7ymPq#M+V)RWvtOJ2j4+?8X&j z=y3u{nZ+eT7rrTx6~AfdsY;H>IdC<~s*0eyFOOc|H#gX_CAU4!N4G+0^V#*(3XrP3 zAJEkGz9?}<@cj+?qC^+Hd%GWcp6Yqb(oP{$WCgPnGN+-A!TirsurkL`HAwI&K|cM! zzu#BZYZ>p&YeOAYz!s1GIIbL(M|Wf$YgwC=SNbc6}$VXwdi5d z_Pj_`upSE5txx*({o-~eOc1e^J6g&cqus|pFQJqvimq9p)_U5o8)|od*^6iu8jF6s z^#C+Yosi#%Ixs?>w)6$;IM9L>XXueWJaN|)Y|wy$kr$rvCB5pefXpEM6SQ03G)suZ z8iH9nLQ3nCYBF^}vjy=TEF(A9^5@;_Z&s@iJ-ZuR1@W899A7hK*9!5EJZoOFj(PF8 zL{CbboU|9||%aOclbvdwj# z=!5#gj#XpwEJ?|lO>0U(DgzoUcT})iTWiM#s2%nzkYsc1{aiY0*S#j#3FVgbz4p}w zBx27_x;>zCO8?XMdzwmdK#-n&blMSOuE%Kkn4`3SkZNqo!qtN8z|7FBMV<;#?f_Pt z&r{x;pKcVY5fe*%##b>Kz1odOPk?AmQI6=;9YoOc`l;^` zKff<}&{|F6j>R4WaUc4jP$d`=EOY@W8q0GHA;(0 zI26;gHoPS0K!mv%jM`CF`*P2&Pj=)4B2HN7Oo_@Y%#yZ1Q!F>|AI-PyH6r>RN3>cP z{eP4}Rnidb#d?}ZS+=z58;Km^cD1>*{z{hn?rO5b(UCUxHar?#t#Bw0vj2tGNZRN! z57sJT@`1se7hP7?Q0l`cDOmI5EaonOvrjsiGTVEN4sDWqP7{!WvEMDsK;ER zbn&>1h0!O}*5)$Wg<#3PXfk!`{f`ruroR_HZ6ElWiJkTblgy!iIQ^E0Axa(kNgYp~ zU!Hjq&(%w=EKDZ=MN@JM|8O!uC)YSt{%MNZXub?%iGIejHy5X=^yA)_u6`gX?HQ#; zn+46+WdpbChrUQB=#G4!uXM4uN0HMT{5uqGsR7yVa^t>Pt+GpjeR#J}0hX!4L}=04a+X z>b!>FA?ldWcx-z(!_`e{Ap2k2z-MZZ84R@2qM@|n^pt@a+|dYxq7Tb)5VhF)a97P* zt>Q*6$@`yqjv9At(N^O$!p9tx#QVnEIG@_k4Qt&M_S#j5f}iAt{y-~Nbf{LZpq&d| zD5%hBEQQzC)1Q`}PQ9k7ldWXcZ5bW{1RKhgmP5?^=qoj#G?t_p=jhNWTfG|wxQ7>o z|2ygx=3BuqcLh(ob;AB98Q@-t5+m_$dUfFZbHh_q9x3$r#J4TRGdAq~$*4#(aCw%QOfr*4IpqJTHB z+%e(_aP7H0E>(eYdoAjYi+S_g$0rV~(14c>3(`acR7Vq~vk8gA^qZv*LLl8~b4{LD zAui}l_@r2i*tgl-F$w`n`;xFeliUp&Fm&hAinX+nCoM-6GC_RNz>1VqYYaRANrwT) ztZ`U=2kIKrf60AZrRLnc)*v@CVxzNi?bnndl3yzs^WcAWX)xYEof1Q7{QPuLrAW1k zMHQ*&Qe%vW$^F4R(NCRU#)ba#G%tFLU!XJnL{IJnPw-@LetY_cH-RV?kqAUN?kFR7 zI~TR=Wyml8C`22cSNU}k@_l(gw;NLpHULy~uy zPsu0k%#?ap(qA<~YN}B>T61c2KDn+XTVtL{?b~Si389pA#J7X6KGiBq1!jqfnyAjzs5b>_00qMQn+9E^;2CI&SbEK%yxAwhtuh~;Lzvz#NvSkTFZk+X<4UAMue z^WZ3T8)5Pcp2Zi5;d7_aSE0X}-K6oCuf>?M~t+hKs&_(4s5r?7a|y+PA*$FdFh(B9M8VRCjFHM`~s z*`N6prW&Pu|~THEv{-3PJQiDlswf6%;G7yA07@xZO_1V%P9gZ2x(L&`a zIc5_sY)m*eJmfwnoLYnpa8dIin$Y~{#_btISh$u83Pw> za~GC+)CzB38Yfuzp~K2Z8`HQ>?+aF#p5?zw+2y|S@a&nViAJ6*N{JE4+LKXR6-zu3 zm?k#3ElB2)7_yteBOlrI8S?m)p-=K7H&ctANgTtD;(uVKAv?gNWob0L@GK< zdIZ_P%A;Z^viKU77#7U32tHLm*O?L8Ut1wsS-Eu#rWm^TY|IZKM8Vbt720*AOG%OT z-JqN1&>j7(Q@S08ULtThL4BNL(0!SsM2cqj%;`j$e#RLK=hvELZTSP2Y)cLvx_7R1 z!2{n2u9R7a{0t4t-VPg4x}9(UMAGyHWqPL>o~-UNVxduQCU7uH^w2_5=rO>P=T}t;I^STsz>C7iezW>{4Yt-KhpY`y0v7lr! zyhh@5Qj*NREg88Qw!6R;)xt|;hPd|+!1Mq9@BjWSRnf?oO1CamO_F9el)PAVURhP<DPi$`gNe*h2>XD z@TyU&z6#9e;uHm43gnETI)vr>o1v7ZM06N(={9#K5<{0yKFfs+F}z-)eF`_hsY1Hx zv2id!6gvQ+BHc*JYe*X4)J-3)0*KQi+0J1im3ufXa;?@K9O6N$NSHQKY(}a%@TbOe<*z z4HTP+5l?GplP~&_ds?f1a^DG|?%{D>naiEE=pr1tQ^U66H^<5ILpB`kjQkm`6r?sTrNEVSdPm*;!kma|80UM-uU|6s4V=I6?2IQkgK{%)&U;Uj+la)n7 zNJk>IbR;Tf;ZSY1?q~7_Uq*6@8>0A>{60$PqXa@!L@A5ssX#@14p!1-)Lacwt>#~?qgt%sIq~=)>yHo-S?~QYTttBwd8igHC+SFs*N@EE5bp&Skc0f2~(%c zV8_#UbI>dW%J0i^PngVvPk4;O|0wiAO$?$iF=a*uQw2(`ODQd-fK@8=v@3NDh+bdr zqD4!sESNa;b=QpZ(XrFozC%&q{uLEDnx&ubsTe=;6e z@|Vo_EL|u1dUf8}y6MYnQJ?>5844xOkJ8GiXjobkU6zTfu|!{A#_ikx`U{n(xT4== z4$4N_w|AZ#Pf6=>T{Tg1%Ja{~XUQkvjQLTpO719V(G(UVOfNY>bAc!)O0vT2li;)C zAt)M3l<}hychWviC4Akxt`q4-!!rJSh}yh?5^K?Ha&PDgUu202`NGK_oJa(VxWTTo z50AtWegD^Yg6Q|ZzCAHh^q@Jesfw~h)1-^WBY%tqbp)B(rcfreNYdXp3tX`W=S=Nl z^P=kG+|?13CRYG%%q@0v*Ib1zO5*d|3(PV*I4WEG*K znYr(%3hkuPiF7&f4cxy`G1sFuJsJ8%4?U^t@?Pm-9P*S(g-;I4io&fDi6l{B%vQHe zBp()_l?ddgsY%P!Of7{m#-zHI<3Nf6@Wkf8;)J z#fOq8Z~cnc%;mByrgR-wG@mhc+>^ST?w2|)2bJverzZ=5vI>3RK#PLZ_0tn-=rD=r zrU8!+#ivWrs;bX8UwYC&%d9n`Gmf{NwOcHYzb)++UdL!WBn#B1u$CgZBr0G+ANT&@ zMd{TAWop3s8@t*w--omLqUYI8{CLuKRho87Sgdp?6Ga?y!HlBp#z0)6M@!a$mWfb3 zmrYpEp}CZsu2~7auVb0GsCrUp^fqFlqh7?KlLQMiWE9Q?fM zs6$Y==!{I<$fHmQpJc{jNf%c!XzO5qmM$ESKaU#dZ+JoXICQYQMhQZpO2udf) z%caJ?vn$I=r|8O8?OjgvOI#5Wu+XfJl#$C-msEVWv5ZSvKB0)#!1<@Lcm2(GKwZDT zFa0Q9l(z<)$e9^k={J1N#61eHf&P-g*pWjcuOUPwoLKUV#2*aekGaOK* z1en^i)xAZ0jPy@KscU+c>-kUGkVed0F15EaGP_}+@ub=FOMD*c(I|}+QWrBP$`5Mn zl;SeykygsnYK)qp`yMS?2Cq-P>xsd1&;N`5q()n=L6LNu^Ht85_&f?X25PTB9ds-7 zWlT!%yZZl;DMYbu2;zn>Q>1#-F>Op1QO2LOL1EJ**R8|sGM{7SS`BpO*@n{1osUr= za$Q>*m9M}LeJDibLEW!s)c$uohM=@R;hdt~Ug%sR{Im5~xXjFT1@E1XVXd-Ld}Dv# zX+fXiPhI$2&ui0G+|uDqSR!q(z?jVJcXDoBHHq-T;S}88B(Wm3Q7Aq&T9>J-i_6Y! zMcW|ynyG2+N&RjxZE6GjcvggH(b4&$)@bX}2}`~;c^P2VrNb8TKDFp8EPr0I?t)Zl zretGI0^>7b*;uY8`G$CL376D4NNQ2$p68jeS0XA2Hp8svrLzcSM979znXpfQ4n>jmFxD_zOxul-l8^Q(n*Xvp+LUk;^*oU08W58Sdl2btD_GgPpiv(UNGc%zHCin#cqYG%kTk&mx*NciV<dsvW%_N^FE_t0yU4J&0IJ8Tf2}Wg zY)3z~)1se==K}KRl&q7;s9U^q5-x^i%^4N-y|lUNHHys_y{WakU>6p%edftcPw=IT z*HdmwE&An+s5P`Yg4OgHLRBE@!;zP(P*%pl%?ha9l296^e0AyX_}Zo_9XvHBms?tg z@E-fNj8gV$vx>PlsWn;My;`THkViTf3?0*jr|VHSZ`(~5E4J3kvwlrV?;{}U;c=)B zZ7PS)mh0guz%aQK<`io%c zRn6LC`)~CGX-4ny>t!hl@fMKD%NMIxDL06I2Dv4t8jq{@2Efx4YKe*5)E1aW1mo7%UUd&P`4VIrXr12;9t-kndiq}K#?NA!u zmj~J)dWP+q8#nWr@VOi>A3tMG$5-g_cTZpRx4X7qYBN+t(x3E$$AwSSAbQQc-thU! zKW&JgIu|kqUyk;5YkE`o^72&^0GETZKkM>jzfMhyHZ}FdV44eBKl_2w=%TAG{4yv0 zGhf_~Oyd6}AJ;x~+4rC2b4Pz>_F}PoI6SS`cSD6*Td!DDx&81*>WsIvuW%7rk(+vcoj;?WHVv`-CXKwWQpK0B`g0Yl3y5CVj#{9uL=NifaCkJ7aaC7$6BZbqs^M0pU#?D9 z;wHQCy7-jqU>OvPQ?tBDa69HHjdXtDGTnGq0KcE)n=b2oyt^5?yWMV8?HmK@i4gUh z%x^EhFBcDP6#O`R#RWdSrn-B%z=)1Ny22~8VIhX#m^pW^$l zG?>E~W3tz5oJnV*QP(KftXMi1eUJ+pU3Z7*$I`;5XMDn!YI9w8tK=g-k*tn;hZ#ph z-2tTt(L;Q$LiA!@*A&z%%*Rd1-oviB_LjJ(_N|BE`48^q3njQDeGe!N9S&s(X7Tb^ zs!>PYOjBw9T@;;LnKL?ySi5SrZfQKEHb>R?M!00=^0f?M#}kD~-ZH+$GL!oj5Y;&p ze(DdrgRasm`7VS}<%_QB%xk?VYiE5(_Fj{;Jgzi6iDhoshtYHkBLa2+fRnF5-^`@t`@A4oA%%XCB6s!VTJ+<=Thi z)!}iL^^uzHHBF{K^jJyfRY)3se%NX>=2s>`8(iPtc>c}3=wYc7WcH@GZhAl*UK2K= zrl}u>?7lZwzNj4~I+AK}t!%r-i?=3oxN|P!fGtQ`hKqgxTw~zbF@Q*VIrx-Q%1ma^ z#KgIbc)GT4oGV|H<`MH4;+|3lRI7e)w7h~Sto@-emX9>fJZm2x5;L&h02t5D&tP2} zRy|N}q(XI{;~el8lAaa-zGJrKt(Cc*(uqijzUziz;I{h|?Mt3Ew64O{$zs#u78J+3 z`r4{#D<}=qjGD{l|1S3N`*^CgF%Xmj>VY}te zOZb#=@kN=NlJRrRIn_pYR2g)C#2k&U`d@x>V-~BIaDq2{6?nV?)c8J#)S7t?d@e9P zaaL&tH6F9DGw+=lvi=6-0y}D(rrxw7ctwcv$ARbPS2TRWmtbcyMDq>W;a3An_!^M8gf0#$ z&|$mX!ZpQRAzHN``hMcjeEkgOC~`{eh$Jjpq;mmJe1+hNuTUg0*n~h+YYfXhSQ+qI z0Z}?T8u$V|8Z~3#FbP=j8Szj^@F)pEG)8(DP1PN~_`41W!M%ms(72y@j1XLXP@Cj| zkROWc1?K_Hf+{zL4IaD1PON7MD25#HO$H#HPMF+bImFh5z!_d=~DO|cAe@e6t z`~}|F5LFe2G|$=wj&Hxguo%&ji_J+8oda)8_82ctV^~3HE?N{#YdS9Q42p5YL8es& zR=(o0L}#4f7Lk~9kjU^1XDMjW4I`9I9_9?#6}k&Veb%^z|NO@*x^uPMBGAf6VCR-~HEU^ja3e#PIa@m&;2;1ffFB5WNp-g8 zO(4qgHTFK?P}m?qA0AQAaX@^MQwoBv#8kyp{ORTr%wYjWy6wqn+$)4;rF~B3J!STF ztaO{)$i5X{bP5`vyar+9|7xZ$Ct_hJ|1d1@Su5R(OwHbmLh1&D$=1;nzV zyDYcCd%T`KHtM(}b6-!)7qtfr&O?0OBFw_^PqlB+lHIVj#PTns3gMeij}I@qmpz`; z93JYBTN zDK{3BQ3~!NKolOl2cipQHM_CD7I%H6nB(FXV&j=VlqJxo8y7ScHX9Mj_U&%7+iyqG zlkk18ptjpbFdsCi#Rrt7;KtHHQ#WgLDoz8K79e4d(ROpp;j~1Yd<>!$@p+q_$vU4= zswHoX&wK#UtMEi68`pFNEXPQ71b9G#FAAFkv*mGrY{q`iInrABt|~O&0ip{nXQ2@b z_cOHv+vzG=&gUvE^8T)CZ5m3A<@&g0f0jiAIuw@~BPBV}cZOlNE!Z4|im zq5xgP6+wX-Jnw3MkWbsV#{x1Hhjb&cH=OhG^<#J+KU9B27j21_&7{X1rD{+u0n$Zi zd4sK+*r=OI*fiujP0{O@oS}=6?p4@VycR@{A@(Ml;Gp5dhh14z)@0M7j^N-Yr^C~k zG1Zj>%7)|`Eta8N?IC{Ov_`>%cE`{z*jG^b8{nY@Us&jc$R$*&fq7! zns`@H<=4RHp}QZWG;QLOG8L-s&bz-~-Bq!!K>xB6Z{E4^$x8SsJGY~l59KlR9FFOz zj)Jdos(KKv@7j3KRj7O?79!Vt(RhtdaqFuT4nvLcrmt3l$BEM?)Qmy?AYcw)608zX z@4fNUE1L7;+Y9}XDzuXl;ZE?WD3uVc9D>Q$Mh4A+IbFFdI_v!w_`J)xdF-TPWG2j= zC=uyp>$7`YmHw4zN5kiP@L9}|%DgpvDnu!fqH4<%YaO~~?JoC?rW54@e8%4gIUn>| zb*neMMVsryJpi%&f^=%syF1O1>%&_-XT#^^TGVuDWL=sZP@N8CGnb93i>~#tyxg{I zhYs(W`yhiH$+FGKp)!WgVd%cTD;lHw9+(Den#=iso!PtY- z`7X4U=nMBK>J^{8TDgi+2k+N=*_!bck2s_6Y&RRdq5d1-GrZcSDc1P3UG2KPB&}OW zdXoTY@LbV-q(8x#`aJf}@8$Mrk6f{E6LqRe6?dYzbE{m&vtvM!2zgZMiz&TKpzhS@|Ju+p=*}5^slQsH50sz<(V&`%VCAIy5;$MTnnp#Ne$9U9!XK6()WMC}O=XsA()p3G3@xg9SH0&AL>sgM zuK^d3TZe78bc3r%*K*+QNrX}ZXo}t&Jv1;>ZHC%fo8A323%FvLjNl*N5TCiW4sLb| zR9bYF2TUrFmD`2TS!Q*ij=~)|nSRk4({f62Ct*XZ4YkC2oN|U^Uq@Uj6&>I1juUd3 zu$TS#5G_TWbu!;|OHz%Xqc)k6C(DoE6ADg4ECEHEy>N*J%G}e#5b7cN`1AyKaNBbC z!GUyY$dl{RU8&_v|DwIrcVOUd38GKmzCAuZ!nI_S4s7;*AAIS;^5;K1F_otXlo;oaIv-%(L%-KnQNZ z$>JIy!68VpL4v~~Nmy9iZ6P=;1oz$P^9P)l zpX#ou>H5x8^>lR)cW;v2uXQ<>8m1QG40ih=>VB-l*NNEG9x3LpI9hB7ZI78`{mS%~ zCj-^z^_yN4jZL{tP_c@qA0=wn|2!ca63#V^^Wgh)KgfHeF{UuINc#BZWb?Ii2j{0v z0@By3tt-xPtH*T*b8ONm*I$Jv|8^<_?+<%%t6BS-Z0VH@jXB?a__o!eTnfEQ&RqL<^{w z4Hw|R=j2xAJc>fRp=uhr3QR`)I~yaMd*0=>9Di~pvmSGR^fE#I1h4VYzW3XHx4b~F z$Qt3}{!Dy8sop8GyYN-JE>wyj6;sz5qwUuM1-{A#=mug|-#sc^ z5U#u5=TH#wv@ue*PWBlBB{jP!+f$^(%DWe}cc5hTOoso4g1*wEx$o*P1xEU~Nk!cx}svB1lJlY^*<)i75Ww^dc^LvpIg!^S<=(=k( zoXwsE7Uweg@?$(v^s;p3Wh09Ju!c;;nV8wFo__5+0@JIRhL0*j8}-yHF8mAQ28KA^ zF?!A`TEHBG(?oGtLE7CXYFK_XQ$NeQ6koMx1>2pS?N1;n1x8sF%9s*CC4Cno5eQ4p zM0fI;AW~_W`)ztaRuR#CXAd_-xM?sIk}F6*A{zINwtCj8xoj<|FG8&xM~SaF+5vOC z1fj7@B6P!}Y2(g6SABzsFr5DLDO_(%j7*drSZv{Z&Hr5gm`;r)IVJ)b4ne2U=i6f% z;U=*J1#bDC%f@4tmEl?eX}n=$-E{R)818$)8YbrMSKg2BUrd5=83Oi$gsnHkxQz_%kfc3@#$#ZLYi7u zr5+(-38yLPy8#fN5xqInr_&x9a$SQNg_z@wx#ZDU!5d-69t;L6pK}gm_WsO5zDu?S4Fc7u%_xNa&2`ZE@W+86sz463n%-Cf%X4G#!*BRH zM&avkC=#ARI65te&+r6yHtL~jIm+YA2*+TF5dn+0@6U&Wispfo`a`k?CHZf`E>X3s zhRFnK(S}|#j&et^0c;%o>qo&~)+)*}jx;#$pIs4w>0OR`ar#+DO5LV)bl7`MclXK6 z-5}))lJR9Kf}*l{;PeXHjj%yLlY>S-X?Z2)CdR%RZz223WQOn%PS!M3(gW+zy7vy# zXP1mX1m%0S29y2GK9iL-@75D;(zIWe%MtYRwXF|Xw}{}5d8E&~i^TJWl{SgDgHkR% z%Pw{P=Qwlom;`cnl)>+2f6Ee3#M`&{TPsVo3<h_t+?>s*i*q2XctEbw~O#fU7^9au~=J-DoCP<;Q z02KEW+fm29K1ObYDGF3i?arI(P!b&-?Mo_$4Mm&5zrp7LH*%#^rzqYC|4H4Eav&Ee z)=ce`NjH@4#pIed4O7!T?#?f1KQdPswIKhtk=MVR+D%OmHN}%{{UX;4lcLb`bZ# zF8@XOwT!qQ$M&?HyUWvh(JOxr+hhi5>?*S%&7}n8u0@h}r}^7!o^|LHD!S(#ppxKP zQF7cjH3251dK1Y8Z4Oh&v4xsZ8-1+h(fq(rG+IDidM`Ge+@(qfJyDz#!+g_DXI0A0 zVL%Smx##lB`BES|$>48$zs`5Ix43pwr&6nzvUDTeMc8-0@Y6JzA#vhMZW~k48?P_C zz=@6&c_K*b4}cGa^l#ohYMN6<@8sd|S&BsmlC*PW%-DJY@b&vGcGX7j<>x42>(s}$ z3FEXwmDr{JhrIgr2{>UYq)UWh?DX)9@<{Djy@gO&U@;)HgTXdDd@GC z)uZzDQ{YM%#`G_UeNux!9+%vrwa$?9z#AUv9;VBkU^uR~2guloxSRv>DZ(1YUo0YD zv&a1OEiu9nMVJ7LNhnrCWNY2$F28~2;ekVIZRphazopgme+CvmHF%2C)BtJ!8uv$a zhyqoDvvn>JqtFRMABCqV^%cc@UYpfo#d#vY#EKIS7&-|wNm^U^C>kaQowj_5)U3ja z`taSE!8s-a@Z+@!_UeK3k@Q|HL+o9a{+p@`PY+dX^NL7Pktbu36tY%u%Q}Oc_1I-< zcpQpZT93HMQc5Mg48Pz44f3)4g-D)%LH{6ep;hkt?Cj~q}2>Uw8)Hz6DxnY(3c>f!wVC&}|9E+uVm7vRH4(*xtBE@M)!saS8kuGvdMS!Z= zofUh)hN2}I`Mpi+89U3KRg@re0+A75Quq+rJgUQ~RRguK<`Fj#;gcNA?utu=nRxEF+U$H!i%tKlTosGka@30u95TbUkXj z*>9yxp!IOOa0@=e7jV4FsZkebkB_Icjx-+)J6zj)hA_H}lO6M0sDClG=#BArE)IRZ zF&!uj+&xQN$MMiCc}3|zgRripxylm~QGoOFcc;IIkUhgCq7?CUbz(PQo zH5h>t?_KZPGK@Jh1;s9?q^d_n#_LJAck|8B6V6M5Jr@TlFC3F~1eVCt%`VN#hZ9X^ z24+%KzNiPpF0>KH;_-4){nV1_Uv~f0qoGHeqd*tgB{WToqYBp?pss$Nn*bu@%(PSK z7LxB$mlZ7|Qsts1RIUB^3f#i`A@G{AdNN6eXFR^sLOhR&EaQ4pY8AG_y9q9^G$&~ye{AE@o`U%!$H zs|IK8l*Asj?*JxX)_9J0W-X;}>89axDyvy6nU-ph8LRvipZbM3_T{FA$%}7#E3a|M zIV~{O?V859F%&OI?3b3qFgD=t^a!_7E|uFz6dS2293VD{1GQ{?$>_-lfPQtj5K>Rf z{|=YMA0AnRE@LUe_O3v9?qiZ&l%-q%_(_}Kuue(p`Sg=K7%;y}=3oKyHlA_7$TUou zfcB;D%yI}N4wP$~C!@%Q@k8;8 z^~_Df36E4W7Oh;CXTbHTX;tpKXhmE)%)1K+e?@Hx}i*zJX z>Qa28yWwBW#H%_suNRFC)7WZmZhR*aQgkEHjJoKupL4qT+!^Lh%vOT|=I>>xQ*{#T zW30t39ueFQ#AK-bG3jQt3fSN3wK}@@v(u+4vJ5@FRkB zKA1^u@vNgNJmMtC+s$TF@^cHK6f6Qc7EOJ#FIK@{7H_=oK)ZgsY{mISHC!Uf+(ujq zz^17I9;jqF=F~b)6UU;$?Wg4sL`2Wb+kx+X(WMMoiDcVFTlQJA>y3~Tyz)t52 zpTIg}t?pU%-cwj{Y3%;oBO%QV-De-tT_~z~5O-jendGz__3SE(AO)_GKYGe6Oy z4N_Ndx8G)E0J<=I^D;U{Q3TV1hmqT&bJ0juc?pYcif(sJ{I2uViVV0%p+_@E*g8E! z&K3Rf6Z18j9BWnm4&HU*2V8`%eE@FG+{H)>9_bmpp_7m>Iqw{SvT*&N(ZVq&vfly@ zS(~mj`{~JnSmYhhJ**nY4gJ!pQ*k)D7ujfTe{}L4tx^yO z-FFTQXf^Ut`BFY|^>lmzt@F^&YwcXUrQ%_yqyb(_!6S*ef&x_79s*hmt%Vd{h8D;| zLq^qXPrVNvp(Q#2H<(dKR}KhYuSx$Nv~{QUu=x7t74j3kU1lB10k1$l&Y9jw%=YR0&INRTq{|jW8&sT{5*ZL3A$fOHeP5l4y|87&| zU*~`EpCJBY{RjVz>3>7~??nAar~jOQfAC+O{-4JG;(v4kC1%{LP?_jPv#CfSD6|un zclv2jP^QBwpHLKiOns436r*`9341U`0Zwo0TyZwh*M8rHFtjP^Z`8C>-juqsm~VbfyCtt3~wB zcd5Eg-rgBaOW?JOvT*XS-0}K+;;jIDdAW+@NU`lN|dFT3pP}ZcLb^k4Cc7#CE zqKpg&ZGG`R)3QcJd`4dE6%Zd9)NpgK6+;UcM%iMW70B<4Oh)Q{72{_XEHR3>&OnCQ zJ7w{&Fw3-9Il=ulUOD#&g$pd6ypD2`7cg-NP8`HOtu){9VfduQKtin)E2Piv;Q!UD zVYvDZojv>Y#(5GG&#U*o$%X#366TVPo~G^zJ}zCJg=EL*a80&QCV7kTVu7{U>djNZ z(C>bccyHJEaDON}bk0PCebZO3oD(nj25jV%`DB&yrGQk9IvIlT`a%)|_py7+?~oWb z(qIWY*1-CAvSP#CwKFOb0#E;0aN53T=Nx-;VirpkkuQ&4biF0m|H(N4M|5L6usz(1 zD==nWCjUJ$0ZDj*QxPK3fW#(BU z4+Nq%O-BqQ1rCCVzeS1GAF~MAcb8+?`r8Kc^!v1h80_~DM%gZl-2H(a0lEuk0x?0p z%xFG;PJYbUi!2Zrwz1z2?K%66^jsxrmWY$7 zsd<)^hj{5r89yqKELA?#5=}lZ|87ef2_Rbyn}xZ%!(fYtM%eA6J&vYsS`2CM@&izL zC({#rkUMGn7Bh~7ki=Uw3KVMWDsx<(S08K@R}rZE6Qc*0MM{!6olc%CCM0EbG19nD zwY$(%qPM=dh|0;^!3`CtVBhi6O#x7Jn$R2_uO>eWC6-(%}=m>{NW|)TgUC4VGO7_Fgs_1Y)UHobo2JKD$#ysYi4bT4V&cS8}B9!v=LVQ z`o}5lIJK690=rCIE0ahqTJ6=>!%JpEez*Kveb-kTq4;n~Y0{{|I_R9s03lrQ<|G^K z`PvOSdqRpm*mXy<~T!ax@1I+^jSpK4oz&_ii$AjfFm=P7K2bcKKP zqUjfr9ij@Ic6s_dK{xxu4px##(1)r=os+=0(1b>-EC zoSe*B4L#1=Z?_3NK5%WqkpSULz2F${%xLFI`hY3b0w}T)#X?K+o%rhA`>3Azw_^MY z4T|Q|Xn*SC_ref6byuz7xdU6r#E@yoP@H_s`?Nlu)K&IQ!Eet%N}SJ5RaO`V_5$_F z($i|K(DI6p-z7_-ss91!kznrS=)t^$eRPCw(ZSC(?X74{>)ysXr>L8UmCAf3_MNPU zwq+UUU;eolRHJd`w057)8K`9G!lV=hhEC|5$YcL9Sjm!4hR;Q$J?B}@l`(7GlM2Np z|C~bV_TCgO5T3LndSOC@SBDK#J(tJ9_xSd_2G*`lpPN)!bL}l!`FF79#r_0A?(?Hl zaky&O+T`?2RWsfj;g!J@~CCN5C;gPNKCfMTq?==MU9eXp}|8%+58;2VhV$WI#CVVt#$4VVL zk#%!U6Uo2`<&F)MZL#nmm3mn?HKK0fh>j>yJ^g*^-J8)?P%H1hlPu)&CwdOInFzPI zr1{9adQMX62tC8gmmMR)7&=#h{QjVq@P13(omijL zG6ojE0Cq2g;R!0?IAn^1by7{a4-2U*+8k8xo3^iYdlt^;jH?yZ;GCgx_{>~4t75Qm zg?DS9a2vc8*e~OYX=JKOg|{U!cEHGGQw>&dv_yT}=Ig#Nnj=oYzKG_o}0sNSWi1M9eV2Sa$ ze3h+FQ^mA3ZC{s8JJm@s+U~I=f7=w{kHLf46ZIpPVe^u;ODp%|MgDQ^S5|zQ5`ElY zx=e$Qu{}gedY3!8?b>JC&=XZcjr8vq5B`06z1H5l_nbOOLuAg!vX;}jYYvRYhcCTP zvBK$fblb(er*B$*fS?DY6+UeWV!Z literal 0 HcmV?d00001 diff --git a/src/index.pug b/src/index.pug new file mode 100644 index 0000000..bea69a7 --- /dev/null +++ b/src/index.pug @@ -0,0 +1,40 @@ +- var data = require('../app.config.json'); + +doctype html +html(lang='pt-br') + head + title #{data.title} - #{data.description} + meta(charset='utf-8') + meta(name='description' content=data.description) + meta(name='image' content=data.url + data.logo) + meta(itemprop='name' content=data.title) + meta(itemprop='description' content=data.description) + meta(itemprop='image' content=data.url + data.logo) + meta(name='twitter:card' content='summary') + meta(name='twitter:title' content=data.title) + meta(name='twitter:description' content=data.description) + meta(name='twitter:site' content=data.twitter) + meta(name='twitter:creator' content=data.twitter) + meta(name='twitter:image:src' content=data.url + data.logo) + meta(name='og:title' content=data.title) + meta(name='og:description' content=data.description) + meta(name='og:image' content=data.url + data.logo) + meta(name='og:url' content=data.url) + meta(name='og:site_name' content=data.title) + meta(name='og:locale' content='en') + meta(name='og:type' content='website') + meta(http-equiv='X-UA-Compatible' content='IE=edge') + meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=5') + meta(name='theme-color' content=data.theme_color) + link(rel='shortcut icon' type='image/favicon' href='favicon.ico') + script(async src='https://www.googletagmanager.com/gtag/js?id=' + data.ga) + script. + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', '#{data.ga}'); + body + include components/welcome/welcome.pug + .main + include components/introduction/introduction.pug + include components/footer/footer.pug diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 0000000..e69de29 diff --git a/src/styles/base.styl b/src/styles/base.styl new file mode 100644 index 0000000..770b675 --- /dev/null +++ b/src/styles/base.styl @@ -0,0 +1,31 @@ +* + box-sizing border-box + margin 0 + padding 0 + + &:before + &:after + box-sizing border-box + + &:hover + &:focus + outline transparent + +a + cursor pointer + +html + -moz-osx-font-smoothing auto + -webkit-font-smoothing auto + font-size 10px + font-size responsive 8px 10px + +body + -webkit-overflow-scrolling touch + background-color $gray-white + color $gray-darker + font-family 'Open Sans', Arial, sans-serif + font-size 1.8rem + font-smoothing auto + overflow-x hidden + diff --git a/src/styles/core.styl b/src/styles/core.styl new file mode 100644 index 0000000..3aad32c --- /dev/null +++ b/src/styles/core.styl @@ -0,0 +1,2 @@ +@import 'core/variables' + diff --git a/src/styles/core/variables.styl b/src/styles/core/variables.styl new file mode 100644 index 0000000..d501365 --- /dev/null +++ b/src/styles/core/variables.styl @@ -0,0 +1,73 @@ +// ================================================== +// Variables +// +// 1. Colors +// 2. Spaces +// 3. Media Queries +// 4. zIndex +// ================================================== + +// -------------------------------------------------- +// 1. Colors +// -------------------------------------------------- + +// +// Colors +// -------------------------------------------------- + +$gray-darker = #282828 +$gray-dark = #333 +$gray = #666 +$gray-medium = #aaa +$gray-light = #c8c8c8 +$gray-lighter = #dedede +$gray-white = #fafafa +$white = #fff + +$yellow = #f0ad4e +$green = #5cb85c +$blue = #5891ff +$blue-light = #aceff9 + +// ------------------------------------------------- +// 2. Spaces +// -------------------------------------------------- + +$space-xxs = .4rem // Smallest space margin +$space-xs = .8rem // Extra small space margin +$space-sm = 1.6rem // Small space margin +$space = 2.4rem // Regular space margin +$space-md = 3.2rem // Medium space margin +$space-lg = 4.8rem // Large space margin +$space-xlg = 6.4rem // Extra Large space margin +$space-xxlg = 8.8rem // Extra Large space margin + +// -------------------------------------------------- +// 3. Media Queries +// -------------------------------------------------- + +$screen-xxs = 380px // xExtra small screen / phone +$screen-xs = 440px // Extra small screen / phone +$screen-sm = 768px // Small screen / tablet +$screen-md = 992px // Medium screen / desktop +$screen-lg = 1200px // Large screen / wide desktop +$screen-xlg = 1400px // Extra Large screen / wide desktop +$screen-xxlg = 1600px // Extra Large screen / wide desktop + +// Rupture Settings +// @stylint off +rupture.mobile-cutoff = $screen-sm +rupture.tablet-cutoff = $screen-md +rupture.desktop-cutoff = $screen-lg +rupture.hd-cutoff = $screen-xlg + +rupture.scale = 0 $screen-xxs $screen-sm $screen-md $screen-lg $screen-xlg $screen-xxlg +rupture.scale-names = 'xxs' 'xs' 'sm' 'md' 'lg' 'xlg' 'hd' +rupture.anti-overlap = -1px +// @stylint on + +// -------------------------------------------------- +// 4. zIndex +// -------------------------------------------------- + +$zindex-default = 1 diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..38a2062 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,157 @@ +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const config = require('./app.config.json'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ImageminPlugin = require('imagemin-webpack-plugin').default; +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const OfflinePlugin = require('offline-plugin'); +const path = require('path'); +const rupture = require('rupture'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +const webpack = require('webpack'); +const WebpackPwaManifest = require('webpack-pwa-manifest'); + +const webapp = { + name: config.title, + short_name: config.short_name, + description: config.description, + background_color: config.theme_color, + theme_color: config.theme_color, + orientation: 'landscape', + icons: [ + { + src: path.resolve('./src/images/logo.png'), + sizes: [96, 128, 192, 256, 384, 512] + } + ] +}; + +const copyFiles = [ + { from: './src/images/', to: './images' }, + { from: './src/favicon.ico', to: './' }, +]; + +const sw = { + safeToUseOptionalCaches: true, + caches: { + main: ['index.html'], + additional: ['*.js?*'] + }, + navigateFallbackURL: '/', + autoUpdate: true, + responseStrategy: 'cache-first', + ServiceWorker: { events: true }, + AppCache: { events: true } +}; + +const baseWebpack = { + entry: { + app: './src/app.js' + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].bundle.js' + }, + module: { + rules: [ + { + test: /\.pug/, + loader: 'pug-loader', + }, + { + test: /\.styl/, + use: [ + 'style-loader', + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { importLoaders: 1 } + }, + 'postcss-loader', + { + loader: 'stylus-loader', + options: { + use: [rupture()], + } + } + ] + }, + { + test: /\.scss/, + use: [ + 'style-loader', + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { importLoaders: 1 } + }, + 'postcss-loader', + { + loader: 'sass-loader' + } + ] + }, + { + test: /\.jpe?g$|\.gif$|\.png$|\.svg$/, + use: 'file-loader' + }, + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: ['env'] + } + } + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.WEBPACK_MODE': JSON.stringify(process.env.WEBPACK_MODE) + }), + new CleanWebpackPlugin(['dist']), + new HtmlWebpackPlugin({ + hash: true, + template: './src/index.pug' + }), + new MiniCssExtractPlugin({ + filename: 'style.[contenthash].css', + }), + new CopyWebpackPlugin(copyFiles) + ] +}; + +const prodStart = () => { + baseWebpack.optimization = { + minimizer: [ new UglifyJsPlugin() ], + }; + baseWebpack.plugins.push(new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i })); + baseWebpack.plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'disabled'})); + baseWebpack.plugins.push(new WebpackPwaManifest(webapp)); + baseWebpack.plugins.push(new OfflinePlugin(sw)); +}; + +const devStart = () => { + baseWebpack.devServer = { + contentBase: path.join(__dirname, 'dist'), + compress: true, + open: true, + port: 9000 + }; +}; + +module.exports = (env, options) => { + if (options.mode === 'production') { + prodStart(); + } + + if (options.mode === 'development') { + devStart(); + } + + return baseWebpack; +}; + \ No newline at end of file