├── .browserslistrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── .gitignore ├── .htmllintrc ├── .stylelintrc ├── .vscode └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api ├── get-all-lines.js ├── get-line-by-date.js ├── get-line-by-lang.js ├── get-lines-by-lang.js ├── get-random-line.js ├── lines.json └── post-on-twitter.js ├── contribute ├── .keep ├── 2019-08-04-wp_reset_postdata-silvestar-bistrović.json ├── 2019-09-03-let-apples-shoppinglist-removelast-ethan-chin.json ├── 2020-01-22-entries-array-heithem-moumni.json └── 2020-01-22-include-heithem-moumni.json ├── data └── site.json ├── docs └── pull_request_template.md ├── gulpfile.js ├── .bump.json ├── .critical.json ├── .css.json ├── .favicon-data-generated.json ├── .favicon-data.json ├── .favicon.json ├── .gfx.json ├── .helpers.json ├── .html.json ├── .js.json ├── .jsdoc.json ├── .kss.json ├── .sassdoc.json ├── .starter-project.json ├── .sync.json ├── .watch.json ├── .xml.json ├── bump.js ├── clean.js ├── cms.js ├── critical.js ├── css.js ├── favicon.js ├── fonts.js ├── gfx.js ├── helpers.js ├── html.js ├── index.js ├── js.js ├── jsdoc.js ├── kss.js ├── sassdoc.js ├── sync.js └── webpack.js ├── netlify.toml ├── package.json ├── scripts └── index.js ├── src ├── cms │ ├── config.yml │ ├── index.html │ └── site.webmanifest ├── commit │ ├── config.yml │ └── index.html ├── critical │ ├── style.critical.css │ └── style.critical.min.css ├── favicons │ ├── README.md │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── html_code.html │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ ├── mstile-70x70.png │ ├── safari-pinned-tab.svg │ └── site.webmanifest ├── fonts │ ├── .DS_Store │ └── ptmono │ │ ├── .DS_Store │ │ ├── ptmono-regular.woff │ │ └── ptmono-regular.woff2 ├── gfx │ ├── cover │ │ └── .keep │ ├── jpg │ │ ├── .DS_Store │ │ ├── cld-2x.jpg │ │ ├── cld.jpg │ │ ├── cover-2x.jpg │ │ ├── cover-dark-2x.jpg │ │ ├── cover-dark.jpg │ │ └── cover.jpg │ ├── png │ │ ├── .DS_Store │ │ ├── cld-2x.png │ │ ├── cld.png │ │ ├── cover-2x.png │ │ ├── cover-dark-2x.png │ │ ├── cover-dark.png │ │ └── cover.png │ └── svg │ │ ├── .DS_Store │ │ ├── cld-dark.svg │ │ ├── cld-logo-dark.svg │ │ ├── cld-logo.svg │ │ ├── cld.svg │ │ ├── cover.svg │ │ ├── placeholder.svg │ │ └── starter-project.svg ├── html │ ├── 404.md │ ├── 404.pug │ ├── _assets │ │ ├── critical-css.pug │ │ ├── deferred-styles.pug │ │ ├── favicon.pug │ │ ├── foft-font-loading.pug │ │ ├── og.pug │ │ └── scripts.pug │ ├── _layout │ │ ├── layout.pug │ │ └── line.pug │ ├── _mixins │ │ └── cld.pug │ ├── _partials │ │ ├── footer.pug │ │ ├── head.pug │ │ ├── header.pug │ │ └── signup.pug │ ├── _variables │ │ ├── line.pug │ │ └── variables.pug │ ├── about.md │ ├── about.pug │ ├── archive.pug │ ├── author │ │ ├── ethan-chin.md │ │ ├── ethan-chin.pug │ │ ├── heithem-moumni.md │ │ ├── heithem-moumni.pug │ │ ├── silvestar.md │ │ └── silvestar.pug │ ├── covers.pug │ ├── evergreen.pug │ ├── index.pug │ ├── privacy.md │ └── privacy.pug ├── js │ ├── foftFontLoading.js │ ├── homepage.md │ └── index.js ├── scss │ ├── components │ │ ├── _colors.scss │ │ ├── _font-face.scss │ │ ├── _fonts.scss │ │ ├── _helpers.scss │ │ ├── _locks.scss │ │ ├── _theme.scss │ │ ├── _typography.scss │ │ ├── _variables.scss │ │ └── elements │ │ │ ├── _btn.scss │ │ │ ├── _cld.scss │ │ │ ├── _content.scss │ │ │ ├── _form.scss │ │ │ ├── _global.scss │ │ │ ├── _hf.scss │ │ │ ├── _message.scss │ │ │ └── _sig.scss │ ├── foft.scss │ ├── homepage.md │ ├── kss.scss │ ├── style.critical.scss │ └── style.scss ├── sw │ └── sw.js └── xml │ ├── _layout │ └── rss.pug │ ├── _mixins │ └── variables.pug │ └── rss.pug └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | last 5 versions 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | trim_trailing_whitespace = true 13 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/vendor/* 3 | **/dist/* 4 | **/node_modules/* 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-base"], 3 | "parser": "babel-eslint", 4 | "parserOptions": { 5 | "ecmaVersion": 6 6 | }, 7 | "rules": { 8 | "no-console": "off", 9 | "no-undef": 0 10 | }, 11 | "globals": { 12 | "requestAnimationFrame": true, 13 | "sessionStorage": true 14 | }, 15 | "env": { 16 | "browser": true, 17 | "es6": true, 18 | "amd": true, 19 | "commonjs": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | .netlify/ 5 | src/gfx/cover/*.png 6 | 7 | # Local Netlify folder 8 | .netlify -------------------------------------------------------------------------------- /.htmllintrc: -------------------------------------------------------------------------------- 1 | { 2 | "attr-bans": false, 3 | "attr-name-ignore-regex": false, 4 | "attr-name-style": "dash", 5 | "attr-new-line": false, 6 | "attr-no-dup": true, 7 | "attr-no-unsafe-char": true, 8 | "attr-order": false, 9 | "attr-quote-style": "double", 10 | "attr-req-value": true, 11 | "attr-validate": true, 12 | "class-no-dup": true, 13 | "class-style": false, 14 | "doctype-first": true, 15 | "doctype-html5": true, 16 | "fig-req-figcaption": false, 17 | "focusable-tabindex-style": false, 18 | "head-req-title": true, 19 | "head-valid-content-model": true, 20 | "href-style": false, 21 | "html-req-lang": true, 22 | "html-valid-content-model": true, 23 | "id-class-ignore-regex": false, 24 | "id-class-no-ad": false, 25 | "id-class-style": false, 26 | "id-no-dup": true, 27 | "img-req-alt": true, 28 | "img-req-src": true, 29 | "indent-delta": false, 30 | "indent-style": false, 31 | "indent-width": false, 32 | "indent-width-cont": false, 33 | "input-radio-req-name": true, 34 | "input-req-label": false, 35 | "label-req-for": true, 36 | "lang-style": "case", 37 | "line-end-style": false, 38 | "line-max-len": false, 39 | "line-max-len-ignore-regex": false, 40 | "line-no-trailing-whitespace": false, 41 | "link-req-noopener": true, 42 | "maxerr": false, 43 | "raw-ignore-regex": "/(\\\\<\/script\\>|\\[\\w\\W]+?\\<\/script\\>)/", 44 | "spec-char-escape": true, 45 | "table-req-caption": false, 46 | "table-req-header": false, 47 | "tag-bans": false, 48 | "tag-close": true, 49 | "tag-name-lowercase": true, 50 | "tag-name-match": true, 51 | "tag-req-attr": false, 52 | "tag-self-close": false, 53 | "text-ignore-regex": false, 54 | "title-max-len": 60, 55 | "title-no-dup": true 56 | } 57 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "stylelint-scss", 4 | "stylelint-order" 5 | ], 6 | "extends": "stylelint-config-sass-guidelines" 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "emeraldwalk.runonsave": { 3 | "commands": [{ 4 | "match": "\\.scss?$", 5 | "cmd": "cd ${workspaceRoot} && stylefmt -c .stylelintrc ${file}" 6 | }] 7 | }, 8 | "git.ignoreLimitWarning": true 9 | } 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at me@silvestar.codes. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Code Line Daily 2 | 3 | See About page: https://cld.silvestar.codes/about. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Silvestar Bistrović 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-line-daily 2 | 3 | A line of code of the day. 4 | 5 | ## Supporters 6 | 7 | [![Stargazers repo roster for @maliMirkec/code-line-daily](https://reporoster.com/stars/maliMirkec/code-line-daily)](https://github.com/maliMirkec/code-line-daily/stargazers) 8 | 9 | ## API 10 | 11 | First version of an API is available! 12 | 13 | URL: [https:cld.silvestar.codes/api/](https:cld.silvestar.codes/api/) 14 | 15 | Methods: 16 | - `/get-random-line` 17 | - Returns random line 18 | - Link structure: https://cld.silvestar.codes/api/get-random-line 19 | - `/get-all-lines` 20 | - Returns every line 21 | - Link structure: https://cld.silvestar.codes/api/get-all-lines 22 | - `/get-lines-by-lang/:lang:` 23 | - Returns every line by language provided 24 | - Link structure: https://cld.silvestar.codes/api/get-lines-by-lang/:lang: 25 | - Parameter [required, case insensitive]: `:lang:` 26 | - Languages: `HTML`, `CSS`, `JavaScript`, `PHP`, `Nodejs` 27 | - `/get-line-by-lang/:lang:` 28 | - Returns latest line by language provided 29 | - Link structure: https://cld.silvestar.codes/api/get-line-by-lang/:lang: 30 | - Parameter [required, case insensitive]: `:lang:` 31 | - Languages: `HTML`, `CSS`, `JavaScript`, `PHP`, `Nodejs` 32 | - `/get-line-by-date/:date:` 33 | - Returns latest line to the date provided 34 | - Link structure: https://cld.silvestar.codes/api/get-line-by-date/:date: 35 | - Parameter [required] : `:date:` 36 | - Date format: `YYYY-MM-DD` 37 | 38 | # ToDo 39 | 40 | - Progressive web app ✅ 41 | - Browser extension ✅ 42 | - README 43 | - CONTRIBUTE 44 | - Newsletter 45 | - Sorting 46 | - Categories 47 | -------------------------------------------------------------------------------- /api/get-all-lines.js: -------------------------------------------------------------------------------- 1 | // Returns every line 2 | // Link structure: https://cld.silvestar.codes/get-all-lines 3 | const lines = require('./lines.json') 4 | 5 | lines.list.sort((a, b) => { 6 | const aa = new Date(a.date) 7 | const bb = new Date(b.date) 8 | 9 | if (aa > bb) { 10 | return -1 11 | } 12 | 13 | if (aa < bb) { 14 | return 1 15 | } 16 | 17 | return 0 18 | }) 19 | 20 | exports.handler = function (event, context, callback) { 21 | callback(null, { 22 | headers: { 23 | 'Access-Control-Allow-Origin': '*' 24 | }, 25 | statusCode: 200, 26 | body: JSON.stringify(lines.list) 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /api/get-line-by-date.js: -------------------------------------------------------------------------------- 1 | // Returns latest line to the date provided 2 | // Link structure: https://cld.silvestar.codes/get-line-by-date/:date: 3 | // Parameter :date: - [required] Date in format YYYY-MM-DD 4 | const lines = require('./lines.json') 5 | 6 | lines.list.sort((a, b) => { 7 | const aa = new Date(a.date) 8 | const bb = new Date(b.date) 9 | 10 | if (aa > bb) { 11 | return -1 12 | } 13 | 14 | if (aa < bb) { 15 | return 1 16 | } 17 | 18 | return 0 19 | }) 20 | 21 | exports.handler = function (event, context, callback) { 22 | const path = event.path.split('get-line-by-date') 23 | 24 | const date = path[1].replace('/', '') 25 | 26 | const ddate = new Date(date) 27 | 28 | const response = lines.list.find( 29 | line => new Date(line.date) <= ddate 30 | ) 31 | 32 | callback(null, { 33 | headers: { 34 | 'Access-Control-Allow-Origin': '*' 35 | }, 36 | statusCode: 200, 37 | body: JSON.stringify(response || []) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /api/get-line-by-lang.js: -------------------------------------------------------------------------------- 1 | // Returns latest line by language provided 2 | // Link structure: https://cld.silvestar.codes/get-line-by-lang/:lang: 3 | // Parameter :lang: - [required, case insensitive] Languages: HTML, CSS, JavaScript, PHP, Nodejs 4 | const lines = require('./lines.json') 5 | 6 | lines.list.sort((a, b) => { 7 | const aa = new Date(a.date) 8 | const bb = new Date(b.date) 9 | 10 | if (aa > bb) { 11 | return -1 12 | } 13 | 14 | if (aa < bb) { 15 | return 1 16 | } 17 | 18 | return 0 19 | }) 20 | 21 | exports.handler = function (event, context, callback) { 22 | const path = event.path.split('get-line-by-lang') 23 | 24 | const lang = path[1].replace('/', '') 25 | 26 | const response = lines.list.find( 27 | line => line.language.toLowerCase() === lang.toLowerCase() 28 | ) 29 | 30 | callback(null, { 31 | headers: { 32 | 'Access-Control-Allow-Origin': '*' 33 | }, 34 | statusCode: 200, 35 | body: JSON.stringify(response || []) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /api/get-lines-by-lang.js: -------------------------------------------------------------------------------- 1 | // Returns every line by language provided 2 | // Link structure: https://cld.silvestar.codes/get-lines-by-lang/:lang: 3 | // Parameter :lang: - [required, case insensitive] Languages: HTML, CSS, JavaScript, PHP, Nodejs 4 | const lines = require('./lines.json') 5 | 6 | lines.list.sort((a, b) => { 7 | const aa = new Date(a.date) 8 | const bb = new Date(b.date) 9 | 10 | if (aa > bb) { 11 | return -1 12 | } 13 | 14 | if (aa < bb) { 15 | return 1 16 | } 17 | 18 | return 0 19 | }) 20 | 21 | exports.handler = function (event, context, callback) { 22 | const path = event.path.split('get-lines-by-lang') 23 | 24 | const lang = path[1].replace('/', '') 25 | 26 | const response = lines.list.filter(line => line.language.toLowerCase() === lang.split('/')[0].oLowerCase()) 27 | 28 | callback(null, { 29 | headers: { 30 | 'Access-Control-Allow-Origin': '*' 31 | }, 32 | statusCode: 200, 33 | body: JSON.stringify(response) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /api/get-random-line.js: -------------------------------------------------------------------------------- 1 | // Returns random line 2 | // Link structure: https://cld.silvestar.codes/get-random-line 3 | const lines = require('./lines.json') 4 | 5 | function randomize (min, max) { 6 | const mmin = Math.ceil(min) 7 | const mmax = Math.floor(max) 8 | return Math.floor(Math.random() * (mmax - mmin)) + mmin 9 | } 10 | 11 | exports.handler = function (event, context, callback) { 12 | const rand = randomize(0, lines.list.length - 1) 13 | 14 | callback(null, { 15 | headers: { 16 | 'Access-Control-Allow-Origin': '*' 17 | }, 18 | statusCode: 200, 19 | body: JSON.stringify(lines.list[rand]) 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /api/post-on-twitter.js: -------------------------------------------------------------------------------- 1 | // Posts the latest line on Twitter 2 | // Link structure: https://cld.silvestar.codes/post-on-twitter: 3 | const Twitter = require('twitter'); 4 | const lines = require('./lines.json'); 5 | 6 | lines.list.sort((a, b) => { 7 | const aa = new Date(a.date); 8 | const bb = new Date(b.date); 9 | 10 | if (aa > bb) { 11 | return -1; 12 | } 13 | 14 | if (aa < bb) { 15 | return 1; 16 | } 17 | 18 | return 0; 19 | }); 20 | 21 | exports.handler = function (event, context, callback) { 22 | const ddate = new Date(); 23 | 24 | const lline = lines.list.find( 25 | (line) => new Date(line.date) <= ddate, 26 | ); 27 | 28 | const client = new Twitter({ 29 | consumer_key: process.env.CONSUMER_API_KEY, 30 | consumer_secret: process.env.CONSUMER_API_SECRET_KEY, 31 | access_token_key: process.env.ACCESS_TOKEN_KEY, 32 | access_token_secret: process.env.ACCESS_TOKEN_SECRET, 33 | }); 34 | 35 | const paramsUpdated = { 36 | status: `Did you know of this line of code: 37 | ${lline.line} 38 | 39 | ${lline.note} 40 | 41 | See more lines here: https://cld.silvestar.codes/line/${lline.date} 42 | #loc #cld #codelinedaily #${lline.language}`, 43 | }; 44 | 45 | const paramsTimeline = { 46 | screen_name: 'CodeLineDaily', 47 | count: 10, 48 | }; 49 | 50 | 51 | client.get('statuses/user_timeline', paramsTimeline) 52 | .then((tweets) => { 53 | let foundTweet = false; 54 | let cbBody = {}; 55 | 56 | tweets.forEach((tweet) => { 57 | if (tweet.text.indexOf(lline.line) !== -1) { 58 | foundTweet = tweet; 59 | } 60 | }); 61 | 62 | if (foundTweet) { 63 | cbBody = { 64 | message: 'Tweet already posted.', 65 | tweet: foundTweet, 66 | }; 67 | 68 | callback(null, { 69 | headers: { 70 | 'Access-Control-Allow-Origin': '*' 71 | }, 72 | statusCode: 200, 73 | body: JSON.stringify(cbBody || []), 74 | }); 75 | } else { 76 | client.post('statuses/update', paramsUpdated) 77 | .then((tweet) => { 78 | cbBody = { 79 | message: 'Tweet posted successfully.', 80 | tweet, 81 | }; 82 | 83 | callback(null, { 84 | headers: { 85 | 'Access-Control-Allow-Origin': '*' 86 | }, 87 | statusCode: 200, 88 | body: JSON.stringify(tweet || []), 89 | }); 90 | }) 91 | .catch((error) => { 92 | throw error; 93 | }); 94 | } 95 | }) 96 | .catch((error) => { 97 | throw error; 98 | }); 99 | }; 100 | -------------------------------------------------------------------------------- /contribute/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/contribute/.keep -------------------------------------------------------------------------------- /contribute/2019-08-04-wp_reset_postdata-silvestar-bistrović.json: -------------------------------------------------------------------------------- 1 | { 2 | "line": "wp_reset_postdata();", 3 | "note": "Reset context for WordPress query.", 4 | "link": "https://developer.wordpress.org/reference/functions/wp_reset_postdata/", 5 | "language": "php", 6 | "author": "Silvestar Bistrović", 7 | "email": "me@silvestar.codes", 8 | "bio": "About me." 9 | } 10 | -------------------------------------------------------------------------------- /contribute/2019-09-03-let-apples-shoppinglist-removelast-ethan-chin.json: -------------------------------------------------------------------------------- 1 | { 2 | "line": "let apples = shoppingList.removeLast()", 3 | "note": "Remove the final item from an array", 4 | "link": "https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html", 5 | "language": "Swift", 6 | "author": "Ethan Chin", 7 | "handle": "EthanChinCN", 8 | "email": "ethanchin.dev@gmail.com", 9 | "bio": "iDev." 10 | } -------------------------------------------------------------------------------- /contribute/2020-01-22-entries-array-heithem-moumni.json: -------------------------------------------------------------------------------- 1 | { 2 | "line": "myArray.entries()", 3 | "note": "Returns a new Array Iterator object that contains the key/value pairs for each index in the array.", 4 | "link": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap", 5 | "language": "JavaScript", 6 | "author": "Heithem Moumni", 7 | "handle": "heithemmoumni", 8 | "email": "moumniheithem@gmail.com", 9 | "bio": "A lover of accessability, Docker, JavaScript, IA, DevJoke Connoisseur." 10 | } 11 | -------------------------------------------------------------------------------- /contribute/2020-01-22-include-heithem-moumni.json: -------------------------------------------------------------------------------- 1 | { 2 | "line": "myArray.includes(item)", 3 | "note": "Determines whether an array includes a certain value among its entries, returning true or false as appropriate.", 4 | "link": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes", 5 | "language": "JavaScript", 6 | "author": "Heithem Moumni", 7 | "handle": "heithemmoumni", 8 | "email": "moumniheithem@gmail.com", 9 | "bio": "A lover of accessability, Docker, JavaScript, IA, DevJoke Connoisseur." 10 | } 11 | -------------------------------------------------------------------------------- /data/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "siteName": "Code Line Daily", 3 | "siteDesc": "A line of code of the day.", 4 | "siteURL": "https://cld.silvestar.codes", 5 | "siteImg": "https://cld.silvestar.codes/gfx/jpg/cover.jpg", 6 | "og": { 7 | "twitter_id": "CodeLineDaily", 8 | "twitter_creator": "malimirkeccita", 9 | "fb_id": "105883960764009", 10 | "fb_admins": "malimirkeccita" 11 | }, 12 | "menu": [{ 13 | "title": "Home", 14 | "href": "/" 15 | }, 16 | { 17 | "title": "Archive", 18 | "href": "/archive.html" 19 | }, 20 | { 21 | "title": "Evergreen", 22 | "href": "/evergreen.html" 23 | }, 24 | { 25 | "title": "About", 26 | "href": "/about.html" 27 | } 28 | ], 29 | "menu2": [{ 30 | "title": "Twitter", 31 | "href": "https://twitter.com/CodeLineDaily" 32 | }, 33 | { 34 | "title": "Facebook", 35 | "href": "https://www.facebook.com/CodeLineDaily" 36 | }, 37 | { 38 | "title": "GitHub", 39 | "href": "https://github.com/maliMirkec/code-line-daily" 40 | }, 41 | { 42 | "title": "RSS", 43 | "href": "/rss.xml" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /docs/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Pull Request Template 2 | 3 | To add a new line of code, please create a new file in the `contribute` folder. 4 | The file should should have the following structure: 5 | 6 | ```json 7 | { 8 | "line": "wp_reset_postdata();", 9 | "note": "Reset context for WordPress query.", 10 | "link": "https://developer.wordpress.org/reference/functions/wp_reset_postdata/", 11 | "language": "php", 12 | "author": "Silvestar Bistrović", 13 | "email": "me@silvestar.codes", 14 | "bio": "About me." 15 | } 16 | ``` 17 | 18 | For all other issues, please use your best judgement, but please follow the Code of Conduction. 19 | -------------------------------------------------------------------------------- /gulpfile.js/.bump.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": ["helpers.proot/package.json"] 3 | } 4 | -------------------------------------------------------------------------------- /gulpfile.js/.critical.json: -------------------------------------------------------------------------------- 1 | { 2 | "temp": "helpers.source/critical/", 3 | "configs": [{ 4 | "src": "style.css", 5 | "settings": { 6 | "out": "style.critical.css", 7 | "url": "http://localhost:8083/", 8 | "width": 1920, 9 | "height": 2000, 10 | "keepLargerMediaQueries": true, 11 | "strict": false, 12 | "blockJSRequests": false, 13 | "renderWaitTime": 2000, 14 | "phantomJsOptions": { 15 | "ssl-protocol": "any", 16 | "ignore-ssl-errors": true 17 | } 18 | } 19 | }] 20 | } 21 | -------------------------------------------------------------------------------- /gulpfile.js/.css.json: -------------------------------------------------------------------------------- 1 | { 2 | "sassConfig": { 3 | "includePaths": [ 4 | "helpers.proot/node_modules/modularscale-sass/stylesheets/", 5 | "helpers.proot/node_modules/sass-mq/", 6 | "helpers.proot/node_modules/normalize.css/", 7 | "helpers.source/config.css.src/", 8 | "helpers.source/config.css.src/components/" 9 | ] 10 | }, 11 | "styleLintConfig": { 12 | "reporters": [{ 13 | "formatter": "string", 14 | "console": true 15 | }] 16 | }, 17 | "autoprefixerConfig": { 18 | "cascade": false 19 | }, 20 | "renameConfig": { 21 | "suffix": ".min" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gulpfile.js/.favicon-data-generated.json: -------------------------------------------------------------------------------- 1 | {"result":{"status":"success"},"favicon":{"package_url":"https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/favicon_package_v0.16.zip","files_urls":["https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/README.md","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/android-chrome-192x192.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/android-chrome-512x512.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/apple-touch-icon.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/browserconfig.xml","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/favicon-16x16.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/favicon-32x32.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/favicon.ico","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/html_code.html","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/mstile-144x144.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/mstile-150x150.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/mstile-310x150.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/mstile-310x310.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/mstile-70x70.png","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/safari-pinned-tab.svg","https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/package_files/site.webmanifest"],"html_code":"\n\n\n\n\n\n\n\n\n\n\n","compression":"true","overlapping_markups":["link[rel=\"apple-touch-icon\"]","meta[name=\"apple-mobile-web-app-title\"]","link[rel=\"shortcut\"]","link[rel=\"shortcut icon\"]","link[rel=\"icon\",sizes=\"16x16\"]","link[rel=\"icon\",sizes=\"32x32\"]","meta[name=\"msapplication-TileColor\"]","meta[name=\"msapplication-TileImage\"]","meta[name=\"msapplication-config\"]","meta[name=\"application-name\"]","link[rel=\"manifest\"]","meta[name=\"theme-color\"]","link[rel=\"mask-icon\"]"]},"files_location":{"type":"path","path":"/favicons/"},"preview_picture_url":"https://realfavicongenerator.net/files/1c93ebc0d49b4f4396f2540f76e77df44d3879f9/favicon_preview.png","version":"0.16"} -------------------------------------------------------------------------------- /gulpfile.js/.favicon-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "masterPicture": "helpers.source/gfx/svg/cld-logo.svg", 3 | "temp": "helpers.source/favicons/", 4 | "dest": "helpers.dist/favicons/", 5 | "iconsPath": "/favicons/", 6 | "markupFile": "helpers.proot/gulpfile.js/.favicon-data-generated.json", 7 | "design": { 8 | "ios": { 9 | "pictureAspect": "backgroundAndMargin", 10 | "backgroundColor": "#12e09f", 11 | "margin": "14%", 12 | "assets": { 13 | "ios6AndPriorIcons": false, 14 | "ios7AndLaterIcons": false, 15 | "precomposedIcons": false, 16 | "declareOnlyDefaultIcon": true 17 | }, 18 | "appName": "Code Line Daily" 19 | }, 20 | "desktopBrowser": {}, 21 | "windows": { 22 | "pictureAspect": "noChange", 23 | "backgroundColor": "#12e09f", 24 | "onConflict": "override", 25 | "assets": { 26 | "windows80Ie10Tile": false, 27 | "windows10Ie11EdgeTiles": { 28 | "small": false, 29 | "medium": true, 30 | "big": false, 31 | "rectangle": false 32 | } 33 | }, 34 | "appName": "Code Line Daily" 35 | }, 36 | "androidChrome": { 37 | "pictureAspect": "shadow", 38 | "themeColor": "#12e09f", 39 | "manifest": { 40 | "name": "Code Line Daily", 41 | "display": "standalone", 42 | "orientation": "notSet", 43 | "onConflict": "override", 44 | "declared": true 45 | }, 46 | "assets": { 47 | "legacyIcon": false, 48 | "lowResolutionIcons": false 49 | } 50 | }, 51 | "safariPinnedTab": { 52 | "pictureAspect": "blackAndWhite", 53 | "threshold": 35.3125, 54 | "themeColor": "#12e09f" 55 | } 56 | }, 57 | "settings": { 58 | "compression": 5, 59 | "scalingAlgorithm": "Cubic", 60 | "errorOnImageTooSmall": false, 61 | "readmeFile": true, 62 | "htmlCodeFile": true, 63 | "usePathAsIs": false 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gulpfile.js/.favicon.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": "helpers.source/config.html.src/_assets/favicon.pug", 3 | "dest": "helpers.source/config.html.src/_assets" 4 | } 5 | -------------------------------------------------------------------------------- /gulpfile.js/.gfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "gifConfig": { 3 | "interlaced": true 4 | }, 5 | "jpegConfig": { 6 | "quality": 90, 7 | "progressive": true 8 | }, 9 | "pngConfig": { 10 | "quality": [0.8, 0.9] 11 | }, 12 | "svgConfig": { 13 | "plugins": [ 14 | { 15 | "cleanupAttrs": true 16 | }, 17 | { 18 | "removeDoctype": true 19 | }, 20 | { 21 | "removeComments": true 22 | }, 23 | { 24 | "removeXMLProcInst": true 25 | }, 26 | { 27 | "removeMetadata": true 28 | }, 29 | { 30 | "removeTitle": false 31 | }, 32 | { 33 | "removeDesc": false 34 | }, 35 | { 36 | "removeUselessDefs": true 37 | }, 38 | { 39 | "removeXMLNS": false 40 | }, 41 | { 42 | "removeEditorsNSData": true 43 | }, 44 | { 45 | "removeEmptyAttrs": true 46 | }, 47 | { 48 | "removeHiddenElems": true 49 | }, 50 | { 51 | "removeEditorsNSData": true 52 | }, 53 | { 54 | "removeEmptyText": true 55 | }, 56 | { 57 | "removeEmptyContainers": true 58 | }, 59 | { 60 | "removeViewBox": false 61 | }, 62 | { 63 | "cleanupEnableBackground": true 64 | }, 65 | { 66 | "convertStyleToAttrs": true 67 | }, 68 | { 69 | "convertColors": true 70 | }, 71 | { 72 | "convertPathData": true 73 | }, 74 | { 75 | "convertTransform": true 76 | }, 77 | { 78 | "removeUnknownsAndDefaults": true 79 | }, 80 | { 81 | "removeNonInheritableGroupAttrs": true 82 | }, 83 | { 84 | "removeUselessStrokeAndFill": true 85 | }, 86 | { 87 | "removeUnusedNS": true 88 | }, 89 | { 90 | "cleanupIDs": false 91 | }, 92 | { 93 | "cleanupNumericValues": true 94 | }, 95 | { 96 | "cleanupListOfValues": true 97 | }, 98 | { 99 | "moveElemsAttrsToGroup": true 100 | }, 101 | { 102 | "moveGroupAttrsToElems": false 103 | }, 104 | { 105 | "collapseGroups": true 106 | }, 107 | { 108 | "removeRasterImages": true 109 | }, 110 | { 111 | "mergePaths": true 112 | }, 113 | { 114 | "convertShapeToPath": false 115 | }, 116 | { 117 | "sortAttrs": true 118 | }, 119 | { 120 | "removeDimensions": true 121 | }, 122 | { 123 | "removeAttrs": false 124 | }, 125 | { 126 | "removeElementsByAttr": false 127 | }, 128 | { 129 | "addClassesToSVGElement": false 130 | }, 131 | { 132 | "addAttributesToSVGElement": false 133 | }, 134 | { 135 | "removeStyleElement": false 136 | }, 137 | { 138 | "removeScriptElement": false 139 | }, 140 | { 141 | "removeDimensions": false 142 | } 143 | ] 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /gulpfile.js/.helpers.json: -------------------------------------------------------------------------------- 1 | { 2 | "wait": 20000 3 | } 4 | -------------------------------------------------------------------------------- /gulpfile.js/.html.json: -------------------------------------------------------------------------------- 1 | { 2 | "pugConfig": { 3 | "basedir": "", 4 | "pretty": true 5 | }, 6 | "htmllintConfig": { 7 | "config": "", 8 | "failOnError": false 9 | }, 10 | "htmlminConfig": { 11 | "collapseWhitespace": true 12 | }, 13 | "renameConfig": { 14 | "extname": ".html" 15 | }, 16 | "inlineConfig": { 17 | "rootpath": "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gulpfile.js/.js.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslintConfig": { 3 | "configFile": "helpers.proot/.eslintrc.json", 4 | "fix": true, 5 | "quiet": true 6 | }, 7 | "includeConfig": { 8 | "hardFail": true, 9 | "includePaths": [ 10 | "helpers.proot/node_modules" 11 | ] 12 | }, 13 | "babelConfig": { 14 | "presets": ["@babel/env"] 15 | }, 16 | "standardConfig": { 17 | "breakOnError": false, 18 | "showRuleNames": true, 19 | "standard": { 20 | "globals": [ 21 | "requestAnimationFrame", 22 | "sessionStorage" 23 | ] 24 | } 25 | }, 26 | "renameConfig": { 27 | "suffix": ".min" 28 | }, 29 | "swConfig": { 30 | "globDirectory": "helpers.dist/", 31 | "globPatterns": [ 32 | "**/*.{html,webmanifest,css,eot,svg,ttf,woff,woff2,png,js,ico,jpg}" 33 | ], 34 | "globIgnores": [ 35 | "docs/**/*", 36 | "mixins/**/*", 37 | "gfx/cover/**/*", 38 | "cms/**/*", 39 | "css/kss.*", 40 | "*.critical.css", 41 | "favicons/*.{png,jpg,svg}" 42 | ], 43 | "swDest": "helpers.dist/sw.js", 44 | "swSrc": "helpers.source/sw/sw.js" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gulpfile.js/.jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "helpers.source/config.js.src/homepage.md", 4 | "helpers.source/config.js.src/" 5 | ], 6 | "settings": { 7 | "tags": { 8 | "allowUnknownTags": true 9 | }, 10 | "opts": { 11 | "destination": "helpers.dist/config.jsdoc.dist/" 12 | }, 13 | "plugins": [ 14 | "plugins/markdown" 15 | ], 16 | "templates": { 17 | "cleverLinks": true, 18 | "monospaceLinks": false, 19 | "default": { 20 | "outputSourceFiles": true 21 | }, 22 | "path": "ink-docstrap", 23 | "theme": "simplex", 24 | "navType": "vertical", 25 | "linenums": true, 26 | "dateFormat": "MMMM Do YYYY, h:mm:ss a" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gulpfile.js/.kss.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Code Line Daily", 3 | "source": "helpers.source", 4 | "destination": "helpers.dist/config.kss.dist/", 5 | "css": [ 6 | "/config.css.dist/style.css", 7 | "/config.css.dist/foft.css", 8 | "/config.css.dist/kss.css" 9 | ], 10 | "js": [ 11 | "/js/foftFontLoading.js" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /gulpfile.js/.sassdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "dest": "helpers.dist/config.sassdoc.dist/", 3 | "package": "package.json", 4 | "autofill": true, 5 | "verbose": true, 6 | "theme": "default", 7 | "display": { 8 | "access": ["public", "private"], 9 | "alias": true, 10 | "watermark": true 11 | }, 12 | "groups": { 13 | "undefined": "Misc" 14 | }, 15 | "basePath": "https://cld.silvestar.codes/docs/sass/" 16 | } 17 | -------------------------------------------------------------------------------- /gulpfile.js/.starter-project.json: -------------------------------------------------------------------------------- 1 | { 2 | "proot": "./", 3 | "src": "src", 4 | "dist": "dist", 5 | "sync": { 6 | "run": true 7 | }, 8 | "html": { 9 | "run": true, 10 | "pug": true, 11 | "src": "html", 12 | "dist": "", 13 | "minify": true, 14 | "inline": true, 15 | "lint": true 16 | }, 17 | "xml": { 18 | "run": true, 19 | "pug": true, 20 | "src": "xml", 21 | "dist": "", 22 | "minify": true, 23 | "inline": false, 24 | "lint": false 25 | }, 26 | "css": { 27 | "run": true, 28 | "sass": true, 29 | "src": "scss", 30 | "dist": "css", 31 | "minify": true, 32 | "autoprefix": true, 33 | "sourcemaps": true, 34 | "lint": true 35 | }, 36 | "js": { 37 | "run": true, 38 | "src": "js", 39 | "dist": "js", 40 | "uglify": true, 41 | "sourcemaps": true, 42 | "lint": true 43 | }, 44 | "gfx": { 45 | "run": true, 46 | "src": "gfx", 47 | "dist": "gfx" 48 | }, 49 | "fonts": { 50 | "run": true, 51 | "src": "fonts", 52 | "dist": "fonts" 53 | }, 54 | "favicon": { 55 | "run": true 56 | }, 57 | "critical": { 58 | "run": true 59 | }, 60 | "gzip": { 61 | "run": false 62 | }, 63 | "kss": { 64 | "run": true, 65 | "dist": "docs/styleguide" 66 | }, 67 | "sassdoc": { 68 | "run": true, 69 | "dist": "docs/sass" 70 | }, 71 | "jsdoc": { 72 | "run": true, 73 | "dist": "docs/js" 74 | }, 75 | "bump": { 76 | "run": true 77 | }, 78 | "cms": { 79 | "run": true, 80 | "adminSrc": "cms", 81 | "adminDist": "cms", 82 | "commitSrc": "commit", 83 | "commitDist": "commit" 84 | }, 85 | "yarn": true 86 | } 87 | -------------------------------------------------------------------------------- /gulpfile.js/.sync.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 8083, 3 | "server": { 4 | "baseDir": "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /gulpfile.js/.watch.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignoreInitial": true 3 | } 4 | -------------------------------------------------------------------------------- /gulpfile.js/.xml.json: -------------------------------------------------------------------------------- 1 | { 2 | "pugConfig": { 3 | "basedir": "", 4 | "pretty": true 5 | }, 6 | "htmlminConfig": { 7 | "collapseWhitespace": true 8 | }, 9 | "renameConfig": { 10 | "extname": ".xml" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /gulpfile.js/bump.js: -------------------------------------------------------------------------------- 1 | const { src, dest } = require('gulp'); 2 | const bump = require('gulp-bump'); 3 | 4 | const { helpers } = require('./helpers'); 5 | 6 | const bumpConfig = require('./.bump.json'); 7 | 8 | // Will patch the version 9 | function patch(cb) { 10 | src(bumpConfig.src.map((path) => helpers.parse(path))) 11 | .pipe(bump()) 12 | .pipe(dest(global.config.proot)); 13 | 14 | cb(); 15 | } 16 | 17 | // Will update minor version 18 | function minor(cb) { 19 | src(bumpConfig.src.map((path) => helpers.parse(path))) 20 | .pipe(bump({ 21 | type: 'minor', 22 | })) 23 | .pipe(dest(global.config.proot)); 24 | 25 | cb(); 26 | } 27 | 28 | // Will update major version 29 | function major(cb) { 30 | src(bumpConfig.src.map((path) => helpers.parse(path))) 31 | .pipe(bump({ 32 | type: 'major', 33 | })) 34 | .pipe(dest(global.config.proot)); 35 | 36 | cb(); 37 | } 38 | 39 | // Will update prerelease version 40 | function prerelease(cb) { 41 | src(bumpConfig.src.map((path) => helpers.parse(path))) 42 | .pipe(bump({ 43 | type: 'prerelease', 44 | })) 45 | .pipe(dest(global.config.proot)); 46 | 47 | cb(); 48 | } 49 | 50 | exports.bump = { 51 | patch, 52 | minor, 53 | major, 54 | prerelease, 55 | }; 56 | -------------------------------------------------------------------------------- /gulpfile.js/clean.js: -------------------------------------------------------------------------------- 1 | // const gulp = require('gulp') 2 | const del = require('del'); 3 | 4 | const { helpers } = require('./helpers'); 5 | 6 | // Will delete dist folder 7 | function cleanStart() { 8 | return del(helpers.dist()); 9 | } 10 | 11 | // Will delete dist folder 12 | function cleanLines() { 13 | return del(helpers.trim(`${helpers.dist()}/${global.config.html.dist}/line/`)); 14 | } 15 | 16 | exports.clean = { 17 | cleanStart, 18 | cleanLines, 19 | }; 20 | -------------------------------------------------------------------------------- /gulpfile.js/cms.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | 3 | const { helpers } = require('./helpers'); 4 | 5 | // Will process font files, too 6 | function adminStart() { 7 | return src(helpers.trim(`${helpers.source()}/${global.config.cms.adminSrc}/**/*`)) 8 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.cms.adminDist}`))); 9 | } 10 | 11 | // Will process font files, too 12 | function commitStart() { 13 | return src(helpers.trim(`${helpers.source()}/${global.config.cms.commitSrc}/**/*`)) 14 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.cms.commitDist}`))); 15 | } 16 | 17 | // When font is changed, it will process font file, too 18 | function adminListen() { 19 | return watch(helpers.trim(`${helpers.source()}/${global.config.cms.src}/**/*`), global.config.watchConfig, adminStart, global.bs.reload); 20 | } 21 | 22 | // When font is changed, it will process font file, too 23 | function commitListen() { 24 | return watch(helpers.trim(`${helpers.source()}/${global.config.cms.src}/**/*`), global.config.watchConfig, commitStart, global.bs.reload); 25 | } 26 | 27 | exports.cms = { 28 | adminStart, 29 | adminListen, 30 | commitStart, 31 | commitListen, 32 | }; 33 | -------------------------------------------------------------------------------- /gulpfile.js/critical.js: -------------------------------------------------------------------------------- 1 | const { src, dest } = require('gulp'); 2 | const critical = require('gulp-penthouse'); 3 | const cleanCSS = require('gulp-clean-css'); 4 | const rename = require('gulp-rename'); 5 | const fs = require('fs'); 6 | 7 | critical.DEBUG = process.env.NODE_ENV !== 'production'; 8 | 9 | const { helpers } = require('./helpers'); 10 | 11 | const criticalConfig = require('./.critical.json'); 12 | const cssConfig = require('./.css.json'); 13 | 14 | const thisCriticalConfig = { ...criticalConfig, temp: `${helpers.parse(criticalConfig.temp)}` }; 15 | 16 | // Will extract Critical CSS 17 | function criticalStart(cb) { 18 | const files = []; 19 | 20 | thisCriticalConfig.configs.forEach((config) => { 21 | const thisSettings = { ...config.settings, out: helpers.trim(`/${config.settings.out}`) }; 22 | 23 | const thisFile = helpers.trim(`${thisCriticalConfig.temp}/${thisSettings.out}`); 24 | 25 | files.push(thisFile); 26 | 27 | if (fs.existsSync(thisFile)) { 28 | src(thisFile.replace('.css', '*.css')) 29 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))); 30 | } else { 31 | const thisConfig = { 32 | ...config, 33 | src: helpers.trim(`${helpers.dist()}/${global.config.css.dist}/${config.src}`), 34 | settings: thisSettings, 35 | }; 36 | 37 | src(thisConfig.src) 38 | .pipe(critical(thisConfig.settings)) 39 | .pipe(dest(helpers.trim(`${thisCriticalConfig.temp}`))) 40 | .pipe(cleanCSS()) 41 | .pipe(rename(cssConfig.renameConfig)) 42 | .pipe(dest(helpers.trim(`${thisCriticalConfig.temp}`))) 43 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))); 44 | } 45 | }); 46 | 47 | const checkInterval = setInterval(() => { 48 | let checkFile = true; 49 | 50 | files.forEach((file) => { 51 | if (!fs.existsSync(file)) { 52 | checkFile = false; 53 | } 54 | }); 55 | 56 | if (checkFile) { 57 | clearInterval(checkInterval); 58 | cb(); 59 | } 60 | }, 250); 61 | 62 | return checkInterval; 63 | } 64 | 65 | exports.critical = { 66 | criticalStart, 67 | }; 68 | -------------------------------------------------------------------------------- /gulpfile.js/css.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | const gulpif = require('gulp-if'); 3 | const cssimport = require('gulp-cssimport'); 4 | const gulpStylelint = global.config.css.lint ? require('gulp-stylelint') : () => true; 5 | const sass = global.config.css.sass ? require('gulp-sass') : () => true; 6 | const autoprefixer = global.config.css.autoprefix ? require('gulp-autoprefixer') : () => true; 7 | const sourcemaps = global.config.css.sourcemaps ? require('gulp-sourcemaps') : () => true; 8 | const cleanCSS = global.config.css.minify ? require('gulp-clean-css') : () => true; 9 | const rename = global.config.css.minify ? require('gulp-rename') : () => true; 10 | 11 | const { helpers } = require('./helpers'); 12 | 13 | const cssConfig = require('./.css.json'); 14 | 15 | const thisSassConfig = (global.config.css.sass) 16 | ? ({ 17 | ...cssConfig.sassConfig, 18 | includePaths: cssConfig.sassConfig.includePaths.map((path) => helpers.parse(path)), 19 | }) 20 | : {}; 21 | 22 | // gulp-if fix 23 | if (!global.config.css.sourcemaps) { 24 | sourcemaps.init = () => true; 25 | sourcemaps.write = () => true; 26 | } 27 | 28 | // Will process Sass files 29 | function cssStart() { 30 | return src(helpers.trim(`${helpers.source()}/${global.config.css.src}/*.scss`)) 31 | .pipe(gulpif(global.config.css.sourcemaps, sourcemaps.init())) 32 | .pipe(gulpif(global.config.css.lint, gulpStylelint(cssConfig.styleLintConfig))) 33 | .pipe(gulpif(global.config.css.sass, sass(thisSassConfig).on('error', sass.logError))) 34 | .pipe(cssimport()) 35 | .pipe(gulpif(global.config.css.autoprefix, autoprefixer(cssConfig.autoprefixerConfig))) 36 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))) 37 | .pipe(gulpif(global.config.css.minify, cleanCSS())) 38 | .pipe(gulpif(global.config.css.minify, rename(cssConfig.renameConfig))) 39 | .pipe(gulpif(global.config.css.sourcemaps, sourcemaps.write(helpers.trim(`${helpers.source()}/${global.config.css.dist}`)))) 40 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))) 41 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 42 | } 43 | 44 | // Will process non Critical Sass files 45 | function cssStartListen() { 46 | return src([helpers.trim(`${helpers.source()}/${global.config.css.src}/*.scss`), helpers.trim(`!${helpers.source()}/${global.config.css.src}/*.critical.scss`)]) 47 | .pipe(gulpif(global.config.css.sourcemaps, sourcemaps.init())) 48 | .pipe(gulpif(global.config.css.lint, gulpStylelint(cssConfig.styleLintConfig))) 49 | .pipe(gulpif(global.config.css.sass, sass(thisSassConfig).on('error', sass.logError))) 50 | .pipe(cssimport()) 51 | .pipe(gulpif(global.config.css.autoprefix, autoprefixer(cssConfig.autoprefixerConfig))) 52 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))) 53 | .pipe(gulpif(global.config.css.minify, cleanCSS())) 54 | .pipe(gulpif(global.config.css.minify, rename(cssConfig.renameConfig))) 55 | .pipe(gulpif(global.config.css.sourcemaps, sourcemaps.write(helpers.trim(`${helpers.source()}/${global.config.css.dist}`)))) 56 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.css.dist}`))) 57 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 58 | } 59 | 60 | // When Sass file is changed, it will process Sass file, too 61 | function cssListen() { 62 | return watch(helpers.trim(`${helpers.source()}/${global.config.css.src}/**/*.scss`), global.config.watchConfig, cssStartListen, global.bs.reload); 63 | } 64 | 65 | exports.css = { 66 | cssStart, 67 | cssListen, 68 | }; 69 | -------------------------------------------------------------------------------- /gulpfile.js/favicon.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | const realFavicon = require('gulp-real-favicon'); 3 | const fs = require('fs'); 4 | 5 | const { helpers } = require('./helpers'); 6 | 7 | const faviconConfig = require('./.favicon.json'); 8 | const faviconDataConfig = require('./.favicon-data.json'); 9 | 10 | const thisFaviconDataConfig = { 11 | ...faviconDataConfig, 12 | masterPicture: `${helpers.parse(faviconDataConfig.masterPicture)}`, 13 | temp: `${helpers.parse(faviconDataConfig.temp)}`, 14 | dest: `${helpers.parse(faviconDataConfig.dest)}`, 15 | iconsPath: `${helpers.parse(faviconDataConfig.iconsPath)}`, 16 | markupFile: `${helpers.parse(faviconDataConfig.markupFile)}`, 17 | }; 18 | 19 | // Will process favicon file 20 | function faviconStart(cb) { 21 | if (fs.existsSync(helpers.trim(`${thisFaviconDataConfig.temp}/favicon.ico`))) { 22 | src(helpers.trim(`${thisFaviconDataConfig.temp}/*`)) 23 | .pipe(dest(helpers.trim(`${thisFaviconDataConfig.dest}`))); 24 | 25 | cb(); 26 | } else { 27 | realFavicon.generateFavicon(thisFaviconDataConfig, () => { 28 | if (fs.existsSync(thisFaviconDataConfig.markupFile)) { 29 | src(helpers.trim(`${thisFaviconDataConfig.dest}/*`)) 30 | .pipe(dest(helpers.trim(`${thisFaviconDataConfig.temp}`))); 31 | 32 | const parsedFaviconFile = JSON.parse(fs.readFileSync(thisFaviconDataConfig.markupFile)); 33 | 34 | src(helpers.parse(faviconConfig.src)) 35 | .pipe(realFavicon.injectFaviconMarkups(parsedFaviconFile.favicon.html_code)) 36 | .pipe(dest(helpers.parse(faviconConfig.dest))); 37 | } 38 | 39 | cb(); 40 | }); 41 | } 42 | } 43 | 44 | // When favicon file change, it will process favicon file, too 45 | function faviconListen() { 46 | return watch(helpers.trim(`${helpers.source()}/${global.config.favicon.src}/**/*`), global.config.watchConfig, faviconStart, global.bs.reload); 47 | } 48 | 49 | exports.favicon = { 50 | faviconStart, 51 | faviconListen, 52 | }; 53 | -------------------------------------------------------------------------------- /gulpfile.js/fonts.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | 3 | const { helpers } = require('./helpers'); 4 | 5 | // Will process font files, too 6 | function fontsStart() { 7 | return src(helpers.trim(`${helpers.source()}/${global.config.fonts.src}/**/*`)) 8 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.fonts.dist}`))); 9 | } 10 | 11 | // When font is changed, it will process font file, too 12 | function fontsListen() { 13 | return watch(helpers.trim(`${helpers.source()}/${global.config.fonts.src}/**/*`), global.config.watchConfig, fontsStart, global.bs.reload); 14 | } 15 | 16 | exports.fonts = { 17 | fontsStart, 18 | fontsListen, 19 | }; 20 | -------------------------------------------------------------------------------- /gulpfile.js/gfx.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | const gulpif = require('gulp-if'); 3 | const imagemin = require('gulp-imagemin'); 4 | const imageminMozjpeg = require('imagemin-mozjpeg'); 5 | const imageminPngquant = require('imagemin-pngquant'); 6 | 7 | const { helpers } = require('./helpers'); 8 | 9 | const gfxConfig = require('./.gfx.json'); 10 | 11 | // Will process image files 12 | function gfxStart() { 13 | return src(helpers.trim(`${helpers.source()}/${global.config.gfx.src}/**/*`)) 14 | .pipe(imagemin([ 15 | imagemin.gifsicle(gfxConfig.gifConfig), 16 | imageminMozjpeg(gfxConfig.jpegConfig), 17 | imageminPngquant(gfxConfig.pngConfig), 18 | imagemin.svgo(gfxConfig.svgConfig), 19 | ])) 20 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.gfx.dist}`))) 21 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 22 | } 23 | 24 | // When image is changed, it will process image file, too 25 | function gfxListen() { 26 | return watch(helpers.trim(`${helpers.source()}/${global.config.gfx.src}/**/*`), global.config.watchConfig, gfxStart, global.bs.reload); 27 | } 28 | 29 | exports.gfx = { 30 | gfxStart, 31 | gfxListen, 32 | }; 33 | -------------------------------------------------------------------------------- /gulpfile.js/helpers.js: -------------------------------------------------------------------------------- 1 | const { src } = require('gulp'); 2 | const exit = require('gulp-exit'); 3 | const wait = require('gulp-wait'); 4 | 5 | const helpersConfig = require('./.helpers.json'); 6 | 7 | // Will remove end slash from path 8 | const trim = (p) => { 9 | let r = p; 10 | while (r.indexOf('..') !== -1) { 11 | r = r.replace('..', ''); 12 | } 13 | 14 | while (r.indexOf('//') !== -1) { 15 | r = r.replace('//', '/'); 16 | } 17 | 18 | return r; 19 | }; 20 | 21 | // Will return root folder 22 | const proot = () => trim(`${global.config.proot}/`); 23 | 24 | // Will return root src folder 25 | const source = () => trim(`${global.config.proot}/${global.config.src}`); 26 | 27 | // Will return root dest folder 28 | const dist = () => trim(`${global.config.proot}/${global.config.dist}`); 29 | 30 | // Will parse path 31 | const parse = (p) => p.replace('helpers.proot/', proot()) 32 | .replace('helpers.dist', dist()).replace('helpers.source', source()) 33 | .replace('config.css.src', global.config.css.src) 34 | .replace('config.css.dist', global.config.css.dist) 35 | .replace('config.js.src', global.config.js.src) 36 | .replace('config.js.dist', global.config.js.dist) 37 | .replace('config.html.src', global.config.html.src) 38 | .replace('config.html.dist', global.config.html.dist) 39 | .replace('config.kss.dist', global.config.kss.dist) 40 | .replace('config.sassdoc.dist', global.config.sassdoc.dist) 41 | .replace('config.jsdoc.dist', global.config.jsdoc.dist); 42 | 43 | // Will skip the task 44 | const skip = (cb) => cb(); 45 | 46 | // Will kill all tasks after delay 47 | const kill = (cb) => { 48 | src(proot()) 49 | .pipe(wait(helpersConfig.wait)) 50 | .pipe(exit()); 51 | 52 | cb(); 53 | }; 54 | 55 | // Will kill all tasks immidiately 56 | const killNow = (cb) => { 57 | src(proot()) 58 | .pipe(exit()); 59 | 60 | cb(); 61 | }; 62 | 63 | exports.helpers = { 64 | proot, 65 | trim, 66 | source, 67 | dist, 68 | skip, 69 | kill, 70 | killNow, 71 | parse, 72 | }; 73 | -------------------------------------------------------------------------------- /gulpfile.js/html.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | const gulpif = require('gulp-if'); 3 | const rename = require('gulp-rename'); 4 | const path = require('path'); 5 | const pug = global.config.html.pug ? require('gulp-pug') : () => true; 6 | const data = global.config.html.pug ? require('gulp-data') : () => true; 7 | const htmlmin = global.config.html.minify ? require('gulp-htmlmin') : () => true; 8 | const htmllint = global.config.html.lint ? require('gulp-htmllint') : () => true; 9 | const inlineSource = global.config.html.inline ? require('gulp-inline-source') : () => true; 10 | const replace = global.config.html.pug ? require('gulp-replace') : () => true; 11 | const wait = require('gulp-wait'); 12 | const fs = global.config.html.inline ? require('fs') : () => true; 13 | 14 | const { helpers } = require('./helpers'); 15 | 16 | const htmlConfig = require('./.html.json'); 17 | const xmlConfig = require('./.xml.json'); 18 | 19 | const siteConfigs = [{ 20 | name: 'site', 21 | path: helpers.trim(`${helpers.proot()}/data/site.json`), 22 | }, { 23 | name: 'data', 24 | path: helpers.trim(`${helpers.proot()}/api/lines.json`), 25 | }]; 26 | 27 | let thisPugConfigHTML = {}; 28 | 29 | if (global.config.html.pug) { 30 | thisPugConfigHTML = htmlConfig.pugConfig.basedir 31 | ? htmlConfig.pugConfig 32 | : ({ ...htmlConfig.pugConfig, basedir: helpers.trim(`${helpers.source()}/${global.config.html.src}/`) }); 33 | } 34 | 35 | let thisHtmllintConfig = {}; 36 | 37 | if (global.config.html.lint) { 38 | thisHtmllintConfig = htmlConfig.htmllintConfig.config 39 | ? htmlConfig.htmllintConfig.config 40 | : ({ ...htmlConfig.htmllintConfig, config: `${helpers.proot()}.htmllintrc` }); 41 | } 42 | 43 | let thisInlineConfigHTML = {}; 44 | 45 | if (global.config.html.inline) { 46 | thisInlineConfigHTML = htmlConfig.inlineConfig.rootpath 47 | ? htmlConfig.inlineConfig 48 | : ({ ...htmlConfig.inlineConfig, rootpath: path.resolve(helpers.dist()) }); 49 | } 50 | 51 | const htmlSrc = global.config.html.pug 52 | ? [helpers.trim(`${helpers.source()}/${global.config.html.src}/**/*.pug`), helpers.trim(`!${helpers.source()}/${global.config.html.src}/_**/*.pug`), helpers.trim(`!${helpers.source()}/${global.config.html.src}/**/_**/*.pug`)] 53 | : helpers.trim(`${helpers.source()}/${global.config.html.src}/**/*.html`); 54 | 55 | // Will process Pug files 56 | function htmlStart() { 57 | return src(htmlSrc) 58 | .pipe(gulpif(global.config.html.pug, data(() => { 59 | const temp = {}; 60 | 61 | siteConfigs.forEach((siteConfig) => { 62 | temp[siteConfig.name] = JSON.parse(fs.readFileSync(siteConfig.path)); 63 | }); 64 | 65 | return temp; 66 | }))) 67 | .pipe(gulpif(global.config.html.pug, pug(thisPugConfigHTML))) 68 | .pipe(gulpif(global.config.html.lint, htmllint(thisHtmllintConfig))) 69 | .pipe(wait(1000)) 70 | .pipe(gulpif(global.config.html.inline, inlineSource(thisInlineConfigHTML))) 71 | .pipe(gulpif(global.config.html.minify, htmlmin(htmlConfig.htmlminConfig))) 72 | .pipe(rename(htmlConfig.renameConfig)) 73 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.html.dist}`))) 74 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 75 | } 76 | 77 | // Will dynamically create page for each line 78 | function lineStart(cb) { 79 | const lineSrc = helpers.trim(`${helpers.source()}/${global.config.html.src}/_layout/line.pug`); 80 | const siteConfig = siteConfigs.find((sc) => sc.name === 'site'); 81 | const dataConfig = siteConfigs.find((sc) => sc.name === 'data'); 82 | const dataLines = JSON.parse(fs.readFileSync(dataConfig.path)); 83 | 84 | dataLines.list.map((dataLine, index, array) => src(lineSrc) 85 | .pipe(gulpif(global.config.html.pug, data(() => ({ 86 | site: JSON.parse(fs.readFileSync(siteConfig.path)), 87 | line: dataLine, 88 | previous: array[index - 1] ? array[index - 1] : false, 89 | next: array[index + 1] ? array[index + 1] : false, 90 | })))) 91 | .pipe(gulpif(global.config.html.pug, pug(thisPugConfigHTML))) 92 | .pipe(gulpif(global.config.html.lint, htmllint(thisHtmllintConfig))) 93 | .pipe(wait(1000)) 94 | .pipe(gulpif(global.config.html.inline, inlineSource(thisInlineConfigHTML))) 95 | .pipe(gulpif(global.config.html.minify, htmlmin(htmlConfig.htmlminConfig))) 96 | .pipe(rename({ 97 | dirname: helpers.proot(), 98 | basename: dataLine.date, 99 | extname: htmlConfig.renameConfig.extname, 100 | })) 101 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.html.dist}/line/`)))); 102 | 103 | cb(); 104 | } 105 | 106 | // When Pug, md, or config file is changed, it will process Pug file, too 107 | function htmlListen() { 108 | return watch([...siteConfigs.map((siteConfig) => siteConfig.path), helpers.trim(`${helpers.source()}/${global.config.html.src}/**/*.pug`), helpers.trim(`${helpers.source()}/${global.config.html.src}/**/*.md`), helpers.trim(`!${helpers.source()}/${global.config.html.src}/_**/*.pug`), helpers.trim(`!${helpers.source()}/${global.config.html.src}/**/_**/*.pug`)], global.config.watchConfig, htmlStart); 109 | } 110 | 111 | // When Pug, md, or config file is changed, it will process Pug file, too 112 | function lineListen() { 113 | return watch(helpers.trim(`${helpers.source()}/${global.config.html.src}/_layout/line.pug`), global.config.watchConfig, lineStart); 114 | } 115 | 116 | let thisPugConfigXML = {}; 117 | 118 | if (global.config.html.pug) { 119 | thisPugConfigXML = xmlConfig.pugConfig.basedir 120 | ? xmlConfig.pugConfig 121 | : ({ ...xmlConfig.pugConfig, basedir: helpers.trim(`${helpers.source()}/${global.config.xml.src}/`) }); 122 | } 123 | 124 | const xmlSrc = global.config.xml.pug 125 | ? [helpers.trim(`${helpers.source()}/${global.config.xml.src}/**/*.pug`), helpers.trim(`!${helpers.source()}/${global.config.xml.src}/_**/*.pug`), helpers.trim(`!${helpers.source()}/${global.config.xml.src}/**/_**/*.pug`)] 126 | : helpers.trim(`${helpers.source()}/${global.config.xml.src}/**/*.xml`); 127 | 128 | // Will process Pug files 129 | function xmlStart() { 130 | return src(xmlSrc) 131 | .pipe(gulpif(global.config.xml.pug, data(() => { 132 | const temp = {}; 133 | 134 | siteConfigs.forEach((siteConfig) => { 135 | temp[siteConfig.name] = JSON.parse(fs.readFileSync(siteConfig.path)); 136 | }); 137 | 138 | return temp; 139 | }))) 140 | .pipe(gulpif(global.config.xml.pug, pug(thisPugConfigXML))) 141 | .pipe(wait(1000)) 142 | .pipe(gulpif(global.config.xml.minify, htmlmin(xmlConfig.htmlminConfig))) 143 | .pipe(replace('div', 'link')) 144 | .pipe(replace('>')) 150 | .pipe(rename(xmlConfig.renameConfig)) 151 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.xml.dist}`))) 152 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 153 | } 154 | 155 | exports.html = { 156 | htmlStart, 157 | lineStart, 158 | xmlStart, 159 | htmlListen, 160 | lineListen, 161 | }; 162 | -------------------------------------------------------------------------------- /gulpfile.js/index.js: -------------------------------------------------------------------------------- 1 | const { series, parallel } = require('gulp'); 2 | 3 | const { helpers } = require('./helpers'); 4 | 5 | global.config = require('./.starter-project.json'); 6 | 7 | global.config.watchConfig = require('./.watch.json'); 8 | 9 | global.bs = global.config.sync.run ? require('browser-sync').create() : () => true; 10 | 11 | const { clean } = require('./clean'); 12 | const { sync } = global.config.sync.run ? require('./sync') : false; 13 | const { bump } = global.config.bump.run ? require('./bump') : false; 14 | const { css } = global.config.css.run ? require('./css') : false; 15 | const { js } = global.config.js.run ? require('./js') : false; 16 | const { gfx } = global.config.gfx.run ? require('./gfx') : false; 17 | const { fonts } = global.config.fonts.run ? require('./fonts') : false; 18 | const { favicon } = global.config.favicon.run ? require('./favicon') : false; 19 | const { html } = global.config.html.run ? require('./html') : false; 20 | const { critical } = global.config.critical.run ? require('./critical') : false; 21 | const { gzip } = global.config.gzip.run ? require('./gzip') : false; 22 | const { kss } = global.config.kss.run ? require('./kss') : false; 23 | const { sassdoc } = global.config.sassdoc.run ? require('./sassdoc') : false; 24 | const { jsdoc } = global.config.jsdoc.run ? require('./jsdoc') : false; 25 | const { cms } = global.config.cms.run ? require('./cms') : false; 26 | 27 | if (global.config.bump.run) { 28 | exports.bumpPatch = bump.patch; 29 | exports.bumpMinor = bump.minor; 30 | exports.bumpPrerelease = bump.prerelease; 31 | } 32 | 33 | // gulp-if fix 34 | if (!global.config.sync.run) { 35 | global.bs.stream = () => true; 36 | global.bs.reload = () => true; 37 | } 38 | 39 | exports.clean = clean.cleanStart; 40 | 41 | exports.default = series( 42 | clean.cleanStart, 43 | parallel( 44 | global.config.css.run ? css.cssStart : helpers.skip, 45 | global.config.js.run ? js.jsStartDev : helpers.skip, 46 | global.config.gfx.run ? gfx.gfxStart : helpers.skip, 47 | global.config.fonts.run ? fonts.fontsStart : helpers.skip, 48 | ), 49 | global.config.html.run ? html.htmlStart : helpers.skip, 50 | global.config.html.run ? html.lineStart : helpers.skip, 51 | global.config.sync.run ? sync.syncStart : helpers.skip, 52 | parallel( 53 | global.config.css.run ? css.cssListen : helpers.skip, 54 | global.config.js.run ? js.jsListen : helpers.skip, 55 | global.config.gfx.run ? gfx.gfxListen : helpers.skip, 56 | global.config.fonts.run ? fonts.fontsListen : helpers.skip, 57 | global.config.html.run ? html.htmlListen : helpers.skip, 58 | global.config.html.run ? html.lineListen : helpers.skip, 59 | ), 60 | ); 61 | 62 | exports.build = series( 63 | clean.cleanStart, 64 | parallel( 65 | global.config.favicon.run ? favicon.faviconStart : helpers.skip, 66 | global.config.css.run ? css.cssStart : helpers.skip, 67 | global.config.js.run ? js.jsStartProd : helpers.skip, 68 | global.config.gfx.run ? gfx.gfxStart : helpers.skip, 69 | global.config.fonts.run ? fonts.fontsStart : helpers.skip, 70 | global.config.cms.run ? cms.adminStart : helpers.skip, 71 | global.config.cms.run ? cms.commitStart : helpers.skip, 72 | ), 73 | global.config.html.run ? html.htmlStart : helpers.skip, 74 | global.config.html.run ? html.xmlStart : helpers.skip, 75 | global.config.kss.run ? kss.kssStart : helpers.skip, 76 | global.config.sassdoc.run ? sassdoc.sassdocStart : helpers.skip, 77 | global.config.jsdoc.run ? jsdoc.jsdocStart : helpers.skip, 78 | global.config.sync.run && global.config.critical.run ? sync.syncStartBuild : helpers.skip, 79 | global.config.critical.run ? critical.criticalStart : helpers.skip, 80 | global.config.sync.run && global.config.critical.run ? sync.syncStop : helpers.skip, 81 | global.config.html.run 82 | && global.config.html.pug 83 | && global.config.critical.run ? html.htmlStart : helpers.skip, 84 | global.config.html.run ? html.lineStart : helpers.skip, 85 | global.config.js.run && global.config.critical.run ? js.swStart : helpers.skip, 86 | global.config.gzip.run ? gzip.gzipStart : helpers.skip, 87 | helpers.killNow, 88 | ); 89 | -------------------------------------------------------------------------------- /gulpfile.js/js.js: -------------------------------------------------------------------------------- 1 | const { src, dest, watch } = require('gulp'); 2 | const gulpif = require('gulp-if'); 3 | const eslint = global.config.js.lint ? require('gulp-eslint') : () => true; 4 | const sourcemaps = global.config.js.sourcemaps ? require('gulp-sourcemaps') : () => true; 5 | const rename = global.config.js.uglify ? require('gulp-rename') : () => true; 6 | const webpack = require('webpack'); 7 | const gulpWebpack = require('webpack-stream'); 8 | const { injectManifest } = require('workbox-build'); 9 | 10 | const { helpers } = require('./helpers'); 11 | 12 | const jsConfig = require('./.js.json'); 13 | const webpackConfig = require('./webpack.js'); 14 | 15 | // gulp-if fix 16 | if (!global.config.css.sourcemaps) { 17 | sourcemaps.init = () => true; 18 | sourcemaps.write = () => true; 19 | } 20 | 21 | const thisEslintConfig = (global.config.js.lint) 22 | ? ({ ...jsConfig.eslintConfig, configFile: helpers.parse(jsConfig.eslintConfig.configFile) }) 23 | : {}; 24 | 25 | if (!global.config.js.lint) { 26 | eslint.format = () => true; 27 | eslint.failAfterError = () => true; 28 | eslint.result = () => true; 29 | } 30 | 31 | webpackConfig.devtool = (global.config.js.sourcemaps) ? 'sourcemaps' : ''; 32 | 33 | function jsStartDev(cb) { 34 | webpackConfig.mode = 'development'; 35 | 36 | jsStart(); 37 | 38 | cb(); 39 | } 40 | 41 | function jsStartProd(cb) { 42 | webpackConfig.mode = (global.config.js.uglify) ? 'production' : 'development'; 43 | 44 | jsStart(); 45 | 46 | cb(); 47 | } 48 | 49 | // Will process JS files 50 | function jsStart() { 51 | return src(helpers.trim(`${helpers.source()}/${global.config.js.src}/*.js`)) 52 | .pipe(gulpif(global.config.js.sourcemaps, sourcemaps.init())) 53 | .pipe(gulpif(global.config.js.lint, eslint(thisEslintConfig))) 54 | .pipe(gulpif(global.config.js.lint, eslint.format())) 55 | .pipe(gulpif(global.config.js.lint, eslint.failAfterError())) 56 | .pipe(gulpif(global.config.js.lint, eslint.result((result) => { 57 | console.log(`[JS] ESLint complete: ${result.filePath}`); 58 | console.log(`[JS] Messages: ${result.messages.length}`); 59 | console.warn(`[JS] Warnings: ${result.warningCount}`); 60 | console.error(`[JS] Errors: ${result.errorCount}`); 61 | }))) 62 | .pipe( 63 | gulpWebpack(webpackConfig), 64 | webpack, 65 | ) 66 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.js.dist}`))) 67 | .pipe(gulpif(global.config.js.uglify, rename(jsConfig.renameConfig))) 68 | .pipe(gulpif(global.config.js.sourcemaps, sourcemaps.write(helpers.trim(`${helpers.source()}/${global.config.js.dist}`)))) 69 | .pipe(dest(helpers.trim(`${helpers.dist()}/${global.config.js.dist}`))) 70 | .pipe(gulpif(global.config.sync.run, global.bs.stream())); 71 | } 72 | 73 | // Will process SW file 74 | function swStart(cb) { 75 | injectManifest({ 76 | globDirectory: helpers.parse(jsConfig.swConfig.globDirectory), 77 | globPatterns: jsConfig.swConfig.globPatterns, 78 | globIgnores: jsConfig.swConfig.globIgnores.map((ignore) => helpers.parse(ignore)), 79 | swSrc: helpers.parse(jsConfig.swConfig.swSrc), 80 | swDest: helpers.parse(jsConfig.swConfig.swDest), 81 | }) 82 | .then(({ count, size }) => { 83 | console.info('Service worker generation completed.'); 84 | console.log(`Generated ${helpers.parse(jsConfig.swConfig.swDest)}, which will precache ${count} files, totaling ${size} bytes.`); 85 | cb(); 86 | }).catch((error) => { 87 | console.warn('Service worker generation failed:', error); 88 | cb(); 89 | }); 90 | } 91 | 92 | // When JS file is changed, it will process JS file, too 93 | function jsListen() { 94 | return watch(helpers.trim(`${helpers.source()}/${global.config.js.src}/*.js`), global.config.watchConfig, jsStart, global.bs.reload); 95 | } 96 | 97 | // When JS file is changed, it will process JS file, too 98 | function swListen() { 99 | return watch(helpers.trim(`${helpers.source()}/${jsConfig.swConfig.swSrc}`), global.config.watchConfig, swStart, global.bs.reload); 100 | } 101 | 102 | exports.js = { 103 | jsStart, 104 | swStart, 105 | jsStartDev, 106 | jsStartProd, 107 | jsListen, 108 | swListen, 109 | }; 110 | -------------------------------------------------------------------------------- /gulpfile.js/jsdoc.js: -------------------------------------------------------------------------------- 1 | const { src, watch } = require('gulp'); 2 | const jsdoc = require('gulp-jsdoc3'); 3 | 4 | const { helpers } = require('./helpers'); 5 | 6 | const jsdocConfig = require('./.jsdoc.json'); 7 | 8 | const thisSrc = jsdocConfig.src.map((path) => helpers.parse(path)); 9 | 10 | const thisOpts = { ...jsdocConfig.settings.opts, destination: helpers.parse(jsdocConfig.settings.opts.destination) }; 11 | 12 | const thisSettings = { ...jsdocConfig.settings, opts: thisOpts }; 13 | 14 | // Will process JSdoc docs 15 | function jsdocStart() { 16 | return src(thisSrc) 17 | .pipe(jsdoc(thisSettings)); 18 | } 19 | 20 | // When JS file is changed, it will process JSdoc docs, too 21 | function jsdocListen() { 22 | return watch([helpers.trim(`${helpers.source()}/${global.config.js.src}/*.js`), helpers.trim(`${helpers.source()}/${global.config.js.src}/*.md`)], global.config.watchConfig, jsdocStart, global.bs.reload); 23 | } 24 | 25 | exports.jsdoc = { 26 | jsdocStart, 27 | jsdocListen, 28 | }; 29 | -------------------------------------------------------------------------------- /gulpfile.js/kss.js: -------------------------------------------------------------------------------- 1 | const { watch } = require('gulp'); 2 | const kss = require('kss'); 3 | 4 | const { helpers } = require('./helpers'); 5 | 6 | const kssConfig = require('./.kss.json'); 7 | 8 | const thisCss = kssConfig.css.map((path) => helpers.parse(path)); 9 | const thisJs = kssConfig.js.map((path) => helpers.parse(path)); 10 | 11 | const thisKssConfig = { 12 | ...kssConfig, 13 | source: helpers.parse(kssConfig.source), 14 | destination: helpers.parse(kssConfig.destination), 15 | css: thisCss, 16 | js: thisJs, 17 | }; 18 | 19 | // Will process KSS docs 20 | function kssStart() { 21 | return kss(thisKssConfig); 22 | } 23 | 24 | // When Sass file is changed, it will process KSS docs, too 25 | function kssListen() { 26 | return watch(helpers.trim(`${helpers.source()}/${global.config.css.src}/**/*.scss`), global.config.watchConfig, kssStart, global.bs.reload); 27 | } 28 | 29 | exports.kss = { 30 | kssStart, 31 | kssListen, 32 | }; 33 | -------------------------------------------------------------------------------- /gulpfile.js/sassdoc.js: -------------------------------------------------------------------------------- 1 | const { src, watch } = require('gulp'); 2 | const sassdoc = require('sassdoc'); 3 | 4 | const { helpers } = require('./helpers'); 5 | 6 | const sassdocConfig = require('./.sassdoc.json'); 7 | 8 | const thisSassdocConfig = { 9 | ...sassdocConfig, 10 | package: `${helpers.proot()}${sassdocConfig.package}`, 11 | dest: helpers.parse(sassdocConfig.dest), 12 | }; 13 | 14 | // Will process SassDoc docs 15 | function sassdocStart() { 16 | return src(helpers.trim(`${helpers.source()}/${global.config.css.src}/**/*.scss`)) 17 | .pipe(sassdoc(thisSassdocConfig)); 18 | } 19 | 20 | // When Sass file is changed, it will process SassDoc docs, too 21 | function sassdocListen() { 22 | return watch(helpers.trim(`${helpers.source()}/${global.config.css.src}/**/*.scss`), global.config.watchConfig, sassdocStart, global.bs.reload); 23 | } 24 | 25 | exports.sassdoc = { 26 | sassdocStart, 27 | sassdocListen, 28 | }; 29 | -------------------------------------------------------------------------------- /gulpfile.js/sync.js: -------------------------------------------------------------------------------- 1 | const { helpers } = require('./helpers'); 2 | 3 | const syncConfig = require('./.sync.json'); 4 | 5 | // Start static server 6 | function syncStart(cb) { 7 | if (global.config.sync.run) { 8 | let thisConfig = {}; 9 | 10 | if (syncConfig.proxy) { 11 | thisConfig = { ...syncConfig, proxy: syncConfig.proxy }; 12 | } else { 13 | const thisServer = syncConfig.server.baseDir 14 | ? helpers.parse(syncConfig.server.baseDir) 15 | : ({ ...syncConfig.server, baseDir: helpers.dist() }); 16 | 17 | thisConfig = { ...syncConfig, server: thisServer }; 18 | } 19 | 20 | global.bs.init(thisConfig); 21 | } 22 | 23 | cb(); 24 | } 25 | 26 | // Start static dev server 27 | function syncStartBuild(cb) { 28 | syncConfig.open = false; 29 | 30 | syncStart(cb); 31 | } 32 | 33 | // Stop static server 34 | function syncStop(cb) { 35 | global.bs.cleanup(); 36 | global.bs.exit(); 37 | 38 | cb(); 39 | } 40 | 41 | exports.sync = { 42 | syncStart, 43 | syncStartBuild, 44 | syncStop, 45 | }; 46 | -------------------------------------------------------------------------------- /gulpfile.js/webpack.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { helpers } = require('./helpers') 3 | 4 | module.exports = { 5 | mode: 'production', 6 | entry: { 7 | index: helpers.parse('helpers.source/config.js.src/index.js'), 8 | foftFontLoading: helpers.parse('helpers.source/config.js.src/foftFontLoading.js') 9 | }, 10 | output: { 11 | path: path.resolve(`${__dirname}/${helpers.parse('helpers.dist/config.js.dist/')}`), 12 | filename: '[name].js' 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.js$/, 18 | exclude: /node_modules/, 19 | use: { 20 | loader: 'babel-loader', 21 | options: { 22 | presets: ['@babel/env'] 23 | } 24 | } 25 | } 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | base = "./" 3 | publish = "./dist/" 4 | command = "rm -rf ./src/gfx/cover/* && yarn build" 5 | functions = "./api/" 6 | 7 | [[redirects]] 8 | from = "/api/*" 9 | to = "/.netlify/functions/:splat" 10 | status = 200 11 | force = true 12 | headers = {Access-Control-Allow-Origin = "*"} 13 | 14 | [[headers]] 15 | # Define which paths this specific [[headers]] block will cover. 16 | for = "*" 17 | [headers.values] 18 | Access-Control-Allow-Origin = "*" 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code-line-daily", 3 | "version": "0.1.54", 4 | "description": "A line of code of the day.", 5 | "main": "index.html", 6 | "scripts": { 7 | "dev": "node scripts/index.js", 8 | "default": "node scripts/index.js && gulp default", 9 | "build": "node scripts/index.js && gulp build" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/maliMirkec/code-line-daily.git" 14 | }, 15 | "keywords": [ 16 | "Starter Project", 17 | "Line of code", 18 | "Code line" 19 | ], 20 | "author": "Silvestar Bistrović ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/maliMirkec/code-line-daily/issues" 24 | }, 25 | "homepage": "https://cld.silvestar.codes", 26 | "dependencies": { 27 | "babel-eslint": "^10.1.0", 28 | "fontfaceobserver": "^2.1.0", 29 | "gulp-data": "^1.3.1", 30 | "gulp-replace": "^1.0.0", 31 | "penthouse": "^2.3.0", 32 | "sharp": "^0.25.4", 33 | "starter-project": "^2.2.9-rc4", 34 | "twitter": "^1.7.1", 35 | "workbox-build": "^5.1.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /scripts/index.js: -------------------------------------------------------------------------------- 1 | const sharp = require('sharp') 2 | const fs = require('fs') 3 | const lines = require('../api/lines.json') 4 | 5 | const tagsToReplace = { 6 | '&': '&', 7 | '<': '<', 8 | '>': '>' 9 | } 10 | 11 | function replaceTag (tag) { 12 | return tagsToReplace[tag] || tag 13 | } 14 | 15 | function safeTagsTeplace (str) { 16 | return str.replace(/[&<>]/g, replaceTag) 17 | } 18 | 19 | if (lines && lines.list && lines.list.length) { 20 | const placeholder = ` 21 | 22 | 23 | 24 | 25 | 26 | 27 | $note 28 | 29 | 30 | $line 31 | 32 | 33 | #$language 34 | 35 | 36 | 37 | ` 38 | 39 | lines.list.forEach((line) => { 40 | try { 41 | const path = `./src/gfx/cover/${line.date}.png` 42 | let lineSvg = '' 43 | let noteSvg = '' 44 | 45 | const lineText = safeTagsTeplace(line.line) 46 | 47 | if (lineText.length > 40) { 48 | const lineIndex = lineText.indexOf(' ', 40) + 1 49 | 50 | if (lineIndex > 0) { 51 | const lineSvg1 = lineText.slice(0, lineIndex) 52 | const lineSvg2 = lineText.slice(lineIndex, 1000) 53 | 54 | if (lineSvg1.length >= 42) { 55 | lineSvg += `${lineSvg1}` 56 | lineSvg += `${lineSvg2}` 57 | } else { 58 | lineSvg += `${lineSvg1}` 59 | lineSvg += `${lineSvg2}` 60 | } 61 | } else if (lineText.length >= 42) { 62 | console.log(lineText, lineText.length >= 42) 63 | lineSvg += `${lineText}` 64 | } else { 65 | lineSvg = `${lineText}` 66 | } 67 | } else { 68 | lineSvg = `${lineText}` 69 | } 70 | 71 | if (line.note.length > 60) { 72 | const noteIndex = line.note.indexOf(' ', 60) + 1 73 | 74 | if (noteIndex > 0) { 75 | const noteSvg1 = line.note.slice(0, noteIndex) 76 | const noteSvg2 = line.note.slice(noteIndex, 1000) 77 | 78 | noteSvg += `${noteSvg1}` 79 | noteSvg += `${noteSvg2}` 80 | } else { 81 | noteSvg = `${line.note}` 82 | } 83 | } else { 84 | noteSvg = `${line.note}` 85 | } 86 | 87 | if (!fs.existsSync(path)) { 88 | let svg = placeholder.replace('$line', lineSvg.replace("'$'", '"$"').replace("'€'", '"€"')) 89 | svg = svg.replace('$note', noteSvg) 90 | svg = svg.replace('$language', line.language) 91 | 92 | sharp(Buffer.from(svg)) 93 | .png() 94 | .toFile(path) 95 | .catch((err) => { 96 | console.error(err) 97 | }) 98 | } 99 | } catch (err) { 100 | console.error(err) 101 | } 102 | }) 103 | } 104 | 105 | console.log('Images have been created.') 106 | -------------------------------------------------------------------------------- /src/cms/config.yml: -------------------------------------------------------------------------------- 1 | backend: 2 | name: git-gateway 3 | branch: master 4 | accept_roles: 5 | - admin 6 | 7 | media_folder: "src/gfx" 8 | 9 | site_url: https://cld.silvestar.codes 10 | display_url: https://cld.silvestar.codes 11 | logo_url: https://cld.silvestar.codes/gfx/svg/cld-logo.svg 12 | 13 | collections: 14 | - name: "setup" 15 | label: "Setup" 16 | files: 17 | - name: "data" 18 | label: "Data" 19 | file: "api/lines.json" 20 | format: "json" 21 | delete: false 22 | fields: 23 | - label: "Lines" 24 | label_singular: "Line" 25 | name: "list" 26 | widget: "list" 27 | fields: 28 | - label: "Line of code" 29 | name: "line" 30 | widget: "string" 31 | required: true 32 | - label: "Note" 33 | name: "note" 34 | widget: "text" 35 | required: true 36 | - label: "Link" 37 | name: "link" 38 | widget: "string" 39 | required: true 40 | - label: "Language" 41 | name: "language" 42 | widget: "string" 43 | required: true 44 | - label: "Evergreen" 45 | name: "evergreen" 46 | widget: "boolean" 47 | required: false 48 | - label: "Author" 49 | name: "author" 50 | widget: "string" 51 | - label: "Email" 52 | name: "email" 53 | widget: "string" 54 | - label: "Twitter handle" 55 | name: "handle" 56 | widget: "string" 57 | required: true 58 | - label: "Date" 59 | name: "date" 60 | widget: "date" 61 | format: "YYYY-MM-DD" 62 | required: true 63 | 64 | -------------------------------------------------------------------------------- /src/cms/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CMS ❇ Code Line Daily 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/cms/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SB site - Silvestar Bistrovi\u0107 website", 3 | "short_name": "SB site - Silvestar Bistrovi\u0107 website", 4 | "icons": [ 5 | { 6 | "src": "/favicon/android-chrome-36x36.png?v=starbist", 7 | "sizes": "36x36", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/favicon/android-chrome-48x48.png?v=starbist", 12 | "sizes": "48x48", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "/favicon/android-chrome-72x72.png?v=starbist", 17 | "sizes": "72x72", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "/favicon/android-chrome-96x96.png?v=starbist", 22 | "sizes": "96x96", 23 | "type": "image/png" 24 | }, 25 | { 26 | "src": "/favicon/android-chrome-144x144.png?v=starbist", 27 | "sizes": "144x144", 28 | "type": "image/png" 29 | }, 30 | { 31 | "src": "/favicon/android-chrome-192x192.png?v=starbist", 32 | "sizes": "192x192", 33 | "type": "image/png" 34 | }, 35 | { 36 | "src": "/favicon/android-chrome-256x256.png?v=starbist", 37 | "sizes": "256x256", 38 | "type": "image/png" 39 | }, 40 | { 41 | "src": "/favicon/android-chrome-384x384.png?v=starbist", 42 | "sizes": "384x384", 43 | "type": "image/png" 44 | }, 45 | { 46 | "src": "/favicon/android-chrome-512x512.png?v=starbist", 47 | "sizes": "512x512", 48 | "type": "image/png" 49 | } 50 | ], 51 | "theme_color": "#12e09f", 52 | "background_color": "#fff", 53 | "start_url": "/offline.html", 54 | "display": "standalone" 55 | } 56 | -------------------------------------------------------------------------------- /src/commit/config.yml: -------------------------------------------------------------------------------- 1 | backend: 2 | name: git-gateway 3 | branch: develop 4 | accept_roles: 5 | - admin 6 | - user 7 | 8 | media_folder: "src/gfx" 9 | 10 | site_url: https://cld.silvestar.codes 11 | display_url: https://cld.silvestar.codes 12 | logo_url: https://cld.silvestar.codes/gfx/svg/cld-logo.svg 13 | 14 | collections: 15 | - name: "lines" 16 | label: "Lines" 17 | label_singular: "Line" 18 | folder: "contribute" 19 | create: true 20 | delete: false 21 | extension: json 22 | format: json 23 | identifier_field: line 24 | slug: "{{year}}-{{month}}-{{day}}-{{line}}-{{author}}" 25 | fields: 26 | - label: "Line of code" 27 | name: "line" 28 | widget: "string" 29 | - label: "Note" 30 | name: "note" 31 | widget: "text" 32 | - label: "Link" 33 | name: "link" 34 | widget: "string" 35 | - label: "Language" 36 | name: "language" 37 | widget: "string" 38 | - label: "Author" 39 | name: "author" 40 | widget: "string" 41 | - label: "Twitter handle" 42 | name: "handle" 43 | widget: "string" 44 | - label: "Email" 45 | name: "email" 46 | widget: "string" 47 | - label: "Bio" 48 | name: "bio" 49 | widget: "markdown" 50 | 51 | -------------------------------------------------------------------------------- /src/commit/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Contribute ❇ Code Line Daily 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 | -------------------------------------------------------------------------------- /src/critical/style.critical.css: -------------------------------------------------------------------------------- 1 | html { 2 | line-height: 1.15; 3 | /* 1 */ 4 | -webkit-text-size-adjust: 100%; 5 | /* 2 */ 6 | } 7 | 8 | body { 9 | margin: 0; 10 | } 11 | 12 | main { 13 | display: block; 14 | } 15 | 16 | h1 { 17 | font-size: 2em; 18 | margin: 0.67em 0; 19 | } 20 | 21 | a { 22 | background-color: transparent; 23 | } 24 | 25 | code { 26 | font-family: monospace, monospace; 27 | /* 1 */ 28 | font-size: 1em; 29 | /* 2 */ 30 | } 31 | 32 | button, 33 | input { 34 | font-family: inherit; 35 | /* 1 */ 36 | font-size: 100%; 37 | /* 1 */ 38 | line-height: 1.15; 39 | /* 1 */ 40 | margin: 0; 41 | /* 2 */ 42 | } 43 | 44 | button, 45 | input { 46 | /* 1 */ 47 | overflow: visible; 48 | } 49 | 50 | button { 51 | /* 1 */ 52 | text-transform: none; 53 | } 54 | 55 | button { 56 | -webkit-appearance: button; 57 | } 58 | 59 | button::-moz-focus-inner { 60 | border-style: none; 61 | padding: 0; 62 | } 63 | 64 | button:-moz-focusring { 65 | outline: 1px dotted ButtonText; 66 | } 67 | 68 | ::-webkit-file-upload-button { 69 | -webkit-appearance: button; 70 | /* 1 */ 71 | font: inherit; 72 | /* 2 */ 73 | } 74 | 75 | html { 76 | font-size: 16px; 77 | } 78 | 79 | @media screen and (min-width: 480px) { 80 | html { 81 | font-size: calc(16px + 4 * (100vw - 480px) / 480); 82 | } 83 | } 84 | 85 | @media screen and (min-width: 960px) { 86 | html { 87 | font-size: 20px; 88 | } 89 | } 90 | 91 | body { 92 | letter-spacing: calc(20 / 1000 * 1em); 93 | font-size: 1rem; 94 | -webkit-font-smoothing: antialiased; 95 | line-height: 1.5; 96 | -moz-osx-font-smoothing: grayscale; 97 | } 98 | 99 | h1, 100 | .t-h1 { 101 | font-size: 1.728rem; 102 | font-weight: normal; 103 | } 104 | 105 | h2 { 106 | font-size: 1.2rem; 107 | font-weight: normal; 108 | } 109 | 110 | p { 111 | font-size: 1rem; 112 | } 113 | 114 | * { 115 | -webkit-box-sizing: border-box; 116 | box-sizing: border-box; 117 | } 118 | 119 | .w { 120 | margin-left: auto; 121 | margin-right: auto; 122 | padding-left: calc(1.5 * 1rem); 123 | padding-right: calc(1.5 * 1rem); 124 | } 125 | 126 | @media (max-width: 29.99em) { 127 | .w { 128 | padding-left: calc(0.5 * 1rem); 129 | padding-right: calc(0.5 * 1rem); 130 | } 131 | } 132 | 133 | .w--alpha { 134 | max-width: calc(72 * 1rem); 135 | width: 100%; 136 | } 137 | 138 | .w--beta { 139 | max-width: calc(48 * 1rem); 140 | width: 100%; 141 | } 142 | 143 | .mt--alpha { 144 | margin-top: calc(4.5 * 1rem); 145 | } 146 | 147 | @media (max-width: 29.99em) { 148 | .mt--alpha { 149 | margin-top: calc(2.25 * 1rem); 150 | } 151 | } 152 | 153 | .mt--beta { 154 | margin-top: calc(1.5 * 1rem); 155 | } 156 | 157 | @media (max-width: 29.99em) { 158 | .mt--beta { 159 | margin-top: calc(0.75 * 1rem); 160 | } 161 | } 162 | 163 | html { 164 | scroll-behavior: smooth; 165 | } 166 | 167 | body { 168 | background-color: #041f17; 169 | color: #12e09f; 170 | display: -webkit-box; 171 | display: -ms-flexbox; 172 | display: flex; 173 | -webkit-box-orient: vertical; 174 | -webkit-box-direction: normal; 175 | -ms-flex-direction: column; 176 | flex-direction: column; 177 | min-height: 100vh; 178 | } 179 | 180 | .main { 181 | -webkit-box-flex: 1; 182 | -ms-flex: 1 1 auto; 183 | flex: 1 1 auto; 184 | } 185 | 186 | a { 187 | color: inherit; 188 | text-decoration: none; 189 | } 190 | 191 | 192 | 193 | article h1:first-child { 194 | text-align: center; 195 | } 196 | 197 | .grid { 198 | display: grid; 199 | grid-gap: calc(1.5 * 1rem); 200 | } 201 | 202 | @media (min-width: 60em) { 203 | .grid { 204 | grid-gap: calc(3 * 1rem); 205 | grid-template-columns: 1fr 1fr; 206 | } 207 | } 208 | 209 | @media (min-width: 60em) { 210 | .grid .cld:nth-child(-n+2) { 211 | margin-top: 0; 212 | } 213 | } 214 | 215 | .grid .cld:first-child { 216 | margin-top: 0; 217 | } 218 | 219 | .hf { 220 | background-color: #101413; 221 | padding: calc(0.75 * 1rem); 222 | } 223 | 224 | .hf a[href*="/"] { 225 | text-decoration: none; 226 | } 227 | 228 | .hf a[href*="/"].active { 229 | position: relative; 230 | } 231 | 232 | .hf a[href*="/"].active:after { 233 | content: '<'; 234 | position: absolute; 235 | right: calc(-0.75 * 1rem); 236 | } 237 | 238 | .hf ul { 239 | list-style: none; 240 | } 241 | 242 | .hf__inner { 243 | -webkit-box-align: center; 244 | -ms-flex-align: center; 245 | align-items: center; 246 | display: -webkit-box; 247 | display: -ms-flexbox; 248 | display: flex; 249 | -webkit-box-pack: justify; 250 | -ms-flex-pack: justify; 251 | justify-content: space-between; 252 | position: relative; 253 | } 254 | 255 | .hf__skip { 256 | -webkit-box-align: center; 257 | -ms-flex-align: center; 258 | align-items: center; 259 | clip: rect(1px 1px 1px 1px); 260 | -webkit-clip-path: inset(1px); 261 | clip-path: inset(1px); 262 | display: -webkit-box; 263 | display: -ms-flexbox; 264 | display: flex; 265 | height: 1px; 266 | -webkit-box-pack: center; 267 | -ms-flex-pack: center; 268 | justify-content: center; 269 | overflow: hidden; 270 | position: absolute; 271 | white-space: nowrap; 272 | width: 1px; 273 | } 274 | 275 | .hf__logo { 276 | -webkit-box-align: center; 277 | -ms-flex-align: center; 278 | align-items: center; 279 | display: -webkit-box; 280 | display: -ms-flexbox; 281 | display: flex; 282 | text-decoration: none; 283 | } 284 | 285 | .hf__src { 286 | display: block; 287 | height: calc(4.5 * 1rem); 288 | width: calc(4.5 * 1rem); 289 | } 290 | 291 | @media (max-width: 29.99em) { 292 | .hf__src { 293 | height: calc(3 * 1rem); 294 | width: calc(3 * 1rem); 295 | } 296 | } 297 | 298 | .hf__cld { 299 | margin-left: calc(0.75 * 1rem); 300 | width: calc(4.5 * 1rem); 301 | } 302 | 303 | @media (max-width: 29.99em) { 304 | .hf__cld { 305 | font-size: 0.83333rem; 306 | margin-left: calc(0.5 * 1rem); 307 | width: calc(3 * 1rem); 308 | } 309 | } 310 | 311 | .hf__list { 312 | -webkit-box-align: end; 313 | -ms-flex-align: end; 314 | align-items: flex-end; 315 | display: -webkit-box; 316 | display: -ms-flexbox; 317 | display: flex; 318 | -webkit-box-orient: vertical; 319 | -webkit-box-direction: normal; 320 | -ms-flex-direction: column; 321 | flex-direction: column; 322 | margin: 0; 323 | } 324 | 325 | .hf__link { 326 | display: -webkit-box; 327 | display: -ms-flexbox; 328 | display: flex; 329 | font-size: 0.83333rem; 330 | } 331 | 332 | .cld { 333 | display: -webkit-box; 334 | display: -ms-flexbox; 335 | display: flex; 336 | -webkit-box-orient: vertical; 337 | -webkit-box-direction: normal; 338 | -ms-flex-direction: column; 339 | flex-direction: column; 340 | margin-bottom: calc(0.5 * 1rem); 341 | } 342 | 343 | .cld .btn { 344 | margin-left: calc(0.5 * 1rem); 345 | } 346 | 347 | @media (max-width: 29.99em) { 348 | .cld .btn:first-of-type:not(:last-of-type) { 349 | margin-left: 0; 350 | } 351 | } 352 | 353 | .cld__inner, 354 | .cld__content { 355 | -webkit-box-align: stretch; 356 | -ms-flex-align: stretch; 357 | align-items: stretch; 358 | display: -webkit-box; 359 | display: -ms-flexbox; 360 | display: flex; 361 | -webkit-box-orient: vertical; 362 | -webkit-box-direction: normal; 363 | -ms-flex-direction: column; 364 | flex-direction: column; 365 | } 366 | 367 | .cld__content { 368 | background-color: #0eaf7c; 369 | border: calc(0.1 * 1rem) solid #92f6d7; 370 | color: #101413; 371 | } 372 | 373 | .cld__inner { 374 | text-decoration: none; 375 | } 376 | 377 | .cld__code, 378 | .cld__details { 379 | padding-left: calc(1 * 1rem); 380 | padding-right: calc(1 * 1rem); 381 | } 382 | 383 | @media (max-width: 29.99em) { 384 | .cld__code, 385 | .cld__details { 386 | padding-left: calc(0.375 * 1rem); 387 | padding-right: calc(0.375 * 1rem); 388 | } 389 | } 390 | 391 | .cld__details { 392 | -webkit-box-align: center; 393 | -ms-flex-align: center; 394 | align-items: center; 395 | display: -webkit-box; 396 | display: -ms-flexbox; 397 | display: flex; 398 | -ms-flex-wrap: wrap; 399 | flex-wrap: wrap; 400 | -webkit-box-pack: justify; 401 | -ms-flex-pack: justify; 402 | justify-content: space-between; 403 | min-height: calc(2.5 * 1rem); 404 | padding-bottom: calc(0.5 * 1rem); 405 | padding-top: calc(0.5 * 1rem); 406 | position: relative; 407 | } 408 | 409 | .cld__details, 410 | .cld__share { 411 | font-size: 0.83333rem; 412 | } 413 | 414 | .cld__details--alpha { 415 | font-size: 1rem; 416 | } 417 | 418 | .cld__detail, 419 | .cld__share { 420 | -webkit-box-align: baseline; 421 | -ms-flex-align: baseline; 422 | align-items: baseline; 423 | display: -webkit-inline-box; 424 | display: -ms-inline-flexbox; 425 | display: inline-flex; 426 | } 427 | 428 | .cld__detail:only-child:before { 429 | content: '>'; 430 | margin-right: 0.5em; 431 | } 432 | 433 | @media (max-width: 29.99em) { 434 | .cld__detail:last-of-type:not(:first-of-type), 435 | .cld__share .cld__detail { 436 | -webkit-box-flex: 1; 437 | -ms-flex: 1 1 100%; 438 | flex: 1 1 100%; 439 | margin-top: calc(0.5 * 1rem); 440 | width: 100%; 441 | } 442 | } 443 | 444 | .cld__code { 445 | -webkit-box-align: center; 446 | -ms-flex-align: center; 447 | align-items: center; 448 | background-color: #12e09f; 449 | border-bottom: calc(0.1 * 1rem) solid #92f6d7; 450 | border-top: calc(0.1 * 1rem) solid #92f6d7; 451 | color: #101413; 452 | display: -webkit-box; 453 | display: -ms-flexbox; 454 | display: flex; 455 | font-size: 1.2rem; 456 | padding-bottom: calc(1.5 * 1rem); 457 | padding-top: calc(1.5 * 1rem); 458 | } 459 | 460 | .cld__share { 461 | -ms-flex-wrap: wrap; 462 | flex-wrap: wrap; 463 | } 464 | 465 | .cld__share .btn { 466 | margin-top: calc(0.5 * 1rem); 467 | } 468 | 469 | .cld__copy { 470 | bottom: calc(100% + calc(0.25 * 1rem)); 471 | position: absolute; 472 | right: calc(0.15 * 1rem); 473 | width: calc(69px); 474 | z-index: 1; 475 | } 476 | 477 | .cld__input { 478 | height: 10px; 479 | position: absolute; 480 | width: 10px; 481 | z-index: -1; 482 | } 483 | 484 | .cld--alpha .cld__content { 485 | border-width: 1px; 486 | } 487 | 488 | .cld--alpha .cld__details { 489 | min-height: calc(1.65 * 1rem); 490 | padding-bottom: calc(0.3 * 1rem); 491 | padding-top: calc(0.3 * 1rem); 492 | } 493 | 494 | .cld--alpha .cld__details, 495 | .cld--alpha .cld__share { 496 | font-size: 0.69444rem; 497 | } 498 | 499 | .cld--alpha .cld__code { 500 | border-width: 1px; 501 | font-size: 1rem; 502 | padding-bottom: calc(1.5 * 1rem); 503 | padding-top: calc(1.5 * 1rem); 504 | } 505 | 506 | .cld--alpha .btn.cld__copy { 507 | font-size: 0.5787rem; 508 | width: calc(57px); 509 | } 510 | 511 | .visually-hidden { 512 | clip: rect(1px 1px 1px 1px); 513 | clip: rect(1px, 1px, 1px, 1px); 514 | -webkit-clip-path: inset(1px); 515 | clip-path: inset(1px); 516 | display: block; 517 | height: 1px; 518 | overflow: hidden; 519 | position: absolute; 520 | white-space: nowrap; 521 | width: 1px; 522 | } 523 | 524 | .btn { 525 | -webkit-box-align: center; 526 | -ms-flex-align: center; 527 | align-items: center; 528 | -webkit-appearance: none; 529 | -moz-appearance: none; 530 | appearance: none; 531 | background-color: #0eaf7c; 532 | border: calc(0.1 * 1rem) solid currentColor; 533 | color: #101413; 534 | display: -webkit-inline-box; 535 | display: -ms-inline-flexbox; 536 | display: inline-flex; 537 | font-size: 0.83333rem; 538 | -webkit-box-pack: center; 539 | -ms-flex-pack: center; 540 | justify-content: center; 541 | line-height: 1; 542 | min-height: calc(1.5 * 1rem); 543 | padding-left: calc(1.05 * 1rem); 544 | padding-right: calc(1.05 * 1rem); 545 | text-decoration: none; 546 | } 547 | 548 | .btn--alpha { 549 | background-color: #041f17; 550 | border-color: #92f6d7; 551 | color: #12e09f; 552 | } 553 | 554 | .btn--beta, 555 | .cld--alpha .btn { 556 | border-width: 1px; 557 | font-size: 0.69444rem; 558 | min-height: calc(1.2 * 1rem); 559 | padding-left: calc(0.9 * 1rem); 560 | padding-right: calc(0.9 * 1rem); 561 | } 562 | -------------------------------------------------------------------------------- /src/critical/style.critical.min.css: -------------------------------------------------------------------------------- 1 | html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}button,input{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button{text-transform:none}button{-webkit-appearance:button}button::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring{outline:1px dotted ButtonText}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{font-size:16px}@media screen and (min-width:480px){html{font-size:calc(16px + 4 * (100vw - 480px)/ 480)}}@media screen and (min-width:960px){html{font-size:20px}}body{letter-spacing:calc(20 / 1000 * 1em);font-size:1rem;-webkit-font-smoothing:antialiased;line-height:1.5;-moz-osx-font-smoothing:grayscale}.t-h1,h1{font-size:1.728rem;font-weight:400}h2{font-size:1.2rem;font-weight:400}p{font-size:1rem}*{-webkit-box-sizing:border-box;box-sizing:border-box}.w{margin-left:auto;margin-right:auto;padding-left:calc(1.5 * 1rem);padding-right:calc(1.5 * 1rem)}@media (max-width:29.99em){.w{padding-left:calc(.5 * 1rem);padding-right:calc(.5 * 1rem)}}.w--alpha{max-width:calc(72 * 1rem);width:100%}.w--beta{max-width:calc(48 * 1rem);width:100%}.mt--alpha{margin-top:calc(4.5 * 1rem)}@media (max-width:29.99em){.mt--alpha{margin-top:calc(2.25 * 1rem)}}.mt--beta{margin-top:calc(1.5 * 1rem)}@media (max-width:29.99em){.mt--beta{margin-top:calc(.75 * 1rem)}}html{scroll-behavior:smooth}body{background-color:#041f17;color:#12e09f;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-height:100vh}.main{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}a{color:inherit;text-decoration:none}article h1:first-child{text-align:center}.grid{display:grid;grid-gap:calc(1.5 * 1rem)}@media (min-width:60em){.grid{grid-gap:calc(3 * 1rem);grid-template-columns:1fr 1fr}}@media (min-width:60em){.grid .cld:nth-child(-n+2){margin-top:0}}.grid .cld:first-child{margin-top:0}.hf{background-color:#101413;padding:calc(.75 * 1rem)}.hf a[href*="/"]{text-decoration:none}.hf a[href*="/"].active{position:relative}.hf a[href*="/"].active:after{content:'<';position:absolute;right:calc(-.75 * 1rem)}.hf ul{list-style:none}.hf__inner{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;position:relative}.hf__skip{-webkit-box-align:center;-ms-flex-align:center;align-items:center;clip:rect(1px 1px 1px 1px);-webkit-clip-path:inset(1px);clip-path:inset(1px);display:-webkit-box;display:-ms-flexbox;display:flex;height:1px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;overflow:hidden;position:absolute;white-space:nowrap;width:1px}.hf__logo{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;text-decoration:none}.hf__src{display:block;height:calc(4.5 * 1rem);width:calc(4.5 * 1rem)}@media (max-width:29.99em){.hf__src{height:calc(3 * 1rem);width:calc(3 * 1rem)}}.hf__cld{margin-left:calc(.75 * 1rem);width:calc(4.5 * 1rem)}@media (max-width:29.99em){.hf__cld{font-size:.83333rem;margin-left:calc(.5 * 1rem);width:calc(3 * 1rem)}}.hf__list{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0}.hf__link{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.83333rem}.cld{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-bottom:calc(.5 * 1rem)}.cld .btn{margin-left:calc(.5 * 1rem)}@media (max-width:29.99em){.cld .btn:first-of-type:not(:last-of-type){margin-left:0}}.cld__content,.cld__inner{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cld__content{background-color:#0eaf7c;border:calc(.1 * 1rem) solid #92f6d7;color:#101413}.cld__inner{text-decoration:none}.cld__code,.cld__details{padding-left:calc(1 * 1rem);padding-right:calc(1 * 1rem)}@media (max-width:29.99em){.cld__code,.cld__details{padding-left:calc(.375 * 1rem);padding-right:calc(.375 * 1rem)}}.cld__details{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;min-height:calc(2.5 * 1rem);padding-bottom:calc(.5 * 1rem);padding-top:calc(.5 * 1rem);position:relative}.cld__details,.cld__share{font-size:.83333rem}.cld__details--alpha{font-size:1rem}.cld__detail,.cld__share{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.cld__detail:only-child:before{content:'>';margin-right:.5em}@media (max-width:29.99em){.cld__detail:last-of-type:not(:first-of-type),.cld__share .cld__detail{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;margin-top:calc(.5 * 1rem);width:100%}}.cld__code{-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#12e09f;border-bottom:calc(.1 * 1rem) solid #92f6d7;border-top:calc(.1 * 1rem) solid #92f6d7;color:#101413;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:1.2rem;padding-bottom:calc(1.5 * 1rem);padding-top:calc(1.5 * 1rem)}.cld__share{-ms-flex-wrap:wrap;flex-wrap:wrap}.cld__share .btn{margin-top:calc(.5 * 1rem)}.cld__copy{bottom:calc(100% + calc(.25 * 1rem));position:absolute;right:calc(.15 * 1rem);width:calc(69px);z-index:1}.cld__input{height:10px;position:absolute;width:10px;z-index:-1}.cld--alpha .cld__content{border-width:1px}.cld--alpha .cld__details{min-height:calc(1.65 * 1rem);padding-bottom:calc(.3 * 1rem);padding-top:calc(.3 * 1rem)}.cld--alpha .cld__details,.cld--alpha .cld__share{font-size:.69444rem}.cld--alpha .cld__code{border-width:1px;font-size:1rem;padding-bottom:calc(1.5 * 1rem);padding-top:calc(1.5 * 1rem)}.cld--alpha .btn.cld__copy{font-size:.5787rem;width:calc(57px)}.visually-hidden{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(1px);clip-path:inset(1px);display:block;height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}.btn{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0eaf7c;border:calc(.1 * 1rem) solid currentColor;color:#101413;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-size:.83333rem;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;line-height:1;min-height:calc(1.5 * 1rem);padding-left:calc(1.05 * 1rem);padding-right:calc(1.05 * 1rem);text-decoration:none}.btn--alpha{background-color:#041f17;border-color:#92f6d7;color:#12e09f}.btn--beta,.cld--alpha .btn{border-width:1px;font-size:.69444rem;min-height:calc(1.2 * 1rem);padding-left:calc(.9 * 1rem);padding-right:calc(.9 * 1rem)} -------------------------------------------------------------------------------- /src/favicons/README.md: -------------------------------------------------------------------------------- 1 | # Your Favicon Package 2 | 3 | This package was generated with [RealFaviconGenerator](https://realfavicongenerator.net/) [v0.16](https://realfavicongenerator.net/change_log#v0.16) 4 | 5 | ## Install instructions 6 | 7 | To install this package: 8 | 9 | Extract this package in <web site>/favicons/. If your site is http://www.example.com, you should be able to access a file named http://www.example.com/favicons/favicon.ico. 10 | 11 | Insert the following code in the `head` section of your pages: 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | *Optional* - Check your favicon with the [favicon checker](https://realfavicongenerator.net/favicon_checker) -------------------------------------------------------------------------------- /src/favicons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/android-chrome-192x192.png -------------------------------------------------------------------------------- /src/favicons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/android-chrome-512x512.png -------------------------------------------------------------------------------- /src/favicons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | #12e09f 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /src/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /src/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/favicon.ico -------------------------------------------------------------------------------- /src/favicons/html_code.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/favicons/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/mstile-144x144.png -------------------------------------------------------------------------------- /src/favicons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/mstile-150x150.png -------------------------------------------------------------------------------- /src/favicons/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/mstile-310x150.png -------------------------------------------------------------------------------- /src/favicons/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/mstile-310x310.png -------------------------------------------------------------------------------- /src/favicons/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/favicons/mstile-70x70.png -------------------------------------------------------------------------------- /src/favicons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/favicons/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Code Line Daily", 3 | "short_name": "Code Line Daily", 4 | "icons": [{ 5 | "src": "/favicons/android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "/favicons/android-chrome-512x512.png", 11 | "sizes": "512x512", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#12e09f", 16 | "background_color": "#fff", 17 | "start_url": "/index.html", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /src/fonts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/fonts/.DS_Store -------------------------------------------------------------------------------- /src/fonts/ptmono/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/fonts/ptmono/.DS_Store -------------------------------------------------------------------------------- /src/fonts/ptmono/ptmono-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/fonts/ptmono/ptmono-regular.woff -------------------------------------------------------------------------------- /src/fonts/ptmono/ptmono-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/fonts/ptmono/ptmono-regular.woff2 -------------------------------------------------------------------------------- /src/gfx/cover/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/cover/.keep -------------------------------------------------------------------------------- /src/gfx/jpg/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/.DS_Store -------------------------------------------------------------------------------- /src/gfx/jpg/cld-2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cld-2x.jpg -------------------------------------------------------------------------------- /src/gfx/jpg/cld.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cld.jpg -------------------------------------------------------------------------------- /src/gfx/jpg/cover-2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cover-2x.jpg -------------------------------------------------------------------------------- /src/gfx/jpg/cover-dark-2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cover-dark-2x.jpg -------------------------------------------------------------------------------- /src/gfx/jpg/cover-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cover-dark.jpg -------------------------------------------------------------------------------- /src/gfx/jpg/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/jpg/cover.jpg -------------------------------------------------------------------------------- /src/gfx/png/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/.DS_Store -------------------------------------------------------------------------------- /src/gfx/png/cld-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cld-2x.png -------------------------------------------------------------------------------- /src/gfx/png/cld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cld.png -------------------------------------------------------------------------------- /src/gfx/png/cover-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cover-2x.png -------------------------------------------------------------------------------- /src/gfx/png/cover-dark-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cover-dark-2x.png -------------------------------------------------------------------------------- /src/gfx/png/cover-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cover-dark.png -------------------------------------------------------------------------------- /src/gfx/png/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/png/cover.png -------------------------------------------------------------------------------- /src/gfx/svg/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maliMirkec/code-line-daily/4613eee3c2aa6b6b72d92617d80ae1c44000bbfc/src/gfx/svg/.DS_Store -------------------------------------------------------------------------------- /src/gfx/svg/cld-logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/gfx/svg/cld-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/gfx/svg/cover.svg: -------------------------------------------------------------------------------- 1 | A line of code of the day. 2 | -------------------------------------------------------------------------------- /src/gfx/svg/placeholder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | > note 8 | 9 | line 10 | 11 | #language 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/gfx/svg/starter-project.svg: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /src/html/404.md: -------------------------------------------------------------------------------- 1 | ## Error 404 2 | 3 | Content not found. 4 | 5 | Go back to [homepage](/). 6 | -------------------------------------------------------------------------------- /src/html/404.pug: -------------------------------------------------------------------------------- 1 | extends ./_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Content Not Found" 5 | - pageURL = "404" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) 404.md 10 | hr 11 | .w.w--beta.mt--beta 12 | p= "Today's best line of code is:" 13 | .w.w--beta.mt 14 | +cld(thisItem, '') 15 | 16 | -------------------------------------------------------------------------------- /src/html/_assets/critical-css.pug: -------------------------------------------------------------------------------- 1 | link(rel="stylesheet", href="css/style.critical.min.css", inline="true") 2 | link(rel="stylesheet", href="css/foft.min.css", inline="true") 3 | -------------------------------------------------------------------------------- /src/html/_assets/deferred-styles.pug: -------------------------------------------------------------------------------- 1 | link(rel="stylesheet", href="/css/style.min.css", media="print", onload="this.media=\"all\"") 2 | 3 | -------------------------------------------------------------------------------- /src/html/_assets/favicon.pug: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/html/_assets/foft-font-loading.pug: -------------------------------------------------------------------------------- 1 | script(src="js/foftFontLoading.min.js", inline="true") 2 | -------------------------------------------------------------------------------- /src/html/_assets/og.pug: -------------------------------------------------------------------------------- 1 | meta(property="og:type" content="website") 2 | 3 | if (siteName) 4 | meta(property="og:title" content=siteName) 5 | 6 | if (siteDesc) 7 | meta(property="og:description" content=siteDesc) 8 | 9 | if (siteURL) 10 | meta(property="og:url" content=siteURL + "/" + pageURL) 11 | 12 | if (siteImg) 13 | meta(property="og:image" content=siteImg) 14 | 15 | if (og && og.twitter_id) 16 | meta(name="twitter:card" content="summary_large_image") 17 | meta(name="twitter:site" content=`@${og.twitter_id}`) 18 | 19 | if (og && og.twitter_creator) 20 | meta(name="twitter:creator" content=`@${og.twitter_creator}`) 21 | 22 | if (siteURL) 23 | meta(property="twitter:url" content=siteURL + "/" + pageURL) 24 | 25 | if (siteName) 26 | meta(name="twitter:title" content=siteName) 27 | 28 | if (siteDesc) 29 | meta(name="twitter:description" content=siteDesc) 30 | 31 | if (siteImg) 32 | meta(property="twitter:image" content=siteImg) 33 | 34 | if (og && og.fb_id) 35 | if (og.fb_id) 36 | meta(name="fb:app_id" content=og.fb_id) 37 | if (og.fb_admins) 38 | meta(name="fb:admins" content=og.fb_admins) 39 | 40 | meta(property="og:locale" content="en_US") 41 | 42 | //- if (isPost()) 43 | //- script(type="application/ld+json"). 44 | //- { 45 | //- "@context": "https://schema.org", 46 | //- "@type": "BlogPosting", 47 | //- "mainEntityOfPage": { 48 | //- "@type": "WebSite", 49 | //- "@id": "#{config.url}" 50 | //- }, 51 | //- "headline": "#{page.title}", 52 | //- "image": [ 53 | //- "#{page.thumbnail.indexOf('http') !== -1 ? page.thumbnail : 'https:' + page.thumbnail}" 54 | //- ], 55 | //- "datePublished": "#{page.date.format()}", 56 | //- "dateModified": "#{page.updated.format()}", 57 | //- "author": { 58 | //- "@type": "Person", 59 | //- "name": "#{config.author}" 60 | //- }, 61 | //- "publisher": { 62 | //- "@type": "Organization", 63 | //- "name": "Cita", 64 | //- "logo": { 65 | //- "@type": "ImageObject", 66 | //- "url": "https://www.cita.hr/favicon/android-chrome-192x192.png" 67 | //- } 68 | //- }, 69 | //- "description": "#{page.description}" 70 | //- } 71 | //- else if (isHome()) 72 | //- script(type="application/ld+json"). 73 | //- { 74 | //- "@context": "https://schema.org", 75 | //- "@type": "WebSite", 76 | //- "url": "#{config.url}", 77 | //- "name": "#{theme.site.short_name}", 78 | //- "about": "#{theme.site.description}", 79 | //- "author": { 80 | //- "@type": "Person", 81 | //- "name": "#{config.author}" 82 | //- } 83 | //- } 84 | //- else 85 | //- script(type="application/ld+json"). 86 | //- { 87 | //- "@context": "https://schema.org", 88 | //- "@type": "BreadcrumbList", 89 | //- "itemListElement": [ 90 | //- { 91 | //- "@type": "ListItem", 92 | //- "position": 1, 93 | //- "item": { 94 | //- "@id": "#{config.url}", 95 | //- "name": "Home" 96 | //- } 97 | //- }, 98 | //- { 99 | //- "@type": "ListItem", 100 | //- "position": 2, 101 | //- "item": { 102 | //- "@id": "#{config.url + '/' + path.replace('index.html','')}", 103 | //- "name": "#{title.replace(" 🤘 " + theme.site.full_name, '')}" 104 | //- } 105 | //- } 106 | //- ] 107 | //- } 108 | 109 | //- link(rel="pingback", href="https://webmention.io/www.silvestar.codes/xmlrpc") 110 | //- link(rel="webmention", href="https://webmention.io/www.silvestar.codes/webmention") 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/html/_assets/scripts.pug: -------------------------------------------------------------------------------- 1 | script(src="/js/index.min.js") 2 | 3 | script(type="module"). 4 | // register service worker 5 | import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-window.prod.mjs'; 6 | if ('serviceWorker' in navigator) { 7 | const displayMessage = () => { 8 | const $swButton = document.createElement('div') 9 | $swButton.className = 'message'; 10 | $swButton.innerHTML = '

