├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── laravel.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── mix-manifest.json ├── package-lock.json ├── package.json ├── publishable ├── assets │ ├── css │ │ ├── app.css │ │ ├── font-awesome-v4-shims.css │ │ └── font-awesome.css │ ├── fonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-solid-900.woff2 │ │ ├── nucleo-icons.eot │ │ ├── nucleo-icons.svg │ │ ├── nucleo-icons.ttf │ │ ├── nucleo-icons.woff │ │ └── nucleo-icons.woff2 │ └── js │ │ └── app.js └── config │ └── larecipe.php ├── resources ├── js │ ├── Larecipe.js │ ├── app.js │ ├── bootsrap.js │ ├── components │ │ ├── AlgoliaSearchBox.vue │ │ ├── InternalSearchBox.vue │ │ ├── LarecipeBackToTop.vue │ │ ├── LarecipeBadge.vue │ │ ├── LarecipeButton.vue │ │ ├── LarecipeCard.vue │ │ ├── LarecipeDropdown.vue │ │ ├── LarecipeProgress.vue │ │ ├── click-outside.js │ │ └── index.js │ └── vendor │ │ ├── mousetrap.js │ │ └── prism.js ├── sass │ ├── _fa_variables.scss │ ├── app.scss │ ├── components │ │ ├── _alerts.scss │ │ ├── _back-to-top.scss │ │ ├── _badges.scss │ │ ├── _search.scss │ │ └── _switch.scss │ ├── font-awesome-v4-shims.scss │ ├── font-awesome.scss │ └── vendor │ │ ├── font-awesome │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _rotated-flipped.scss │ │ ├── _screen-reader.scss │ │ ├── _shims.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ ├── brands.scss │ │ ├── fontawesome.scss │ │ ├── regular.scss │ │ ├── solid.scss │ │ └── v4-shims.scss │ │ ├── nucleo │ │ ├── css │ │ │ ├── nucleo-svg.css │ │ │ └── nucleo.css │ │ └── fonts │ │ │ ├── nucleo-icons.eot │ │ │ ├── nucleo-icons.svg │ │ │ ├── nucleo-icons.ttf │ │ │ ├── nucleo-icons.woff │ │ │ └── nucleo-icons.woff2 │ │ └── prism │ │ ├── _code-toolbar.scss │ │ ├── _dark.scss │ │ └── _light.scss └── views │ ├── default.blade.php │ ├── docs.blade.php │ ├── partials │ ├── 404.blade.php │ ├── logo.blade.php │ ├── nav.blade.php │ └── sidebar.blade.php │ ├── plugins │ ├── forum.blade.php │ └── search.blade.php │ └── style.blade.php ├── routes └── LaRecipe.php ├── src ├── Cache.php ├── Commands │ ├── AssetCommand.php │ ├── GenerateDocumentationCommand.php │ ├── InstallCommand.php │ └── ThemeCommand.php ├── Contracts │ └── MarkdownParser.php ├── DocumentationRepository.php ├── Facades │ └── LaRecipe.php ├── Helpers │ └── helpers.php ├── Http │ └── Controllers │ │ ├── Controller.php │ │ ├── DocumentationController.php │ │ ├── ScriptController.php │ │ ├── SearchController.php │ │ └── StyleController.php ├── LaRecipe.php ├── LaRecipeServiceProvider.php ├── Models │ └── Documentation.php ├── Services │ └── ParseDownMarkdownParser.php └── Traits │ ├── HasBladeParser.php │ ├── HasDocumentationAttributes.php │ ├── HasMarkdownParser.php │ ├── Indexable.php │ └── RunProcess.php ├── stubs ├── asset-stubs │ ├── .gitignore │ ├── composer.json │ ├── package.json │ ├── resources │ │ ├── js │ │ │ ├── ExampleComponent.vue │ │ │ └── asset.js │ │ └── sass │ │ │ └── asset.scss │ ├── src │ │ └── AssetServiceProvider.stub │ └── webpack.mix.js ├── index.stub ├── landing.stub └── theme-stubs │ ├── .gitignore │ ├── composer.json │ ├── resources │ └── css │ │ └── theme.css │ └── src │ └── ThemeServiceProvider.stub ├── tailwind.js ├── webpack.mix.js └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [saleem-hadad] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/workflows/laravel.yml: -------------------------------------------------------------------------------- 1 | name: Laravel 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | laravel-tests: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Install Dependencies 17 | run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist 18 | - name: Execute tests (Unit and Feature tests) via PHPUnit 19 | run: vendor/bin/phpunit 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `larecipe` will be documented in this file 4 | 5 | --- 6 | 7 | 8 | # [2.5.0](https://github.com/saleem-hadad/larecipe/releases/tag/v2.5.0) (2022-03-26) 9 | 10 | ### Enhancement & Fixes 11 | 12 | - Add support for Laravel 9 - ([#294](https://github.com/saleem-hadad/larecipe/pull/294)) 13 | 14 | [More information](https://github.com/saleem-hadad/larecipe/compare/v2.4.4...v2.5.0) 15 | 16 | 17 | # [2.4.0](https://github.com/saleem-hadad/larecipe/releases/tag/v2.4.0) (2020-09-08) 18 | 19 | ### Enhancement & Fixes 20 | 21 | - Add support for Laravel 8 - ([#235](https://github.com/saleem-hadad/larecipe/pull/235)) 22 | - Permit show blade directives - ([#234](https://github.com/saleem-hadad/larecipe/pull/234)) 23 | - Exclude code blocks from Blade compilation - ([#206](https://github.com/saleem-hadad/larecipe/pull/206)) 24 | - Markdown is now parsed against a contract, allowing you to change it - ([#252](https://github.com/saleem-hadad/larecipe/issues/252)) 25 | 26 | 27 | # [2.3.0](https://github.com/saleem-hadad/larecipe/releases/tag/v2.3.0) (2020-03-09) 28 | 29 | ### Enhancement & Fixes 30 | 31 | - Add support for Laravel 7 - ([#197](https://github.com/saleem-hadad/larecipe/pull/197)) 32 | - Fix Laravel ^7.0.x compatibility (Symfony/process) - ([#202](https://github.com/saleem-hadad/larecipe/pull/202)) 33 | - Allow remote asset URLs & empty favicon fix - ([#183](https://github.com/saleem-hadad/larecipe/pull/183)) 34 | 35 | 36 | # [2.2.3](https://github.com/saleem-hadad/larecipe/releases/tag/v2.2.3) (2020-01-21) 37 | 38 | ### Enhancement & Fixes 39 | 40 | - Add support for PHP 7.4 - ([#189](https://github.com/saleem-hadad/larecipe/pull/189)) 41 | 42 | 43 | # [2.2.1](https://github.com/saleem-hadad/larecipe/releases/tag/v2.2.1) (2019-11-08) 44 | 45 | ### Enhancement & Fixes 46 | 47 | - Adding middleware usage - ([#906da6c](https://github.com/saleem-hadad/larecipe/commit/906da6cd98ea7942558ce40f8022effe3191f913)) 48 | - Use relative path to fonts folder - ([#b116594](https://github.com/saleem-hadad/larecipe/commit/b116594f8d239d3d7700b7b92659a8a36bdeef7f)) 49 | - Remove base url, fixes header links - ([#d3b173d](https://github.com/saleem-hadad/larecipe/commit/d3b173deb4d0ff365de222e55225b84e40d63985)) 50 | - Allow custom ordering of theme styles - ([#7b7dc0b](https://github.com/saleem-hadad/larecipe/commit/7b7dc0bfff1541dacfa76d0338fae9684a0b16b6)) 51 | - Allow removing themes - ([#22dbb67](https://github.com/saleem-hadad/larecipe/commit/22dbb67dace9b850ff36aebd4628af5e958710f1)) 52 | 53 | 54 | # [2.1.4](https://github.com/saleem-hadad/larecipe/releases/tag/v2.1.4) (2019-05-18) 55 | 56 | ### Features 57 | Update smoothscroll-for-websites dependency to 1.4.9 in order to prevent the error 58 | 59 | `Unable to preventDefault inside passive event listener due to target being treated as passive` 60 | 61 | 62 | # [2.1.3](https://github.com/saleem-hadad/larecipe/releases/tag/v2.1.3) (2019-05-15) 63 | 64 | ### Features 65 | Fix Algolia search box - ([#fef3c74](https://github.com/saleem-hadad/larecipe/commit/fef3c74ca3c99524254b78baf49e3ef0fbd20ecc)) 66 | 67 | 68 | # [2.1.2](https://github.com/saleem-hadad/larecipe/releases/tag/v2.1.2) (2019-05-15) 69 | 70 | ### Features 71 | Fix Algolia search box - ([#973b230](https://github.com/saleem-hadad/larecipe/commit/973b230271981b94feab151e0ede5e906ea26de0)) 72 | 73 | 74 | # [2.1.1](https://github.com/saleem-hadad/larecipe/releases/tag/v2.1.1) (2019-05-15) 75 | 76 | ### Features 77 | Fix search button - ([#8c3ced6](https://github.com/saleem-hadad/larecipe/commit/8c3ced63b3dca194afc8084e2babd478c24ccd1f)) 78 | 79 | 80 | # [2.1.0](https://github.com/saleem-hadad/larecipe/releases/tag/v2.1.0) (2019-05-15) 81 | 82 | ### Features 83 | 84 | - Add support for FontAwesome v5 - ([#afb6347](https://github.com/saleem-hadad/larecipe/commit/afb6347df83e1f7abeee5aa9ee6757c08a978075)) 85 | 86 | ### Enhancement 87 | 88 | - Few UI improvements 89 | - Configureable new larecipe packages location - ([#6b82478](https://github.com/saleem-hadad/larecipe/commit/6b824786849ff4578bff5916fc510d21f746410d)) 90 | - Add Z-index to Medium Zoom to prevent hiding - ([#58a7c05](https://github.com/saleem-hadad/larecipe/commit/58a7c05f013070c0b5628b04fe95761f97ec5108)) 91 | 92 | 93 | # [2.0.0](https://github.com/saleem-hadad/larecipe/releases/tag/v2.0.0) (2019-04-01) 94 | 95 | ### Features 96 | 97 | - Move to TailwindCSS - ([#b6071e4](https://github.com/saleem-hadad/larecipe/commit/b6071e425e7a6545c9b947f43858145c4415da15)) 98 | - Add support for custom packages - ([#73b9245](https://github.com/saleem-hadad/larecipe/commit/73b9245f8b338e53e633890a4b2d22c09ef15466)) 99 | 100 | ### Enhancement 101 | 102 | - Support nested menus in sidebar - ([# 103 | 98](https://github.com/saleem-hadad/larecipe/pull/98)) 104 | - Add copy-to-clipboard prism plugin - ([# 105 | 99](https://github.com/saleem-hadad/larecipe/pull/99)) 106 | - Expand Test Coverage - ([# 107 | 103](https://github.com/saleem-hadad/larecipe/pull/103)) 108 | - Check for Laravel version and change cache from minutes to seconds - ([# 109 | 106](https://github.com/saleem-hadad/larecipe/pull/106)) 110 | 111 | 112 | ### Breaking Changes 113 | 114 | - Remove Few Vue Component 115 | - Change Most of Vue components props 116 | 117 | 118 | # [1.4.0](https://github.com/saleem-hadad/larecipe/releases/tag/v1.4.0) (2019-02-28) 119 | 120 | ### Enhancement 121 | 122 | - Add support for Laravel 5.8 - ([# 123 | 95](https://github.com/saleem-hadad/larecipe/pull/95)) 124 | - Feat/bust cache custom assets - ([# 125 | 93](https://github.com/saleem-hadad/larecipe/pull/93)) 126 | 127 | 128 | 129 | # [1.3.5](https://github.com/saleem-hadad/larecipe/releases/tag/v1.3.5) (2019-02-14) 130 | 131 | ### Fix 132 | - Fix mobile search - ([#90](https://github.com/saleem-hadad/larecipe/pull/90)) 133 | 134 | 135 | # [1.3.4](https://github.com/saleem-hadad/larecipe/releases/tag/v1.3.4) (2019-02-11) 136 | 137 | ### Enhancement 138 | 139 | - Improve internal search UI - ([# 140 | c1b4a24](https://github.com/saleem-hadad/larecipe/commit/c1b4a24348d3690a0ce6afecb17bd304b3ac0b49)) 141 | - Save theme once selected by a user in local storage - ([# 142 | 8902a72](https://github.com/saleem-hadad/larecipe/commit/8902a7221e059f16cba38179794036cfc685372c)) 143 | 144 | 145 | # [1.3.0](https://github.com/saleem-hadad/larecipe/releases/tag/v1.3.0) (2019-02-07) 146 | 147 | ### Features 148 | 149 | - Add internal search functionality - ([#548f5ff](https://github.com/saleem-hadad/larecipe/commit/548f5ff918f85aa6512de7676a006505e9f9a9c7)) 150 | - Add font-awesome icon selection to alarm markdown sugar - ([#78](https://github.com/saleem-hadad/larecipe/pull/78)) 151 | 152 | ### Enhancement 153 | 154 | - Make sidebar link display as block - ([#53](https://github.com/saleem-hadad/larecipe/pull/53)) 155 | - Add option for users to add extra links to auth dropdown menu - ([#56](https://github.com/saleem-hadad/larecipe/pull/56)) 156 | 157 | ### Fix 158 | 159 | - Fix rendering blade before replacing version number - ([#43e1195](https://github.com/saleem-hadad/larecipe/commit/43e1195ac985519747dcb871daa39f40bc749f0a)) ([#44](https://github.com/saleem-hadad/larecipe/issues/44)) 160 | - Fixed multi-level lists - ([#43](https://github.com/saleem-hadad/larecipe/pull/43)) 161 | - Make the mediumZoom selector more specific - ([#77](https://github.com/saleem-hadad/larecipe/pull/77)) 162 | 163 | ### Minor 164 | 165 | - close nav menu when search button pressed on mobile viewport - ([#42d0a1f](https://github.com/saleem-hadad/larecipe/commit/42d0a1f6c19be9f0d70d9b97b980a6599b3d6e66)) 166 | 167 | 168 | # [1.2.5](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.5) (2018-09-26) 169 | 170 | ### Enhancement 171 | 172 | - Add Medium-zoom like effect - ([#aa3dcce](https://github.com/saleem-hadad/larecipe/commit/aa3dcce082463e5e0dda834becec9eb6dee06e15)) 173 | 174 | ### Fix 175 | 176 | - Fix rendering blade before replacing version number - ([#43e1195](https://github.com/saleem-hadad/larecipe/commit/43e1195ac985519747dcb871daa39f40bc749f0a)) ([#44](https://github.com/saleem-hadad/larecipe/issues/44)) 177 | - Fixed multi-level lists - ([#43](https://github.com/saleem-hadad/larecipe/pull/43)) 178 | 179 | ### Minor 180 | 181 | - Add laravel 5.4 and 5.7 in require-dev composer.json - ([#41](https://github.com/saleem-hadad/larecipe/pull/41)) 182 | 183 | 184 | # [1.2.4](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.4) (2018-09-23) 185 | 186 | ### Enhancement 187 | 188 | - Add support for many Prism languages using autoloader 🔥 - ([#39](https://github.com/saleem-hadad/larecipe/pull/39)) ([#34](https://github.com/saleem-hadad/larecipe/issues/34)) ([#30](https://github.com/saleem-hadad/larecipe/issues/30)) 189 | - Add support for Blade syntax inside amrkdown 🔥 - ([#35](https://github.com/saleem-hadad/larecipe/pull/35))([#29](https://github.com/saleem-hadad/larecipe/issues/29)) ([#28](https://github.com/saleem-hadad/larecipe/issues/28)) 190 | 191 | 192 | 193 | # [1.2.3](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.3) (2018-09-22) 194 | 195 | ### Enhancement 196 | 197 | - Add support for dynamic route placeholder - ([#fd21ce2](https://github.com/saleem-hadad/larecipe/commit/fd21ce228a5934976c8f8d20230c60097891746c)) 198 | 199 | 200 | # [1.2.2](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.2) (2018-09-21) 201 | 202 | ### Features 203 | 204 | - Add disqus fourm support - ([#8b4111e](https://github.com/saleem-hadad/larecipe/commit/8b4111e56638be601d118a63f67089688098e434)) 205 | 206 | ### Minor 207 | 208 | - Add php7.1+ version requirement in readme - ([#33](https://github.com/saleem-hadad/larecipe/pull/33)) 209 | 210 | 211 | 212 | # [1.2.1](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.1) (2018-09-20) 213 | 214 | ### Enhancement 215 | 216 | - Add version number in the search - ([#791ca9c](https://github.com/saleem-hadad/larecipe/commit/791ca9c326bf3441d01d4e39acee99cad2898a23)) 217 | 218 | 219 | # [1.2.0](https://github.com/saleem-hadad/larecipe/releases/tag/v1.2.0) (2018-09-20) 220 | 221 | ### Features 222 | 223 | - Algolia Search Support - ([#0271ec3](https://github.com/saleem-hadad/larecipe/commit/0271ec3a1cfeb8975cbec34e2cf7aba970b56d71)) 224 | 225 | ### Enhancement 226 | 227 | - Dynamic color palette - ([#73a1c83](https://github.com/saleem-hadad/larecipe/commit/73a1c838f025986010ef28d4ece3dceaae0f4fbd)) ([#55678fc](https://github.com/saleem-hadad/larecipe/commit/55678fc54e3e721b897d536845d4c2a12119aaf4)) 228 | - Dark/Light code theme - ([#c577ac5](https://github.com/saleem-hadad/larecipe/commit/c577ac509906736800d58db3d3ed738dc138b0cb)) 229 | - Organize doc files in subfolders - ([#27](https://github.com/saleem-hadad/larecipe/pull/27)) 230 | - Sidebar visibility can be configured - ([#1bb3fc4](https://github.com/saleem-hadad/larecipe/commit/1bb3fc4b8f9dd6e75fd8cff21a3a9b8f41974784)) ([#18](https://github.com/saleem-hadad/larecipe/issues/18)) 231 | - Better SEO support - ([#8eb0551](https://github.com/saleem-hadad/larecipe/commit/8eb055167c4d701ac970ce3265d829f80b240db3)) ([#df82de7](https://github.com/saleem-hadad/larecipe/commit/df82de7dd86e1f1178178c48100510adf13c3877)) 232 | 233 | 234 | ### Fix 235 | 236 | - Fix publishable config - ([#19](https://github.com/saleem-hadad/larecipe/pull/19)) 237 | - Having all publishables in the vendor folder - ([#23](https://github.com/saleem-hadad/larecipe/pull/23)) 238 | 239 | 240 | ### Minor 241 | 242 | - Create .gitattributes - ([#20](https://github.com/saleem-hadad/larecipe/pull/20)) 243 | 244 | 245 | 246 | # [1.1.0](https://github.com/saleem-hadad/larecipe/releases/tag/v1.1.0) (2018-09-11) 247 | 248 | ### Features 249 | 250 | - Google Analytics Support 🔥 ([#aacef69](https://github.com/saleem-hadad/larecipe/commit/aacef69cceb55fdbfbec4e00ec2c6c4bf1216fe9)) 251 | - Authorization Support 🤚 ([#640ca87](https://github.com/saleem-hadad/larecipe/commit/640ca8791c6dab5c96b0db43da6fffc644dec9e5)) 252 | 253 | ### Enhancement 254 | 255 | - Allow to opt out app name in navbar ([#e1c8193](https://github.com/saleem-hadad/larecipe/commit/e1c8193a5887b30adaadec5ee8bc6db45c5b5e78)) 256 | - Add small notification if a user forgot to run install command ([#1a758d2](https://github.com/saleem-hadad/larecipe/commit/1a758d27dceb3cec2ce589ef3f0c8ecf9fce843e)) ([#8](https://github.com/saleem-hadad/larecipe/issues/8)) 257 | - Use Larecipe logo by default to prevent showing blank logo after installation ([#ebace69](https://github.com/saleem-hadad/larecipe/commit/ebace697017ec9a4d863d465b9e9ca2b677d686b)) ([#8](https://github.com/saleem-hadad/larecipe/issues/8)) 258 | 259 | ### Fix 260 | 261 | - Weird content animation ([#d87f711](https://github.com/saleem-hadad/larecipe/commit/d87f71102d5b897e50fad856c6a8f5d6b3b558f7)) 262 | 263 | 264 | 265 | # [1.0.1](https://github.com/saleem-hadad/larecipe/releases/tag/v1.0.1) (2018-09-02) 266 | 267 | ### Features 268 | 269 | - Store sidebar user's preference visibility in localStorage ([#4](https://github.com/saleem-hadad/larecipe/issues/4)) 270 | 271 | 272 | 273 | # [1.0.0](https://github.com/saleem-hadad/larecipe/releases/tag/v1.0.0) (2018-09-02) 274 | 275 | - initial release 276 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at saleem@binary-torch.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Procedure 8 | 9 | Before filing an issue: 10 | 11 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 12 | - Check to make sure your feature suggestion isn't already present within the project. 13 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 14 | - Check the pull requests tab to ensure that the feature isn't already in progress. 15 | 16 | Before submitting a pull request: 17 | 18 | - Check the codebase to ensure that your feature doesn't already exist. 19 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 20 | 21 | ## Requirements 22 | 23 | If the project maintainer has any additional requirements, you will find them listed here. 24 | 25 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). 26 | 27 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 28 | 29 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 30 | 31 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 32 | 33 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 34 | 35 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 36 | 37 | **Happy coding**! 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Saleem Hadad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |

6 | LaRecipe 7 |

8 | 9 | 10 |
11 | Write gorgeous documentation for your products using Markdown inside your Laravel app. 12 |
13 | 14 | 15 |

16 | License 17 | 18 | Release 19 | License 20 | 21 |

22 | 23 | --- 24 | 25 | 26 | **LaRecipe** is simply a code-driven package that provides an easy way to create beautiful documentation for your product or application inside your Laravel app. 27 | > We are working on dotnet version as well. Check it out [LaRecipe Dotnet](https://github.com/larecipe/larecipe-dotnet) 28 | 29 | Follow me on [LinkedIn](https://www.linkedin.com/in/saleem-hadad/) for updates and the latest news. 30 | 31 | ![LaRecipe Screenshot](https://larecipe.saleem.dev/images/screenshot.png#) 32 | 33 | ## Getting Started 34 | 35 | ☝️ Install the package via composer. 36 | 37 | composer require binarytorch/larecipe 38 | 39 | ✌️ Run the install command. 40 | 41 | php artisan larecipe:install 42 | 43 | Visit your app domain with `/docs` endpoint. That's it. 44 | 45 | #### See [full documentation](https://larecipe.saleem.dev/) 46 | 47 | 48 | ## 🩷 Sponsors 49 | 50 | ## JetBrains 51 | Thank you, JetBrains for sponsoring the license ❤️ 52 | 53 | 54 | 55 | 56 | 57 | Support this project by becoming a sponsor. [[Become a sponsor](https://github.com/sponsors/saleem-hadad)] 58 | 59 | --- 60 | 61 | Get $200 DigitalOcean Credit 62 | 63 | [![DigitalOcean Referral Badge](https://web-platforms.sfo2.cdn.digitaloceanspaces.com/WWW/Badge%201.svg)](https://www.digitalocean.com/?refcode=64aee93d49da&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge) 64 | 65 | ## Official tools and assets support 66 | 67 | - [LaRecipe Dark Theme](https://larecipe.saleem.dev/packages/binarytorch/larecipe-dark-theme) 68 | - [LaRecipe RTL Support](https://larecipe.saleem.dev/packages/binarytorch/larecipe-rtl) 69 | - [LaRecipe Feedback](https://larecipe.saleem.dev/packages/binarytorch/larecipe-feedback) 70 | - [LaRecipe Swagger](https://larecipe.saleem.dev/packages/binarytorch/larecipe-swagger) 71 | 72 | ## Used by 73 | * [WooSignal](https://woosignal.com/docs/api/1.0/overview) - Fastest WooCommerce App Templates. 74 | * [AddChat](https://addchat-docs.classiebit.com/docs/1.0/introduction) - All-in-one multi-purpose Chat Widget For Laravel & Codeigniter websites. 75 | * [RoadLeagues](https://roadleagues.com/docs/1.0/overview) - A cycling league management system with an API to allow data distrubution externally. 76 | * [Raileo](https://raileo.com/docs/1.0/overview) - Raileo helps you to monitor your website's uptime, performance and SEO 77 | * Add your docs here 😍👌 78 | 79 | ## Contributors 80 | 81 | This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. 82 | 83 | 84 | ## License 85 | 86 | This library is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details. 87 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "binarytorch/larecipe", 3 | "description": "Generate gorgeous recipes for your Laravel applications using MarkDown", 4 | "keywords": [ 5 | "laravel", 6 | "markdown", 7 | "docs", 8 | "documentation", 9 | "api" 10 | ], 11 | "license": "MIT", 12 | "type": "library", 13 | "support": { 14 | "issues": "https://github.com/saleem-hadad/larecipe/issues", 15 | "source": "https://github.com/saleem-hadad/larecipe" 16 | }, 17 | "authors": [ 18 | { 19 | "name": "Saleem Hadad", 20 | "email": "saleem@binary-torch.com" 21 | } 22 | ], 23 | "require": { 24 | "php": "^7.1|^8.0", 25 | "illuminate/support": "^5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 26 | "illuminate/view": "^5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 27 | "erusev/parsedown-extra": "^0.8.1|^0.8", 28 | "symfony/dom-crawler": "^4.1|^5.0|^6.0|^7.0" 29 | }, 30 | "require-dev": { 31 | "phpunit/phpunit": "^7.0|^8.0|^9.0|^10.0|^11.5.3", 32 | "laravel/framework": "^5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 33 | "orchestra/testbench": "^3.4|^4.0|^5.0|^7.0|^8.0|^9.0|^10.0" 34 | }, 35 | "autoload": { 36 | "files": [ 37 | "src/Helpers/helpers.php" 38 | ], 39 | "psr-4": { 40 | "BinaryTorch\\LaRecipe\\": "src/" 41 | } 42 | }, 43 | "autoload-dev": { 44 | "psr-4": { 45 | "BinaryTorch\\LaRecipe\\Tests\\": "tests/" 46 | } 47 | }, 48 | "minimum-stability": "stable", 49 | "extra": { 50 | "laravel": { 51 | "providers": [ 52 | "BinaryTorch\\LaRecipe\\LaRecipeServiceProvider" 53 | ], 54 | "aliases": { 55 | "LaRecipe": "BinaryTorch\\LaRecipe\\LaRecipe" 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/publishable/assets/js/app.js": "/publishable/assets/js/app.js", 3 | "/publishable/assets/css/app.css": "/publishable/assets/css/app.css", 4 | "/publishable/assets/css/font-awesome.css": "/publishable/assets/css/font-awesome.css", 5 | "/publishable/assets/css/font-awesome-v4-shims.css": "/publishable/assets/css/font-awesome-v4-shims.css" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 11 | "postinstall": "opencollective-postinstall" 12 | }, 13 | "devDependencies": { 14 | "cross-env": "^5.1", 15 | "laravel-mix": "^2.0", 16 | "tar": "^4.4.10", 17 | "opencollective": "^1.0.3", 18 | "opencollective-postinstall": "^2.0.2", 19 | "webpack-dev-server": "^3.7.2" 20 | }, 21 | "dependencies": { 22 | "axios": "^0.21.1", 23 | "clipboard": "^2.0.4", 24 | "docsearch.js": "^2.6.3", 25 | "medium-zoom": "^1.0.4", 26 | "vue": "^2.6.10", 27 | "jquery": "^3.4.0", 28 | "tailwindcss": "^0.7.4", 29 | "vue2-transitions": "0.2.3" 30 | }, 31 | "collective": { 32 | "type": "opencollective", 33 | "url": "https://opencollective.com/larecipe" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /publishable/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /publishable/assets/fonts/nucleo-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/nucleo-icons.eot -------------------------------------------------------------------------------- /publishable/assets/fonts/nucleo-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/nucleo-icons.ttf -------------------------------------------------------------------------------- /publishable/assets/fonts/nucleo-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/nucleo-icons.woff -------------------------------------------------------------------------------- /publishable/assets/fonts/nucleo-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/publishable/assets/fonts/nucleo-icons.woff2 -------------------------------------------------------------------------------- /publishable/config/larecipe.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'route' => '/docs', 18 | 'path' => '/resources/docs', 19 | 'landing' => 'overview', 20 | 'middleware' => ['web'], 21 | ], 22 | 23 | /* 24 | |-------------------------------------------------------------------------- 25 | | Documentation Versions 26 | |-------------------------------------------------------------------------- 27 | | 28 | | Here you may specify and set the versions and the default (latest) one 29 | | of your documentation's versions where you can redirect the user to. 30 | | Just make sure that the default version is in the published list. 31 | | 32 | | 33 | */ 34 | 35 | 'versions' => [ 36 | 'default' => '1.0', 37 | 'published' => [ 38 | '1.0' 39 | ] 40 | ], 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | Documentation Settings 45 | |-------------------------------------------------------------------------- 46 | | 47 | | These options configure the additional behaviors of your documentation 48 | | where you can limit the access to only authenticated users in your 49 | | system. It is false initially so that guests can view your docs. 50 | | Middleware can be defined if auth is set to false. For example, if you want all users to be able to access your docs, 51 | | use web middleware. If you want just auth users, use auth middleware. Or, make your own middleware 52 | | to handle who can see your docs (don't forget to use gates for more granular control!). 53 | | 54 | | 55 | */ 56 | 57 | 'settings' => [ 58 | 'auth' => false, 59 | 'guard' => null, 60 | 'ga_id' => '', 61 | 'middleware' => [ 62 | 'web', 63 | ] 64 | ], 65 | 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Cache 69 | |-------------------------------------------------------------------------- 70 | | 71 | | Obviously rendering markdown at the back-end is costly especially if 72 | | the rendered files are massive. Thankfully, caching is considered 73 | | as a good option to speed up your app when having high traffic. 74 | | 75 | | Caching period unit: minutes 76 | | 77 | */ 78 | 79 | 'cache' => [ 80 | 'enabled' => false, 81 | 'period' => 5 82 | ], 83 | 84 | /* 85 | |-------------------------------------------------------------------------- 86 | | Search 87 | |-------------------------------------------------------------------------- 88 | | 89 | | Here you can add configure the search functionality of your docs. 90 | | You can choose the default engine of your search from the list 91 | | However, you can also enable/disable the search's visibility 92 | | 93 | | Supported Search Engines: 'algolia', 'internal' 94 | | 95 | */ 96 | 97 | 'search' => [ 98 | 'enabled' => false, 99 | 'default' => 'algolia', 100 | 'engines' => [ 101 | 'internal' => [ 102 | 'index' => ['h2', 'h3'] 103 | ], 104 | 'algolia' => [ 105 | 'key' => '', 106 | 'index' => '' 107 | ] 108 | ] 109 | ], 110 | 111 | /* 112 | |-------------------------------------------------------------------------- 113 | | Appearance 114 | |-------------------------------------------------------------------------- 115 | | 116 | | Here you can add configure the appearance of your docs. For example, 117 | | you can set the primary and secondary colors that will give your 118 | | documentation a unique look. You can set the fav of your docs. 119 | | 120 | | 121 | */ 122 | 123 | 'ui' => [ 124 | 'code_theme' => 'dark', // or: light 125 | 'fav' => '', // eg: fav.png 126 | 'fa_v4_shims' => true, // Add FontAwesome v4 shims prevent BC break 127 | 'show_side_bar' => true, 128 | 'colors' => [ 129 | 'primary' => '#787AF6', 130 | 'secondary' => '#2b9cf2' 131 | ], 132 | 133 | 'theme_order' => null // ['LaRecipeDarkTheme', 'customTheme'] 134 | ], 135 | 136 | /* 137 | |-------------------------------------------------------------------------- 138 | | SEO 139 | |-------------------------------------------------------------------------- 140 | | 141 | | These options configure the SEO settings of your docs. You can set the 142 | | author, the description and the keywords. Also, LaRecipe by default 143 | | sets the canonical link to the viewed page's link automatically. 144 | | 145 | | 146 | */ 147 | 148 | 'seo' => [ 149 | 'author' => '', 150 | 'description' => '', 151 | 'keywords' => '', 152 | 'og' => [ 153 | 'title' => '', 154 | 'type' => 'article', 155 | 'url' => '', 156 | 'image' => '', 157 | 'description' => '', 158 | ] 159 | ], 160 | 161 | /* 162 | |-------------------------------------------------------------------------- 163 | | Forum 164 | |-------------------------------------------------------------------------- 165 | | 166 | | Giving a chance to your users to post their questions or feedback 167 | | directly on your docs, is pretty nice way to engage them more. 168 | | However, you can also enable/disable the forum's visibility. 169 | | 170 | | Supported Services: 'disqus' 171 | | 172 | */ 173 | 174 | 'forum' => [ 175 | 'enabled' => false, 176 | 'default' => 'disqus', 177 | 'services' => [ 178 | 'disqus' => [ 179 | 'site_name' => '', // yoursite.disqus.com 180 | ] 181 | ] 182 | ], 183 | 184 | /* 185 | |-------------------------------------------------------------------------- 186 | | Components and Packages 187 | |-------------------------------------------------------------------------- 188 | | 189 | | Once you create a new asset or theme, its directory will be 190 | | published under `larecipe-components` folder. However, If 191 | | you want a different location, feel free to change it. 192 | | 193 | | 194 | */ 195 | 196 | 'packages' => [ 197 | 'path' => 'larecipe-components', 198 | ], 199 | 200 | 'blade-parser' => [ 201 | 'regex' => [ 202 | 'code-blocks' => [ 203 | 'match' => '/\(.|\n)*?<\/pre\>/', 204 | 'replacement' => '', 205 | ] 206 | ] 207 | ] 208 | ]; 209 | -------------------------------------------------------------------------------- /resources/js/Larecipe.js: -------------------------------------------------------------------------------- 1 | import "../sass/vendor/nucleo/css/nucleo.css"; 2 | 3 | import Vue from "vue"; 4 | import mediumZoom from "medium-zoom"; 5 | import LaRecipeComponents from "./components"; 6 | 7 | Vue.use(LaRecipeComponents); 8 | Vue.config.productionTip = false; 9 | const noDelimiter = { replace: () => "(?!x)x" }; 10 | 11 | export default class LaRecipe { 12 | constructor(config) { 13 | this.config = config; 14 | this.bootingCallbacks = []; 15 | } 16 | 17 | booting(callback) { 18 | this.bootingCallbacks.push(callback); 19 | } 20 | 21 | boot() { 22 | this.bootingCallbacks.forEach(callback => callback(Vue)); 23 | 24 | this.bootingCallbacks = []; 25 | } 26 | 27 | run() { 28 | this.boot(); 29 | 30 | this.app = new Vue({ 31 | el: "#app", 32 | delimiters: [noDelimiter, noDelimiter], 33 | data() { 34 | return { 35 | sidebar: false, 36 | searchBox: false 37 | }; 38 | }, 39 | watch: { 40 | // listen to the sidebar value if changed => if so, cache it. 41 | sidebar: function() { 42 | localStorage.setItem("larecipeSidebar", this.sidebar); 43 | } 44 | }, 45 | mounted() { 46 | this.handleSidebarVisibility(); 47 | this.addLinksToHeaders(); 48 | this.setupSmoothScrolling(); 49 | this.activateCurrentSection(); 50 | this.parseDocsContent(); 51 | this.setupKeyboardShortcuts(); 52 | mediumZoom(".documentation img"); 53 | }, 54 | methods: { 55 | handleSidebarVisibility() { 56 | // check if the user already save some sidebar's visibility preferenece 57 | // if yes, load it from the cache. 58 | if ( 59 | typeof Storage !== "undefined" && 60 | localStorage.getItem("larecipeSidebar") !== null 61 | ) { 62 | this.sidebar = localStorage.getItem("larecipeSidebar") == "true"; 63 | } 64 | 65 | // hide the sidebar if clicked on the page on mobile screens 66 | $(".documentation").click(() => { 67 | if (window.matchMedia("(max-width: 960px)").matches) { 68 | this.sidebar = false; 69 | } 70 | }); 71 | }, 72 | addLinksToHeaders() { 73 | $(".documentation") 74 | .find("a[name]") 75 | .each(function() { 76 | var anchor = $(''); 77 | $(this) 78 | .parent() 79 | .next("h2") 80 | .wrapInner(anchor); 81 | }); 82 | }, 83 | setupSmoothScrolling() { 84 | $( 85 | '.documentation > ul:first > li a[href*="#"]:not([href="#"])' 86 | ).click(function() { 87 | var target = $(this.hash); 88 | target = target.length 89 | ? target 90 | : $("[name=" + this.hash.slice(1) + "]"); 91 | if (target.length) { 92 | $("html,body").animate( 93 | { 94 | scrollTop: target.offset().top - 70 95 | }, 96 | 500 97 | ); 98 | } 99 | }); 100 | }, 101 | activateCurrentSection() { 102 | // active sidebar element 103 | if ($(".sidebar ul").length) { 104 | var current = $(".sidebar ul").find( 105 | 'li a[href="' + window.location.pathname + '"]' 106 | ); 107 | 108 | if (current.length) { 109 | current 110 | .parent() 111 | .css("font-weight", "bold") 112 | .addClass("is-active"); 113 | } 114 | } 115 | }, 116 | parseDocsContent() { 117 | // custom blockquote icons 118 | $(".documentation blockquote p:first-child").each(function() { 119 | var str = $(this).html(); 120 | var match = str.match(/\{(.*?)\}/); 121 | 122 | if (match) { 123 | var icon = match[1] || false; 124 | } 125 | 126 | if (icon) { 127 | var word = icon; 128 | 129 | if ( 130 | icon.indexOf(".") >= 0 && 131 | icon.split(".")[1].startsWith("fa") 132 | ) { 133 | var match = icon.split("."); 134 | var word = match[0]; 135 | icon = ''; 136 | } else { 137 | var icons = { 138 | info: 139 | '', 140 | primary: 141 | '', 142 | success: 143 | '', 144 | danger: 145 | '', 146 | warning: 147 | '' 148 | }; 149 | icon = '' + icons[icon] + ""; 150 | } 151 | 152 | $(this).html( 153 | str.replace(/\{(.*?)\}/, '
' + icon + "
") 154 | ); 155 | $(this) 156 | .parent() 157 | .addClass("alert is-" + word); 158 | } 159 | }); 160 | 161 | // Replace markdown checkboxes with html checkboxes 162 | $(".documentation ul li").each(function() { 163 | var regex = /\[.+\]/; 164 | var text = $(this).text(); 165 | var match = text.match(regex); 166 | 167 | if (match) { 168 | $(this).parent().addClass('list-reset pl-0'); 169 | var checkbox = '' 170 | var html = text.replace(regex, checkbox); 171 | $(this).html(html); 172 | } 173 | }); 174 | }, 175 | setupKeyboardShortcuts() { 176 | // keyboard magic 🎹 177 | const Mousetrap = require("./vendor/mousetrap.js"); 178 | 179 | // toggle the sidebar 180 | Mousetrap.bind("/", e => { 181 | e.preventDefault(); 182 | this.sidebar = !this.sidebar; 183 | }); 184 | 185 | // open the search box 186 | Mousetrap.bind("s", e => { 187 | e.preventDefault(); 188 | this.searchBox = true; 189 | }); 190 | 191 | // scroll to the top of the page 192 | Mousetrap.bind("t", e => { 193 | e.preventDefault(); 194 | $("html,body").animate( 195 | { 196 | scrollTop: 0 197 | }, 198 | 500 199 | ); 200 | }); 201 | 202 | // scroll to the bottom of the page 203 | Mousetrap.bind("b", e => { 204 | e.preventDefault(); 205 | $("html,body").animate( 206 | { 207 | scrollTop: $(document).height() 208 | }, 209 | 500 210 | ); 211 | }); 212 | } 213 | } 214 | }); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootsrap'); 2 | 3 | import LaRecipe from './Larecipe'; 4 | 5 | ;(function() { 6 | this.CreateLarecipe = function(config) { 7 | return new LaRecipe(config) 8 | } 9 | }.call(window)); 10 | -------------------------------------------------------------------------------- /resources/js/bootsrap.js: -------------------------------------------------------------------------------- 1 | window.jQuery = window.$ = require('jquery'); 2 | 3 | window.axios = require('axios'); 4 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 5 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = document.head.querySelector('meta[name="csrf-token"]').content; 6 | 7 | require('./vendor/prism.js'); 8 | Prism.plugins.autoloader.use_minified = true; 9 | Prism.plugins.autoloader.languages_path = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/components/'; 10 | -------------------------------------------------------------------------------- /resources/js/components/AlgoliaSearchBox.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /resources/js/components/InternalSearchBox.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeBackToTop.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeBadge.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 50 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeButton.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 62 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeCard.vue: -------------------------------------------------------------------------------- 1 | 8 | 37 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeDropdown.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | -------------------------------------------------------------------------------- /resources/js/components/LarecipeProgress.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /resources/js/components/click-outside.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind: function(el, binding, vnode) { 3 | el.clickOutsideEvent = function(event) { 4 | if (!(el == event.target || el.contains(event.target))) { 5 | vnode.context[binding.expression](event); 6 | } 7 | }; 8 | document.body.addEventListener("click", el.clickOutsideEvent); 9 | }, 10 | unbind: function(el) { 11 | document.body.removeEventListener("click", el.clickOutsideEvent); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /resources/js/components/index.js: -------------------------------------------------------------------------------- 1 | import ClickOutside from './click-outside'; 2 | 3 | import AlgoliaSearchBox from "./AlgoliaSearchBox"; 4 | import InternalSearchBox from "./InternalSearchBox"; 5 | import LarecipeBackToTop from "./LarecipeBackToTop"; 6 | import LarecipeBadge from "./LarecipeBadge"; 7 | import LarecipeButton from "./LarecipeButton"; 8 | import LarecipeCard from "./LarecipeCard"; 9 | import LarecipeDropdown from "./LarecipeDropdown"; 10 | import LarecipeProgress from "./LarecipeProgress"; 11 | 12 | export default { 13 | install(Vue) { 14 | Vue.directive("click-outside", ClickOutside); 15 | 16 | Vue.component(AlgoliaSearchBox.name, AlgoliaSearchBox); 17 | Vue.component(InternalSearchBox.name, InternalSearchBox); 18 | Vue.component(LarecipeBackToTop.name, LarecipeBackToTop); 19 | Vue.component(LarecipeBadge.name, LarecipeBadge); 20 | Vue.component(LarecipeButton.name, LarecipeButton); 21 | Vue.component(LarecipeCard.name, LarecipeCard); 22 | Vue.component(LarecipeDropdown.name, LarecipeDropdown); 23 | Vue.component(LarecipeProgress.name, LarecipeProgress); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /resources/js/vendor/mousetrap.js: -------------------------------------------------------------------------------- 1 | /* mousetrap v1.5.3 craig.is/killing/mice */ 2 | (function(C,r,g){function t(a,b,h){a.addEventListener?a.addEventListener(b,h,!1):a.attachEvent("on"+b,h)}function x(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return l[a.which]?l[a.which]:p[a.which]?p[a.which]:String.fromCharCode(a.which).toLowerCase()}function D(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function u(a){return"shift"==a||"ctrl"==a||"alt"==a|| 3 | "meta"==a}function y(a,b){var h,c,e,g=[];h=a;"+"===h?h=["+"]:(h=h.replace(/\+{2}/g,"+plus"),h=h.split("+"));for(e=0;em||l.hasOwnProperty(m)&&(k[l[m]]=m)}e=k[h]?"keydown":"keypress"}"keypress"==e&&g.length&&(e="keydown");return{key:c,modifiers:g,action:e}}function B(a,b){return null===a||a===r?!1:a===b?!0:B(a.parentNode,b)}function c(a){function b(a){a= 4 | a||{};var b=!1,n;for(n in q)a[n]?b=!0:q[n]=0;b||(v=!1)}function h(a,b,n,f,c,h){var g,e,l=[],m=n.type;if(!d._callbacks[a])return[];"keyup"==m&&u(a)&&(b=[a]);for(g=0;g":".","?":"/","|":"\\"},z={option:"alt",command:"meta","return":"enter", 9 | escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},k;for(g=1;20>g;++g)l[111+g]="f"+g;for(g=0;9>=g;++g)l[g+96]=g;c.prototype.bind=function(a,b,c){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,c);return this};c.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};c.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};c.prototype.reset=function(){this._callbacks={};this._directMap= 10 | {};return this};c.prototype.stopCallback=function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")||B(b,this.target)?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};c.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};c.init=function(){var a=c(r),b;for(b in a)"_"!==b.charAt(0)&&(c[b]=function(b){return function(){return a[b].apply(a,arguments)}}(b))};c.init();C.Mousetrap=c;"undefined"!==typeof module&&module.exports&&(module.exports= 11 | c);"function"===typeof define&&define.amd&&define(function(){return c})})(window,document); -------------------------------------------------------------------------------- /resources/sass/_fa_variables.scss: -------------------------------------------------------------------------------- 1 | // Override default FontAwesome font path 2 | $fa-font-path: "../fonts"; -------------------------------------------------------------------------------- /resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | @tailwind preflight; 2 | @tailwind components; 3 | 4 | @import "./components/alerts"; 5 | @import "./components/badges"; 6 | @import "./components/search"; 7 | @import "./components/switch"; 8 | @import "./components/back-to-top"; 9 | 10 | @import "./vendor/prism/dark"; 11 | @import "./vendor/prism/light"; 12 | @import "./vendor/prism/code-toolbar"; 13 | 14 | /**************************************/ 15 | /**************** Root ****************/ 16 | /**************************************/ 17 | :root { 18 | --black: #22292f; 19 | --white: white; 20 | --primary: #787AF6; 21 | --secondary: #2b9cf2; 22 | --info: #03a9f4; 23 | --warning: #fb6340; 24 | --success: #21b978; 25 | --danger: #f5365c; 26 | 27 | --sidebar: #f4f5f7; 28 | --documentation: rgb(254, 254, 254); 29 | --navbar: white; 30 | } 31 | 32 | /**************************************/ 33 | /*************** Global ***************/ 34 | /**************************************/ 35 | html, body { 36 | @apply bg-documentation; 37 | } 38 | 39 | a { 40 | @apply no-underline; 41 | } 42 | 43 | /**************************************/ 44 | /*************** Sidebar **************/ 45 | /**************************************/ 46 | .sidebar { 47 | @apply bg-sidebar border-r border-grey-light w-64 fixed z-10 text-base pin-y pin-l mt-16 overflow-y-auto py-8; 48 | transition: all 0.2s; 49 | 50 | &.is-hidden { 51 | left: -16rem; 52 | } 53 | 54 | > ul { 55 | @apply list-reset; 56 | 57 | > li { 58 | > h2 { 59 | @apply p-5 text-grey-darkest text-base mb-0; 60 | } 61 | 62 | > ul { 63 | @apply list-reset leading-loose; 64 | 65 | > li { 66 | &.is-active { 67 | @apply pl-2; 68 | 69 | &::before { 70 | content: ""; 71 | position: absolute; 72 | left: 0; 73 | z-index: 100; 74 | width: 2px; 75 | height: 35px; 76 | background: var(--primary); 77 | } 78 | 79 | a { 80 | @apply font-bold; 81 | } 82 | 83 | > ul > li { 84 | @apply -ml-2; 85 | a { 86 | @apply font-normal; 87 | } 88 | } 89 | } 90 | 91 | a { 92 | @apply text-base font-thin text-grey-dark py-0 px-8 block; 93 | 94 | transition: padding-left 0.3s; 95 | 96 | &:hover { 97 | padding-left: 2.25rem; 98 | } 99 | } 100 | 101 | ul { 102 | @apply list-reset; 103 | > li { 104 | @apply pl-4; 105 | 106 | &.is-active { 107 | @apply border-l-2 border-primary; 108 | 109 | a { 110 | @apply font-bold; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | 121 | /**************************************/ 122 | /**************** Cards ***************/ 123 | /**************************************/ 124 | .card { 125 | @apply p-6 my-4 shadow-xs rounded; 126 | 127 | &.is-default { @apply bg-white text-grey-darkest border border-grey-lighter; } 128 | &.is-white { @apply bg-grey-lightest text-grey-darkest; } 129 | &.is-black { @apply bg-grey-darkest text-white; } 130 | &.is-primary { @apply bg-primary text-white; } 131 | &.is-secondary { @apply bg-secondary text-white; } 132 | &.is-success { @apply bg-success text-white; } 133 | &.is-info { @apply bg-info text-white; } 134 | &.is-warning { @apply bg-warning text-white; } 135 | &.is-danger { @apply bg-danger text-white; } 136 | } 137 | 138 | /**************************************/ 139 | /************** Buttons ***************/ 140 | /**************************************/ 141 | .button { 142 | @apply py-3 px-6 rounded shadow; 143 | transition: all 0.1s; 144 | 145 | &:hover { 146 | transform: translateY(-1px); 147 | @apply shadow-md; 148 | } 149 | 150 | &:focus { 151 | @apply outline-none; 152 | } 153 | 154 | &.is-link { @apply bg-transparent text-grey shadow-none; } 155 | &.is-white { @apply bg-grey-lightest text-grey-darkest; } 156 | &.is-black { @apply bg-grey-darkest text-white; } 157 | &.is-primary { @apply bg-primary text-white; } 158 | &.is-secondary { @apply bg-secondary text-white; } 159 | &.is-success { @apply bg-success text-white; } 160 | &.is-info { @apply bg-info text-white; } 161 | &.is-warning { @apply bg-warning text-white; } 162 | &.is-danger { @apply bg-danger text-white; } 163 | } 164 | 165 | /**************************************/ 166 | /************** Tables ****************/ 167 | /**************************************/ 168 | table { 169 | @apply shadow-lg bg-white w-full p-4 my-4; 170 | transition: box-shadow 0.1s; 171 | 172 | &:hover { 173 | @apply shadow; 174 | } 175 | 176 | tr, td, th { 177 | @apply border border-grey-light; 178 | 179 | &:hover { 180 | @apply bg-grey-lightest; 181 | } 182 | } 183 | 184 | td, th { 185 | @apply p-4; 186 | } 187 | } 188 | 189 | /**************************************/ 190 | /*********** Medium-Zoom **************/ 191 | /**************************************/ 192 | 193 | .medium-zoom-overlay, img.medium-zoom-image--opened{ 194 | z-index: 10; 195 | } 196 | 197 | /**************************************/ 198 | /********** Documentation *************/ 199 | /**************************************/ 200 | .documentation { 201 | @apply bg-documentation static my-32 pl-50 w-3/4; 202 | transition: padding-left 0.2s; 203 | 204 | &.expanded { 205 | @apply pl-20; 206 | } 207 | 208 | h1:first-of-type { 209 | @apply border-l-2 border-primary pl-4 mb-6 font-bold; 210 | } 211 | 212 | h2 { 213 | @apply mt-10 mb-4 font-bold; 214 | 215 | a, a:hover { 216 | @apply text-grey-darker no-underline; 217 | } 218 | 219 | a:before { 220 | content: "#"; 221 | @apply -ml-4 mt-1 absolute text-base text-primary opacity-75; 222 | } 223 | } 224 | 225 | h3 { 226 | @apply mt-10 mb-4; 227 | } 228 | 229 | hr { 230 | @apply border-t-2 border-dashed border-grey-lighter my-4; 231 | } 232 | 233 | img { 234 | max-width: 100%; 235 | } 236 | 237 | & > ul:first-of-type { 238 | @apply fixed p-4 list-reset w-1/5; 239 | top: 100px; 240 | right: 30px; 241 | 242 | li { 243 | @apply border-b border-dashed border-grey-light leading-normal p-3; 244 | 245 | a { 246 | @apply text-sm text-grey; 247 | } 248 | } 249 | 250 | ul { 251 | @apply list-reset pl-4; 252 | } 253 | } 254 | 255 | :not(pre) > code { 256 | @apply bg-grey-lighter px-2 rounded text-primary leading-normal; 257 | padding-top: 0.1rem; 258 | padding-bottom: 0.1rem; 259 | line-height: 1.6; 260 | } 261 | 262 | ul > li , ol > li { 263 | @apply py-2; 264 | } 265 | 266 | p { 267 | @apply text-base leading-large; 268 | } 269 | } 270 | 271 | @media (max-width: 780px) { 272 | .documentation { 273 | padding: 0 40px !important; 274 | @apply w-full; 275 | 276 | > ul:first-of-type { 277 | @apply list-reset w-full; 278 | position: inherit; 279 | top: 10px; 280 | right: 30px; 281 | } 282 | } 283 | } 284 | 285 | 286 | @tailwind utilities; -------------------------------------------------------------------------------- /resources/sass/components/_alerts.scss: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /************** Alerts ****************/ 3 | /**************************************/ 4 | .alert { 5 | @apply relative bg-primary shadow-lg my-8 p-6 rounded-lg overflow-hidden; 6 | transition: box-shadow 0.1s; 7 | 8 | &:hover { 9 | @apply shadow; 10 | } 11 | 12 | &.is-info { @apply bg-info; } 13 | &.is-success { @apply bg-success; } 14 | &.is-danger { @apply bg-danger; } 15 | &.is-warning { @apply bg-warning; } 16 | 17 | p { 18 | @apply pl-8 mb-0 text-white; 19 | } 20 | 21 | .icon { 22 | @apply absolute w-16 h-16 opacity-25 font-bold; 23 | left: -10px; 24 | top: -10px; 25 | svg { 26 | fill: white; 27 | width: 60px; 28 | height: 60px; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /resources/sass/components/_back-to-top.scss: -------------------------------------------------------------------------------- 1 | #backtotop { 2 | @apply fixed pin-r opacity-0 z-50 mr-6; 3 | bottom: 25px; 4 | transition: 0.35s; 5 | transform: scale(0.7); 6 | transition: all 0.5s; 7 | } 8 | 9 | #backtotop.visible { 10 | @apply opacity-100; 11 | transform: scale(1); 12 | } 13 | 14 | #backtotop.visible a:hover { 15 | @apply bg-primary opacity-75 outline-none; 16 | } 17 | 18 | #backtotop a { 19 | @apply bg-primary outline-none border-none block opacity-100 w-12 h-12 rounded-full; 20 | text-decoration: none; 21 | transition: all 0.3s; 22 | text-align: center; 23 | font-size: 26px; 24 | } 25 | 26 | body #backtotop a { 27 | @apply outline-none text-white; 28 | } 29 | 30 | #backtotop a:after { 31 | @apply outline-none relative block; 32 | content: "\f106"; 33 | font-family: "Font Awesome 5 Free"; 34 | font-weight: 900; 35 | top: 50%; 36 | -webkit-transform: translateY(-55%); 37 | transform: translateY(-55%); 38 | } 39 | -------------------------------------------------------------------------------- /resources/sass/components/_badges.scss: -------------------------------------------------------------------------------- 1 | .badge { 2 | @apply px-4 py-2 text-sm; 3 | 4 | &.is-white { @apply bg-grey-lightest text-grey-darkest; } 5 | &.is-black { @apply bg-grey-darkest text-white; } 6 | &.is-primary { @apply bg-primary text-white; } 7 | &.is-secondary { @apply bg-secondary text-white; } 8 | &.is-success { @apply bg-success text-white; } 9 | &.is-info { @apply bg-info text-white; } 10 | &.is-warning { @apply bg-warning text-white; } 11 | &.is-danger { @apply bg-danger text-white; } 12 | } -------------------------------------------------------------------------------- /resources/sass/components/_search.scss: -------------------------------------------------------------------------------- 1 | .search-box { 2 | @apply w-full h-24 flex items-center z-50 shadow; 3 | transition: all 0.2s; 4 | margin-top: 4.25rem; 5 | 6 | input { 7 | @apply border-none mb-0 h-full w-full text-center outline-none; 8 | font-size: 2rem; 9 | text-transform: uppercase; 10 | background: #f4f5f7; 11 | transition: all 0.2s; 12 | 13 | &:focus { 14 | @apply bg-white; 15 | } 16 | } 17 | 18 | .algolia-autocomplete { 19 | @apply w-full h-full shadow-lg; 20 | } 21 | } 22 | 23 | .internal-autocomplete-result { 24 | @apply shadow-lg bg-white; 25 | min-width: 300px; 26 | max-height: 400px; 27 | position: absolute; 28 | top: 7rem; 29 | right: 10px; 30 | border-radius: 10px; 31 | transition: all 0.2s; 32 | z-index: 100; 33 | overflow: scroll; 34 | 35 | ul { 36 | list-style: none; 37 | margin-left: -20px !important; 38 | margin-right: 20px !important; 39 | 40 | li { 41 | width: 100%; 42 | margin-top: 20px; 43 | 44 | .page-title { 45 | @apply text-grey-darker font-bold; 46 | } 47 | 48 | hr { 49 | @apply bg-grey-lighter w-full border-t border-grey-light my-2; 50 | } 51 | 52 | .heading { 53 | @apply w-full mb-0 text-grey; 54 | padding: 5px 10px; 55 | cursor: pointer; 56 | 57 | &:hover { 58 | @apply font-bold; 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /resources/sass/components/_switch.scss: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /*************** Switch ***************/ 3 | /**************************************/ 4 | .switch { 5 | @apply relative select-none w-12 mr-2 leading-normal; 6 | } 7 | .switch-checkbox { 8 | @apply hidden; 9 | } 10 | .switch-label { 11 | @apply block overflow-hidden cursor-pointer bg-grey-light rounded-full h-6 shadow-inner border-2 border-white; 12 | transition: background-color 0.1s ease-in; 13 | } 14 | .switch-label:before { 15 | @apply absolute block bg-white border shadow pin-y w-6 rounded-full -ml-1; 16 | 17 | right: 50%; 18 | content: ""; 19 | transition: all 0.1s ease-in; 20 | } 21 | .switch-checkbox:checked + .switch-label { 22 | @apply bg-primary shadow-none; 23 | } 24 | .switch-checkbox:checked + .switch-label:before { 25 | @apply pin-r; 26 | } -------------------------------------------------------------------------------- /resources/sass/font-awesome-v4-shims.scss: -------------------------------------------------------------------------------- 1 | // Override default FontAwesome variables 2 | @import "fa_variables.scss"; 3 | 4 | @import "./vendor/font-awesome/v4-shims.scss"; -------------------------------------------------------------------------------- /resources/sass/font-awesome.scss: -------------------------------------------------------------------------------- 1 | // Override default FontAwesome variables 2 | @import "fa_variables.scss"; 3 | 4 | @import "./vendor/font-awesome/fontawesome.scss"; 5 | @import "./vendor/font-awesome/brands.scss"; 6 | @import "./vendor/font-awesome/regular.scss"; 7 | @import "./vendor/font-awesome/solid.scss"; -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_animated.scss: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .#{$fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 17 | 100% { 18 | transform: rotate(360deg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | border: solid .08em $fa-border-color; 6 | border-radius: .1em; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix}, 14 | .fas, 15 | .far, 16 | .fal, 17 | .fab { 18 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 19 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 20 | } 21 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}, 5 | .fas, 6 | .far, 7 | .fal, 8 | .fab { 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | display: inline-block; 12 | font-style: normal; 13 | font-variant: normal; 14 | text-rendering: auto; 15 | line-height: 1; 16 | } 17 | 18 | %fa-icon { 19 | @include fa-icon; 20 | } 21 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | text-align: center; 5 | width: $fa-fw-width; 6 | } 7 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | // makes the font 33% larger relative to the icon container 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -.0667em; 9 | } 10 | 11 | .#{$fa-css-prefix}-xs { 12 | font-size: .75em; 13 | } 14 | 15 | .#{$fa-css-prefix}-sm { 16 | font-size: .875em; 17 | } 18 | 19 | @for $i from 1 through 10 { 20 | .#{$fa-css-prefix}-#{$i}x { 21 | font-size: $i * 1em; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | list-style-type: none; 6 | margin-left: $fa-li-width * 5/4; 7 | padding-left: 0; 8 | 9 | > li { position: relative; } 10 | } 11 | 12 | .#{$fa-css-prefix}-li { 13 | left: -$fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: $fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon { 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | font-weight: normal; 11 | line-height: 1; 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 16 | transform: rotate($degrees); 17 | } 18 | 19 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 20 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 21 | transform: scale($horiz, $vert); 22 | } 23 | 24 | 25 | // Only display content to screen readers. A la Bootstrap 4. 26 | // 27 | // See: http://a11yproject.com/posts/how-to-hide-content/ 28 | 29 | @mixin sr-only { 30 | border: 0; 31 | clip: rect(0, 0, 0, 0); 32 | height: 1px; 33 | margin: -1px; 34 | overflow: hidden; 35 | padding: 0; 36 | position: absolute; 37 | width: 1px; 38 | } 39 | 40 | // Use in conjunction with .sr-only to only display content when it's focused. 41 | // 42 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 43 | // 44 | // Credit: HTML5 Boilerplate 45 | 46 | @mixin sr-only-focusable { 47 | &:active, 48 | &:focus { 49 | clip: auto; 50 | height: auto; 51 | margin: 0; 52 | overflow: visible; 53 | position: static; 54 | width: auto; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | .#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .#{$fa-css-prefix}-rotate-90, 17 | .#{$fa-css-prefix}-rotate-180, 18 | .#{$fa-css-prefix}-rotate-270, 19 | .#{$fa-css-prefix}-flip-horizontal, 20 | .#{$fa-css-prefix}-flip-vertical, 21 | .#{$fa-css-prefix}-flip-both { 22 | filter: none; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only; } 5 | .sr-only-focusable { @include sr-only-focusable; } 6 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: ($fa-fw-width*2); 11 | } 12 | 13 | .#{$fa-css-prefix}-stack-1x, 14 | .#{$fa-css-prefix}-stack-2x { 15 | left: 0; 16 | position: absolute; 17 | text-align: center; 18 | width: 100%; 19 | } 20 | 21 | .#{$fa-css-prefix}-stack-1x { 22 | line-height: inherit; 23 | } 24 | 25 | .#{$fa-css-prefix}-stack-2x { 26 | font-size: 2em; 27 | } 28 | 29 | .#{$fa-css-prefix}-inverse { 30 | color: $fa-inverse; 31 | } 32 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/brands.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Brands'; 9 | font-style: normal; 10 | font-weight: normal; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-brands-400.eot'); 13 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .fab { 21 | font-family: 'Font Awesome 5 Brands'; 22 | } 23 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/fontawesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'mixins'; 7 | @import 'core'; 8 | @import 'larger'; 9 | @import 'fixed-width'; 10 | @import 'list'; 11 | @import 'bordered-pulled'; 12 | @import 'animated'; 13 | @import 'rotated-flipped'; 14 | @import 'stacked'; 15 | @import 'icons'; 16 | @import 'screen-reader'; 17 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/regular.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 400; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-regular-400.eot'); 13 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .far { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 400; 23 | } 24 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/solid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-solid-900.eot'); 13 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .fa, 21 | .fas { 22 | font-family: 'Font Awesome 5 Free'; 23 | font-weight: 900; 24 | } 25 | -------------------------------------------------------------------------------- /resources/sass/vendor/font-awesome/v4-shims.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'shims'; 7 | -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/css/nucleo-svg.css: -------------------------------------------------------------------------------- 1 | /* Generated using nucleoapp.com */ 2 | /* -------------------------------- 3 | 4 | Icon colors 5 | 6 | -------------------------------- */ 7 | 8 | .icon { 9 | display: inline-block; 10 | /* icon primary color */ 11 | color: #111111; 12 | height: 1em; 13 | width: 1em; 14 | } 15 | 16 | .icon use { 17 | /* icon secondary color - fill */ 18 | fill: #7ea6f6; 19 | } 20 | 21 | .icon.icon-outline use { 22 | /* icon secondary color - stroke */ 23 | stroke: #7ea6f6; 24 | } 25 | 26 | /* -------------------------------- 27 | 28 | Change icon size 29 | 30 | -------------------------------- */ 31 | 32 | .icon-xs { 33 | height: 0.5em; 34 | width: 0.5em; 35 | } 36 | 37 | .icon-sm { 38 | height: 0.8em; 39 | width: 0.8em; 40 | } 41 | 42 | .icon-lg { 43 | height: 1.6em; 44 | width: 1.6em; 45 | } 46 | 47 | .icon-xl { 48 | height: 2em; 49 | width: 2em; 50 | } 51 | 52 | /* -------------------------------- 53 | 54 | Align icon and text 55 | 56 | -------------------------------- */ 57 | 58 | .icon-text-aligner { 59 | /* add this class to parent element that contains icon + text */ 60 | display: flex; 61 | align-items: center; 62 | } 63 | 64 | .icon-text-aligner .icon { 65 | color: inherit; 66 | margin-right: 0.4em; 67 | } 68 | 69 | .icon-text-aligner .icon use { 70 | color: inherit; 71 | fill: currentColor; 72 | } 73 | 74 | .icon-text-aligner .icon.icon-outline use { 75 | stroke: currentColor; 76 | } 77 | 78 | /* -------------------------------- 79 | 80 | Icon reset values - used to enable color customizations 81 | 82 | -------------------------------- */ 83 | 84 | .icon { 85 | fill: currentColor; 86 | stroke: none; 87 | } 88 | 89 | .icon.icon-outline { 90 | fill: none; 91 | stroke: currentColor; 92 | } 93 | 94 | .icon use { 95 | stroke: none; 96 | } 97 | 98 | .icon.icon-outline use { 99 | fill: none; 100 | } 101 | 102 | /* -------------------------------- 103 | 104 | Stroke effects - Nucleo outline icons 105 | 106 | - 16px icons -> up to 1px stroke (16px outline icons do not support stroke changes) 107 | - 24px, 32px icons -> up to 2px stroke 108 | - 48px, 64px icons -> up to 4px stroke 109 | 110 | -------------------------------- */ 111 | 112 | .icon-outline.icon-stroke-1 { 113 | stroke-width: 1px; 114 | } 115 | 116 | .icon-outline.icon-stroke-2 { 117 | stroke-width: 2px; 118 | } 119 | 120 | .icon-outline.icon-stroke-3 { 121 | stroke-width: 3px; 122 | } 123 | 124 | .icon-outline.icon-stroke-4 { 125 | stroke-width: 4px; 126 | } 127 | 128 | .icon-outline.icon-stroke-1 use, 129 | .icon-outline.icon-stroke-3 use { 130 | -webkit-transform: translateX(0.5px) translateY(0.5px); 131 | -moz-transform: translateX(0.5px) translateY(0.5px); 132 | -ms-transform: translateX(0.5px) translateY(0.5px); 133 | -o-transform: translateX(0.5px) translateY(0.5px); 134 | transform: translateX(0.5px) translateY(0.5px); 135 | } -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/css/nucleo.css: -------------------------------------------------------------------------------- 1 | /*-------------------------------- 2 | 3 | hermes-dashboard-icons Web Font - built using nucleoapp.com 4 | License - nucleoapp.com/license/ 5 | 6 | -------------------------------- */ 7 | @font-face { 8 | font-family: 'NucleoIcons'; 9 | src: url('../fonts/nucleo-icons.eot'); 10 | src: url('../fonts/nucleo-icons.eot') format('embedded-opentype'), url('../fonts/nucleo-icons.woff2') format('woff2'), url('../fonts/nucleo-icons.woff') format('woff'), url('../fonts/nucleo-icons.ttf') format('truetype'), url('../fonts/nucleo-icons.svg') format('svg'); 11 | font-weight: normal; 12 | font-style: normal; 13 | } 14 | /*------------------------ 15 | base class definition 16 | -------------------------*/ 17 | .ni { 18 | display: inline-block; 19 | font: normal normal normal 14px/1 NucleoIcons; 20 | font-size: inherit; 21 | text-rendering: auto; 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | /*------------------------ 26 | change icon size 27 | -------------------------*/ 28 | .ni-lg { 29 | font-size: 1.33333333em; 30 | line-height: 0.75em; 31 | vertical-align: -15%; 32 | } 33 | .ni-2x { 34 | font-size: 2em; 35 | } 36 | .ni-3x { 37 | font-size: 3em; 38 | } 39 | .ni-4x { 40 | font-size: 4em; 41 | } 42 | .ni-5x { 43 | font-size: 5em; 44 | } 45 | 46 | /*---------------------------------- 47 | add a square/circle background 48 | -----------------------------------*/ 49 | .ni.square, 50 | .ni.circle { 51 | padding: 0.33333333em; 52 | vertical-align: -16%; 53 | background-color: #eee; 54 | } 55 | .ni.circle { 56 | border-radius: 50%; 57 | } 58 | /*------------------------ 59 | list icons 60 | -------------------------*/ 61 | .ni-ul { 62 | padding-left: 0; 63 | margin-left: 2.14285714em; 64 | list-style-type: none; 65 | } 66 | .ni-ul > li { 67 | position: relative; 68 | } 69 | .ni-ul > li > .ni { 70 | position: absolute; 71 | left: -1.57142857em; 72 | top: 0.14285714em; 73 | text-align: center; 74 | } 75 | .ni-ul > li > .ni.lg { 76 | top: 0; 77 | left: -1.35714286em; 78 | } 79 | .ni-ul > li > .ni.circle, 80 | .ni-ul > li > .ni.square { 81 | top: -0.19047619em; 82 | left: -1.9047619em; 83 | } 84 | /*------------------------ 85 | spinning icons 86 | -------------------------*/ 87 | .ni.spin { 88 | -webkit-animation: nc-spin 2s infinite linear; 89 | -moz-animation: nc-spin 2s infinite linear; 90 | animation: nc-spin 2s infinite linear; 91 | } 92 | @-webkit-keyframes nc-spin { 93 | 0% { 94 | -webkit-transform: rotate(0deg); 95 | } 96 | 100% { 97 | -webkit-transform: rotate(360deg); 98 | } 99 | } 100 | @-moz-keyframes nc-spin { 101 | 0% { 102 | -moz-transform: rotate(0deg); 103 | } 104 | 100% { 105 | -moz-transform: rotate(360deg); 106 | } 107 | } 108 | @keyframes nc-spin { 109 | 0% { 110 | -webkit-transform: rotate(0deg); 111 | -moz-transform: rotate(0deg); 112 | -ms-transform: rotate(0deg); 113 | -o-transform: rotate(0deg); 114 | transform: rotate(0deg); 115 | } 116 | 100% { 117 | -webkit-transform: rotate(360deg); 118 | -moz-transform: rotate(360deg); 119 | -ms-transform: rotate(360deg); 120 | -o-transform: rotate(360deg); 121 | transform: rotate(360deg); 122 | } 123 | } 124 | /*------------------------ 125 | rotated/flipped icons 126 | -------------------------*/ 127 | .ni.rotate-90 { 128 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 129 | -webkit-transform: rotate(90deg); 130 | -moz-transform: rotate(90deg); 131 | -ms-transform: rotate(90deg); 132 | -o-transform: rotate(90deg); 133 | transform: rotate(90deg); 134 | } 135 | .ni.rotate-180 { 136 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 137 | -webkit-transform: rotate(180deg); 138 | -moz-transform: rotate(180deg); 139 | -ms-transform: rotate(180deg); 140 | -o-transform: rotate(180deg); 141 | transform: rotate(180deg); 142 | } 143 | .ni.rotate-270 { 144 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 145 | -webkit-transform: rotate(270deg); 146 | -moz-transform: rotate(270deg); 147 | -ms-transform: rotate(270deg); 148 | -o-transform: rotate(270deg); 149 | transform: rotate(270deg); 150 | } 151 | .ni.flip-y { 152 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0); 153 | -webkit-transform: scale(-1, 1); 154 | -moz-transform: scale(-1, 1); 155 | -ms-transform: scale(-1, 1); 156 | -o-transform: scale(-1, 1); 157 | transform: scale(-1, 1); 158 | } 159 | .ni.flip-x { 160 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 161 | -webkit-transform: scale(1, -1); 162 | -moz-transform: scale(1, -1); 163 | -ms-transform: scale(1, -1); 164 | -o-transform: scale(1, -1); 165 | transform: scale(1, -1); 166 | } 167 | /*------------------------ 168 | font icons 169 | -------------------------*/ 170 | 171 | .ni-active-40::before { 172 | content: "\ea02"; 173 | } 174 | 175 | .ni-air-baloon::before { 176 | content: "\ea03"; 177 | } 178 | 179 | .ni-album-2::before { 180 | content: "\ea04"; 181 | } 182 | 183 | .ni-align-center::before { 184 | content: "\ea05"; 185 | } 186 | 187 | .ni-align-left-2::before { 188 | content: "\ea06"; 189 | } 190 | 191 | .ni-ambulance::before { 192 | content: "\ea07"; 193 | } 194 | 195 | .ni-app::before { 196 | content: "\ea08"; 197 | } 198 | 199 | .ni-archive-2::before { 200 | content: "\ea09"; 201 | } 202 | 203 | .ni-atom::before { 204 | content: "\ea0a"; 205 | } 206 | 207 | .ni-badge::before { 208 | content: "\ea0b"; 209 | } 210 | 211 | .ni-bag-17::before { 212 | content: "\ea0c"; 213 | } 214 | 215 | .ni-basket::before { 216 | content: "\ea0d"; 217 | } 218 | 219 | .ni-bell-55::before { 220 | content: "\ea0e"; 221 | } 222 | 223 | .ni-bold-down::before { 224 | content: "\ea0f"; 225 | } 226 | 227 | .ni-bold-left::before { 228 | content: "\ea10"; 229 | } 230 | 231 | .ni-bold-right::before { 232 | content: "\ea11"; 233 | } 234 | 235 | .ni-bold-up::before { 236 | content: "\ea12"; 237 | } 238 | 239 | .ni-bold::before { 240 | content: "\ea13"; 241 | } 242 | 243 | .ni-book-bookmark::before { 244 | content: "\ea14"; 245 | } 246 | 247 | .ni-books::before { 248 | content: "\ea15"; 249 | } 250 | 251 | .ni-box-2::before { 252 | content: "\ea16"; 253 | } 254 | 255 | .ni-briefcase-24::before { 256 | content: "\ea17"; 257 | } 258 | 259 | .ni-building::before { 260 | content: "\ea18"; 261 | } 262 | 263 | .ni-bulb-61::before { 264 | content: "\ea19"; 265 | } 266 | 267 | .ni-bullet-list-67::before { 268 | content: "\ea1a"; 269 | } 270 | 271 | .ni-bus-front-12::before { 272 | content: "\ea1b"; 273 | } 274 | 275 | .ni-button-pause::before { 276 | content: "\ea1c"; 277 | } 278 | 279 | .ni-button-play::before { 280 | content: "\ea1d"; 281 | } 282 | 283 | .ni-button-power::before { 284 | content: "\ea1e"; 285 | } 286 | 287 | .ni-calendar-grid-58::before { 288 | content: "\ea1f"; 289 | } 290 | 291 | .ni-camera-compact::before { 292 | content: "\ea20"; 293 | } 294 | 295 | .ni-caps-small::before { 296 | content: "\ea21"; 297 | } 298 | 299 | .ni-cart::before { 300 | content: "\ea22"; 301 | } 302 | 303 | .ni-chart-bar-32::before { 304 | content: "\ea23"; 305 | } 306 | 307 | .ni-chart-pie-35::before { 308 | content: "\ea24"; 309 | } 310 | 311 | .ni-chat-round::before { 312 | content: "\ea25"; 313 | } 314 | 315 | .ni-check-bold::before { 316 | content: "\ea26"; 317 | } 318 | 319 | .ni-circle-08::before { 320 | content: "\ea27"; 321 | } 322 | 323 | .ni-cloud-download-95::before { 324 | content: "\ea28"; 325 | } 326 | 327 | .ni-cloud-upload-96::before { 328 | content: "\ea29"; 329 | } 330 | 331 | .ni-compass-04::before { 332 | content: "\ea2a"; 333 | } 334 | 335 | .ni-controller::before { 336 | content: "\ea2b"; 337 | } 338 | 339 | .ni-credit-card::before { 340 | content: "\ea2c"; 341 | } 342 | 343 | .ni-curved-next::before { 344 | content: "\ea2d"; 345 | } 346 | 347 | .ni-delivery-fast::before { 348 | content: "\ea2e"; 349 | } 350 | 351 | .ni-diamond::before { 352 | content: "\ea2f"; 353 | } 354 | 355 | .ni-email-83::before { 356 | content: "\ea30"; 357 | } 358 | 359 | .ni-fat-add::before { 360 | content: "\ea31"; 361 | } 362 | 363 | .ni-fat-delete::before { 364 | content: "\ea32"; 365 | } 366 | 367 | .ni-fat-remove::before { 368 | content: "\ea33"; 369 | } 370 | 371 | .ni-favourite-28::before { 372 | content: "\ea34"; 373 | } 374 | 375 | .ni-folder-17::before { 376 | content: "\ea35"; 377 | } 378 | 379 | .ni-glasses-2::before { 380 | content: "\ea36"; 381 | } 382 | 383 | .ni-hat-3::before { 384 | content: "\ea37"; 385 | } 386 | 387 | .ni-headphones::before { 388 | content: "\ea38"; 389 | } 390 | 391 | .ni-html5::before { 392 | content: "\ea39"; 393 | } 394 | 395 | .ni-istanbul::before { 396 | content: "\ea3a"; 397 | } 398 | 399 | .ni-key-25::before { 400 | content: "\ea3b"; 401 | } 402 | 403 | .ni-laptop::before { 404 | content: "\ea3c"; 405 | } 406 | 407 | .ni-like-2::before { 408 | content: "\ea3d"; 409 | } 410 | 411 | .ni-lock-circle-open::before { 412 | content: "\ea3e"; 413 | } 414 | 415 | .ni-map-big::before { 416 | content: "\ea3f"; 417 | } 418 | 419 | .ni-mobile-button::before { 420 | content: "\ea40"; 421 | } 422 | 423 | .ni-money-coins::before { 424 | content: "\ea41"; 425 | } 426 | 427 | .ni-note-03::before { 428 | content: "\ea42"; 429 | } 430 | 431 | .ni-notification-70::before { 432 | content: "\ea43"; 433 | } 434 | 435 | .ni-palette::before { 436 | content: "\ea44"; 437 | } 438 | 439 | .ni-paper-diploma::before { 440 | content: "\ea45"; 441 | } 442 | 443 | .ni-pin-3::before { 444 | content: "\ea46"; 445 | } 446 | 447 | .ni-planet::before { 448 | content: "\ea47"; 449 | } 450 | 451 | .ni-ruler-pencil::before { 452 | content: "\ea48"; 453 | } 454 | 455 | .ni-satisfied::before { 456 | content: "\ea49"; 457 | } 458 | 459 | .ni-scissors::before { 460 | content: "\ea4a"; 461 | } 462 | 463 | .ni-send::before { 464 | content: "\ea4b"; 465 | } 466 | 467 | .ni-settings-gear-65::before { 468 | content: "\ea4c"; 469 | } 470 | 471 | .ni-settings::before { 472 | content: "\ea4d"; 473 | } 474 | 475 | .ni-single-02::before { 476 | content: "\ea4e"; 477 | } 478 | 479 | .ni-single-copy-04::before { 480 | content: "\ea4f"; 481 | } 482 | 483 | .ni-sound-wave::before { 484 | content: "\ea50"; 485 | } 486 | 487 | .ni-spaceship::before { 488 | content: "\ea51"; 489 | } 490 | 491 | .ni-square-pin::before { 492 | content: "\ea52"; 493 | } 494 | 495 | .ni-support-16::before { 496 | content: "\ea53"; 497 | } 498 | 499 | .ni-tablet-button::before { 500 | content: "\ea54"; 501 | } 502 | 503 | .ni-tag::before { 504 | content: "\ea55"; 505 | } 506 | 507 | .ni-tie-bow::before { 508 | content: "\ea56"; 509 | } 510 | 511 | .ni-time-alarm::before { 512 | content: "\ea57"; 513 | } 514 | 515 | .ni-trophy::before { 516 | content: "\ea58"; 517 | } 518 | 519 | .ni-tv-2::before { 520 | content: "\ea59"; 521 | } 522 | 523 | .ni-umbrella-13::before { 524 | content: "\ea5a"; 525 | } 526 | 527 | .ni-user-run::before { 528 | content: "\ea5b"; 529 | } 530 | 531 | .ni-vector::before { 532 | content: "\ea5c"; 533 | } 534 | 535 | .ni-watch-time::before { 536 | content: "\ea5d"; 537 | } 538 | 539 | .ni-world::before { 540 | content: "\ea5e"; 541 | } 542 | 543 | .ni-zoom-split-in::before { 544 | content: "\ea5f"; 545 | } 546 | 547 | .ni-collection::before { 548 | content: "\ea60"; 549 | } 550 | 551 | .ni-image::before { 552 | content: "\ea61"; 553 | } 554 | 555 | .ni-shop::before { 556 | content: "\ea62"; 557 | } 558 | 559 | .ni-ungroup::before { 560 | content: "\ea63"; 561 | } 562 | 563 | .ni-world-2::before { 564 | content: "\ea64"; 565 | } 566 | 567 | .ni-ui-04::before { 568 | content: "\ea65"; 569 | } 570 | 571 | 572 | /* all icon font classes list here */ 573 | -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/fonts/nucleo-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/resources/sass/vendor/nucleo/fonts/nucleo-icons.eot -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/fonts/nucleo-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/resources/sass/vendor/nucleo/fonts/nucleo-icons.ttf -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/fonts/nucleo-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/resources/sass/vendor/nucleo/fonts/nucleo-icons.woff -------------------------------------------------------------------------------- /resources/sass/vendor/nucleo/fonts/nucleo-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saleem-hadad/larecipe/a5bd62b9ee2c9e15dee97a5cb7026736c8467269/resources/sass/vendor/nucleo/fonts/nucleo-icons.woff2 -------------------------------------------------------------------------------- /resources/sass/vendor/prism/_code-toolbar.scss: -------------------------------------------------------------------------------- 1 | div.code-toolbar { 2 | position: relative; 3 | } 4 | 5 | div.code-toolbar > .toolbar { 6 | position: absolute; 7 | top: 15px; 8 | right: 10px; 9 | transition: opacity 0.3s ease-in-out; 10 | opacity: 0; 11 | } 12 | 13 | div.code-toolbar:hover > .toolbar { 14 | opacity: 1; 15 | } 16 | 17 | div.code-toolbar > .toolbar .toolbar-item { 18 | display: inline-block; 19 | } 20 | 21 | div.code-toolbar > .toolbar a { 22 | cursor: pointer; 23 | } 24 | 25 | div.code-toolbar > .toolbar button { 26 | background: none; 27 | border: 0; 28 | color: inherit; 29 | font: inherit; 30 | line-height: normal; 31 | overflow: visible; 32 | padding: 0; 33 | -webkit-user-select: none; /* for button */ 34 | -moz-user-select: none; 35 | -ms-user-select: none; 36 | } 37 | 38 | div.code-toolbar > .toolbar a, 39 | div.code-toolbar > .toolbar button, 40 | div.code-toolbar > .toolbar span { 41 | @apply text-white bg-primary p-2 shadow rounded-lg text-sm; 42 | transition: box-shadow 0.2s; 43 | } 44 | 45 | div.code-toolbar > .toolbar a:hover, 46 | div.code-toolbar > .toolbar a:focus, 47 | div.code-toolbar > .toolbar button:hover, 48 | div.code-toolbar > .toolbar button:focus, 49 | div.code-toolbar > .toolbar span:hover, 50 | div.code-toolbar > .toolbar span:focus { 51 | color: #fff; 52 | text-decoration: none; 53 | } 54 | 55 | div.code-toolbar > .toolbar a, 56 | div.code-toolbar > .toolbar button, 57 | div.code-toolbar > .toolbar span { 58 | padding: 0.25rem 0.5em; 59 | } 60 | 61 | div.code-toolbar > .toolbar a:hover, 62 | div.code-toolbar > .toolbar a:focus, 63 | div.code-toolbar > .toolbar button:hover, 64 | div.code-toolbar > .toolbar button:focus, 65 | div.code-toolbar > .toolbar span:hover, 66 | div.code-toolbar > .toolbar span:focus { 67 | @apply shadow-md; 68 | } -------------------------------------------------------------------------------- /resources/sass/vendor/prism/_dark.scss: -------------------------------------------------------------------------------- 1 | .documentation.is-dark { 2 | code[class*="language-"], 3 | pre[class*="language-"] { 4 | text-shadow: none; 5 | } 6 | 7 | :not(pre) > code[class*="language-"], 8 | pre[class*="language-"] { 9 | background: #344258 !important; 10 | } 11 | 12 | code[class*="language-"], 13 | pre[class*="language-"] { 14 | color: #ccc; 15 | background: none; 16 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 17 | text-align: left; 18 | white-space: pre; 19 | word-spacing: normal; 20 | word-break: normal; 21 | word-wrap: normal; 22 | line-height: 1.5; 23 | 24 | -moz-tab-size: 4; 25 | -o-tab-size: 4; 26 | tab-size: 4; 27 | 28 | -webkit-hyphens: none; 29 | -moz-hyphens: none; 30 | -ms-hyphens: none; 31 | hyphens: none; 32 | } 33 | 34 | /* Code blocks */ 35 | pre[class*="language-"] { 36 | padding: 1em; 37 | margin: 0.5em 0; 38 | overflow: auto; 39 | } 40 | 41 | /* Inline code */ 42 | :not(pre) > code[class*="language-"] { 43 | padding: 0.1em; 44 | border-radius: 0.3em; 45 | white-space: normal; 46 | } 47 | 48 | :not(pre) > code[class*="language-"], 49 | pre[class*="language-"] { 50 | padding: 20px; 51 | border-radius: 5px; 52 | } 53 | 54 | .token.comment, 55 | .token.block-comment, 56 | .token.prolog, 57 | .token.doctype, 58 | .token.cdata { 59 | color: #999; 60 | } 61 | 62 | .token.punctuation { 63 | color: #ccc; 64 | } 65 | 66 | .token.tag, 67 | .token.attr-name, 68 | .token.namespace, 69 | .token.deleted { 70 | color: #e2777a; 71 | } 72 | 73 | .token.function-name { 74 | color: #6196cc; 75 | } 76 | 77 | .token.boolean, 78 | .token.number, 79 | .token.function { 80 | color: #f08d49; 81 | } 82 | 83 | .token.property, 84 | .token.class-name, 85 | .token.constant, 86 | .token.symbol { 87 | color: #f8c555; 88 | } 89 | 90 | .token.selector, 91 | .token.important, 92 | .token.atrule, 93 | .token.keyword, 94 | .token.builtin { 95 | color: #cc99cd; 96 | } 97 | 98 | .token.string, 99 | .token.char, 100 | .token.attr-value, 101 | .token.regex, 102 | .token.variable { 103 | color: #7ec699; 104 | } 105 | 106 | .token.operator, 107 | .token.entity, 108 | .token.url { 109 | color: #67cdcc; 110 | } 111 | 112 | .token.important, 113 | .token.bold { 114 | font-weight: bold; 115 | } 116 | .token.italic { 117 | font-style: italic; 118 | } 119 | 120 | .token.entity { 121 | cursor: help; 122 | } 123 | 124 | .token.inserted { 125 | color: green; 126 | } 127 | 128 | pre[data-line] { 129 | position: relative; 130 | padding: 1em 0 1em 3em; 131 | } 132 | 133 | .line-highlight { 134 | position: absolute; 135 | left: 0; 136 | right: 0; 137 | padding: inherit 0; 138 | margin-top: 1em; /* Same as .prism’s padding-top */ 139 | 140 | background: hsla(24, 20%, 50%, 0.08); 141 | background: linear-gradient( 142 | to right, 143 | hsla(24, 20%, 50%, 0.1) 70%, 144 | hsla(24, 20%, 50%, 0) 145 | ); 146 | 147 | pointer-events: none; 148 | 149 | line-height: inherit; 150 | white-space: pre; 151 | } 152 | 153 | .line-highlight:before, 154 | .line-highlight[data-end]:after { 155 | content: attr(data-start); 156 | position: absolute; 157 | top: 0.4em; 158 | left: 0.6em; 159 | min-width: 1em; 160 | padding: 0 0.5em; 161 | background-color: hsla(24, 20%, 50%, 0.4); 162 | color: hsl(24, 20%, 95%); 163 | font: bold 65%/1.5 sans-serif; 164 | text-align: center; 165 | vertical-align: 0.3em; 166 | border-radius: 999px; 167 | text-shadow: none; 168 | box-shadow: 0 1px white; 169 | } 170 | 171 | .line-highlight[data-end]:after { 172 | content: attr(data-end); 173 | top: auto; 174 | bottom: 0.4em; 175 | } 176 | 177 | .line-numbers .line-highlight:before, 178 | .line-numbers .line-highlight:after { 179 | content: none; 180 | } 181 | 182 | pre[class*="language-"].line-numbers { 183 | position: relative; 184 | padding-left: 3.8em; 185 | counter-reset: linenumber; 186 | } 187 | 188 | pre[class*="language-"].line-numbers > code { 189 | position: relative; 190 | white-space: inherit; 191 | } 192 | 193 | .line-numbers .line-numbers-rows { 194 | position: absolute; 195 | pointer-events: none; 196 | top: 0; 197 | font-size: 100%; 198 | left: -3.8em; 199 | width: 3em; /* works for line-numbers below 1000 lines */ 200 | letter-spacing: -1px; 201 | border-right: 1px solid #999; 202 | 203 | -webkit-user-select: none; 204 | -moz-user-select: none; 205 | -ms-user-select: none; 206 | user-select: none; 207 | } 208 | 209 | .line-numbers-rows > span { 210 | pointer-events: none; 211 | display: block; 212 | counter-increment: linenumber; 213 | } 214 | 215 | .line-numbers-rows > span:before { 216 | content: counter(linenumber); 217 | color: #999; 218 | display: block; 219 | padding-right: 0.8em; 220 | text-align: right; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /resources/sass/vendor/prism/_light.scss: -------------------------------------------------------------------------------- 1 | .documentation.is-light { 2 | code[class*="language-"], 3 | pre[class*="language-"] { 4 | color: black; 5 | text-shadow: 0 1px white; 6 | direction: ltr; 7 | text-align: left; 8 | white-space: pre; 9 | word-spacing: normal; 10 | word-break: normal; 11 | line-height: 1.7; 12 | font-size: 14px; 13 | 14 | -moz-tab-size: 4; 15 | -o-tab-size: 4; 16 | tab-size: 4; 17 | 18 | -webkit-hyphens: none; 19 | -moz-hyphens: none; 20 | -ms-hyphens: none; 21 | hyphens: none; 22 | } 23 | 24 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 25 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 26 | text-shadow: none; 27 | background: #b3d4fc; 28 | } 29 | 30 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 31 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 32 | text-shadow: none; 33 | background: #b3d4fc; 34 | } 35 | 36 | @media print { 37 | code[class*="language-"], 38 | pre[class*="language-"] { 39 | text-shadow: none; 40 | } 41 | } 42 | 43 | /* Code blocks */ 44 | pre[class*="language-"] { 45 | padding: 1em; 46 | margin: 10px 0 20px; 47 | overflow: auto; 48 | } 49 | 50 | :not(pre) > code[class*="language-"], 51 | pre[class*="language-"] { 52 | background: #fff; 53 | border-radius: 5px; 54 | padding: 20px; 55 | @apply shadow border-t-4 border-primary; 56 | } 57 | 58 | /* Inline code */ 59 | :not(pre) > code[class*="language-"] { 60 | padding: 1px 5px; 61 | border-radius: 3px; 62 | } 63 | 64 | .token.comment, 65 | .token.prolog, 66 | .token.doctype, 67 | .token.cdata { 68 | color: #999; 69 | } 70 | 71 | .token.punctuation { 72 | color: #999; 73 | } 74 | 75 | .namespace { 76 | opacity: .7; 77 | } 78 | 79 | .token.property, 80 | .token.tag, 81 | .token.boolean, 82 | .token.number, 83 | .token.constant, 84 | .token.symbol, 85 | .token.deleted { 86 | color: #DA564A; 87 | } 88 | 89 | .token.scope, .token.attr-name { 90 | color: #DA564A; 91 | } 92 | 93 | .token.selector, 94 | .token.string, 95 | .token.char, 96 | .token.builtin, 97 | .token.inserted { 98 | color: #2E7D32; 99 | } 100 | 101 | .token.operator, 102 | .token.entity, 103 | .token.url, 104 | .language-css .token.string, 105 | .style .token.string { 106 | color: #555; 107 | } 108 | 109 | .token.atrule, 110 | .token.attr-value, 111 | .token.keyword { 112 | color: #07a; 113 | } 114 | 115 | .token.function { 116 | color: #555; 117 | } 118 | 119 | .token.regex, 120 | .token.important, 121 | .token.variable { 122 | color: #4EA1DF; 123 | } 124 | 125 | .token.important, 126 | .token.bold { 127 | font-weight: bold; 128 | } 129 | .token.italic { 130 | font-style: italic; 131 | } 132 | 133 | .token.entity { 134 | cursor: help; 135 | } 136 | 137 | pre.line-numbers { 138 | position: relative; 139 | padding-left: 3.8em; 140 | padding-top: 0px; 141 | margin-top: -1px; 142 | border-radius:0; 143 | counter-reset: linenumber; 144 | } 145 | 146 | pre.line-numbers > code { 147 | position: relative; 148 | } 149 | 150 | .line-numbers .line-numbers-rows { 151 | position: absolute; 152 | pointer-events: none; 153 | top: -4px; 154 | padding-top: 0px; 155 | font-size: 100%; 156 | left: -3.8em; 157 | width: 3em; /* works for line-numbers below 1000 lines */ 158 | letter-spacing: -1px; 159 | 160 | -webkit-user-select: none; 161 | -moz-user-select: none; 162 | -ms-user-select: none; 163 | user-select: none; 164 | 165 | } 166 | 167 | .line-numbers-rows > span { 168 | pointer-events: none; 169 | display: block; 170 | counter-increment: linenumber; 171 | } 172 | 173 | .line-numbers-rows > span:before { 174 | content: counter(linenumber); 175 | color: #999; 176 | display: block; 177 | padding-right: 0.8em; 178 | text-align: right; 179 | } 180 | 181 | 182 | // Dark Theme 183 | .dark-code { 184 | code[class*="language-"], 185 | pre[class*="language-"] { 186 | color: #f8f8f2; 187 | text-shadow: 0 1px rgba(0, 0, 0, 0.3); 188 | direction: ltr; 189 | text-align: left; 190 | white-space: pre; 191 | word-spacing: normal; 192 | word-break: normal; 193 | line-height: 1.5; 194 | 195 | -moz-tab-size: 4; 196 | -o-tab-size: 4; 197 | tab-size: 4; 198 | 199 | -webkit-hyphens: none; 200 | -moz-hyphens: none; 201 | -ms-hyphens: none; 202 | hyphens: none; 203 | } 204 | 205 | /* Code blocks */ 206 | pre[class*="language-"] { 207 | padding: 1em; 208 | margin: .5em 0; 209 | overflow: auto; 210 | border-radius: 0.3em; 211 | } 212 | 213 | :not(pre) > code[class*="language-"], 214 | pre[class*="language-"] { 215 | background: #272822; 216 | } 217 | 218 | /* Inline code */ 219 | :not(pre) > code[class*="language-"] { 220 | padding: .1em; 221 | border-radius: .3em; 222 | } 223 | 224 | .token.comment, 225 | .token.prolog, 226 | .token.doctype, 227 | .token.cdata { 228 | color: slategray; 229 | } 230 | 231 | .token.punctuation { 232 | color: #f8f8f2; 233 | } 234 | 235 | .namespace { 236 | opacity: .7; 237 | } 238 | 239 | .token.property, 240 | .token.tag, 241 | .token.constant, 242 | .token.symbol, 243 | .token.deleted { 244 | color: #f92672; 245 | } 246 | 247 | .token.boolean, 248 | .token.number { 249 | color: #ae81ff; 250 | } 251 | 252 | .token.selector, 253 | .token.attr-name, 254 | .token.string, 255 | .token.char, 256 | .token.builtin, 257 | .token.inserted { 258 | color: #a6e22e; 259 | } 260 | 261 | .token.operator, 262 | .token.entity, 263 | .token.url, 264 | .language-css .token.string, 265 | .style .token.string, 266 | .token.variable { 267 | color: #f8f8f2; 268 | } 269 | 270 | .token.atrule, 271 | .token.attr-value { 272 | color: #e6db74; 273 | } 274 | 275 | .token.keyword { 276 | color: #66d9ef; 277 | } 278 | 279 | .token.regex, 280 | .token.important { 281 | color: #fd971f; 282 | } 283 | 284 | .token.important, 285 | .token.bold { 286 | font-weight: bold; 287 | } 288 | .token.italic { 289 | font-style: italic; 290 | } 291 | 292 | .token.entity { 293 | cursor: help; 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /resources/views/default.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ isset($title) ? $title . ' | ' : null }}{{ config('app.name') }} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | @if (isset($canonical) && $canonical) 16 | 17 | @endif 18 | @if($openGraph = config('larecipe.seo.og')) 19 | @foreach($openGraph as $key => $value) 20 | @if($value) 21 | 22 | @endif 23 | @endforeach 24 | @endif 25 | 26 | 27 | 28 | 29 | @if (config('larecipe.ui.fav')) 30 | 31 | 32 | 33 | @endif 34 | 35 | 36 | 37 | @if (config('larecipe.ui.fa_v4_shims', true)) 38 | 39 | @endif 40 | 41 | 42 | @include('larecipe::style') 43 | 44 | 45 | 46 | 47 | @foreach(LaRecipe::allStyles() as $name => $path) 48 | @if (preg_match('/^https?:\/\//', $path)) 49 | 50 | @else 51 | 52 | @endif 53 | @endforeach 54 | 55 | 56 | 57 |
58 | @include('larecipe::partials.nav') 59 | 60 | @include('larecipe::plugins.search') 61 | 62 | @yield('content') 63 | 64 | 65 |
66 | 67 | 68 | 71 | 72 | 77 | 78 | 79 | 80 | 83 | 84 | 85 | @if(config('larecipe.settings.ga_id')) 86 | 87 | 94 | @endif 95 | 96 | 97 | @foreach (LaRecipe::allScripts() as $name => $path) 98 | @if (preg_match('/^https?:\/\//', $path)) 99 | 100 | @else 101 | 102 | @endif 103 | @endforeach 104 | 105 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /resources/views/docs.blade.php: -------------------------------------------------------------------------------- 1 | @extends('larecipe::default') 2 | 3 | @section('content') 4 |
5 | @include('larecipe::partials.sidebar') 6 | 7 |
8 | {!! $content !!} 9 | @include('larecipe::plugins.forum') 10 |
11 |
12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/partials/404.blade.php: -------------------------------------------------------------------------------- 1 |
2 | no data 3 |

