Merge pull request #1464 from rstacruz/feature-parcel

This commit is contained in:
Rico Sta. Cruz 2020-06-22 20:44:30 +10:00 committed by GitHub
commit 048697b3d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 6712 additions and 5602 deletions

View File

@ -1,9 +1,10 @@
{ {
"presets": [ "presets": [
[ [
"env", "@babel/preset-env",
{ {
"forceAllTransforms": true "useBuiltIns": "entry",
"targets": "> 2%"
} }
] ]
] ]

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
yarn.lock binary

4
.gitignore vendored
View File

@ -4,3 +4,7 @@ _site
/node_modules /node_modules
/vendor /vendor
.idea/ .idea/
# Generated by 'yarn dev'
/_includes/2017/critical/critical-home.js
/_includes/2017/critical/critical-sheet.js

View File

@ -1,5 +1,6 @@
{ {
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"jsxSingleQuote": true "jsxSingleQuote": true,
"trailingComma": "none"
} }

View File

@ -1,10 +1,25 @@
language: ruby language: ruby
rvm: rvm: [2.7.1]
- 2.5
before_install:
- nvm install 12
- nvm use 12
- node --version
- ruby --version
install:
- yarn --frozen-lockfile
- bundle --jobs=3 --retry=3 --deployment --path=${BUNDLE_PATH:-vendor/bundle}
script: script:
- make -B _site - yarn build
- yarn test
- if ! make test; then make test-warning; exit 16; fi - if ! make test; then make test-warning; exit 16; fi
cache: bundler
cache:
bundler: true
yarn: true
notifications: notifications:
slack: slack:
if: branch = master OR branch =~ ^.*slack.*$ if: branch = master OR branch =~ ^.*slack.*$

View File

@ -1,6 +1,7 @@
# Developer notes # Developer notes
## Gitpod ## Gitpod
This repository supports contribution using [gitpod](https://gitpod.io) which is online IDE using [Theia](https://github.com/eclipse-theia/theia). This repository supports contribution using [gitpod](https://gitpod.io) which is online IDE using [Theia](https://github.com/eclipse-theia/theia).
To open-up the environment simple natigate on https://gitpod.io/#https://github.com/rstacruz/cheatsheets To open-up the environment simple natigate on https://gitpod.io/#https://github.com/rstacruz/cheatsheets
@ -9,14 +10,14 @@ Or using a button:<br>
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rstacruz/cheatsheets) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rstacruz/cheatsheets)
### Preview built website ### Preview built website
To preview the website you need to first build it then you can navigate to file that you are trying to contribute and preview directly. To preview the website you need to first build it then you can navigate to file that you are trying to contribute and preview directly.
<img src='_docs/images/gitpod_preview_tut.png' width=828 height=459/> <img src='_docs/images/gitpod_preview_tut.png' width=828 height=459/>
## Starting a local instance ## Starting a local instance
This starts Jekyll and Webpack. This requires recent versions of [Node.js], [Yarn], [Ruby] and [Bundler] installed. This starts Jekyll and Parcel. This requires recent versions of [Node.js], [Yarn], [Ruby] and [Bundler] installed.
```bash ```bash
yarn install yarn install
@ -56,9 +57,11 @@ See <https://devhints.io/cheatsheet-styles> for a reference on styling.
## JavaScript ## JavaScript
When updating JavaScript, be sure webpack is running (`yarn run dev` takes care of this). When updating JavaScript, be sure Parcel is running (`yarn dev` takes care of this).
This auto-updates `/assets/packed/` with sources in `_js/`. This auto-updates `/assets/packed/` and `_includes/2017/critical/` with sources in `_parcel/`.
Before committing, run `yarn parcel:build` first.
## JavaScript tests ## JavaScript tests
@ -96,6 +99,7 @@ tags:
type: home # home | article | error type: home # home | article | error
og_type: website # opengraph type og_type: website # opengraph type
--- ---
``` ```
## Prism languages ## Prism languages
@ -115,6 +119,7 @@ title: ES2015
category: Hidden category: Hidden
redirect_to: /es6 redirect_to: /es6
--- ---
``` ```
## Localizations ## Localizations
@ -170,26 +175,3 @@ building web user interfaces...
### intro only ### intro only
If you left out `description` or `keywords`, a default description will be added. If you left out `description` or `keywords`, a default description will be added.
## Critical path CSS
The critical path CSS is stored in:
- `_includes/2017/critical/home.html`
- `_includes/2017/critical/sheet.html`
You'll need to update these every now and then when you change something in the CSS. Use this to update these snippets:
```
yarn run critical
```
You can temporarily disable critical path optimizations by loading it with `?nocrit=1`, eg, `https://devhints.io/?nocrit=1`.
## Critical path JS
There's JavaScript that's included inline in every page. It's entrypoint is:
- `_js/critical.js`
This is automatically compiled into the partial `_includes/2017/critical/critical.js`. Keep this bundle as small as possible.

View File

@ -1,5 +1,5 @@
FROM ruby:2.5.1 FROM ruby:2.7.1
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -qq --no-install-recommends \ RUN apt-get update -qq && apt-get install -qq --no-install-recommends \

View File

@ -9,43 +9,14 @@ help:
@echo @echo
# Builds intermediate files. Needs a _site built first though # Builds intermediate files. Needs a _site built first though
update: _site critical update: _site
# Builds _site # Builds _site
_site: _site:
bundle exec jekyll build --incremental yarn build
critical: _site ## Builds critical path CSS/JS dev:
node _support/critical.js yarn dev
# Ensure that bins are available.
ensure-bin:
@if [ ! -d $(npmbin) ]; then \
echo "---"; \
echo "Error: $(npmbin) not found, you may need to run '[docker-compose run --rm web] yarn install'."; \
echo "---"; \
exit 1; \
fi
@if ! which jekyll &>/dev/null; then \
echo "---"; \
echo "Warning: Jekyll not found, you may need to run '[docker-compose run --rm web] bundle install'."; \
echo "---"; \
fi
dev: ensure-bin ## Starts development server
$(npmbin)/concurrently -k -p command -c "blue,green" \
"make dev-webpack" \
"make dev-jekyll"
dev-webpack: ensure-bin
$(npmbin)/webpack --watch --colors -p
dev-jekyll: ensure-bin
if [ -f _site ]; then \
bundle exec jekyll serve --safe --trace --drafts --watch --incremental --host $(HOST) --port $(PORT); \
else \
bundle exec jekyll serve --safe --trace --drafts --watch --host $(HOST) --port $(PORT); \
fi
test: _site ## Runs rudimentary tests test: _site ## Runs rudimentary tests
@test -f _site/vim.html @test -f _site/vim.html

View File

@ -9,21 +9,23 @@ plugins:
- jekyll-github-metadata - jekyll-github-metadata
exclude: exclude:
- Makefile - .babelrc
- README.md - .cache
- CNAME
- CONTRIBUTING.md - CONTRIBUTING.md
- docker_compose.yml
- Dockerfile
- Gemfile - Gemfile
- Gemfile.lock - Gemfile.lock
- CNAME - Makefile
- vendor
- package.json
- .babelrc
- yarn.lock
- package-lock.json
- webpack.config.js
- node_modules - node_modules
- Dockerfile - package.json
- docker_compose.yml - package-lock.json
- README.md
- vendor
- webpack.config.js
- yarn-error.log
- yarn.lock
# Markdown # Markdown

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1,15 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=2)}([function(e,n){function t(e,n){var t=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;if(t)return t.call(e,n);if(e.parentNode){for(var r=e.parentNode.querySelectorAll(n),o=r.length;o--;0)if(r[o]===e)return!0;return!1}}e.exports=t},function(e,n,t){function r(e,n){if(n){if(Array.isArray(n))return void o(n,function(n){r(e,n)});if(e.classList){var t=n.split(" ").filter(Boolean);o(t,function(n){e.classList.add(n)})}else e.className+=" "+n}}var o=t(4);e.exports=r},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){d||((0,c.default)(document.documentElement,"LoadDone"),d=!0)}var i=t(3),u=r(i),a=t(1),c=r(a),f=t(6),l=r(f),s=document.querySelector("[data-js-main-body]");s&&((0,u.default)(s),(0,c.default)(s,"-wrapified")),(0,l.default)(window,"load",o),setTimeout(o,5e3);var d=void 0},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}function i(e){u(e).forEach(function(e){(0,p.findChildren)(e,"[data-js-h3-section-list]").forEach(function(e){a(e)})})}function u(e){return c(e,{tag:"h2",wrapperFn:function(){return(0,p.createDiv)({class:"h2-section"})},bodyFn:function(){return(0,p.createDiv)({class:"body h3-section-list","data-js-h3-section-list":""})}})}function a(e){return c(e,{tag:"h3",wrapperFn:function(){return(0,p.createDiv)({class:"h3-section"})},bodyFn:function(){return(0,p.createDiv)({class:"body"})}})}function c(e,n){function t(e,n,t){var r=i(),o=e.className;o&&(0,d.default)(r,o),(0,p.before)(e,r);var a=u();return o&&(0,d.default)(a,o),(0,p.appendMany)(a,t),n&&r.appendChild(n),r.appendChild(a),r}var r=n.tag,i=n.wrapperFn,u=n.bodyFn,a=e.children[0],c=[];if(a&&!(0,l.default)(a,r)){var f=(0,p.nextUntil)(a,r);c.push(t(a,null,[a].concat(o(f))))}return(0,p.findChildren)(e,r).forEach(function(e){var n=(0,p.nextUntil)(e,r);c.push(t(e,e,n))}),c}Object.defineProperty(n,"__esModule",{value:!0}),n.default=i,n.groupify=c;var f=t(0),l=r(f),s=t(1),d=r(s),p=t(5)},function(e,n){function t(e,n){var t,r,o=e.length;if("number"==typeof o)for(t=0;t<o;t++)n(e[t],t);else{r=0;for(t in e)e.hasOwnProperty(t)&&n(e[t],t,r++)}return e}e.exports=t},function(e,n,t){"use strict";function r(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}function o(e,n){n.forEach(function(n){e.appendChild(n)})}function i(e,n){return u(e.nextSibling,n,[])}function u(e,n,t){return e?(0,s.default)(e,n)?t:u(e.nextSibling,n,[].concat(r(t),[e])):t}function a(e,n){e.parentNode.insertBefore(n,e)}function c(e,n){return[].slice.call(e.children).filter(function(e){return(0,s.default)(e,n)})}function f(e){var n=document.createElement("div");return Object.keys(e).forEach(function(t){n.setAttribute(t,e[t])}),n}Object.defineProperty(n,"__esModule",{value:!0}),n.appendMany=o,n.nextUntil=i,n.before=a,n.findChildren=c,n.createDiv=f;var l=t(0),s=function(e){return e&&e.__esModule?e:{default:e}}(l)},function(e,n){function t(e,n,t){e.addEventListener?e.addEventListener(n,t):e.attachEvent("on"+n,function(){t.call(e)})}e.exports=t}]); parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"r6WJ":[function(require,module,exports) {
function e(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;if(r)return r.call(e,t);if(e.parentNode){for(var c=e.parentNode.querySelectorAll(t),o=c.length;o--;0)if(c[o]===e)return!0;return!1}}module.exports=e;
},{}],"cDuO":[function(require,module,exports) {
function e(e,r){var n,o,t=e.length;if("number"==typeof t)for(n=0;n<t;n++)r(e[n],n);else for(n in o=0,e)e.hasOwnProperty(n)&&r(e[n],n,o++);return e}module.exports=e;
},{}],"G20n":[function(require,module,exports) {
var s=require("./each");function e(i,a){if(a)if(Array.isArray(a))s(a,function(s){e(i,s)});else if(i.classList){var r=a.split(" ").filter(Boolean);s(r,function(s){i.classList.add(s)})}else i.className+=" "+a}module.exports=e;
},{"./each":"cDuO"}],"THIL":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.appendMany=c,exports.nextUntil=f,exports.before=s,exports.findChildren=d,exports.createDiv=p;var t=e(require("dom101/matches"));function e(t){return t&&t.__esModule?t:{default:t}}function r(t){return u(t)||i(t)||o(t)||n()}function n(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(t,e){if(t){if("string"==typeof t)return a(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(t,e):void 0}}function i(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}function u(t){if(Array.isArray(t))return a(t)}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}function c(t,e){e.forEach(function(e){t.appendChild(e)})}function f(t,e){return l(t.nextSibling,e,[])}function l(e,n,o){return e?(0,t.default)(e,n)?o:l(e.nextSibling,n,[].concat(r(o),[e])):o}function s(t,e){t.parentNode.insertBefore(e,t)}function d(e,r){return[].slice.call(e.children).filter(function(e){return(0,t.default)(e,r)})}function p(t){var e=document.createElement("div");return Object.keys(t).forEach(function(r){e.setAttribute(r,t[r])}),e}
},{"dom101/matches":"r6WJ"}],"hE9p":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=f,exports.groupify=p;var r=e(require("dom101/matches")),t=e(require("dom101/add-class")),n=require("../helpers/dom");function e(r){return r&&r.__esModule?r:{default:r}}function o(r){return c(r)||u(r)||i(r)||a()}function a(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function i(r,t){if(r){if("string"==typeof r)return s(r,t);var n=Object.prototype.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(r,t):void 0}}function u(r){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(r))return Array.from(r)}function c(r){if(Array.isArray(r))return s(r)}function s(r,t){(null==t||t>r.length)&&(t=r.length);for(var n=0,e=new Array(t);n<t;n++)e[n]=r[n];return e}function f(r){l(r).forEach(function(r){(0,n.findChildren)(r,"[data-js-h3-section-list]").forEach(function(r){d(r)})})}function l(r){return p(r,{tag:"h2",wrapperFn:function(){return(0,n.createDiv)({class:"h2-section"})},bodyFn:function(){return(0,n.createDiv)({class:"body h3-section-list","data-js-h3-section-list":""})}})}function d(r){return p(r,{tag:"h3",wrapperFn:function(){return(0,n.createDiv)({class:"h3-section"})},bodyFn:function(){return(0,n.createDiv)({class:"body"})}})}function p(e,a){var i=a.tag,u=a.wrapperFn,c=a.bodyFn,s=e.children[0],f=[];if(s&&!(0,r.default)(s,i)){var l=(0,n.nextUntil)(s,i);f.push(d(s,null,[s].concat(o(l))))}return(0,n.findChildren)(e,i).forEach(function(r){var t=(0,n.nextUntil)(r,i);f.push(d(r,r,t))}),f;function d(r,e,o){var a=u(),i=r.className;i&&(0,t.default)(a,i),(0,n.before)(r,a);var s=c();return i&&(0,t.default)(s,i),(0,n.appendMany)(s,o),e&&a.appendChild(e),a.appendChild(s),a}}
},{"dom101/matches":"r6WJ","dom101/add-class":"G20n","../helpers/dom":"THIL"}],"DJ2P":[function(require,module,exports) {
function n(n,t,e){n.addEventListener?n.addEventListener(t,e):n.attachEvent("on"+t,function(){e.call(n)})}module.exports=n;
},{}],"eoMl":[function(require,module,exports) {
"use strict";var e=u(require("./wrapify")),d=u(require("dom101/add-class")),t=u(require("dom101/on"));function u(e){return e&&e.__esModule?e:{default:e}}var a,o=document.querySelector("[data-js-main-body]");function r(){a||((0,d.default)(document.documentElement,"LoadDone"),a=!0)}o&&((0,e.default)(o),(0,d.default)(o,"-wrapified")),(0,t.default)(window,"load",r),setTimeout(r,5e3);
},{"./wrapify":"hE9p","dom101/add-class":"G20n","dom101/on":"DJ2P"}]},{},["eoMl"], null)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,3 @@
<!-- critical js -->
<script>{% include 2017/critical/critical.js %}</script> <script>{% include 2017/critical/critical.js %}</script>
<script src='{{base}}/assets/packed/vendor.js?t={{ timestamp }}'></script>
<script src='{{base}}/assets/packed/app.js?t={{ timestamp }}'></script> <script src='{{base}}/assets/packed/app.js?t={{ timestamp }}'></script>
{% for lang in page.prism_languages %}<script src='https://cdn.jsdelivr.net/npm/prismjs@1.6.0/components/prism-{{lang}}.min.js'></script>{% endfor %} {% for lang in page.prism_languages %}<script src='https://cdn.jsdelivr.net/npm/prismjs@1.6.0/components/prism-{{lang}}.min.js'></script>{% endfor %}