The content has been updated. To see the latest changes, refresh the page, please.

'; 11 | document.body.appendChild($swButton) 12 | } 13 | const wb = new Workbox('/sw.js'); 14 | wb.addEventListener('installed', event => { 15 | if (!event.isUpdate) { 16 | displayMessage() 17 | } 18 | }); 19 | wb.addEventListener('activated', (event) => { 20 | if (!event.isUpdate) { 21 | console.log('Service Worker has been installed successfully.') 22 | } else { 23 | displayMessage() 24 | } 25 | }); 26 | wb.addEventListener('message', (event) => { 27 | if (event.data.type === 'CACHE_UPDATED') { 28 | displayMessage() 29 | } 30 | }); 31 | wb.addEventListener('waiting', (event) => { 32 | displayMessage() 33 | }); 34 | wb.addEventListener('externalinstalled', (event) => { 35 | if (!event.isUpdate) { 36 | displayMessage() 37 | } 38 | }); 39 | wb.addEventListener('externalactivated', (event) => { 40 | if (!event.isUpdate) { 41 | console.log('Service Worker has been installed successfully.') 42 | } else { 43 | displayMessage() 44 | } 45 | }); 46 | wb.addEventListener('externalwaiting', (event) => { 47 | displayMessage() 48 | }); 49 | wb.register(); 50 | } 51 | -------------------------------------------------------------------------------- /src/html/_layout/layout.pug: -------------------------------------------------------------------------------- 1 | include /_variables/variables.pug 2 | include /_mixins/cld.pug 3 | 4 | doctype 5 | html(lang="en") 6 | include /_partials/head.pug 7 | body 8 | include /_partials/header.pug 9 | main.main#main 10 | .content 11 | block content 12 | include /_partials/footer.pug 13 | include /_assets/deferred-styles.pug 14 | include /_assets/foft-font-loading.pug 15 | include /_assets/scripts.pug 16 | 17 | -------------------------------------------------------------------------------- /src/html/_layout/line.pug: -------------------------------------------------------------------------------- 1 | include /_variables/line.pug 2 | include /_mixins/cld.pug 3 | 4 | block variables 5 | - pageTitle = "A Line of Code of " + thisItem.date 6 | - pageURL = "line/" + thisItem.date 7 | 8 | doctype 9 | html(lang="en") 10 | include /_partials/head.pug 11 | body 12 | include /_partials/header.pug 13 | main.main#main 14 | .content 15 | block content 16 | article.w.w--alpha.mt--alpha 17 | h1= siteDesc 18 | .w.w--beta.mt--alpha 19 | +cld(thisItem, '', false) 20 | .w.w--beta.w--omega.mt--alpha 21 | if (previousItem) 22 | a.btn.btn--alpha.btn--beta(href="/line/" + previousItem.date + ".html")= "<= Previous" 23 | if (nextItem) 24 | a.btn.btn--alpha.btn--beta(href="/line/" + nextItem.date + ".html")= "Next =>" 25 | include /_partials/footer.pug 26 | include /_assets/deferred-styles.pug 27 | include /_assets/foft-font-loading.pug 28 | include /_assets/scripts.pug 29 | -------------------------------------------------------------------------------- /src/html/_mixins/cld.pug: -------------------------------------------------------------------------------- 1 | mixin cld(line, modifier, linked = true) 2 | - var cldClass = "cld " + modifier; 3 | - var shareTextPlain = encodeURIComponent("Code Line Daily: " + line.line.trim()) 4 | - var shareTextFancy = encodeURIComponent("Code Line Daily:\n" + line.line.trim() + "\n\n") 5 | - var shareRelated = line.handle ? '&related=' + line.handle : '' 6 | - var twitterLink = "https://twitter.com/intent/tweet?url=" + siteURL + "&text=" + shareTextFancy + "&hashtags=loc,cld,codelinedaily," + line.language + "&via=" + og.twitter_id + shareRelated; 7 | - var facebookLink = "https://facebook.com/sharer.php?u=" + siteURL; 8 | - var redditLink = "https://www.reddit.com/submit?url=" + siteURL + "&title=" + shareTextPlain; 9 | - var cldId = line.language + Math.random().toString(36).substring(7); 10 | div(class=cldClass) 11 | .cld__content 12 | a.cld__inner(href=line.link, title="Learn more", target="_blank", rel="noopener") 13 | .cld__details.cld__details--alpha 14 | span.cld__detail #{line.note} 15 | code.cld__code #{line.line} 16 | .cld__details.cld__details--beta 17 | span.cld__detail= "#" + line.language 18 | if (linked) 19 | a.cld__detail(href="/line/" + line.date + ".html")= line.date 20 | else 21 | span.cld__detail= line.date 22 | span.cld__detail. 23 | By: #[a.btn(href="/author/" + line.author.toLowerCase().replace(' ', '-') + ".html", title="See author")=line.author] 24 | button.cld__copy.btn.btn--alpha.btn--beta(onclick="copyToClipboard(this)")= "Copy" 25 | input.cld__input(type="text", value=line.line, id=cldId) 26 | label.visually-hidden(for=cldId)= "Copy command" 27 | .cld__share 28 | span.cld__detail= "Share:" 29 | a.btn(href=twitterLink, target="_blank", rel="noopener", title="Share on Twitter") Twitter 30 | a.btn(href=facebookLink, target="_blank", rel="noopener", title="Share on Facebook") Facebook 31 | a.btn(href=redditLink, target="_blank", rel="noopener", title="Share on Reddit") Reddit 32 | -------------------------------------------------------------------------------- /src/html/_partials/footer.pug: -------------------------------------------------------------------------------- 1 | //- include /_partials/signup.pug 2 | 3 | .hf.mt--alpha 4 | .w.w--beta.hf__inner 5 | a.hf__logo(href="/") 6 | .hf__img 7 | img.hf__src(src="/gfx/svg/cld-logo.svg", alt="Code Line Daily Icon", inline="true") 8 | .hf__cld #{siteName} 9 | nav.hf__nav 10 | ul.hf__list 11 | each menuValue, menuIndex in menu2 12 | - var currentClass = menuValue.title == pageTitle ? 'hf__link active' : 'hf__link'; 13 | li.hf__item 14 | if (menuValue.title === "Twitter") 15 | a(class=currentClass, href=menuValue.href, rel="me")= menuValue.title 16 | else 17 | a(class=currentClass, href=menuValue.href)= menuValue.title 18 | 19 | .sig 20 | p Powered by #[a.sig__link(href="https://starter.silvestar.codes") #[img.sig__icon(src="/gfx/svg/starter-project.svg", alt="Starter Project Icon", inline="true")] Starter Project]. 21 | -------------------------------------------------------------------------------- /src/html/_partials/head.pug: -------------------------------------------------------------------------------- 1 | block variables 2 | head 3 | meta(charset="utf-8") 4 | meta(name="viewport", content="width=device-width, initial-scale=1.0") 5 | meta(http-equiv="X-UA-Compatible", content="ie=edge") 6 | 7 | title= pageTitle + " ❇ " + siteName 8 | meta(name="description", content=siteDesc) 9 | 10 | include ../_assets/og.pug 11 | 12 | link(rel="preload", href="/css/style.min.css", as="style") 13 | link(rel="preload", href="/js/index.min.js", as="script") 14 | 15 | link(rel="dns-prefetch", href="//cdn.optimizely.com") 16 | link(rel="preconnect", href="//cdn.optimizely.com", crossorigin="true") 17 | 18 | link(rel="webmention", href="https://webmention.io/cld.silvestar.codes/webmention") 19 | link(rel="pingback", href="https://webmention.io/cld.silvestar.codes/xmlrpc") 20 | 21 | script(src="//instant.page/3.0.0", type="module", defer="true", integrity="sha384-OeDn4XE77tdHo8pGtE1apMPmAipjoxUQ++eeJa6EtJCfHlvijigWiJpD7VDPWXV1") 22 | 23 | include ../_assets/favicon.pug 24 | include ../_assets/critical-css.pug 25 | 26 | link(rel="canonical", href=siteURL + "/" + pageURL) 27 | 28 | link(rel="alternate", type="application/rss+xml", title="RSS Feed for cld.silvestar.codes", href="/rss.xml") 29 | -------------------------------------------------------------------------------- /src/html/_partials/header.pug: -------------------------------------------------------------------------------- 1 | .hf 2 | .w.w--beta.hf__inner 3 | a.hf__skip(href="#main")= "Skip to main content" 4 | a.hf__logo(href="/") 5 | .hf__img 6 | img.hf__src(src="/gfx/svg/cld-logo.svg", alt="Code Line Daily Icon", inline="true") 7 | .hf__cld #{siteName} 8 | nav.hf__nav 9 | ul.hf__list 10 | each menuValue, menuIndex in menu 11 | - var currentClass = menuValue.title == pageTitle ? 'hf__link active' : 'hf__link'; 12 | li.hf__item 13 | a(class=currentClass, href=menuValue.href)= menuValue.title 14 | 15 | -------------------------------------------------------------------------------- /src/html/_partials/signup.pug: -------------------------------------------------------------------------------- 1 | .w.w--beta.mt--alpha 2 | .form-wrapper 3 | h2.t-h2= "Subscribe to Code Line Daily newsletter" 4 | #mc_embed_signup 5 | form.form(action="https://gmail.us4.list-manage.com/subscribe/post?u=e599feae2e1250eeb9fd674e2&id=a19cadbd6d" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" target="_blank" 6 | novalidate) 7 | #mc_embed_signup_scroll 8 | .form__group 9 | label(for="mce-EMAIL")= "Email Address" 10 | input(type="email" name="EMAIL" id="mce-EMAIL" value="") 11 | .form__group 12 | span= "Get it weekly or daily?" 13 | div.form__radio 14 | div.form__element 15 | input(type="radio" value="Weekly" name="FREQ" id="mce-FREQ-0") 16 | label(for="mce-FREQ-0")= "Weekly" 17 | div.form__element 18 | input(type="radio" value="Daily" name="FREQ" id="mce-FREQ-1") 19 | label(for="mce-FREQ-1")= "Daily" 20 | #mce-responses 21 | #mce-error-response.response(style="display:none") 22 | #mce-success-response.response(style="display:none") 23 | .form__group(style="position: absolute; left: -5000px;" aria-hidden="true") 24 | input(type="text" name="b_e599feae2e1250eeb9fd674e2_a19cadbd6d" tabindex="-1" value="") 25 | .form__group 26 | input.btn(type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe") 27 | -------------------------------------------------------------------------------- /src/html/_variables/line.pug: -------------------------------------------------------------------------------- 1 | block variables 2 | - var siteName = locals.site.siteName ? locals.site.siteName : 'Code Line Daily'; 3 | - var siteDesc = locals.site.siteDesc ? locals.site.siteDesc : 'A line of code of the day.'; 4 | - var siteURL = locals.site.siteURL ? locals.site.siteURL : '/'; 5 | //- - var siteImg = locals.site.siteImg ? locals.site.siteImg : '/'; 6 | - var og = locals.site.og ? locals.site.og : '/'; 7 | - var menu = locals.site.menu ? locals.site.menu : []; 8 | - var menu2 = locals.site.menu2 ? locals.site.menu2 : []; 9 | - var thisItem = locals.line 10 | - var siteImg = siteURL + '/gfx/cover/' + thisItem.date + '.png' 11 | - var previousItem = locals.previous 12 | - var nextItem = locals && locals.next && new Date(locals.next.date) < new Date() ? locals.next : false; 13 | 14 | - function formatNumber(num) 15 | - return num < 10 ? '0' + num : num; 16 | 17 | - function formatDate(date) 18 | - var d = new Date(date); 19 | - return d.getFullYear() + '-' + formatNumber(d.getMonth() + 1) + '-' + formatNumber(d.getDate()); 20 | -------------------------------------------------------------------------------- /src/html/_variables/variables.pug: -------------------------------------------------------------------------------- 1 | block variables 2 | - var siteName = locals.site.siteName ? locals.site.siteName : 'Code Line Daily'; 3 | - var siteDesc = locals.site.siteDesc ? locals.site.siteDesc : 'A line of code of the day.'; 4 | - var siteURL = locals.site.siteURL ? locals.site.siteURL : '/'; 5 | //- - var siteImg = locals.site.siteImg ? locals.site.siteImg : '/'; 6 | - var og = locals.site.og ? locals.site.og : '/'; 7 | - var menu = locals.site.menu ? locals.site.menu : []; 8 | - var menu2 = locals.site.menu2 ? locals.site.menu2 : []; 9 | - var list = locals.data.list ? locals.data.list.filter(item => new Date(item.date) < new Date()) : []; 10 | - var thisItem = list.slice(-1).pop() 11 | - var listArchive = list.slice().reverse(); 12 | - var listEvergreen = list.slice().filter(item => item.evergreen); 13 | - var hash = new Date().getTime(); 14 | - var siteImg = siteURL + '/gfx/cover/' + thisItem.date + '.png?' + hash; 15 | 16 | - function formatNumber(num) 17 | - return num < 10 ? '0' + num : num; 18 | 19 | - function formatDate(date) 20 | - var d = new Date(date); 21 | - return d.getFullYear() + '-' + formatNumber(d.getMonth() + 1) + '-' + formatNumber(d.getDate()); 22 | -------------------------------------------------------------------------------- /src/html/about.md: -------------------------------------------------------------------------------- 1 | # About Code Line Daily 2 | 3 | Code Line Daily is a project made by [Silvestar Bistrović] in his free time. The goal of the project is to highlight the simplicity in the code, the essence, if you will: a single line of code. 4 | 5 | ## Open-source project 6 | 7 | The project is open-sourced, and you are very welcome to add your line of code, fix any bug, report any issue, or suggest any improvement. To add your favorite line of code, you could either use: 8 | 9 | - [CMS to submit the line], or 10 | - [GitHub to create a new pull request]. 11 | 12 | And don't forget to share and follow the project! Code Line Daily is available on [Twitter], [Facebook], and [IndieHackers]. 13 | 14 | --- 15 | 16 | Code Line Daily is build by [Starter Project], [Netlify], and [Netlify CMS]. 17 | 18 | [Silvestar Bistrović]: https://www.silvestar.codes 19 | [CMS to submit the line]: https://cld.silvestar.codes/commit/ 20 | [GitHub to create a new pull request]: https://github.com/maliMirkec/code-line-daily 21 | [Starter Project]: https://www.silvestar.codes 22 | [Netlify]: https://www.netlify.com/ 23 | [Netlify CMS]: https://www.netlifycms.org/ 24 | [Twitter]: https://twitter.com/CodeLineDaily 25 | [Facebook]: tps://www.facebook.com/CodeLineDaily 26 | [IndieHackers]: https://www.indiehackers.com/product/code-line-daily 27 | -------------------------------------------------------------------------------- /src/html/about.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "About" 5 | - pageURL = "about" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) about.md 10 | hr 11 | .w.w--beta.mt--beta 12 | p= "Today's best line of code is:" 13 | .w.w--beta.mt 14 | +cld(thisItem, '') 15 | -------------------------------------------------------------------------------- /src/html/archive.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Archive" 5 | - pageURL = "archive" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | h1= "An archive of lines of code of the day." 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date DESC" 12 | .w.w--alpha.grid 13 | each listValue, listIndex in listArchive 14 | +cld(listValue, 'cld--alpha') 15 | -------------------------------------------------------------------------------- /src/html/author/ethan-chin.md: -------------------------------------------------------------------------------- 1 | # Posts by: Ethan Chin 2 | 3 | iDev. 4 | -------------------------------------------------------------------------------- /src/html/author/ethan-chin.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Posts by: Ethan Chin" 5 | - pageURL = "author/ethan-chin" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) ethan-chin.md 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date DESC" 12 | .w.w--alpha.grid 13 | - var authorArchive = listArchive.filter(item => item.author === "Ethan Chin") 14 | each listValue, listIndex in authorArchive 15 | +cld(listValue, 'cld--alpha') 16 | -------------------------------------------------------------------------------- /src/html/author/heithem-moumni.md: -------------------------------------------------------------------------------- 1 | # Posts by: Heithem Moumni 2 | 3 | A lover of accessability, Docker, JavaScript, IA, DevJoke Connoisseur. 4 | -------------------------------------------------------------------------------- /src/html/author/heithem-moumni.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Posts by: Heithem Moumni" 5 | - pageURL = "author/heithem-moumni" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) heithem-moumni.md 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date DESC" 12 | .w.w--alpha.grid 13 | - var authorArchive = listArchive.filter(item => item.author === "Heithem Moumni") 14 | each listValue, listIndex in authorArchive 15 | +cld(listValue, 'cld--alpha') 16 | -------------------------------------------------------------------------------- /src/html/author/silvestar.md: -------------------------------------------------------------------------------- 1 | # Posts by: Silvestar Bistrović 2 | 3 | Silvestar is a fearless web developer, CSS craftsman, JAMstack enthusiast, and WordPress theme specialist. 4 | 5 | Read more about Silvestar on his website: [https://www.silvestar.codes](https://www.silvestar.codes) 6 | -------------------------------------------------------------------------------- /src/html/author/silvestar.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Posts by: Silvestar Bistrović" 5 | - pageURL = "author/silvestar" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) silvestar.md 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date DESC" 12 | .w.w--alpha.grid 13 | - var authorArchive = listArchive.filter(item => item.author === "Silvestar") 14 | each listValue, listIndex in authorArchive 15 | +cld(listValue, 'cld--alpha') 16 | -------------------------------------------------------------------------------- /src/html/covers.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Covers" 5 | - pageURL = "covers" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | h1= "An archive of lines of code of the day." 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date DESC" 12 | .w.w--alpha.grid 13 | each listValue, listIndex in listArchive 14 | div 15 | h2.t-p= listValue.line 16 | img(src=siteURL + "/gfx/cover/" + listValue.date + ".png", alt="Cover for " + listValue.line) 17 | -------------------------------------------------------------------------------- /src/html/evergreen.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Evergreen" 5 | - pageURL = "evergreen" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | h1= "All time best lines of code of the day." 10 | .w.w--alpha.mt--alpha 11 | p.t-sm.t-r= "Sorted by: Date ASC" 12 | .w.w--alpha.grid 13 | each listValue, listIndex in listEvergreen 14 | +cld(listValue, 'cld--alpha') 15 | -------------------------------------------------------------------------------- /src/html/index.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Home" 5 | - pageURL = "" 6 | 7 | block content 8 | article.w.w--alpha.mt--alpha 9 | h1= siteDesc 10 | .w.w--beta.mt--alpha 11 | +cld(thisItem, '') 12 | .w.w--alpha.mt--alpha 13 | h2.t-h1= "Archive" 14 | .w.w--alpha.grid.mt--beta 15 | each listValue, listIndex in listArchive 16 | if(listIndex != 0 && listIndex < 3) 17 | +cld(listValue, 'cld--alpha') 18 | .w.w--alpha.mt--beta 19 | a.btn.btn--alpha.btn--beta(href="/archive.html")= "See full archive =>" 20 | .w.w--alpha.mt--alpha 21 | h2.t-h1= "Evergreen" 22 | .w.w--alpha.grid.mt--beta 23 | each listValue, listIndex in listEvergreen 24 | if(listIndex < 2) 25 | +cld(listValue, 'cld--alpha') 26 | .w.w--alpha.mt--beta 27 | a.btn.btn--alpha.btn--beta(href="/evergreen.html")= "See evergreen lines =>" 28 | .w.w--beta.mt--alpha 29 | h2.t-h1= "Around the web" 30 | .w.w--beta.mt--beta.grid 31 | div 32 | p= "Featured on Product Hunt" 33 | a(href="https://www.producthunt.com/posts/code-line-daily?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-code-line-daily", target="_blank", rel="noopener") 34 | img(src= "https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=165832&theme=light" alt="Code Line Daily - Explore a new line of code every day | Product Hunt Embed" style="width: 250px; height: 54px;" width="250px" height="54px" ) 35 | div 36 | p= "Chrome Extension available" 37 | a.btn.btn--gamma(href="https://chrome.google.com/webstore/detail/code-line-daily/jfgojeolhopchbgfdgodicnaimmkbpbg", target="_blank", rel="noopener")= "Install the Chrome extension" 38 | -------------------------------------------------------------------------------- /src/html/privacy.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | Effective Date: 2019-08-01 4 | 5 | At https://cld.silvestar.codes/ (the “Site”), we are committed to protecting your privacy. This privacy policy outlines the limited nature of our interaction with visitors and how we handle any data that may be related to your use of this Site. 6 | 7 | ## No Data Collection 8 | 9 | We do not collect, store, or process any personal data from visitors to this Site. This means: 10 | 11 | - We do not use cookies or other tracking mechanisms. 12 | - We do not request, store, or process any personally identifiable information (e.g., names, email addresses). 13 | - We do not track users’ behavior or actions on the Site. 14 | 15 | ## Third-Party Services 16 | 17 | As of the effective date of this policy, this Site does not integrate or make use of any third-party services that collect data or track user behavior. Should this change in the future, this privacy policy will be updated accordingly. 18 | 19 | ## External Links 20 | 21 | Our Site may contain links to other websites. We are not responsible for the content or privacy practices of external sites. We recommend reviewing the privacy policies of any third-party websites that you visit. 22 | 23 | ## Changes to This Privacy Policy 24 | 25 | We reserve the right to update or change this privacy policy at any time. Any changes will be posted on this page with an updated effective date. 26 | 27 | ## Contact Us 28 | 29 | If you have any questions or concerns about this privacy policy, feel free to contact us at: 30 | me[at]silvestar.codes 31 | -------------------------------------------------------------------------------- /src/html/privacy.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/layout.pug 2 | 3 | block variables 4 | - pageTitle = "Privacy" 5 | - pageURL = "privacy" 6 | 7 | block content 8 | article.w.w--beta.mt--alpha 9 | include:markdown-it(html) privacy.md 10 | hr 11 | .w.w--beta.mt--beta 12 | p= "Today's best line of code is:" 13 | .w.w--beta.mt 14 | +cld(thisItem, '') 15 | -------------------------------------------------------------------------------- /src/js/foftFontLoading.js: -------------------------------------------------------------------------------- 1 | import FontFaceObserver from 'fontfaceobserver' 2 | 3 | /** 4 | * A better font loading using FontFaceObserver. 5 | * 6 | * @module CriticalFOFT 7 | * @author Zach Leatherman 8 | * @see https://www.zachleat.com/web/comprehensive-webfonts/#critical-foft 9 | */ 10 | 11 | /** 12 | * @constructor 13 | * @author Zach Leatherman 14 | * @see https://www.zachleat.com/web/comprehensive-webfonts/#critical-foft 15 | */ 16 | 17 | /** 18 | * @function 19 | * @name Anonymous self-invoked function 20 | * @description Adds classes to document when each font loads successfully. 21 | * If fonts are already loaded, then skip loading. 22 | */ 23 | (function () { 24 | if (window.sessionStorage.criticalFoftDataUriFontsLoaded) { 25 | document.documentElement.className += ' fonts-stage-1 fonts-stage-2' 26 | return 27 | } 28 | 29 | /** 30 | * A subset of default font type. 31 | * 32 | * @const 33 | * @name fontASubset 34 | * @type {Object} 35 | */ 36 | const fontASubset = new FontFaceObserver('PT Mono Subset') 37 | 38 | /** 39 | * A promise that adds 'fonts-stage-1' if {@link fontASubset} 40 | * is loaded successfully. 41 | * 42 | * @method 43 | * @name Promise 44 | */ 45 | Promise.all([fontASubset.load()]).then(() => { 46 | document.documentElement.className += ' fonts-stage-1' 47 | 48 | /** 49 | * Default font type. 50 | * 51 | * @const 52 | * @name fontA 53 | * @type {Object} 54 | */ 55 | const fontA = new FontFaceObserver('PT Mono') 56 | 57 | /** 58 | * A promise that adds 'fonts-stage-2' if 59 | * {@link fontA}, {@link fontB}, {@link fontC}, {@link fontD} 60 | * are loaded successfully. 61 | * Also, set Critical FOFT session variable to true. 62 | * 63 | * @method 64 | * @name Promise 65 | */ 66 | Promise.all([fontA.load()]).then(() => { 67 | document.documentElement.className += ' fonts-stage-2' 68 | 69 | // Optimization for Repeat Views 70 | window.sessionStorage.criticalFoftDataUriFontsLoaded = true 71 | }) 72 | }) 73 | })() 74 | -------------------------------------------------------------------------------- /src/js/homepage.md: -------------------------------------------------------------------------------- 1 | # [Code Line Daily] 2 | 3 | ![Code Line Daily Logo](https://raw.githubusercontent.com/maliMirkec/code-line-daily/master/src/gfx/png/cld.png) 4 | 5 | A line of code of the day. 6 | 7 | [Code Line Daily]: https://github.com/maliMirkec/code-line-daily 8 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | console.log('Powered by Starter Project (https://starter.silvestar.codes).') 2 | 3 | function copyToClipboard (elem) { 4 | /* Get the text field */ 5 | const $elem = elem 6 | const copyText = $elem.nextElementSibling 7 | 8 | if (copyText) { 9 | /* Select the text field */ 10 | copyText.select() 11 | copyText.setSelectionRange(0, 99999) /* For mobile devices */ 12 | 13 | /* Copy the text inside the text field */ 14 | document.execCommand('copy') 15 | 16 | $elem.innerHTML = 'Copied!' 17 | 18 | setTimeout(() => { 19 | $elem.innerHTML = 'Copy' 20 | }, 1750) 21 | } 22 | } 23 | 24 | window.copyToClipboard = copyToClipboard 25 | -------------------------------------------------------------------------------- /src/scss/components/_colors.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | // 3 | // This is a color palette for the CCI website. You shall have no other colors before these. 4 | // 5 | // Use `.c-$color` class for text color. 6 | // 7 | // Use `.bgc-$color` class for background color. 8 | // 9 | // Replace `$color` with corresponding color name. 10 | // 11 | // Example: 12 | // ``` 13 | //
...
14 | //
...
15 | // ``` 16 | // 17 | // --- 18 | // 19 | // Colors: 20 | // primary-alpha: #12e09f - Primary Alpha 21 | // primary-beta: #92f6d7 - Primary Beta 22 | // secondary-alpha: #041f17 - Secondary Alpha 23 | // secondary-beta: #0c201a - Secondary Beta 24 | // secondary-gamma: #101413 - Secondary Gamma 25 | // 26 | // Weight: 100 27 | // 28 | // Styleguide: Colors 29 | 30 | .c-primary-alpha { 31 | color: $color-primary--alpha; 32 | } 33 | 34 | .c-primary-beta { 35 | color: $color-primary--beta; 36 | } 37 | 38 | .c-secondary--alpha { 39 | color: $color-secondary--alpha; 40 | } 41 | 42 | .c-secondary--beta { 43 | color: $color-secondary--beta; 44 | } 45 | 46 | .c-secondary--gamma { 47 | color: $color-secondary--beta; 48 | } 49 | 50 | .bg-primary--alpha { 51 | background-color: $color-primary--alpha; 52 | } 53 | 54 | .bg-primary--beta { 55 | background-color: $color-primary--beta; 56 | } 57 | 58 | .bg-secondary-alpha { 59 | background-color: $color-secondary--alpha; 60 | } 61 | 62 | .bg-secondary-beta { 63 | background-color: $color-secondary--beta; 64 | } 65 | 66 | .bg-secondary-gamma { 67 | background-color: $color-secondary--beta; 68 | } 69 | -------------------------------------------------------------------------------- /src/scss/components/_fonts.scss: -------------------------------------------------------------------------------- 1 | // Use this if no web font is present in design 2 | // body { 3 | // font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 4 | // } 5 | 6 | // Use this if using web fonts 7 | body { 8 | font-family: 'Courier New', Courier, monospace; 9 | line-height: $line-height; 10 | } 11 | 12 | .fonts-stage-1 body { 13 | font-family: $font-alpha-subset, monospace; 14 | font-style: normal; 15 | font-weight: 400; 16 | } 17 | 18 | .fonts-stage-2 body { 19 | font-family: $font-alpha, monospace; 20 | font-style: normal; 21 | font-weight: 400; 22 | } 23 | -------------------------------------------------------------------------------- /src/scss/components/_helpers.scss: -------------------------------------------------------------------------------- 1 | /// Function for converting a value to rem unit 2 | /// @access public 3 | /// @author Silvestar Bistrović 4 | /// @example font-size: rem(20px, 'mobile'); 5 | /// @group 3.1.Helpers 6 | /// @name rem 7 | /// @since 1.0.0 8 | /// @param {Unit} $size [20px] A value with unit (e.g. 20px) 9 | /// @param {String} $media ['desktop'] A media, (e.g. 'desktop' or 'mobile') 10 | /// @return {Unit} Returns a value converted in rem; returns 1rem if media is not 'desktop' or 'mobile' 11 | 12 | @function rem($size: 20px, $media: 'desktop') { 13 | @if $media == 'desktop' { 14 | @return calc(#{strip-unit($size / $font-size--desktop)} * 1rem); 15 | } @else if $media == 'mobile' { 16 | @return calc(#{strip-unit($size / $font-size--mobile)} * 1rem); 17 | } @else { 18 | @return 1rem; 19 | } 20 | } 21 | 22 | /// Function that calculates tracking 23 | /// @access public 24 | /// @author Silvestar Bistrović 25 | /// @example letter-spacing: tracking(200); 26 | /// @group 3.1.Helpers 27 | /// @name tracking 28 | /// @since 1.0.0 29 | /// @param {Integer} $tracking [0] Tracking value without a unit (e.g. 200) 30 | /// @param {String} $media ['desktop'] A media, (e.g. 'desktop' or 'mobile') 31 | /// @return {Unit} Returns a tracking value 32 | 33 | @function tracking($tracking: 0) { 34 | @if $tracking == 0 { 35 | @return 0; 36 | } @else { 37 | @return calc(#{$tracking} / 1000 * 1em); 38 | } 39 | } 40 | 41 | /// Mixin for defining tracking 42 | /// @access public 43 | /// @author Silvestar Bistrović 44 | /// @example @include ls(100); 45 | /// @group 3.1.Helpers 46 | /// @name ls 47 | /// @since 1.0.0 48 | /// @param {Integer} $tracking [0] Tracking value without a unit (e.g. 200) 49 | @mixin ls($tracking: 0) { 50 | letter-spacing: tracking(#{strip-unit($tracking)}); 51 | } 52 | 53 | /// Mixin for reseting padding and margin to zero 54 | /// @access public 55 | /// @author Silvestar Bistrović 56 | /// @example @include zero-box; 57 | /// @group 3.1.Helpers 58 | /// @name zero-box 59 | /// @since 1.0.0 60 | @mixin zero-box() { 61 | margin: 0; 62 | padding: 0; 63 | } 64 | 65 | /// Mixin for defining transition 66 | /// @access public 67 | /// @author Silvestar Bistrović 68 | /// @example @include tra($trd, $tra); 69 | /// @group 3.1.Helpers 70 | /// @name tra 71 | /// @since 1.0.0 72 | /// @param {Unit} $transition-duration [$trd] A duration of the transition (e.g. 1s) 73 | /// @param {String} $transition-animation [$tra] An easing function of the transition (e.g. linear or cubic-bezier(0.04, 0.88, 0.74, 1.04)) 74 | @mixin tra($transition-duration: $trd, $transition-animation: $tra) { 75 | transition: all $transition-duration $transition-animation; 76 | } 77 | -------------------------------------------------------------------------------- /src/scss/components/_locks.scss: -------------------------------------------------------------------------------- 1 | /// Function for stripping units 2 | /// @access public 3 | /// @author Silvestar Bistrović 4 | /// @example font-size: strip-unit(20px); 5 | /// @group 2.1.Locks 6 | /// @name strip-unit 7 | /// @since 1.0.0 8 | /// @param {Unit} $value A value with unit (e.g. 20px) 9 | /// @return {Integer} Returns a value without unit 10 | /// @link https://css-tricks.com/snippets/css/fluid-typography/ 11 | 12 | @function strip-unit($value) { 13 | @return $value / ($value * 0 + 1); 14 | } 15 | 16 | /// Mixin for creating CSS Locks 17 | /// @access public 18 | /// @author Silvestar Bistrović 19 | /// @example @include css-locks(font-size, 480px, 960px, 14px, 20px); 20 | /// @group 2.1.Locks 21 | /// @name css-locks 22 | /// @since 1.0.0 23 | /// @param {String} $properties A property (e.g. font-size) 24 | /// @param {Unit} $min-vw A minimal view width (e.g. 480px) 25 | /// @param {Unit} $max-vw A maximal view width (e.g. 960px) 26 | /// @param {Unit} $min-value A minimal value for lock (e.g. 14px) 27 | /// @param {Unit} $max-value A maximum value for lock (e.g. 20px) 28 | /// @link https://css-tricks.com/snippets/css/fluid-typography/ 29 | @mixin css-locks($properties, $min-vw, $max-vw, $min-value, $max-value) { 30 | @each $property in $properties { 31 | #{$property}: $min-value; 32 | } 33 | 34 | @media screen and (min-width: $min-vw) { 35 | @each $property in $properties { 36 | #{$property}: calc(#{$min-value} + #{strip-unit($max-value - $min-value)} * (100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)}); 37 | } 38 | } 39 | 40 | @media screen and (min-width: $max-vw) { 41 | @each $property in $properties { 42 | #{$property}: $max-value; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/scss/components/_theme.scss: -------------------------------------------------------------------------------- 1 | @import 'elements/global'; 2 | @import 'elements/content'; 3 | @import 'elements/hf'; 4 | @import 'elements/cld'; 5 | @import 'elements/form'; 6 | @import 'elements/btn'; 7 | @import 'elements/sig'; 8 | @import 'elements/message'; 9 | -------------------------------------------------------------------------------- /src/scss/components/_typography.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | // 3 | // [Modular Scale](http://www.modularscale.com/) is used to achieve perfect vertical rhythm. 4 | //
5 | // [CSS Locks](https://fvsch.com/code/css-locks/) is used to achieve perfect fluid typography. 6 | // 7 | // Markup: 8 | //
9 | //

