├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── JS-Lint.yml │ └── PHP-Lint.yml ├── .gitignore ├── .htaccess ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── package-lock.json ├── package.json ├── post-install.php ├── public ├── .htaccess ├── index.php └── www │ ├── .eslintrc.js │ ├── dist │ ├── console.css │ ├── console.js │ ├── google_icons.css │ ├── jquery.min.js │ └── src.css │ └── src │ ├── console │ ├── console.css │ └── console.js │ ├── images │ ├── logo.png │ └── welcome │ │ ├── 1.PNG │ │ ├── 2.PNG │ │ ├── 3.PNG │ │ └── 4.PNG │ └── site │ └── site.css ├── src ├── common │ ├── controller │ │ └── CommonController.php │ └── view │ │ ├── Console.php │ │ ├── Footer.php │ │ ├── Header.php │ │ └── PageNotFoundView.php ├── product │ ├── controller │ │ └── ProductController.php │ ├── model │ │ └── ProductModel.php │ └── view │ │ └── ProductDescriptionView.php └── welcome │ ├── controller │ └── WelcomeController.php │ └── view │ └── WelcomeView.php └── system ├── bootstrap.php ├── config ├── config.php ├── environment.php ├── ini.php └── routes.php ├── engine ├── AutoLoader.php ├── Base.php ├── Container.php ├── Router.php └── SecureSession.php ├── logs └── .gitkeep └── services ├── Config.php ├── Console.php ├── Database.php ├── Logger.php ├── Output.php ├── Session.php └── Util.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [**.php] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{js,html,css}] 12 | charset = utf-8 13 | end_of_line = lf 14 | indent_size = 2 15 | indent_style = space 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*] 20 | charset = utf-8 21 | end_of_line = lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Bug title 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 | **Enviroment** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - PHP Version [e.g. 22] 27 | - Light-PHP Version: 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/workflows/JS-Lint.yml: -------------------------------------------------------------------------------- 1 | name: JS CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [10.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: npm install, lint 21 | run: | 22 | cd src/view/www 23 | npm install 24 | npm run lint 25 | env: 26 | CI: true 27 | -------------------------------------------------------------------------------- /.github/workflows/PHP-Lint.yml: -------------------------------------------------------------------------------- 1 | name: PHP CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | 13 | - name: Validate composer.json and composer.lock 14 | run: composer validate 15 | 16 | - name: Install Lint 17 | run: composer install --prefer-dist --no-progress --no-suggest 18 | 19 | - name: Lint code 20 | run: composer lint 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editors 2 | /.idea/* 3 | /.vscode/* 4 | 5 | # Libraries 6 | /system/composer/vendor/* 7 | /node_modules/* 8 | 9 | # logs 10 | /system/logs/* -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | Options +FollowSymlinks 2 | 3 | # Block all files 4 | 5 | Order Deny,Allow 6 | Deny from all 7 | 8 | 9 | # Prevent Directoy listing 10 | Options -Indexes 11 | 12 | # SEO URL Settings 13 | RewriteEngine On 14 | RewriteBase / 15 | RewriteCond %{REQUEST_FILENAME} !-f 16 | RewriteCond %{REQUEST_FILENAME} !-d 17 | RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css) 18 | RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA] 19 | 20 | # Gzip 21 | 22 | AddOutputFilterByType DEFLATE application/javascript 23 | AddOutputFilterByType DEFLATE application/rss+xml 24 | AddOutputFilterByType DEFLATE application/vnd.ms-fontobject 25 | AddOutputFilterByType DEFLATE application/x-font 26 | AddOutputFilterByType DEFLATE application/x-font-opentype 27 | AddOutputFilterByType DEFLATE application/x-font-otf 28 | AddOutputFilterByType DEFLATE application/x-font-truetype 29 | AddOutputFilterByType DEFLATE application/x-font-ttf 30 | AddOutputFilterByType DEFLATE application/x-javascript 31 | AddOutputFilterByType DEFLATE application/xhtml+xml 32 | AddOutputFilterByType DEFLATE application/xml 33 | AddOutputFilterByType DEFLATE font/opentype 34 | AddOutputFilterByType DEFLATE font/otf 35 | AddOutputFilterByType DEFLATE font/ttf 36 | AddOutputFilterByType DEFLATE image/svg+xml 37 | AddOutputFilterByType DEFLATE image/x-icon 38 | AddOutputFilterByType DEFLATE text/css 39 | AddOutputFilterByType DEFLATE text/html 40 | AddOutputFilterByType DEFLATE text/javascript 41 | AddOutputFilterByType DEFLATE text/plain 42 | AddOutputFilterByType DEFLATE text/xml 43 | 44 | 45 | # Cache 46 | 47 | Header set Cache-Control "max-age=2628000, public" 48 | 49 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | logo 5 | 6 |

7 | Micro PHP framework. 8 |
9 | - Explore the DOCS - 10 |

11 | GitHub 12 | GitHub code size in bytes 13 | GitHub stars 14 | Packagist Version 15 | 16 |

17 |

18 |
19 | 20 | # Light-PHP 21 | 22 | ## Easiest PHP framework 23 | `Light-php` Light PHP it's an open-source minimal PHP framework that only includes what's necessary, avoiding big and complex structures, yet capable of building big and fully-featured API/Websites. 24 | It's advantages from others frameworks are the small learning curve, possibility to start working without reading massive documentations and it's easy to understand how the framework works and being able to modify its original behavior. 25 | 26 | This project includes the `PSR-0`, `PSR-1`, `PSR-4`, `PSR-11`, `PSR-12` standards, good coding practices, MVC structure, service container and much more! 27 | 28 | ### What's this project? 29 | This is a lightweight micro PHP Framework focused on simplicity, aimed to capable to build small, medium Apps/APIs (big Apps/APIs even possible, dividing your app in smaller ones) and making things just work. 30 | 31 | ### What's not this project? 32 | This doesn't pretend to be a full complete PHP framework, highly abstracted, with ORM, autowiring, automatic processes, complex algorithm, or any kind of 'black magic' that frameworks comes nowdays. 33 | 34 | ### For who is this project? 35 | This proyect can be aimed for people who only needs a small proyect to build and doesn't need a complete PHP framework, for beginners in PHP who need a easy entry point, for people who want to try a new PHP framework, and this proyect cover all it's needs 36 | 37 | ### What are benefits of using Light-php: 38 | 39 | - Quick development 40 | - Lightweight 41 | - MVC structure 42 | - Focused on simplicity 43 | - Implements best practices 44 | - Security implementations 45 | 46 | ### Installation 47 | 48 | ```php 49 | composer create-project bakeiro/light-php 50 | ``` 51 | 52 | ### License 53 | 54 | Light-PHP is licensed under the Open Source MIT license, feel free to use it, modify it or contribute on it!

55 | Built by [David Baqueiro](https://davidbaqueiro.com) 56 | 57 | ### Support 58 | Light-PHP is an open source project licensed under the MIT license. It's completely free to use. However, it would be great if you buy me a cup of coffee once in a while to keep me awake :) 59 | 60 | Buy Me A Coffee 61 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bakeiro/light-php", 3 | "type": "project", 4 | "license": "MIT", 5 | "description": "Easiest PHP framework", 6 | "config": { 7 | "vendor-dir": "./system/composer/vendor/" 8 | }, 9 | "scripts": { 10 | "post-create-project-cmd": [ 11 | "php -r \"require_once('./post-install.php'); \"", 12 | "php -r \"unlink('./post-install.php'); \"" 13 | ], 14 | "lint": [ 15 | "phpcs --encoding=utf-8 -n -s --colors --standard=PSR1,PSR12 --ignore=node_modules/*,system/composer/*,public/* ./ " 16 | ], 17 | "fix-lint": [ 18 | "phpcbf --encoding=utf-8 -n --colors --standard=PSR1,PSR12 --ignore=node_modules/*,system/composer/*,public/* ./" 19 | ] 20 | }, 21 | "authors": [ 22 | { 23 | "name": "David Baqueiro Santerbas", 24 | "email": "davidbaqueiro@outlook.com", 25 | "homepage": "http://davidbaqueiro.com", 26 | "role": "Lead developer" 27 | } 28 | ], 29 | "require": { 30 | "php": ">=8.0", 31 | "ext-openssl": "*", 32 | "ext-mbstring": "*" 33 | }, 34 | "require-dev": { 35 | "sunra/dbug": "^0.2.1", 36 | "squizlabs/php_codesniffer": "3.*" 37 | }, 38 | "minimum-stability": "dev" 39 | } 40 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "ce46ba0f91bfd5bacf496c31a2e7ade9", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "squizlabs/php_codesniffer", 12 | "version": "3.7.1", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 16 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", 21 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "ext-simplexml": "*", 26 | "ext-tokenizer": "*", 27 | "ext-xmlwriter": "*", 28 | "php": ">=5.4.0" 29 | }, 30 | "require-dev": { 31 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 32 | }, 33 | "bin": [ 34 | "bin/phpcs", 35 | "bin/phpcbf" 36 | ], 37 | "type": "library", 38 | "extra": { 39 | "branch-alias": { 40 | "dev-master": "3.x-dev" 41 | } 42 | }, 43 | "notification-url": "https://packagist.org/downloads/", 44 | "license": [ 45 | "BSD-3-Clause" 46 | ], 47 | "authors": [ 48 | { 49 | "name": "Greg Sherwood", 50 | "role": "lead" 51 | } 52 | ], 53 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 54 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 55 | "keywords": [ 56 | "phpcs", 57 | "standards" 58 | ], 59 | "support": { 60 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 61 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 62 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 63 | }, 64 | "time": "2022-06-18T07:21:10+00:00" 65 | }, 66 | { 67 | "name": "sunra/dbug", 68 | "version": "0.2.1", 69 | "source": { 70 | "type": "git", 71 | "url": "https://github.com/sunra/dBug.git", 72 | "reference": "ecd8a589dc3ee1bba84095828c222ff560bc19e5" 73 | }, 74 | "dist": { 75 | "type": "zip", 76 | "url": "https://api.github.com/repos/sunra/dBug/zipball/ecd8a589dc3ee1bba84095828c222ff560bc19e5", 77 | "reference": "ecd8a589dc3ee1bba84095828c222ff560bc19e5", 78 | "shasum": "" 79 | }, 80 | "require": { 81 | "php": ">=5.3.2" 82 | }, 83 | "type": "library", 84 | "autoload": { 85 | "psr-4": { 86 | "Ospinto\\": "" 87 | } 88 | }, 89 | "notification-url": "https://packagist.org/downloads/", 90 | "license": [ 91 | "GPL-3.0" 92 | ], 93 | "authors": [ 94 | { 95 | "name": "sunra", 96 | "email": "sunra@yandex.ru", 97 | "homepage": "http://github.com/sunra" 98 | }, 99 | { 100 | "name": "Kwaku Otchere", 101 | "email": "ospinto@hotmail.com" 102 | } 103 | ], 104 | "description": "Most beautiful variable dump library for PHP (ColdFusion like style)", 105 | "homepage": "http://github.com/sunra/dBug.git", 106 | "keywords": [ 107 | "debug", 108 | "dump", 109 | "php" 110 | ], 111 | "support": { 112 | "source": "https://github.com/sunra/dBug/tree/master" 113 | }, 114 | "time": "2015-12-14T22:37:24+00:00" 115 | } 116 | ], 117 | "aliases": [], 118 | "minimum-stability": "stable", 119 | "stability-flags": [], 120 | "prefer-stable": false, 121 | "prefer-lowest": false, 122 | "platform": { 123 | "php": ">=8.0", 124 | "ext-openssl": "*" 125 | }, 126 | "platform-dev": [], 127 | "plugin-api-version": "2.3.0" 128 | } 129 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "light-php", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@babel/code-frame": { 7 | "version": "7.10.4", 8 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 9 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 10 | "dev": true, 11 | "requires": { 12 | "@babel/highlight": "^7.10.4" 13 | } 14 | }, 15 | "@babel/helper-validator-identifier": { 16 | "version": "7.10.4", 17 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 18 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 19 | "dev": true 20 | }, 21 | "@babel/highlight": { 22 | "version": "7.10.4", 23 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 24 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 25 | "dev": true, 26 | "requires": { 27 | "@babel/helper-validator-identifier": "^7.10.4", 28 | "chalk": "^2.0.0", 29 | "js-tokens": "^4.0.0" 30 | } 31 | }, 32 | "@types/json5": { 33 | "version": "0.0.29", 34 | "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", 35 | "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", 36 | "dev": true 37 | }, 38 | "acorn": { 39 | "version": "6.4.2", 40 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", 41 | "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", 42 | "dev": true 43 | }, 44 | "acorn-jsx": { 45 | "version": "5.3.1", 46 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", 47 | "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", 48 | "dev": true 49 | }, 50 | "ajv": { 51 | "version": "6.12.6", 52 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 53 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 54 | "dev": true, 55 | "requires": { 56 | "fast-deep-equal": "^3.1.1", 57 | "fast-json-stable-stringify": "^2.0.0", 58 | "json-schema-traverse": "^0.4.1", 59 | "uri-js": "^4.2.2" 60 | } 61 | }, 62 | "ansi-escapes": { 63 | "version": "3.2.0", 64 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 65 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", 66 | "dev": true 67 | }, 68 | "ansi-regex": { 69 | "version": "3.0.1", 70 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", 71 | "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", 72 | "dev": true 73 | }, 74 | "ansi-styles": { 75 | "version": "3.2.1", 76 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 77 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 78 | "dev": true, 79 | "requires": { 80 | "color-convert": "^1.9.0" 81 | } 82 | }, 83 | "argparse": { 84 | "version": "1.0.10", 85 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 86 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 87 | "dev": true, 88 | "requires": { 89 | "sprintf-js": "~1.0.2" 90 | } 91 | }, 92 | "array-includes": { 93 | "version": "3.1.1", 94 | "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", 95 | "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", 96 | "dev": true, 97 | "requires": { 98 | "define-properties": "^1.1.3", 99 | "es-abstract": "^1.17.0", 100 | "is-string": "^1.0.5" 101 | } 102 | }, 103 | "array.prototype.flat": { 104 | "version": "1.2.3", 105 | "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", 106 | "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", 107 | "dev": true, 108 | "requires": { 109 | "define-properties": "^1.1.3", 110 | "es-abstract": "^1.17.0-next.1" 111 | } 112 | }, 113 | "astral-regex": { 114 | "version": "1.0.0", 115 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 116 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 117 | "dev": true 118 | }, 119 | "balanced-match": { 120 | "version": "1.0.0", 121 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 122 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 123 | "dev": true 124 | }, 125 | "brace-expansion": { 126 | "version": "1.1.11", 127 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 128 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 129 | "dev": true, 130 | "requires": { 131 | "balanced-match": "^1.0.0", 132 | "concat-map": "0.0.1" 133 | } 134 | }, 135 | "call-bind": { 136 | "version": "1.0.0", 137 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", 138 | "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", 139 | "dev": true, 140 | "requires": { 141 | "function-bind": "^1.1.1", 142 | "get-intrinsic": "^1.0.0" 143 | } 144 | }, 145 | "callsites": { 146 | "version": "3.1.0", 147 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 148 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 149 | "dev": true 150 | }, 151 | "chalk": { 152 | "version": "2.4.2", 153 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 154 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 155 | "dev": true, 156 | "requires": { 157 | "ansi-styles": "^3.2.1", 158 | "escape-string-regexp": "^1.0.5", 159 | "supports-color": "^5.3.0" 160 | } 161 | }, 162 | "chardet": { 163 | "version": "0.7.0", 164 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 165 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 166 | "dev": true 167 | }, 168 | "cli-cursor": { 169 | "version": "2.1.0", 170 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 171 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 172 | "dev": true, 173 | "requires": { 174 | "restore-cursor": "^2.0.0" 175 | } 176 | }, 177 | "cli-width": { 178 | "version": "2.2.1", 179 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", 180 | "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", 181 | "dev": true 182 | }, 183 | "color-convert": { 184 | "version": "1.9.3", 185 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 186 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 187 | "dev": true, 188 | "requires": { 189 | "color-name": "1.1.3" 190 | } 191 | }, 192 | "color-name": { 193 | "version": "1.1.3", 194 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 195 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 196 | "dev": true 197 | }, 198 | "concat-map": { 199 | "version": "0.0.1", 200 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 201 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 202 | "dev": true 203 | }, 204 | "contains-path": { 205 | "version": "0.1.0", 206 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", 207 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", 208 | "dev": true 209 | }, 210 | "cross-spawn": { 211 | "version": "6.0.5", 212 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 213 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 214 | "dev": true, 215 | "requires": { 216 | "nice-try": "^1.0.4", 217 | "path-key": "^2.0.1", 218 | "semver": "^5.5.0", 219 | "shebang-command": "^1.2.0", 220 | "which": "^1.2.9" 221 | } 222 | }, 223 | "debug": { 224 | "version": "4.2.0", 225 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 226 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 227 | "dev": true, 228 | "requires": { 229 | "ms": "2.1.2" 230 | } 231 | }, 232 | "deep-is": { 233 | "version": "0.1.3", 234 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 235 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 236 | "dev": true 237 | }, 238 | "define-properties": { 239 | "version": "1.1.3", 240 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 241 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 242 | "dev": true, 243 | "requires": { 244 | "object-keys": "^1.0.12" 245 | } 246 | }, 247 | "doctrine": { 248 | "version": "3.0.0", 249 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 250 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 251 | "dev": true, 252 | "requires": { 253 | "esutils": "^2.0.2" 254 | } 255 | }, 256 | "emoji-regex": { 257 | "version": "7.0.3", 258 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 259 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 260 | "dev": true 261 | }, 262 | "error-ex": { 263 | "version": "1.3.2", 264 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 265 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 266 | "dev": true, 267 | "requires": { 268 | "is-arrayish": "^0.2.1" 269 | } 270 | }, 271 | "es-abstract": { 272 | "version": "1.17.7", 273 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", 274 | "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", 275 | "dev": true, 276 | "requires": { 277 | "es-to-primitive": "^1.2.1", 278 | "function-bind": "^1.1.1", 279 | "has": "^1.0.3", 280 | "has-symbols": "^1.0.1", 281 | "is-callable": "^1.2.2", 282 | "is-regex": "^1.1.1", 283 | "object-inspect": "^1.8.0", 284 | "object-keys": "^1.1.1", 285 | "object.assign": "^4.1.1", 286 | "string.prototype.trimend": "^1.0.1", 287 | "string.prototype.trimstart": "^1.0.1" 288 | } 289 | }, 290 | "es-to-primitive": { 291 | "version": "1.2.1", 292 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 293 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 294 | "dev": true, 295 | "requires": { 296 | "is-callable": "^1.1.4", 297 | "is-date-object": "^1.0.1", 298 | "is-symbol": "^1.0.2" 299 | } 300 | }, 301 | "escape-string-regexp": { 302 | "version": "1.0.5", 303 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 304 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 305 | "dev": true 306 | }, 307 | "eslint": { 308 | "version": "5.16.0", 309 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", 310 | "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", 311 | "dev": true, 312 | "requires": { 313 | "@babel/code-frame": "^7.0.0", 314 | "ajv": "^6.9.1", 315 | "chalk": "^2.1.0", 316 | "cross-spawn": "^6.0.5", 317 | "debug": "^4.0.1", 318 | "doctrine": "^3.0.0", 319 | "eslint-scope": "^4.0.3", 320 | "eslint-utils": "^1.3.1", 321 | "eslint-visitor-keys": "^1.0.0", 322 | "espree": "^5.0.1", 323 | "esquery": "^1.0.1", 324 | "esutils": "^2.0.2", 325 | "file-entry-cache": "^5.0.1", 326 | "functional-red-black-tree": "^1.0.1", 327 | "glob": "^7.1.2", 328 | "globals": "^11.7.0", 329 | "ignore": "^4.0.6", 330 | "import-fresh": "^3.0.0", 331 | "imurmurhash": "^0.1.4", 332 | "inquirer": "^6.2.2", 333 | "js-yaml": "^3.13.0", 334 | "json-stable-stringify-without-jsonify": "^1.0.1", 335 | "levn": "^0.3.0", 336 | "lodash": "^4.17.11", 337 | "minimatch": "^3.0.4", 338 | "mkdirp": "^0.5.1", 339 | "natural-compare": "^1.4.0", 340 | "optionator": "^0.8.2", 341 | "path-is-inside": "^1.0.2", 342 | "progress": "^2.0.0", 343 | "regexpp": "^2.0.1", 344 | "semver": "^5.5.1", 345 | "strip-ansi": "^4.0.0", 346 | "strip-json-comments": "^2.0.1", 347 | "table": "^5.2.3", 348 | "text-table": "^0.2.0" 349 | } 350 | }, 351 | "eslint-import-resolver-node": { 352 | "version": "0.3.4", 353 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", 354 | "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", 355 | "dev": true, 356 | "requires": { 357 | "debug": "^2.6.9", 358 | "resolve": "^1.13.1" 359 | }, 360 | "dependencies": { 361 | "debug": { 362 | "version": "2.6.9", 363 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 364 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 365 | "dev": true, 366 | "requires": { 367 | "ms": "2.0.0" 368 | } 369 | }, 370 | "ms": { 371 | "version": "2.0.0", 372 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 373 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 374 | "dev": true 375 | } 376 | } 377 | }, 378 | "eslint-module-utils": { 379 | "version": "2.6.0", 380 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", 381 | "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", 382 | "dev": true, 383 | "requires": { 384 | "debug": "^2.6.9", 385 | "pkg-dir": "^2.0.0" 386 | }, 387 | "dependencies": { 388 | "debug": { 389 | "version": "2.6.9", 390 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 391 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 392 | "dev": true, 393 | "requires": { 394 | "ms": "2.0.0" 395 | } 396 | }, 397 | "ms": { 398 | "version": "2.0.0", 399 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 400 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 401 | "dev": true 402 | } 403 | } 404 | }, 405 | "eslint-plugin-import": { 406 | "version": "2.22.1", 407 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", 408 | "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", 409 | "dev": true, 410 | "requires": { 411 | "array-includes": "^3.1.1", 412 | "array.prototype.flat": "^1.2.3", 413 | "contains-path": "^0.1.0", 414 | "debug": "^2.6.9", 415 | "doctrine": "1.5.0", 416 | "eslint-import-resolver-node": "^0.3.4", 417 | "eslint-module-utils": "^2.6.0", 418 | "has": "^1.0.3", 419 | "minimatch": "^3.0.4", 420 | "object.values": "^1.1.1", 421 | "read-pkg-up": "^2.0.0", 422 | "resolve": "^1.17.0", 423 | "tsconfig-paths": "^3.9.0" 424 | }, 425 | "dependencies": { 426 | "debug": { 427 | "version": "2.6.9", 428 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 429 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 430 | "dev": true, 431 | "requires": { 432 | "ms": "2.0.0" 433 | } 434 | }, 435 | "doctrine": { 436 | "version": "1.5.0", 437 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", 438 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", 439 | "dev": true, 440 | "requires": { 441 | "esutils": "^2.0.2", 442 | "isarray": "^1.0.0" 443 | } 444 | }, 445 | "ms": { 446 | "version": "2.0.0", 447 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 448 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 449 | "dev": true 450 | } 451 | } 452 | }, 453 | "eslint-scope": { 454 | "version": "4.0.3", 455 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", 456 | "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", 457 | "dev": true, 458 | "requires": { 459 | "esrecurse": "^4.1.0", 460 | "estraverse": "^4.1.1" 461 | } 462 | }, 463 | "eslint-utils": { 464 | "version": "1.4.3", 465 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 466 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 467 | "dev": true, 468 | "requires": { 469 | "eslint-visitor-keys": "^1.1.0" 470 | } 471 | }, 472 | "eslint-visitor-keys": { 473 | "version": "1.3.0", 474 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 475 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 476 | "dev": true 477 | }, 478 | "espree": { 479 | "version": "5.0.1", 480 | "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", 481 | "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", 482 | "dev": true, 483 | "requires": { 484 | "acorn": "^6.0.7", 485 | "acorn-jsx": "^5.0.0", 486 | "eslint-visitor-keys": "^1.0.0" 487 | } 488 | }, 489 | "esprima": { 490 | "version": "4.0.1", 491 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 492 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 493 | "dev": true 494 | }, 495 | "esquery": { 496 | "version": "1.3.1", 497 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 498 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 499 | "dev": true, 500 | "requires": { 501 | "estraverse": "^5.1.0" 502 | }, 503 | "dependencies": { 504 | "estraverse": { 505 | "version": "5.2.0", 506 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 507 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 508 | "dev": true 509 | } 510 | } 511 | }, 512 | "esrecurse": { 513 | "version": "4.3.0", 514 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 515 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 516 | "dev": true, 517 | "requires": { 518 | "estraverse": "^5.2.0" 519 | }, 520 | "dependencies": { 521 | "estraverse": { 522 | "version": "5.2.0", 523 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 524 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 525 | "dev": true 526 | } 527 | } 528 | }, 529 | "estraverse": { 530 | "version": "4.3.0", 531 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 532 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 533 | "dev": true 534 | }, 535 | "esutils": { 536 | "version": "2.0.3", 537 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 538 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 539 | "dev": true 540 | }, 541 | "external-editor": { 542 | "version": "3.1.0", 543 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 544 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 545 | "dev": true, 546 | "requires": { 547 | "chardet": "^0.7.0", 548 | "iconv-lite": "^0.4.24", 549 | "tmp": "^0.0.33" 550 | } 551 | }, 552 | "fast-deep-equal": { 553 | "version": "3.1.3", 554 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 555 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 556 | "dev": true 557 | }, 558 | "fast-json-stable-stringify": { 559 | "version": "2.1.0", 560 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 561 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 562 | "dev": true 563 | }, 564 | "fast-levenshtein": { 565 | "version": "2.0.6", 566 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 567 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 568 | "dev": true 569 | }, 570 | "figures": { 571 | "version": "2.0.0", 572 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 573 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 574 | "dev": true, 575 | "requires": { 576 | "escape-string-regexp": "^1.0.5" 577 | } 578 | }, 579 | "file-entry-cache": { 580 | "version": "5.0.1", 581 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 582 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 583 | "dev": true, 584 | "requires": { 585 | "flat-cache": "^2.0.1" 586 | } 587 | }, 588 | "find-up": { 589 | "version": "2.1.0", 590 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 591 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 592 | "dev": true, 593 | "requires": { 594 | "locate-path": "^2.0.0" 595 | } 596 | }, 597 | "flat-cache": { 598 | "version": "2.0.1", 599 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 600 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 601 | "dev": true, 602 | "requires": { 603 | "flatted": "^2.0.0", 604 | "rimraf": "2.6.3", 605 | "write": "1.0.3" 606 | } 607 | }, 608 | "flatted": { 609 | "version": "2.0.2", 610 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", 611 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", 612 | "dev": true 613 | }, 614 | "fs.realpath": { 615 | "version": "1.0.0", 616 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 617 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 618 | "dev": true 619 | }, 620 | "function-bind": { 621 | "version": "1.1.1", 622 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 623 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 624 | "dev": true 625 | }, 626 | "functional-red-black-tree": { 627 | "version": "1.0.1", 628 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 629 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 630 | "dev": true 631 | }, 632 | "get-intrinsic": { 633 | "version": "1.0.1", 634 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", 635 | "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", 636 | "dev": true, 637 | "requires": { 638 | "function-bind": "^1.1.1", 639 | "has": "^1.0.3", 640 | "has-symbols": "^1.0.1" 641 | } 642 | }, 643 | "glob": { 644 | "version": "7.1.6", 645 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 646 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 647 | "dev": true, 648 | "requires": { 649 | "fs.realpath": "^1.0.0", 650 | "inflight": "^1.0.4", 651 | "inherits": "2", 652 | "minimatch": "^3.0.4", 653 | "once": "^1.3.0", 654 | "path-is-absolute": "^1.0.0" 655 | } 656 | }, 657 | "globals": { 658 | "version": "11.12.0", 659 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 660 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 661 | "dev": true 662 | }, 663 | "graceful-fs": { 664 | "version": "4.2.4", 665 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 666 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 667 | "dev": true 668 | }, 669 | "has": { 670 | "version": "1.0.3", 671 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 672 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 673 | "dev": true, 674 | "requires": { 675 | "function-bind": "^1.1.1" 676 | } 677 | }, 678 | "has-flag": { 679 | "version": "3.0.0", 680 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 681 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 682 | "dev": true 683 | }, 684 | "has-symbols": { 685 | "version": "1.0.1", 686 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 687 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 688 | "dev": true 689 | }, 690 | "hosted-git-info": { 691 | "version": "2.8.9", 692 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", 693 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", 694 | "dev": true 695 | }, 696 | "iconv-lite": { 697 | "version": "0.4.24", 698 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 699 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 700 | "dev": true, 701 | "requires": { 702 | "safer-buffer": ">= 2.1.2 < 3" 703 | } 704 | }, 705 | "ignore": { 706 | "version": "4.0.6", 707 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 708 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 709 | "dev": true 710 | }, 711 | "import-fresh": { 712 | "version": "3.2.2", 713 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", 714 | "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", 715 | "dev": true, 716 | "requires": { 717 | "parent-module": "^1.0.0", 718 | "resolve-from": "^4.0.0" 719 | } 720 | }, 721 | "imurmurhash": { 722 | "version": "0.1.4", 723 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 724 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 725 | "dev": true 726 | }, 727 | "inflight": { 728 | "version": "1.0.6", 729 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 730 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 731 | "dev": true, 732 | "requires": { 733 | "once": "^1.3.0", 734 | "wrappy": "1" 735 | } 736 | }, 737 | "inherits": { 738 | "version": "2.0.4", 739 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 740 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 741 | "dev": true 742 | }, 743 | "inquirer": { 744 | "version": "6.5.2", 745 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", 746 | "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", 747 | "dev": true, 748 | "requires": { 749 | "ansi-escapes": "^3.2.0", 750 | "chalk": "^2.4.2", 751 | "cli-cursor": "^2.1.0", 752 | "cli-width": "^2.0.0", 753 | "external-editor": "^3.0.3", 754 | "figures": "^2.0.0", 755 | "lodash": "^4.17.12", 756 | "mute-stream": "0.0.7", 757 | "run-async": "^2.2.0", 758 | "rxjs": "^6.4.0", 759 | "string-width": "^2.1.0", 760 | "strip-ansi": "^5.1.0", 761 | "through": "^2.3.6" 762 | }, 763 | "dependencies": { 764 | "ansi-regex": { 765 | "version": "4.1.1", 766 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", 767 | "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", 768 | "dev": true 769 | }, 770 | "strip-ansi": { 771 | "version": "5.2.0", 772 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 773 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 774 | "dev": true, 775 | "requires": { 776 | "ansi-regex": "^4.1.0" 777 | } 778 | } 779 | } 780 | }, 781 | "is-arrayish": { 782 | "version": "0.2.1", 783 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 784 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 785 | "dev": true 786 | }, 787 | "is-callable": { 788 | "version": "1.2.2", 789 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", 790 | "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", 791 | "dev": true 792 | }, 793 | "is-core-module": { 794 | "version": "2.0.0", 795 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", 796 | "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", 797 | "dev": true, 798 | "requires": { 799 | "has": "^1.0.3" 800 | } 801 | }, 802 | "is-date-object": { 803 | "version": "1.0.2", 804 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 805 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 806 | "dev": true 807 | }, 808 | "is-fullwidth-code-point": { 809 | "version": "2.0.0", 810 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 811 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 812 | "dev": true 813 | }, 814 | "is-negative-zero": { 815 | "version": "2.0.0", 816 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", 817 | "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", 818 | "dev": true 819 | }, 820 | "is-regex": { 821 | "version": "1.1.1", 822 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", 823 | "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", 824 | "dev": true, 825 | "requires": { 826 | "has-symbols": "^1.0.1" 827 | } 828 | }, 829 | "is-string": { 830 | "version": "1.0.5", 831 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", 832 | "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", 833 | "dev": true 834 | }, 835 | "is-symbol": { 836 | "version": "1.0.3", 837 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 838 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 839 | "dev": true, 840 | "requires": { 841 | "has-symbols": "^1.0.1" 842 | } 843 | }, 844 | "isarray": { 845 | "version": "1.0.0", 846 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 847 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 848 | "dev": true 849 | }, 850 | "isexe": { 851 | "version": "2.0.0", 852 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 853 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 854 | "dev": true 855 | }, 856 | "js-tokens": { 857 | "version": "4.0.0", 858 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 859 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 860 | "dev": true 861 | }, 862 | "js-yaml": { 863 | "version": "3.14.0", 864 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 865 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 866 | "dev": true, 867 | "requires": { 868 | "argparse": "^1.0.7", 869 | "esprima": "^4.0.0" 870 | } 871 | }, 872 | "json-schema-traverse": { 873 | "version": "0.4.1", 874 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 875 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 876 | "dev": true 877 | }, 878 | "json-stable-stringify-without-jsonify": { 879 | "version": "1.0.1", 880 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 881 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 882 | "dev": true 883 | }, 884 | "json5": { 885 | "version": "1.0.1", 886 | "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", 887 | "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", 888 | "dev": true, 889 | "requires": { 890 | "minimist": "^1.2.0" 891 | } 892 | }, 893 | "levn": { 894 | "version": "0.3.0", 895 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 896 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 897 | "dev": true, 898 | "requires": { 899 | "prelude-ls": "~1.1.2", 900 | "type-check": "~0.3.2" 901 | } 902 | }, 903 | "load-json-file": { 904 | "version": "2.0.0", 905 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 906 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 907 | "dev": true, 908 | "requires": { 909 | "graceful-fs": "^4.1.2", 910 | "parse-json": "^2.2.0", 911 | "pify": "^2.0.0", 912 | "strip-bom": "^3.0.0" 913 | } 914 | }, 915 | "locate-path": { 916 | "version": "2.0.0", 917 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 918 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 919 | "dev": true, 920 | "requires": { 921 | "p-locate": "^2.0.0", 922 | "path-exists": "^3.0.0" 923 | } 924 | }, 925 | "lodash": { 926 | "version": "4.17.21", 927 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 928 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 929 | "dev": true 930 | }, 931 | "mimic-fn": { 932 | "version": "1.2.0", 933 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 934 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 935 | "dev": true 936 | }, 937 | "minimatch": { 938 | "version": "3.0.4", 939 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 940 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 941 | "dev": true, 942 | "requires": { 943 | "brace-expansion": "^1.1.7" 944 | } 945 | }, 946 | "minimist": { 947 | "version": "1.2.6", 948 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 949 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 950 | "dev": true 951 | }, 952 | "mkdirp": { 953 | "version": "0.5.5", 954 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 955 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 956 | "dev": true, 957 | "requires": { 958 | "minimist": "^1.2.5" 959 | } 960 | }, 961 | "ms": { 962 | "version": "2.1.2", 963 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 964 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 965 | "dev": true 966 | }, 967 | "mute-stream": { 968 | "version": "0.0.7", 969 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 970 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 971 | "dev": true 972 | }, 973 | "natural-compare": { 974 | "version": "1.4.0", 975 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 976 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 977 | "dev": true 978 | }, 979 | "nice-try": { 980 | "version": "1.0.5", 981 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 982 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 983 | "dev": true 984 | }, 985 | "normalize-package-data": { 986 | "version": "2.5.0", 987 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 988 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 989 | "dev": true, 990 | "requires": { 991 | "hosted-git-info": "^2.1.4", 992 | "resolve": "^1.10.0", 993 | "semver": "2 || 3 || 4 || 5", 994 | "validate-npm-package-license": "^3.0.1" 995 | } 996 | }, 997 | "object-inspect": { 998 | "version": "1.8.0", 999 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", 1000 | "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", 1001 | "dev": true 1002 | }, 1003 | "object-keys": { 1004 | "version": "1.1.1", 1005 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1006 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1007 | "dev": true 1008 | }, 1009 | "object.assign": { 1010 | "version": "4.1.2", 1011 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", 1012 | "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", 1013 | "dev": true, 1014 | "requires": { 1015 | "call-bind": "^1.0.0", 1016 | "define-properties": "^1.1.3", 1017 | "has-symbols": "^1.0.1", 1018 | "object-keys": "^1.1.1" 1019 | } 1020 | }, 1021 | "object.values": { 1022 | "version": "1.1.1", 1023 | "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", 1024 | "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", 1025 | "dev": true, 1026 | "requires": { 1027 | "define-properties": "^1.1.3", 1028 | "es-abstract": "^1.17.0-next.1", 1029 | "function-bind": "^1.1.1", 1030 | "has": "^1.0.3" 1031 | } 1032 | }, 1033 | "once": { 1034 | "version": "1.4.0", 1035 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1036 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1037 | "dev": true, 1038 | "requires": { 1039 | "wrappy": "1" 1040 | } 1041 | }, 1042 | "onetime": { 1043 | "version": "2.0.1", 1044 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1045 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1046 | "dev": true, 1047 | "requires": { 1048 | "mimic-fn": "^1.0.0" 1049 | } 1050 | }, 1051 | "optionator": { 1052 | "version": "0.8.3", 1053 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1054 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1055 | "dev": true, 1056 | "requires": { 1057 | "deep-is": "~0.1.3", 1058 | "fast-levenshtein": "~2.0.6", 1059 | "levn": "~0.3.0", 1060 | "prelude-ls": "~1.1.2", 1061 | "type-check": "~0.3.2", 1062 | "word-wrap": "~1.2.3" 1063 | } 1064 | }, 1065 | "os-tmpdir": { 1066 | "version": "1.0.2", 1067 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1068 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1069 | "dev": true 1070 | }, 1071 | "p-limit": { 1072 | "version": "1.3.0", 1073 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", 1074 | "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", 1075 | "dev": true, 1076 | "requires": { 1077 | "p-try": "^1.0.0" 1078 | } 1079 | }, 1080 | "p-locate": { 1081 | "version": "2.0.0", 1082 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1083 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1084 | "dev": true, 1085 | "requires": { 1086 | "p-limit": "^1.1.0" 1087 | } 1088 | }, 1089 | "p-try": { 1090 | "version": "1.0.0", 1091 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 1092 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", 1093 | "dev": true 1094 | }, 1095 | "parent-module": { 1096 | "version": "1.0.1", 1097 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1098 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1099 | "dev": true, 1100 | "requires": { 1101 | "callsites": "^3.0.0" 1102 | } 1103 | }, 1104 | "parse-json": { 1105 | "version": "2.2.0", 1106 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1107 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1108 | "dev": true, 1109 | "requires": { 1110 | "error-ex": "^1.2.0" 1111 | } 1112 | }, 1113 | "path-exists": { 1114 | "version": "3.0.0", 1115 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1116 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1117 | "dev": true 1118 | }, 1119 | "path-is-absolute": { 1120 | "version": "1.0.1", 1121 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1122 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1123 | "dev": true 1124 | }, 1125 | "path-is-inside": { 1126 | "version": "1.0.2", 1127 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1128 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 1129 | "dev": true 1130 | }, 1131 | "path-key": { 1132 | "version": "2.0.1", 1133 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1134 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 1135 | "dev": true 1136 | }, 1137 | "path-parse": { 1138 | "version": "1.0.7", 1139 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1140 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1141 | "dev": true 1142 | }, 1143 | "path-type": { 1144 | "version": "2.0.0", 1145 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 1146 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 1147 | "dev": true, 1148 | "requires": { 1149 | "pify": "^2.0.0" 1150 | } 1151 | }, 1152 | "pify": { 1153 | "version": "2.3.0", 1154 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1155 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1156 | "dev": true 1157 | }, 1158 | "pkg-dir": { 1159 | "version": "2.0.0", 1160 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", 1161 | "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", 1162 | "dev": true, 1163 | "requires": { 1164 | "find-up": "^2.1.0" 1165 | } 1166 | }, 1167 | "prelude-ls": { 1168 | "version": "1.1.2", 1169 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1170 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1171 | "dev": true 1172 | }, 1173 | "progress": { 1174 | "version": "2.0.3", 1175 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1176 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1177 | "dev": true 1178 | }, 1179 | "punycode": { 1180 | "version": "2.1.1", 1181 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1182 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1183 | "dev": true 1184 | }, 1185 | "read-pkg": { 1186 | "version": "2.0.0", 1187 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 1188 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 1189 | "dev": true, 1190 | "requires": { 1191 | "load-json-file": "^2.0.0", 1192 | "normalize-package-data": "^2.3.2", 1193 | "path-type": "^2.0.0" 1194 | } 1195 | }, 1196 | "read-pkg-up": { 1197 | "version": "2.0.0", 1198 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 1199 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 1200 | "dev": true, 1201 | "requires": { 1202 | "find-up": "^2.0.0", 1203 | "read-pkg": "^2.0.0" 1204 | } 1205 | }, 1206 | "regexpp": { 1207 | "version": "2.0.1", 1208 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 1209 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 1210 | "dev": true 1211 | }, 1212 | "resolve": { 1213 | "version": "1.18.1", 1214 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", 1215 | "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", 1216 | "dev": true, 1217 | "requires": { 1218 | "is-core-module": "^2.0.0", 1219 | "path-parse": "^1.0.6" 1220 | } 1221 | }, 1222 | "resolve-from": { 1223 | "version": "4.0.0", 1224 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1225 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1226 | "dev": true 1227 | }, 1228 | "restore-cursor": { 1229 | "version": "2.0.0", 1230 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1231 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1232 | "dev": true, 1233 | "requires": { 1234 | "onetime": "^2.0.0", 1235 | "signal-exit": "^3.0.2" 1236 | } 1237 | }, 1238 | "rimraf": { 1239 | "version": "2.6.3", 1240 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1241 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1242 | "dev": true, 1243 | "requires": { 1244 | "glob": "^7.1.3" 1245 | } 1246 | }, 1247 | "run-async": { 1248 | "version": "2.4.1", 1249 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", 1250 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", 1251 | "dev": true 1252 | }, 1253 | "rxjs": { 1254 | "version": "6.6.3", 1255 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", 1256 | "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", 1257 | "dev": true, 1258 | "requires": { 1259 | "tslib": "^1.9.0" 1260 | } 1261 | }, 1262 | "safer-buffer": { 1263 | "version": "2.1.2", 1264 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1265 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1266 | "dev": true 1267 | }, 1268 | "semver": { 1269 | "version": "5.7.1", 1270 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1271 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1272 | "dev": true 1273 | }, 1274 | "shebang-command": { 1275 | "version": "1.2.0", 1276 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1277 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1278 | "dev": true, 1279 | "requires": { 1280 | "shebang-regex": "^1.0.0" 1281 | } 1282 | }, 1283 | "shebang-regex": { 1284 | "version": "1.0.0", 1285 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1286 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1287 | "dev": true 1288 | }, 1289 | "signal-exit": { 1290 | "version": "3.0.3", 1291 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1292 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 1293 | "dev": true 1294 | }, 1295 | "slice-ansi": { 1296 | "version": "2.1.0", 1297 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1298 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1299 | "dev": true, 1300 | "requires": { 1301 | "ansi-styles": "^3.2.0", 1302 | "astral-regex": "^1.0.0", 1303 | "is-fullwidth-code-point": "^2.0.0" 1304 | } 1305 | }, 1306 | "spdx-correct": { 1307 | "version": "3.1.1", 1308 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", 1309 | "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", 1310 | "dev": true, 1311 | "requires": { 1312 | "spdx-expression-parse": "^3.0.0", 1313 | "spdx-license-ids": "^3.0.0" 1314 | } 1315 | }, 1316 | "spdx-exceptions": { 1317 | "version": "2.3.0", 1318 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", 1319 | "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", 1320 | "dev": true 1321 | }, 1322 | "spdx-expression-parse": { 1323 | "version": "3.0.1", 1324 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", 1325 | "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", 1326 | "dev": true, 1327 | "requires": { 1328 | "spdx-exceptions": "^2.1.0", 1329 | "spdx-license-ids": "^3.0.0" 1330 | } 1331 | }, 1332 | "spdx-license-ids": { 1333 | "version": "3.0.6", 1334 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", 1335 | "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", 1336 | "dev": true 1337 | }, 1338 | "sprintf-js": { 1339 | "version": "1.0.3", 1340 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1341 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1342 | "dev": true 1343 | }, 1344 | "string-width": { 1345 | "version": "2.1.1", 1346 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1347 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1348 | "dev": true, 1349 | "requires": { 1350 | "is-fullwidth-code-point": "^2.0.0", 1351 | "strip-ansi": "^4.0.0" 1352 | } 1353 | }, 1354 | "string.prototype.trimend": { 1355 | "version": "1.0.2", 1356 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", 1357 | "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", 1358 | "dev": true, 1359 | "requires": { 1360 | "define-properties": "^1.1.3", 1361 | "es-abstract": "^1.18.0-next.1" 1362 | }, 1363 | "dependencies": { 1364 | "es-abstract": { 1365 | "version": "1.18.0-next.1", 1366 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", 1367 | "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", 1368 | "dev": true, 1369 | "requires": { 1370 | "es-to-primitive": "^1.2.1", 1371 | "function-bind": "^1.1.1", 1372 | "has": "^1.0.3", 1373 | "has-symbols": "^1.0.1", 1374 | "is-callable": "^1.2.2", 1375 | "is-negative-zero": "^2.0.0", 1376 | "is-regex": "^1.1.1", 1377 | "object-inspect": "^1.8.0", 1378 | "object-keys": "^1.1.1", 1379 | "object.assign": "^4.1.1", 1380 | "string.prototype.trimend": "^1.0.1", 1381 | "string.prototype.trimstart": "^1.0.1" 1382 | } 1383 | } 1384 | } 1385 | }, 1386 | "string.prototype.trimstart": { 1387 | "version": "1.0.2", 1388 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", 1389 | "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", 1390 | "dev": true, 1391 | "requires": { 1392 | "define-properties": "^1.1.3", 1393 | "es-abstract": "^1.18.0-next.1" 1394 | }, 1395 | "dependencies": { 1396 | "es-abstract": { 1397 | "version": "1.18.0-next.1", 1398 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", 1399 | "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", 1400 | "dev": true, 1401 | "requires": { 1402 | "es-to-primitive": "^1.2.1", 1403 | "function-bind": "^1.1.1", 1404 | "has": "^1.0.3", 1405 | "has-symbols": "^1.0.1", 1406 | "is-callable": "^1.2.2", 1407 | "is-negative-zero": "^2.0.0", 1408 | "is-regex": "^1.1.1", 1409 | "object-inspect": "^1.8.0", 1410 | "object-keys": "^1.1.1", 1411 | "object.assign": "^4.1.1", 1412 | "string.prototype.trimend": "^1.0.1", 1413 | "string.prototype.trimstart": "^1.0.1" 1414 | } 1415 | } 1416 | } 1417 | }, 1418 | "strip-ansi": { 1419 | "version": "4.0.0", 1420 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1421 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1422 | "dev": true, 1423 | "requires": { 1424 | "ansi-regex": "^3.0.0" 1425 | } 1426 | }, 1427 | "strip-bom": { 1428 | "version": "3.0.0", 1429 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1430 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 1431 | "dev": true 1432 | }, 1433 | "strip-json-comments": { 1434 | "version": "2.0.1", 1435 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1436 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1437 | "dev": true 1438 | }, 1439 | "supports-color": { 1440 | "version": "5.5.0", 1441 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1442 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1443 | "dev": true, 1444 | "requires": { 1445 | "has-flag": "^3.0.0" 1446 | } 1447 | }, 1448 | "table": { 1449 | "version": "5.4.6", 1450 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1451 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1452 | "dev": true, 1453 | "requires": { 1454 | "ajv": "^6.10.2", 1455 | "lodash": "^4.17.14", 1456 | "slice-ansi": "^2.1.0", 1457 | "string-width": "^3.0.0" 1458 | }, 1459 | "dependencies": { 1460 | "ansi-regex": { 1461 | "version": "4.1.1", 1462 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", 1463 | "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", 1464 | "dev": true 1465 | }, 1466 | "string-width": { 1467 | "version": "3.1.0", 1468 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1469 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1470 | "dev": true, 1471 | "requires": { 1472 | "emoji-regex": "^7.0.1", 1473 | "is-fullwidth-code-point": "^2.0.0", 1474 | "strip-ansi": "^5.1.0" 1475 | } 1476 | }, 1477 | "strip-ansi": { 1478 | "version": "5.2.0", 1479 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1480 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1481 | "dev": true, 1482 | "requires": { 1483 | "ansi-regex": "^4.1.0" 1484 | } 1485 | } 1486 | } 1487 | }, 1488 | "text-table": { 1489 | "version": "0.2.0", 1490 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1491 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1492 | "dev": true 1493 | }, 1494 | "through": { 1495 | "version": "2.3.8", 1496 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1497 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1498 | "dev": true 1499 | }, 1500 | "tmp": { 1501 | "version": "0.0.33", 1502 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1503 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1504 | "dev": true, 1505 | "requires": { 1506 | "os-tmpdir": "~1.0.2" 1507 | } 1508 | }, 1509 | "tsconfig-paths": { 1510 | "version": "3.9.0", 1511 | "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", 1512 | "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", 1513 | "dev": true, 1514 | "requires": { 1515 | "@types/json5": "^0.0.29", 1516 | "json5": "^1.0.1", 1517 | "minimist": "^1.2.0", 1518 | "strip-bom": "^3.0.0" 1519 | } 1520 | }, 1521 | "tslib": { 1522 | "version": "1.14.1", 1523 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 1524 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", 1525 | "dev": true 1526 | }, 1527 | "type-check": { 1528 | "version": "0.3.2", 1529 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1530 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1531 | "dev": true, 1532 | "requires": { 1533 | "prelude-ls": "~1.1.2" 1534 | } 1535 | }, 1536 | "uri-js": { 1537 | "version": "4.4.0", 1538 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", 1539 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", 1540 | "dev": true, 1541 | "requires": { 1542 | "punycode": "^2.1.0" 1543 | } 1544 | }, 1545 | "validate-npm-package-license": { 1546 | "version": "3.0.4", 1547 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 1548 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 1549 | "dev": true, 1550 | "requires": { 1551 | "spdx-correct": "^3.0.0", 1552 | "spdx-expression-parse": "^3.0.0" 1553 | } 1554 | }, 1555 | "which": { 1556 | "version": "1.3.1", 1557 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1558 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1559 | "dev": true, 1560 | "requires": { 1561 | "isexe": "^2.0.0" 1562 | } 1563 | }, 1564 | "word-wrap": { 1565 | "version": "1.2.3", 1566 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1567 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1568 | "dev": true 1569 | }, 1570 | "wrappy": { 1571 | "version": "1.0.2", 1572 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1573 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1574 | "dev": true 1575 | }, 1576 | "write": { 1577 | "version": "1.0.3", 1578 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1579 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1580 | "dev": true, 1581 | "requires": { 1582 | "mkdirp": "^0.5.1" 1583 | } 1584 | } 1585 | } 1586 | } 1587 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "light-php", 3 | "scripts": { 4 | "lint": "eslint \"src/**/*.js\" " 5 | }, 6 | "author": "David Baqueiro Santerbas", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "eslint": "^5.3.0", 10 | "eslint-plugin-import": "^2.17.2" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /post-install.php: -------------------------------------------------------------------------------- 1 | ') ? true : false; 27 | 28 | if (!$enough_php_version || !empty($unloaded_dependencies)) { 29 | 30 | $log_file_path = "system/logs/incompatibility_errors.log"; 31 | 32 | if (!file_exists($log_file_path)) { 33 | $fileResource = fopen($log_file_path, "w"); 34 | fclose($fileResource); 35 | } 36 | 37 | if (!$enough_php_version) { 38 | error_log("Version of PHP not compatible!" . "\n", 3, $log_file_path); 39 | } 40 | 41 | foreach($unloaded_dependencies as $unloaded_dependency) { 42 | error_log("Missing PHP module!: " . $unloaded_dependency . "\n", 3, $log_file_path); 43 | } 44 | } 45 | 46 | require_once "./system/services/Util.php"; 47 | $config_string = file_get_contents("./system/config/config.php"); 48 | 49 | $util = new Service\Util(); 50 | $token_iv = $util->generateSimpleToken(16); 51 | $config_string = str_replace("ThisIsMySecretIv", $token_iv, $config_string); 52 | 53 | $token_pass = $util->generateSimpleToken(32); 54 | $config_string = str_replace("ThisIsMySecretPass", $token_pass, $config_string); 55 | 56 | file_put_contents("./system/config/config.php", $config_string); 57 | 58 | rename("./system/config/config.php", "./system/config/config.php"); 59 | rename("./system/config/ini.php", "./system/config/ini.php"); 60 | 61 | unlink("README.md"); 62 | unlink("LICENSE.md"); 63 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | # Allow all files except .php files 2 | 3 | 4 | allow from all 5 | 6 | 7 | 8 | order allow,deny 9 | deny from all 10 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | register(); 15 | $loader->addNamespace("Engine", "system/engine"); 16 | $loader->addNamespace("Service", "system/services"); 17 | 18 | // Environment 19 | require "system/config/environment.php"; 20 | 21 | // Bootstrap 22 | require "system/config/ini.php"; 23 | require "system/bootstrap.php"; 24 | 25 | // Start MVC 26 | $controller->$method(); 27 | -------------------------------------------------------------------------------- /public/www/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "globals": { 8 | "Atomics": "readonly", 9 | "SharedArrayBuffer": "readonly", 10 | "$": true, 11 | "window": true, 12 | "console": true, 13 | "e": true 14 | }, 15 | "parserOptions": { 16 | "ecmaVersion": 2018, 17 | "sourceType": "module" 18 | }, 19 | "rules": { 20 | "linebreak-style": ["error","unix" ], 21 | "quotes": ["error","double" ], 22 | "no-alert": "off", 23 | "prefer-destructuring": "off", 24 | "class-methods-use-this": "off", 25 | //"camelcase": ["error", {properties: "never"}] 26 | "camelcase": "off" 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /public/www/dist/console.css: -------------------------------------------------------------------------------- 1 | #console-div{overflow:hidden;background:white;width:100%;height:100px;position:fixed;bottom:0;left:0;z-index:100}div#console-body{overflow:auto;height:100%;width:100%}div.console-body-seccion.active{display:inline-block}div.console-body-seccion{display:none;height:100%;width:100%;padding:15px}div#error-console-top{height:30px;width:100%;background-color:grey}div#error-console-top:hover{cursor:n-resize}button.btn-console{height:27px;text-align:center;border-radius:2px 2px 0 0;border:none;margin-left:5px;margin-top:3px;background-color:#26a69a}button.btn-console:hover{cursor:pointer;background-color:#80cbc4}button.btn-console.active{background-color:white}div.right-console-info{float:right;height:35px;padding:3px 3px;color:white;line-height:1.5;font-family:BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Arial;font-weight:400}div.right-console-info span{position:relative;top:-6px} 2 | -------------------------------------------------------------------------------- /public/www/dist/console.js: -------------------------------------------------------------------------------- 1 | function makeResizableDiv(e,t){let o=0,n=document.querySelector(e),s=document.querySelector(t),l=parseFloat(getComputedStyle(n,null).getPropertyValue("height").replace("px",""));function c(e){if("error-console-top"===s.id){let t=l-(e.pageY-o);t>30&&t<600&&(n.style.height=t+"px",sessionStorage.setItem("console_position",t+"px"))}}function i(){window.removeEventListener("mousemove",c)}s.addEventListener("mousedown",t=>{l=document.querySelector(e).clientHeight,o=t.pageY,t.preventDefault(),window.addEventListener("mousemove",c),window.addEventListener("mouseup",i)})}makeResizableDiv("div#console-div","div#error-console-top");let buttons=document.querySelectorAll("button.enable");buttons.forEach((e,t)=>{e.addEventListener("click",e=>{document.querySelectorAll("div.console-body-seccion").forEach(e=>{e.classList.remove("active")}),document.querySelectorAll("button.btn-console").forEach(e=>{e.classList.remove("active")});let t=e.srcElement.className;t=t.split(/ /)[2],document.getElementById(t).className+=" active",e.srcElement.className+=" active"})}),sessionStorage.getItem("console_position")&&(document.querySelector("div#console-div").style.height=sessionStorage.getItem("console_position"),document.querySelector("body").style.paddingBottom="30px"); 2 | -------------------------------------------------------------------------------- /public/www/dist/google_icons.css: -------------------------------------------------------------------------------- 1 | /* fallback */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url(http://frame.localhost/src/view/www/fonts/google_icons.woff2) format('woff2'); 7 | } 8 | 9 | .material-icons { 10 | font-family: 'Material Icons'; 11 | font-weight: normal; 12 | font-style: normal; 13 | font-size: 24px; 14 | line-height: 1; 15 | letter-spacing: normal; 16 | text-transform: none; 17 | display: inline-block; 18 | white-space: nowrap; 19 | word-wrap: normal; 20 | direction: ltr; 21 | -webkit-font-feature-settings: 'liga'; 22 | -webkit-font-smoothing: antialiased; 23 | } 24 | 25 | /*# sourceMappingURL=/google_icons.de06537a.css.map */ 26 | -------------------------------------------------------------------------------- /public/www/dist/src.css: -------------------------------------------------------------------------------- 1 | body{font-size: 1.15rem;} 2 | -------------------------------------------------------------------------------- /public/www/src/console/console.css: -------------------------------------------------------------------------------- 1 | /* Console div */ 2 | #console-div { 3 | overflow: hidden; 4 | background: white; 5 | width: 100%; 6 | height: 100px; 7 | 8 | position: fixed; 9 | bottom: 0; 10 | left: 0; 11 | z-index: 100; 12 | } 13 | 14 | div#console-body{ 15 | overflow: auto; 16 | height: 100%; 17 | width: 100%; 18 | } 19 | 20 | div.console-body-seccion.active{ 21 | display: inline-block; 22 | } 23 | 24 | div.console-body-seccion{ 25 | display: none; 26 | height: 100%; 27 | width: 100%; 28 | padding: 15px; 29 | } 30 | 31 | /* console topbar */ 32 | div#error-console-top { 33 | height: 30px; 34 | width: 100%; 35 | background-color: grey; 36 | } 37 | 38 | div#error-console-top:hover { 39 | cursor: n-resize; 40 | } 41 | 42 | button.btn-console{ 43 | height: 27px; 44 | text-align: center; 45 | border-radius: 2px 2px 0px 0px; 46 | border: none; 47 | margin-left: 5px; 48 | margin-top: 3px; 49 | background-color: #26a69a; 50 | } 51 | 52 | button.btn-console:hover{ 53 | cursor: pointer; 54 | background-color: #80cbc4; 55 | } 56 | 57 | button.btn-console.active{ 58 | background-color: white; 59 | } 60 | 61 | div.right-console-info { 62 | float: right; 63 | height: 35px; 64 | padding: 3px 3px; 65 | color: white; 66 | 67 | line-height: 1.5; 68 | font-family: BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Arial; 69 | font-weight: normal; 70 | } 71 | 72 | div.right-console-info span{ 73 | position: relative; 74 | top: -6px; 75 | } 76 | -------------------------------------------------------------------------------- /public/www/src/console/console.js: -------------------------------------------------------------------------------- 1 | function makeResizableDiv(div_selector, top_div_selector) { 2 | let original_mouse_y = 0; 3 | const element = document.querySelector(div_selector); 4 | const resizer = document.querySelector(top_div_selector); 5 | let original_height = parseFloat(getComputedStyle(element, null).getPropertyValue("height").replace("px", "")); 6 | 7 | function resize(e) { 8 | if (resizer.id === "error-console-top") { 9 | const updated_height = original_height - (e.pageY - original_mouse_y); 10 | if (updated_height > 30 && updated_height < 600) { 11 | element.style.height = `${updated_height}px`; 12 | sessionStorage.setItem("console_position", `${updated_height}px`); 13 | } 14 | } 15 | } 16 | 17 | function stopResize() { 18 | window.removeEventListener("mousemove", resize); 19 | } 20 | 21 | resizer.addEventListener("mousedown", (e) => { 22 | original_height = document.querySelector(div_selector).clientHeight; 23 | original_mouse_y = e.pageY; 24 | e.preventDefault(); 25 | window.addEventListener("mousemove", resize); 26 | window.addEventListener("mouseup", stopResize); 27 | }); 28 | } 29 | 30 | makeResizableDiv("div#console-div", "div#error-console-top"); 31 | 32 | const buttons = document.querySelectorAll("button.enable"); 33 | buttons.forEach((value) => { 34 | value.addEventListener("click", (event) => { 35 | // Remove active div 36 | const console_bodies = document.querySelectorAll("div.console-body-seccion"); 37 | console_bodies.forEach((console_body) => { 38 | console_body.classList.remove("active"); 39 | }); 40 | 41 | // Remove active buttons 42 | const console_buttons = document.querySelectorAll("button.btn-console"); 43 | console_buttons.forEach((console_button) => { 44 | console_button.classList.remove("active"); 45 | }); 46 | 47 | // Add active div 48 | let id_div_to_enable = event.srcElement.className; 49 | id_div_to_enable = id_div_to_enable.split(/ /)[2]; 50 | document.getElementById(id_div_to_enable).className += " active"; 51 | 52 | // Add active button 53 | // event.srcElement.className += " active"; 54 | const src_element = event.srcElement; 55 | src_element.className += " active"; 56 | }); 57 | }); 58 | 59 | // DOM loaded 60 | if (sessionStorage.getItem("console_position")) { 61 | document.querySelector("div#console-div").style.height = sessionStorage.getItem("console_position"); 62 | document.querySelector("body").style.paddingBottom = "30px"; 63 | } 64 | -------------------------------------------------------------------------------- /public/www/src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/public/www/src/images/logo.png -------------------------------------------------------------------------------- /public/www/src/images/welcome/1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/public/www/src/images/welcome/1.PNG -------------------------------------------------------------------------------- /public/www/src/images/welcome/2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/public/www/src/images/welcome/2.PNG -------------------------------------------------------------------------------- /public/www/src/images/welcome/3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/public/www/src/images/welcome/3.PNG -------------------------------------------------------------------------------- /public/www/src/images/welcome/4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/public/www/src/images/welcome/4.PNG -------------------------------------------------------------------------------- /public/www/src/site/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 1.15rem; 3 | } 4 | -------------------------------------------------------------------------------- /src/common/controller/CommonController.php: -------------------------------------------------------------------------------- 1 | "Error! The Page: " . $this->config->get("url_action") . " couldn't be found!", 21 | "body" => "The page which you are looking for its not available, try searching in another place or try this later." 22 | ]; 23 | 24 | $this->output->load("common/PageNotFound", $data); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/common/view/Console.php: -------------------------------------------------------------------------------- 1 | console->convert(memory_get_usage(true)); 10 | 11 | // Time 12 | $time_script = microtime(true) - $this->console->max_execution_time; 13 | $time_script = round($time_script, 4); 14 | 15 | // Cache 16 | $cache = $this->cache_version; 17 | ?> 18 | 19 | 20 | 21 |
22 | 23 |
24 | 25 | 26 | 27 |
28 | ms 29 | access_time 30 |
31 |
32 | 33 | storage 34 | | 35 |
36 | 37 |
38 | 39 |
40 |
41 | console::$console_execution_traces as $trace_message) { 43 | if ($trace_message["type"] === "error") { 44 | echo "

error" . $trace_message["message"] . "

"; 45 | } 46 | if ($trace_message["type"] === "warning") { 47 | echo "

warning" . $trace_message["message"] . "

"; 48 | } 49 | if ($trace_message["type"] === "query") { 50 | echo "

dns" . $trace_message["message"] . "

"; 51 | } 52 | if ($trace_message["type"] === "debug_info") { 53 | if (gettype($trace_message["message"]) === "array" || gettype($trace_message["message"]) === "object") { 54 | echo "
";
55 |                         print_r($trace_message["message"]);
56 |                         echo "
"; 57 | } else { 58 | echo "

" . $trace_message["message"] . "

"; 59 | } 60 | } 61 | } 62 | ?> 63 |


64 |
65 | 66 |
67 | console->getServerInfo(); 69 | new Ospinto\dBug($server_info); 70 | ?> 71 |


72 |
73 | 74 |
75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/common/view/Footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | is_debug_console_enabled) { 8 | include "src/common/view/Console.php"; 9 | } 10 | ?> 11 | 12 |

13 | 14 | 27 | 28 | 29 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/common/view/Header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Light PHP 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | output_styles as $style_file) { 21 | echo $style_file; 22 | } 23 | foreach ($this->output_scripts as $script_file) { 24 | echo $script_file; 25 | } 26 | ?> 27 | 28 | 44 | 45 | 52 | 53 |
54 |
55 | -------------------------------------------------------------------------------- /src/common/view/PageNotFoundView.php: -------------------------------------------------------------------------------- 1 |