Not Found

4 | 5 | @if (! is_dir(public_path('vendor/binarytorch'))) 6 |
7 |

Please don't forget to fire the install command!

8 |

php artisan larecipe:install

9 | @endif 10 |
-------------------------------------------------------------------------------- /resources/views/partials/logo.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /resources/views/partials/nav.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
71 |
-------------------------------------------------------------------------------- /resources/views/partials/sidebar.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/plugins/forum.blade.php: -------------------------------------------------------------------------------- 1 | @if(config('larecipe.forum.enabled')) 2 | @if(config('larecipe.forum.default') == 'disqus' && config('larecipe.forum.services.disqus.site_name')) 3 |
4 |
5 | 18 | 19 | @endif 20 | @endif 21 | 22 | -------------------------------------------------------------------------------- /resources/views/plugins/search.blade.php: -------------------------------------------------------------------------------- 1 | @if(config('larecipe.search.enabled')) 2 | @if(config('larecipe.search.default') == 'algolia') 3 | 10 | @elseif(config('larecipe.search.default') == 'internal') 11 | 17 | @endif 18 | @endif -------------------------------------------------------------------------------- /resources/views/style.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /routes/LaRecipe.php: -------------------------------------------------------------------------------- 1 | name('search'); 7 | 8 | // Styles & Scripts.. 9 | Route::get('/styles/{style}', 'StyleController')->name('styles'); 10 | Route::get('/scripts/{script}', 'ScriptController')->name('scripts'); 11 | 12 | // Documentation.. 13 | Route::get('/', 'DocumentationController@index')->name('index'); 14 | Route::get('/{version}/{page?}', 'DocumentationController@show')->where('page', '(.*)')->name('show'); 15 | -------------------------------------------------------------------------------- /src/Cache.php: -------------------------------------------------------------------------------- 1 | cache = $cache; 25 | } 26 | 27 | /** 28 | * Wrapper. 29 | * 30 | * @param \Closure $callback 31 | * @param string $key 32 | * @return mixed 33 | */ 34 | public function remember(\Closure $callback, $key) 35 | { 36 | if (! config('larecipe.cache.enabled')) { 37 | return $callback(); 38 | } 39 | 40 | $cachePeriod = $this->checkTtlNeedsChanged(config('larecipe.cache.period')); 41 | 42 | return $this->cache->remember($key, $cachePeriod, $callback); 43 | } 44 | 45 | /** 46 | * Checks if minutes need to be changed to seconds 47 | * 48 | * @param $ttl 49 | * @return float|int 50 | */ 51 | public function checkTtlNeedsChanged($ttl) 52 | { 53 | $app_version = explode('.', app()->version()); 54 | 55 | if (((int) $app_version[0] == 5 && (int) $app_version[1] >= 8) || $app_version[0] > 5) { 56 | return config('larecipe.cache.period') * 60; 57 | } 58 | 59 | return $ttl; 60 | } 61 | } -------------------------------------------------------------------------------- /src/Commands/AssetCommand.php: -------------------------------------------------------------------------------- 1 | hasValidNameArgument()) { 36 | return; 37 | } 38 | 39 | (new Filesystem)->copyDirectory( 40 | __DIR__.'/../../stubs/asset-stubs', 41 | $this->assetPath() 42 | ); 43 | 44 | // AssetServiceProvider.php replacements... 45 | $this->replace('{{ namespace }}', $this->assetNamespace(), $this->assetPath().'/src/AssetServiceProvider.stub'); 46 | $this->replace('{{ component }}', $this->assetName(), $this->assetPath().'/src/AssetServiceProvider.stub'); 47 | $this->replace('{{ name }}', $this->assetName(), $this->assetPath().'/src/AssetServiceProvider.stub'); 48 | 49 | // Asset composer.json replacements... 50 | $this->replace('{{ name }}', $this->argument('name'), $this->assetPath().'/composer.json'); 51 | $this->replace('{{ escapedNamespace }}', $this->escapedAssetNamespace(), $this->assetPath().'/composer.json'); 52 | 53 | // Rename the stubs with the proper file extensions... 54 | $this->renameStubs(); 55 | 56 | // Register the asset... 57 | $this->addAssetRepositoryToRootComposer(); 58 | $this->addAssetPackageToRootComposer(); 59 | $this->addScriptsToNpmPackage(); 60 | 61 | if ($this->confirm("Would you like to install the asset's NPM dependencies?", true)) { 62 | $this->installNpmDependencies(); 63 | 64 | $this->output->newLine(); 65 | } 66 | 67 | if ($this->confirm("Would you like to compile the asset's assets?", true)) { 68 | $this->compile(); 69 | 70 | $this->output->newLine(); 71 | } 72 | 73 | if ($this->confirm('Would you like to update your Composer packages?', true)) { 74 | $this->composerUpdate(); 75 | } 76 | } 77 | 78 | /** 79 | * Get the array of stubs that need PHP file extensions. 80 | * 81 | * @return array 82 | */ 83 | protected function stubsToRename() 84 | { 85 | return [ 86 | $this->assetPath().'/src/AssetServiceProvider.stub', 87 | ]; 88 | } 89 | 90 | /** 91 | * Add a path repository for the asset to the application's composer.json file. 92 | * 93 | * @return void 94 | */ 95 | protected function addAssetRepositoryToRootComposer() 96 | { 97 | $composer = json_decode(file_get_contents(base_path('composer.json')), true); 98 | 99 | $composer['repositories'][] = [ 100 | 'type' => 'path', 101 | 'url' => './'.$this->relativeAssetPath(), 102 | ]; 103 | 104 | file_put_contents( 105 | base_path('composer.json'), 106 | json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) 107 | ); 108 | } 109 | 110 | /** 111 | * Add a package entry for the asset to the application's composer.json file. 112 | * 113 | * @return void 114 | */ 115 | protected function addAssetPackageToRootComposer() 116 | { 117 | $composer = json_decode(file_get_contents(base_path('composer.json')), true); 118 | 119 | $composer['require'][$this->argument('name')] = '*'; 120 | 121 | file_put_contents( 122 | base_path('composer.json'), 123 | json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) 124 | ); 125 | } 126 | 127 | /** 128 | * Add a path repository for the asset to the application's composer.json file. 129 | * 130 | * @return void 131 | */ 132 | protected function addScriptsToNpmPackage() 133 | { 134 | $package = json_decode(file_get_contents(base_path('package.json')), true); 135 | 136 | $package['scripts']['build-'.$this->assetName()] = 'cd '.$this->relativeAssetPath().' && npm run dev'; 137 | $package['scripts']['build-'.$this->assetName().'-prod'] = 'cd '.$this->relativeAssetPath().' && npm run prod'; 138 | 139 | file_put_contents( 140 | base_path('package.json'), 141 | json_encode($package, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) 142 | ); 143 | } 144 | 145 | /** 146 | * Install the asset's NPM dependencies. 147 | * 148 | * @return void 149 | */ 150 | protected function installNpmDependencies() 151 | { 152 | $this->runProcess('npm set progress=false', $this->assetPath()); 153 | $this->runProcess('npm install', $this->assetPath()); 154 | } 155 | 156 | /** 157 | * Compile the asset's assets. 158 | * 159 | * @return void 160 | */ 161 | protected function compile() 162 | { 163 | $this->runProcess('npm run dev', $this->assetPath()); 164 | } 165 | 166 | /** 167 | * Update the project's composer dependencies. 168 | * 169 | * @return void 170 | */ 171 | protected function composerUpdate() 172 | { 173 | $this->runProcess('composer update', getcwd()); 174 | } 175 | 176 | /** 177 | * Replace the given string in the given file. 178 | * 179 | * @param string $search 180 | * @param string $replace 181 | * @param string $path 182 | * @return void 183 | */ 184 | protected function replace($search, $replace, $path) 185 | { 186 | file_put_contents($path, str_replace($search, $replace, file_get_contents($path))); 187 | } 188 | 189 | /** 190 | * Get the path to the asset. 191 | * 192 | * @return string 193 | */ 194 | protected function assetPath() 195 | { 196 | return base_path($this->relativeAssetPath()); 197 | } 198 | 199 | /** 200 | * Get the relative path to the asset. 201 | * 202 | * @return string 203 | */ 204 | protected function relativeAssetPath() 205 | { 206 | return config('larecipe.packages.path', 'larecipe-components').'/'.$this->assetClass(); 207 | } 208 | 209 | /** 210 | * Get the asset's namespace. 211 | * 212 | * @return string 213 | */ 214 | protected function assetNamespace() 215 | { 216 | return Str::studly($this->assetVendor()).'\\'.$this->assetClass(); 217 | } 218 | 219 | /** 220 | * Get the asset's escaped namespace. 221 | * 222 | * @return string 223 | */ 224 | protected function escapedAssetNamespace() 225 | { 226 | return str_replace('\\', '\\\\', $this->assetNamespace()); 227 | } 228 | 229 | /** 230 | * Get the asset's class name. 231 | * 232 | * @return string 233 | */ 234 | protected function assetClass() 235 | { 236 | return Str::studly($this->assetName()); 237 | } 238 | 239 | /** 240 | * Get the asset's vendor. 241 | * 242 | * @return string 243 | */ 244 | protected function assetVendor() 245 | { 246 | return explode('/', $this->argument('name'))[0]; 247 | } 248 | 249 | /** 250 | * Get the asset's base name. 251 | * 252 | * @return string 253 | */ 254 | protected function assetName() 255 | { 256 | return explode('/', $this->argument('name'))[1]; 257 | } 258 | 259 | /** 260 | * Determine if the name argument is valid. 261 | * 262 | * @return bool 263 | */ 264 | public function hasValidNameArgument() 265 | { 266 | $name = $this->argument('name'); 267 | 268 | if (! Str::contains($name, '/')) { 269 | $this->error("The name argument expects a vendor and name in 'Composer' format. Here's an example: `vendor/name`."); 270 | 271 | return false; 272 | } 273 | 274 | return true; 275 | } 276 | 277 | /** 278 | * Rename the stubs with PHP file extensions. 279 | * 280 | * @return void 281 | */ 282 | protected function renameStubs() 283 | { 284 | foreach ($this->stubsToRename() as $stub) { 285 | (new Filesystem)->move($stub, str_replace('.stub', '.php', $stub)); 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /src/Commands/GenerateDocumentationCommand.php: -------------------------------------------------------------------------------- 1 | filesystem = $filesystem; 39 | 40 | parent::__construct(); 41 | } 42 | 43 | /** 44 | * Execute the console command. 45 | * 46 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 47 | */ 48 | public function handle() 49 | { 50 | $publishedVersions = config('larecipe.versions.published'); 51 | 52 | $this->info('Reading all docs versions, found: '.implode(',', $publishedVersions)); 53 | foreach ($publishedVersions as $version) { 54 | $versionDirectory = config('larecipe.docs.path').'/'.$version; 55 | 56 | $this->line(''); 57 | $this->info('---------------- Version '.$version.' ----------------'); 58 | // check if the version directory not exists => create one 59 | if ($this->createVersionDirectory(base_path($versionDirectory))) { 60 | $this->line('Docs folder created for v'.$version.' under '.$versionDirectory); 61 | } else { 62 | $this->line('Docs folder for v'.$version.' already exists.'); 63 | } 64 | 65 | // check if the version index.md not exists => create one 66 | if ($this->createVersionIndex(base_path($versionDirectory))) { 67 | $this->line('index.md created under '.$versionDirectory); 68 | } else { 69 | $this->line('index.md for v'.$version.' already exists.'); 70 | } 71 | 72 | // // check if the version landing page not exists => create one 73 | if ($this->createVersionLanding(base_path($versionDirectory))) { 74 | $this->line(config('larecipe.docs.landing').'.md created under '.$versionDirectory); 75 | } else { 76 | $this->line(''.config('larecipe.docs.landing').'.md for v'.$version.' already exists.'); 77 | } 78 | 79 | $this->info('--------------- /Version '.$version.' ----------------'); 80 | $this->line(''); 81 | } 82 | $this->info('Done.'); 83 | } 84 | 85 | /** 86 | * Create a new directory for the given version if not exists. 87 | * 88 | * @return bool 89 | */ 90 | protected function createVersionDirectory($versionDirectory) 91 | { 92 | if (! $this->filesystem->isDirectory($versionDirectory)) { 93 | $this->filesystem->makeDirectory($versionDirectory, 0755, true); 94 | 95 | return true; 96 | } 97 | 98 | return false; 99 | } 100 | 101 | /** 102 | * Create index.md for the given version if it's not exists. 103 | * 104 | * @param $versionDirectory 105 | * @return bool 106 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 107 | */ 108 | protected function createVersionIndex($versionDirectory) 109 | { 110 | $indexPath = $versionDirectory.'/index.md'; 111 | 112 | if (! $this->filesystem->exists($indexPath)) { 113 | $content = $this->generateIndexContent($this->getStub('index')); 114 | $this->filesystem->put($indexPath, $content); 115 | 116 | return true; 117 | } 118 | 119 | return false; 120 | } 121 | 122 | /** 123 | * Create {landing}.md for the given version if it's not exists. 124 | * 125 | * @param $versionDirectory 126 | * @return bool 127 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 128 | */ 129 | protected function createVersionLanding($versionDirectory) 130 | { 131 | $landingPath = $versionDirectory.'/'.config('larecipe.docs.landing').'.md'; 132 | 133 | if (! $this->filesystem->exists($landingPath)) { 134 | $content = $this->generateLandingContent($this->getStub('landing')); 135 | $this->filesystem->put($landingPath, $content); 136 | 137 | return true; 138 | } 139 | 140 | return false; 141 | } 142 | 143 | /** 144 | * replace stub placeholders. 145 | * 146 | * @return string 147 | */ 148 | protected function generateIndexContent($stub) 149 | { 150 | $content = str_replace( 151 | '{{LANDING}}', 152 | ucwords(config('larecipe.docs.landing')), 153 | $stub 154 | ); 155 | 156 | $content = str_replace( 157 | '{{LANDINGSMALL}}', 158 | trim(config('larecipe.docs.landing'), '/'), 159 | $content 160 | ); 161 | 162 | return $content; 163 | } 164 | 165 | /** 166 | * replace stub placeholders. 167 | * 168 | * @return string 169 | */ 170 | protected function generateLandingContent($stub) 171 | { 172 | return str_replace( 173 | '{{TITLE}}', 174 | ucwords(config('larecipe.docs.landing')), 175 | $stub 176 | ); 177 | } 178 | 179 | /** 180 | * Get the stub file for the generator. 181 | * 182 | * @param $stub 183 | * @return string 184 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 185 | */ 186 | protected function getStub($stub) 187 | { 188 | return $this->filesystem->get(base_path('/vendor/binarytorch/larecipe/stubs/'.$stub.'.stub')); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/Commands/InstallCommand.php: -------------------------------------------------------------------------------- 1 | line('Publishing assets and congigurations.. 🍪'); 33 | $this->call('vendor:publish', ['--provider' => LaRecipeServiceProvider::class, '--tag' => ['larecipe_assets', 'larecipe_config', 'larecipe_views']]); 34 | 35 | $this->line('Setup initial documentations structure under '.config('larecipe.docs.path').'.. 🍪'); 36 | $this->call('larecipe:docs'); 37 | 38 | $this->line('Dumping the autoloaded files and reloading all new files.. 🍪'); 39 | $composer = $this->findComposer(); 40 | $appVersion = explode('.', app()::VERSION); 41 | $process = new Process($appVersion[0]>6 ? [$composer.' dump-autoload'] : $composer.' dump-autoload') ; 42 | $process->setTimeout(null); 43 | $process->setWorkingDirectory(base_path())->run(); 44 | 45 | $this->info('LaRecipe successfully installed! Enjoy 😍'); 46 | $this->info('Visit /docs in your browser 👻'); 47 | } 48 | 49 | /** 50 | * Get the composer command for the environment. 51 | * 52 | * @return string 53 | */ 54 | protected function findComposer() 55 | { 56 | if (file_exists(getcwd().'/composer.phar')) { 57 | return '"'.PHP_BINARY.'" '.getcwd().'/composer.phar'; 58 | } 59 | 60 | return 'composer'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Commands/ThemeCommand.php: -------------------------------------------------------------------------------- 1 | hasValidNameArgument()) { 36 | return; 37 | } 38 | 39 | if ($this->option('remove')) { 40 | $this->removeTheme(); 41 | $this->info('Successfully removed LaRecipe theme.'); 42 | return; 43 | } 44 | 45 | (new Filesystem)->copyDirectory( 46 | __DIR__.'/../../stubs/theme-stubs', 47 | $this->themePath() 48 | ); 49 | 50 | // ThemeServiceProvider.php replacements... 51 | $this->replace('{{ namespace }}', $this->themeNamespace(), $this->themePath().'/src/ThemeServiceProvider.stub'); 52 | $this->replace('{{ component }}', $this->themeName(), $this->themePath().'/src/ThemeServiceProvider.stub'); 53 | $this->replace('{{ name }}', $this->themeName(), $this->themePath().'/src/ThemeServiceProvider.stub'); 54 | 55 | // Theme composer.json replacements... 56 | $this->replace('{{ name }}', $this->argument('name'), $this->themePath().'/composer.json'); 57 | $this->replace('{{ escapedNamespace }}', $this->escapedThemeNamespace(), $this->themePath().'/composer.json'); 58 | 59 | // Rename the stubs with the proper file extensions... 60 | $this->renameStubs(); 61 | 62 | // Register the theme... 63 | $this->addThemeRepositoryToRootComposer(); 64 | $this->addThemePackageToRootComposer(); 65 | 66 | if ($this->confirm('Would you like to update your Composer packages?', true)) { 67 | $this->composerUpdate(); 68 | } 69 | } 70 | 71 | /** 72 | * Get the array of stubs that need PHP file extensions. 73 | * 74 | * @return array 75 | */ 76 | protected function stubsToRename() 77 | { 78 | return [ 79 | $this->themePath().'/src/ThemeServiceProvider.stub', 80 | ]; 81 | } 82 | 83 | /** 84 | * Add a path repository for the theme to the application's composer.json file. 85 | * 86 | * @return void 87 | */ 88 | protected function addThemeRepositoryToRootComposer() 89 | { 90 | $composer = json_decode(file_get_contents(base_path('composer.json')), true); 91 | 92 | $composer['repositories'][] = [ 93 | 'type' => 'path', 94 | 'url' => './'.$this->relativeThemePath(), 95 | ]; 96 | 97 | file_put_contents( 98 | base_path('composer.json'), 99 | json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) 100 | ); 101 | } 102 | 103 | /** 104 | * Add a package entry for the theme to the application's composer.json file. 105 | * 106 | * @return void 107 | */ 108 | protected function addThemePackageToRootComposer() 109 | { 110 | $composer = json_decode(file_get_contents(base_path('composer.json')), true); 111 | 112 | $composer['require'][$this->argument('name')] = '*'; 113 | 114 | file_put_contents( 115 | base_path('composer.json'), 116 | json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) 117 | ); 118 | } 119 | 120 | /** 121 | * Update the project's composer dependencies. 122 | * 123 | * @return void 124 | */ 125 | protected function composerUpdate() 126 | { 127 | $this->runProcess('composer update', getcwd()); 128 | } 129 | 130 | /** 131 | * Replace the given string in the given file. 132 | * 133 | * @param string $search 134 | * @param string $replace 135 | * @param string $path 136 | * @return void 137 | */ 138 | protected function replace($search, $replace, $path) 139 | { 140 | file_put_contents($path, str_replace($search, $replace, file_get_contents($path))); 141 | } 142 | 143 | /** 144 | * Get the path to the theme. 145 | * 146 | * @return string 147 | */ 148 | protected function themePath() 149 | { 150 | return base_path($this->relativeThemePath()); 151 | } 152 | 153 | /** 154 | * Get the relative path to the theme. 155 | * 156 | * @return string 157 | */ 158 | protected function relativeThemePath() 159 | { 160 | return config('larecipe.packages.path', 'larecipe-components').'/'.$this->themeClass(); 161 | } 162 | 163 | /** 164 | * Get the theme's namespace. 165 | * 166 | * @return string 167 | */ 168 | protected function themeNamespace() 169 | { 170 | return Str::studly($this->themeVendor()).'\\'.$this->themeClass(); 171 | } 172 | 173 | /** 174 | * Get the theme's escaped namespace. 175 | * 176 | * @return string 177 | */ 178 | protected function escapedThemeNamespace() 179 | { 180 | return str_replace('\\', '\\\\', $this->themeNamespace()); 181 | } 182 | 183 | /** 184 | * Get the theme's class name. 185 | * 186 | * @return string 187 | */ 188 | protected function themeClass() 189 | { 190 | return Str::studly($this->themeName()); 191 | } 192 | 193 | /** 194 | * Get the theme's vendor. 195 | * 196 | * @return string 197 | */ 198 | protected function themeVendor() 199 | { 200 | return explode('/', $this->argument('name'))[0]; 201 | } 202 | 203 | /** 204 | * Get the theme's base name. 205 | * 206 | * @return string 207 | */ 208 | protected function themeName() 209 | { 210 | return explode('/', $this->argument('name'))[1]; 211 | } 212 | 213 | /** 214 | * Determine if the name argument is valid. 215 | * 216 | * @return bool 217 | */ 218 | public function hasValidNameArgument() 219 | { 220 | $name = $this->argument('name'); 221 | 222 | if (! Str::contains($name, '/')) { 223 | $this->error("The name argument expects a vendor and name in 'Composer' format. Here's an example: `vendor/name`."); 224 | 225 | return false; 226 | } 227 | 228 | return true; 229 | } 230 | 231 | /** 232 | * Rename the stubs with PHP file extensions. 233 | * 234 | * @return void 235 | */ 236 | protected function renameStubs() 237 | { 238 | foreach ($this->stubsToRename() as $stub) { 239 | (new Filesystem)->move($stub, str_replace('.stub', '.php', $stub)); 240 | } 241 | } 242 | 243 | /** 244 | * Remove the theme specified by vendor-name/theme 245 | * 246 | * @return void 247 | */ 248 | protected function removeTheme() 249 | { 250 | $this->runProcess('composer remove '.$this->argument('name'), getcwd()); 251 | (new Filesystem)->deleteDirectory($this->themePath()); 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/Contracts/MarkdownParser.php: -------------------------------------------------------------------------------- 1 | documentation = $documentation; 29 | 30 | $this->docsRoute = route('larecipe.index'); 31 | $this->defaultVersion = config('larecipe.versions.default'); 32 | $this->publishedVersions = config('larecipe.versions.published'); 33 | $this->defaultVersionUrl = route('larecipe.show', ['version' => $this->defaultVersion]); 34 | } 35 | 36 | /** 37 | * @param $version 38 | * @param null $page 39 | * @param array $data 40 | * @return $this|DocumentationRepository 41 | */ 42 | public function get($version, $page = null, $data = []) 43 | { 44 | $this->version = $version; 45 | $this->sectionPage = $page ?: config('larecipe.docs.landing'); 46 | $this->index = $this->documentation->getIndex($version); 47 | 48 | $this->content = $this->documentation->get($version, $this->sectionPage, $data); 49 | 50 | if (is_null($this->content)) { 51 | return $this->prepareNotFound(); 52 | } 53 | 54 | $this->prepareTitle() 55 | ->prepareCanonical() 56 | ->prepareSection($version, $page); 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * If the docs content is empty then show 404 page. 63 | * 64 | * @return $this 65 | */ 66 | protected function prepareNotFound() 67 | { 68 | $this->title = 'Page not found'; 69 | $this->content = view('larecipe::partials.404'); 70 | $this->currentSection = ''; 71 | $this->canonical = ''; 72 | $this->statusCode = 404; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Prepare the page title from the first h1 found. 79 | * 80 | * @return $this 81 | */ 82 | protected function prepareTitle() 83 | { 84 | $this->title = (new Crawler($this->content))->filterXPath('//h1'); 85 | $this->title = count($this->title) ? $this->title->text() : null; 86 | 87 | return $this; 88 | } 89 | 90 | /** 91 | * Prepare the current section page. 92 | * 93 | * @param $version 94 | * @param $page 95 | * @return $this 96 | */ 97 | protected function prepareSection($version, $page) 98 | { 99 | if ($this->documentation->sectionExists($version, $page)) { 100 | $this->currentSection = $page; 101 | } 102 | 103 | return $this; 104 | } 105 | 106 | /** 107 | * Prepare the canonical link. 108 | * 109 | * @return $this 110 | */ 111 | protected function prepareCanonical() 112 | { 113 | if ($this->documentation->sectionExists($this->defaultVersion, $this->sectionPage)) { 114 | $this->canonical = route('larecipe.show', [ 115 | 'version' => $this->defaultVersion, 116 | 'page' => $this->sectionPage 117 | ]); 118 | } 119 | 120 | return $this; 121 | } 122 | 123 | /** 124 | * Check if the given version is in the published versions. 125 | * 126 | * @param $version 127 | * @return bool 128 | */ 129 | public function isPublishedVersion($version) 130 | { 131 | return in_array($version, $this->publishedVersions); 132 | } 133 | 134 | /** 135 | * Check if the given version is not in the published versions. 136 | * 137 | * @param $version 138 | * @return bool 139 | */ 140 | public function isNotPublishedVersion($version) 141 | { 142 | return ! $this->isPublishedVersion($version); 143 | } 144 | 145 | /** 146 | * @param $version 147 | * 148 | * @return $this 149 | */ 150 | public function search($version) 151 | { 152 | return $this->documentation->index($version); 153 | } 154 | 155 | /** 156 | * Dynamically retrieve attributes on the model. 157 | * 158 | * @param string $key 159 | * @return mixed 160 | */ 161 | public function __get($key) 162 | { 163 | return $this->getAttribute($key); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Facades/LaRecipe.php: -------------------------------------------------------------------------------- 1 | documentationRepository = $documentationRepository; 23 | 24 | if (config('larecipe.settings.guard')) { 25 | Auth::shouldUse(config('larecipe.settings.guard')); 26 | } 27 | 28 | if (config('larecipe.settings.auth')) { 29 | $this->middleware(['auth']); 30 | }else{ 31 | if(config('larecipe.settings.middleware')){ 32 | $this->middleware(config('larecipe.settings.middleware')); 33 | } 34 | } 35 | } 36 | 37 | /** 38 | * Redirect the index page of docs to the default version. 39 | * 40 | * @return \Illuminate\Http\RedirectResponse 41 | */ 42 | public function index() 43 | { 44 | return redirect()->route( 45 | 'larecipe.show', 46 | [ 47 | 'version' => config('larecipe.versions.default'), 48 | 'page' => config('larecipe.docs.landing') 49 | ] 50 | ); 51 | } 52 | 53 | /** 54 | * Show a documentation page. 55 | * 56 | * @param $version 57 | * @param null $page 58 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Routing\Redirector 59 | * @throws \Illuminate\Auth\Access\AuthorizationException 60 | */ 61 | public function show($version, $page = null) 62 | { 63 | $documentation = $this->documentationRepository->get($version, $page); 64 | 65 | if (Gate::has('viewLarecipe')) { 66 | $this->authorize('viewLarecipe', $documentation); 67 | } 68 | 69 | if ($this->documentationRepository->isNotPublishedVersion($version)) { 70 | return redirect()->route( 71 | 'larecipe.show', 72 | [ 73 | 'version' => config('larecipe.versions.default'), 74 | 'page' => config('larecipe.docs.landing') 75 | ] 76 | ); 77 | } 78 | 79 | return response()->view('larecipe::docs', [ 80 | 'title' => $documentation->title, 81 | 'index' => $documentation->index, 82 | 'content' => $documentation->content, 83 | 'currentVersion' => $version, 84 | 'versions' => $documentation->publishedVersions, 85 | 'currentSection' => $documentation->currentSection, 86 | 'canonical' => $documentation->canonical, 87 | ], $documentation->statusCode); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Http/Controllers/ScriptController.php: -------------------------------------------------------------------------------- 1 | script]), 18 | 200, ['Content-Type' => 'application/javascript'] 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Http/Controllers/SearchController.php: -------------------------------------------------------------------------------- 1 | documentationRepository = $documentationRepository; 21 | 22 | if (config('larecipe.settings.auth')) { 23 | $this->middleware(['auth']); 24 | }else{ 25 | if(config('larecipe.settings.middleware')){ 26 | $this->middleware(config('larecipe.settings.middleware')); 27 | } 28 | } 29 | 30 | } 31 | 32 | /** 33 | * Get the index of a given version. 34 | * 35 | * @param $version 36 | * @return \Illuminate\Http\JsonResponse 37 | */ 38 | public function __invoke($version) 39 | { 40 | $this->authorizeAccessSearch($version); 41 | 42 | return response()->json( 43 | $this->documentationRepository->search($version) 44 | ); 45 | } 46 | 47 | /** 48 | * @param $version 49 | */ 50 | protected function authorizeAccessSearch($version) 51 | { 52 | abort_if( 53 | $this->documentationRepository->isNotPublishedVersion($version) 54 | || 55 | config('larecipe.search.default') != 'internal' 56 | || 57 | ! config('larecipe.search.enabled') 58 | , 403); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Http/Controllers/StyleController.php: -------------------------------------------------------------------------------- 1 | style]), 18 | 200, ['Content-Type' => 'text/css'] 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LaRecipe.php: -------------------------------------------------------------------------------- 1 | loadViewsFrom(__DIR__.'/../resources/views', 'larecipe'); 25 | 26 | Route::group($this->routesConfig(), function () { 27 | $this->loadRoutesFrom(__DIR__.'/../routes/LaRecipe.php'); 28 | }); 29 | } 30 | 31 | /** 32 | * @return array 33 | */ 34 | protected function routesConfig() 35 | { 36 | return [ 37 | 'prefix' => config('larecipe.docs.route'), 38 | 'namespace' => 'BinaryTorch\LaRecipe\Http\Controllers', 39 | 'domain' => config('larecipe.domain', null), 40 | 'as' => 'larecipe.', 41 | 'middleware' => config('larecipe.docs.middleware'), 42 | ]; 43 | } 44 | 45 | /** 46 | * Register the application services. 47 | * 48 | * @return void 49 | */ 50 | public function register() 51 | { 52 | $this->registerConfigs(); 53 | 54 | if ($this->app->runningInConsole()) { 55 | $this->registerPublishableResources(); 56 | $this->registerConsoleCommands(); 57 | } 58 | 59 | $this->app->bind(MarkdownParser::class, ParseDownMarkdownParser::class); 60 | 61 | $this->app->alias('LaRecipe', LaRecipeFacade::class); 62 | 63 | $this->app->singleton('LaRecipe', function () { 64 | return new LaRecipe(); 65 | }); 66 | } 67 | 68 | /** 69 | * Register the publishable files. 70 | */ 71 | protected function registerPublishableResources() 72 | { 73 | $publishablePath = dirname(__DIR__) . '/publishable'; 74 | 75 | $publishable = [ 76 | 'larecipe_config' => [ 77 | "{$publishablePath}/config/larecipe.php" => config_path('larecipe.php'), 78 | ], 79 | 'larecipe_assets' => [ 80 | "{$publishablePath}/assets/" => public_path('vendor/binarytorch/larecipe/assets'), 81 | ], 82 | 'larecipe_views' => [ 83 | dirname(__DIR__) . "/resources/views/partials" => resource_path('views/vendor/larecipe/partials'), 84 | ], 85 | ]; 86 | 87 | foreach ($publishable as $group => $paths) { 88 | $this->publishes($paths, $group); 89 | } 90 | } 91 | 92 | /** 93 | * Register the commands accessible from the Console. 94 | */ 95 | protected function registerConsoleCommands() 96 | { 97 | $this->commands(AssetCommand::class); 98 | $this->commands(ThemeCommand::class); 99 | $this->commands(InstallCommand::class); 100 | $this->commands(GenerateDocumentationCommand::class); 101 | } 102 | 103 | /** 104 | * Register the package configs. 105 | */ 106 | protected function registerConfigs() 107 | { 108 | $this->mergeConfigFrom( 109 | dirname(__DIR__).'/publishable/config/larecipe.php', 110 | 'larecipe' 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Models/Documentation.php: -------------------------------------------------------------------------------- 1 | files = $files; 38 | $this->cache = $cache; 39 | } 40 | 41 | /** 42 | * Get the documentation index page. 43 | * 44 | * @param string $version 45 | * @return string 46 | */ 47 | public function getIndex($version) 48 | { 49 | return $this->cache->remember(function() use($version) { 50 | $path = base_path(config('larecipe.docs.path').'/'.$version.'/index.md'); 51 | 52 | if ($this->files->exists($path)) { 53 | $parsedContent = $this->parse($this->files->get($path)); 54 | 55 | return $this->replaceLinks($version, $parsedContent); 56 | } 57 | 58 | return null; 59 | }, 'larecipe.docs.'.$version.'.index'); 60 | } 61 | 62 | /** 63 | * Get the given documentation page. 64 | * 65 | * @param $version 66 | * @param $page 67 | * @param array $data 68 | * @return mixed 69 | */ 70 | public function get($version, $page, $data = []) 71 | { 72 | return $this->cache->remember(function() use($version, $page, $data) { 73 | $path = base_path(config('larecipe.docs.path').'/'.$version.'/'.$page.'.md'); 74 | 75 | if ($this->files->exists($path)) { 76 | $parsedContent = $this->parse($this->files->get($path)); 77 | 78 | $parsedContent = $this->replaceLinks($version, $parsedContent); 79 | 80 | return $this->renderBlade($parsedContent, $data); 81 | } 82 | 83 | return null; 84 | }, 'larecipe.docs.'.$version.'.'.$page); 85 | } 86 | 87 | /** 88 | * Replace the version and route placeholders. 89 | * 90 | * @param string $version 91 | * @param string $content 92 | * @return string 93 | */ 94 | public static function replaceLinks($version, $content) 95 | { 96 | $content = str_replace('{{version}}', $version, $content); 97 | 98 | $content = str_replace('{{route}}', trim(config('larecipe.docs.route'), '/'), $content); 99 | 100 | $content = str_replace('"#', '"'.request()->getRequestUri().'#', $content); 101 | 102 | return $content; 103 | } 104 | 105 | /** 106 | * Check if the given section exists. 107 | * 108 | * @param string $version 109 | * @param string $page 110 | * @return bool 111 | */ 112 | public function sectionExists($version, $page) 113 | { 114 | return $this->files->exists( 115 | base_path(config('larecipe.docs.path').'/'.$version.'/'.$page.'.md') 116 | ); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Services/ParseDownMarkdownParser.php: -------------------------------------------------------------------------------- 1 | text($source); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Traits/HasBladeParser.php: -------------------------------------------------------------------------------- 1 | compileBlade($content); 20 | $obLevel = ob_get_level(); 21 | ob_start(); 22 | extract($data, EXTR_SKIP); 23 | 24 | try { 25 | eval('?'.'>'.$content); 26 | } catch (\Exception $e) { 27 | while (ob_get_level() > $obLevel) { 28 | ob_end_clean(); 29 | } 30 | throw $e; 31 | } catch (\Throwable $e) { 32 | while (ob_get_level() > $obLevel) { 33 | ob_end_clean(); 34 | } 35 | throw new \Exception($e); 36 | } 37 | 38 | $contents = ob_get_clean(); 39 | 40 | return $contents; 41 | } 42 | 43 | /** 44 | * Compile blade content, except within code blocks. 45 | * 46 | * @param $rawContent 47 | * @return string 48 | */ 49 | public function compileBlade($rawContent) 50 | { 51 | $compilableContent = $this->stripCodeBlocks($rawContent); 52 | 53 | $compiledContent = Blade::compileString($compilableContent); 54 | 55 | return $this->mergeContent($compiledContent, $rawContent); 56 | } 57 | 58 | /** 59 | * Replace code blocks with a placeholder string. 60 | * 61 | * @param $content 62 | * @return string|string[]|null 63 | */ 64 | private function stripCodeBlocks($content) 65 | { 66 | return preg_replace( 67 | config('larecipe.blade-parser.regex.code-blocks.match'), 68 | config('larecipe.blade-parser.regex.code-blocks.replacement'), 69 | $content 70 | ); 71 | } 72 | 73 | /** 74 | * Add in stubbed out code blocks with the original content. 75 | * 76 | * @param $compiledContent 77 | * @param $originalContent 78 | * @return string|string[]|null 79 | */ 80 | private function mergeContent($compiledContent, $originalContent) 81 | { 82 | $replacement = config('larecipe.blade-parser.regex.code-blocks.replacement'); 83 | $codeBlocks = $this->getCodeBlocks($originalContent); 84 | 85 | foreach ($codeBlocks as $codeBlock) { 86 | $compiledContent = preg_replace( 87 | "/{$replacement}/", 88 | $codeBlock, 89 | $compiledContent, 90 | 1 91 | ); 92 | } 93 | 94 | return $compiledContent; 95 | } 96 | 97 | /** 98 | * Find all code blocks in the current content. 99 | * 100 | * @param $rawContent 101 | * @return mixed 102 | */ 103 | private function getCodeBlocks($rawContent) 104 | { 105 | $pattern = config('larecipe.blade-parser.regex.code-blocks.match'); 106 | 107 | preg_match_all( 108 | $pattern, 109 | $rawContent, 110 | $codeBlocks 111 | ); 112 | 113 | return $codeBlocks[0]; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Traits/HasDocumentationAttributes.php: -------------------------------------------------------------------------------- 1 | title; 26 | } 27 | 28 | /** 29 | * @return mixed 30 | */ 31 | public function getIndexAttribute() 32 | { 33 | return $this->index; 34 | } 35 | 36 | /** 37 | * @return string 38 | */ 39 | public function getVersionAttribute() 40 | { 41 | return $this->version; 42 | } 43 | 44 | /** 45 | * @return string 46 | */ 47 | public function getContentAttribute() 48 | { 49 | return $this->content; 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function getCanonicalAttribute() 56 | { 57 | return $this->canonical; 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function getDefaultVersionUrlAttribute() 64 | { 65 | return $this->defaultVersionUrl; 66 | } 67 | 68 | /** 69 | * @return string 70 | */ 71 | public function getCurrentSectionAttribute() 72 | { 73 | return $this->currentSection; 74 | } 75 | 76 | /** 77 | * @return int 78 | */ 79 | public function getStatusCodeAttribute() 80 | { 81 | return $this->statusCode; 82 | } 83 | 84 | /** 85 | * @return string 86 | */ 87 | public function getPublishedVersionsAttribute() 88 | { 89 | return $this->publishedVersions; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Traits/HasMarkdownParser.php: -------------------------------------------------------------------------------- 1 | parse($text); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Traits/Indexable.php: -------------------------------------------------------------------------------- 1 | cache->remember(function () use ($version) { 16 | $pages = $this->getPages($version); 17 | 18 | $result = []; 19 | foreach($pages as $page) { 20 | $split = explode("{{version}}", $page); 21 | if (count($split) <= 1) 22 | continue; 23 | 24 | $page = $split[1]; 25 | $pageContent = $this->get($version, $page); 26 | 27 | if(! $pageContent) 28 | continue; 29 | 30 | $indexableNodes = implode(',', config('larecipe.search.engines.internal.index')); 31 | 32 | $nodes = (new Crawler($pageContent)) 33 | ->filter($indexableNodes) 34 | ->each(function (Crawler $node, $i) { 35 | return $node->text(); 36 | }); 37 | 38 | $title = (new Crawler($pageContent)) 39 | ->filter('h1') 40 | ->each(function (Crawler $node, $i) { 41 | return $node->text(); 42 | }); 43 | 44 | $result[] = [ 45 | 'path' => $page, 46 | 'title' => $title ? $title[0] : '', 47 | 'headings' => $nodes 48 | ]; 49 | } 50 | 51 | return $result; 52 | }, 'larecipe.docs.'.$version.'.search'); 53 | } 54 | 55 | /** 56 | * @param $version 57 | * @return mixed 58 | */ 59 | protected function getPages($version) 60 | { 61 | $path = base_path(config('larecipe.docs.path').'/'.$version.'/index.md'); 62 | 63 | // match all markdown urls => [title](url) 64 | preg_match_all('/\[.+\]\((.+)\)/', $this->files->get($path), $matches); 65 | 66 | return $matches[1]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Traits/RunProcess.php: -------------------------------------------------------------------------------- 1 | setTimeout(null); 19 | 20 | if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { 21 | $process->setTty(true); 22 | } 23 | 24 | $process->run(function ($type, $line) { 25 | $this->output->write($line); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /stubs/asset-stubs/.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /node_modules 4 | package-lock.json 5 | composer.phar 6 | composer.lock 7 | phpunit.xml 8 | .phpunit.result.cache 9 | .DS_Store 10 | Thumbs.db 11 | -------------------------------------------------------------------------------- /stubs/asset-stubs/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ name }}", 3 | "description": "A LaRecipe asset.", 4 | "keywords": [ 5 | "laravel", 6 | "larecipe" 7 | ], 8 | "license": "MIT", 9 | "require": { 10 | "php": ">=7.1.0" 11 | }, 12 | "autoload": { 13 | "psr-4": { 14 | "{{ escapedNamespace }}\\": "src/" 15 | } 16 | }, 17 | "extra": { 18 | "laravel": { 19 | "providers": [ 20 | "{{ escapedNamespace }}\\AssetServiceProvider" 21 | ] 22 | } 23 | }, 24 | "config": { 25 | "sort-packages": true 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true 29 | } 30 | -------------------------------------------------------------------------------- /stubs/asset-stubs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "cross-env": "^5.0.0", 14 | "laravel-mix": "^1.0" 15 | }, 16 | "dependencies": { 17 | "vue": "^2.5.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /stubs/asset-stubs/resources/js/ExampleComponent.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /stubs/asset-stubs/resources/js/asset.js: -------------------------------------------------------------------------------- 1 | import ExampleComponent from './ExampleComponent'; 2 | 3 | LaRecipe.booting((Vue) => { 4 | Vue.component(ExampleComponent.name, ExampleComponent); 5 | }) -------------------------------------------------------------------------------- /stubs/asset-stubs/resources/sass/asset.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /stubs/asset-stubs/src/AssetServiceProvider.stub: -------------------------------------------------------------------------------- 1 | 8 | ## First Section 9 | 10 | Write something cool.. 🦊 -------------------------------------------------------------------------------- /stubs/theme-stubs/.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /node_modules 4 | package-lock.json 5 | composer.phar 6 | composer.lock 7 | phpunit.xml 8 | .phpunit.result.cache 9 | .DS_Store 10 | Thumbs.db 11 | -------------------------------------------------------------------------------- /stubs/theme-stubs/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ name }}", 3 | "description": "A LaRecipe theme.", 4 | "keywords": [ 5 | "laravel", 6 | "larecipe" 7 | ], 8 | "license": "MIT", 9 | "require": { 10 | "php": ">=7.1.0" 11 | }, 12 | "autoload": { 13 | "psr-4": { 14 | "{{ escapedNamespace }}\\": "src/" 15 | } 16 | }, 17 | "extra": { 18 | "laravel": { 19 | "providers": [ 20 | "{{ escapedNamespace }}\\ThemeServiceProvider" 21 | ] 22 | } 23 | }, 24 | "config": { 25 | "sort-packages": true 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true 29 | } 30 | -------------------------------------------------------------------------------- /stubs/theme-stubs/resources/css/theme.css: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /**************** Root ****************/ 3 | /**************************************/ 4 | :root { 5 | --documentation: white; 6 | --navbar: white; 7 | } 8 | 9 | /**************************************/ 10 | /*************** Sidebar **************/ 11 | /**************************************/ 12 | .sidebar { 13 | border: none; 14 | background-image: linear-gradient(0deg, #12283A, #1C3D5A); 15 | } 16 | 17 | .sidebar ul li h2 { 18 | color: #6CB2EB; 19 | } 20 | 21 | .sidebar ul li ul li a { 22 | color: #DAE1E7; 23 | } -------------------------------------------------------------------------------- /stubs/theme-stubs/src/ThemeServiceProvider.stub: -------------------------------------------------------------------------------- 1 |