About Code Line Daily

10 | //

Code Line Daily is a project made by Silvestar Bistrović in his free time. The goal of the project is to highlight the simplicity in the code, the essence, if you will—a single line of code.

11 | //

Open source

12 | //

The project is open-sourced, and you are very welcome to add your line of code, fix any bug, report any issue, or suggest any improvement. To add your favorite line of code, you could use either CMS to submit the line or GitHub to create a new pull request.

13 | //

And don't forget to share the project with the community! Code Line Daily is available on Twitter, Facebook, and IndieHackers.

14 | //
15 | // 16 | // Weight: 200 17 | // 18 | // Styleguide: Typography 19 | 20 | html { 21 | @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 22 | } 23 | 24 | body { 25 | @include ls(20); 26 | font-size: ms(0); 27 | -webkit-font-smoothing: antialiased; 28 | line-height: $line-height; 29 | -moz-osx-font-smoothing: grayscale; 30 | } 31 | 32 | // Headings 33 | // 34 | // Headings are usually used as titles. Use `.t-h1` and `.t-h2` as helper classes to force apply desired heading style to non-matching elements. 35 | // 36 | // Markup: 37 | //
38 | //

This is an H1 heading.

39 | //

This is an H2 heading.

40 | //
41 | // 42 | // Weight: 210 43 | // 44 | // Styleguide: Typography.Headings 45 | h1, 46 | .t-h1 { 47 | font-size: ms(3); 48 | font-weight: normal; 49 | } 50 | 51 | h2, 52 | .t-h2 { 53 | font-size: ms(1); 54 | font-weight: normal; 55 | } 56 | 57 | // Paragraphs 58 | // 59 | // Paragraphs are usualy used as body text. Use `.t-p` and `t-sm` as helper classes to force apply desired paragraph style to a non-matching element. 60 | // 61 | // Markup: 62 | //
63 | //