Not found!

2 | 3 |

4 |

5 | -------------------------------------------------------------------------------- /src/product/controller/ProductController.php: -------------------------------------------------------------------------------- 1 | getAllProducts(); 21 | $product_data = ["product_name" => "test product", "product_price" => "9000€", "product_description" => "this is a test product"]; 22 | 23 | $this->output->load("product/ProductDescription", $product_data); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/product/model/ProductModel.php: -------------------------------------------------------------------------------- 1 | database->query("SELECT * FROM `product`"); 18 | } 19 | 20 | /** 21 | * Sample function: get product by id 22 | * 23 | * @param int $prod_id product id for searching 24 | */ 25 | public function getProductById(int $prod_id): array 26 | { 27 | return $this->database->query("SELECT * FROM `product` WHERE id = :prod_id", array(":prod_id" => $prod_id)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/product/view/ProductDescriptionView.php: -------------------------------------------------------------------------------- 1 |

Sample


2 | 3 | product info: 4 | 5 | 10 | -------------------------------------------------------------------------------- /src/welcome/controller/WelcomeController.php: -------------------------------------------------------------------------------- 1 | console->addDebugInfo("welcome page loaded ;)"); 20 | 21 | // $cont = 5 / 0; // intentional exception to display it in the debug console ;) 22 | 23 | $this->console->addDebugInfo([1, "my_value", "hi there! "]); 24 | 25 | $this->output->addJs("products"); 26 | 27 | $this->output->load("welcome/Welcome"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/welcome/view/WelcomeView.php: -------------------------------------------------------------------------------- 1 |

Welcome Light-PHP 2.0

2 |

Your application it's ready, Documentation

3 | -------------------------------------------------------------------------------- /system/bootstrap.php: -------------------------------------------------------------------------------- 1 | $config_value) { 23 | $config->set($key, $config_value); 24 | } 25 | 26 | // Config PHP values 27 | $ini_variables = include "system/config/ini.php"; 28 | foreach ($ini_variables[getenv("ENVIRONMENT")] as $ini_name => $ini_value) { 29 | ini_set($ini_name, $ini_value); 30 | } 31 | 32 | // complete namespace mapping 33 | $modules = scandir("src/"); 34 | array_shift($modules); 35 | array_shift($modules); 36 | foreach ($modules as $module) { 37 | $loader->addNamespace(ucfirst($module), "src/" . $module . "/controller"); 38 | $loader->addNamespace(ucfirst($module), "src/" . $module . "/model"); 39 | } 40 | 41 | 42 | $console = new Console($config->get("system_execution_time")); 43 | 44 | $util = new Util(); 45 | 46 | $output = new Output($config->get("template_header"), $config->get("template_footer"), $config->get("system_cache_version"), $config->get('system_debug_console'), $console); 47 | 48 | $logger = new Logger($config->get("log_path_error"), $config->get("log_path_notice"), $config->get("log_path_warning"), $config->get("log_path_unknown_error"), $console); 49 | 50 | $session_handler = new SecureSession($config->get("session_iv"), $config->get("session_key"), $config->get("session_encrypt_method")); 51 | 52 | $session = new Session($session_handler, $config->get("session_name")); 53 | 54 | $database = new Database(false, $config->get("db_host"), $config->get("db_user"), $config->get("db_name"), $config->get("db_pass"), $console); 55 | 56 | // Init database 57 | if ($config->get('database_auto_init')) { 58 | $database->initialize(); 59 | } 60 | 61 | // Init session 62 | $session->start(); 63 | 64 | // If it's expired or fingerprint changed, reset the session 65 | if (!$session->isValid()) { 66 | $session->forget(); 67 | } 68 | 69 | // CSRF token (forms security) 70 | if ($session->get("csrf_token") === null) { 71 | $session->set("csrf_token", $util->generateCSRFToken()); 72 | $session->set("CSRF_input", ""); 73 | } 74 | 75 | if (!$config->get("allow_forms_without_csrf_input")) { 76 | $util->checkPostCSRFToken(); 77 | } 78 | 79 | // Error handler 80 | set_error_handler(array($logger,"myErrorHandler"), E_ALL); 81 | error_reporting(E_ALL); 82 | 83 | // Exception handler 84 | set_exception_handler(array($logger,"myExceptionHandler")); 85 | 86 | // XSS, scape characters, SQL Injection 87 | $util->arrayWalkRecursiveReferential($_GET, array($util, "preventXSS")); 88 | $util->arrayWalkRecursiveReferential($_GET, "trim"); 89 | $util->arrayWalkRecursiveReferential($_GET, array($util, "escape")); 90 | 91 | $util->arrayWalkRecursiveReferential($_POST, array($util, "preventXSS")); 92 | $util->arrayWalkRecursiveReferential($_POST, "trim"); 93 | $util->arrayWalkRecursiveReferential($_POST, array($util, "escape")); 94 | 95 | // Add container entries 96 | $container = new Container(); 97 | $container->set("config", $config); 98 | $container->set("console", $console); 99 | $container->set("database", $database); 100 | $container->set("logger", $logger); 101 | $container->set("output", $output); 102 | $container->set("session", $session); 103 | $container->set("util", $util); 104 | 105 | // Timezone 106 | date_default_timezone_set($config->get("system_default_time_zone")); 107 | 108 | // Import the controller 109 | $router = new Router(); 110 | $path_data = $router->parsePath(); 111 | 112 | $method = $path_data["method"]; 113 | require_once $path_data["file"]; 114 | $controller = new $path_data["class"](); 115 | -------------------------------------------------------------------------------- /system/config/config.php: -------------------------------------------------------------------------------- 1 | [ 16 | "database_host" => "", 17 | "database_user" => "", 18 | "database_pass" => "", 19 | "dabatase_name" => "", 20 | "database_auto_init" => false, 21 | 22 | "session_name" => "session", 23 | "session_encrypt_method" => "aes-256-cbc", 24 | "session_iv" => "ThisIsMySecretIv", // Generated in the install process 25 | "session_key" => "ThisIsMySecretPass", // Generated in the install process 26 | 27 | "email_host" => "", 28 | "email_name" => "", 29 | "email_pass" => "", 30 | "email_port" => "", 31 | "email_from" => "", 32 | 33 | "system_default_time_zone" => "Europe/Madrid", 34 | "system_debug_console" => true, 35 | "system_execution_time" => microtime(true), 36 | "system_cache_version" => 0001, // Refresh frontend cache 37 | "system_allow_forms_without_csrf" => false, 38 | 39 | "template_header" => "src/common/view/Header.php", 40 | "template_footer" => "src/common/view/Footer.php", 41 | 42 | "log_path_warning" => "system/logs/warning.log", 43 | "log_path_error" => "system/logs/error.log", 44 | "log_path_notice" => "system/logs/notice.log", 45 | "log_path_unknown_error" => "system/logs/unknown_error.log" 46 | ], 47 | 48 | "production" => [ 49 | "database_host" => "", 50 | "database_user" => "", 51 | "database_pass" => "", 52 | "dabatase_name" => "", 53 | "database_auto_init" => true, 54 | 55 | "session_name" => "session", 56 | "session_encrypt_method" => "aes-256-cbc", 57 | "session_iv" => "ThisIsMySecretIv", // Generated in the install process 58 | "session_key" => "ThisIsMySecretPass", // Generated in the install process 59 | 60 | "email_host" => "", 61 | "email_name" => "", 62 | "email_pass" => "", 63 | "email_port" => "", 64 | "email_from" => "", 65 | 66 | "system_default_time_zone" => "Europe/Madrid", 67 | "system_debug_console" => false, 68 | "system_execution_time" => microtime(true), 69 | "system_cache_version" => 0001, // Refresh frontend cache 70 | "system_allow_forms_without_csrf" => false, 71 | 72 | "template_header" => "src/common/view/Header.php", 73 | "template_footer" => "src/common/view/Footer.php", 74 | 75 | "log_path_warning" => "system/logs/warning.log", 76 | "log_path_error" => "system/logs/error.log", 77 | "log_path_notice" => "system/logs/notice.log", 78 | "log_path_unknown_error" => "system/logs/unknown_error.log" 79 | ] 80 | ]; 81 | -------------------------------------------------------------------------------- /system/config/environment.php: -------------------------------------------------------------------------------- 1 | [ 9 | "display_errors" => "On", 10 | "log_errors" => 1, 11 | 12 | "session.auto_start" => "Off", 13 | "session.use_only_cookies" => true, 14 | "session.use_cookies" => "On", 15 | "session.use_trans_sid" => "Off", 16 | "session.cookie_httponly" => "On", 17 | "session.cookie_lifetime" => 90, 18 | "session.gc_maxlifetime" => 90, 19 | "session.gc_probability" => 1, 20 | "session.gc_divisor" => 100, 21 | 22 | "expose_php" => "On", 23 | "default_charset" => "UTF-8", 24 | "max_input_time" => 200, 25 | "memory_limit" => "64M", 26 | "max_execution_time" => 7200, 27 | "upload_max_filesize" => "200M", 28 | "mysql.connect_timeout" => 40, 29 | ], 30 | "production" => [ 31 | "display_errors" => "Off", 32 | "log_errors" => 0, 33 | 34 | "session.auto_start" => "Off", 35 | "session.use_only_cookies" => true, 36 | "session.use_cookies" => "On", 37 | "session.use_trans_sid" => "Off", 38 | "session.cookie_httponly" => "On", 39 | "session.cookie_lifetime" => 90, 40 | "session.gc_maxlifetime" => 90, 41 | "session.gc_probability" => 1, 42 | "session.gc_divisor" => 100, 43 | 44 | "expose_php" => "Off", 45 | "default_charset" => "UTF-8", 46 | "max_input_time" => 100, 47 | "memory_limit" => "32M", 48 | "max_execution_time" => 3600, 49 | "upload_max_filesize" => "99M", 50 | "mysql.connect_timeout" => 20, 51 | ] 52 | ]; 53 | 54 | 55 | // Common settings 56 | // ini_set("magic_quotes_gpc", "Off"); 57 | // ini_set("register_globals", "Off"); 58 | // ini_set("safe_mode", "Off"); 59 | // ini_set("session.cookie_lifetime", 3600); 60 | // ini_set("allow_url_fopen", "On"); 61 | // ini_set("error_reporting", E_ALL); 62 | -------------------------------------------------------------------------------- /system/config/routes.php: -------------------------------------------------------------------------------- 1 | url 5 | * Array value => folder/controller-class/method (index method if none specified) 6 | */ 7 | 8 | return [ 9 | "/" => "welcome/welcome/index", 10 | "/welcome" => "welcome/welcome/index", 11 | "/product" => "product/product/samplePage" 12 | ]; 13 | -------------------------------------------------------------------------------- /system/engine/AutoLoader.php: -------------------------------------------------------------------------------- 1 | prefixes[$prefix]) === false) { 44 | $this->prefixes[$prefix] = array(); 45 | } 46 | 47 | if ($prepend) { 48 | array_unshift($this->prefixes[$prefix], $base_dir); 49 | } else { 50 | array_push($this->prefixes[$prefix], $base_dir); 51 | } 52 | } 53 | 54 | /** 55 | * Loads the class file for a given class name. 56 | * 57 | * @param string $class The fully-qualified class name. 58 | * 59 | * @return mixed The mapped file name on success, or boolean false on 60 | * failure. 61 | */ 62 | public function loadClass(string $class) 63 | { 64 | $prefix = $class; 65 | 66 | while (false !== $pos = strrpos($prefix, '\\')) { 67 | $prefix = substr($class, 0, $pos + 1); 68 | $relative_class = substr($class, $pos + 1); 69 | $mapped_file = $this->loadMappedFile($prefix, $relative_class); 70 | 71 | if ($mapped_file) { 72 | return $mapped_file; 73 | } 74 | 75 | $prefix = rtrim($prefix, '\\'); 76 | } 77 | 78 | return false; 79 | } 80 | 81 | /** 82 | * Load the mapped file for a namespace prefix and relative class. 83 | * 84 | * @param string $prefix The namespace prefix. 85 | * @param string $relative_class The relative class name. 86 | * 87 | * @return mixed Boolean false if no mapped file can be loaded, or the 88 | * name of the mapped file that was loaded. 89 | */ 90 | protected function loadMappedFile(string $prefix, $relative_class) 91 | { 92 | if (isset($this->prefixes[$prefix]) === false) { 93 | return false; 94 | } 95 | 96 | foreach ($this->prefixes[$prefix] as $base_dir) { 97 | $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; 98 | 99 | if ($this->requireFile($file)) { 100 | return $file; 101 | } 102 | } 103 | 104 | return false; 105 | } 106 | 107 | /** 108 | * If a file exists, require it from the file system. 109 | * 110 | * @param string $file The file to require. 111 | * 112 | * @return bool True if the file exists, false if not. 113 | */ 114 | protected function requireFile(string $file): bool 115 | { 116 | if (file_exists($file)) { 117 | include $file; 118 | return true; 119 | } 120 | return false; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /system/engine/Base.php: -------------------------------------------------------------------------------- 1 | get($dependency_name); 15 | } 16 | 17 | public function __set($dependency_name, $dependency): void 18 | { 19 | $this->set($dependency_name, $dependency); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /system/engine/Container.php: -------------------------------------------------------------------------------- 1 | getPathFromSeoUrl($url_action); 29 | } 30 | 31 | $this->action = $url_action; 32 | $this->path = $path; 33 | } 34 | 35 | /** 36 | * Parses the url, and sets the controller, class and method based in that 37 | */ 38 | public function parsePath(): array 39 | { 40 | $url_split = explode('/', $this->path); 41 | 42 | $file = "src/" . $url_split[0] . '/controller/' . ucfirst($url_split[1]) . 'Controller.php'; 43 | $class = ucfirst($url_split[1]) . "\\" . ucfirst($url_split[1]) . 'Controller'; 44 | $method = $url_split[2]; 45 | 46 | if (!$this->isValidPath($file, $class, $method)) { 47 | $file = 'src/common/controller/CommonController.php'; 48 | $method = 'pageNotFound'; 49 | $class = "Common\\CommonController"; 50 | } 51 | 52 | return [ 53 | "file" => $file, 54 | "method" => $method, 55 | "class" => $class 56 | ]; 57 | } 58 | 59 | /** 60 | * Checks wether the file, class and method exist, if not, uses the error controller 61 | */ 62 | private function isValidPath($file, $class, $method): bool 63 | { 64 | $is_controller_ok = true; 65 | if (!file_exists($file)) { 66 | echo 'aaaa'; 67 | echo $file; 68 | $is_controller_ok = false; 69 | } 70 | 71 | if (method_exists($class, $method) === false) { 72 | $is_controller_ok = false; 73 | } 74 | 75 | return $is_controller_ok; 76 | } 77 | 78 | /** 79 | * Search the seo url entered in the function's parameter, in the routes.php file, and sets 80 | * controller, class and method associated to that seo url 81 | * 82 | * @param string $url_action seo url to search 83 | */ 84 | private function getPathFromSeoUrl(string $url_action): string 85 | { 86 | $routes = include "system/config/routes.php"; 87 | 88 | if (in_array($url_action, array_keys($routes))) { 89 | return $routes[$url_action]; 90 | } else { 91 | return "common/common/PageNotFound"; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /system/engine/SecureSession.php: -------------------------------------------------------------------------------- 1 | iv = $session_iv; 28 | $this->key = $session_key; 29 | $this->encrypt_method = $session_encrypt_method; 30 | } 31 | 32 | /** 33 | * Read the encrypted values 34 | * 35 | * @param string $session_id session id to read the values 36 | * 37 | * @return array 38 | */ 39 | public function read($session_id) :string { 40 | $data = parent::read($session_id); 41 | $data = (string) openssl_decrypt($data, $this->encrypt_method, $this->key, 0, $this->iv); 42 | return $data; 43 | } 44 | 45 | /** 46 | * Encrypt and save session values 47 | * 48 | * @param string $session_id session to write in the information 49 | * @param string $data data to write into the session id 50 | * 51 | * @return array 52 | */ 53 | public function write($session_id, $data): bool { 54 | $encrypted_data = openssl_encrypt($data, $this->encrypt_method, $this->key, 0, $this->iv); 55 | return parent::write($session_id, $encrypted_data); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /system/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakeiro/Light-PHP/9908ea4de877d922da6e0885f7e7cba8eedd29d2/system/logs/.gitkeep -------------------------------------------------------------------------------- /system/services/Config.php: -------------------------------------------------------------------------------- 1 | data[$key] = $value; 25 | } 26 | 27 | /** 28 | * Gets the value 29 | * 30 | * @param string $key name of the key to get the value 31 | * 32 | * @return array|string|int|null 33 | */ 34 | public function get(string $key) 35 | { 36 | return isset($this->data[$key]) ? $this->data[$key] : null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /system/services/Console.php: -------------------------------------------------------------------------------- 1 | max_execution_time = $max_execution_time; 20 | } 21 | 22 | /** 23 | * Adds the SQL query to show it in the console 24 | * 25 | * @param string $query SQL query for display in the debug console 26 | * 27 | */ 28 | public function addQuery(string $query): void 29 | { 30 | Console::$db_queries[] = $query; 31 | 32 | $this->addStackTrace($query, "query"); 33 | } 34 | 35 | /** 36 | * Adds an error message to the debug console 37 | * 38 | * @param string $error String Errors message to display 39 | * 40 | */ 41 | public function addError(string $error): void 42 | { 43 | Console::$errors[] = $error; 44 | 45 | $this->addStackTrace($error, "error"); 46 | } 47 | 48 | /** 49 | * Adds a warning message to the debug console 50 | * 51 | * @param string $warning warning message to display in the debug console 52 | * 53 | */ 54 | public function addWarning(string $warning): void 55 | { 56 | Console::$warnings[] = $warning; 57 | 58 | $this->addStackTrace($warning, "warning"); 59 | } 60 | 61 | /** 62 | * Displays the variable passed in the parameter in the debug console, if an Array, or Object is passed 63 | * this output all the array/object content 64 | * 65 | * @param string|int|object|array|boolean $debug_message variable to display in the debug console 66 | * 67 | */ 68 | public function addDebugInfo($debug_message): void 69 | { 70 | Console::$debug_info[] = $debug_message; 71 | 72 | $this->addStackTrace($debug_message, "debug_info"); 73 | } 74 | 75 | /** 76 | * Adds a message to display into the debug console 77 | * 78 | * @param $message Message to add into the debug console 79 | * @param string $type Type of the message added 80 | * 81 | */ 82 | public function addStackTrace($message, string $type): void 83 | { 84 | Console::$console_execution_traces[] = array("message" => $message, "type" => $type); 85 | } 86 | 87 | /** 88 | * Gets all the server information, including session settings, cookie, server settings 89 | * date and time information and much more to display it into the debug console in a friendly way ;) 90 | * 91 | */ 92 | public function getServerInfo() 93 | { 94 | $entitiesToUtf8 = function ($input) { 95 | // http://php.net/manual/en/function.html-entity-decode.php#104617 96 | return preg_replace_callback( 97 | "/(&#[0-9]+;)/", 98 | function ($m) { 99 | return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); 100 | }, 101 | $input 102 | ); 103 | }; 104 | $plainText = function ($input) use ($entitiesToUtf8) { 105 | return trim(html_entity_decode($entitiesToUtf8(strip_tags($input)))); 106 | }; 107 | $titlePlainText = function ($input) use ($plainText) { 108 | return '# ' . $plainText($input); 109 | }; 110 | 111 | ob_start(); 112 | phpinfo(-1); 113 | 114 | $phpinfo = array('phpinfo' => array()); 115 | 116 | // Strip everything after the

Configuration

tag (other h1's) 117 | if (!preg_match('#(.*]*>\s*Configuration.*)(?:)?(.*?)(?:<\/a>)?<\/h2>)|' . 127 | '(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#s', 128 | $input, 129 | $matches, 130 | PREG_SET_ORDER 131 | ) 132 | ) { 133 | foreach ($matches as $match) { 134 | $fn = strpos($match[0], '_host = $host; 20 | $this->_user = $user; 21 | $this->_db_name = $db_name; 22 | $this->_pass = $pass; 23 | $this->_console = $console; 24 | } 25 | 26 | /** 27 | * Executes the SQL query in the 1st param, and replaces the values in it using the array in the second param 28 | * 29 | * @param string $sql_query SQL query statement to execute 30 | * @param array $params array containing all the values to replace in the $sql_query variable to do safe prepare statements 31 | * 32 | * @return array|boolean 33 | */ 34 | public function query(string $sql_query, array $params = array()) 35 | { 36 | $this->_console->addQuery($sql_query); 37 | 38 | $smtp = $this->_connection->prepare($sql_query); 39 | $smtp->setFetchMode(\PDO::FETCH_ASSOC); 40 | $query = $smtp->execute($params); 41 | 42 | $data = array(); 43 | 44 | if ($query) { 45 | while ($row = $smtp->fetch()) { 46 | $data[] = $row; 47 | } 48 | $smtp = null; 49 | 50 | if (count($data) === 1) { 51 | $data = $data[0]; 52 | } 53 | if (count($data) === 0) { 54 | $data = false; 55 | } 56 | 57 | if (strpos($sql_query, "INSERT INTO") !== false) { 58 | $data = $this->_connection->lastInsertId(); 59 | } 60 | } 61 | 62 | return $data; 63 | } 64 | 65 | /** 66 | * Get the last id of the inserted value in the database 67 | */ 68 | public function getLastId(): int 69 | { 70 | return $this->_connection->lastInsertId(); 71 | } 72 | 73 | /** 74 | * Initializes the database connections 75 | */ 76 | public function initialize(): void 77 | { 78 | try { 79 | $temp_connection = new \PDO("mysql:host=" . $this->_host . ";port=3306;dbname=" . $this->_db_name, $this->_user, $this->_pass); 80 | $temp_connection->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); // true prepare statements 81 | 82 | $temp_connection->exec("SET NAMES 'utf8'"); 83 | $temp_connection->exec("SET CHARACTER SET utf8"); 84 | $temp_connection->exec("SET CHARACTER_SET_CONNECTION=utf8"); 85 | 86 | $this->_connection = $temp_connection; 87 | } catch (\Throwable $th) { 88 | $this->_console->addDebugInfo("Error loading database"); 89 | } 90 | } 91 | 92 | /** 93 | * Kills the database connection, more info: https://php.net/pdo.connections 94 | */ 95 | public function destruct(): void 96 | { 97 | //More info about this here: https://php.net/pdo.connections 98 | //KILL CONNECTION_ID() 99 | $this->_connection->query('SELECT pg_terminate_backend(pg_backend_pid());'); 100 | $this->_connection = null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /system/services/Logger.php: -------------------------------------------------------------------------------- 1 | _error_log_path = $error_log_path; 26 | $this->_notice_log_path = $notice_log_path; 27 | $this->_warning_log_path = $warning_log_path; 28 | $this->_unknown_errors_log_path = $unknown_errors_log_path; 29 | $this->_console = $console; 30 | } 31 | 32 | /** 33 | * Error handler, parses the error, and wether it's a warning, exception, notice or something else, executes the 34 | * correct callback 35 | * 36 | * @param string $errno Error name 37 | * @param string $error_string Error description 38 | * @param string $error_file File of the error 39 | * @param string $error_line Line of the error 40 | */ 41 | public function myErrorHandler(string $errno, string $error_string, string $error_file, string $error_line): void 42 | { 43 | $error = "Unknown"; 44 | if ($errno === E_NOTICE || $errno === E_USER_NOTICE) { 45 | $error = 'Notice'; 46 | } 47 | if ($errno === E_WARNING || $errno === E_USER_WARNING) { 48 | $error = 'Warning'; 49 | } 50 | if ($errno === E_ERROR || $errno === E_USER_ERROR) { 51 | $error = 'Fatal Error'; 52 | } 53 | 54 | $error_string_log = " *" . $error . "* " . $error_string . "\n - file: " . $error_file . "\n - on line: " . $error_line . "\n\n"; 55 | $error_string_log = addslashes($error_string_log); 56 | 57 | if ($error === "Warning") { 58 | $this->warningHandler($error_string_log); 59 | } 60 | 61 | if ($error === "Notice") { 62 | $this->noticeHandler($error_string_log); 63 | } 64 | 65 | if ($error === "Fatal Error") { 66 | $this->errorHandler($error_string_log); 67 | } 68 | 69 | if ($error === "Unknown") { 70 | $this->noticeHandler($error_string_log); 71 | } 72 | } 73 | 74 | /** 75 | * Exception callback 76 | * 77 | * @param $exception Exception message 78 | */ 79 | public function myExceptionHandler($exception): void 80 | { 81 | $exception_message = $exception->getMessage(); 82 | 83 | $this->_console->addError($exception_message); 84 | 85 | $this->checkLogFile($this->_error_log_path); 86 | error_log($exception_message . "\n", 3, $this->_error_log_path); 87 | 88 | die($exception_message); 89 | } 90 | 91 | /** 92 | * Notice callback 93 | * 94 | * @param string $error_string Notice message 95 | */ 96 | public function noticeHandler(string $error_string): void 97 | { 98 | $this->_console->addWarning($error_string); 99 | $this->checkLogFile($this->_notice_log_path); 100 | error_log($error_string . "\n", 3, $this->_notice_log_path); 101 | } 102 | 103 | /** 104 | * Warning handler 105 | * 106 | * @param string $error_string Warning message 107 | */ 108 | public function warningHandler(string $error_string): void 109 | { 110 | $this->_console->addWarning($error_string); 111 | $this->checkLogFile($this->_warning_log_path); 112 | error_log($error_string . "\n", 3, $this->_warning_log_path); 113 | } 114 | 115 | /** 116 | * Error handler 117 | * 118 | * @param string $error_string Error message 119 | */ 120 | public function errorHandler(string $error_string): void 121 | { 122 | $this->_console->addError($error_string); 123 | $this->checkLogFile($this->_error_log_path); 124 | error_log($error_string . "\n", 3, $this->_error_log_path); 125 | } 126 | 127 | /** 128 | * Unknown Error handler 129 | * 130 | * @param string $error_string Unknown error message 131 | */ 132 | public function unknownErrorHandler(string $error_string): void 133 | { 134 | $this->_console->addError($error_string); 135 | $this->checkLogFile($this->_unknown_errors_log_path); 136 | error_log($error_string . "\n", 3, $this->_unknown_errors_log_path); 137 | } 138 | 139 | /** 140 | * Checks, wether the file passed in the argument exist, if not, creates it 141 | * 142 | * @param string $file_name path of the log file 143 | */ 144 | public function checkLogFile(string $file_name): void 145 | { 146 | if (!file_exists($file_name)) { 147 | $fileResource = fopen($file_name, "w"); 148 | fclose($fileResource); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /system/services/Output.php: -------------------------------------------------------------------------------- 1 | header_path = $header_path; 22 | $this->footer_path = $footer_path; 23 | $this->cache_version = $cache_version; 24 | $this->is_debug_console_enabled = $is_debug_console_enabled; 25 | $this->console = $console; 26 | $this->output_scripts = []; 27 | $this->output_styles = []; 28 | } 29 | 30 | /** 31 | * Loads a templates using the $route, and uses the $data Array (if exists) in the template. 32 | * this load also the header and the footer template 33 | * 34 | * @param string $route path of the template to load 35 | * @param array $data array of data to use in the template (if any) 36 | */ 37 | public function load(string $route, array $data = array()): void 38 | { 39 | $content = $this->loadFile($this->header_path, $data); 40 | 41 | $route_paths = explode("/", $route); 42 | $content .= $this->loadFile('src/' . $route_paths[0] . '/view/' . $route_paths[1] . 'View.php', $data); 43 | 44 | $content .= $this->loadFile($this->footer_path, $data); 45 | 46 | echo $content; 47 | } 48 | 49 | /** 50 | * Receives a array and sends it back to the user as JSON 51 | */ 52 | public function json(array $list):void { 53 | header('Content-type: application/json'); 54 | echo json_encode($list); 55 | } 56 | 57 | /** 58 | * Load a template, replaces the brackets for the variables in the array $data, and returns 59 | * the template as String 60 | * 61 | * @param string $route route of the template to load 62 | * @param array $data Array with values to print in the template 63 | * 64 | * @return string template 65 | */ 66 | public function loadFile(string $route, array $data): string 67 | { 68 | extract($data); 69 | 70 | ob_start(); 71 | include $route; 72 | 73 | return ob_get_clean(); 74 | } 75 | 76 | /** 77 | * Adds a js file at the end of the html document 78 | * 79 | * @param string $js_route path of the js file (without extension) 80 | */ 81 | public function addJs(string $js_route): void 82 | { 83 | $output_script = ""; 84 | $this->output_scripts[] = $output_script; 85 | } 86 | 87 | /** 88 | * Adds a css file at the end of the html document 89 | * 90 | * @param string $css_route path of the css file (without extension) 91 | */ 92 | public function addCss(string $css_route): void 93 | { 94 | $output_style = ""; 95 | $this->output_styles[] = $output_style; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /system/services/Session.php: -------------------------------------------------------------------------------- 1 | cookie = $cookie; 27 | $this->name = $session_name; 28 | $this->cookie += [ 29 | 'lifetime' => ini_get('session.gc_maxlifetime'), 30 | 'path' => "/", 31 | 'domain' => "", 32 | 'secure' => isset($_SERVER['HTTPS']), 33 | 'httponly' => true, 34 | ]; 35 | 36 | session_name($this->name); 37 | session_set_cookie_params( 38 | $this->cookie['lifetime'], 39 | $this->cookie['path'], 40 | $this->cookie['domain'], 41 | $this->cookie['secure'], 42 | $this->cookie['httponly'] 43 | ); 44 | } 45 | 46 | /** 47 | * Starts the session and checks that it's not empty, and regenerates the id of the session 48 | * with a probability of 1/5 49 | */ 50 | public function start(): bool 51 | { 52 | if (session_id() === '') { 53 | if (session_start()) { 54 | return mt_rand(0, 4) === 0 ? session_regenerate_id() : true; // 1/5 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | 61 | /** 62 | * Get function, gets the value inserted in the $name param 63 | * 64 | * @param string $name name of the array key to get the session value 65 | * 66 | * @return string|boolean 67 | */ 68 | public function get(string $name) 69 | { 70 | $parsed = explode('.', $name); 71 | $result = $_SESSION; 72 | 73 | while ($parsed) { 74 | $next = array_shift($parsed); 75 | if (isset($result[$next])) { 76 | $result = $result[$next]; 77 | } else { 78 | return null; 79 | } 80 | } 81 | 82 | return $result; 83 | } 84 | 85 | /** 86 | * Writes the $value param into the $name index of the array 87 | * 88 | * @param string $name name of the session index to store the value 89 | * @param string $value value to write into the session $name index 90 | */ 91 | public function set(string $name, string $value): void 92 | { 93 | $parsed = explode('.', $name); 94 | $session = &$_SESSION; 95 | 96 | while (count($parsed) > 1) { 97 | $next = array_shift($parsed); 98 | if (!isset($session[$next]) || !is_array($session[$next])) { 99 | $session[$next] = []; 100 | } 101 | $session = &$session[$next]; 102 | } 103 | 104 | $session[array_shift($parsed)] = $value; 105 | } 106 | 107 | /** 108 | * Checks if the current session is valid, this means, that it's not expired 109 | * and that the fingerprint, didn't change 110 | */ 111 | public function isValid(): bool 112 | { 113 | return !$this->isExpired() && $this->isFingerprint(); 114 | } 115 | 116 | /** 117 | * Checks wether the clients headers and the remote ip address didn't change 118 | */ 119 | public function isFingerprint(): bool 120 | { 121 | $hash = md5( 122 | $_SERVER['HTTP_USER_AGENT'] . 123 | (ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0')) 124 | ); 125 | 126 | if (isset($_SESSION['_fingerprint'])) { 127 | return $_SESSION['_fingerprint'] === $hash; 128 | } 129 | 130 | $_SESSION['_fingerprint'] = $hash; 131 | 132 | return true; 133 | } 134 | 135 | /** 136 | * Checks wether the session didn't expire (ttl) 137 | * 138 | * @param int $ttl time to live setting 139 | */ 140 | public function isExpired(int $ttl = 30): bool 141 | { 142 | $last = isset($_SESSION['_last_activity']) ? $_SESSION['_last_activity'] : false; 143 | 144 | if ($last !== false && time() - $last > $ttl * 60) { 145 | return true; 146 | } 147 | 148 | $_SESSION['_last_activity'] = time(); 149 | 150 | return false; 151 | } 152 | 153 | /** 154 | * Deletes and cleans the session 155 | */ 156 | public function forget(): bool 157 | { 158 | if (session_id() === '') { 159 | return false; 160 | } 161 | 162 | $_SESSION = []; 163 | 164 | setcookie( 165 | $this->name, 166 | '', 167 | time() - 42000, 168 | $this->cookie['path'], 169 | $this->cookie['domain'], 170 | $this->cookie['secure'], 171 | $this->cookie['httponly'] 172 | ); 173 | 174 | return session_destroy(); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /system/services/Util.php: -------------------------------------------------------------------------------- 1 | $row) { 21 | $sort_col[$key] = $row[$col]; 22 | } 23 | array_multisort($sort_col, $dir, $arr); 24 | } 25 | 26 | /** 27 | * Convert the size number into a human readable value 28 | * 29 | * @param int $size size number of memory to convert into a readable value 30 | */ 31 | public function convert(int $size): string 32 | { 33 | $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb'); 34 | return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; 35 | } 36 | 37 | /** 38 | * Check if the running HTTP request is started by an AJAX 39 | */ 40 | public function isAjaxRequest(): bool 41 | { 42 | if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') { 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | /** 49 | * Get client's IP address - if proxy lets get the REAL IP address 50 | */ 51 | public function ipAddress(): string 52 | { 53 | if (!empty($_SERVER['REMOTE_ADDR']) and !empty($_SERVER['HTTP_CLIENT_IP'])) { 54 | $ip = $_SERVER['HTTP_CLIENT_IP']; 55 | } elseif (!empty($_SERVER['REMOTE_ADDR'])) { 56 | $ip = $_SERVER['REMOTE_ADDR']; 57 | } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) { 58 | $ip = $_SERVER['HTTP_CLIENT_IP']; 59 | } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 60 | $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 61 | } else { 62 | $ip = '0.0.0.0'; 63 | } 64 | return $ip; 65 | } 66 | 67 | /** 68 | * Escapes all the quotes/special characters 69 | * 70 | * @param string $value String to clean all the quotes, break lines and special chars 71 | */ 72 | public function escape(string $value): string 73 | { 74 | return str_replace(array("\\", "\0", "\n", "\r", "\x1a", "'", '"'), array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'), $value); 75 | } 76 | 77 | /** 78 | * Deletes special characters 79 | * 80 | * @param string $text text to clean special characters 81 | */ 82 | public function preventXSS($value): string 83 | { 84 | return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); 85 | } 86 | 87 | /** 88 | * Generates an simple random token with an specified length 89 | * 90 | * @param int $length length of the token to generate 91 | */ 92 | public function generateSimpleToken(int $length): string 93 | { 94 | $token = ""; 95 | $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 96 | $codeAlphabet .= "abcdefghijklmnopqrstuvwxyz"; 97 | $codeAlphabet .= "0123456789"; 98 | $max = strlen($codeAlphabet); 99 | 100 | for ($i = 0; $i < $length; $i++) { 101 | $token .= $codeAlphabet[random_int(0, $max - 1)]; 102 | } 103 | 104 | return $token; 105 | } 106 | 107 | /** 108 | * Generates a random token for use in the CSRF token (this is used to check the POST forms integrity) 109 | */ 110 | public function generateCSRFToken(): string 111 | { 112 | return bin2hex(random_bytes(32)); 113 | } 114 | 115 | /** 116 | * Checks wether the CSRF token used in the POST form, matches with the CSRF token stored in the session 117 | */ 118 | public function checkPostCSRFToken(): void 119 | { 120 | if ($_SERVER["REQUEST_METHOD"] === "POST") { 121 | if (isset($_POST["csrf_token"])) { 122 | if (!hash_equals(Session::get("csrf_token"), $_POST["csrf_token"])) { 123 | throw new \Exception('The CSRF token doesn\'t match!'); 124 | } 125 | } else { 126 | throw new \Exception('The CSRF token was not defined'); 127 | } 128 | } 129 | } 130 | 131 | /** 132 | * This function acts exactly like array_walk_recursive, except that it pretends that the function 133 | * its calling replaces the value with its result. 134 | * 135 | * @param $array The first value of the array will be passed into $function as the primary argument 136 | * @param $function The function to be called on each element in the array, recursively 137 | * @param $parameters An optional array of the additional parameters to be appended to the function 138 | * 139 | * Example usage to alter $array to get the second, third and fourth character from each value 140 | * arrayWalkRecursiveReferential($array, "substr", array("1","3")); 141 | */ 142 | public function arrayWalkRecursiveReferential(&$array, $function, $parameters = array()): void 143 | { 144 | $reference_function = function (&$value, $key, $userdata): void { 145 | $parameters = array_merge(array($value), $userdata[1]); 146 | $value = call_user_func_array($userdata[0], $parameters); 147 | }; 148 | array_walk_recursive($array, $reference_function, array($function, $parameters)); 149 | } 150 | } 151 | --------------------------------------------------------------------------------