View File

@ -3,11 +3,11 @@
<!-- critical css --> <!-- critical css -->
{% if include.critical == 'home' {% if include.critical == 'home'
%}<style id='critical-css'>{% include 2017/critical/home.css %}</style>{% %}<style id='critical-css'>{% include 2017/critical/critical-home.css %}</style>{%
endif endif
%}{% %}{%
if include.critical == 'sheet' if include.critical == 'sheet'
%}<style id='critical-css'>{% include 2017/critical/sheet.css %}</style>{% %}<style id='critical-css'>{% include 2017/critical/critical-sheet.css %}</style>{%
endif %} endif %}
<!-- allow disabling critical CSS optimization by passing ?nocrit=1 --> <!-- allow disabling critical CSS optimization by passing ?nocrit=1 -->

View File

@ -1,7 +0,0 @@
// 3rd party libs
window.Prism = require('prismjs')
// All the others
function requireAll (r) { r.keys().forEach(r) }
requireAll(require.context('./initializers/', true, /\.js$/))
requireAll(require.context('./behaviors/', true, /\.js$/))

View File

@ -1,21 +0,0 @@
/* eslint-env jest */
import qs from '../qs'
describe('qs()', () => {
test('basic', run({
input: '?preview=1',
output: { preview: '1' }
}))
test('two fragments', run({
input: '?a=1&b=2',
output: { a: '1', b: '2' }
}))
function run ({ input, output }) {
return function () {
const result = qs(input)
expect(result).toEqual(output)
}
}
})