This is a regular paragraph.

64 | //
65 | // 66 | // .t-p - Font size: ms(0) 67 | // .t-sm - Font size: ms(-1) 68 | // .t-xs - Font size: ms(-2) 69 | // 70 | // Weight: 220 71 | // 72 | // Styleguide: Typography.Paragraphs 73 | p, 74 | .t-p { 75 | font-size: ms(0); 76 | } 77 | 78 | .t-sm { 79 | font-size: ms(-1); 80 | } 81 | 82 | .t-xs { 83 | font-size: ms(-2); 84 | } 85 | 86 | .t-r { 87 | text-align: right; 88 | } 89 | 90 | ::selection { 91 | background-color: $color-primary--alpha; 92 | color: $color-secondary--alpha; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /src/scss/components/_variables.scss: -------------------------------------------------------------------------------- 1 | /// Media query definition for mobile devices, used in css-locks. 2 | /// @access public 3 | /// @author Silvestar Bistrović 4 | /// @example @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 5 | /// @group 1.1.Sizes 6 | /// @name mq--mobile 7 | /// @since 1.0.0 8 | $mq--mobile: 480px; 9 | 10 | /// Media query definition for desktop devices, used in css-locks. 11 | /// @access public 12 | /// @author Silvestar Bistrović 13 | /// @example @include css-locks(font-size, $mq--mobile, $mq--tablet, $font-size--mobile, $font-size--tablet); 14 | /// @group 1.1.Sizes 15 | /// @name mq--tablet 16 | /// @since 1.0.0 17 | $mq--tablet: 768px; 18 | 19 | /// Media query definition for desktop devices, used in css-locks. 20 | /// @access public 21 | /// @author Silvestar Bistrović 22 | /// @example @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 23 | /// @group 1.1.Sizes 24 | /// @name mq--desktop 25 | /// @since 1.0.0 26 | $mq--desktop: 960px; 27 | 28 | /// Media query definition for wide devices, used in css-locks. 29 | /// @access public 30 | /// @author Silvestar Bistrović 31 | /// @example @include css-locks(font-size, $mq--mobile, $mq--wide, $font-size--mobile, $font-size--wide); 32 | /// @group 1.1.Sizes 33 | /// @name mq--wide 34 | /// @since 1.0.0 35 | $mq--wide: 1440px; 36 | 37 | /// Default font size on mobile devices, used in css-locks. 38 | /// @access public 39 | /// @author Silvestar Bistrović 40 | /// @example @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 41 | /// @group 1.1.Sizes 42 | /// @name font-size--mobile 43 | /// @since 1.0.0 44 | $font-size--mobile: 16px; 45 | 46 | /// Default font size on desktop devices, used in css-locks. 47 | /// @access public 48 | /// @author Silvestar Bistrović 49 | /// @example @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 50 | /// @group 1.1.Sizes 51 | /// @name font-size--desktop 52 | /// @since 1.0.0 53 | $font-size--desktop: 20px; 54 | 55 | /// Default line-height 56 | /// @access public 57 | /// @author Silvestar Bistrović 58 | /// @example line-height: $line-height; 59 | /// @group 1.1.Sizes 60 | /// @name line-height 61 | /// @since 1.0.0 62 | $line-height: 1.5; 63 | 64 | /// Default letter-spacing 65 | /// @access public 66 | /// @author Silvestar Bistrović 67 | /// @example letter-spacing: $letter-spacing; 68 | /// @group 1.1.Sizes 69 | /// @name letter-spacing 70 | /// @since 1.0.0 71 | $letter-spacing: 0.02em; 72 | 73 | /// Configuration for modular scale 74 | /// @access public 75 | /// @author Silvestar Bistrović 76 | /// @example @include css-locks(font-size, $mq--mobile, $mq--desktop, $font-size--mobile, $font-size--desktop); 77 | /// @group 1.1.Sizes 78 | /// @name modularscale 79 | /// @since 1.0.0 80 | /// @link http://www.modularscale.com/ 81 | $modularscale: ( 82 | base: 1rem, 83 | ratio: $minor-third 84 | ); 85 | 86 | /// Configuration for media queries 87 | /// @access public 88 | /// @author Silvestar Bistrović 89 | /// @example 90 | /// @include mq($from: mobile, $until: desktop) { 91 | /// color: $color-alpha; 92 | /// } 93 | /// @group 1.1.Sizes 94 | /// @name mq-breakpoints 95 | /// @since 1.0.0 96 | /// @link https://www.npmjs.com/package/sass-mq 97 | $mq-breakpoints: ( 98 | mobile: $mq--mobile, 99 | tablet: $mq--tablet, 100 | desktop: $mq--desktop, 101 | wide: $mq--wide 102 | ); 103 | 104 | /// Color from color palette 105 | /// @access public 106 | /// @author Silvestar Bistrović 107 | /// @example color: $color-primary--alpha; 108 | /// @group 1.2.Colors 109 | /// @name color-primary--alpha 110 | /// @since 1.0.0 111 | $color-primary--alpha: #12e09f; 112 | 113 | /// Color from color palette 114 | /// @access public 115 | /// @author Silvestar Bistrović 116 | /// @example color: $color-primary--beta; 117 | /// @group 1.2.Colors 118 | /// @name color-primary--beta 119 | /// @since 1.0.0 120 | $color-primary--beta: #92f6d7; 121 | 122 | /// Color from color palette 123 | /// @access public 124 | /// @author Silvestar Bistrović 125 | /// @example color: $color-primary--gamma; 126 | /// @group 1.2.Colors 127 | /// @name color-primary--gamma 128 | /// @since 1.0.0 129 | $color-primary--gamma: #0eaf7c; 130 | 131 | /// Color from color palette 132 | /// @access public 133 | /// @author Silvestar Bistrović 134 | /// @example color: $color-secondary--alpha; 135 | /// @group 1.2.Colors 136 | /// @name color-secondary--alpha 137 | /// @since 1.0.0 138 | $color-secondary--alpha: #041f17; 139 | 140 | /// Color from color palette 141 | /// @access public 142 | /// @author Silvestar Bistrović 143 | /// @example color: $color-secondary--beta; 144 | /// @group 1.2.Colors 145 | /// @name color-secondary--beta 146 | /// @since 1.0.0 147 | $color-secondary--beta: #101413; 148 | 149 | /// Transition duration 150 | /// @access public 151 | /// @author Silvestar Bistrović 152 | /// @example transition-duration: $tra; 153 | /// @group 1.3.Transitions 154 | /// @name trd 155 | /// @since 1.0.0 156 | $trd: 0.175s; 157 | 158 | /// Transition animation 159 | /// @access public 160 | /// @author Silvestar Bistrović 161 | /// @example transition-duration: $tra; 162 | /// @group 1.3.Transitions 163 | /// @name tra 164 | /// @since 1.0.0 165 | $tra: cubic-bezier(0.04, 0.88, 0.74, 1.04); 166 | 167 | /// PT Mono 168 | /// @access public 169 | /// @author Silvestar Bistrović 170 | /// @example font-family: $font-alpha; 171 | /// @group 1.4.Fonts 172 | /// @name font-alpha 173 | /// @since 1.0.0 174 | $font-alpha: 'PT Mono'; 175 | 176 | /// PT Mono Subset 177 | /// @access public 178 | /// @author Silvestar Bistrović 179 | /// @example font-family: $font-alpha-subset; 180 | /// @group 1.4.Fonts 181 | /// @name font-alpha-subset 182 | /// @since 1.0.0 183 | $font-alpha-subset: 'PT Mono Subset'; 184 | -------------------------------------------------------------------------------- /src/scss/components/elements/_btn.scss: -------------------------------------------------------------------------------- 1 | // Button 2 | // 3 | // Button component. 4 | // 5 | // Markup: 6 | // Button 7 | // 8 | // 9 | // .btn--alpha - Outline button 10 | // .btn--beta - Small button 11 | // .btn--gamma - Small button 12 | // 13 | // Weight: 500 14 | // 15 | // Styleguide: Button 16 | 17 | .btn { 18 | align-items: center; 19 | appearance: none; 20 | background-color: $color-primary--gamma; 21 | border: rem(2px) solid currentColor; 22 | // border-radius: rem(15px); 23 | color: $color-secondary--beta; 24 | cursor: pointer; 25 | display: inline-flex; 26 | font-size: ms(-1); 27 | justify-content: center; 28 | line-height: 1; 29 | min-height: rem(30px); 30 | padding-left: rem(21px); 31 | padding-right: rem(21px); 32 | text-decoration: none; 33 | 34 | &:hover, 35 | &:focus, 36 | &:active { 37 | background-color: $color-primary--beta; 38 | color: $color-secondary--beta; 39 | } 40 | } 41 | 42 | .btn--alpha { 43 | background-color: $color-secondary--alpha; 44 | border-color: $color-primary--beta; 45 | color: $color-primary--alpha; 46 | } 47 | 48 | .btn--beta { 49 | border-width: 1px; 50 | // border-radius: rem(12px); 51 | font-size: ms(-2); 52 | min-height: rem(24px); 53 | padding-left: rem(18px); 54 | padding-right: rem(18px); 55 | } 56 | 57 | .btn--gamma { 58 | border-width: 1px; 59 | // border-radius: rem(12px); 60 | font-size: ms(-1); 61 | min-height: rem(54px); 62 | padding-left: rem(24px); 63 | padding-right: rem(24px); 64 | } 65 | -------------------------------------------------------------------------------- /src/scss/components/elements/_cld.scss: -------------------------------------------------------------------------------- 1 | // Code Block 2 | // 3 | // Code Block is the main component. It contains line of code, author, date and other details. 4 | // 5 | // Markup: 6 | //
7 | // 20 | // 26 | //
27 | // 28 | // .cld--alpha - Small code block 29 | // 30 | // Weight: 600 31 | // 32 | // Styleguide: CodeBlock 33 | 34 | .cld { 35 | display: flex; 36 | flex-direction: column; 37 | margin-bottom: rem(10px); 38 | 39 | .btn { 40 | margin-left: rem(10px); 41 | 42 | &:first-of-type:not(:last-of-type) { 43 | @include mq($until: mobile) { 44 | margin-left: 0; 45 | } 46 | } 47 | } 48 | } 49 | 50 | .cld__inner, 51 | .cld__content { 52 | align-items: stretch; 53 | display: flex; 54 | flex-direction: column; 55 | } 56 | 57 | .cld__content { 58 | background-color: $color-primary--gamma; 59 | border: rem(2px) solid $color-primary--beta; 60 | // border-radius: rem(15px); 61 | color: $color-secondary--beta; 62 | } 63 | 64 | .cld__inner { 65 | text-decoration: none; 66 | } 67 | 68 | .cld__code, 69 | .cld__details { 70 | padding-left: rem(20px); 71 | padding-right: rem(20px); 72 | 73 | @include mq($until: mobile) { 74 | padding-left: rem(7.5px); 75 | padding-right: rem(7.5px); 76 | } 77 | } 78 | 79 | .cld__details { 80 | align-items: center; 81 | display: flex; 82 | flex-wrap: wrap; 83 | justify-content: space-between; 84 | min-height: rem(50px); 85 | padding-bottom: rem(10px); 86 | padding-top: rem(10px); 87 | position: relative; 88 | } 89 | 90 | .cld__details, 91 | .cld__share { 92 | font-size: ms(-1); 93 | } 94 | 95 | .cld__details--alpha { 96 | @include tra; 97 | font-size: ms(0); 98 | 99 | .cld__inner:hover &, 100 | .cld__inner:focus &, 101 | .cld__inner:active & { 102 | color: $color-secondary--alpha; 103 | } 104 | } 105 | 106 | .cld__detail, 107 | .cld__share { 108 | align-items: baseline; 109 | display: inline-flex; 110 | } 111 | 112 | .cld__detail { 113 | &:only-child:before { 114 | content: '>'; 115 | margin-right: 0.5em; 116 | } 117 | 118 | &:last-of-type:not(:first-of-type), 119 | .cld__share & { 120 | @include mq($until: mobile) { 121 | flex: 1 1 100%; 122 | margin-top: rem(10px); 123 | width: 100%; 124 | } 125 | } 126 | } 127 | 128 | .cld__code { 129 | @include tra; 130 | align-items: center; 131 | background-color: $color-primary--alpha; 132 | border-bottom: rem(2px) solid $color-primary--beta; 133 | border-top: rem(2px) solid $color-primary--beta; 134 | color: $color-secondary--beta; 135 | display: flex; 136 | font-size: ms(1); 137 | padding-bottom: rem(30px); 138 | padding-top: rem(30px); 139 | 140 | .cld__inner:hover &, 141 | .cld__inner:focus &, 142 | .cld__inner:active & { 143 | background-color: $color-primary--beta; 144 | } 145 | } 146 | 147 | .cld__share { 148 | flex-wrap: wrap; 149 | 150 | .btn { 151 | margin-top: rem(10px); 152 | } 153 | } 154 | 155 | .cld__copy { 156 | bottom: calc(100% + #{rem(5px)}); 157 | position: absolute; 158 | right: rem(3px); 159 | width: calc(69px); 160 | z-index: 1; 161 | } 162 | 163 | .cld__input { 164 | height: 10px; 165 | position: absolute; 166 | width: 10px; 167 | z-index: -1; 168 | } 169 | 170 | .cld--alpha { 171 | .cld__content { 172 | border-width: 1px; 173 | } 174 | 175 | .cld__details { 176 | min-height: rem(33px); 177 | padding-bottom: rem(6px); 178 | padding-top: rem(6px); 179 | } 180 | 181 | .cld__details, 182 | .cld__share { 183 | font-size: ms(-2); 184 | } 185 | 186 | .cld__code { 187 | border-width: 1px; 188 | font-size: ms(0); 189 | padding-bottom: rem(30px); 190 | padding-top: rem(30px); 191 | } 192 | 193 | .btn { 194 | @extend .btn--beta; 195 | 196 | &.cld__copy { 197 | font-size: ms(-3); 198 | width: calc(57px); 199 | } 200 | } 201 | } 202 | 203 | .visually-hidden { 204 | clip: rect(1px 1px 1px 1px); 205 | clip: rect(1px, 1px, 1px, 1px); 206 | clip-path: inset(1px); 207 | display: block; 208 | height: 1px; 209 | overflow: hidden; 210 | position: absolute; 211 | white-space: nowrap; 212 | width: 1px; 213 | } 214 | -------------------------------------------------------------------------------- /src/scss/components/elements/_content.scss: -------------------------------------------------------------------------------- 1 | html { 2 | scroll-behavior: smooth; 3 | } 4 | 5 | body { 6 | background-color: $color-secondary--alpha; 7 | color: $color-primary--alpha; 8 | display: flex; 9 | flex-direction: column; 10 | min-height: 100vh; 11 | } 12 | 13 | .main { 14 | flex: 1 1 auto; 15 | } 16 | 17 | a { 18 | @include tra; 19 | color: inherit; 20 | text-decoration: none; 21 | 22 | &:not([class*="btn"]):visited { 23 | // color: $color-primary--beta; 24 | } 25 | 26 | &:hover, 27 | &:focus, 28 | &:active { 29 | color: $color-primary--beta; 30 | } 31 | } 32 | 33 | button { 34 | @include tra; 35 | } 36 | 37 | img { 38 | max-width: 100%; 39 | } 40 | 41 | hr { 42 | border-color: $color-primary--alpha; 43 | margin-bottom: rem(60px); 44 | margin-top: rem(60px); 45 | width: rem(100px); 46 | } 47 | 48 | article { 49 | h2:before { 50 | content: '> '; 51 | } 52 | 53 | h1:first-child { 54 | text-align: center; 55 | } 56 | 57 | h2 { 58 | text-transform: uppercase; 59 | } 60 | 61 | a { 62 | box-shadow: 0 1px 0 currentColor; 63 | } 64 | } 65 | 66 | .main + .hf { 67 | margin-top: rem(90px); 68 | } 69 | 70 | .grid { 71 | display: grid; 72 | grid-gap: rem(30px); 73 | 74 | @include mq($from: desktop) { 75 | grid-gap: rem(60px); 76 | grid-template-columns: 1fr 1fr; 77 | } 78 | 79 | .cld { 80 | @include mq($from: desktop) { 81 | &:nth-child(-n+2) { 82 | margin-top: 0; 83 | } 84 | } 85 | 86 | &:first-child { 87 | margin-top: 0; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/scss/components/elements/_form.scss: -------------------------------------------------------------------------------- 1 | .form-wrapper { 2 | border: 1px solid currentColor; 3 | padding: rem(9px) rem(30px) rem(39px); 4 | } 5 | 6 | .form { 7 | font-size: ms(-1); 8 | 9 | label { 10 | display: block; 11 | margin-bottom: rem(15px); 12 | } 13 | 14 | input[type="email"] { 15 | background-color: $color-secondary--beta; 16 | border: 1px double $color-primary--alpha; 17 | color: $color-primary--alpha; 18 | margin-bottom: rem(15px); 19 | min-height: rem(51px); 20 | min-width: 100%; 21 | padding-left: rem(9px); 22 | padding-right: rem(9px); 23 | } 24 | 25 | input[type="submit"] { 26 | line-height: 1.2; 27 | } 28 | } 29 | 30 | .form__group { 31 | &:not(:last-child) { 32 | margin-bottom: rem(15px); 33 | } 34 | } 35 | 36 | .form__radio, 37 | .form__element { 38 | display: flex; 39 | } 40 | 41 | .form__radio { 42 | margin-top: rem(15px); 43 | } 44 | 45 | .form__element { 46 | align-items: center; 47 | 48 | & + & { 49 | margin-left: rem(30px); 50 | } 51 | 52 | input { 53 | background-color: red; 54 | margin-bottom: rem(18px); 55 | } 56 | 57 | label { 58 | margin-left: rem(15px); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/scss/components/elements/_global.scss: -------------------------------------------------------------------------------- 1 | // Wrappers 2 | // 3 | // Wrappers are used to limit the content to certain width. 4 | // 5 | // Markup: 6 | //
7 | //

