From 96a2aa4b1f52567dee50398c79f81a959492eb0d Mon Sep 17 00:00:00 2001 From: Fu Cheng Date: Tue, 27 Feb 2018 00:31:28 +1300 Subject: [PATCH] Add installation types - developer and integrator --- .gitignore | 1 + Dockerfile.hbs | 54 +++++++++ README.md | 6 + crontab | 2 - crontab.hbs | 3 + Dockerfile => developer/Dockerfile | 45 ++++--- developer/auth.json | 8 ++ developer/crontab | 3 + {bin => developer}/install-magento | 0 {bin => developer}/install-sampledata | 0 install-magento | 7 ++ install-sampledata | 13 +++ integrator/Dockerfile | 55 +++++++++ integrator/auth.json | 8 ++ integrator/crontab | 4 + integrator/install-magento | 7 ++ integrator/install-sampledata | 13 +++ package.json | 22 ++++ partials/developer/extraCronJobs | 0 partials/developer/magento2Installation | 8 ++ partials/integrator/extraCronJobs | 2 + partials/integrator/magento2Installation | 2 + update.js | 42 +++++++ yarn.lock | 143 +++++++++++++++++++++++ 24 files changed, 422 insertions(+), 26 deletions(-) create mode 100644 Dockerfile.hbs delete mode 100644 crontab create mode 100644 crontab.hbs rename Dockerfile => developer/Dockerfile (63%) create mode 100644 developer/auth.json create mode 100644 developer/crontab rename {bin => developer}/install-magento (100%) rename {bin => developer}/install-sampledata (100%) create mode 100644 install-magento create mode 100644 install-sampledata create mode 100644 integrator/Dockerfile create mode 100644 integrator/auth.json create mode 100644 integrator/crontab create mode 100644 integrator/install-magento create mode 100644 integrator/install-sampledata create mode 100644 package.json create mode 100644 partials/developer/extraCronJobs create mode 100644 partials/developer/magento2Installation create mode 100644 partials/integrator/extraCronJobs create mode 100644 partials/integrator/magento2Installation create mode 100644 update.js create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index c40b48396..abbbec450 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .bash_history +node_modules \ No newline at end of file diff --git a/Dockerfile.hbs b/Dockerfile.hbs new file mode 100644 index 000000000..1856b770d --- /dev/null +++ b/Dockerfile.hbs @@ -0,0 +1,54 @@ +FROM alexcheng/apache2-php7:{{phpVersion}} + +Label maintainer="alexcheng1982@gmail.com" + +ENV MAGENTO_VERSION {{magento2Version}} +ENV INSTALL_DIR /var/www/html +ENV COMPOSER_HOME /var/www/.composer/ + +RUN curl -sS https://getcomposer.org/installer | php \ + && mv composer.phar /usr/local/bin/composer +COPY ./auth.json $COMPOSER_HOME + +RUN requirements="libpng12-dev libmcrypt-dev libmcrypt4 libcurl3-dev libfreetype6 libjpeg-turbo8 libjpeg-turbo8-dev libpng12-dev libfreetype6-dev libicu-dev libxslt1-dev" \ + && apt-get update \ + && apt-get install -y $requirements \ + && rm -rf /var/lib/apt/lists/* \ + && docker-php-ext-install pdo_mysql \ + && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ + && docker-php-ext-install gd \ + && docker-php-ext-install mcrypt \ + && docker-php-ext-install mbstring \ + && docker-php-ext-install zip \ + && docker-php-ext-install intl \ + && docker-php-ext-install xsl \ + && docker-php-ext-install soap \ + && requirementsToRemove="libpng12-dev libmcrypt-dev libcurl3-dev libpng12-dev libfreetype6-dev libjpeg-turbo8-dev" \ + && apt-get purge --auto-remove -y $requirementsToRemove + +RUN chsh -s /bin/bash www-data + +{{{magento2Installation}}} + +RUN cd $INSTALL_DIR \ + && find . -type d -exec chmod 770 {} \; \ + && find . -type f -exec chmod 660 {} \; \ + && chmod u+x bin/magento + +COPY ./install-magento /usr/local/bin/install-magento +RUN chmod +x /usr/local/bin/install-magento + +COPY ./install-sampledata /usr/local/bin/install-sampledata +RUN chmod +x /usr/local/bin/install-sampledata + +RUN a2enmod rewrite +RUN echo "memory_limit=2048M" > /usr/local/etc/php/conf.d/memory-limit.ini + +RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +WORKDIR $INSTALL_DIR + +# Add cron job +ADD crontab /etc/cron.d/magento2-cron +RUN chmod 0644 /etc/cron.d/magento2-cron \ + && crontab -u www-data /etc/cron.d/magento2-cron \ No newline at end of file diff --git a/README.md b/README.md index da1206f23..1b91e6136 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ __Note__ This docker image uses the *Contributing developer* profile to install **Please note: this Docker image is for development and testing only, not for production use. Setting up a Magento 2 production server requires more configurations. Please refer to [official documentations](http://devdocs.magento.com/guides/v2.2/config-guide/deployment/).** +## Magento 2 installation types + +Magento 2 has three different ways to [install](http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html), for users, integrators and developers. This Docker image uses **integrator** as the default installation type, so the **Web Setup Wizard** can be used. For each version, both integrator and developer installation types are available. The user installation type is not currently supported. + +For example, Magento 2 version `2.2.2` has tag `2.2.2`, `2.2.2-integrator` and `2.2.2-developer`. `2.2.2` is the same as `2.2.2-integrator`. + Below are some basic instructions. ## Quick start diff --git a/crontab b/crontab deleted file mode 100644 index 6b27176c4..000000000 --- a/crontab +++ /dev/null @@ -1,2 +0,0 @@ -*/1 * * * * www-data /usr/local/bin/php /var/www/html/bin/magento cron:run -*/1 * * * * www-data /usr/local/bin/php /var/www/html/bin/magento indexer:reindex diff --git a/crontab.hbs b/crontab.hbs new file mode 100644 index 000000000..a27e1aa5a --- /dev/null +++ b/crontab.hbs @@ -0,0 +1,3 @@ +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /var/www/html/var/log/magento.cron.log +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento indexer:reindex +{{{extraCronJobs}}} diff --git a/Dockerfile b/developer/Dockerfile similarity index 63% rename from Dockerfile rename to developer/Dockerfile index c407442e4..f0bfab385 100644 --- a/Dockerfile +++ b/developer/Dockerfile @@ -1,21 +1,17 @@ FROM alexcheng/apache2-php7:7.1.11 -MAINTAINER Fu Cheng - -RUN a2enmod rewrite +Label maintainer="alexcheng1982@gmail.com" ENV MAGENTO_VERSION 2.2.2 - -RUN rm -rf /var/www/html/* \ - && apt-get update \ - && apt-get install -y wget - -RUN cd /tmp && curl https://codeload.github.com/magento/magento2/tar.gz/$MAGENTO_VERSION -o $MAGENTO_VERSION.tar.gz && tar xvf $MAGENTO_VERSION.tar.gz && mv magento2-$MAGENTO_VERSION/* magento2-$MAGENTO_VERSION/.htaccess /var/www/html - +ENV INSTALL_DIR /var/www/html +ENV COMPOSER_HOME /var/www/.composer/ RUN curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/composer +COPY ./auth.json $COMPOSER_HOME + RUN requirements="libpng12-dev libmcrypt-dev libmcrypt4 libcurl3-dev libfreetype6 libjpeg-turbo8 libjpeg-turbo8-dev libpng12-dev libfreetype6-dev libicu-dev libxslt1-dev" \ + && apt-get update \ && apt-get install -y $requirements \ && rm -rf /var/lib/apt/lists/* \ && docker-php-ext-install pdo_mysql \ @@ -30,33 +26,34 @@ RUN requirements="libpng12-dev libmcrypt-dev libmcrypt4 libcurl3-dev libfreetype && requirementsToRemove="libpng12-dev libmcrypt-dev libcurl3-dev libpng12-dev libfreetype6-dev libjpeg-turbo8-dev" \ && apt-get purge --auto-remove -y $requirementsToRemove -COPY ./auth.json /var/www/.composer/ RUN chsh -s /bin/bash www-data + +RUN cd /tmp && \ + curl https://codeload.github.com/magento/magento2/tar.gz/$MAGENTO_VERSION -o $MAGENTO_VERSION.tar.gz && \ + tar xvf $MAGENTO_VERSION.tar.gz && \ + mv magento2-$MAGENTO_VERSION/* magento2-$MAGENTO_VERSION/.htaccess $INSTALL_DIR + RUN chown -R www-data:www-data /var/www -RUN su www-data -c "cd /var/www/html && composer install" -RUN cd /var/www/html \ +RUN su www-data -c "cd $INSTALL_DIR && composer install" +RUN su www-data -c "cd $INSTALL_DIR && composer config repositories.magento composer https://repo.magento.com/" + +RUN cd $INSTALL_DIR \ && find . -type d -exec chmod 770 {} \; \ && find . -type f -exec chmod 660 {} \; \ && chmod u+x bin/magento - -RUN su www-data -c "cd /var/www/html && composer config repositories.magento composer https://repo.magento.com/" - - -COPY ./bin/install-magento /usr/local/bin/install-magento +COPY ./install-magento /usr/local/bin/install-magento RUN chmod +x /usr/local/bin/install-magento -COPY ./bin/install-sampledata /usr/local/bin/install-sampledata +COPY ./install-sampledata /usr/local/bin/install-sampledata RUN chmod +x /usr/local/bin/install-sampledata -RUN echo "memory_limit=1024M" > /usr/local/etc/php/conf.d/memory-limit.ini +RUN a2enmod rewrite +RUN echo "memory_limit=2048M" > /usr/local/etc/php/conf.d/memory-limit.ini RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -#Commented out the next 3 lines, because i don't see no use of this -WORKDIR /var/www/html -#VOLUME /var/www/html/var -#VOLUME /var/www/html/pub +WORKDIR $INSTALL_DIR # Add cron job ADD crontab /etc/cron.d/magento2-cron diff --git a/developer/auth.json b/developer/auth.json new file mode 100644 index 000000000..8506a6847 --- /dev/null +++ b/developer/auth.json @@ -0,0 +1,8 @@ + { + "http-basic": { + "repo.magento.com": { + "username": "5310458a34d580de1700dfe826ff19a1", + "password": "255059b03eb9d30604d5ef52fca7465d" + } + } +} \ No newline at end of file diff --git a/developer/crontab b/developer/crontab new file mode 100644 index 000000000..41d1c84d8 --- /dev/null +++ b/developer/crontab @@ -0,0 +1,3 @@ +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /var/www/html/var/log/magento.cron.log +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento indexer:reindex + diff --git a/bin/install-magento b/developer/install-magento similarity index 100% rename from bin/install-magento rename to developer/install-magento diff --git a/bin/install-sampledata b/developer/install-sampledata similarity index 100% rename from bin/install-sampledata rename to developer/install-sampledata diff --git a/install-magento b/install-magento new file mode 100644 index 000000000..671656dbd --- /dev/null +++ b/install-magento @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +su www-data < /usr/local/etc/php/conf.d/memory-limit.ini + +RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +WORKDIR $INSTALL_DIR + +# Add cron job +ADD crontab /etc/cron.d/magento2-cron +RUN chmod 0644 /etc/cron.d/magento2-cron \ + && crontab -u www-data /etc/cron.d/magento2-cron \ No newline at end of file diff --git a/integrator/auth.json b/integrator/auth.json new file mode 100644 index 000000000..8506a6847 --- /dev/null +++ b/integrator/auth.json @@ -0,0 +1,8 @@ + { + "http-basic": { + "repo.magento.com": { + "username": "5310458a34d580de1700dfe826ff19a1", + "password": "255059b03eb9d30604d5ef52fca7465d" + } + } +} \ No newline at end of file diff --git a/integrator/crontab b/integrator/crontab new file mode 100644 index 000000000..ff0100928 --- /dev/null +++ b/integrator/crontab @@ -0,0 +1,4 @@ +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /var/www/html/var/log/magento.cron.log +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento indexer:reindex +* * * * * www-data /usr/local/bin/php /var/www/html/update/cron.php >> /var/www/html/var/log/update.cron.log +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento setup:cron:run >> /var/www/html/var/log/setup.cron.log diff --git a/integrator/install-magento b/integrator/install-magento new file mode 100644 index 000000000..671656dbd --- /dev/null +++ b/integrator/install-magento @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +su www-data <", + "license": "MIT", + "bugs": { + "url": "https://github.com/alexcheng1982/docker-magento2/issues" + }, + "homepage": "https://github.com/alexcheng1982/docker-magento2#readme", + "dependencies": { + "bluebird": "^3.5.1", + "handlebars": "^4.0.11", + "lodash.merge": "^4.6.1" + } +} diff --git a/partials/developer/extraCronJobs b/partials/developer/extraCronJobs new file mode 100644 index 000000000..e69de29bb diff --git a/partials/developer/magento2Installation b/partials/developer/magento2Installation new file mode 100644 index 000000000..45c49cef0 --- /dev/null +++ b/partials/developer/magento2Installation @@ -0,0 +1,8 @@ +RUN cd /tmp && \ + curl https://codeload.github.com/magento/magento2/tar.gz/$MAGENTO_VERSION -o $MAGENTO_VERSION.tar.gz && \ + tar xvf $MAGENTO_VERSION.tar.gz && \ + mv magento2-$MAGENTO_VERSION/* magento2-$MAGENTO_VERSION/.htaccess $INSTALL_DIR + +RUN chown -R www-data:www-data /var/www +RUN su www-data -c "cd $INSTALL_DIR && composer install" +RUN su www-data -c "cd $INSTALL_DIR && composer config repositories.magento composer https://repo.magento.com/" \ No newline at end of file diff --git a/partials/integrator/extraCronJobs b/partials/integrator/extraCronJobs new file mode 100644 index 000000000..05bcea3c4 --- /dev/null +++ b/partials/integrator/extraCronJobs @@ -0,0 +1,2 @@ +* * * * * www-data /usr/local/bin/php /var/www/html/update/cron.php >> /var/www/html/var/log/update.cron.log +* * * * * www-data /usr/local/bin/php /var/www/html/bin/magento setup:cron:run >> /var/www/html/var/log/setup.cron.log \ No newline at end of file diff --git a/partials/integrator/magento2Installation b/partials/integrator/magento2Installation new file mode 100644 index 000000000..a842d6b5b --- /dev/null +++ b/partials/integrator/magento2Installation @@ -0,0 +1,2 @@ +RUN chown -R www-data:www-data /var/www +RUN su www-data -c "composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition $INSTALL_DIR $MAGENTO_VERSION" \ No newline at end of file diff --git a/update.js b/update.js new file mode 100644 index 000000000..700faae16 --- /dev/null +++ b/update.js @@ -0,0 +1,42 @@ +const Handlebars = require('handlebars'); +const Promise = require('bluebird'); +const merge = require('lodash.merge'); +const fs = Promise.promisifyAll(require("fs")); +const path = require("path"); + +const commonOptions = { + phpVersion: '7.1.11', + magento2Version: '2.2.2', +}; + +function readPartial(profile, section) { + return fs.readFileAsync(path.join(__dirname, 'partials', profile, section), 'utf8'); +} + +function writeFile(context, profile, fileName, template) { + return fs.readFileAsync(path.join(__dirname, template || `${fileName}.hbs`), 'utf8') + .then(content => Handlebars.compile(content)(context)) + .then(content => fs.writeFileAsync(path.join(__dirname, profile, fileName), content)); +} + +function copyFile(fileName, profile) { + return fs.copyFileAsync(path.join(__dirname, fileName), path.join(__dirname, profile, fileName)); +} + +const profiles = ['integrator', 'developer']; +const sections = ['magento2Installation', 'extraCronJobs']; +const filesToCopy = ['auth.json', 'install-magento', 'install-sampledata']; +const templatedFiles = ['Dockerfile', 'crontab']; +Promise.map(profiles, profile => { + return Promise.reduce(sections, (obj, section) => { + return readPartial(profile, section).then(value => { + obj[section] = value; + return obj; + }) + }, {}).then(profileContext => { + const context = merge({}, commonOptions, profileContext); + return Promise.map(filesToCopy, fileToCopy => copyFile(fileToCopy, profile)) + .then(_ => Promise.map(templatedFiles, templatedFile => writeFile(context, profile, templatedFile))); + }); +}).then(() => console.log("Update successfully")) + .catch(console.error); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..34f60fb75 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,143 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.npmjs.org/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +decamelize@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +handlebars@^4.0.11: + version "4.0.11" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lodash.merge@^4.6.1: + version "4.6.1" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0"