View File

@ -1,63 +0,0 @@
/* eslint-env jest */
import wrapify from '../index'
import $ from 'jquery'
it('simple usage', run(`
<div>
<h2>simple usage<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
</div>
`, $div => {
expect($div.find('.h2-section .h3-section-list .h3-section').length).toEqual(2)
}))
it('h3 with class', run(`
<div>
<h3 class='-hello'>install</h3>
<p>(install)</p>
</div>
`, $div => {
expect($div.find('div.h3-section.-hello').length).toEqual(1)
expect($div.find('div.h3-section-list.-hello').length).toEqual(1)
}))
it('multiple h2s', run(`
<div>
<h2>multiple h2<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
<h2>getting started<h2>
<h3>first</h3>
<p>(first)</p>
<h3>second</h3>
<p>(second)</p>
</div>
`))
function run (input, fn) {
return function () {
const $div = $(input)
wrapify($div[0])
expect($div[0]).toMatchSnapshot()
if (fn) fn($div)
}
}
it('h2 + pre', run(`
<div>
<h2>heading</h2>
<pre class='language-markdown'>(code)</pre>
</div>
`))

32
_parcel/_base.scss Normal file
View File

@ -0,0 +1,32 @@
// Vendor and variables
@import 'sanitize.css/sanitize.css';
@import '../_sass/2017/variables.scss';
@import '../node_modules/modularscale-sass/stylesheets/_modularscale.scss';
@import '../_sass/vendor/ionicons-inline/ionicons.scss';
// Utilities
@import '../_sass/2017/utils/carbon-style.scss';
@import '../_sass/2017/utils/_font-size.scss';
@import '../_sass/2017/utils/gutter.scss';
@import '../_sass/2017/utils/heading-style.scss';
@import '../_sass/2017/utils/section-gutter.scss';
@import '../_sass/2017/utils/section-with-container.scss';
// Base
@import 'sanitize.css/sanitize.css';
@import '../_sass/2017/base/base.scss';
@import '../_sass/2017/base/fade.scss';
// Components
@import '../_sass/2017/components/attribute-peg.scss';
@import '../_sass/2017/components/announcements-item.scss';
@import '../_sass/2017/components/announcements-list.scss';
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/pages-list.scss';
@import '../_sass/2017/components/search-box.scss';
@import '../_sass/2017/components/site-header.scss';
@import '../_sass/2017/components/top-nav.scss';
@import '../_sass/2017/components/top-sheet.scss';