This is a wrapper.

8 | //
9 | // 10 | // .w--alpha - Maximum width: 1440px 11 | // .w--beta - Maximum width: 900px 12 | // 13 | // Weight: 300 14 | // 15 | // Styleguide: Wrappers 16 | * { 17 | box-sizing: border-box; 18 | } 19 | 20 | .w { 21 | margin-left: auto; 22 | margin-right: auto; 23 | padding-left: rem(30px); 24 | padding-right: rem(30px); 25 | 26 | @include mq($until: mobile) { 27 | padding-left: rem(10px); 28 | padding-right: rem(10px); 29 | } 30 | } 31 | 32 | .w--alpha { 33 | max-width: rem(1440px); 34 | width: 100%; 35 | } 36 | 37 | .w--beta { 38 | max-width: rem(960px); 39 | width: 100%; 40 | } 41 | 42 | .w--omega { 43 | align-items: center; 44 | display: flex; 45 | justify-content: space-between; 46 | } 47 | 48 | // Spacing Margin 49 | // 50 | // Spacing are used for whitespace. 51 | // 52 | // Markup: 53 | //
54 | //

This is whitespace for margin top.

55 | //
56 | // 57 | // .pt--alpha - Big margin top 58 | // .mt--beta - Small margin top 59 | // 60 | // Weight: 310 61 | // 62 | // Styleguide: SpacingMargin 63 | .mt--alpha { 64 | margin-top: rem(90px); 65 | 66 | @include mq($until: mobile) { 67 | margin-top: rem(45px); 68 | } 69 | } 70 | 71 | .mt--beta { 72 | margin-top: rem(30px); 73 | 74 | @include mq($until: mobile) { 75 | margin-top: rem(15px); 76 | } 77 | } 78 | 79 | // Spacing Padding 80 | // 81 | // Spacing are used for whitespace. 82 | // 83 | // Markup: 84 | //
85 | //

This is whitespace for padding top.

86 | //
87 | // 88 | // .pt--alpha - Big padding top 89 | // .pt--beta - Small padding top 90 | // 91 | // Weight: 320 92 | // 93 | // Styleguide: Spacing 94 | .pt--alpha { 95 | padding-top: rem(90px); 96 | 97 | @include mq($until: mobile) { 98 | padding-top: rem(45px); 99 | } 100 | } 101 | 102 | .pt--beta { 103 | padding-top: rem(30px); 104 | 105 | @include mq($until: mobile) { 106 | padding-top: rem(15px); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/scss/components/elements/_hf.scss: -------------------------------------------------------------------------------- 1 | // Header 2 | // 3 | // Header is displayed at the top of the page and it consists 4 | // of logo, title and menu. 5 | // 6 | // Markup: 7 | //
8 | //
9 | // Skip to main content 10 | // 16 | // 32 | //
33 | //
34 | // 35 | // Weight: 400 36 | // 37 | // Styleguide: Header 38 | 39 | // Footer 40 | // 41 | // Footer is displayed at the end of the page and it consists 42 | // of logo, title and menu. 43 | // 44 | // Markup: 45 | //
46 | //
47 | // Skip to main content 48 | // 54 | // 67 | //
68 | //
69 | // 70 | // Weight: 410 71 | // 72 | // Styleguide: Footer 73 | 74 | .hf { 75 | background-color: $color-secondary--beta; 76 | padding: rem(15px); 77 | 78 | a[href*="/"] { 79 | text-decoration: none; 80 | 81 | &.active { 82 | position: relative; 83 | 84 | &:after { 85 | content: '<'; 86 | position: absolute; 87 | right: rem(-15px); 88 | } 89 | } 90 | } 91 | 92 | ul { 93 | list-style: none; 94 | } 95 | } 96 | 97 | .hf__inner { 98 | align-items: center; 99 | display: flex; 100 | justify-content: space-between; 101 | position: relative; 102 | } 103 | 104 | .hf__skip { 105 | align-items: center; 106 | clip: rect(1px 1px 1px 1px); 107 | clip-path: inset(1px); 108 | display: flex; 109 | height: 1px; 110 | justify-content: center; 111 | overflow: hidden; 112 | position: absolute; 113 | transition: none; 114 | white-space: nowrap; 115 | width: 1px; 116 | 117 | &:focus { 118 | background-color: $color-primary--alpha; 119 | clip: auto; 120 | color: $color-secondary--alpha; 121 | height: 100%; 122 | width: auto; 123 | } 124 | } 125 | 126 | .hf__logo { 127 | align-items: center; 128 | display: flex; 129 | text-decoration: none; 130 | } 131 | 132 | .hf__img { 133 | img { 134 | display: block; 135 | } 136 | } 137 | 138 | .hf__src { 139 | display: block; 140 | height: rem(90px); 141 | width: rem(90px); 142 | 143 | @include mq($until: mobile) { 144 | height: rem(60px); 145 | width: rem(60px); 146 | } 147 | } 148 | 149 | .hf__cld { 150 | margin-left: rem(15px); 151 | width: rem(90px); 152 | 153 | @include mq($until: mobile) { 154 | font-size: ms(-1); 155 | margin-left: rem(10px); 156 | width: rem(60px); 157 | } 158 | } 159 | 160 | .hf__list { 161 | align-items: flex-end; 162 | display: flex; 163 | flex-direction: column; 164 | margin: 0; 165 | } 166 | 167 | .hf__link { 168 | // color: inherit; 169 | display: flex; 170 | font-size: ms(-1); 171 | } 172 | -------------------------------------------------------------------------------- /src/scss/components/elements/_message.scss: -------------------------------------------------------------------------------- 1 | .message { 2 | align-items: center; 3 | animation: jump cubic-bezier(0.46, 1.51, 0.66, 0.92) 0.3s forwards; 4 | background-color: $color-primary--gamma; 5 | border: 1px dotted $color-secondary--beta; 6 | bottom: rem(10); 7 | display: flex; 8 | justify-content: space-between; 9 | left: rem(10); 10 | margin-left: auto; 11 | margin-right: auto; 12 | max-width: rem(600); 13 | padding: rem(5) rem(10); 14 | position: fixed; 15 | right: rem(10); 16 | transform: translateY(200%); 17 | z-index: 1; 18 | 19 | p { 20 | color: $color-secondary--alpha; 21 | font-size: ms(-2); 22 | margin: 0; 23 | } 24 | 25 | .btn { 26 | font-size: ms(-1); 27 | } 28 | } 29 | 30 | @keyframes jump { 31 | 0% { 32 | transform: translateY(200%); 33 | } 34 | 35 | 100% { 36 | transform: none; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/scss/components/elements/_sig.scss: -------------------------------------------------------------------------------- 1 | // Ribbon 2 | // 3 | // Ribbon is displayed at the bottom of the page. 4 | // The main function of this element is to display 5 | // "Powered by Starter Project" text. Help others by 6 | // sharing this package. 7 | // https://starter.silvestar.codes 8 | // 9 | // Markup: 10 | //
11 | //