12
_parcel/_utils.scss Normal file
View File

@ -0,0 +1,12 @@
// Vendor
@import '../_sass/2017/variables.scss';
@import '../node_modules/modularscale-sass/stylesheets/_modularscale.scss';
@import '../_sass/vendor/ionicons-inline/ionicons.scss';
// Utilities
@import '../_sass/2017/utils/carbon-style.scss';
@import '../_sass/2017/utils/_font-size.scss';
@import '../_sass/2017/utils/gutter.scss';
@import '../_sass/2017/utils/heading-style.scss';
@import '../_sass/2017/utils/section-gutter.scss';
@import '../_sass/2017/utils/section-with-container.scss';

30
_parcel/app.js Normal file
View File

@ -0,0 +1,30 @@
// Prismjs
import 'prismjs'
import 'prismjs/plugins/line-highlight/prism-line-highlight.min.js'
import 'prismjs/components/prism-jsx.min.js'
import 'prismjs/components/prism-bash.min.js'
import 'prismjs/components/prism-scss.min.js'
import 'prismjs/components/prism-css.min.js'
import 'prismjs/components/prism-elixir.min.js'
import 'prismjs/components/prism-ruby.min.js'
// Initializers
import './initializers/prism'
import './initializers/onmount'
// Behaviors
import './behaviors/anchors'
import './behaviors/dismissable'
import './behaviors/dismiss'
import './behaviors/disqus'
import './behaviors/h3-section-list'
import './behaviors/main-body'
import './behaviors/no-preview'
import './behaviors/searchable-header'
import './behaviors/searchable-item'
import './behaviors/search-form'
import './behaviors/search-input'
// CSS
import 'prismjs/plugins/line-highlight/prism-line-highlight.css'
import 'hint.css/hint.min.css'