Powered by Starter Project.

12 | //
13 | // 14 | // Weight: 900 15 | // 16 | // Styleguide: Ribbon 17 | $color-sp1: #d91a79; 18 | $color-sp2: #ba1ada; 19 | 20 | .sig { 21 | align-items: baseline; 22 | background-image: linear-gradient(to right, transparentize($color-sp1, 0.85), transparentize($color-sp2, 0.85)); 23 | color: $color-sp1; 24 | display: flex; 25 | justify-content: center; 26 | line-height: 1; 27 | padding: rem(1px) rem(10px) rem(6px); 28 | 29 | p { 30 | font-size: ms(-1); 31 | margin: 0; 32 | transform: skewX(-1deg); 33 | } 34 | } 35 | 36 | .sig__link { 37 | align-items: baseline; 38 | display: inline-flex; 39 | text-decoration: none; 40 | transition: all $trd $tra; 41 | 42 | &:visited { 43 | color: $color-sp2; 44 | } 45 | } 46 | 47 | .sig__icon { 48 | height: rem(20px); 49 | margin-right: rem(2px); 50 | transform: translateY(rem(4px)); 51 | transform-origin: center; 52 | transition: all $trd $tra forwards; 53 | width: rem(20px); 54 | } 55 | -------------------------------------------------------------------------------- /src/scss/foft.scss: -------------------------------------------------------------------------------- 1 | // Plugins 2 | @import 'modularscale'; 3 | 4 | // Configuration 5 | @import 'modularscale'; 6 | @import 'variables'; 7 | @import 'font-face'; 8 | @import 'fonts'; 9 | -------------------------------------------------------------------------------- /src/scss/homepage.md: -------------------------------------------------------------------------------- 1 | # [Code Line Daily] 2 | 3 | ![Code Line Daily Logo](https://raw.githubusercontent.com/maliMirkec/code-line-daily/master/src/gfx/png/cld.png) 4 | 5 | A line of code of the day. 6 | 7 | [Code Line Daily]: https://github.com/maliMirkec/code-line-daily 8 | -------------------------------------------------------------------------------- /src/scss/kss.scss: -------------------------------------------------------------------------------- 1 | // Plugins 2 | // @import 'normalize'; 3 | @import 'modularscale'; 4 | @import 'mq'; 5 | 6 | // Configuration 7 | @import 'variables'; 8 | @import 'locks'; 9 | @import 'helpers'; 10 | 11 | [class*='kss-modifier__wrapper'] { 12 | background-color: $color-secondary--alpha; 13 | color: $color-primary--alpha; 14 | 15 | .kss-style { 16 | color: inherit; 17 | } 18 | } 19 | 20 | [id*='wrappers'] { 21 | .w { 22 | box-shadow: 0 0 0 1px $color-primary--alpha inset; 23 | margin-bottom: rem(15px); 24 | margin-top: rem(15px); 25 | } 26 | } 27 | 28 | [id*='spacing'] { 29 | .mt, 30 | .pt { 31 | box-shadow: 0 0 0 1px $color-primary--alpha inset; 32 | padding-left: rem(15px); 33 | padding-right: rem(15px); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/scss/style.critical.scss: -------------------------------------------------------------------------------- 1 | // leave this empty 2 | // will be overriden by penthouse gulp task 3 | // if you need multiple critical stylesheets, add new file style2.critical.scss 4 | -------------------------------------------------------------------------------- /src/scss/style.scss: -------------------------------------------------------------------------------- 1 | // Plugins 2 | @import 'normalize'; 3 | @import 'modularscale'; 4 | @import 'mq'; 5 | 6 | // Configuration 7 | @import 'helpers'; 8 | @import 'variables'; 9 | @import 'locks'; 10 | @import 'typography'; 11 | @import 'colors'; 12 | @import 'theme'; 13 | -------------------------------------------------------------------------------- /src/sw/sw.js: -------------------------------------------------------------------------------- 1 | // load workbox 2 | importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js'); 3 | 4 | // output successful message 5 | if (workbox) { 6 | console.log('Yay! Workbox is loaded 🎉'); 7 | } else { 8 | console.log('Boo! Workbox didn\'t load 😬'); 9 | } 10 | 11 | // workbox.setConfig({ debug: true }) 12 | 13 | workbox.core.setCacheNameDetails({ 14 | prefix: 'cld', 15 | suffix: 'v1.9', 16 | precache: 'precache', 17 | runtime: 'runtime', 18 | }); 19 | 20 | workbox.core.skipWaiting(); 21 | 22 | workbox.core.clientsClaim(); 23 | 24 | workbox.precaching.cleanupOutdatedCaches(); 25 | 26 | workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); 27 | 28 | // Serve all html files with StaleWhileRevalidate strategy 29 | workbox.routing.registerRoute( 30 | /\.html$/, 31 | new workbox.strategies.StaleWhileRevalidate({ 32 | cacheName: 'cld-html-cache', 33 | plugins: [ 34 | new workbox.expiration.ExpirationPlugin({ 35 | maxEntries: 10, 36 | maxAgeSeconds: 60 * 60, 37 | }), 38 | new workbox.broadcastUpdate.BroadcastUpdatePlugin({ 39 | channelName: 'html-updates', 40 | }), 41 | ], 42 | }), 43 | ); 44 | 45 | // Serve all css files with StaleWhileRevalidate strategy 46 | workbox.routing.registerRoute( 47 | /\.js$/, 48 | new workbox.strategies.StaleWhileRevalidate({ 49 | cacheName: 'cld-js-cache', 50 | plugins: [ 51 | new workbox.expiration.ExpirationPlugin({ 52 | maxEntries: 10, 53 | maxAgeSeconds: 24 * 60 * 60, 54 | }), 55 | new workbox.broadcastUpdate.BroadcastUpdatePlugin({ 56 | channelName: 'js-updates', 57 | }), 58 | ], 59 | }), 60 | ); 61 | 62 | // Serve all css files with StaleWhileRevalidate strategy 63 | workbox.routing.registerRoute( 64 | /\.css$/, 65 | new workbox.strategies.StaleWhileRevalidate({ 66 | cacheName: 'cld-css-cache', 67 | plugins: [ 68 | new workbox.expiration.ExpirationPlugin({ 69 | maxEntries: 10, 70 | maxAgeSeconds: 24 * 60 * 60, 71 | }), 72 | new workbox.broadcastUpdate.BroadcastUpdatePlugin({ 73 | channelName: 'css-updates', 74 | }), 75 | ], 76 | }), 77 | ); 78 | 79 | // Serve all other assets with CacheFirst strategy 80 | workbox.routing.registerRoute( 81 | /\.(?:png|jpg|jpeg|svg|gif|webp|ico|webmanifest|eot,ttf,woff,woff2)$/, 82 | new workbox.strategies.CacheFirst({ 83 | cacheName: 'cld-asset-cache', 84 | plugins: [ 85 | new workbox.expiration.ExpirationPlugin({ 86 | maxEntries: 10, 87 | maxAgeSeconds: 30 * 24 * 60 * 60, 88 | }), 89 | ], 90 | }), 91 | ); 92 | -------------------------------------------------------------------------------- /src/xml/_layout/rss.pug: -------------------------------------------------------------------------------- 1 | include /_mixins/variables.pug 2 | 3 | doctype xml 4 | rss(version="2.0", xmlns:content="http://purl.org/rss/1.0/modules/content/", xmlns:atom='http://www.w3.org/2005/Atom') 5 | channel 6 | title= siteName 7 | div= siteURL 8 | atom:link(href="https://cld.silvestar.codes/rss.xml", rel="self", type="application/rss+xml") 9 | description= siteDesc 10 | - var pDate = new Date('2019-08-01'); 11 | pubDate= pDate.toUTCString() 12 | - var bDate = new Date(); 13 | lastBuildDate= bDate.toUTCString() 14 | generator= siteName + " Feed generator" 15 | 16 | block content 17 | -------------------------------------------------------------------------------- /src/xml/_mixins/variables.pug: -------------------------------------------------------------------------------- 1 | block variables 2 | - var siteName = locals.site.siteName ? locals.site.siteName : 'Code Line Daily'; 3 | - var siteDesc = locals.site.siteDesc ? locals.site.siteDesc : 'A line of code of the day.'; 4 | - var siteURL = locals.site.siteURL ? locals.site.siteURL : '/'; 5 | - var siteImg = locals.site.siteImg ? locals.site.siteImg : '/'; 6 | - var og = locals.site.og ? locals.site.og : '/'; 7 | - var menu = locals.site.menu ? locals.site.menu : []; 8 | - var menu2 = locals.site.menu2 ? locals.site.menu2 : []; 9 | - var list = locals.data.list ? locals.data.list.filter(item => new Date(item.date) < new Date()) : []; 10 | - var thisItem = list.slice(-1).pop() 11 | - var listArchive = list.slice().reverse(); 12 | - var listEvergreen = list.slice().filter(item => item.evergreen); 13 | 14 | - function formatNumber(num) 15 | - return num < 10 ? '0' + num : num; 16 | 17 | - function formatDate(date) 18 | - var d = new Date(date); 19 | - return d.getFullYear() + '-' + formatNumber(d.getMonth() + 1) + '-' + formatNumber(d.getDate()); 20 | -------------------------------------------------------------------------------- /src/xml/rss.pug: -------------------------------------------------------------------------------- 1 | extends /_layout/rss.pug 2 | 3 | block variables 4 | 5 | block content 6 | - var checkLinks = []; 7 | each listValue, listIndex in listArchive 8 | item 9 | title 10 | div= "https://cld.silvestar.codes/archive/" 11 | - var link = listValue.link; 12 | if checkLinks.indexOf(link) === -1 13 | - checkLinks.push(listValue.link) 14 | else 15 | - link += '#' + Math.random(); 16 | guid= "https://cld.silvestar.codes/archive/?url=" + link 17 | description 18 | enclosure(url="https://cld.silvestar.codes/gfx/cover/" + listValue.date + ".png" length="12345" type="image/png") 19 | if (listValue.email) 20 | author= listValue.email + " (" + listValue.author + ")" 21 | category= listValue.language 22 | - var uDate = new Date(listValue.date); 23 | pubDate= uDate.toUTCString() 24 | --------------------------------------------------------------------------------