View File

@ -9,7 +9,7 @@ const DEFAULTS = {
// text of anchor // text of anchor
text: '#', text: '#',
// append before or after innerText? // append before or after innerText?
shouldAppend: false, shouldAppend: false
} }
/* /*
@ -19,7 +19,9 @@ const DEFAULTS = {
onmount('[data-js-anchors]', function () { onmount('[data-js-anchors]', function () {
const data = JSON.parse(this.getAttribute('data-js-anchors') || '{}') const data = JSON.parse(this.getAttribute('data-js-anchors') || '{}')
const rules = Array.isArray(data) const rules = Array.isArray(data)
? (data.length ? data : [DEFAULTS]) ? data.length
? data
: [DEFAULTS]
: [Object.assign({}, DEFAULTS, data)] : [Object.assign({}, DEFAULTS, data)]
for (const { rule, className, text, shouldAppend } of rules) { for (const { rule, className, text, shouldAppend } of rules) {

View File

@ -14,7 +14,7 @@ onmount('[data-js-dismiss]', function () {
const dismissable = getData(parent, 'js-dismissable') const dismissable = getData(parent, 'js-dismissable')
const id = (dismissable && dismissable.id) || '' const id = (dismissable && dismissable.id) || ''
on(this, 'click', e => { on(this, 'click', (e) => {
Dismiss.setDismissed(id) Dismiss.setDismissed(id)
e.preventDefault() e.preventDefault()
if (parent) remove(parent) if (parent) remove(parent)

View File

@ -1,6 +1,6 @@
/* eslint-disable no-new */ /* eslint-disable no-new */
import Isotope from 'isotope-layout/dist/isotope.pkgd.js' import Isotope from 'isotope-layout'
import onmount from 'onmount' import onmount from 'onmount'
import on from 'dom101/on' import on from 'dom101/on'
import qsa from 'dom101/query-selector-all' import qsa from 'dom101/query-selector-all'
@ -17,7 +17,7 @@ onmount('[data-js-h3-section-list]', function () {
const images = qsa('img', this) const images = qsa('img', this)
images.forEach(image => { images.forEach((image) => {
on(image, 'load', () => { on(image, 'load', () => {
iso.layout() iso.layout()
}) })

View File

@ -6,7 +6,7 @@ import on from 'dom101/on'
*/ */
onmount('[data-js-search-form]', function () { onmount('[data-js-search-form]', function () {
on(this, 'submit', e => { on(this, 'submit', (e) => {
e.preventDefault() e.preventDefault()
const link = document.querySelector('a[data-search-index]:visible') const link = document.querySelector('a[data-search-index]:visible')

View File

@ -17,6 +17,8 @@ onmount('[data-js-search-input]', function () {
const query = (qs(window.location.search) || {}).q const query = (qs(window.location.search) || {}).q
if (query && query.length) { if (query && query.length) {
this.value = query this.value = query
setTimeout(() => { Search.show(query) }) setTimeout(() => {
Search.show(query)
})
} }
}) })

View File

@ -10,11 +10,12 @@ import './searchable-item'
*/ */
onmount('[data-js-searchable-header]', function () { onmount('[data-js-searchable-header]', function () {
const els = nextUntil(this, '[data-js-searchable-header]') const els = nextUntil(this, '[data-js-searchable-header]').filter((el) =>
.filter(el => matches(el, '[data-search-index]')) matches(el, '[data-search-index]')
)
const keywords = els const keywords = els
.map(n => n.getAttribute('data-search-index')) .map((n) => n.getAttribute('data-search-index'))
.join(' ') .join(' ')
.split(' ') .split(' ')

View File

@ -0,0 +1,16 @@
@import './_utils.scss';
@import './_base.scss';
// Components
@import '../_sass/2017/components/attribute-peg.scss';
@import '../_sass/2017/components/announcements-item.scss';
@import '../_sass/2017/components/announcements-list.scss';
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/pages-list.scss';
@import '../_sass/2017/components/search-box.scss';
@import '../_sass/2017/components/site-header.scss';
@import '../_sass/2017/components/top-nav.scss';
@import '../_sass/2017/components/top-sheet.scss';

View File

@ -0,0 +1,21 @@
@import './_utils.scss';
@import './_base.scss';
// Markdown
@import '../_sass/2017/markdown/a-em.scss';
@import '../_sass/2017/markdown/code.scss';
@import '../_sass/2017/markdown/headings.scss';
@import '../_sass/2017/markdown/local-anchor.scss';
@import '../_sass/2017/markdown/p.scss';
@import '../_sass/2017/markdown/table.scss';
@import '../_sass/2017/markdown/ul.scss';
// Components
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/h3-section.scss';
@import '../_sass/2017/components/h3-section-list.scss';
@import '../_sass/2017/components/main-heading.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/top-nav.scss';

View File

@ -5,7 +5,9 @@ import matches from 'dom101/matches'
*/ */
export function appendMany(el, children) { export function appendMany(el, children) {
children.forEach(child => { el.appendChild(child) }) children.forEach((child) => {
el.appendChild(child)
})
} }
/* /*
@ -39,8 +41,7 @@ export function before (reference, newNode) {
*/ */
export function findChildren(el, selector) { export function findChildren(el, selector) {
return [].slice.call(el.children) return [].slice.call(el.children).filter((child) => matches(child, selector))
.filter(child => matches(child, selector))
} }
/** /**
@ -54,7 +55,7 @@ export function findChildren (el, selector) {
export function createDiv(props) { export function createDiv(props) {
const d = document.createElement('div') const d = document.createElement('div')
Object.keys(props).forEach(key => { Object.keys(props).forEach((key) => {
d.setAttribute(key, props[key]) d.setAttribute(key, props[key])
}) })
return d return d

View File

@ -30,7 +30,7 @@ export function permutateString (str) {
let words = [] let words = []
let inputs = splitwords(str) let inputs = splitwords(str)
inputs.forEach(word => { inputs.forEach((word) => {
words = words.concat(permutateWord(word)) words = words.concat(permutateWord(word))
}) })
@ -63,9 +63,10 @@ export function permutateWord (str) {
*/ */
export function splitwords(str) { export function splitwords(str) {
const words = str.toLowerCase() const words = str
.toLowerCase()
.split(/[ /\-_]/) .split(/[ /\-_]/)
.filter(k => k && k.length !== 0) .filter((k) => k && k.length !== 0)
return words return words
} }

View File

@ -4,7 +4,7 @@
export default function qs(search) { export default function qs(search) {
search = search.substr(1) search = search.substr(1)
const parts = search.split('&').map(p => p.split('=')) const parts = search.split('&').map((p) => p.split('='))
return parts.reduce((result, part) => { return parts.reduce((result, part) => {
result[part[0]] = qsdecode(part[1]) result[part[0]] = qsdecode(part[1])
return result return result

View File

@ -9,7 +9,7 @@ import qsa from 'dom101/query-selector-all'
*/ */
export function showAll() { export function showAll() {
qsa('[data-search-index]').forEach(el => { qsa('[data-search-index]').forEach((el) => {
el.removeAttribute('aria-hidden') el.removeAttribute('aria-hidden')
}) })
} }
@ -27,14 +27,14 @@ export function show (val) {
if (!keywords.length) return showAll() if (!keywords.length) return showAll()
const selectors = keywords const selectors = keywords
.map(k => `[data-search-index~=${JSON.stringify(k)}]`) .map((k) => `[data-search-index~=${JSON.stringify(k)}]`)
.join('') .join('')
qsa('[data-search-index]').forEach(el => { qsa('[data-search-index]').forEach((el) => {
el.setAttribute('aria-hidden', true) el.setAttribute('aria-hidden', true)
}) })
qsa(selectors).forEach(el => { qsa(selectors).forEach((el) => {
el.removeAttribute('aria-hidden') el.removeAttribute('aria-hidden')
}) })
} }

View File

@ -6,5 +6,7 @@ import onmount from 'onmount'
*/ */
ready(() => { ready(() => {
setTimeout(() => { onmount() }) setTimeout(() => {
onmount()
})
}) })

View File

@ -0,0 +1 @@
window.Prism = require('prismjs')

View File

@ -0,0 +1,88 @@
/* eslint-env jest */
import wrapify from '../index'
it(
'simple usage',
run(
`
<div>
<h2>simple usage<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
</div>
`,
(root) => {
expect(
root.querySelectorAll('.h2-section .h3-section-list .h3-section').length
).toEqual(2)
}
)
)
it(
'h3 with class',
run(
`
<div>
<h3 class='-hello'>install</h3>
<p>(install)</p>
</div>
`,
(root) => {
expect(root.querySelectorAll('div.h3-section.-hello').length).toEqual(1)
expect(
root.querySelectorAll('div.h3-section-list.-hello').length
).toEqual(1)
}
)
)
it(
'multiple h2s',
run(`
<div>
<h2>multiple h2<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
<h2>getting started<h2>
<h3>first</h3>
<p>(first)</p>
<h3>second</h3>
<p>(second)</p>
</div>
`)
)
function run(input, fn) {
return function () {
const div = document.createElement('div')
div.innerHTML = input
const root = div.children[0]
wrapify(root)
expect(root).toMatchSnapshot()
if (fn) fn(root)
}
}
it(
'h2 + pre',
run(`
<div>
<h2>heading</h2>
<pre class='language-markdown'>(code)</pre>
</div>
`)
)

View File

@ -1,6 +1,12 @@
import matches from 'dom101/matches' import matches from 'dom101/matches'
import addClass from 'dom101/add-class' import addClass from 'dom101/add-class'
import { appendMany, nextUntil, before, findChildren, createDiv } from '../helpers/dom' import {
appendMany,
nextUntil,
before,
findChildren,
createDiv
} from '../helpers/dom'
/** /**
* Wraps h2 sections into h2-section. * Wraps h2 sections into h2-section.
@ -14,9 +20,11 @@ export default function wrapify (root) {
const sections = wrapifyH2(root) const sections = wrapifyH2(root)
// For each h2 section, wrap the H3's in them // For each h2 section, wrap the H3's in them
sections.forEach(section => { sections.forEach((section) => {
const bodies = findChildren(section, '[data-js-h3-section-list]') const bodies = findChildren(section, '[data-js-h3-section-list]')
bodies.forEach(body => { wrapifyH3(body) }) bodies.forEach((body) => {
wrapifyH3(body)
})
}) })
} }
@ -37,7 +45,8 @@ function wrapifyH2 (root) {
return groupify(root, { return groupify(root, {
tag: 'h2', tag: 'h2',
wrapperFn: () => createDiv({ class: 'h2-section' }), wrapperFn: () => createDiv({ class: 'h2-section' }),
bodyFn: () => createDiv({ bodyFn: () =>
createDiv({
class: 'body h3-section-list', class: 'body h3-section-list',
'data-js-h3-section-list': '' 'data-js-h3-section-list': ''
}) })
@ -84,7 +93,7 @@ export function groupify (el, { tag, wrapperFn, bodyFn }) {
// Find all h3's inside it // Find all h3's inside it
const children = findChildren(el, tag) const children = findChildren(el, tag)
children.forEach(child => { children.forEach((child) => {
const sibs = nextUntil(child, tag) const sibs = nextUntil(child, tag)
result.push(wrap(child, child, sibs)) result.push(wrap(child, child, sibs))
}) })

View File

@ -43,6 +43,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
background: transparent;
&:hover, &:hover,
&:focus { &:focus {

View File

@ -1,4 +1,6 @@
@import '../vendor/sanitize.css/sanitize'; // Generated by parcel
@import '../../assets/packed/app.css';
@import './variables'; @import './variables';
@import '../vendor/modularscale/modularscale'; @import '../vendor/modularscale/modularscale';
@import '../vendor/ionicons-inline/ionicons'; @import '../vendor/ionicons-inline/ionicons';

View File

@ -80,14 +80,14 @@ $modularscale : () !default;// Parse settings starting with defaults.
// This does not support non-integer exponents, // This does not support non-integer exponents,
// Check and return an error if a non-integer exponent is passed. // Check and return an error if a non-integer exponent is passed.
@if (floor($e) != $e) { @if (floor($e) != $e) {
@error ' // @error '
====================================================================== // ======================================================================
Non-integer values are not supported in modularscale by default. // Non-integer values are not supported in modularscale by default.
Try using mathsass in your project to add non-integer scale support. // Try using mathsass in your project to add non-integer scale support.
https://github.com/terkel/mathsass // https://github.com/terkel/mathsass
====================================================================== // ======================================================================
' // '
} }
// Seed the return. // Seed the return.

View File

@ -1,45 +0,0 @@
const critical = require('critical')
console.warn('Generating critical path styles into _includes/2017/critical/...')
const OPTIONS = {
base: '_site',
width: 1400,
height: 900,
minify: true,
extract: true,
ignore: [
'@font-face'
],
include: [
// fade-in magic (base/fade)
/html\.WithJs/
]
}
critical.generate({
...OPTIONS,
src: 'index.html',
dest: '../_includes/2017/critical/home.css',
include: [
...OPTIONS.include,
// searchbox with placeholder
/\.search-box/
]
})
critical.generate({
...OPTIONS,
src: 'react.html',
dest: '../_includes/2017/critical/sheet.css',
include: [
...OPTIONS.include,
// sections (and h3 section list), just to be sure
/\.h3-section/,
// eg, -six-column in devhints.io/layout-thrashing
/-column/
]
})

View File

@ -1,73 +0,0 @@
const join = require('path').resolve
const webpack = require('webpack')
module.exports = {
context: join(__dirname, '..'),
entry: {
app: './_js/app.js',
vendor: [
// Large 3rd-party libs
'prismjs',
// Prism plugins
'prismjs/plugins/line-highlight/prism-line-highlight.min.js',
'prismjs/components/prism-jsx.min.js',
'prismjs/components/prism-bash.min.js',
'prismjs/components/prism-scss.min.js',
'prismjs/components/prism-css.min.js',
'prismjs/components/prism-elixir.min.js',
'prismjs/components/prism-ruby.min.js',
// CSS
'prismjs/plugins/line-highlight/prism-line-highlight.css',
'hint.css/hint.min.css'
]
},
output: {
path: join(__dirname, '..', 'assets', 'packed'),
filename: '[name].js',
devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' }
]
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
}
]
},
resolve: {
alias: {
// Never bundle jQuery
'jquery': join(__dirname, '..', '_js/helpers/noop.js')
}
},
stats: 'minimal',
plugins: [
// Optimize module ID's for vendor chunks
new webpack.HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'base64',
hashDigestLength: 20
}),
// Optimize vendor
new webpack.optimize.CommonsChunkPlugin('vendor'),
// Don't include debug symbols ever
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
})
],
devtool: 'source-map'
}

View File

@ -1,28 +0,0 @@
const join = require('path').resolve
const webpack = require('webpack')
module.exports = {
context: join(__dirname, '..'),
entry: './_js/critical.js',
output: {
path: join(__dirname, '..', '_includes', '2017', 'critical'),
filename: 'critical.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' }
]
}
]
},
stats: 'minimal',
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
})
]
}

3
assets/packed/app.css Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,11 +6,14 @@ services:
- .:/app - .:/app
- rubygems:/usr/local/bundle - rubygems:/usr/local/bundle
- ./node_modules:/app/node_modules - ./node_modules:/app/node_modules
- yarn_cache:/root/.cache/yarn
ports: ports:
- '4001:4001' - '4001:4001'
- '35729:35729' - '35729:35729'
command: 'env PORT=4001 HOST=0.0.0.0 yarn run dev' command: >
bash -c 'yarn; bundle; env PORT=4001 HOST=0.0.0.0 yarn run dev'
volumes: volumes:
rubygems: rubygems:
node_modules: node_modules:
yarn_cache:

16
netlify.toml Normal file
View File

@ -0,0 +1,16 @@
[build]
command = "yarn build"
publish = "_site/"
[[plugins]]
# https://www.npmjs.com/package/netlify-plugin-minify-html
package = "netlify-plugin-minify-html"
[plugins.inputs]
contexts = [ 'production', 'branch-deploy', 'deploy-preview' ]
# https://github.com/kangax/html-minifier#options-quick-reference
[plugins.inputs.minifierOptions]
removeComments = true
minifyCSS = true
minifyJS = true

View File

@ -1,59 +1,54 @@
{ {
"name": "cheatsheets", "name": "cheatsheets",
"description": "Devhints.io",
"version": "1.0.0", "version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/rstacruz/cheatsheets.git",
"author": "Rico Sta. Cruz <rstacruz@users.noreply.github.com>", "author": "Rico Sta. Cruz <rstacruz@users.noreply.github.com>",
"license": "MIT",
"devDependencies": {
"babel-core": "6.26.0",
"babel-eslint": "8.0.1",
"babel-jest": "21.2.0",
"babel-loader": "7.1.2",
"babel-preset-env": "1.6.0",
"concurrently": "3.5.0",
"css-loader": "0.28.7",
"eslint-plugin-flowtype": "2.37.0",
"jest": "21.2.1",
"jest-html": "1.3.5",
"npm-run-all": "4.1.1",
"standard": "10.0.3",
"style-loader": "0.18.2",
"uglifyjs-webpack-plugin": "0.4.6",
"webpack": "3.6.0"
},
"scripts": {
"critical": "make critical",
"dev": "make dev",
"test": "jest",
"test:all": "run-s test lint",
"lint": "standard -v",
"jest-html": "jest-html"
},
"dependencies": { "dependencies": {
"babel-polyfill": "6.26.0", "autoprefixer": "^9.8.0",
"critical": "0.9.1", "dom101": "^2.2.1",
"dom101": "2.2.1", "hint.css": "^2.6.0",
"hint.css": "2.5.0", "isotope-layout": "^3.0.6",
"isotope-layout": "3.0.4", "lodash.noop": "^3.0.1",
"jquery": "3.2.1", "modularscale-sass": "^3.0.10",
"onmount": "1.3.0", "onmount": "^1.3.0",
"prettier": "1.11.1", "postcss-modules": "^2.0.0",
"prismjs": "1.8.1", "prismjs": "^1.20.0",
"sanitize.css": "5.0.0" "sanitize.css": "^11.0.1",
"sass": "^1.26.8"
}, },
"standard": { "devDependencies": {
"parser": "babel-eslint", "@babel/core": "^7.10.2",
"ignore": [ "@babel/preset-env": "^7.10.2",
"assets/script.js" "jest": "26.0.1",
], "jest-html": "1.5.0",
"plugins": [ "netlify-plugin-minify-html": "^0.2.3",
"flowtype" "npm-run-all": "^4.1.5",
] "parcel-bundler": "^1.12.4",
"prettier": "^2.0.5",
"wait-on": "^5.0.1"
}, },
"homepage": "https://devhints.io/",
"jest": { "jest": {
"snapshotSerializers": [ "snapshotSerializers": [
"<rootDir>/node_modules/jest-html" "<rootDir>/node_modules/jest-html"
] ]
},
"license": "MIT",
"main": "index.js",
"private": true,
"repository": "https://github.com/rstacruz/cheatsheets.git",
"scripts": {
"build": "run-s -s 'parcel:*:build' jekyll:build",
"dev": "run-p -sl jekyll:watch 'parcel:*:watch'",
"jekyll:build": "bundle exec jekyll build",
"jekyll:watch": "wait-on assets/packed/app.js && bundle exec jekyll serve --safe --trace --drafts --watch --incremental --host ${HOST:-0.0.0.0} --port ${PORT:-3000}",
"jest-html": "jest-html",
"parcel:app:build": "parcel build '_parcel/app.js' -d assets/packed --no-source-maps --no-autoinstall",
"parcel:app:watch": "parcel watch '_parcel/app.js' -d assets/packed --no-source-maps --no-autoinstall",
"parcel:build": "run-s -s 'parcel:*:build'",
"parcel:critical:build": "parcel build '_parcel/critical*.{js,scss}' -d _includes/2017/critical --no-source-maps --no-autoinstall",
"parcel:critical:watch": "parcel watch '_parcel/critical*.{js,scss}' -d _includes/2017/critical --no-source-maps --no-autoinstall",
"prettier:format": "prettier --write '_parcel/**/*.{js,scss}'",
"test": "jest"
} }
} }

View File

@ -1,4 +0,0 @@
module.exports = [
require('./_support/webpack.config.js'),
require('./_support/webpack.critical.js')
]

11231
yarn.lock

File diff suppressed because it is too large Load Diff