From 72f14e83cd82528bdcf6f2111a31f82ce829ec0c Mon Sep 17 00:00:00 2001 From: ORG-wiki Date: Sat, 4 Dec 2021 12:05:10 +1300 Subject: [PATCH] (Grav GitSync) Automatic Commit from ORG-wiki --- pages/01.blog/blog.de.md | 20 + pages/01.blog/blog.en.md | 20 + .../item.de.md | 86 + .../item.en.md | 86 + .../ts&grav.png | Bin 0 -> 150348 bytes .../item.de.md | 38 + .../item.en.md | 38 + .../techsaviours-hierarchy.png | Bin 0 -> 85417 bytes pages/02.home/external.de.md | 5 + pages/02.home/external.en.md | 5 + pages/03.wiki/external.de.md | 5 + pages/03.wiki/external.en.md | 5 + pages/04.free-services/external.de.md | 5 + pages/04.free-services/external.en.md | 5 + pages/05.tutorials/external.de.md | 5 + pages/05.tutorials/external.en.md | 5 + pages/06.about/external.de.md | 5 + pages/06.about/external.en.md | 5 + pages/sidebar/about/blog.de.md | 27 + pages/sidebar/about/blog.en.md | 27 + .../about/org-favicon-white-background.png | Bin 0 -> 56853 bytes plugins/.gitkeep | 0 plugins/admin/.editorconfig | 17 + plugins/admin/.gitattributes | 8 + plugins/admin/.github/FUNDING.yml | 8 + plugins/admin/.gitignore | 16 + plugins/admin/CHANGELOG.md | 2427 + plugins/admin/CONTRIBUTING.md | 1 + plugins/admin/LICENSE | 21 + plugins/admin/README.md | 152 + plugins/admin/UPGRADE.md | 6 + plugins/admin/admin.php | 1347 + plugins/admin/admin.yaml | 85 + plugins/admin/assets/admin-dashboard.png | Bin 0 -> 241372 bytes plugins/admin/blueprints.yaml | 787 + .../admin/blueprints/admin/pages/copy.yaml | 43 + .../blueprints/admin/pages/modular_new.yaml | 52 + .../blueprints/admin/pages/modular_raw.yaml | 104 + .../admin/blueprints/admin/pages/move.yaml | 5 + plugins/admin/blueprints/admin/pages/new.yaml | 62 + .../blueprints/admin/pages/new_folder.yaml | 31 + plugins/admin/blueprints/admin/pages/raw.yaml | 104 + .../blueprints/admin/pages/root_raw.yaml | 34 + plugins/admin/blueprints/config/media.yaml | 36 + plugins/admin/classes/plugin/Admin.php | 2493 + .../classes/plugin/AdminBaseController.php | 1167 + .../admin/classes/plugin/AdminController.php | 3044 + plugins/admin/classes/plugin/AdminForm.php | 182 + .../admin/classes/plugin/AdminFormFactory.php | 44 + .../plugin/Controllers/AbstractController.php | 407 + .../plugin/Controllers/AdminController.php | 359 + .../Controllers/Login/LoginController.php | 630 + plugins/admin/classes/plugin/Gpm.php | 435 + plugins/admin/classes/plugin/Popularity.php | 303 + plugins/admin/classes/plugin/Router.php | 72 + .../classes/plugin/Routers/LoginRouter.php | 93 + plugins/admin/classes/plugin/ScssCompiler.php | 55 + plugins/admin/classes/plugin/ScssList.php | 52 + plugins/admin/classes/plugin/Themes.php | 22 + .../plugin/Twig/AdminTwigExtension.php | 131 + plugins/admin/classes/plugin/Utils.php | 54 + plugins/admin/classes/plugin/WhiteLabel.php | 93 + plugins/admin/codeception.yml | 18 + plugins/admin/composer.json | 57 + plugins/admin/composer.lock | 3756 + plugins/admin/hebe.json | 15 + plugins/admin/languages/ar.yaml | 307 + plugins/admin/languages/bg.yaml | 356 + plugins/admin/languages/bn.yaml | 4 + plugins/admin/languages/br.yaml | 592 + plugins/admin/languages/ca.yaml | 643 + plugins/admin/languages/cs.yaml | 1112 + plugins/admin/languages/cy.yaml | 89 + plugins/admin/languages/da.yaml | 760 + plugins/admin/languages/de.yaml | 965 + plugins/admin/languages/el.yaml | 710 + plugins/admin/languages/en.yaml | 1124 + plugins/admin/languages/eo.yaml | 766 + plugins/admin/languages/es.yaml | 989 + plugins/admin/languages/et.yaml | 896 + plugins/admin/languages/eu.yaml | 181 + plugins/admin/languages/fa.yaml | 878 + plugins/admin/languages/fi.yaml | 259 + plugins/admin/languages/fr.yaml | 1112 + plugins/admin/languages/gl.yaml | 867 + plugins/admin/languages/he.yaml | 410 + plugins/admin/languages/hr.yaml | 600 + plugins/admin/languages/hu.yaml | 777 + plugins/admin/languages/id.yaml | 708 + plugins/admin/languages/it.yaml | 1112 + plugins/admin/languages/ja.yaml | 759 + plugins/admin/languages/ko.yaml | 107 + plugins/admin/languages/ku.yaml | 121 + plugins/admin/languages/lt.yaml | 359 + plugins/admin/languages/mn.yaml | 1112 + plugins/admin/languages/nl.yaml | 853 + plugins/admin/languages/no.yaml | 730 + plugins/admin/languages/pl.yaml | 795 + plugins/admin/languages/pt.yaml | 620 + plugins/admin/languages/ro.yaml | 1106 + plugins/admin/languages/ru.yaml | 1103 + plugins/admin/languages/si.yaml | 98 + plugins/admin/languages/sk.yaml | 548 + plugins/admin/languages/sl.yaml | 242 + plugins/admin/languages/sr.yaml | 805 + plugins/admin/languages/sv.yaml | 670 + plugins/admin/languages/th.yaml | 688 + plugins/admin/languages/tlh.yaml | 8 + plugins/admin/languages/tr.yaml | 862 + plugins/admin/languages/uk.yaml | 600 + plugins/admin/languages/vi.yaml | 452 + plugins/admin/languages/zh-cn.yaml | 1112 + plugins/admin/languages/zh-tw.yaml | 718 + plugins/admin/languages/zh.yaml | 1112 + plugins/admin/pages/admin/ajax.md | 8 + plugins/admin/pages/admin/backup.md | 9 + plugins/admin/pages/admin/cache.md | 10 + plugins/admin/pages/admin/changelog.md | 9 + plugins/admin/pages/admin/config.md | 7 + plugins/admin/pages/admin/dashboard.md | 8 + plugins/admin/pages/admin/denied.md | 5 + plugins/admin/pages/admin/error.md | 10 + plugins/admin/pages/admin/feed.md | 8 + plugins/admin/pages/admin/forgot.md | 19 + plugins/admin/pages/admin/info.md | 9 + plugins/admin/pages/admin/installer.md | 8 + plugins/admin/pages/admin/login.md | 40 + plugins/admin/pages/admin/media.md | 9 + plugins/admin/pages/admin/notifications.md | 8 + plugins/admin/pages/admin/pages-filter.md | 9 + plugins/admin/pages/admin/pages.md | 8 + plugins/admin/pages/admin/plugins.md | 8 + plugins/admin/pages/admin/preview.md | 8 + plugins/admin/pages/admin/register.md | 63 + plugins/admin/pages/admin/reset.md | 24 + plugins/admin/pages/admin/site.md | 9 + plugins/admin/pages/admin/statistics.md | 8 + plugins/admin/pages/admin/system.md | 9 + plugins/admin/pages/admin/themes.md | 8 + plugins/admin/pages/admin/tools.md | 7 + plugins/admin/pages/admin/update.md | 9 + plugins/admin/pages/admin/user.md | 9 + plugins/admin/permissions.yaml | 48 + plugins/admin/presets.yaml | 370 + plugins/admin/tests/_bootstrap.php | 11 + plugins/admin/tests/_support/Helper/Unit.php | 80 + plugins/admin/tests/_support/UnitTester.php | 26 + plugins/admin/tests/unit.suite.yml | 9 + plugins/admin/tests/unit/_bootstrap.php | 3 + .../tests/unit/classes/controllerTest.php | 42 + plugins/admin/themes/grav/.babelrc | 3 + plugins/admin/themes/grav/.eslintrc | 166 + .../admin/themes/grav/app/dashboard/backup.js | 42 + .../admin/themes/grav/app/dashboard/cache.js | 49 + .../admin/themes/grav/app/dashboard/chart.js | 138 + .../admin/themes/grav/app/dashboard/index.js | 12 + .../admin/themes/grav/app/dashboard/update.js | 1 + .../grav/app/forms/fields/acl-picker.js | 89 + .../themes/grav/app/forms/fields/array.js | 205 + .../grav/app/forms/fields/collections.js | 261 + .../grav/app/forms/fields/colorpicker.js | 579 + .../themes/grav/app/forms/fields/cron.js | 85 + .../themes/grav/app/forms/fields/datetime.js | 63 + .../themes/grav/app/forms/fields/editor.js | 237 + .../grav/app/forms/fields/editor/buttons.js | 416 + .../grav/app/forms/fields/filepicker.js | 144 + .../themes/grav/app/forms/fields/files.js | 390 + .../themes/grav/app/forms/fields/folder.js | 20 + .../grav/app/forms/fields/iconpicker.js | 298 + .../grav/app/forms/fields/indeterminate.js | 52 + .../themes/grav/app/forms/fields/index.js | 75 + .../grav/app/forms/fields/mediapicker.js | 51 + .../grav/app/forms/fields/multilevel.js | 281 + .../themes/grav/app/forms/fields/parents.js | 270 + .../grav/app/forms/fields/permissions.js | 46 + .../themes/grav/app/forms/fields/range.js | 10 + .../themes/grav/app/forms/fields/selectize.js | 66 + .../grav/app/forms/fields/selectunique.js | 160 + .../themes/grav/app/forms/fields/text.js | 13 + plugins/admin/themes/grav/app/forms/form.js | 139 + plugins/admin/themes/grav/app/forms/index.js | 16 + plugins/admin/themes/grav/app/forms/state.js | 150 + plugins/admin/themes/grav/app/main.js | 72 + plugins/admin/themes/grav/app/media/index.js | 226 + plugins/admin/themes/grav/app/pages/filter.js | 148 + plugins/admin/themes/grav/app/pages/index.js | 53 + .../admin/themes/grav/app/pages/page/add.js | 67 + .../themes/grav/app/pages/page/delete.js | 15 + .../grav/app/pages/page/disable-buttons.js | 5 + .../admin/themes/grav/app/pages/page/index.js | 47 + .../admin/themes/grav/app/pages/page/media.js | 205 + .../admin/themes/grav/app/pages/page/move.js | 63 + .../themes/grav/app/pages/page/multilang.js | 22 + .../admin/themes/grav/app/pages/page/unset.js | 18 + plugins/admin/themes/grav/app/pages/tree.js | 125 + .../admin/themes/grav/app/plugins/index.js | 92 + plugins/admin/themes/grav/app/themes/index.js | 46 + plugins/admin/themes/grav/app/tools/index.js | 1 + plugins/admin/themes/grav/app/tools/logs.js | 14 + .../grav/app/updates/channel-switcher.js | 24 + .../admin/themes/grav/app/updates/check.js | 26 + plugins/admin/themes/grav/app/updates/feed.js | 68 + .../admin/themes/grav/app/updates/index.js | 196 + .../themes/grav/app/updates/notifications.js | 169 + .../admin/themes/grav/app/updates/update.js | 22 + plugins/admin/themes/grav/app/utils/2fa.js | 32 + .../grav/app/utils/bootstrap-collapse.js | 210 + .../app/utils/bootstrap-datetimepicker.js | 2632 + .../grav/app/utils/bootstrap-dropdown.js | 169 + .../grav/app/utils/bootstrap-transition.js | 52 + .../admin/themes/grav/app/utils/changelog.js | 25 + plugins/admin/themes/grav/app/utils/colors.js | 152 + .../admin/themes/grav/app/utils/cookies.js | 164 + .../admin/themes/grav/app/utils/cron-ui.js | 864 + .../admin/themes/grav/app/utils/finderjs.js | 325 + .../themes/grav/app/utils/formatbytes.js | 11 + plugins/admin/themes/grav/app/utils/gpm.js | 57 + .../themes/grav/app/utils/jquery-utils.js | 50 + .../admin/themes/grav/app/utils/keepalive.js | 34 + .../admin/themes/grav/app/utils/offline.js | 21 + .../admin/themes/grav/app/utils/packages.js | 470 + .../admin/themes/grav/app/utils/remodal.js | 820 + .../admin/themes/grav/app/utils/request.js | 38 + .../admin/themes/grav/app/utils/response.js | 101 + .../admin/themes/grav/app/utils/scrollbar.js | 1 + .../grav/app/utils/selectize-option-click.js | 42 + .../grav/app/utils/selectize-required-fix.js | 28 + .../admin/themes/grav/app/utils/sidebar.js | 181 + .../admin/themes/grav/app/utils/storage.js | 41 + .../themes/grav/app/utils/tabs-memory.js | 29 + plugins/admin/themes/grav/app/utils/toastr.js | 6 + .../themes/grav/app/whitelabel/compile.js | 25 + .../admin/themes/grav/app/whitelabel/index.js | 93 + .../themes/grav/app/whitelabel/presets.js | 169 + .../admin/themes/grav/css-compiled/fonts.css | 3 + .../themes/grav/css-compiled/fonts.css.map | 1 + .../themes/grav/css-compiled/nucleus.css | 625 + .../themes/grav/css-compiled/nucleus.css.map | 93 + .../themes/grav/css-compiled/paper.css.map | 1 + .../admin/themes/grav/css-compiled/preset.css | 1517 + .../themes/grav/css-compiled/preset.css.map | 18 + .../themes/grav/css-compiled/simple-fonts.css | 13 + .../grav/css-compiled/simple-fonts.css.map | 10 + .../themes/grav/css-compiled/template.css | 5607 + .../themes/grav/css-compiled/template.css.map | 129 + .../admin/themes/grav/css/chartist.min.css | 1 + .../themes/grav/css/codemirror/codemirror.css | 332 + .../grav/css/codemirror/themes/3024-day.css | 41 + .../grav/css/codemirror/themes/3024-night.css | 39 + .../grav/css/codemirror/themes/abcdef.css | 32 + .../css/codemirror/themes/ambiance-mobile.css | 5 + .../grav/css/codemirror/themes/ambiance.css | 74 + .../grav/css/codemirror/themes/ayu-dark.css | 42 + .../grav/css/codemirror/themes/ayu-mirage.css | 43 + .../css/codemirror/themes/base16-dark.css | 38 + .../css/codemirror/themes/base16-light.css | 38 + .../grav/css/codemirror/themes/bespin.css | 34 + .../grav/css/codemirror/themes/blackboard.css | 32 + .../grav/css/codemirror/themes/cobalt.css | 25 + .../grav/css/codemirror/themes/colorforth.css | 33 + .../grav/css/codemirror/themes/darcula.css | 53 + .../grav/css/codemirror/themes/dracula.css | 40 + .../css/codemirror/themes/duotone-dark.css | 35 + .../css/codemirror/themes/duotone-light.css | 36 + .../grav/css/codemirror/themes/eclipse.css | 23 + .../grav/css/codemirror/themes/elegant.css | 13 + .../css/codemirror/themes/erlang-dark.css | 34 + .../css/codemirror/themes/gruvbox-dark.css | 37 + .../grav/css/codemirror/themes/hopscotch.css | 34 + .../grav/css/codemirror/themes/icecoder.css | 43 + .../grav/css/codemirror/themes/idea.css | 42 + .../grav/css/codemirror/themes/isotope.css | 34 + .../css/codemirror/themes/lesser-dark.css | 47 + .../grav/css/codemirror/themes/liquibyte.css | 95 + .../grav/css/codemirror/themes/lucario.css | 37 + .../css/codemirror/themes/material-darker.css | 135 + .../css/codemirror/themes/material-ocean.css | 135 + .../codemirror/themes/material-palenight.css | 135 + .../grav/css/codemirror/themes/material.css | 135 + .../themes/grav/css/codemirror/themes/mbo.css | 37 + .../grav/css/codemirror/themes/mdn-like.css | 46 + .../grav/css/codemirror/themes/midnight.css | 39 + .../grav/css/codemirror/themes/monokai.css | 41 + .../grav/css/codemirror/themes/moxer.css | 143 + .../grav/css/codemirror/themes/neat.css | 12 + .../themes/grav/css/codemirror/themes/neo.css | 43 + .../grav/css/codemirror/themes/night.css | 27 + .../grav/css/codemirror/themes/nord.css | 42 + .../css/codemirror/themes/oceanic-next.css | 44 + .../css/codemirror/themes/panda-syntax.css | 85 + .../grav/css/codemirror/themes/paper.css | 143 + .../css/codemirror/themes/paraiso-dark.css | 38 + .../css/codemirror/themes/paraiso-light.css | 38 + .../css/codemirror/themes/pastel-on-dark.css | 52 + .../grav/css/codemirror/themes/railscasts.css | 34 + .../grav/css/codemirror/themes/rubyblue.css | 25 + .../grav/css/codemirror/themes/seti.css | 44 + .../grav/css/codemirror/themes/shadowfox.css | 52 + .../grav/css/codemirror/themes/solarized.css | 168 + .../grav/css/codemirror/themes/ssms.css | 16 + .../grav/css/codemirror/themes/the-matrix.css | 30 + .../themes/tomorrow-night-bright.css | 35 + .../themes/tomorrow-night-eighties.css | 38 + .../grav/css/codemirror/themes/ttcn.css | 64 + .../grav/css/codemirror/themes/twilight.css | 32 + .../css/codemirror/themes/vibrant-ink.css | 34 + .../grav/css/codemirror/themes/xq-dark.css | 53 + .../grav/css/codemirror/themes/xq-light.css | 43 + .../grav/css/codemirror/themes/yeti.css | 44 + .../grav/css/codemirror/themes/yonce.css | 59 + .../grav/css/codemirror/themes/zenburn.css | 37 + .../themes/grav/css/featherlight.min.css | 8 + .../themes/grav/css/fork-awesome.min.css | 12 + .../admin/themes/grav/css/hint.base.min.css | 5 + plugins/admin/themes/grav/css/iconpicker.css | 222 + .../admin/themes/grav/css/nucleus-ie10.css | 24 + plugins/admin/themes/grav/css/nucleus-ie9.css | 62 + plugins/admin/themes/grav/css/prism.css | 121 + .../themes/grav/css/pure-0.5.0/grids-min.css | 15 + plugins/admin/themes/grav/css/rtl.css | 1240 + .../admin/themes/grav/css/selectize.min.css | 1 + .../themes/grav/fonts/forkawesome-webfont.eot | Bin 0 -> 186490 bytes .../themes/grav/fonts/forkawesome-webfont.svg | 2810 + .../themes/grav/fonts/forkawesome-webfont.ttf | Bin 0 -> 186300 bytes .../grav/fonts/forkawesome-webfont.woff | Bin 0 -> 113404 bytes .../grav/fonts/forkawesome-webfont.woff2 | Bin 0 -> 90420 bytes .../rockettheme-apps/rockettheme-apps.eot | Bin 0 -> 4838 bytes .../rockettheme-apps/rockettheme-apps.svg | 16 + .../rockettheme-apps/rockettheme-apps.ttf | Bin 0 -> 4644 bytes .../rockettheme-apps/rockettheme-apps.woff | Bin 0 -> 3348 bytes plugins/admin/themes/grav/images/favicon.png | Bin 0 -> 13203 bytes .../admin/themes/grav/images/grav-regular.svg | 1 + .../admin/themes/grav/images/grav-small.svg | 1 + .../themes/grav/images/icons/book-edit.svg | 10 + .../themes/grav/images/icons/clock-hands.svg | 8 + .../admin/themes/grav/images/icons/crown.svg | 1 + .../admin/themes/grav/images/icons/house.svg | 5 + .../themes/grav/images/icons/module-four.svg | 12 + .../themes/grav/images/icons/superman.svg | 7 + .../themes/grav/images/icons/touchid-lock.svg | 15 + plugins/admin/themes/grav/images/logo.svg | 1 + .../admin/themes/grav/images/transparent.png | Bin 0 -> 5123 bytes plugins/admin/themes/grav/js/admin.min.js | 15055 +++ .../themes/grav/js/form-attr.polyfill.js | 80 + plugins/admin/themes/grav/js/vendor.min.js | 93005 ++++++++++++++++ plugins/admin/themes/grav/package-lock.json | 9097 ++ plugins/admin/themes/grav/package.json | 68 + .../scss/configuration/nucleus/_base.scss | 14 + .../configuration/nucleus/_breakpoints.scss | 16 + .../scss/configuration/nucleus/_core.scss | 2 + .../scss/configuration/nucleus/_layout.scss | 8 + .../grav/scss/configuration/nucleus/_nav.scss | 3 + .../configuration/nucleus/_typography.scss | 14 + .../scss/configuration/template/_base.scss | 5 + .../scss/configuration/template/_colors.scss | 15 + .../configuration/template/_variables.scss | 22 + plugins/admin/themes/grav/scss/nucleus.scss | 27 + .../admin/themes/grav/scss/nucleus/_core.scss | 217 + .../admin/themes/grav/scss/nucleus/_flex.scss | 195 + .../themes/grav/scss/nucleus/_forms.scss | 62 + .../themes/grav/scss/nucleus/_typography.scss | 89 + .../grav/scss/nucleus/functions/_base.scss | 2 + .../scss/nucleus/functions/_direction.scss | 37 + .../grav/scss/nucleus/functions/_range.scss | 13 + .../grav/scss/nucleus/mixins/_base.scss | 2 + .../scss/nucleus/mixins/_breakpoints.scss | 44 + .../grav/scss/nucleus/mixins/_utilities.scss | 30 + .../scss/nucleus/particles/_align-text.scss | 46 + .../scss/nucleus/particles/_visibility.scss | 0 plugins/admin/themes/grav/scss/preset.scss | 2364 + .../admin/themes/grav/scss/simple-fonts.scss | 13 + plugins/admin/themes/grav/scss/template.scss | 109 + .../themes/grav/scss/template/_admin.scss | 1431 + .../themes/grav/scss/template/_buttons.scss | 131 + .../themes/grav/scss/template/_changelog.scss | 117 + .../themes/grav/scss/template/_colors.scss | 93 + .../themes/grav/scss/template/_core.scss | 51 + .../themes/grav/scss/template/_custom.scss | 2 + .../themes/grav/scss/template/_dropzone.scss | 285 + .../themes/grav/scss/template/_editor.scss | 315 + .../themes/grav/scss/template/_errors.scss | 17 + .../grav/scss/template/_extensions.scss | 58 + .../themes/grav/scss/template/_fonts.scss | 40 + .../themes/grav/scss/template/_forms.scss | 974 + .../admin/themes/grav/scss/template/_gpm.scss | 207 + .../themes/grav/scss/template/_header.scss | 3 + .../scss/template/_horizontal-scroll.scss | 54 + .../themes/grav/scss/template/_jqcron.scss | 70 + .../themes/grav/scss/template/_login.scss | 191 + .../themes/grav/scss/template/_media.scss | 331 + .../grav/scss/template/_nav-toggle.scss | 71 + .../grav/scss/template/_notifications.scss | 116 + .../themes/grav/scss/template/_pages.scss | 856 + .../themes/grav/scss/template/_phpinfo.scss | 35 + .../themes/grav/scss/template/_remodal.scss | 329 + .../grav/scss/template/_scrollbars.scss | 210 + .../themes/grav/scss/template/_tables.scss | 190 + .../themes/grav/scss/template/_tabs.scss | 125 + .../themes/grav/scss/template/_toastr.scss | 183 + .../themes/grav/scss/template/_tools.scss | 97 + .../grav/scss/template/_typography.scss | 166 + .../themes/grav/scss/template/_utilities.scss | 9 + .../grav/scss/template/_whitelabel.scss | 268 + .../grav/scss/template/modules/_base.scss | 5 + .../template/modules/_bourbon_essentials.scss | 120 + .../grav/scss/template/modules/_buttons.scss | 91 + .../scss/template/modules/_colorpicker.scss | 253 + .../template/modules/_datetimepicker.scss | 466 + .../grav/scss/template/modules/_finderjs.scss | 161 + .../scss/template/modules/_input-range.scss | 87 + .../scss/template/modules/_scrollbars.scss | 18 + .../scss/template/modules/_toggle-switch.scss | 20 + .../bourbon/_bourbon-deprecated-upcoming.scss | 8 + .../grav/scss/vendor/bourbon/_bourbon.scss | 77 + .../scss/vendor/bourbon/addons/_button.scss | 374 + .../scss/vendor/bourbon/addons/_clearfix.scss | 23 + .../bourbon/addons/_directional-values.scss | 111 + .../scss/vendor/bourbon/addons/_ellipsis.scss | 7 + .../vendor/bourbon/addons/_font-family.scss | 5 + .../vendor/bourbon/addons/_hide-text.scss | 10 + .../bourbon/addons/_html5-input-types.scss | 86 + .../scss/vendor/bourbon/addons/_position.scss | 32 + .../scss/vendor/bourbon/addons/_prefixer.scss | 45 + .../grav/scss/vendor/bourbon/addons/_rem.scss | 33 + .../vendor/bourbon/addons/_retina-image.scss | 31 + .../scss/vendor/bourbon/addons/_size.scss | 16 + .../bourbon/addons/_timing-functions.scss | 32 + .../scss/vendor/bourbon/addons/_triangle.scss | 83 + .../vendor/bourbon/addons/_word-wrap.scss | 8 + .../scss/vendor/bourbon/css3/_animation.scss | 52 + .../scss/vendor/bourbon/css3/_appearance.scss | 3 + .../bourbon/css3/_backface-visibility.scss | 6 + .../bourbon/css3/_background-image.scss | 42 + .../scss/vendor/bourbon/css3/_background.scss | 55 + .../vendor/bourbon/css3/_border-image.scss | 59 + .../vendor/bourbon/css3/_border-radius.scss | 22 + .../scss/vendor/bourbon/css3/_box-sizing.scss | 4 + .../grav/scss/vendor/bourbon/css3/_calc.scss | 4 + .../scss/vendor/bourbon/css3/_columns.scss | 47 + .../scss/vendor/bourbon/css3/_filter.scss | 5 + .../scss/vendor/bourbon/css3/_flex-box.scss | 321 + .../scss/vendor/bourbon/css3/_font-face.scss | 23 + .../bourbon/css3/_font-feature-settings.scss | 10 + .../bourbon/css3/_hidpi-media-query.scss | 10 + .../scss/vendor/bourbon/css3/_hyphens.scss | 4 + .../vendor/bourbon/css3/_image-rendering.scss | 14 + .../scss/vendor/bourbon/css3/_keyframes.scss | 35 + .../vendor/bourbon/css3/_linear-gradient.scss | 38 + .../vendor/bourbon/css3/_perspective.scss | 8 + .../vendor/bourbon/css3/_placeholder.scss | 8 + .../vendor/bourbon/css3/_radial-gradient.scss | 39 + .../scss/vendor/bourbon/css3/_transform.scss | 15 + .../scss/vendor/bourbon/css3/_transition.scss | 77 + .../vendor/bourbon/css3/_user-select.scss | 3 + .../vendor/bourbon/functions/_assign.scss | 11 + .../bourbon/functions/_color-lightness.scss | 13 + .../vendor/bourbon/functions/_flex-grid.scss | 39 + .../bourbon/functions/_golden-ratio.scss | 3 + .../vendor/bourbon/functions/_grid-width.scss | 13 + .../bourbon/functions/_modular-scale.scss | 66 + .../vendor/bourbon/functions/_px-to-em.scss | 13 + .../vendor/bourbon/functions/_px-to-rem.scss | 15 + .../bourbon/functions/_strip-units.scss | 5 + .../vendor/bourbon/functions/_tint-shade.scss | 9 + .../functions/_transition-property-name.scss | 22 + .../vendor/bourbon/functions/_unpack.scss | 17 + .../bourbon/helpers/_convert-units.scss | 15 + .../helpers/_gradient-positions-parser.scss | 13 + .../scss/vendor/bourbon/helpers/_is-num.scss | 8 + .../bourbon/helpers/_linear-angle-parser.scss | 25 + .../helpers/_linear-gradient-parser.scss | 41 + .../helpers/_linear-positions-parser.scss | 61 + .../helpers/_linear-side-corner-parser.scss | 31 + .../bourbon/helpers/_radial-arg-parser.scss | 69 + .../helpers/_radial-gradient-parser.scss | 50 + .../helpers/_radial-positions-parser.scss | 18 + .../bourbon/helpers/_render-gradients.scss | 26 + .../bourbon/helpers/_shape-size-stripper.scss | 10 + .../vendor/bourbon/helpers/_str-to-num.scss | 50 + .../vendor/bourbon/settings/_prefixer.scss | 6 + .../vendor/bourbon/settings/_px-to-em.scss | 1 + .../vendor/color-schemer/_color-schemer.scss | 31 + .../color-schemer/color-schemer/_cmyk.scss | 14 + .../color-schemer/_color-adjustments.scss | 30 + .../color-schemer/_color-schemer.scss | 208 + .../color-schemer/_colorblind.scss | 29 + .../color-schemer/_comparison.scss | 15 + .../color-schemer/_equalize.scss | 5 + .../color-schemer/_harmonize.scss | 59 + .../color-schemer/_interpolation.scss | 34 + .../color-schemer/color-schemer/_mix.scss | 40 + .../color-schemer/color-schemer/_mixins.scss | 29 + .../color-schemer/color-schemer/_ryb.scss | 76 + .../color-schemer/_tint-shade.scss | 9 + .../themes/grav/templates/changelog.html.twig | 21 + .../themes/grav/templates/config.html.twig | 82 + .../themes/grav/templates/dashboard.html.twig | 73 + .../themes/grav/templates/default.json.twig | 5 + .../themes/grav/templates/denied.html.twig | 18 + .../grav/templates/email/base.html.twig | 194 + .../themes/grav/templates/empty.html.twig | 0 .../themes/grav/templates/error.html.twig | 20 + .../themes/grav/templates/error.json.twig | 1 + .../themes/grav/templates/forgot.html.twig | 14 + .../grav/templates/forms/field.html.twig | 130 + .../fields/acl_picker/acl_picker.html.twig | 134 + .../forms/fields/array/array.html.twig | 96 + .../backupshistory/backupshistory.html.twig | 32 + .../fields/blueprint/blueprint.html.twig | 12 + .../fields/codemirror/codemirror.html.twig | 10 + .../fields/colorpicker/colorpicker.html.twig | 39 + .../colorscheme.color.html.twig | 40 + .../fields/colorscheme/colorscheme.html.twig | 15 + .../forms/fields/column/column.html.twig | 8 + .../forms/fields/columns/columns.html.twig | 8 + .../forms/fields/cron/cron.html.twig | 7 + .../fields/cronstatus/cronstatus.html.twig | 71 + .../fields/dateformat/dateformat.html.twig | 24 + .../forms/fields/datetime/datetime.html.twig | 27 + .../forms/fields/editor/editor.html.twig | 62 + .../forms/fields/fieldset/fieldset.html.twig | 81 + .../forms/fields/file/file.html.twig | 118 + .../fields/filepicker/filepicker.html.twig | 27 + .../fields/folder-slug/folder-slug.html.twig | 8 + .../fields/frontmatter/frontmatter.html.twig | 10 + .../fields/iconpicker/iconpicker.html.twig | 46 + .../forms/fields/iconpicker/icons.yaml | 6570 ++ .../forms/fields/list/list.html.twig | 177 + .../forms/fields/markdown/markdown.html.twig | 1 + .../fields/mediapicker/mediapicker.html.twig | 20 + .../fields/multilevel/multilevel.html.twig | 121 + .../forms/fields/order/order.html.twig | 64 + .../fields/pagemedia/pagemedia.html.twig | 58 + .../pagemediaselect/pagemediaselect.html.twig | 1 + .../forms/fields/pages/pages.html.twig | 52 + .../forms/fields/parents/parents.html.twig | 58 + .../fields/permissions/permissions.html.twig | 161 + .../forms/fields/range/range.html.twig | 28 + .../forms/fields/section/section.html.twig | 24 + .../fields/selectize/selectize.html.twig | 19 + .../selectunique/selectunique.html.twig | 43 + .../forms/fields/taxonomy/taxonomy.html.twig | 38 + .../themepreview/themepreview.html.twig | 106 + .../fields/themeselect/themeselect.html.twig | 31 + .../forms/fields/userinfo/userinfo.html.twig | 19 + .../forms/fields/widgets/widgets.html.twig | 61 + .../templates/forms/fields/xss/xss.html.twig | 6 + .../themes/grav/templates/installer.html.twig | 13 + .../themes/grav/templates/login.html.twig | 11 + .../templates/media-list-content.html.twig | 19 + .../themes/grav/templates/pages.html.twig | 469 + .../partials/backups-button.html.twig | 21 + .../templates/partials/base-root.html.twig | 156 + .../grav/templates/partials/base.html.twig | 1 + .../partials/blueprints-copy.html.twig | 19 + .../partials/blueprints-new-folder.html.twig | 18 + .../partials/blueprints-new.html.twig | 19 + .../partials/blueprints-raw.html.twig | 22 + .../templates/partials/blueprints.html.twig | 34 + .../partials/dashboard-feed.html.twig | 14 + .../partials/dashboard-maintenance.html.twig | 33 + .../dashboard-notifications.html.twig | 13 + .../partials/dashboard-pages.html.twig | 20 + .../partials/dashboard-problems.html.twig | 11 + .../partials/dashboard-statistics.html.twig | 24 + .../templates/partials/feed-block.html.twig | 3 + .../grav/templates/partials/footer.html.twig | 5 + .../grav/templates/partials/header.html.twig | 11 + .../partials/javascript-config.html.twig | 43 + .../templates/partials/javascripts.html.twig | 11 + .../templates/partials/list-sort.html.twig | 12 + .../templates/partials/login-form.html.twig | 25 + .../templates/partials/login-logo.html.twig | 14 + .../templates/partials/login-logout.html.twig | 15 + .../templates/partials/login-twofa.html.twig | 20 + .../grav/templates/partials/login.html.twig | 33 + .../grav/templates/partials/logo.html.twig | 20 + .../partials/media-list-wrapper.html.twig | 32 + .../media-list-wrapper__list.html.twig | 23 + ...edia-list-wrapper__list__filters.html.twig | 28 + .../media-list-wrapper__sidebar.html.twig | 36 + .../templates/partials/messages.html.twig | 14 + .../partials/modal-add-package.html.twig | 89 + .../partials/modal-changelog.html.twig | 1 + .../partials/modal-changes-detected.html.twig | 13 + .../modal-reinstall-package.html.twig | 38 + .../partials/modal-remove-package.html.twig | 44 + .../partials/modal-switch-theme.html.twig | 16 + .../partials/modal-update-packages.html.twig | 89 + .../partials/nav-quick-tray.html.twig | 47 + .../templates/partials/nav-toggle.html.twig | 3 + .../partials/nav-user-avatar.html.twig | 2 + .../partials/nav-user-details.html.twig | 21 + .../grav/templates/partials/nav.html.twig | 47 + .../notification-dashboard-block.html.twig | 6 + .../notification-feed-block.html.twig | 3 + .../notification-plugins-block.html.twig | 6 + .../notification-themes-block.html.twig | 6 + .../partials/notification-top-block.html.twig | 6 + .../partials/page-children.html.twig | 11 + .../templates/partials/page-legend.html.twig | 11 + .../templates/partials/page-move.html.twig | 21 + .../templates/partials/plugin-data.html.twig | 74 + .../partials/plugins-details.html.twig | 76 + .../templates/partials/plugins-list.html.twig | 75 + .../templates/partials/register.html.twig | 24 + .../partials/release-toggle.html.twig | 11 + .../partials/spinning-wheel.html.twig | 3 + .../templates/partials/stylesheets.html.twig | 16 + .../grav/templates/partials/theme.html.twig | 13 + .../partials/themes-details.html.twig | 161 + .../templates/partials/themes-list.html.twig | 80 + .../partials/tools-backups-titlebar.html.twig | 7 + .../partials/tools-backups.html.twig | 81 + .../partials/tools-direct-install.html.twig | 29 + .../templates/partials/tools-logs.html.twig | 80 + .../partials/tools-reports.html.twig | 15 + .../tools-scheduler-titlebar.html.twig | 6 + .../partials/tools-scheduler.html.twig | 36 + .../partials/userinfo-avatar-credit.html.twig | 1 + .../partials/userinfo-avatar.html.twig | 5 + .../themes/grav/templates/plugins.html.twig | 94 + .../templates/plugins/admin-buttons.html.twig | 3 + .../themes/grav/templates/preview.html.twig | 24 + .../themes/grav/templates/register.html.twig | 24 + .../grav/templates/reports/security.html.twig | 20 + .../templates/reports/yamllinter.html.twig | 31 + .../themes/grav/templates/reset.html.twig | 14 + .../grav/templates/statistics.html.twig | 15 + .../themes/grav/templates/themes.html.twig | 87 + .../themes/grav/templates/tools.html.twig | 50 + .../grav/templates/unauthorized.html.twig | 1 + .../themes/grav/templates/user.html.twig | 63 + plugins/admin/themes/grav/theme.yaml | 0 plugins/admin/themes/grav/watch.sh | 27 + plugins/admin/themes/grav/webpack.conf.js | 54 + plugins/admin/themes/grav/yarn.lock | 3558 + plugins/admin/twig/AdminTwigExtension.php | 7 + plugins/admin/vendor/autoload.php | 7 + plugins/admin/vendor/bin/picofeed | 1 + plugins/admin/vendor/bin/pscss | 1 + plugins/admin/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 283 + plugins/admin/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../admin/vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 10 + .../admin/vendor/composer/autoload_psr4.php | 13 + .../admin/vendor/composer/autoload_real.php | 75 + .../admin/vendor/composer/autoload_static.php | 73 + plugins/admin/vendor/composer/installed.json | 272 + plugins/admin/vendor/composer/installed.php | 88 + .../admin/vendor/composer/platform_check.php | 26 + .../workflows/continuous-integration.yml | 33 + .../workflows/release-on-milestone-closed.yml | 71 + .../vendor/laminas/laminas-xml/COPYRIGHT.md | 1 + .../vendor/laminas/laminas-xml/LICENSE.md | 26 + .../vendor/laminas/laminas-xml/README.md | 46 + .../vendor/laminas/laminas-xml/composer.json | 55 + .../vendor/laminas/laminas-xml/composer.lock | 2295 + .../src/Exception/ExceptionInterface.php | 13 + .../Exception/InvalidArgumentException.php | 16 + .../src/Exception/RuntimeException.php | 16 + .../laminas/laminas-xml/src/Security.php | 416 + .../.github/FUNDING.yml | 1 + .../workflows/continuous-integration.yml | 32 + .../workflows/release-on-milestone-closed.yml | 61 + .../.laminas-ci.json | 5 + .../laminas-zendframework-bridge/COPYRIGHT.md | 1 + .../laminas-zendframework-bridge/LICENSE.md | 26 + .../laminas-zendframework-bridge/README.md | 30 + .../composer.json | 61 + .../composer.lock | 3841 + .../config/replacements.php | 372 + .../psalm-baseline.xml | 363 + .../psalm.xml.dist | 33 + .../src/Autoloader.php | 166 + .../src/ConfigPostProcessor.php | 426 + .../src/Module.php | 48 + .../src/Replacements.php | 40 + .../src/RewriteRules.php | 73 + .../src/autoload.php | 3 + plugins/admin/vendor/p3k/picofeed/LICENSE | 21 + .../vendor/p3k/picofeed/lib/PicoFeed/Base.php | 38 + .../picofeed/lib/PicoFeed/Client/Client.php | 712 + .../lib/PicoFeed/Client/ClientException.php | 14 + .../p3k/picofeed/lib/PicoFeed/Client/Curl.php | 412 + .../PicoFeed/Client/ForbiddenException.php | 10 + .../lib/PicoFeed/Client/HttpHeaders.php | 79 + .../Client/InvalidCertificateException.php | 12 + .../PicoFeed/Client/InvalidUrlException.php | 12 + .../PicoFeed/Client/MaxRedirectException.php | 12 + .../lib/PicoFeed/Client/MaxSizeException.php | 12 + .../picofeed/lib/PicoFeed/Client/Stream.php | 205 + .../lib/PicoFeed/Client/TimeoutException.php | 12 + .../PicoFeed/Client/UnauthorizedException.php | 10 + .../p3k/picofeed/lib/PicoFeed/Client/Url.php | 283 + .../picofeed/lib/PicoFeed/Config/Config.php | 102 + .../lib/PicoFeed/Encoding/Encoding.php | 33 + .../lib/PicoFeed/Filter/Attribute.php | 700 + .../picofeed/lib/PicoFeed/Filter/Filter.php | 144 + .../p3k/picofeed/lib/PicoFeed/Filter/Html.php | 243 + .../p3k/picofeed/lib/PicoFeed/Filter/Tag.php | 208 + .../Generator/ContentGeneratorInterface.php | 23 + .../Generator/FileContentGenerator.php | 36 + .../Generator/YoutubeContentGenerator.php | 67 + .../picofeed/lib/PicoFeed/Logging/Logger.php | 114 + .../p3k/picofeed/lib/PicoFeed/Parser/Atom.php | 395 + .../lib/PicoFeed/Parser/DateParser.php | 128 + .../p3k/picofeed/lib/PicoFeed/Parser/Feed.php | 315 + .../p3k/picofeed/lib/PicoFeed/Parser/Item.php | 562 + .../PicoFeed/Parser/MalformedXmlException.php | 13 + .../picofeed/lib/PicoFeed/Parser/Parser.php | 397 + .../lib/PicoFeed/Parser/ParserException.php | 15 + .../lib/PicoFeed/Parser/ParserInterface.php | 191 + .../picofeed/lib/PicoFeed/Parser/Rss10.php | 318 + .../picofeed/lib/PicoFeed/Parser/Rss20.php | 330 + .../picofeed/lib/PicoFeed/Parser/Rss91.php | 13 + .../picofeed/lib/PicoFeed/Parser/Rss92.php | 13 + .../PicoFeed/Parser/XmlEntityException.php | 13 + .../lib/PicoFeed/Parser/XmlParser.php | 249 + .../lib/PicoFeed/PicoFeedException.php | 14 + .../Processor/ContentFilterProcessor.php | 39 + .../Processor/ContentGeneratorProcessor.php | 49 + .../PicoFeed/Processor/ItemPostProcessor.php | 106 + .../Processor/ItemProcessorInterface.php | 25 + .../PicoFeed/Processor/ScraperProcessor.php | 96 + .../picofeed/lib/PicoFeed/Reader/Favicon.php | 186 + .../picofeed/lib/PicoFeed/Reader/Reader.php | 189 + .../lib/PicoFeed/Reader/ReaderException.php | 14 + .../Reader/SubscriptionNotFoundException.php | 12 + .../Reader/UnsupportedFeedFormatException.php | 12 + .../lib/PicoFeed/Rules/.blog.lemonde.fr.php | 14 + .../lib/PicoFeed/Rules/.blogs.nytimes.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/.igen.fr.php | 13 + .../lib/PicoFeed/Rules/.nytimes.com.php | 11 + .../lib/PicoFeed/Rules/.over-blog.com.php | 11 + .../lib/PicoFeed/Rules/.phoronix.com.php | 12 + .../lib/PicoFeed/Rules/.slate.com.php | 20 + .../lib/PicoFeed/Rules/.theguardian.com.php | 14 + .../lib/PicoFeed/Rules/.wikipedia.org.php | 29 + .../lib/PicoFeed/Rules/.wired.com.php | 44 + .../picofeed/lib/PicoFeed/Rules/.wsj.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/01net.com.php | 18 + .../p3k/picofeed/lib/PicoFeed/Rules/24.hu.php | 16 + .../picofeed/lib/PicoFeed/Rules/444.hu.php | 19 + .../picofeed/lib/PicoFeed/Rules/888.hu.php | 16 + .../lib/PicoFeed/Rules/abstrusegoose.com.php | 8 + .../lib/PicoFeed/Rules/achgut.com.php | 16 + .../PicoFeed/Rules/adventuregamers.com.php | 23 + .../lib/PicoFeed/Rules/alainonline.net.php | 14 + .../lib/PicoFeed/Rules/aljazeera.com.php | 25 + .../lib/PicoFeed/Rules/allafrica.com.php | 20 + .../PicoFeed/Rules/allgemeine-zeitung.de.php | 23 + .../PicoFeed/Rules/amazingsuperpowers.com.php | 8 + .../lib/PicoFeed/Rules/anythingcomic.com.php | 13 + .../picofeed/lib/PicoFeed/Rules/ap.org.php | 13 + .../lib/PicoFeed/Rules/areadvd.de.php | 10 + .../lib/PicoFeed/Rules/arstechnica.com.php | 25 + .../picofeed/lib/PicoFeed/Rules/atv.hu.php | 18 + .../lib/PicoFeed/Rules/awkwardzombie.com.php | 10 + .../lib/PicoFeed/Rules/backchannel.com.php | 18 + .../lib/PicoFeed/Rules/bangkokpost.com.php | 19 + .../lib/PicoFeed/Rules/bauerwilli.com.php | 17 + .../picofeed/lib/PicoFeed/Rules/bgr.com.php | 15 + .../lib/PicoFeed/Rules/bigfootjustice.com.php | 8 + .../lib/PicoFeed/Rules/bigpicture.ru.php | 31 + .../lib/PicoFeed/Rules/bizjournals.com.php | 12 + .../lib/PicoFeed/Rules/biztimes.com.php | 22 + .../PicoFeed/Rules/bleepingcomputer.com.php | 15 + .../lib/PicoFeed/Rules/blog.fefe.de.php | 13 + .../lib/PicoFeed/Rules/blog.mapillary.com.php | 11 + .../lib/PicoFeed/Rules/brewers.mlb.com.php | 22 + .../PicoFeed/Rules/buenosairesherald.com.php | 17 + .../lib/PicoFeed/Rules/bunicomic.com.php | 13 + .../lib/PicoFeed/Rules/buttersafe.com.php | 13 + .../lib/PicoFeed/Rules/cad-comic.com.php | 12 + .../Rules/chaoslife.findchaos.com.php | 10 + .../lib/PicoFeed/Rules/chinafile.com.php | 18 + .../picofeed/lib/PicoFeed/Rules/cicero.de.php | 17 + .../lib/PicoFeed/Rules/cliquerefresh.com.php | 10 + .../picofeed/lib/PicoFeed/Rules/cnet.com.php | 37 + .../lib/PicoFeed/Rules/coinwelt.de.php | 14 + .../lib/PicoFeed/Rules/consomac.fr.php | 13 + .../lib/PicoFeed/Rules/cowbirdsinlove.com.php | 8 + .../picofeed/lib/PicoFeed/Rules/crash.net.php | 18 + .../lib/PicoFeed/Rules/csmonitor.com.php | 19 + .../lib/PicoFeed/Rules/dailyjs.com.php | 19 + .../lib/PicoFeed/Rules/dailyreporter.com.php | 15 + .../lib/PicoFeed/Rules/dailytech.com.php | 13 + .../lib/PicoFeed/Rules/degroupnews.com.php | 14 + .../lib/PicoFeed/Rules/derstandard.at.php | 14 + .../lib/PicoFeed/Rules/dilbert.com.php | 11 + .../PicoFeed/Rules/discovermagazine.com.php | 26 + .../lib/PicoFeed/Rules/distrowatch.com.php | 13 + .../lib/PicoFeed/Rules/dozodomo.com.php | 15 + .../PicoFeed/Rules/drawingboardcomic.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/e-w-e.ru.php | 22 + .../lib/PicoFeed/Rules/economist.com.php | 25 + .../Rules/encyclopedie.naheulbeuk.com.php | 13 + .../lib/PicoFeed/Rules/endlessorigami.com.php | 8 + .../lib/PicoFeed/Rules/engadget.com.php | 10 + .../PicoFeed/Rules/escapistmagazine.com.php | 45 + .../lib/PicoFeed/Rules/espn.go.com.php | 11 + .../lib/PicoFeed/Rules/exocomics.com.php | 15 + .../lib/PicoFeed/Rules/explosm.net.php | 13 + .../Rules/extrafabulouscomics.com.php | 8 + .../lib/PicoFeed/Rules/factroom.ru.php | 27 + .../lib/PicoFeed/Rules/fastcodesign.com.php | 13 + .../lib/PicoFeed/Rules/fastcoexist.com.php | 13 + .../lib/PicoFeed/Rules/fastcompany.com.php | 13 + .../lib/PicoFeed/Rules/ffworld.com.php | 13 + .../lib/PicoFeed/Rules/foreignpolicy.com.php | 21 + .../lib/PicoFeed/Rules/fossbytes.com.php | 18 + .../lib/PicoFeed/Rules/fototelegraf.ru.php | 19 + .../PicoFeed/Rules/fowllanguagecomics.com.php | 10 + .../lib/PicoFeed/Rules/gamechannel.hu.php | 15 + .../lib/PicoFeed/Rules/gamestar.hu.php | 17 + .../picofeed/lib/PicoFeed/Rules/geek.com.php | 17 + .../lib/PicoFeed/Rules/geektimes.ru.php | 12 + .../PicoFeed/Rules/gerbilwithajetpack.com.php | 12 + .../lib/PicoFeed/Rules/giantitp.com.php | 12 + .../lib/PicoFeed/Rules/github.com.php | 14 + .../lib/PicoFeed/Rules/gocomics.com.php | 12 + .../picofeed/lib/PicoFeed/Rules/golem.de.php | 21 + .../lib/PicoFeed/Rules/gondola.hu.php | 22 + .../lib/PicoFeed/Rules/gorabbit.ru.php | 19 + .../lib/PicoFeed/Rules/habrahabr.ru.php | 12 + .../lib/PicoFeed/Rules/happletea.com.php | 18 + .../lib/PicoFeed/Rules/hardware.fr.php | 11 + .../picofeed/lib/PicoFeed/Rules/heise.de.php | 79 + .../lib/PicoFeed/Rules/hirek.prim.hu.php | 14 + .../lib/PicoFeed/Rules/hotshowlife.com.php | 23 + .../lib/PicoFeed/Rules/huffingtonpost.com.php | 13 + .../picofeed/lib/PicoFeed/Rules/hvg.hu.php | 17 + .../picofeed/lib/PicoFeed/Rules/idokep.hu.php | 18 + .../lib/PicoFeed/Rules/imogenquest.net.php | 8 + .../picofeed/lib/PicoFeed/Rules/index.hu.php | 29 + .../lib/PicoFeed/Rules/indiehaven.com.php | 11 + .../lib/PicoFeed/Rules/inforadio.hu.php | 25 + .../picofeed/lib/PicoFeed/Rules/ing.dk.php | 12 + .../lib/PicoFeed/Rules/invisiblebread.com.php | 8 + .../lib/PicoFeed/Rules/ir.amd.com.php | 10 + .../lib/PicoFeed/Rules/japantimes.co.jp.php | 21 + .../lib/PicoFeed/Rules/japantoday.com.php | 15 + .../lib/PicoFeed/Rules/journaldugeek.com.php | 11 + .../lib/PicoFeed/Rules/jsonline.com.php | 37 + .../lib/PicoFeed/Rules/justcoolidea.ru.php | 19 + .../picofeed/lib/PicoFeed/Rules/kanpai.fr.php | 13 + .../PicoFeed/Rules/karriere.jobfinder.dk.php | 12 + .../lib/PicoFeed/Rules/kisalfold.hu.php | 17 + .../lib/PicoFeed/Rules/kiszamolo.hu.php | 14 + .../picofeed/lib/PicoFeed/Rules/kodi.tv.php | 11 + .../lib/PicoFeed/Rules/koreaherald.com.php | 11 + .../lib/PicoFeed/Rules/koreatimes.php | 14 + .../PicoFeed/Rules/lastplacecomics.com.php | 8 + .../lib/PicoFeed/Rules/legorafi.fr.php | 22 + .../lib/PicoFeed/Rules/lejapon.fr.php | 17 + .../lib/PicoFeed/Rules/lesjoiesducode.fr.php | 13 + .../picofeed/lib/PicoFeed/Rules/lfg.co.php | 12 + .../lib/PicoFeed/Rules/lifehacker.com.php | 18 + .../lib/PicoFeed/Rules/lifehacker.ru.php | 22 + .../lib/PicoFeed/Rules/linux-magazin.de.php | 16 + .../picofeed/lib/PicoFeed/Rules/linux.org.php | 14 + .../lib/PicoFeed/Rules/linux.org.ru.php | 13 + .../lib/PicoFeed/Rules/linuxinsider.com.php | 20 + .../p3k/picofeed/lib/PicoFeed/Rules/lists.php | 13 + .../lib/PicoFeed/Rules/loadingartist.com.php | 8 + .../lib/PicoFeed/Rules/loldwell.com.php | 10 + .../lib/PicoFeed/Rules/lukesurl.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/macg.co.php | 13 + .../lib/PicoFeed/Rules/maclife.de.php | 11 + .../lib/PicoFeed/Rules/magyarkurir.hu.php | 21 + .../picofeed/lib/PicoFeed/Rules/marc.info.php | 13 + .../PicoFeed/Rules/marriedtothesea.com.php | 12 + .../lib/PicoFeed/Rules/marycagle.com.php | 13 + .../Rules/maximumble.thebookofbiff.com.php | 10 + .../lib/PicoFeed/Rules/medium.com.php | 19 + .../lib/PicoFeed/Rules/mercworks.net.php | 17 + .../lib/PicoFeed/Rules/metronieuws.nl.php | 10 + .../lib/PicoFeed/Rules/milwaukeenns.php | 14 + .../picofeed/lib/PicoFeed/Rules/mno.hu.php | 14 + .../Rules/mokepon.smackjeeves.com.php | 10 + .../lib/PicoFeed/Rules/monandroid.com.php | 13 + .../lib/PicoFeed/Rules/monwindows.com.php | 13 + .../lib/PicoFeed/Rules/moya-planeta.ru.php | 21 + .../lib/PicoFeed/Rules/mrlovenstein.com.php | 9 + .../lib/PicoFeed/Rules/muckrock.com.php | 20 + .../PicoFeed/Rules/mynorthshorenow.com.php | 27 + .../lib/PicoFeed/Rules/nakedCapitalism.php | 11 + .../picofeed/lib/PicoFeed/Rules/nasa.gov.php | 14 + .../lib/PicoFeed/Rules/nat-geo.ru.php | 11 + .../PicoFeed/Rules/nationaljournal.com.php | 15 + .../lib/PicoFeed/Rules/nature.com.php | 13 + .../picofeed/lib/PicoFeed/Rules/nba.com.php | 15 + .../lib/PicoFeed/Rules/nedroid.com.php | 8 + .../lib/PicoFeed/Rules/networkworld.com.php | 20 + .../lib/PicoFeed/Rules/neustadt-ticker.de.php | 15 + .../lib/PicoFeed/Rules/nextinpact.com.php | 18 + .../lib/PicoFeed/Rules/niceteethcomic.com.php | 10 + .../lib/PicoFeed/Rules/nichtlustig.de.php | 8 + .../picofeed/lib/PicoFeed/Rules/nlcafe.hu.php | 18 + .../lib/PicoFeed/Rules/novo-argumente.com.php | 16 + .../picofeed/lib/PicoFeed/Rules/oglaf.com.php | 19 + .../picofeed/lib/PicoFeed/Rules/onhax.net.php | 15 + .../lib/PicoFeed/Rules/onlinekosten.de.php | 13 + .../lib/PicoFeed/Rules/onmilwaukee.php | 24 + .../lib/PicoFeed/Rules/openculture.com.php | 11 + .../lib/PicoFeed/Rules/opennet.ru.php | 13 + .../PicoFeed/Rules/openrightsgroup.org.php | 20 + .../lib/PicoFeed/Rules/opensource.com.php | 22 + .../lib/PicoFeed/Rules/optipess.com.php | 8 + .../picofeed/lib/PicoFeed/Rules/origo.hu.php | 14 + .../lib/PicoFeed/Rules/osnews.com.php | 11 + .../lib/PicoFeed/Rules/pastebin.com.php | 13 + .../lib/PicoFeed/Rules/pcgameshardware.de.php | 16 + .../lib/PicoFeed/Rules/peebleslab.com.php | 9 + .../lib/PicoFeed/Rules/penny-arcade.com.php | 21 + .../lib/PicoFeed/Rules/pixelbeat.org.php | 12 + .../lib/PicoFeed/Rules/plus.google.com.php | 11 + .../lib/PicoFeed/Rules/popstrip.com.php | 8 + .../lib/PicoFeed/Rules/portfolio.hu.php | 15 + .../lib/PicoFeed/Rules/pro-linux.de.php | 16 + .../PicoFeed/Rules/publicpolicyforum.org.php | 15 + .../picofeed/lib/PicoFeed/Rules/publy.ru.php | 24 + .../lib/PicoFeed/Rules/putaindecode.fr.php | 16 + .../lib/PicoFeed/Rules/recode.net.php | 20 + .../PicoFeed/Rules/retractionwatch.com.php | 18 + .../PicoFeed/Rules/rockpapershotgun.com.php | 11 + .../PicoFeed/Rules/rue89.nouvelobs.com.php | 13 + .../lib/PicoFeed/Rules/rugbyrama.fr.php | 20 + .../lib/PicoFeed/Rules/salonkolumnisten.com | 17 + .../lib/PicoFeed/Rules/satwcomic.com.php | 13 + .../PicoFeed/Rules/science-skeptical.de.php | 14 + .../lib/PicoFeed/Rules/scrumalliance.org.php | 12 + .../lib/PicoFeed/Rules/securityfocus.com.php | 17 + .../PicoFeed/Rules/sentfromthemoon.com.php | 18 + .../lib/PicoFeed/Rules/sitepoint.com.php | 13 + .../lib/PicoFeed/Rules/slashdot.org.php | 11 + .../PicoFeed/Rules/smallhousebliss.com.php | 19 + .../lib/PicoFeed/Rules/smarthomewelt.de.php | 10 + .../PicoFeed/Rules/smashingmagazine.com.php | 10 + .../lib/PicoFeed/Rules/smbc-comics.com.php | 14 + .../lib/PicoFeed/Rules/snopes.com.php | 22 + .../lib/PicoFeed/Rules/soundandvision.com.php | 21 + .../lib/PicoFeed/Rules/spiegel.de.php | 14 + .../lib/PicoFeed/Rules/stereophile.com.php | 11 + .../lib/PicoFeed/Rules/stupidfox.net.php | 13 + .../lib/PicoFeed/Rules/subtraction.com.php | 15 + .../p3k/picofeed/lib/PicoFeed/Rules/sz.de.php | 10 + .../lib/PicoFeed/Rules/takprosto.cc.php | 21 + .../lib/PicoFeed/Rules/techcrunch.com.php | 15 + .../PicoFeed/Rules/the-ebook-reader.com.php | 15 + .../lib/PicoFeed/Rules/theatlantic.com.php | 23 + .../lib/PicoFeed/Rules/theawkwardyeti.com.php | 12 + .../lib/PicoFeed/Rules/thecodinglove.com.php | 10 + .../PicoFeed/Rules/thedoghousediaries.com.php | 18 + .../lib/PicoFeed/Rules/thegamercat.com.php | 10 + .../lib/PicoFeed/Rules/thehindu.com.php | 19 + .../lib/PicoFeed/Rules/thelocal.se.php | 17 + .../lib/PicoFeed/Rules/themerepublic.net.php | 10 + .../lib/PicoFeed/Rules/themoscowtimes.com.php | 18 + .../lib/PicoFeed/Rules/thenewslens.com.php | 21 + .../lib/PicoFeed/Rules/theodd1sout.com.php | 8 + .../lib/PicoFeed/Rules/theonion.com.php | 12 + .../lib/PicoFeed/Rules/theregister.co.uk.php | 18 + .../lib/PicoFeed/Rules/thestandard.com.hk.php | 22 + .../lib/PicoFeed/Rules/theverge.com.php | 16 + .../lib/PicoFeed/Rules/threepanelsoul.com.php | 11 + .../lib/PicoFeed/Rules/tichyseinblick.de.php | 22 + .../Rules/timesofindia.indiatimes.com.php | 14 + .../lib/PicoFeed/Rules/totalcar.hu.php | 18 + .../lib/PicoFeed/Rules/tozsdeforum.hu.php | 15 + .../lib/PicoFeed/Rules/travel-dealz.de.php | 15 + .../lib/PicoFeed/Rules/travelo.hu.php | 17 + .../lib/PicoFeed/Rules/treehugger.com.php | 14 + .../lib/PicoFeed/Rules/treelobsters.com.php | 8 + .../lib/PicoFeed/Rules/tutorialzine.com.php | 20 + .../lib/PicoFeed/Rules/twogag.com.php | 8 + .../PicoFeed/Rules/twokinds.keenspot.com.php | 10 + .../lib/PicoFeed/Rules/undeadly.org.php | 14 + .../picofeed/lib/PicoFeed/Rules/upi.com.php | 15 + .../lib/PicoFeed/Rules/usatoday.com.php | 27 + .../lib/PicoFeed/Rules/version2.dk.php | 12 + .../picofeed/lib/PicoFeed/Rules/vezess.hu.php | 20 + .../lib/PicoFeed/Rules/vgcats.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/vuxml.org.php | 17 + .../PicoFeed/Rules/wausaudailyherald.com.php | 27 + .../picofeed/lib/PicoFeed/Rules/welt.de.php | 20 + .../lib/PicoFeed/Rules/westfalen-blatt.de.php | 16 + .../lib/PicoFeed/Rules/www.bbc.co.uk.php | 33 + .../lib/PicoFeed/Rules/www.bdgest.com.php | 15 + .../lib/PicoFeed/Rules/www.bgr.in.php | 23 + .../PicoFeed/Rules/www.businessweek.com.php | 15 + .../lib/PicoFeed/Rules/www.cnn.com.php | 24 + .../lib/PicoFeed/Rules/www.developpez.com.php | 21 + .../lib/PicoFeed/Rules/www.egscomics.com.php | 12 + .../Rules/www.fakingnews.firstpost.com.php | 17 + .../lib/PicoFeed/Rules/www.forbes.com.php | 20 + .../PicoFeed/Rules/www.franceculture.fr.php | 14 + .../Rules/www.futura-sciences.com.php | 19 + .../PicoFeed/Rules/www.geekculture.com.php | 13 + .../lib/PicoFeed/Rules/www.howtogeek.com.php | 14 + .../lib/PicoFeed/Rules/www.lepoint.fr.php | 18 + .../PicoFeed/Rules/www.lesnumeriques.com.php | 25 + .../lib/PicoFeed/Rules/www.mac4ever.com.php | 13 + .../lib/PicoFeed/Rules/www.makeuseof.com.php | 18 + .../Rules/www.monsieur-le-chien.fr.php | 11 + .../lib/PicoFeed/Rules/www.npr.org.php | 28 + .../lib/PicoFeed/Rules/www.numerama.com.php | 15 + .../lib/PicoFeed/Rules/www.oneindia.com.php | 14 + .../Rules/www.pseudo-sciences.org.php | 16 + .../lib/PicoFeed/Rules/www.sciencemag.org.php | 16 + .../lib/PicoFeed/Rules/www.slate.fr.php | 19 + .../PicoFeed/Rules/www.universfreebox.com.php | 15 + .../lib/PicoFeed/Rules/www.zeit.de.php | 41 + .../picofeed/lib/PicoFeed/Rules/xkcd.com.php | 8 + .../lib/PicoFeed/Rules/ymatuhin.ru.php | 21 + .../lib/PicoFeed/Rules/zarojel.hu.php | 19 + .../picofeed/lib/PicoFeed/Rules/zdnet.com.php | 23 + .../picofeed/lib/PicoFeed/Rules/zoom.hu.php | 17 + .../lib/PicoFeed/Scraper/CandidateParser.php | 281 + .../lib/PicoFeed/Scraper/ParserInterface.php | 20 + .../lib/PicoFeed/Scraper/RuleLoader.php | 104 + .../lib/PicoFeed/Scraper/RuleParser.php | 102 + .../picofeed/lib/PicoFeed/Scraper/Scraper.php | 282 + .../PicoFeed/Serialization/Subscription.php | 175 + .../Serialization/SubscriptionList.php | 75 + .../Serialization/SubscriptionListBuilder.php | 204 + .../Serialization/SubscriptionListParser.php | 100 + .../Serialization/SubscriptionParser.php | 142 + .../PicoFeed/Syndication/AtomFeedBuilder.php | 65 + .../lib/PicoFeed/Syndication/AtomHelper.php | 139 + .../PicoFeed/Syndication/AtomItemBuilder.php | 63 + .../lib/PicoFeed/Syndication/FeedBuilder.php | 185 + .../lib/PicoFeed/Syndication/ItemBuilder.php | 209 + .../PicoFeed/Syndication/Rss20FeedBuilder.php | 76 + .../lib/PicoFeed/Syndication/Rss20Helper.php | 115 + .../PicoFeed/Syndication/Rss20ItemBuilder.php | 67 + plugins/admin/vendor/p3k/picofeed/picofeed | 135 + .../admin/vendor/scssphp/scssphp/LICENSE.md | 20 + .../admin/vendor/scssphp/scssphp/README.md | 71 + .../admin/vendor/scssphp/scssphp/bin/pscss | 244 + .../vendor/scssphp/scssphp/composer.json | 108 + .../vendor/scssphp/scssphp/phpcs.xml.dist | 12 + .../admin/vendor/scssphp/scssphp/scss.inc.php | 21 + .../vendor/scssphp/scssphp/src/Base/Range.php | 57 + .../vendor/scssphp/scssphp/src/Block.php | 73 + .../vendor/scssphp/scssphp/src/Cache.php | 272 + .../vendor/scssphp/scssphp/src/Colors.php | 247 + .../scssphp/scssphp/src/CompilationResult.php | 69 + .../vendor/scssphp/scssphp/src/Compiler.php | 10087 ++ .../scssphp/src/Compiler/CachedResult.php | 77 + .../scssphp/src/Compiler/Environment.php | 48 + .../src/Exception/CompilerException.php | 24 + .../scssphp/src/Exception/ParserException.php | 50 + .../scssphp/src/Exception/RangeException.php | 24 + .../scssphp/src/Exception/SassException.php | 7 + .../src/Exception/SassScriptException.php | 32 + .../scssphp/src/Exception/ServerException.php | 26 + .../vendor/scssphp/scssphp/src/Formatter.php | 364 + .../scssphp/scssphp/src/Formatter/Compact.php | 52 + .../scssphp/src/Formatter/Compressed.php | 85 + .../scssphp/src/Formatter/Crunched.php | 87 + .../scssphp/scssphp/src/Formatter/Debug.php | 127 + .../scssphp/src/Formatter/Expanded.php | 70 + .../scssphp/scssphp/src/Formatter/Nested.php | 236 + .../scssphp/src/Formatter/OutputBlock.php | 68 + .../scssphp/src/Logger/LoggerInterface.php | 48 + .../scssphp/src/Logger/QuietLogger.php | 27 + .../scssphp/src/Logger/StreamLogger.php | 60 + .../admin/vendor/scssphp/scssphp/src/Node.php | 43 + .../scssphp/scssphp/src/Node/Number.php | 804 + .../scssphp/scssphp/src/OutputStyle.php | 9 + .../vendor/scssphp/scssphp/src/Parser.php | 4128 + .../scssphp/scssphp/src/SourceMap/Base64.php | 187 + .../scssphp/src/SourceMap/Base64VLQ.php | 151 + .../src/SourceMap/SourceMapGenerator.php | 381 + .../admin/vendor/scssphp/scssphp/src/Type.php | 76 + .../admin/vendor/scssphp/scssphp/src/Util.php | 184 + .../vendor/scssphp/scssphp/src/Util/Path.php | 77 + .../scssphp/scssphp/src/ValueConverter.php | 95 + .../vendor/scssphp/scssphp/src/Version.php | 23 + .../admin/vendor/scssphp/scssphp/src/Warn.php | 84 + plugins/anchors/.idea/vcs.xml | 6 + plugins/anchors/CHANGELOG.md | 65 + plugins/anchors/LICENSE | 21 + plugins/anchors/README.md | 106 + plugins/anchors/anchors.php | 109 + plugins/anchors/anchors.yaml | 9 + plugins/anchors/blueprints.yaml | 107 + plugins/anchors/hebe.json | 15 + plugins/anchors/js/anchor.min.js | 9 + plugins/anchors/js/clipboard.min.js | 7 + plugins/anchors/twig/AnchorsTwigExtension.php | 142 + plugins/archives/CHANGELOG.md | 90 + plugins/archives/LICENSE | 21 + plugins/archives/README.md | 142 + plugins/archives/archives.php | 267 + plugins/archives/archives.yaml | 27 + plugins/archives/assets/readme_1.png | Bin 0 -> 39328 bytes plugins/archives/blueprints.yaml | 190 + plugins/archives/composer.json | 27 + plugins/archives/composer.lock | 22 + .../templates/partials/archives.html.twig | 13 + plugins/archives/vendor/autoload.php | 7 + .../archives/vendor/composer/ClassLoader.php | 445 + plugins/archives/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 9 + .../vendor/composer/autoload_real.php | 52 + .../vendor/composer/autoload_static.php | 20 + .../archives/vendor/composer/installed.json | 1 + plugins/aura-authors/.gitattributes | 2 + plugins/aura-authors/CHANGELOG.md | 5 + plugins/aura-authors/LICENSE | 21 + plugins/aura-authors/README.md | 39 + plugins/aura-authors/assets/demo.jpg | Bin 0 -> 108256 bytes plugins/aura-authors/assets/fonts/icomoon.eot | Bin 0 -> 3188 bytes plugins/aura-authors/assets/fonts/icomoon.svg | 17 + plugins/aura-authors/assets/fonts/icomoon.ttf | Bin 0 -> 3024 bytes .../aura-authors/assets/fonts/icomoon.woff | Bin 0 -> 3100 bytes plugins/aura-authors/assets/style.min.css | 1 + plugins/aura-authors/assets/style.min.css.map | 1 + plugins/aura-authors/assets/style.scss | 128 + plugins/aura-authors/aura-authors.php | 112 + plugins/aura-authors/aura-authors.yaml | 2 + plugins/aura-authors/blueprints.yaml | 126 + plugins/aura-authors/blueprints/default.yaml | 40 + .../templates/partials/author-bio.html.twig | 45 + plugins/comments/CHANGELOG.md | 135 + plugins/comments/README.md | 74 + plugins/comments/admin/pages/comments.md | 7 + .../admin/templates/comments.html.twig | 133 + plugins/comments/blueprints.yaml | 33 + plugins/comments/comments.php | 435 + plugins/comments/comments.yaml | 77 + plugins/comments/languages.yaml | 276 + .../templates/partials/comments.html.twig | 60 + plugins/custom-css/CHANGELOG.md | 25 + plugins/custom-css/LICENSE | 21 + plugins/custom-css/README.md | 9 + plugins/custom-css/blueprints.yaml | 48 + plugins/custom-css/custom-css.php | 48 + plugins/custom-css/custom-css.yaml | 1 + plugins/custom-css/languages.yaml | 20 + plugins/email/CHANGELOG.md | 314 + plugins/email/LICENSE | 21 + plugins/email/README.md | 491 + plugins/email/blueprints.yaml | 251 + plugins/email/classes/Email.php | 560 + plugins/email/classes/Utils.php | 48 + .../email/cli/ClearQueueFailuresCommand.php | 62 + plugins/email/cli/FlushQueueCommand.php | 63 + plugins/email/cli/TestEmailCommand.php | 107 + plugins/email/composer.json | 33 + plugins/email/composer.lock | 651 + plugins/email/email.php | 181 + plugins/email/email.yaml | 23 + plugins/email/hebe.json | 15 + plugins/email/languages.yaml | 165 + plugins/email/templates/email/base.html.twig | 214 + plugins/email/vendor/autoload.php | 7 + plugins/email/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 291 + plugins/email/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 12 + .../email/vendor/composer/autoload_files.php | 15 + .../vendor/composer/autoload_namespaces.php | 9 + .../email/vendor/composer/autoload_psr4.php | 18 + .../email/vendor/composer/autoload_real.php | 75 + .../email/vendor/composer/autoload_static.php | 96 + plugins/email/vendor/composer/installed.json | 660 + plugins/email/vendor/composer/installed.php | 96 + .../email/vendor/composer/platform_check.php | 26 + plugins/email/vendor/doctrine/lexer/LICENSE | 19 + plugins/email/vendor/doctrine/lexer/README.md | 9 + .../email/vendor/doctrine/lexer/composer.json | 41 + .../Doctrine/Common/Lexer/AbstractLexer.php | 328 + .../vendor/egulias/email-validator/LICENSE | 19 + .../egulias/email-validator/composer.json | 38 + .../email-validator/src/EmailLexer.php | 283 + .../email-validator/src/EmailParser.php | 137 + .../email-validator/src/EmailValidator.php | 67 + .../src/Exception/AtextAfterCFWS.php | 9 + .../src/Exception/CRLFAtTheEnd.php | 9 + .../email-validator/src/Exception/CRLFX2.php | 9 + .../email-validator/src/Exception/CRNoLF.php | 9 + .../src/Exception/CharNotAllowed.php | 9 + .../src/Exception/CommaInDomain.php | 9 + .../src/Exception/ConsecutiveAt.php | 9 + .../src/Exception/ConsecutiveDot.php | 9 + .../src/Exception/DomainAcceptsNoMail.php | 9 + .../src/Exception/DomainHyphened.php | 9 + .../src/Exception/DotAtEnd.php | 9 + .../src/Exception/DotAtStart.php | 9 + .../src/Exception/ExpectingAT.php | 9 + .../src/Exception/ExpectingATEXT.php | 9 + .../src/Exception/ExpectingCTEXT.php | 9 + .../src/Exception/ExpectingDTEXT.php | 9 + .../Exception/ExpectingDomainLiteralClose.php | 9 + .../src/Exception/ExpectingQPair.php | 9 + .../src/Exception/InvalidEmail.php | 14 + .../src/Exception/LocalOrReservedDomain.php | 9 + .../src/Exception/NoDNSRecord.php | 9 + .../src/Exception/NoDomainPart.php | 9 + .../src/Exception/NoLocalPart.php | 9 + .../src/Exception/UnclosedComment.php | 9 + .../src/Exception/UnclosedQuotedString.php | 9 + .../src/Exception/UnopenedComment.php | 9 + .../email-validator/src/Parser/DomainPart.php | 443 + .../email-validator/src/Parser/LocalPart.php | 145 + .../email-validator/src/Parser/Parser.php | 249 + .../src/Validation/DNSCheckValidation.php | 166 + .../src/Validation/EmailValidation.php | 34 + .../src/Validation/Error/RFCWarnings.php | 11 + .../src/Validation/Error/SpoofEmail.php | 11 + .../Exception/EmptyValidationList.php | 16 + .../src/Validation/MultipleErrors.php | 32 + .../Validation/MultipleValidationWithAnd.php | 124 + .../Validation/NoRFCWarningsValidation.php | 41 + .../src/Validation/RFCValidation.php | 49 + .../src/Validation/SpoofCheckValidation.php | 51 + .../src/Warning/AddressLiteral.php | 14 + .../src/Warning/CFWSNearAt.php | 13 + .../src/Warning/CFWSWithFWS.php | 13 + .../email-validator/src/Warning/Comment.php | 13 + .../src/Warning/DeprecatedComment.php | 13 + .../src/Warning/DomainLiteral.php | 14 + .../src/Warning/DomainTooLong.php | 14 + .../src/Warning/EmailTooLong.php | 15 + .../src/Warning/IPV6BadChar.php | 14 + .../src/Warning/IPV6ColonEnd.php | 14 + .../src/Warning/IPV6ColonStart.php | 14 + .../src/Warning/IPV6Deprecated.php | 14 + .../src/Warning/IPV6DoubleColon.php | 14 + .../src/Warning/IPV6GroupCount.php | 14 + .../src/Warning/IPV6MaxGroups.php | 14 + .../src/Warning/LabelTooLong.php | 14 + .../src/Warning/LocalTooLong.php | 15 + .../src/Warning/NoDNSMXRecord.php | 14 + .../src/Warning/ObsoleteDTEXT.php | 14 + .../src/Warning/QuotedPart.php | 17 + .../src/Warning/QuotedString.php | 17 + .../email-validator/src/Warning/TLD.php | 13 + .../email-validator/src/Warning/Warning.php | 47 + .../swiftmailer/swiftmailer/.gitattributes | 11 + .../swiftmailer/.github/ISSUE_TEMPLATE.md | 19 + .../.github/PULL_REQUEST_TEMPLATE.md | 14 + .../vendor/swiftmailer/swiftmailer/.gitignore | 9 + .../swiftmailer/swiftmailer/.php_cs.dist | 21 + .../swiftmailer/swiftmailer/.travis.yml | 30 + .../vendor/swiftmailer/swiftmailer/CHANGES | 366 + .../vendor/swiftmailer/swiftmailer/LICENSE | 19 + .../vendor/swiftmailer/swiftmailer/README.md | 19 + .../swiftmailer/swiftmailer/composer.json | 42 + .../swiftmailer/swiftmailer/doc/headers.rst | 621 + .../swiftmailer/swiftmailer/doc/index.rst | 12 + .../swiftmailer/doc/introduction.rst | 61 + .../swiftmailer/swiftmailer/doc/japanese.rst | 19 + .../swiftmailer/swiftmailer/doc/messages.rst | 947 + .../swiftmailer/swiftmailer/doc/plugins.rst | 337 + .../swiftmailer/swiftmailer/doc/sending.rst | 453 + .../swiftmailer/lib/classes/Swift.php | 78 + .../lib/classes/Swift/AddressEncoder.php | 25 + .../AddressEncoder/IdnAddressEncoder.php | 50 + .../AddressEncoder/Utf8AddressEncoder.php | 36 + .../classes/Swift/AddressEncoderException.php | 32 + .../lib/classes/Swift/Attachment.php | 54 + .../AbstractFilterableInputStream.php | 176 + .../Swift/ByteStream/ArrayByteStream.php | 178 + .../Swift/ByteStream/FileByteStream.php | 214 + .../ByteStream/TemporaryFileByteStream.php | 52 + .../lib/classes/Swift/CharacterReader.php | 67 + .../GenericFixedWidthReader.php | 97 + .../Swift/CharacterReader/UsAsciiReader.php | 84 + .../Swift/CharacterReader/Utf8Reader.php | 176 + .../classes/Swift/CharacterReaderFactory.php | 26 + .../SimpleCharacterReaderFactory.php | 124 + .../lib/classes/Swift/CharacterStream.php | 87 + .../CharacterStream/ArrayCharacterStream.php | 291 + .../CharacterStream/NgCharacterStream.php | 262 + .../lib/classes/Swift/ConfigurableSpool.php | 63 + .../lib/classes/Swift/DependencyContainer.php | 387 + .../lib/classes/Swift/DependencyException.php | 27 + .../lib/classes/Swift/EmbeddedFile.php | 53 + .../swiftmailer/lib/classes/Swift/Encoder.php | 28 + .../classes/Swift/Encoder/Base64Encoder.php | 58 + .../lib/classes/Swift/Encoder/QpEncoder.php | 300 + .../classes/Swift/Encoder/Rfc2231Encoder.php | 90 + .../lib/classes/Swift/Events/CommandEvent.php | 64 + .../classes/Swift/Events/CommandListener.php | 22 + .../lib/classes/Swift/Events/Event.php | 38 + .../classes/Swift/Events/EventDispatcher.php | 70 + .../classes/Swift/Events/EventListener.php | 18 + .../lib/classes/Swift/Events/EventObject.php | 61 + .../classes/Swift/Events/ResponseEvent.php | 64 + .../classes/Swift/Events/ResponseListener.php | 22 + .../lib/classes/Swift/Events/SendEvent.php | 126 + .../lib/classes/Swift/Events/SendListener.php | 27 + .../Swift/Events/SimpleEventDispatcher.php | 142 + .../Swift/Events/TransportChangeEvent.php | 27 + .../Swift/Events/TransportChangeListener.php | 37 + .../Swift/Events/TransportExceptionEvent.php | 43 + .../Events/TransportExceptionListener.php | 22 + .../lib/classes/Swift/FailoverTransport.php | 33 + .../lib/classes/Swift/FileSpool.php | 208 + .../lib/classes/Swift/FileStream.php | 24 + .../lib/classes/Swift/Filterable.php | 31 + .../lib/classes/Swift/IdGenerator.php | 22 + .../swiftmailer/lib/classes/Swift/Image.php | 43 + .../lib/classes/Swift/InputByteStream.php | 75 + .../lib/classes/Swift/IoException.php | 28 + .../lib/classes/Swift/KeyCache.php | 104 + .../classes/Swift/KeyCache/ArrayKeyCache.php | 197 + .../classes/Swift/KeyCache/DiskKeyCache.php | 294 + .../Swift/KeyCache/KeyCacheInputStream.php | 47 + .../classes/Swift/KeyCache/NullKeyCache.php | 113 + .../KeyCache/SimpleKeyCacheInputStream.php | 123 + .../classes/Swift/LoadBalancedTransport.php | 33 + .../swiftmailer/lib/classes/Swift/Mailer.php | 98 + .../Swift/Mailer/ArrayRecipientIterator.php | 53 + .../Swift/Mailer/RecipientIterator.php | 32 + .../lib/classes/Swift/MemorySpool.php | 110 + .../swiftmailer/lib/classes/Swift/Message.php | 279 + .../lib/classes/Swift/Mime/Attachment.php | 144 + .../classes/Swift/Mime/CharsetObserver.php | 24 + .../lib/classes/Swift/Mime/ContentEncoder.php | 34 + .../ContentEncoder/Base64ContentEncoder.php | 101 + .../ContentEncoder/NativeQpContentEncoder.php | 121 + .../ContentEncoder/NullContentEncoder.php | 79 + .../ContentEncoder/PlainContentEncoder.php | 164 + .../Mime/ContentEncoder/QpContentEncoder.php | 134 + .../ContentEncoder/QpContentEncoderProxy.php | 96 + .../Mime/ContentEncoder/RawContentEncoder.php | 65 + .../lib/classes/Swift/Mime/EmbeddedFile.php | 41 + .../classes/Swift/Mime/EncodingObserver.php | 22 + .../lib/classes/Swift/Mime/Header.php | 93 + .../lib/classes/Swift/Mime/HeaderEncoder.php | 24 + .../HeaderEncoder/Base64HeaderEncoder.php | 55 + .../Mime/HeaderEncoder/QpHeaderEncoder.php | 65 + .../Swift/Mime/Headers/AbstractHeader.php | 476 + .../classes/Swift/Mime/Headers/DateHeader.php | 113 + .../Mime/Headers/IdentificationHeader.php | 186 + .../Swift/Mime/Headers/MailboxHeader.php | 358 + .../Swift/Mime/Headers/OpenDKIMHeader.php | 135 + .../Mime/Headers/ParameterizedHeader.php | 255 + .../classes/Swift/Mime/Headers/PathHeader.php | 153 + .../Swift/Mime/Headers/UnstructuredHeader.php | 109 + .../lib/classes/Swift/Mime/IdGenerator.php | 54 + .../lib/classes/Swift/Mime/MimePart.php | 199 + .../Swift/Mime/SimpleHeaderFactory.php | 194 + .../classes/Swift/Mime/SimpleHeaderSet.php | 399 + .../lib/classes/Swift/Mime/SimpleMessage.php | 642 + .../classes/Swift/Mime/SimpleMimeEntity.php | 826 + .../lib/classes/Swift/MimePart.php | 45 + .../lib/classes/Swift/NullTransport.php | 26 + .../lib/classes/Swift/OutputByteStream.php | 46 + .../classes/Swift/Plugins/AntiFloodPlugin.php | 137 + .../Swift/Plugins/BandwidthMonitorPlugin.php | 154 + .../Swift/Plugins/Decorator/Replacements.php | 31 + .../classes/Swift/Plugins/DecoratorPlugin.php | 200 + .../Swift/Plugins/ImpersonatePlugin.php | 65 + .../lib/classes/Swift/Plugins/Logger.php | 36 + .../classes/Swift/Plugins/LoggerPlugin.php | 126 + .../Swift/Plugins/Loggers/ArrayLogger.php | 72 + .../Swift/Plugins/Loggers/EchoLogger.php | 58 + .../classes/Swift/Plugins/MessageLogger.php | 70 + .../Swift/Plugins/Pop/Pop3Connection.php | 31 + .../Swift/Plugins/Pop/Pop3Exception.php | 27 + .../Swift/Plugins/PopBeforeSmtpPlugin.php | 242 + .../Swift/Plugins/RedirectingPlugin.php | 201 + .../lib/classes/Swift/Plugins/Reporter.php | 31 + .../classes/Swift/Plugins/ReporterPlugin.php | 57 + .../Swift/Plugins/Reporters/HitReporter.php | 58 + .../Swift/Plugins/Reporters/HtmlReporter.php | 38 + .../lib/classes/Swift/Plugins/Sleeper.php | 24 + .../classes/Swift/Plugins/ThrottlerPlugin.php | 196 + .../lib/classes/Swift/Plugins/Timer.php | 24 + .../lib/classes/Swift/Preferences.php | 100 + .../Swift/ReplacementFilterFactory.php | 27 + .../classes/Swift/RfcComplianceException.php | 27 + .../lib/classes/Swift/SendmailTransport.php | 33 + .../swiftmailer/lib/classes/Swift/Signer.php | 19 + .../lib/classes/Swift/Signers/BodySigner.php | 31 + .../lib/classes/Swift/Signers/DKIMSigner.php | 682 + .../classes/Swift/Signers/DomainKeySigner.php | 504 + .../classes/Swift/Signers/HeaderSigner.php | 61 + .../classes/Swift/Signers/OpenDKIMSigner.php | 183 + .../lib/classes/Swift/Signers/SMimeSigner.php | 542 + .../lib/classes/Swift/SmtpTransport.php | 42 + .../swiftmailer/lib/classes/Swift/Spool.php | 53 + .../lib/classes/Swift/SpoolTransport.php | 33 + .../lib/classes/Swift/StreamFilter.php | 35 + .../ByteArrayReplacementFilter.php | 166 + .../StreamFilters/StringReplacementFilter.php | 70 + .../StringReplacementFilterFactory.php | 45 + .../lib/classes/Swift/SwiftException.php | 28 + .../lib/classes/Swift/Transport.php | 76 + .../Swift/Transport/AbstractSmtpTransport.php | 556 + .../Esmtp/Auth/CramMd5Authenticator.php | 75 + .../Esmtp/Auth/LoginAuthenticator.php | 45 + .../Esmtp/Auth/NTLMAuthenticator.php | 681 + .../Esmtp/Auth/PlainAuthenticator.php | 44 + .../Esmtp/Auth/XOAuth2Authenticator.php | 64 + .../Swift/Transport/Esmtp/AuthHandler.php | 268 + .../Swift/Transport/Esmtp/Authenticator.php | 36 + .../Transport/Esmtp/EightBitMimeHandler.php | 113 + .../Swift/Transport/Esmtp/SmtpUtf8Handler.php | 107 + .../classes/Swift/Transport/EsmtpHandler.php | 86 + .../Swift/Transport/EsmtpTransport.php | 446 + .../Swift/Transport/FailoverTransport.php | 103 + .../lib/classes/Swift/Transport/IoBuffer.php | 65 + .../Swift/Transport/LoadBalancedTransport.php | 192 + .../classes/Swift/Transport/NullTransport.php | 98 + .../Swift/Transport/SendmailTransport.php | 158 + .../lib/classes/Swift/Transport/SmtpAgent.php | 36 + .../Swift/Transport/SpoolTransport.php | 120 + .../classes/Swift/Transport/StreamBuffer.php | 319 + .../lib/classes/Swift/TransportException.php | 28 + .../lib/dependency_maps/cache_deps.php | 23 + .../lib/dependency_maps/message_deps.php | 9 + .../lib/dependency_maps/mime_deps.php | 134 + .../lib/dependency_maps/transport_deps.php | 97 + .../swiftmailer/lib/mime_types.php | 1007 + .../swiftmailer/lib/preferences.php | 19 + .../swiftmailer/lib/swift_required.php | 22 + .../lib/swiftmailer_generate_mimes_config.php | 182 + .../vendor/symfony/polyfill-iconv/Iconv.php | 744 + .../vendor/symfony/polyfill-iconv/LICENSE | 19 + .../vendor/symfony/polyfill-iconv/README.md | 14 + .../Resources/charset/from.big5.php | 13719 +++ .../Resources/charset/from.cp037.php | Bin 0 -> 3779 bytes .../Resources/charset/from.cp1006.php | Bin 0 -> 3860 bytes .../Resources/charset/from.cp1026.php | Bin 0 -> 3779 bytes .../Resources/charset/from.cp424.php | Bin 0 -> 3210 bytes .../Resources/charset/from.cp437.php | Bin 0 -> 3841 bytes .../Resources/charset/from.cp500.php | Bin 0 -> 3779 bytes .../Resources/charset/from.cp737.php | Bin 0 -> 3834 bytes .../Resources/charset/from.cp775.php | Bin 0 -> 3815 bytes .../Resources/charset/from.cp850.php | Bin 0 -> 3809 bytes .../Resources/charset/from.cp852.php | Bin 0 -> 3808 bytes .../Resources/charset/from.cp855.php | Bin 0 -> 3809 bytes .../Resources/charset/from.cp856.php | Bin 0 -> 3194 bytes .../Resources/charset/from.cp857.php | Bin 0 -> 3763 bytes .../Resources/charset/from.cp860.php | Bin 0 -> 3840 bytes .../Resources/charset/from.cp861.php | Bin 0 -> 3841 bytes .../Resources/charset/from.cp862.php | Bin 0 -> 3841 bytes .../Resources/charset/from.cp863.php | Bin 0 -> 3841 bytes .../Resources/charset/from.cp864.php | Bin 0 -> 3779 bytes .../Resources/charset/from.cp865.php | Bin 0 -> 3841 bytes .../Resources/charset/from.cp866.php | Bin 0 -> 3831 bytes .../Resources/charset/from.cp869.php | Bin 0 -> 3676 bytes .../Resources/charset/from.cp874.php | Bin 0 -> 3410 bytes .../Resources/charset/from.cp875.php | Bin 0 -> 3776 bytes .../Resources/charset/from.cp932.php | Bin 0 -> 134095 bytes .../Resources/charset/from.cp936.php | Bin 0 -> 372283 bytes .../Resources/charset/from.cp949.php | Bin 0 -> 291504 bytes .../Resources/charset/from.cp950.php | Bin 0 -> 231436 bytes .../Resources/charset/from.iso-8859-1.php | Bin 0 -> 3779 bytes .../Resources/charset/from.iso-8859-10.php | Bin 0 -> 3780 bytes .../Resources/charset/from.iso-8859-11.php | Bin 0 -> 3746 bytes .../Resources/charset/from.iso-8859-13.php | Bin 0 -> 3783 bytes .../Resources/charset/from.iso-8859-14.php | Bin 0 -> 3801 bytes .../Resources/charset/from.iso-8859-15.php | Bin 0 -> 3780 bytes .../Resources/charset/from.iso-8859-16.php | Bin 0 -> 3782 bytes .../Resources/charset/from.iso-8859-2.php | Bin 0 -> 3779 bytes .../Resources/charset/from.iso-8859-3.php | Bin 0 -> 3674 bytes .../Resources/charset/from.iso-8859-4.php | Bin 0 -> 3779 bytes .../Resources/charset/from.iso-8859-5.php | Bin 0 -> 3780 bytes .../Resources/charset/from.iso-8859-6.php | Bin 0 -> 3104 bytes .../Resources/charset/from.iso-8859-7.php | Bin 0 -> 3692 bytes .../Resources/charset/from.iso-8859-8.php | Bin 0 -> 3242 bytes .../Resources/charset/from.iso-8859-9.php | Bin 0 -> 3779 bytes .../Resources/charset/from.koi8-r.php | Bin 0 -> 3835 bytes .../Resources/charset/from.koi8-u.php | Bin 0 -> 3827 bytes .../Resources/charset/from.us-ascii.php | Bin 0 -> 1859 bytes .../Resources/charset/from.windows-1250.php | Bin 0 -> 3721 bytes .../Resources/charset/from.windows-1251.php | Bin 0 -> 3782 bytes .../Resources/charset/from.windows-1252.php | Bin 0 -> 3721 bytes .../Resources/charset/from.windows-1253.php | Bin 0 -> 3542 bytes .../Resources/charset/from.windows-1254.php | Bin 0 -> 3691 bytes .../Resources/charset/from.windows-1255.php | Bin 0 -> 3454 bytes .../Resources/charset/from.windows-1256.php | Bin 0 -> 3800 bytes .../Resources/charset/from.windows-1257.php | Bin 0 -> 3616 bytes .../Resources/charset/from.windows-1258.php | Bin 0 -> 3662 bytes .../Resources/charset/translit.php | 4103 + .../symfony/polyfill-iconv/bootstrap.php | 88 + .../symfony/polyfill-iconv/bootstrap80.php | 80 + .../symfony/polyfill-iconv/composer.json | 38 + .../vendor/symfony/polyfill-intl-idn/Idn.php | 925 + .../vendor/symfony/polyfill-intl-idn/Info.php | 23 + .../vendor/symfony/polyfill-intl-idn/LICENSE | 19 + .../symfony/polyfill-intl-idn/README.md | 12 + .../Resources/unidata/DisallowedRanges.php | 375 + .../Resources/unidata/Regex.php | 24 + .../Resources/unidata/deviation.php | 8 + .../Resources/unidata/disallowed.php | 2638 + .../unidata/disallowed_STD3_mapped.php | 308 + .../unidata/disallowed_STD3_valid.php | 71 + .../Resources/unidata/ignored.php | 273 + .../Resources/unidata/mapped.php | 5778 + .../Resources/unidata/virama.php | 65 + .../symfony/polyfill-intl-idn/bootstrap.php | 145 + .../symfony/polyfill-intl-idn/bootstrap80.php | 128 + .../symfony/polyfill-intl-idn/composer.json | 44 + .../symfony/polyfill-intl-normalizer/LICENSE | 19 + .../polyfill-intl-normalizer/Normalizer.php | 310 + .../polyfill-intl-normalizer/README.md | 14 + .../Resources/stubs/Normalizer.php | 17 + .../unidata/canonicalComposition.php | 945 + .../unidata/canonicalDecomposition.php | 2065 + .../Resources/unidata/combiningClass.php | 876 + .../unidata/compatibilityDecomposition.php | 3695 + .../polyfill-intl-normalizer/bootstrap.php | 23 + .../polyfill-intl-normalizer/bootstrap80.php | 19 + .../polyfill-intl-normalizer/composer.json | 39 + .../vendor/symfony/polyfill-mbstring/LICENSE | 19 + .../symfony/polyfill-mbstring/Mbstring.php | 869 + .../symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/lowerCase.php | 1397 + .../Resources/unidata/titleCaseRegexp.php | 5 + .../Resources/unidata/upperCase.php | 1414 + .../symfony/polyfill-mbstring/bootstrap.php | 147 + .../symfony/polyfill-mbstring/bootstrap80.php | 143 + .../symfony/polyfill-mbstring/composer.json | 38 + .../vendor/symfony/polyfill-php72/LICENSE | 19 + .../vendor/symfony/polyfill-php72/Php72.php | 217 + .../vendor/symfony/polyfill-php72/README.md | 28 + .../symfony/polyfill-php72/bootstrap.php | 57 + .../symfony/polyfill-php72/composer.json | 35 + plugins/error/.gitignore | 9 + plugins/error/CHANGELOG.md | 91 + plugins/error/LICENSE | 21 + plugins/error/README.md | 93 + plugins/error/assets/readme_1.png | Bin 0 -> 41685 bytes plugins/error/blueprints.yaml | 36 + plugins/error/cli/LogCommand.php | 130 + plugins/error/composer.json | 39 + plugins/error/error.php | 117 + plugins/error/error.yaml | 3 + plugins/error/hebe.json | 15 + plugins/error/languages.yaml | 55 + plugins/error/pages/error.md | 14 + plugins/error/templates/error.html.twig | 3 + plugins/error/templates/error.json.twig | 1 + plugins/error/vendor/autoload.php | 7 + plugins/error/vendor/composer/ClassLoader.php | 445 + plugins/error/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../error/vendor/composer/autoload_psr4.php | 10 + .../error/vendor/composer/autoload_real.php | 52 + .../error/vendor/composer/autoload_static.php | 36 + plugins/error/vendor/composer/installed.json | 1 + plugins/feed/CHANGELOG.md | 143 + plugins/feed/LICENSE | 21 + plugins/feed/README.md | 146 + plugins/feed/assets/readme_1.png | Bin 0 -> 298108 bytes plugins/feed/blueprints.yaml | 78 + plugins/feed/blueprints/feed.yaml | 22 + plugins/feed/composer.json | 36 + plugins/feed/composer.lock | 21 + plugins/feed/feed.php | 162 + plugins/feed/feed.yaml | 7 + plugins/feed/templates/feed.atom.twig | 45 + plugins/feed/templates/feed.json.twig | 43 + plugins/feed/templates/feed.rss.twig | 40 + plugins/feed/vendor/autoload.php | 7 + plugins/feed/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 209 + plugins/feed/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../feed/vendor/composer/autoload_psr4.php | 9 + .../feed/vendor/composer/autoload_real.php | 55 + .../feed/vendor/composer/autoload_static.php | 21 + plugins/feed/vendor/composer/installed.json | 5 + plugins/feed/vendor/composer/installed.php | 24 + plugins/flex-objects/.eslintrc | 170 + plugins/flex-objects/.gitignore | 3 + plugins/flex-objects/CHANGELOG.md | 469 + plugins/flex-objects/LICENSE | 21 + plugins/flex-objects/README.md | 289 + .../flex-objects/admin/pages/flex-objects.md | 7 + .../admin/templates/flex-objects.html.twig | 30 + .../admin/templates/flex-objects.json.twig | 1 + .../flex-objects/layouts/404.html.twig | 1 + .../layouts/accounts/partials/top.html.twig | 25 + .../types/default/buttons/add.html.twig | 3 + .../types/default/buttons/back.html.twig | 3 + .../default/buttons/configuration.html.twig | 7 + .../types/default/buttons/delete.html.twig | 3 + .../default/buttons/export-csv.html.twig | 3 + .../types/default/buttons/export.html.twig | 21 + .../types/default/buttons/languages.html.twig | 18 + .../default/buttons/preview-open.html.twig | 5 + .../types/default/buttons/preview.html.twig | 3 + .../types/default/buttons/save.html.twig | 4 + .../types/default/configure.html.twig | 103 + .../flex-objects/types/default/edit.html.twig | 121 + .../flex-objects/types/default/list.html.twig | 98 + .../types/default/list/list.html.twig | 112 + .../types/default/list/list_actions.html.twig | 39 + .../types/default/modals/remove.html.twig | 13 + .../types/default/preview.html.twig | 62 + .../default/titlebar/configure.html.twig | 32 + .../types/default/titlebar/edit.html.twig | 46 + .../types/default/titlebar/list.html.twig | 48 + .../types/default/titlebar/preview.html.twig | 30 + .../types/default/titlebar/types.html.twig | 22 + .../types/default/types.html.twig | 46 + .../types/pages/buttons/add.html.twig | 20 + .../types/pages/buttons/back.html.twig | 3 + .../types/pages/buttons/copy.html.twig | 4 + .../types/pages/buttons/delete.html.twig | 3 + .../types/pages/buttons/move.html.twig | 6 + .../types/pages/buttons/nav-child.html.twig | 9 + .../types/pages/buttons/nav-next.html.twig | 9 + .../types/pages/buttons/nav-parent.html.twig | 9 + .../types/pages/buttons/nav-prev.html.twig | 9 + .../types/pages/buttons/preview.html.twig | 5 + .../types/pages/buttons/save.html.twig | 23 + .../flex-objects/types/pages/edit.html.twig | 236 + .../flex-objects/types/pages/list.html.twig | 29 + .../types/pages/list/columns.html.twig | 155 + .../types/pages/list/list.html.twig | 41 + .../types/pages/preview.html.twig | 16 + .../types/user-accounts/configure.html.twig | 9 + .../types/user-accounts/edit.html.twig | 9 + .../types/user-accounts/list.html.twig | 7 + .../types/user-groups/configure.html.twig | 9 + .../types/user-groups/list.html.twig | 7 + .../flex-objects/flex-objects.html.twig | 69 + .../save-redirect/save-redirect.html.twig | 37 + plugins/flex-objects/app/columns/finder.js | 425 + plugins/flex-objects/app/columns/index.js | 102 + plugins/flex-objects/app/filters/index.js | 46 + plugins/flex-objects/app/filters/panel.js | 15 + plugins/flex-objects/app/list/App.vue | 27 + .../app/list/VuetableCssConfig.js | 29 + .../app/list/components/ContentLoader.vue | 48 + .../app/list/components/FilterBar.vue | 66 + .../app/list/components/Table.vue | 94 + plugins/flex-objects/app/list/index.js | 19 + plugins/flex-objects/app/main.js | 3 + plugins/flex-objects/app/utils/finder.js | 393 + plugins/flex-objects/app/utils/get-filters.js | 34 + .../flex-objects/app/utils/indeterminate.js | 44 + .../assets/flex-objects-directory.png | Bin 0 -> 137785 bytes .../flex-objects/assets/flex-objects-edit.png | Bin 0 -> 159728 bytes .../flex-objects/assets/flex-objects-list.png | Bin 0 -> 239360 bytes .../assets/flex-objects-options.png | Bin 0 -> 256165 bytes .../flex-objects/assets/flex-objects-site.png | Bin 0 -> 253928 bytes plugins/flex-objects/blueprints.yaml | 55 + .../flex-objects/blueprints/flex-objects.yaml | 16 + .../blueprints/flex-objects/contacts.yaml | 158 + .../blueprints/flex-objects/pages.yaml | 22 + .../flex-objects/user-accounts.yaml | 7 + .../blueprints/flex-objects/user-groups.yaml | 7 + .../blueprints/pages/flex-objects.yaml | 21 + .../classes/Admin/AdminController.php | 1911 + .../Controllers/AbstractController.php | 359 + .../classes/Controllers/MediaController.php | 504 + .../classes/Controllers/ObjectController.php | 501 + plugins/flex-objects/classes/Flex.php | 444 + .../flex-objects/classes/FlexFormFactory.php | 80 + plugins/flex-objects/classes/FlexRouter.php | 64 + .../flex-objects/classes/Table/DataTable.php | 410 + .../cli/FlexConvertDataCommand.php | 140 + plugins/flex-objects/composer.json | 32 + plugins/flex-objects/composer.lock | 25 + plugins/flex-objects/css/admin.css | 97 + plugins/flex-objects/css/admin.css.map | 11 + plugins/flex-objects/css/admin.min.css | 1 + plugins/flex-objects/css/site.css | 27 + plugins/flex-objects/css/site.css.map | 11 + plugins/flex-objects/css/site.min.css | 1 + .../data/flex-objects/contacts.json | 6262 ++ plugins/flex-objects/flex-objects.php | 785 + plugins/flex-objects/flex-objects.yaml | 14 + plugins/flex-objects/js/flex-objects.js | 905 + plugins/flex-objects/js/list.min.js | 2 + plugins/flex-objects/languages/de.yaml | 60 + plugins/flex-objects/languages/en.yaml | 72 + plugins/flex-objects/languages/ru.yaml | 12 + plugins/flex-objects/package.json | 51 + plugins/flex-objects/permissions.yaml | 45 + plugins/flex-objects/scss/_preset.scss | 69 + plugins/flex-objects/scss/admin.scss | 3 + plugins/flex-objects/scss/plugin/_admin.scss | 215 + plugins/flex-objects/scss/plugin/_site.scss | 68 + plugins/flex-objects/scss/site.scss | 2 + .../templates/flex-edit.html.twig | 42 + .../templates/flex-objects.html.twig | 21 + .../directories/default.html.twig | 30 + .../templates/flex-objects/page.html.twig | 37 + .../flex-objects/views/404.html.twig | 1 + .../flex-objects/views/directories.html.twig | 12 + .../flex-objects/views/directory.html.twig | 24 + .../flex-objects/views/object.html.twig | 23 + .../contacts/collection/default.html.twig | 26 + .../flex/contacts/object/default.html.twig | 15 + .../contacts/object/list-default.html.twig | 15 + .../collection/default.html.twig | 25 + .../user-accounts/object/default.html.twig | 17 + .../object/list-default.html.twig | 27 + .../user-groups/collection/default.html.twig | 25 + .../flex/user-groups/object/default.html.twig | 14 + .../user-groups/object/list-default.html.twig | 16 + .../fields/filepicker/filepicker.html.twig | 17 + .../forms/fields/list/list.html.twig | 177 + .../fields/pagemedia/pagemedia.html.twig | 89 + .../forms/fields/pagemedia/template.html.twig | 33 + plugins/flex-objects/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 219 + plugins/flex-objects/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 57 + .../vendor/composer/autoload_static.php | 37 + .../vendor/composer/installed.json | 5 + .../vendor/composer/installed.php | 24 + .../vendor/composer/platform_check.php | 26 + plugins/flex-objects/watch.sh | 27 + plugins/flex-objects/webpack.conf.js | 75 + plugins/flex-objects/yarn.lock | 3271 + plugins/form/.eslintrc | 165 + plugins/form/.gitignore | 5 + plugins/form/CHANGELOG.md | 1158 + plugins/form/LICENSE | 21 + plugins/form/README.md | 39 + plugins/form/app/fields/array.js | 200 + plugins/form/app/fields/file.js | 340 + plugins/form/app/fields/form.js | 94 + plugins/form/app/fields/index.js | 7 + plugins/form/app/fields/media.js | 174 + plugins/form/app/fields/tabs.js | 14 + plugins/form/app/main.js | 4 + plugins/form/app/utils/keep-alive.js | 17 + plugins/form/assets/dropzone.min.css | 1 + plugins/form/assets/form-styles.css | 80 + plugins/form/assets/form-styles.min.css | 1 + plugins/form/assets/form.min.js | 41 + plugins/form/assets/form.vendor.js | 24 + plugins/form/assets/object.assign.polyfill.js | 29 + plugins/form/assets/signature_pad.js | 617 + plugins/form/blueprints.yaml | 198 + plugins/form/classes/Form.php | 1422 + plugins/form/classes/FormFactory.php | 38 + plugins/form/classes/Forms.php | 129 + plugins/form/classes/TwigExtension.php | 155 + plugins/form/composer.json | 40 + plugins/form/composer.lock | 77 + plugins/form/form.php | 1167 + plugins/form/form.yaml | 20 + plugins/form/gulpfile.js | 84 + plugins/form/hebe.json | 15 + plugins/form/languages.yaml | 897 + plugins/form/package.json | 45 + plugins/form/scss/form-styles.scss | 289 + .../form/templates/form-messages.html.twig | 2 + .../form/templates/form-messages.json.twig | 2 + plugins/form/templates/form.html.twig | 8 + plugins/form/templates/form.json.twig | 1 + plugins/form/templates/formdata.html.twig | 20 + plugins/form/templates/forms/ajax.json.twig | 5 + plugins/form/templates/forms/data.html.twig | 1 + plugins/form/templates/forms/data.txt.twig | 1 + .../templates/forms/default/data.html.twig | 77 + .../templates/forms/default/data.txt.twig | 21 + .../templates/forms/default/field.html.twig | 158 + .../templates/forms/default/fields.html.twig | 17 + .../templates/forms/default/form.html.twig | 206 + .../forms/default/toggleable.html.twig | 9 + .../forms/dropzone/template.html.twig | 39 + plugins/form/templates/forms/field.html.twig | 9 + .../forms/fields/array/array.html.twig | 99 + .../forms/fields/avatar/avatar.html.twig | 10 + .../forms/fields/captcha/captcha.html.twig | 100 + .../forms/fields/checkbox/checkbox.html.twig | 46 + .../fields/checkboxes/checkboxes.html.twig | 42 + .../forms/fields/color/color.html.twig | 6 + .../forms/fields/column/column.html.twig | 8 + .../forms/fields/columns/columns.html.twig | 7 + .../fields/conditional/conditional.html.twig | 19 + .../forms/fields/date/date.html.twig | 8 + .../forms/fields/date/edit_list.html.twig | 1 + .../forms/fields/datetime/datetime.html.twig | 2 + .../forms/fields/datetime/edit_list.html.twig | 1 + .../forms/fields/display/display.html.twig | 21 + .../forms/fields/email/email.html.twig | 10 + .../forms/fields/fieldset/fieldset.html.twig | 12 + .../forms/fields/file/file.html.twig | 124 + .../forms/fields/formname/formname.html.twig | 5 + .../forms/fields/formtask/formtask.html.twig | 8 + .../forms/fields/hidden/hidden.html.twig | 15 + .../forms/fields/honeypot/honeypot.html.twig | 13 + .../forms/fields/ignore/ignore.html.twig | 0 .../templates/forms/fields/key/key.html.twig | 28 + .../forms/fields/month/month.html.twig | 6 + .../forms/fields/nonce/nonce.html.twig | 1 + .../forms/fields/number/number.html.twig | 9 + .../forms/fields/password/password.html.twig | 8 + .../forms/fields/radio/radio.html.twig | 24 + .../forms/fields/range/range.html.twig | 9 + .../forms/fields/section/section.html.twig | 21 + .../forms/fields/select/select.html.twig | 71 + .../select_optgroup/select_optgroup.html.twig | 2 + .../fields/signature/signature.html.twig | 105 + .../forms/fields/spacer/spacer.html.twig | 19 + .../forms/fields/switch/switch.html.twig | 1 + .../templates/forms/fields/tab/tab.html.twig | 8 + .../forms/fields/tabs/tabs.html.twig | 60 + .../templates/forms/fields/tel/tel.html.twig | 9 + .../forms/fields/text/edit_list.html.twig | 7 + .../forms/fields/text/text.html.twig | 39 + .../forms/fields/textarea/textarea.html.twig | 51 + .../forms/fields/time/edit_list.html.twig | 1 + .../forms/fields/time/time.html.twig | 6 + .../forms/fields/toggle/edit_list.html.twig | 5 + .../forms/fields/toggle/toggle.html.twig | 52 + .../forms/fields/uniqueid/uniqueid.html.twig | 5 + .../forms/fields/url/edit_list.html.twig | 1 + .../templates/forms/fields/url/url.html.twig | 9 + .../forms/fields/value/value.html.twig | 18 + .../forms/fields/week/week.html.twig | 6 + plugins/form/templates/forms/form.html.twig | 29 + .../templates/forms/layouts/button.html.twig | 4 + .../layouts/button/default-button.html.twig | 12 + .../forms/layouts/field-variables.html.twig | 1 + .../templates/forms/layouts/field.html.twig | 4 + .../layouts/field/default-field.html.twig | 53 + .../templates/forms/layouts/form.html.twig | 4 + .../forms/layouts/form/default-form.html.twig | 8 + plugins/form/templates/modular/form.html.twig | 4 + .../partials/form-messages.html.twig | 6 + .../partials/form-messages.json.twig | 3 + plugins/form/vendor/autoload.php | 7 + plugins/form/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 228 + plugins/form/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../form/vendor/composer/autoload_psr4.php | 11 + .../form/vendor/composer/autoload_real.php | 57 + .../form/vendor/composer/autoload_static.php | 45 + plugins/form/vendor/composer/installed.json | 61 + plugins/form/vendor/composer/installed.php | 33 + .../form/vendor/composer/platform_check.php | 26 + .../.github/ISSUE_TEMPLATE/bug_report.md | 28 + .../form/vendor/google/recaptcha/.gitignore | 7 + .../form/vendor/google/recaptcha/.travis.yml | 33 + .../vendor/google/recaptcha/ARCHITECTURE.md | 64 + .../vendor/google/recaptcha/CONTRIBUTING.md | 49 + plugins/form/vendor/google/recaptcha/LICENSE | 29 + .../form/vendor/google/recaptcha/README.md | 140 + plugins/form/vendor/google/recaptcha/app.yaml | 8 + .../vendor/google/recaptcha/composer.json | 39 + .../recaptcha/examples/appengine-https.php | 42 + .../google/recaptcha/examples/config.php.dist | 46 + .../google/recaptcha/examples/examples.css | 37 + .../examples/google0afd8760fd68f119.html | 1 + .../google/recaptcha/examples/index.php | 79 + .../recaptcha-content-security-policy.php | 152 + .../recaptcha-v2-checkbox-explicit.php | 148 + .../examples/recaptcha-v2-checkbox.php | 139 + .../examples/recaptcha-v2-invisible.php | 141 + .../examples/recaptcha-v3-request-scores.php | 120 + .../examples/recaptcha-v3-verify.php | 59 + .../google/recaptcha/examples/robots.txt | 2 + .../vendor/google/recaptcha/phpunit.xml.dist | 20 + .../recaptcha/src/ReCaptcha/ReCaptcha.php | 269 + .../recaptcha/src/ReCaptcha/RequestMethod.php | 50 + .../src/ReCaptcha/RequestMethod/Curl.php | 82 + .../src/ReCaptcha/RequestMethod/CurlPost.php | 104 + .../src/ReCaptcha/RequestMethod/Post.php | 88 + .../src/ReCaptcha/RequestMethod/Socket.php | 112 + .../ReCaptcha/RequestMethod/SocketPost.php | 108 + .../src/ReCaptcha/RequestParameters.php | 111 + .../recaptcha/src/ReCaptcha/Response.php | 218 + .../vendor/google/recaptcha/src/autoload.php | 69 + .../tests/ReCaptcha/ReCaptchaTest.php | 198 + .../ReCaptcha/RequestMethod/CurlPostTest.php | 123 + .../ReCaptcha/RequestMethod/PostTest.php | 149 + .../RequestMethod/SocketPostTest.php | 136 + .../tests/ReCaptcha/RequestParametersTest.php | 70 + .../tests/ReCaptcha/ResponseTest.php | 173 + plugins/form/webpack.conf.js | 65 + plugins/form/yarn.lock | 7407 ++ plugins/git-sync/.eslintrc | 167 + plugins/git-sync/.gitignore | 4 + plugins/git-sync/CHANGELOG.md | 200 + plugins/git-sync/LICENSE | 201 + plugins/git-sync/README.md | 90 + plugins/git-sync/app/main.js | 1 + plugins/git-sync/app/wizard/index.js | 379 + plugins/git-sync/blueprints.yaml | 289 + plugins/git-sync/classes/AdminController.php | 177 + plugins/git-sync/classes/GitSync.php | 536 + plugins/git-sync/classes/Helper.php | 158 + plugins/git-sync/cli/InitCommand.php | 45 + plugins/git-sync/cli/PasswdCommand.php | 91 + plugins/git-sync/cli/StatusCommand.php | 149 + plugins/git-sync/cli/SyncCommand.php | 51 + plugins/git-sync/composer.json | 28 + plugins/git-sync/composer.lock | 139 + .../git-sync/css-compiled/git-sync-icon.css | 22 + plugins/git-sync/css-compiled/git-sync.css | 137 + plugins/git-sync/fonts/gitsync.svg | 12 + plugins/git-sync/fonts/gitsync.ttf | Bin 0 -> 1832 bytes plugins/git-sync/fonts/gitsync.woff | Bin 0 -> 1908 bytes plugins/git-sync/git-sync.php | 490 + plugins/git-sync/git-sync.yaml | 1 + plugins/git-sync/gosass.sh | 2 + plugins/git-sync/images/gitsync-logo.png | Bin 0 -> 6495 bytes plugins/git-sync/images/repos/bitbucket.svg | 79 + plugins/git-sync/images/repos/github.svg | 15 + plugins/git-sync/images/repos/gitlab.svg | 77 + plugins/git-sync/images/repos/gitlogo.svg | 65 + plugins/git-sync/js/app.js | 196 + plugins/git-sync/js/vendor.js | 61 + plugins/git-sync/package.json | 44 + .../git-sync/scss/configuration/_colors.scss | 8 + plugins/git-sync/scss/git-sync.scss | 7 + plugins/git-sync/scss/plugin/_wizard.scss | 191 + .../bourbon/_bourbon-deprecated-upcoming.scss | 411 + .../scss/vendor/bourbon/_bourbon.scss | 87 + .../vendor/bourbon/addons/_border-color.scss | 26 + .../vendor/bourbon/addons/_border-radius.scss | 48 + .../vendor/bourbon/addons/_border-style.scss | 25 + .../vendor/bourbon/addons/_border-width.scss | 25 + .../scss/vendor/bourbon/addons/_buttons.scss | 64 + .../scss/vendor/bourbon/addons/_clearfix.scss | 25 + .../scss/vendor/bourbon/addons/_ellipsis.scss | 30 + .../vendor/bourbon/addons/_font-stacks.scss | 31 + .../vendor/bourbon/addons/_hide-text.scss | 27 + .../scss/vendor/bourbon/addons/_margin.scss | 26 + .../scss/vendor/bourbon/addons/_padding.scss | 26 + .../scss/vendor/bourbon/addons/_position.scss | 48 + .../scss/vendor/bourbon/addons/_prefixer.scss | 66 + .../vendor/bourbon/addons/_retina-image.scss | 25 + .../scss/vendor/bourbon/addons/_size.scss | 51 + .../vendor/bourbon/addons/_text-inputs.scss | 113 + .../bourbon/addons/_timing-functions.scss | 34 + .../scss/vendor/bourbon/addons/_triangle.scss | 63 + .../vendor/bourbon/addons/_word-wrap.scss | 29 + .../scss/vendor/bourbon/css3/_animation.scss | 43 + .../scss/vendor/bourbon/css3/_appearance.scss | 3 + .../bourbon/css3/_backface-visibility.scss | 3 + .../bourbon/css3/_background-image.scss | 42 + .../scss/vendor/bourbon/css3/_background.scss | 55 + .../vendor/bourbon/css3/_border-image.scss | 59 + .../scss/vendor/bourbon/css3/_calc.scss | 4 + .../scss/vendor/bourbon/css3/_columns.scss | 47 + .../scss/vendor/bourbon/css3/_filter.scss | 4 + .../scss/vendor/bourbon/css3/_flex-box.scss | 287 + .../scss/vendor/bourbon/css3/_font-face.scss | 24 + .../bourbon/css3/_font-feature-settings.scss | 4 + .../bourbon/css3/_hidpi-media-query.scss | 10 + .../scss/vendor/bourbon/css3/_hyphens.scss | 4 + .../vendor/bourbon/css3/_image-rendering.scss | 14 + .../scss/vendor/bourbon/css3/_keyframes.scss | 36 + .../vendor/bourbon/css3/_linear-gradient.scss | 38 + .../vendor/bourbon/css3/_perspective.scss | 8 + .../vendor/bourbon/css3/_placeholder.scss | 8 + .../vendor/bourbon/css3/_radial-gradient.scss | 39 + .../scss/vendor/bourbon/css3/_selection.scss | 42 + .../vendor/bourbon/css3/_text-decoration.scss | 19 + .../scss/vendor/bourbon/css3/_transform.scss | 15 + .../scss/vendor/bourbon/css3/_transition.scss | 71 + .../vendor/bourbon/css3/_user-select.scss | 3 + .../bourbon/functions/_assign-inputs.scss | 11 + .../bourbon/functions/_contains-falsy.scss | 20 + .../vendor/bourbon/functions/_contains.scss | 26 + .../vendor/bourbon/functions/_is-length.scss | 11 + .../vendor/bourbon/functions/_is-light.scss | 21 + .../vendor/bourbon/functions/_is-number.scss | 11 + .../vendor/bourbon/functions/_is-size.scss | 13 + .../bourbon/functions/_modular-scale.scss | 69 + .../vendor/bourbon/functions/_px-to-em.scss | 13 + .../vendor/bourbon/functions/_px-to-rem.scss | 15 + .../scss/vendor/bourbon/functions/_shade.scss | 24 + .../bourbon/functions/_strip-units.scss | 17 + .../scss/vendor/bourbon/functions/_tint.scss | 24 + .../functions/_transition-property-name.scss | 22 + .../vendor/bourbon/functions/_unpack.scss | 27 + .../bourbon/helpers/_convert-units.scss | 21 + .../bourbon/helpers/_directional-values.scss | 96 + .../helpers/_font-source-declaration.scss | 43 + .../helpers/_gradient-positions-parser.scss | 13 + .../bourbon/helpers/_linear-angle-parser.scss | 25 + .../helpers/_linear-gradient-parser.scss | 41 + .../helpers/_linear-positions-parser.scss | 61 + .../helpers/_linear-side-corner-parser.scss | 31 + .../bourbon/helpers/_radial-arg-parser.scss | 69 + .../helpers/_radial-gradient-parser.scss | 50 + .../helpers/_radial-positions-parser.scss | 18 + .../bourbon/helpers/_render-gradients.scss | 26 + .../bourbon/helpers/_shape-size-stripper.scss | 10 + .../vendor/bourbon/helpers/_str-to-num.scss | 50 + .../bourbon/settings/_asset-pipeline.scss | 7 + .../vendor/bourbon/settings/_prefixer.scss | 9 + .../vendor/bourbon/settings/_px-to-em.scss | 1 + .../enc-password/enc-password.html.twig | 12 + .../fields/git-wizard/git-wizard.html.twig | 17 + .../templates/partials/modal-reset.html.twig | 17 + .../templates/partials/modal-wizard.html.twig | 460 + plugins/git-sync/vendor/autoload.php | 7 + .../git-sync/vendor/bin/generate-defuse-key | 1 + .../git-sync/vendor/composer/ClassLoader.php | 477 + .../vendor/composer/InstalledVersions.php | 309 + plugins/git-sync/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 14 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 12 + .../vendor/composer/autoload_real.php | 57 + .../vendor/composer/autoload_static.php | 53 + .../git-sync/vendor/composer/installed.json | 124 + .../git-sync/vendor/composer/installed.php | 49 + .../vendor/composer/platform_check.php | 26 + .../vendor/defuse/php-encryption/LICENSE | 21 + .../vendor/defuse/php-encryption/README.md | 121 + .../php-encryption/bin/generate-defuse-key | 14 + .../defuse/php-encryption/composer.json | 34 + .../defuse/php-encryption/dist/Makefile | 39 + .../defuse/php-encryption/dist/box.json | 25 + .../php-encryption/dist/signingkey-new.asc | 53 + .../dist/signingkey-new.asc.sig | Bin 0 -> 566 bytes .../defuse/php-encryption/dist/signingkey.asc | 52 + .../php-encryption/docs/CryptoDetails.md | 64 + .../vendor/defuse/php-encryption/docs/FAQ.md | 51 + .../docs/InstallingAndVerifying.md | 53 + .../docs/InternalDeveloperDocs.md | 166 + .../defuse/php-encryption/docs/Tutorial.md | 314 + .../php-encryption/docs/UpgradingFromV1.2.md | 51 + .../php-encryption/docs/classes/Crypto.md | 280 + .../php-encryption/docs/classes/File.md | 486 + .../defuse/php-encryption/docs/classes/Key.md | 117 + .../docs/classes/KeyProtectedByPassword.md | 259 + .../vendor/defuse/php-encryption/src/Core.php | 457 + .../defuse/php-encryption/src/Crypto.php | 445 + .../defuse/php-encryption/src/DerivedKeys.php | 50 + .../defuse/php-encryption/src/Encoding.php | 269 + .../src/Exception/BadFormatException.php | 7 + .../src/Exception/CryptoException.php | 7 + .../EnvironmentIsBrokenException.php | 7 + .../src/Exception/IOException.php | 7 + .../WrongKeyOrModifiedCiphertextException.php | 7 + .../vendor/defuse/php-encryption/src/File.php | 778 + .../vendor/defuse/php-encryption/src/Key.php | 94 + .../php-encryption/src/KeyOrPassword.php | 149 + .../src/KeyProtectedByPassword.php | 145 + .../php-encryption/src/RuntimeTests.php | 228 + .../git-sync/vendor/sebastian/git/.gitignore | 5 + plugins/git-sync/vendor/sebastian/git/LICENSE | 33 + .../git-sync/vendor/sebastian/git/README.md | 14 + .../git-sync/vendor/sebastian/git/build.xml | 30 + .../vendor/sebastian/git/composer.json | 26 + .../sebastian/git/src/Exception/Exception.php | 15 + .../git/src/Exception/RuntimeException.php | 15 + .../git-sync/vendor/sebastian/git/src/Git.php | 145 + plugins/git-sync/watch.sh | 27 + plugins/git-sync/webpack.conf.js | 70 + plugins/git-sync/wizard.png | Bin 0 -> 135495 bytes plugins/git-sync/yarn.lock | 3623 + plugins/langswitcher/CHANGELOG.md | 78 + plugins/langswitcher/LICENSE | 21 + plugins/langswitcher/README.md | 125 + plugins/langswitcher/assets/readme_1.png | Bin 0 -> 38637 bytes plugins/langswitcher/blueprints.yaml | 61 + plugins/langswitcher/composer.json | 29 + plugins/langswitcher/composer.lock | 24 + plugins/langswitcher/css/langswitcher.css | 22 + plugins/langswitcher/langswitcher.php | 113 + plugins/langswitcher/langswitcher.yaml | 4 + plugins/langswitcher/languages.yaml | 33 + .../partials/langswitcher-long.html.twig | 1 + .../partials/langswitcher-short.html.twig | 1 + .../partials/langswitcher.hreflang.html.twig | 9 + .../templates/partials/langswitcher.html.twig | 31 + plugins/langswitcher/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 + plugins/langswitcher/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 9 + .../vendor/composer/autoload_real.php | 52 + .../vendor/composer/autoload_static.php | 20 + .../vendor/composer/installed.json | 1 + plugins/login/.gitignore | 2 + plugins/login/CHANGELOG.md | 834 + plugins/login/LICENSE | 21 + plugins/login/README.md | 556 + plugins/login/blueprints.yaml | 462 + plugins/login/classes/Controller.php | 758 + .../login/classes/Events/UserLoginEvent.php | 397 + .../login/classes/Invitations/Invitation.php | 59 + .../login/classes/Invitations/Invitations.php | 165 + plugins/login/classes/Login.php | 925 + plugins/login/classes/LoginCache.php | 105 + plugins/login/classes/RateLimiter.php | 110 + .../login/classes/RememberMe/RememberMe.php | 43 + .../login/classes/RememberMe/TokenStorage.php | 172 + .../classes/TwoFactorAuth/BaconQrProvider.php | 32 + .../classes/TwoFactorAuth/TwoFactorAuth.php | 76 + plugins/login/cli/ChangePasswordCommand.php | 177 + plugins/login/cli/ChangeUserStateCommand.php | 157 + plugins/login/cli/LookupUserCommand.php | 94 + plugins/login/cli/NewUserCommand.php | 324 + plugins/login/composer.json | 49 + plugins/login/composer.lock | 247 + plugins/login/css/login.css | 86 + plugins/login/hebe.json | 15 + plugins/login/js/2fa.js | 34 + plugins/login/languages/de.yaml | 139 + plugins/login/languages/en.yaml | 161 + plugins/login/languages/es.yaml | 126 + plugins/login/languages/fr.yaml | 97 + plugins/login/languages/hr.yaml | 54 + plugins/login/languages/hu.yaml | 35 + plugins/login/languages/lt.yaml | 154 + plugins/login/languages/no.yaml | 73 + plugins/login/languages/pt-BR.yaml | 136 + plugins/login/languages/ro.yaml | 97 + plugins/login/languages/ru.yaml | 145 + plugins/login/languages/uk.yaml | 145 + plugins/login/languages/zh.yaml | 136 + plugins/login/login.php | 1245 + plugins/login/login.yaml | 63 + plugins/login/pages/forgot.md | 22 + plugins/login/pages/login.md | 42 + plugins/login/pages/profile.md | 81 + plugins/login/pages/register.md | 60 + plugins/login/pages/reset.md | 35 + plugins/login/pages/unauthorized.md | 7 + plugins/login/templates/forgot.html.twig | 6 + .../fields/2fa_secret/2fa_secret.html.twig | 31 + plugins/login/templates/login.html.twig | 6 + plugins/login/templates/login.json.twig | 5 + .../templates/partials/forgot-form.html.twig | 29 + .../templates/partials/login-form.html.twig | 74 + .../templates/partials/login-status.html.twig | 5 + .../templates/partials/login-twofa.html.twig | 32 + .../templates/partials/reset-form.html.twig | 30 + plugins/login/templates/profile.html.twig | 9 + plugins/login/templates/profile.json.twig | 1 + plugins/login/templates/register.html.twig | 1 + plugins/login/templates/reset.html.twig | 8 + .../login/templates/unauthorized.html.twig | 1 + plugins/login/vendor/autoload.php | 7 + .../vendor/bacon/bacon-qr-code/.gitignore | 9 + .../vendor/bacon/bacon-qr-code/.travis.yml | 14 + .../vendor/bacon/bacon-qr-code/CHANGELOG.md | 37 + .../login/vendor/bacon/bacon-qr-code/LICENSE | 22 + .../vendor/bacon/bacon-qr-code/Module.php | 37 + .../vendor/bacon/bacon-qr-code/README.md | 24 + .../bacon/bacon-qr-code/autoload_classmap.php | 43 + .../bacon/bacon-qr-code/autoload_function.php | 12 + .../bacon/bacon-qr-code/autoload_register.php | 2 + .../vendor/bacon/bacon-qr-code/composer.json | 29 + .../src/BaconQrCode/Common/AbstractEnum.php | 115 + .../src/BaconQrCode/Common/BitArray.php | 435 + .../src/BaconQrCode/Common/BitMatrix.php | 350 + .../src/BaconQrCode/Common/BitUtils.php | 51 + .../BaconQrCode/Common/CharacterSetEci.php | 134 + .../src/BaconQrCode/Common/EcBlock.php | 65 + .../src/BaconQrCode/Common/EcBlocks.php | 101 + .../Common/ErrorCorrectionLevel.php | 62 + .../BaconQrCode/Common/FormatInformation.php | 236 + .../src/BaconQrCode/Common/Mode.php | 70 + .../BaconQrCode/Common/ReedSolomonCodec.php | 476 + .../src/BaconQrCode/Common/Version.php | 687 + .../src/BaconQrCode/Encoder/BlockPair.php | 64 + .../src/BaconQrCode/Encoder/ByteMatrix.php | 158 + .../src/BaconQrCode/Encoder/Encoder.php | 687 + .../src/BaconQrCode/Encoder/MaskUtil.php | 291 + .../src/BaconQrCode/Encoder/MatrixUtil.php | 580 + .../src/BaconQrCode/Encoder/QrCode.php | 201 + .../Exception/ExceptionInterface.php | 14 + .../Exception/InvalidArgumentException.php | 14 + .../Exception/OutOfBoundsException.php | 14 + .../Exception/RuntimeException.php | 14 + .../Exception/UnexpectedValueException.php | 14 + .../BaconQrCode/Exception/WriterException.php | 14 + .../src/BaconQrCode/Renderer/Color/Cmyk.php | 160 + .../Renderer/Color/ColorInterface.php | 37 + .../src/BaconQrCode/Renderer/Color/Gray.php | 84 + .../src/BaconQrCode/Renderer/Color/Rgb.php | 148 + .../Renderer/Image/AbstractRenderer.php | 338 + .../Image/Decorator/DecoratorInterface.php | 63 + .../Image/Decorator/FinderPattern.php | 210 + .../src/BaconQrCode/Renderer/Image/Eps.php | 152 + .../src/BaconQrCode/Renderer/Image/Png.php | 115 + .../Renderer/Image/RendererInterface.php | 61 + .../src/BaconQrCode/Renderer/Image/Svg.php | 146 + .../Renderer/RendererInterface.php | 26 + .../src/BaconQrCode/Renderer/Text/Html.php | 91 + .../src/BaconQrCode/Renderer/Text/Plain.php | 150 + .../bacon-qr-code/src/BaconQrCode/Writer.php | 105 + .../bacon-qr-code/src/Common/BitArray.php | 372 + .../bacon-qr-code/src/Common/BitMatrix.php | 313 + .../bacon-qr-code/src/Common/BitUtils.php | 41 + .../src/Common/CharacterSetEci.php | 180 + .../bacon-qr-code/src/Common/EcBlock.php | 49 + .../bacon-qr-code/src/Common/EcBlocks.php | 74 + .../src/Common/ErrorCorrectionLevel.php | 63 + .../src/Common/FormatInformation.php | 203 + .../bacon/bacon-qr-code/src/Common/Mode.php | 76 + .../src/Common/ReedSolomonCodec.php | 468 + .../bacon-qr-code/src/Common/Version.php | 596 + .../bacon-qr-code/src/Encoder/BlockPair.php | 58 + .../bacon-qr-code/src/Encoder/ByteMatrix.php | 150 + .../bacon-qr-code/src/Encoder/Encoder.php | 652 + .../bacon-qr-code/src/Encoder/MaskUtil.php | 271 + .../bacon-qr-code/src/Encoder/MatrixUtil.php | 513 + .../bacon-qr-code/src/Encoder/QrCode.php | 141 + .../src/Exception/ExceptionInterface.php | 10 + .../Exception/InvalidArgumentException.php | 8 + .../src/Exception/OutOfBoundsException.php | 8 + .../src/Exception/RuntimeException.php | 8 + .../Exception/UnexpectedValueException.php | 8 + .../src/Exception/WriterException.php | 8 + .../src/Renderer/Color/Alpha.php | 57 + .../bacon-qr-code/src/Renderer/Color/Cmyk.php | 103 + .../src/Renderer/Color/ColorInterface.php | 22 + .../bacon-qr-code/src/Renderer/Color/Gray.php | 46 + .../bacon-qr-code/src/Renderer/Color/Rgb.php | 88 + .../src/Renderer/Eye/CompositeEye.php | 38 + .../src/Renderer/Eye/EyeInterface.php | 26 + .../src/Renderer/Eye/ModuleEye.php | 54 + .../src/Renderer/Eye/SimpleCircleEye.php | 54 + .../src/Renderer/Eye/SquareEye.php | 53 + .../src/Renderer/Image/EpsImageBackEnd.php | 376 + .../Renderer/Image/ImageBackEndInterface.php | 87 + .../Renderer/Image/ImagickImageBackEnd.php | 339 + .../src/Renderer/Image/SvgImageBackEnd.php | 369 + .../Renderer/Image/TransformationMatrix.php | 67 + .../src/Renderer/ImageRenderer.php | 152 + .../src/Renderer/Module/DotsModule.php | 63 + .../src/Renderer/Module/EdgeIterator/Edge.php | 100 + .../Module/EdgeIterator/EdgeIterator.php | 169 + .../src/Renderer/Module/ModuleInterface.php | 18 + .../src/Renderer/Module/RoundnessModule.php | 129 + .../src/Renderer/Module/SquareModule.php | 47 + .../bacon-qr-code/src/Renderer/Path/Close.php | 29 + .../bacon-qr-code/src/Renderer/Path/Curve.php | 92 + .../src/Renderer/Path/EllipticArc.php | 278 + .../bacon-qr-code/src/Renderer/Path/Line.php | 41 + .../bacon-qr-code/src/Renderer/Path/Move.php | 41 + .../src/Renderer/Path/OperationInterface.php | 12 + .../bacon-qr-code/src/Renderer/Path/Path.php | 106 + .../src/Renderer/PlainTextRenderer.php | 86 + .../src/Renderer/RendererInterface.php | 11 + .../src/Renderer/RendererStyle/EyeFill.php | 74 + .../src/Renderer/RendererStyle/Fill.php | 168 + .../src/Renderer/RendererStyle/Gradient.php | 46 + .../Renderer/RendererStyle/GradientType.php | 22 + .../Renderer/RendererStyle/RendererStyle.php | 90 + .../vendor/bacon/bacon-qr-code/src/Writer.php | 68 + .../tests/BaconQrCode/Common/BitArrayTest.php | 201 + .../BaconQrCode/Common/BitMatrixTest.php | 119 + .../tests/BaconQrCode/Common/BitUtilsTest.php | 30 + .../Common/ErrorCorrectionLevelTest.php | 40 + .../Common/FormatInformationTest.php | 104 + .../tests/BaconQrCode/Common/ModeTest.php | 42 + .../Common/ReedSolomonCodecTest.php | 111 + .../tests/BaconQrCode/Common/VersionTest.php | 88 + .../tests/BaconQrCode/Encoder/EncoderTest.php | 468 + .../BaconQrCode/Encoder/MaskUtilTest.php | 281 + .../BaconQrCode/Encoder/MatrixUtilTest.php | 336 + .../BaconQrCode/Renderer/Text/HtmlTest.php | 99 + .../BaconQrCode/Renderer/Text/TextTest.php | 149 + .../bacon/bacon-qr-code/tests/bootstrap.php | 10 + .../bacon/bacon-qr-code/tests/phpunit.xml | 11 + .../login/vendor/birke/rememberme/.gitignore | 4 + plugins/login/vendor/birke/rememberme/LICENSE | 21 + .../login/vendor/birke/rememberme/README.md | 40 + .../vendor/birke/rememberme/composer.json | 24 + .../birke/rememberme/example/action.php | 119 + .../birke/rememberme/example/css/style.css | 157 + .../vendor/birke/rememberme/example/index.php | 42 + .../example/templates/cookie_was_stolen.php | 4 + .../rememberme/example/templates/login.php | 14 + .../example/templates/user_is_logged_in.php | 31 + .../login/vendor/birke/rememberme/phpunit.xml | 7 + .../src/Rememberme/Authenticator.php | 293 + .../rememberme/src/Rememberme/Cookie.php | 104 + .../rememberme/src/Rememberme/Storage/DB.php | 145 + .../src/Rememberme/Storage/File.php | 119 + .../rememberme/src/Rememberme/Storage/PDO.php | 121 + .../Rememberme/Storage/StorageInterface.php | 66 + .../birke/rememberme/test/CookieTest.php | 31 + .../birke/rememberme/test/RemembermeTest.php | 352 + .../birke/rememberme/test/Storage/PDO.php | 98 + .../birke/rememberme/test/Storage/tokens.xml | 8 + .../birke/rememberme/test/bootstrap.php | 3 + plugins/login/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 255 + plugins/login/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../login/vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 10 + .../login/vendor/composer/autoload_psr4.php | 13 + .../login/vendor/composer/autoload_real.php | 75 + .../login/vendor/composer/autoload_static.php | 73 + plugins/login/vendor/composer/installed.json | 227 + plugins/login/vendor/composer/installed.php | 60 + .../login/vendor/composer/platform_check.php | 26 + .../login/vendor/dasprid/enum/.coveralls.yml | 2 + plugins/login/vendor/dasprid/enum/.gitignore | 3 + plugins/login/vendor/dasprid/enum/.travis.yml | 41 + plugins/login/vendor/dasprid/enum/README.md | 164 + .../login/vendor/dasprid/enum/composer.json | 30 + plugins/login/vendor/dasprid/enum/phpcs.xml | 30 + .../vendor/dasprid/enum/phpunit.xml.dist | 17 + .../vendor/dasprid/enum/src/AbstractEnum.php | 241 + .../login/vendor/dasprid/enum/src/EnumMap.php | 375 + .../Exception/CloneNotSupportedException.php | 10 + .../enum/src/Exception/ExceptionInterface.php | 10 + .../src/Exception/ExpectationException.php | 10 + .../Exception/IllegalArgumentException.php | 10 + .../enum/src/Exception/MismatchException.php | 10 + .../SerializeNotSupportedException.php | 10 + .../UnserializeNotSupportedException.php | 10 + .../vendor/dasprid/enum/src/NullValue.php | 55 + .../dasprid/enum/test/AbstractEnumTest.php | 121 + .../vendor/dasprid/enum/test/EnumMapTest.php | 243 + .../dasprid/enum/test/NullValueTest.php | 31 + .../login/vendor/dasprid/enum/test/Planet.php | 73 + .../vendor/dasprid/enum/test/WeekDay.php | 26 + .../paragonie/random_compat/CHANGELOG.md | 290 + .../vendor/paragonie/random_compat/LICENSE | 22 + .../paragonie/random_compat/RATIONALE.md | 42 + .../vendor/paragonie/random_compat/README.md | 176 + .../paragonie/random_compat/SECURITY.md | 108 + .../paragonie/random_compat/build-phar.sh | 5 + .../paragonie/random_compat/composer.json | 35 + .../dist/random_compat.phar.pubkey | 5 + .../dist/random_compat.phar.pubkey.asc | 11 + .../random_compat/lib/byte_safe_strings.php | 181 + .../random_compat/lib/cast_to_int.php | 74 + .../random_compat/lib/error_polyfill.php | 49 + .../paragonie/random_compat/lib/random.php | 247 + .../lib/random_bytes_com_dotnet.php | 88 + .../lib/random_bytes_dev_urandom.php | 150 + .../lib/random_bytes_libsodium.php | 88 + .../lib/random_bytes_libsodium_legacy.php | 92 + .../random_compat/lib/random_bytes_mcrypt.php | 77 + .../lib/random_bytes_openssl.php | 86 + .../random_compat/lib/random_int.php | 190 + .../random_compat/other/build_phar.php | 57 + .../random_compat/other/ide_stubs/COM.php | 20 + .../random_compat/other/ide_stubs/README.md | 7 + .../other/ide_stubs/com_exception.php | 11 + .../other/ide_stubs/libsodium.php | 90 + .../random_compat/psalm-autoload.php | 9 + .../vendor/paragonie/random_compat/psalm.xml | 15 + .../twofactorauth/.github/FUNDING.yml | 4 + .../twofactorauth/.github/workflows/test.yml | 27 + .../vendor/robthree/twofactorauth/.gitignore | 192 + .../vendor/robthree/twofactorauth/LICENSE | 22 + .../vendor/robthree/twofactorauth/README.md | 209 + .../twofactorauth/TwoFactorAuth.phpproj | 70 + .../robthree/twofactorauth/TwoFactorAuth.sln | 22 + .../robthree/twofactorauth/composer.json | 49 + .../robthree/twofactorauth/demo/demo.php | 35 + .../robthree/twofactorauth/demo/loader.php | 50 + .../lib/Providers/Qr/BaconQrCodeProvider.php | 152 + .../Providers/Qr/BaseHTTPQRCodeProvider.php | 33 + .../Providers/Qr/EndroidQrCodeProvider.php | 70 + .../Qr/EndroidQrCodeWithLogoProvider.php | 35 + .../lib/Providers/Qr/IQRCodeProvider.php | 24 + .../Qr/ImageChartsQRCodeProvider.php | 60 + .../lib/Providers/Qr/QRException.php | 7 + .../lib/Providers/Qr/QRServerProvider.php | 108 + .../lib/Providers/Qr/QRicketProvider.php | 76 + .../lib/Providers/Rng/CSRNGProvider.php | 22 + .../lib/Providers/Rng/HashRNGProvider.php | 43 + .../lib/Providers/Rng/IRNGProvider.php | 18 + .../lib/Providers/Rng/MCryptRNGProvider.php | 37 + .../lib/Providers/Rng/OpenSSLRNGProvider.php | 40 + .../lib/Providers/Rng/RNGException.php | 7 + .../lib/Providers/Time/HttpTimeProvider.php | 71 + .../lib/Providers/Time/ITimeProvider.php | 11 + .../Time/LocalMachineTimeProvider.php | 11 + .../lib/Providers/Time/NTPTimeProvider.php | 70 + .../lib/Providers/Time/TimeException.php | 7 + .../twofactorauth/lib/TwoFactorAuth.php | 360 + .../lib/TwoFactorAuthException.php | 7 + .../vendor/robthree/twofactorauth/logo.png | Bin 0 -> 2636 bytes .../multifactorauthforeveryone.png | Bin 0 -> 20735 bytes .../vendor/robthree/twofactorauth/phpunit.xml | 26 + .../tests/MightNotMakeAssertions.php | 26 + .../Providers/Qr/IQRCodeProviderTest.php | 56 + .../tests/Providers/Qr/TestQrProvider.php | 24 + .../tests/Providers/Rng/CSRNGProviderTest.php | 30 + .../Providers/Rng/HashRNGProviderTest.php | 24 + .../tests/Providers/Rng/IRNGProviderTest.php | 61 + .../Providers/Rng/MCryptRNGProviderTest.php | 32 + .../tests/Providers/Rng/NeedsRngLengths.php | 9 + .../Providers/Rng/OpenSSLRNGProviderTest.php | 37 + .../tests/Providers/Rng/TestRNGProvider.php | 41 + .../Providers/Time/ITimeProviderTest.php | 53 + .../tests/Providers/Time/TestTimeProvider.php | 27 + .../twofactorauth/tests/TwoFactorAuthTest.php | 246 + plugins/page-toc/CHANGELOG.md | 63 + plugins/page-toc/LICENSE | 21 + plugins/page-toc/README.md | 203 + plugins/page-toc/assets/page-toc-anchors.css | 22 + plugins/page-toc/assets/page-toc.png | Bin 0 -> 338518 bytes plugins/page-toc/blueprints.yaml | 156 + plugins/page-toc/blueprints/page-toc.yaml | 140 + plugins/page-toc/classes/HtmlHelper.php | 102 + plugins/page-toc/classes/MarkupFixer.php | 89 + .../page-toc/classes/OrderedListRenderer.php | 68 + plugins/page-toc/classes/TocGenerator.php | 179 + plugins/page-toc/classes/UniqueSlugify.php | 74 + .../classes/shortcodes/AnchorShortcode.php | 36 + plugins/page-toc/composer.json | 31 + plugins/page-toc/composer.lock | 170 + plugins/page-toc/languages.yaml | 32 + plugins/page-toc/page-toc.php | 239 + plugins/page-toc/page-toc.yaml | 17 + .../templates/components/page-toc.html.twig | 26 + plugins/page-toc/vendor/autoload.php | 7 + plugins/page-toc/vendor/cocur/slugify/LICENSE | 9 + .../page-toc/vendor/cocur/slugify/README.md | 751 + .../vendor/cocur/slugify/composer.json | 59 + .../src/Bridge/Laravel/SlugifyFacade.php | 39 + .../Bridge/Laravel/SlugifyServiceProvider.php | 57 + .../src/Bridge/Latte/SlugifyHelper.php | 38 + .../Bridge/League/SlugifyServiceProvider.php | 37 + .../src/Bridge/Nette/SlugifyExtension.php | 49 + .../src/Bridge/Plum/SlugifyConverter.php | 50 + .../src/Bridge/Symfony/CocurSlugifyBundle.php | 31 + .../Bridge/Symfony/CocurSlugifyExtension.php | 62 + .../src/Bridge/Symfony/Configuration.php | 46 + .../src/Bridge/Twig/SlugifyExtension.php | 80 + .../cocur/slugify/src/Bridge/ZF2/Module.php | 50 + .../slugify/src/Bridge/ZF2/SlugifyService.php | 30 + .../src/Bridge/ZF2/SlugifyViewHelper.php | 41 + .../Bridge/ZF2/SlugifyViewHelperFactory.php | 28 + .../src/RuleProvider/DefaultRuleProvider.php | 8557 ++ .../src/RuleProvider/FileRuleProvider.php | 47 + .../RuleProvider/RuleProviderInterface.php | 29 + .../vendor/cocur/slugify/src/Slugify.php | 192 + .../cocur/slugify/src/SlugifyInterface.php | 36 + .../page-toc/vendor/composer/ClassLoader.php | 572 + .../vendor/composer/InstalledVersions.php | 350 + plugins/page-toc/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 12 + .../vendor/composer/autoload_real.php | 57 + .../vendor/composer/autoload_static.php | 53 + .../page-toc/vendor/composer/installed.json | 158 + .../page-toc/vendor/composer/installed.php | 41 + .../vendor/composer/platform_check.php | 26 + .../tmp-f711f3efca8baf836db7f0f0b18aef94~ | 1 + .../vendor/knplabs/knp-menu/CHANGELOG.md | 174 + .../page-toc/vendor/knplabs/knp-menu/LICENSE | 19 + .../vendor/knplabs/knp-menu/composer.json | 52 + .../src/Knp/Menu/Factory/CoreExtension.php | 62 + .../Knp/Menu/Factory/ExtensionInterface.php | 24 + .../src/Knp/Menu/FactoryInterface.php | 16 + .../Integration/Symfony/RoutingExtension.php | 44 + .../knp-menu/src/Knp/Menu/ItemInterface.php | 333 + .../Iterator/CurrentItemFilterIterator.php | 35 + .../Iterator/DisplayedItemFilterIterator.php | 27 + .../Menu/Iterator/RecursiveItemIterator.php | 33 + .../src/Knp/Menu/Loader/ArrayLoader.php | 62 + .../src/Knp/Menu/Loader/LoaderInterface.php | 22 + .../src/Knp/Menu/Loader/NodeLoader.php | 40 + .../knp-menu/src/Knp/Menu/Matcher/Matcher.php | 76 + .../src/Knp/Menu/Matcher/MatcherInterface.php | 28 + .../src/Knp/Menu/Matcher/Voter/RegexVoter.php | 35 + .../src/Knp/Menu/Matcher/Voter/RouteVoter.php | 94 + .../src/Knp/Menu/Matcher/Voter/UriVoter.php | 34 + .../Knp/Menu/Matcher/Voter/VoterInterface.php | 19 + .../knp-menu/src/Knp/Menu/MenuFactory.php | 66 + .../knp-menu/src/Knp/Menu/MenuItem.php | 620 + .../knp-menu/src/Knp/Menu/NodeInterface.php | 30 + .../Knp/Menu/Provider/ArrayAccessProvider.php | 55 + .../src/Knp/Menu/Provider/ChainProvider.php | 43 + .../src/Knp/Menu/Provider/LazyProvider.php | 52 + .../Menu/Provider/MenuProviderInterface.php | 24 + .../src/Knp/Menu/Provider/PsrProvider.php | 39 + .../Knp/Menu/Renderer/ArrayAccessProvider.php | 54 + .../src/Knp/Menu/Renderer/ListRenderer.php | 260 + .../src/Knp/Menu/Renderer/PsrProvider.php | 51 + .../src/Knp/Menu/Renderer/Renderer.php | 100 + .../Knp/Menu/Renderer/RendererInterface.php | 27 + .../Renderer/RendererProviderInterface.php | 20 + .../src/Knp/Menu/Renderer/TwigRenderer.php | 66 + .../Menu/Resources/views/knp_menu.html.twig | 101 + .../Resources/views/knp_menu_base.html.twig | 1 + .../views/knp_menu_ordered.html.twig | 11 + .../knp-menu/src/Knp/Menu/Twig/Helper.php | 192 + .../src/Knp/Menu/Twig/MenuExtension.php | 166 + .../src/Knp/Menu/Util/MenuManipulator.php | 304 + plugins/pagination/CHANGELOG.md | 89 + plugins/pagination/LICENSE | 21 + plugins/pagination/README.md | 151 + plugins/pagination/blueprints.yaml | 48 + .../pagination/classes/paginationhelper.php | 132 + plugins/pagination/classes/paginationpage.php | 84 + plugins/pagination/css/pagination.css | 17 + plugins/pagination/languages.yaml | 20 + plugins/pagination/pagination.php | 141 + plugins/pagination/pagination.yaml | 3 + .../templates/partials/pagination.html.twig | 34 + .../twig/PaginationTwigExtension.php | 42 + plugins/problems/CHANGELOG.md | 164 + plugins/problems/LICENSE | 21 + plugins/problems/README.md | 92 + plugins/problems/assets/cli.png | Bin 0 -> 401907 bytes plugins/problems/assets/code-3.svg | 11 + plugins/problems/assets/grav-logo.svg | 1 + plugins/problems/assets/heart.svg | 5 + plugins/problems/assets/readme_1.jpg | Bin 0 -> 368222 bytes plugins/problems/blueprints.yaml | 43 + plugins/problems/classes/Problems/Apache.php | 61 + .../classes/Problems/Base/Problem.php | 141 + .../classes/Problems/Base/ProblemChecker.php | 159 + .../classes/Problems/EssentialFolders.php | 78 + .../problems/classes/Problems/PHPModules.php | 148 + .../problems/classes/Problems/PHPVersion.php | 43 + .../problems/classes/Problems/Permissions.php | 42 + plugins/problems/cli/CheckCommand.php | 107 + plugins/problems/composer.json | 32 + plugins/problems/composer.lock | 20 + plugins/problems/css/admin.css | 31 + plugins/problems/css/admin.min.css | 1 + plugins/problems/css/spectre-icons.css | 168 + plugins/problems/css/spectre-icons.min.css | 1 + plugins/problems/css/spectre.css | 1276 + plugins/problems/css/spectre.min.css | 1 + plugins/problems/gulpfile.js | 39 + plugins/problems/languages.yaml | 14 + plugins/problems/package.json | 45 + plugins/problems/problems.php | 185 + plugins/problems/problems.yaml | 2 + plugins/problems/scss/_accordions.scss | 38 + plugins/problems/scss/_animations.scss | 20 + plugins/problems/scss/_asian.scss | 38 + plugins/problems/scss/_autocomplete.scss | 47 + plugins/problems/scss/_avatars.scss | 77 + plugins/problems/scss/_badges.scss | 60 + plugins/problems/scss/_bars.scss | 71 + plugins/problems/scss/_base.scss | 44 + plugins/problems/scss/_breadcrumbs.scss | 29 + plugins/problems/scss/_buttons.scss | 195 + plugins/problems/scss/_calendars.scss | 222 + plugins/problems/scss/_cards.scss | 43 + plugins/problems/scss/_carousels.scss | 126 + plugins/problems/scss/_chips.scss | 30 + plugins/problems/scss/_codes.scss | 31 + .../problems/scss/_comparison-sliders.scss | 115 + plugins/problems/scss/_dropdowns.scss | 36 + plugins/problems/scss/_empty.scss | 21 + plugins/problems/scss/_filters.scss | 37 + plugins/problems/scss/_forms.scss | 545 + plugins/problems/scss/_icons.scss | 5 + plugins/problems/scss/_labels.scss | 34 + plugins/problems/scss/_layout.scss | 424 + plugins/problems/scss/_media.scss | 75 + plugins/problems/scss/_menus.scss | 62 + plugins/problems/scss/_meters.scss | 57 + plugins/problems/scss/_mixins.scss | 11 + plugins/problems/scss/_modals.scss | 87 + plugins/problems/scss/_navbar.scss | 29 + plugins/problems/scss/_navs.scss | 34 + plugins/problems/scss/_normalize.scss | 446 + plugins/problems/scss/_off-canvas.scss | 95 + plugins/problems/scss/_pagination.scss | 61 + plugins/problems/scss/_panels.scss | 23 + plugins/problems/scss/_parallax.scss | 135 + plugins/problems/scss/_popovers.scss | 65 + plugins/problems/scss/_preset.scss | 90 + plugins/problems/scss/_problems.scss | 72 + plugins/problems/scss/_progress.scss | 45 + plugins/problems/scss/_sliders.scss | 99 + plugins/problems/scss/_steps.scss | 70 + plugins/problems/scss/_tables.scss | 57 + plugins/problems/scss/_tabs.scss | 66 + plugins/problems/scss/_tiles.scss | 38 + plugins/problems/scss/_timelines.scss | 54 + plugins/problems/scss/_toasts.scss | 42 + plugins/problems/scss/_tooltips.scss | 79 + plugins/problems/scss/_typography.scss | 128 + plugins/problems/scss/_utilities.scss | 8 + plugins/problems/scss/_variables.scss | 116 + plugins/problems/scss/admin.scss | 92 + .../problems/scss/icons/_icons-action.scss | 316 + plugins/problems/scss/icons/_icons-core.scss | 53 + .../scss/icons/_icons-navigation.scss | 133 + .../problems/scss/icons/_icons-object.scss | 176 + plugins/problems/scss/mixins/_avatar.scss | 6 + plugins/problems/scss/mixins/_button.scss | 54 + plugins/problems/scss/mixins/_clearfix.scss | 8 + plugins/problems/scss/mixins/_color.scss | 27 + plugins/problems/scss/mixins/_label.scss | 11 + plugins/problems/scss/mixins/_position.scss | 65 + plugins/problems/scss/mixins/_shadow.scss | 9 + plugins/problems/scss/mixins/_text.scss | 6 + plugins/problems/scss/mixins/_toast.scss | 5 + plugins/problems/scss/mixins/_transition.scss | 4 + plugins/problems/scss/spectre-icons.scss | 10 + plugins/problems/scss/spectre.scss | 51 + plugins/problems/scss/utilities/_colors.scss | 31 + plugins/problems/scss/utilities/_cursors.scss | 24 + plugins/problems/scss/utilities/_display.scss | 44 + plugins/problems/scss/utilities/_divider.scss | 50 + plugins/problems/scss/utilities/_loading.scss | 34 + .../problems/scss/utilities/_position.scss | 50 + plugins/problems/scss/utilities/_shapes.scss | 8 + plugins/problems/scss/utilities/_text.scss | 64 + plugins/problems/templates/problems.html.twig | 34 + .../reports/problems-report.html.twig | 33 + plugins/problems/vendor/autoload.php | 7 + .../problems/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 219 + plugins/problems/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 11 + .../vendor/composer/autoload_real.php | 55 + .../vendor/composer/autoload_static.php | 42 + .../problems/vendor/composer/installed.json | 5 + .../problems/vendor/composer/installed.php | 24 + plugins/readingtime/CHANGELOG.md | 43 + plugins/readingtime/LICENSE | 21 + plugins/readingtime/README.md | 87 + plugins/readingtime/blueprints.yaml | 72 + .../classes/TwigReadingTimeFilters.php | 136 + plugins/readingtime/composer.json | 38 + plugins/readingtime/composer.lock | 22 + plugins/readingtime/languages.yaml | 62 + plugins/readingtime/readingtime.php | 49 + plugins/readingtime/readingtime.yaml | 6 + plugins/readingtime/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 + plugins/readingtime/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 52 + .../vendor/composer/autoload_static.php | 36 + .../vendor/composer/installed.json | 1 + plugins/relatedpages/CHANGELOG.md | 69 + plugins/relatedpages/LICENSE | 22 + plugins/relatedpages/README.md | 131 + plugins/relatedpages/assets/readme_1.png | Bin 0 -> 43313 bytes plugins/relatedpages/blueprints.yaml | 194 + plugins/relatedpages/languages.yaml | 187 + plugins/relatedpages/relatedpages.php | 254 + plugins/relatedpages/relatedpages.yaml | 35 + .../templates/partials/relatedpages.html.twig | 13 + plugins/simplesearch/CHANGELOG.md | 285 + plugins/simplesearch/LICENSE | 21 + plugins/simplesearch/README.md | 209 + plugins/simplesearch/assets/readme_1.png | Bin 0 -> 113109 bytes plugins/simplesearch/assets/search.svg | 7 + plugins/simplesearch/blueprints.yaml | 172 + plugins/simplesearch/composer.json | 35 + plugins/simplesearch/composer.lock | 22 + plugins/simplesearch/css/simplesearch.css | 42 + plugins/simplesearch/js/simplesearch.js | 32 + plugins/simplesearch/languages.yaml | 226 + plugins/simplesearch/pages/simplesearch.md | 7 + plugins/simplesearch/simplesearch.php | 450 + plugins/simplesearch/simplesearch.yaml | 21 + .../partials/simplesearch_base.html.twig | 1 + .../partials/simplesearch_item.html.twig | 23 + .../partials/simplesearch_searchbox.html.twig | 23 + .../templates/simplesearch_results.html.twig | 23 + .../templates/simplesearch_results.json.twig | 5 + plugins/simplesearch/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 + plugins/simplesearch/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 9 + .../vendor/composer/autoload_real.php | 52 + .../vendor/composer/autoload_static.php | 20 + .../vendor/composer/installed.json | 1 + plugins/sitemap/.gitignore | 1 + plugins/sitemap/CHANGELOG.md | 167 + plugins/sitemap/LICENSE | 21 + plugins/sitemap/README.md | 137 + plugins/sitemap/blueprints.yaml | 226 + plugins/sitemap/blueprints/sitemap.yaml | 59 + plugins/sitemap/classes/SitemapEntry.php | 243 + plugins/sitemap/composer.json | 30 + plugins/sitemap/composer.lock | 23 + plugins/sitemap/hebe.json | 15 + plugins/sitemap/languages.yaml | 142 + plugins/sitemap/pages/sitemap.md | 3 + plugins/sitemap/sitemap.php | 316 + plugins/sitemap/sitemap.xsl | 107 + plugins/sitemap/sitemap.yaml | 16 + plugins/sitemap/templates/sitemap.html.twig | 31 + plugins/sitemap/templates/sitemap.json.twig | 1 + plugins/sitemap/templates/sitemap.xml.twig | 42 + plugins/sitemap/vendor/autoload.php | 7 + .../sitemap/vendor/composer/ClassLoader.php | 445 + .../vendor/composer/InstalledVersions.php | 219 + plugins/sitemap/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../sitemap/vendor/composer/autoload_psr4.php | 10 + .../sitemap/vendor/composer/autoload_real.php | 57 + .../vendor/composer/autoload_static.php | 37 + .../sitemap/vendor/composer/installed.json | 5 + plugins/sitemap/vendor/composer/installed.php | 24 + .../vendor/composer/platform_check.php | 26 + plugins/taxonomylist/CHANGELOG.md | 93 + plugins/taxonomylist/LICENSE | 21 + plugins/taxonomylist/README.md | 64 + plugins/taxonomylist/assets/readme_1.png | Bin 0 -> 12888 bytes plugins/taxonomylist/blueprints.yaml | 39 + plugins/taxonomylist/classes/taxonomylist.php | 97 + plugins/taxonomylist/composer.json | 36 + plugins/taxonomylist/composer.lock | 22 + plugins/taxonomylist/taxonomylist.php | 75 + plugins/taxonomylist/taxonomylist.yaml | 2 + .../templates/partials/taxonomylist.html.twig | 10 + plugins/taxonomylist/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 + plugins/taxonomylist/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 9 + .../vendor/composer/autoload_real.php | 52 + .../vendor/composer/autoload_static.php | 21 + .../vendor/composer/installed.json | 1 + themes/.gitkeep | 0 themes/mytheme/css/content.css | 327 + themes/mytheme/css/fork-awesome.min.css | 12 + themes/mytheme/css/item.css | 346 + themes/mytheme/css/sidebar.css | 93 + themes/mytheme/css/style.css | 1279 + themes/mytheme/fonts/forkawesome-webfont.eot | Bin 0 -> 219194 bytes themes/mytheme/fonts/forkawesome-webfont.svg | 3232 + themes/mytheme/fonts/forkawesome-webfont.ttf | Bin 0 -> 219004 bytes themes/mytheme/fonts/forkawesome-webfont.woff | Bin 0 -> 136120 bytes .../mytheme/fonts/forkawesome-webfont.woff2 | Bin 0 -> 109916 bytes themes/mytheme/images/bmenu.png | Bin 0 -> 3308 bytes themes/mytheme/images/favicon.png | Bin 0 -> 58877 bytes themes/mytheme/images/license.webp | Bin 0 -> 1214 bytes .../mytheme/images/org-navbar-logo-white.webp | Bin 0 -> 80220 bytes themes/mytheme/mytheme.yaml | 10 + .../plugins/aura-authors/blueprints.yaml | 126 + .../de/partials/author-bio.html.twig | 66 + .../templates/de/partials/base.html.twig | 71 + .../templates/de/partials/blog_item.html.twig | 305 + .../templates/de/partials/footer.html.twig | 48 + .../templates/de/partials/header.html.twig | 28 + .../de/partials/langswitcher.html.twig | 31 + .../de/partials/navigation.html.twig | 57 + .../en/partials/author-bio.html.twig | 54 + .../templates/en/partials/base.html.twig | 71 + .../templates/en/partials/blog_item.html.twig | 284 + .../templates/en/partials/footer.html.twig | 48 + .../templates/en/partials/header.html.twig | 28 + .../en/partials/langswitcher.html.twig | 31 + .../en/partials/navigation.html.twig | 57 + .../mytheme/templates/sidebar/blog.html.twig | 40 + themes/pinpress/CHANGELOG.md | 45 + themes/pinpress/LICENSE | 65 + themes/pinpress/README.md | 83 + themes/pinpress/assets/readme_1.png | Bin 0 -> 463764 bytes themes/pinpress/blueprints.yaml | 32 + themes/pinpress/css/content.css | 327 + themes/pinpress/css/item.css | 346 + themes/pinpress/css/sidebar.css | 92 + themes/pinpress/css/style.css | 1279 + themes/pinpress/css/widget.css | 1 + themes/pinpress/images/bmenu.png | Bin 0 -> 3308 bytes themes/pinpress/images/favicon.png | Bin 0 -> 717 bytes themes/pinpress/js/scripts.js | 58 + themes/pinpress/js/video.js | 6 + themes/pinpress/pinpress.php | 9 + themes/pinpress/pinpress.yaml | 3 + themes/pinpress/screenshot.jpg | Bin 0 -> 214151 bytes themes/pinpress/templates/blog.html.twig | 33 + themes/pinpress/templates/default.html.twig | 15 + themes/pinpress/templates/error.html.twig | 15 + themes/pinpress/templates/form.html.twig | 19 + themes/pinpress/templates/formdata.html.twig | 19 + themes/pinpress/templates/item.html.twig | 26 + .../templates/macros/macros.html.twig | 3 + .../pinpress/templates/pagination.html.twig | 25 + .../templates/partials/base.html.twig | 76 + .../templates/partials/blog_item.html.twig | 270 + .../partials/blog_sidebar_footer.html.twig | 7 + .../partials/blog_sidebar_header.html.twig | 3 + .../templates/partials/footer.html.twig | 16 + .../templates/partials/header.html.twig | 26 + .../templates/partials/navigation.html.twig | 48 + .../templates/partials/relatedpages.html.twig | 16 + .../templates/partials/sidebar.html.twig | 60 + .../templates/partials/taxonomylist.html.twig | 14 + .../templates/sidebar/about.html.twig | 20 + .../templates/sidebar/widget.html.twig | 4 + .../templates/simplesearch_results.html.twig | 29 + themes/pinpress/thumbnail.jpg | Bin 0 -> 48782 bytes 2811 files changed, 495718 insertions(+) create mode 100755 pages/01.blog/blog.de.md create mode 100644 pages/01.blog/blog.en.md create mode 100644 pages/01.blog/our-news-blog-is-online-with-grav/item.de.md create mode 100644 pages/01.blog/our-news-blog-is-online-with-grav/item.en.md create mode 100755 pages/01.blog/our-news-blog-is-online-with-grav/ts&grav.png create mode 100644 pages/01.blog/tech-saviours-org-nz-online-de-why/item.de.md create mode 100644 pages/01.blog/tech-saviours-org-nz-online-de-why/item.en.md create mode 100755 pages/01.blog/tech-saviours-org-nz-online-de-why/techsaviours-hierarchy.png create mode 100644 pages/02.home/external.de.md create mode 100644 pages/02.home/external.en.md create mode 100644 pages/03.wiki/external.de.md create mode 100644 pages/03.wiki/external.en.md create mode 100644 pages/04.free-services/external.de.md create mode 100644 pages/04.free-services/external.en.md create mode 100644 pages/05.tutorials/external.de.md create mode 100644 pages/05.tutorials/external.en.md create mode 100644 pages/06.about/external.de.md create mode 100644 pages/06.about/external.en.md create mode 100755 pages/sidebar/about/blog.de.md create mode 100644 pages/sidebar/about/blog.en.md create mode 100644 pages/sidebar/about/org-favicon-white-background.png create mode 100644 plugins/.gitkeep create mode 100644 plugins/admin/.editorconfig create mode 100644 plugins/admin/.gitattributes create mode 100644 plugins/admin/.github/FUNDING.yml create mode 100644 plugins/admin/.gitignore create mode 100644 plugins/admin/CHANGELOG.md create mode 100644 plugins/admin/CONTRIBUTING.md create mode 100644 plugins/admin/LICENSE create mode 100644 plugins/admin/README.md create mode 100644 plugins/admin/UPGRADE.md create mode 100644 plugins/admin/admin.php create mode 100644 plugins/admin/admin.yaml create mode 100644 plugins/admin/assets/admin-dashboard.png create mode 100644 plugins/admin/blueprints.yaml create mode 100644 plugins/admin/blueprints/admin/pages/copy.yaml create mode 100644 plugins/admin/blueprints/admin/pages/modular_new.yaml create mode 100644 plugins/admin/blueprints/admin/pages/modular_raw.yaml create mode 100644 plugins/admin/blueprints/admin/pages/move.yaml create mode 100644 plugins/admin/blueprints/admin/pages/new.yaml create mode 100644 plugins/admin/blueprints/admin/pages/new_folder.yaml create mode 100644 plugins/admin/blueprints/admin/pages/raw.yaml create mode 100644 plugins/admin/blueprints/admin/pages/root_raw.yaml create mode 100644 plugins/admin/blueprints/config/media.yaml create mode 100644 plugins/admin/classes/plugin/Admin.php create mode 100644 plugins/admin/classes/plugin/AdminBaseController.php create mode 100644 plugins/admin/classes/plugin/AdminController.php create mode 100644 plugins/admin/classes/plugin/AdminForm.php create mode 100644 plugins/admin/classes/plugin/AdminFormFactory.php create mode 100644 plugins/admin/classes/plugin/Controllers/AbstractController.php create mode 100644 plugins/admin/classes/plugin/Controllers/AdminController.php create mode 100644 plugins/admin/classes/plugin/Controllers/Login/LoginController.php create mode 100644 plugins/admin/classes/plugin/Gpm.php create mode 100644 plugins/admin/classes/plugin/Popularity.php create mode 100644 plugins/admin/classes/plugin/Router.php create mode 100644 plugins/admin/classes/plugin/Routers/LoginRouter.php create mode 100644 plugins/admin/classes/plugin/ScssCompiler.php create mode 100644 plugins/admin/classes/plugin/ScssList.php create mode 100644 plugins/admin/classes/plugin/Themes.php create mode 100644 plugins/admin/classes/plugin/Twig/AdminTwigExtension.php create mode 100644 plugins/admin/classes/plugin/Utils.php create mode 100644 plugins/admin/classes/plugin/WhiteLabel.php create mode 100644 plugins/admin/codeception.yml create mode 100644 plugins/admin/composer.json create mode 100644 plugins/admin/composer.lock create mode 100644 plugins/admin/hebe.json create mode 100644 plugins/admin/languages/ar.yaml create mode 100644 plugins/admin/languages/bg.yaml create mode 100644 plugins/admin/languages/bn.yaml create mode 100644 plugins/admin/languages/br.yaml create mode 100644 plugins/admin/languages/ca.yaml create mode 100644 plugins/admin/languages/cs.yaml create mode 100644 plugins/admin/languages/cy.yaml create mode 100644 plugins/admin/languages/da.yaml create mode 100644 plugins/admin/languages/de.yaml create mode 100644 plugins/admin/languages/el.yaml create mode 100644 plugins/admin/languages/en.yaml create mode 100644 plugins/admin/languages/eo.yaml create mode 100644 plugins/admin/languages/es.yaml create mode 100644 plugins/admin/languages/et.yaml create mode 100644 plugins/admin/languages/eu.yaml create mode 100644 plugins/admin/languages/fa.yaml create mode 100644 plugins/admin/languages/fi.yaml create mode 100644 plugins/admin/languages/fr.yaml create mode 100644 plugins/admin/languages/gl.yaml create mode 100644 plugins/admin/languages/he.yaml create mode 100644 plugins/admin/languages/hr.yaml create mode 100644 plugins/admin/languages/hu.yaml create mode 100644 plugins/admin/languages/id.yaml create mode 100644 plugins/admin/languages/it.yaml create mode 100644 plugins/admin/languages/ja.yaml create mode 100644 plugins/admin/languages/ko.yaml create mode 100644 plugins/admin/languages/ku.yaml create mode 100644 plugins/admin/languages/lt.yaml create mode 100644 plugins/admin/languages/mn.yaml create mode 100644 plugins/admin/languages/nl.yaml create mode 100644 plugins/admin/languages/no.yaml create mode 100644 plugins/admin/languages/pl.yaml create mode 100644 plugins/admin/languages/pt.yaml create mode 100644 plugins/admin/languages/ro.yaml create mode 100644 plugins/admin/languages/ru.yaml create mode 100644 plugins/admin/languages/si.yaml create mode 100644 plugins/admin/languages/sk.yaml create mode 100644 plugins/admin/languages/sl.yaml create mode 100644 plugins/admin/languages/sr.yaml create mode 100644 plugins/admin/languages/sv.yaml create mode 100644 plugins/admin/languages/th.yaml create mode 100644 plugins/admin/languages/tlh.yaml create mode 100644 plugins/admin/languages/tr.yaml create mode 100644 plugins/admin/languages/uk.yaml create mode 100644 plugins/admin/languages/vi.yaml create mode 100644 plugins/admin/languages/zh-cn.yaml create mode 100644 plugins/admin/languages/zh-tw.yaml create mode 100644 plugins/admin/languages/zh.yaml create mode 100644 plugins/admin/pages/admin/ajax.md create mode 100644 plugins/admin/pages/admin/backup.md create mode 100644 plugins/admin/pages/admin/cache.md create mode 100644 plugins/admin/pages/admin/changelog.md create mode 100644 plugins/admin/pages/admin/config.md create mode 100644 plugins/admin/pages/admin/dashboard.md create mode 100644 plugins/admin/pages/admin/denied.md create mode 100644 plugins/admin/pages/admin/error.md create mode 100644 plugins/admin/pages/admin/feed.md create mode 100644 plugins/admin/pages/admin/forgot.md create mode 100644 plugins/admin/pages/admin/info.md create mode 100644 plugins/admin/pages/admin/installer.md create mode 100644 plugins/admin/pages/admin/login.md create mode 100644 plugins/admin/pages/admin/media.md create mode 100644 plugins/admin/pages/admin/notifications.md create mode 100644 plugins/admin/pages/admin/pages-filter.md create mode 100644 plugins/admin/pages/admin/pages.md create mode 100644 plugins/admin/pages/admin/plugins.md create mode 100644 plugins/admin/pages/admin/preview.md create mode 100644 plugins/admin/pages/admin/register.md create mode 100644 plugins/admin/pages/admin/reset.md create mode 100644 plugins/admin/pages/admin/site.md create mode 100644 plugins/admin/pages/admin/statistics.md create mode 100644 plugins/admin/pages/admin/system.md create mode 100644 plugins/admin/pages/admin/themes.md create mode 100644 plugins/admin/pages/admin/tools.md create mode 100644 plugins/admin/pages/admin/update.md create mode 100644 plugins/admin/pages/admin/user.md create mode 100644 plugins/admin/permissions.yaml create mode 100644 plugins/admin/presets.yaml create mode 100644 plugins/admin/tests/_bootstrap.php create mode 100644 plugins/admin/tests/_support/Helper/Unit.php create mode 100644 plugins/admin/tests/_support/UnitTester.php create mode 100644 plugins/admin/tests/unit.suite.yml create mode 100644 plugins/admin/tests/unit/_bootstrap.php create mode 100644 plugins/admin/tests/unit/classes/controllerTest.php create mode 100644 plugins/admin/themes/grav/.babelrc create mode 100644 plugins/admin/themes/grav/.eslintrc create mode 100644 plugins/admin/themes/grav/app/dashboard/backup.js create mode 100644 plugins/admin/themes/grav/app/dashboard/cache.js create mode 100644 plugins/admin/themes/grav/app/dashboard/chart.js create mode 100644 plugins/admin/themes/grav/app/dashboard/index.js create mode 100644 plugins/admin/themes/grav/app/dashboard/update.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/acl-picker.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/array.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/collections.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/colorpicker.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/cron.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/datetime.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/editor.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/editor/buttons.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/filepicker.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/files.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/folder.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/iconpicker.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/indeterminate.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/index.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/mediapicker.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/multilevel.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/parents.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/permissions.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/range.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/selectize.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/selectunique.js create mode 100644 plugins/admin/themes/grav/app/forms/fields/text.js create mode 100644 plugins/admin/themes/grav/app/forms/form.js create mode 100644 plugins/admin/themes/grav/app/forms/index.js create mode 100644 plugins/admin/themes/grav/app/forms/state.js create mode 100644 plugins/admin/themes/grav/app/main.js create mode 100644 plugins/admin/themes/grav/app/media/index.js create mode 100644 plugins/admin/themes/grav/app/pages/filter.js create mode 100644 plugins/admin/themes/grav/app/pages/index.js create mode 100644 plugins/admin/themes/grav/app/pages/page/add.js create mode 100644 plugins/admin/themes/grav/app/pages/page/delete.js create mode 100644 plugins/admin/themes/grav/app/pages/page/disable-buttons.js create mode 100644 plugins/admin/themes/grav/app/pages/page/index.js create mode 100644 plugins/admin/themes/grav/app/pages/page/media.js create mode 100644 plugins/admin/themes/grav/app/pages/page/move.js create mode 100644 plugins/admin/themes/grav/app/pages/page/multilang.js create mode 100644 plugins/admin/themes/grav/app/pages/page/unset.js create mode 100644 plugins/admin/themes/grav/app/pages/tree.js create mode 100644 plugins/admin/themes/grav/app/plugins/index.js create mode 100644 plugins/admin/themes/grav/app/themes/index.js create mode 100644 plugins/admin/themes/grav/app/tools/index.js create mode 100644 plugins/admin/themes/grav/app/tools/logs.js create mode 100644 plugins/admin/themes/grav/app/updates/channel-switcher.js create mode 100644 plugins/admin/themes/grav/app/updates/check.js create mode 100644 plugins/admin/themes/grav/app/updates/feed.js create mode 100644 plugins/admin/themes/grav/app/updates/index.js create mode 100644 plugins/admin/themes/grav/app/updates/notifications.js create mode 100644 plugins/admin/themes/grav/app/updates/update.js create mode 100644 plugins/admin/themes/grav/app/utils/2fa.js create mode 100644 plugins/admin/themes/grav/app/utils/bootstrap-collapse.js create mode 100644 plugins/admin/themes/grav/app/utils/bootstrap-datetimepicker.js create mode 100644 plugins/admin/themes/grav/app/utils/bootstrap-dropdown.js create mode 100644 plugins/admin/themes/grav/app/utils/bootstrap-transition.js create mode 100644 plugins/admin/themes/grav/app/utils/changelog.js create mode 100644 plugins/admin/themes/grav/app/utils/colors.js create mode 100644 plugins/admin/themes/grav/app/utils/cookies.js create mode 100644 plugins/admin/themes/grav/app/utils/cron-ui.js create mode 100644 plugins/admin/themes/grav/app/utils/finderjs.js create mode 100644 plugins/admin/themes/grav/app/utils/formatbytes.js create mode 100644 plugins/admin/themes/grav/app/utils/gpm.js create mode 100644 plugins/admin/themes/grav/app/utils/jquery-utils.js create mode 100644 plugins/admin/themes/grav/app/utils/keepalive.js create mode 100644 plugins/admin/themes/grav/app/utils/offline.js create mode 100644 plugins/admin/themes/grav/app/utils/packages.js create mode 100644 plugins/admin/themes/grav/app/utils/remodal.js create mode 100644 plugins/admin/themes/grav/app/utils/request.js create mode 100644 plugins/admin/themes/grav/app/utils/response.js create mode 100644 plugins/admin/themes/grav/app/utils/scrollbar.js create mode 100644 plugins/admin/themes/grav/app/utils/selectize-option-click.js create mode 100644 plugins/admin/themes/grav/app/utils/selectize-required-fix.js create mode 100644 plugins/admin/themes/grav/app/utils/sidebar.js create mode 100644 plugins/admin/themes/grav/app/utils/storage.js create mode 100644 plugins/admin/themes/grav/app/utils/tabs-memory.js create mode 100644 plugins/admin/themes/grav/app/utils/toastr.js create mode 100644 plugins/admin/themes/grav/app/whitelabel/compile.js create mode 100644 plugins/admin/themes/grav/app/whitelabel/index.js create mode 100644 plugins/admin/themes/grav/app/whitelabel/presets.js create mode 100644 plugins/admin/themes/grav/css-compiled/fonts.css create mode 100644 plugins/admin/themes/grav/css-compiled/fonts.css.map create mode 100644 plugins/admin/themes/grav/css-compiled/nucleus.css create mode 100644 plugins/admin/themes/grav/css-compiled/nucleus.css.map create mode 100644 plugins/admin/themes/grav/css-compiled/paper.css.map create mode 100644 plugins/admin/themes/grav/css-compiled/preset.css create mode 100644 plugins/admin/themes/grav/css-compiled/preset.css.map create mode 100644 plugins/admin/themes/grav/css-compiled/simple-fonts.css create mode 100644 plugins/admin/themes/grav/css-compiled/simple-fonts.css.map create mode 100644 plugins/admin/themes/grav/css-compiled/template.css create mode 100644 plugins/admin/themes/grav/css-compiled/template.css.map create mode 100644 plugins/admin/themes/grav/css/chartist.min.css create mode 100644 plugins/admin/themes/grav/css/codemirror/codemirror.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/3024-day.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/3024-night.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/abcdef.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ambiance-mobile.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ambiance.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ayu-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ayu-mirage.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/base16-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/base16-light.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/bespin.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/blackboard.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/cobalt.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/colorforth.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/darcula.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/dracula.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/duotone-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/duotone-light.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/eclipse.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/elegant.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/erlang-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/gruvbox-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/hopscotch.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/icecoder.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/idea.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/isotope.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/lesser-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/liquibyte.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/lucario.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/material-darker.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/material-ocean.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/material-palenight.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/material.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/mbo.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/mdn-like.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/midnight.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/monokai.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/moxer.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/neat.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/neo.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/night.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/nord.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/oceanic-next.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/panda-syntax.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/paper.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/paraiso-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/paraiso-light.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/pastel-on-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/railscasts.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/rubyblue.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/seti.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/shadowfox.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/solarized.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ssms.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/the-matrix.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/tomorrow-night-bright.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/tomorrow-night-eighties.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/ttcn.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/twilight.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/vibrant-ink.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/xq-dark.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/xq-light.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/yeti.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/yonce.css create mode 100644 plugins/admin/themes/grav/css/codemirror/themes/zenburn.css create mode 100644 plugins/admin/themes/grav/css/featherlight.min.css create mode 100644 plugins/admin/themes/grav/css/fork-awesome.min.css create mode 100644 plugins/admin/themes/grav/css/hint.base.min.css create mode 100644 plugins/admin/themes/grav/css/iconpicker.css create mode 100644 plugins/admin/themes/grav/css/nucleus-ie10.css create mode 100644 plugins/admin/themes/grav/css/nucleus-ie9.css create mode 100644 plugins/admin/themes/grav/css/prism.css create mode 100644 plugins/admin/themes/grav/css/pure-0.5.0/grids-min.css create mode 100644 plugins/admin/themes/grav/css/rtl.css create mode 100644 plugins/admin/themes/grav/css/selectize.min.css create mode 100644 plugins/admin/themes/grav/fonts/forkawesome-webfont.eot create mode 100644 plugins/admin/themes/grav/fonts/forkawesome-webfont.svg create mode 100644 plugins/admin/themes/grav/fonts/forkawesome-webfont.ttf create mode 100644 plugins/admin/themes/grav/fonts/forkawesome-webfont.woff create mode 100644 plugins/admin/themes/grav/fonts/forkawesome-webfont.woff2 create mode 100644 plugins/admin/themes/grav/fonts/rockettheme-apps/rockettheme-apps.eot create mode 100644 plugins/admin/themes/grav/fonts/rockettheme-apps/rockettheme-apps.svg create mode 100644 plugins/admin/themes/grav/fonts/rockettheme-apps/rockettheme-apps.ttf create mode 100644 plugins/admin/themes/grav/fonts/rockettheme-apps/rockettheme-apps.woff create mode 100644 plugins/admin/themes/grav/images/favicon.png create mode 100644 plugins/admin/themes/grav/images/grav-regular.svg create mode 100644 plugins/admin/themes/grav/images/grav-small.svg create mode 100644 plugins/admin/themes/grav/images/icons/book-edit.svg create mode 100644 plugins/admin/themes/grav/images/icons/clock-hands.svg create mode 100644 plugins/admin/themes/grav/images/icons/crown.svg create mode 100644 plugins/admin/themes/grav/images/icons/house.svg create mode 100644 plugins/admin/themes/grav/images/icons/module-four.svg create mode 100644 plugins/admin/themes/grav/images/icons/superman.svg create mode 100644 plugins/admin/themes/grav/images/icons/touchid-lock.svg create mode 100644 plugins/admin/themes/grav/images/logo.svg create mode 100644 plugins/admin/themes/grav/images/transparent.png create mode 100644 plugins/admin/themes/grav/js/admin.min.js create mode 100644 plugins/admin/themes/grav/js/form-attr.polyfill.js create mode 100644 plugins/admin/themes/grav/js/vendor.min.js create mode 100644 plugins/admin/themes/grav/package-lock.json create mode 100644 plugins/admin/themes/grav/package.json create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_base.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_breakpoints.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_core.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_layout.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_nav.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/nucleus/_typography.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/template/_base.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/template/_colors.scss create mode 100644 plugins/admin/themes/grav/scss/configuration/template/_variables.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/_core.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/_flex.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/_forms.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/_typography.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/functions/_base.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/functions/_direction.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/functions/_range.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/mixins/_base.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/mixins/_breakpoints.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/mixins/_utilities.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/particles/_align-text.scss create mode 100644 plugins/admin/themes/grav/scss/nucleus/particles/_visibility.scss create mode 100644 plugins/admin/themes/grav/scss/preset.scss create mode 100644 plugins/admin/themes/grav/scss/simple-fonts.scss create mode 100644 plugins/admin/themes/grav/scss/template.scss create mode 100644 plugins/admin/themes/grav/scss/template/_admin.scss create mode 100644 plugins/admin/themes/grav/scss/template/_buttons.scss create mode 100644 plugins/admin/themes/grav/scss/template/_changelog.scss create mode 100644 plugins/admin/themes/grav/scss/template/_colors.scss create mode 100644 plugins/admin/themes/grav/scss/template/_core.scss create mode 100644 plugins/admin/themes/grav/scss/template/_custom.scss create mode 100644 plugins/admin/themes/grav/scss/template/_dropzone.scss create mode 100644 plugins/admin/themes/grav/scss/template/_editor.scss create mode 100644 plugins/admin/themes/grav/scss/template/_errors.scss create mode 100644 plugins/admin/themes/grav/scss/template/_extensions.scss create mode 100644 plugins/admin/themes/grav/scss/template/_fonts.scss create mode 100644 plugins/admin/themes/grav/scss/template/_forms.scss create mode 100644 plugins/admin/themes/grav/scss/template/_gpm.scss create mode 100644 plugins/admin/themes/grav/scss/template/_header.scss create mode 100644 plugins/admin/themes/grav/scss/template/_horizontal-scroll.scss create mode 100644 plugins/admin/themes/grav/scss/template/_jqcron.scss create mode 100644 plugins/admin/themes/grav/scss/template/_login.scss create mode 100644 plugins/admin/themes/grav/scss/template/_media.scss create mode 100644 plugins/admin/themes/grav/scss/template/_nav-toggle.scss create mode 100644 plugins/admin/themes/grav/scss/template/_notifications.scss create mode 100644 plugins/admin/themes/grav/scss/template/_pages.scss create mode 100644 plugins/admin/themes/grav/scss/template/_phpinfo.scss create mode 100644 plugins/admin/themes/grav/scss/template/_remodal.scss create mode 100644 plugins/admin/themes/grav/scss/template/_scrollbars.scss create mode 100644 plugins/admin/themes/grav/scss/template/_tables.scss create mode 100644 plugins/admin/themes/grav/scss/template/_tabs.scss create mode 100644 plugins/admin/themes/grav/scss/template/_toastr.scss create mode 100644 plugins/admin/themes/grav/scss/template/_tools.scss create mode 100644 plugins/admin/themes/grav/scss/template/_typography.scss create mode 100644 plugins/admin/themes/grav/scss/template/_utilities.scss create mode 100644 plugins/admin/themes/grav/scss/template/_whitelabel.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_base.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_bourbon_essentials.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_buttons.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_colorpicker.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_datetimepicker.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_finderjs.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_input-range.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_scrollbars.scss create mode 100644 plugins/admin/themes/grav/scss/template/modules/_toggle-switch.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/_bourbon-deprecated-upcoming.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/_bourbon.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_button.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_clearfix.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_directional-values.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_ellipsis.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_font-family.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_hide-text.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_html5-input-types.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_position.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_prefixer.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_rem.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_retina-image.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_size.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_timing-functions.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_triangle.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/addons/_word-wrap.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_animation.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_appearance.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_backface-visibility.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_background-image.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_background.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_border-image.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_border-radius.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_box-sizing.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_calc.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_columns.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_filter.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_flex-box.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_font-face.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_font-feature-settings.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_hidpi-media-query.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_hyphens.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_image-rendering.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_keyframes.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_linear-gradient.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_perspective.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_placeholder.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_radial-gradient.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_transform.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_transition.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/css3/_user-select.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_assign.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_color-lightness.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_flex-grid.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_golden-ratio.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_grid-width.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_modular-scale.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_px-to-em.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_px-to-rem.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_strip-units.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_tint-shade.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_transition-property-name.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/functions/_unpack.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_convert-units.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_gradient-positions-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_is-num.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_linear-angle-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_linear-gradient-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_linear-positions-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_linear-side-corner-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_radial-arg-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_radial-gradient-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_radial-positions-parser.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_render-gradients.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_shape-size-stripper.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/helpers/_str-to-num.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/settings/_prefixer.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/bourbon/settings/_px-to-em.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/_color-schemer.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_cmyk.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_color-adjustments.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_color-schemer.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_colorblind.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_comparison.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_equalize.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_harmonize.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_interpolation.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_mix.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_mixins.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_ryb.scss create mode 100644 plugins/admin/themes/grav/scss/vendor/color-schemer/color-schemer/_tint-shade.scss create mode 100644 plugins/admin/themes/grav/templates/changelog.html.twig create mode 100644 plugins/admin/themes/grav/templates/config.html.twig create mode 100644 plugins/admin/themes/grav/templates/dashboard.html.twig create mode 100644 plugins/admin/themes/grav/templates/default.json.twig create mode 100644 plugins/admin/themes/grav/templates/denied.html.twig create mode 100644 plugins/admin/themes/grav/templates/email/base.html.twig create mode 100644 plugins/admin/themes/grav/templates/empty.html.twig create mode 100644 plugins/admin/themes/grav/templates/error.html.twig create mode 100644 plugins/admin/themes/grav/templates/error.json.twig create mode 100644 plugins/admin/themes/grav/templates/forgot.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/field.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/acl_picker/acl_picker.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/array/array.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/backupshistory/backupshistory.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/blueprint/blueprint.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/codemirror/codemirror.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/colorpicker/colorpicker.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/colorscheme.color/colorscheme.color.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/colorscheme/colorscheme.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/column/column.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/columns/columns.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/cron/cron.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/cronstatus/cronstatus.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/dateformat/dateformat.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/datetime/datetime.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/editor/editor.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/fieldset/fieldset.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/file/file.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/filepicker/filepicker.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/folder-slug/folder-slug.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/frontmatter/frontmatter.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/iconpicker/iconpicker.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/iconpicker/icons.yaml create mode 100644 plugins/admin/themes/grav/templates/forms/fields/list/list.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/markdown/markdown.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/mediapicker/mediapicker.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/multilevel/multilevel.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/order/order.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/pagemedia/pagemedia.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/pagemediaselect/pagemediaselect.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/pages/pages.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/parents/parents.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/permissions/permissions.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/range/range.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/section/section.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/selectize/selectize.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/selectunique/selectunique.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/taxonomy/taxonomy.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/themepreview/themepreview.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/themeselect/themeselect.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/userinfo/userinfo.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/widgets/widgets.html.twig create mode 100644 plugins/admin/themes/grav/templates/forms/fields/xss/xss.html.twig create mode 100644 plugins/admin/themes/grav/templates/installer.html.twig create mode 100644 plugins/admin/themes/grav/templates/login.html.twig create mode 100644 plugins/admin/themes/grav/templates/media-list-content.html.twig create mode 100644 plugins/admin/themes/grav/templates/pages.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/backups-button.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/base-root.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/base.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/blueprints-copy.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/blueprints-new-folder.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/blueprints-new.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/blueprints-raw.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/blueprints.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-feed.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-maintenance.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-notifications.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-pages.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-problems.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/dashboard-statistics.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/feed-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/footer.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/header.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/javascript-config.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/javascripts.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/list-sort.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/login-form.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/login-logo.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/login-logout.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/login-twofa.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/login.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/logo.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/media-list-wrapper.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/media-list-wrapper__list.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/media-list-wrapper__list__filters.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/media-list-wrapper__sidebar.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/messages.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-add-package.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-changelog.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-changes-detected.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-reinstall-package.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-remove-package.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-switch-theme.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/modal-update-packages.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/nav-quick-tray.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/nav-toggle.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/nav-user-avatar.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/nav-user-details.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/nav.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/notification-dashboard-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/notification-feed-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/notification-plugins-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/notification-themes-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/notification-top-block.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/page-children.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/page-legend.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/page-move.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/plugin-data.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/plugins-details.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/plugins-list.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/register.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/release-toggle.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/spinning-wheel.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/stylesheets.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/theme.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/themes-details.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/themes-list.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-backups-titlebar.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-backups.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-direct-install.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-logs.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-reports.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-scheduler-titlebar.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/tools-scheduler.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/userinfo-avatar-credit.html.twig create mode 100644 plugins/admin/themes/grav/templates/partials/userinfo-avatar.html.twig create mode 100644 plugins/admin/themes/grav/templates/plugins.html.twig create mode 100644 plugins/admin/themes/grav/templates/plugins/admin-buttons.html.twig create mode 100644 plugins/admin/themes/grav/templates/preview.html.twig create mode 100644 plugins/admin/themes/grav/templates/register.html.twig create mode 100644 plugins/admin/themes/grav/templates/reports/security.html.twig create mode 100644 plugins/admin/themes/grav/templates/reports/yamllinter.html.twig create mode 100644 plugins/admin/themes/grav/templates/reset.html.twig create mode 100644 plugins/admin/themes/grav/templates/statistics.html.twig create mode 100644 plugins/admin/themes/grav/templates/themes.html.twig create mode 100644 plugins/admin/themes/grav/templates/tools.html.twig create mode 100644 plugins/admin/themes/grav/templates/unauthorized.html.twig create mode 100644 plugins/admin/themes/grav/templates/user.html.twig create mode 100644 plugins/admin/themes/grav/theme.yaml create mode 100644 plugins/admin/themes/grav/watch.sh create mode 100644 plugins/admin/themes/grav/webpack.conf.js create mode 100644 plugins/admin/themes/grav/yarn.lock create mode 100644 plugins/admin/twig/AdminTwigExtension.php create mode 100644 plugins/admin/vendor/autoload.php create mode 100644 plugins/admin/vendor/bin/picofeed create mode 100644 plugins/admin/vendor/bin/pscss create mode 100644 plugins/admin/vendor/composer/ClassLoader.php create mode 100644 plugins/admin/vendor/composer/InstalledVersions.php create mode 100644 plugins/admin/vendor/composer/LICENSE create mode 100644 plugins/admin/vendor/composer/autoload_classmap.php create mode 100644 plugins/admin/vendor/composer/autoload_files.php create mode 100644 plugins/admin/vendor/composer/autoload_namespaces.php create mode 100644 plugins/admin/vendor/composer/autoload_psr4.php create mode 100644 plugins/admin/vendor/composer/autoload_real.php create mode 100644 plugins/admin/vendor/composer/autoload_static.php create mode 100644 plugins/admin/vendor/composer/installed.json create mode 100644 plugins/admin/vendor/composer/installed.php create mode 100644 plugins/admin/vendor/composer/platform_check.php create mode 100644 plugins/admin/vendor/laminas/laminas-xml/.github/workflows/continuous-integration.yml create mode 100644 plugins/admin/vendor/laminas/laminas-xml/.github/workflows/release-on-milestone-closed.yml create mode 100644 plugins/admin/vendor/laminas/laminas-xml/COPYRIGHT.md create mode 100644 plugins/admin/vendor/laminas/laminas-xml/LICENSE.md create mode 100644 plugins/admin/vendor/laminas/laminas-xml/README.md create mode 100644 plugins/admin/vendor/laminas/laminas-xml/composer.json create mode 100644 plugins/admin/vendor/laminas/laminas-xml/composer.lock create mode 100644 plugins/admin/vendor/laminas/laminas-xml/src/Exception/ExceptionInterface.php create mode 100644 plugins/admin/vendor/laminas/laminas-xml/src/Exception/InvalidArgumentException.php create mode 100644 plugins/admin/vendor/laminas/laminas-xml/src/Exception/RuntimeException.php create mode 100644 plugins/admin/vendor/laminas/laminas-xml/src/Security.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/.github/FUNDING.yml create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/.github/workflows/continuous-integration.yml create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/.github/workflows/release-on-milestone-closed.yml create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/.laminas-ci.json create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/LICENSE.md create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/README.md create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/composer.json create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/composer.lock create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/config/replacements.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/psalm-baseline.xml create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/psalm.xml.dist create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/Module.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/Replacements.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php create mode 100644 plugins/admin/vendor/laminas/laminas-zendframework-bridge/src/autoload.php create mode 100644 plugins/admin/vendor/p3k/picofeed/LICENSE create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Base.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/Client.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/ClientException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/Curl.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/ForbiddenException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/HttpHeaders.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/InvalidUrlException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/MaxRedirectException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/MaxSizeException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/Stream.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/TimeoutException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/UnauthorizedException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Client/Url.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Config/Config.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Encoding/Encoding.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Filter/Attribute.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Filter/Filter.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Filter/Html.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Filter/Tag.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Generator/ContentGeneratorInterface.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Generator/FileContentGenerator.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Generator/YoutubeContentGenerator.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Logging/Logger.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Atom.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/DateParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Feed.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Item.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Parser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/ParserException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/ParserInterface.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss10.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss20.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss91.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss92.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/XmlEntityException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/XmlParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/PicoFeedException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ContentFilterProcessor.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ScraperProcessor.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Favicon.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Reader.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/ReaderException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/SubscriptionNotFoundException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/UnsupportedFeedFormatException.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.blog.lemonde.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.blogs.nytimes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.igen.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.nytimes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.over-blog.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.phoronix.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.slate.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.theguardian.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.wikipedia.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.wired.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/.wsj.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/01net.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/24.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/444.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/888.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/abstrusegoose.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/achgut.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/adventuregamers.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/alainonline.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/aljazeera.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allafrica.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allgemeine-zeitung.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/amazingsuperpowers.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/anythingcomic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ap.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/areadvd.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/arstechnica.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/atv.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/awkwardzombie.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/backchannel.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bangkokpost.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bauerwilli.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bgr.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigfootjustice.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigpicture.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bizjournals.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/biztimes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bleepingcomputer.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.fefe.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.mapillary.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/brewers.mlb.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buenosairesherald.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bunicomic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buttersafe.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cad-comic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chaoslife.findchaos.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chinafile.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cicero.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cliquerefresh.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cnet.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/coinwelt.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/consomac.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cowbirdsinlove.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/crash.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/csmonitor.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyjs.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyreporter.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailytech.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/degroupnews.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/derstandard.at.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dilbert.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/discovermagazine.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/distrowatch.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dozodomo.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/drawingboardcomic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/e-w-e.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/economist.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/encyclopedie.naheulbeuk.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/endlessorigami.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/engadget.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/escapistmagazine.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/espn.go.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/exocomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/explosm.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/extrafabulouscomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/factroom.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcodesign.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcoexist.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcompany.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ffworld.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/foreignpolicy.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fossbytes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fototelegraf.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fowllanguagecomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamechannel.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamestar.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geek.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geektimes.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gerbilwithajetpack.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/giantitp.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/github.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gocomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/golem.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gondola.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gorabbit.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/habrahabr.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/happletea.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hardware.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/heise.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hirek.prim.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hotshowlife.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/huffingtonpost.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hvg.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/idokep.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/imogenquest.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/index.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/indiehaven.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/inforadio.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ing.dk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/invisiblebread.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ir.amd.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantimes.co.jp.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantoday.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/journaldugeek.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/jsonline.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/justcoolidea.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kanpai.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/karriere.jobfinder.dk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kisalfold.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kiszamolo.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kodi.tv.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreaherald.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreatimes.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lastplacecomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/legorafi.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lejapon.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lesjoiesducode.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lfg.co.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux-magazin.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linuxinsider.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lists.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loadingartist.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loldwell.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lukesurl.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/macg.co.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maclife.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/magyarkurir.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marc.info.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marriedtothesea.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marycagle.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maximumble.thebookofbiff.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/medium.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mercworks.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/metronieuws.nl.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/milwaukeenns.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mno.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mokepon.smackjeeves.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monandroid.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monwindows.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/moya-planeta.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mrlovenstein.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/muckrock.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mynorthshorenow.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nakedCapitalism.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nasa.gov.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nat-geo.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nationaljournal.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nature.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nba.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nedroid.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/networkworld.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/neustadt-ticker.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nextinpact.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/niceteethcomic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nichtlustig.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nlcafe.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/novo-argumente.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/oglaf.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleLoader.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php create mode 100644 plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php create mode 100644 plugins/admin/vendor/p3k/picofeed/picofeed create mode 100644 plugins/admin/vendor/scssphp/scssphp/LICENSE.md create mode 100644 plugins/admin/vendor/scssphp/scssphp/README.md create mode 100644 plugins/admin/vendor/scssphp/scssphp/bin/pscss create mode 100644 plugins/admin/vendor/scssphp/scssphp/composer.json create mode 100644 plugins/admin/vendor/scssphp/scssphp/phpcs.xml.dist create mode 100644 plugins/admin/vendor/scssphp/scssphp/scss.inc.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Base/Range.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Block.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Cache.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Colors.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Compiler.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/SassScriptException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Exception/ServerException.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Logger/QuietLogger.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Logger/StreamLogger.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Node.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Parser.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Type.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Util.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/ValueConverter.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Version.php create mode 100644 plugins/admin/vendor/scssphp/scssphp/src/Warn.php create mode 100644 plugins/anchors/.idea/vcs.xml create mode 100644 plugins/anchors/CHANGELOG.md create mode 100644 plugins/anchors/LICENSE create mode 100644 plugins/anchors/README.md create mode 100644 plugins/anchors/anchors.php create mode 100644 plugins/anchors/anchors.yaml create mode 100644 plugins/anchors/blueprints.yaml create mode 100644 plugins/anchors/hebe.json create mode 100644 plugins/anchors/js/anchor.min.js create mode 100644 plugins/anchors/js/clipboard.min.js create mode 100644 plugins/anchors/twig/AnchorsTwigExtension.php create mode 100644 plugins/archives/CHANGELOG.md create mode 100644 plugins/archives/LICENSE create mode 100644 plugins/archives/README.md create mode 100644 plugins/archives/archives.php create mode 100644 plugins/archives/archives.yaml create mode 100644 plugins/archives/assets/readme_1.png create mode 100644 plugins/archives/blueprints.yaml create mode 100644 plugins/archives/composer.json create mode 100644 plugins/archives/composer.lock create mode 100644 plugins/archives/templates/partials/archives.html.twig create mode 100644 plugins/archives/vendor/autoload.php create mode 100644 plugins/archives/vendor/composer/ClassLoader.php create mode 100644 plugins/archives/vendor/composer/LICENSE create mode 100644 plugins/archives/vendor/composer/autoload_classmap.php create mode 100644 plugins/archives/vendor/composer/autoload_namespaces.php create mode 100644 plugins/archives/vendor/composer/autoload_psr4.php create mode 100644 plugins/archives/vendor/composer/autoload_real.php create mode 100644 plugins/archives/vendor/composer/autoload_static.php create mode 100644 plugins/archives/vendor/composer/installed.json create mode 100644 plugins/aura-authors/.gitattributes create mode 100644 plugins/aura-authors/CHANGELOG.md create mode 100644 plugins/aura-authors/LICENSE create mode 100644 plugins/aura-authors/README.md create mode 100644 plugins/aura-authors/assets/demo.jpg create mode 100644 plugins/aura-authors/assets/fonts/icomoon.eot create mode 100644 plugins/aura-authors/assets/fonts/icomoon.svg create mode 100644 plugins/aura-authors/assets/fonts/icomoon.ttf create mode 100644 plugins/aura-authors/assets/fonts/icomoon.woff create mode 100644 plugins/aura-authors/assets/style.min.css create mode 100644 plugins/aura-authors/assets/style.min.css.map create mode 100644 plugins/aura-authors/assets/style.scss create mode 100644 plugins/aura-authors/aura-authors.php create mode 100644 plugins/aura-authors/aura-authors.yaml create mode 100755 plugins/aura-authors/blueprints.yaml create mode 100644 plugins/aura-authors/blueprints/default.yaml create mode 100644 plugins/aura-authors/templates/partials/author-bio.html.twig create mode 100644 plugins/comments/CHANGELOG.md create mode 100644 plugins/comments/README.md create mode 100644 plugins/comments/admin/pages/comments.md create mode 100644 plugins/comments/admin/templates/comments.html.twig create mode 100644 plugins/comments/blueprints.yaml create mode 100644 plugins/comments/comments.php create mode 100644 plugins/comments/comments.yaml create mode 100644 plugins/comments/languages.yaml create mode 100644 plugins/comments/templates/partials/comments.html.twig create mode 100644 plugins/custom-css/CHANGELOG.md create mode 100644 plugins/custom-css/LICENSE create mode 100644 plugins/custom-css/README.md create mode 100644 plugins/custom-css/blueprints.yaml create mode 100644 plugins/custom-css/custom-css.php create mode 100644 plugins/custom-css/custom-css.yaml create mode 100644 plugins/custom-css/languages.yaml create mode 100644 plugins/email/CHANGELOG.md create mode 100644 plugins/email/LICENSE create mode 100644 plugins/email/README.md create mode 100644 plugins/email/blueprints.yaml create mode 100644 plugins/email/classes/Email.php create mode 100644 plugins/email/classes/Utils.php create mode 100644 plugins/email/cli/ClearQueueFailuresCommand.php create mode 100644 plugins/email/cli/FlushQueueCommand.php create mode 100644 plugins/email/cli/TestEmailCommand.php create mode 100644 plugins/email/composer.json create mode 100644 plugins/email/composer.lock create mode 100644 plugins/email/email.php create mode 100644 plugins/email/email.yaml create mode 100644 plugins/email/hebe.json create mode 100644 plugins/email/languages.yaml create mode 100644 plugins/email/templates/email/base.html.twig create mode 100644 plugins/email/vendor/autoload.php create mode 100644 plugins/email/vendor/composer/ClassLoader.php create mode 100644 plugins/email/vendor/composer/InstalledVersions.php create mode 100644 plugins/email/vendor/composer/LICENSE create mode 100644 plugins/email/vendor/composer/autoload_classmap.php create mode 100644 plugins/email/vendor/composer/autoload_files.php create mode 100644 plugins/email/vendor/composer/autoload_namespaces.php create mode 100644 plugins/email/vendor/composer/autoload_psr4.php create mode 100644 plugins/email/vendor/composer/autoload_real.php create mode 100644 plugins/email/vendor/composer/autoload_static.php create mode 100644 plugins/email/vendor/composer/installed.json create mode 100644 plugins/email/vendor/composer/installed.php create mode 100644 plugins/email/vendor/composer/platform_check.php create mode 100644 plugins/email/vendor/doctrine/lexer/LICENSE create mode 100644 plugins/email/vendor/doctrine/lexer/README.md create mode 100644 plugins/email/vendor/doctrine/lexer/composer.json create mode 100644 plugins/email/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php create mode 100644 plugins/email/vendor/egulias/email-validator/LICENSE create mode 100644 plugins/email/vendor/egulias/email-validator/composer.json create mode 100644 plugins/email/vendor/egulias/email-validator/src/EmailLexer.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/EmailParser.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/EmailValidator.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/AtextAfterCFWS.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/CRLFAtTheEnd.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/CRLFX2.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/CRNoLF.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/CharNotAllowed.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/CommaInDomain.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ConsecutiveAt.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ConsecutiveDot.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/DomainAcceptsNoMail.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/DomainHyphened.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/DotAtEnd.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/DotAtStart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingAT.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingATEXT.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingCTEXT.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingDTEXT.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingDomainLiteralClose.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/ExpectingQPair.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/InvalidEmail.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/LocalOrReservedDomain.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/NoDNSRecord.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/NoDomainPart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/NoLocalPart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/UnclosedComment.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/UnclosedQuotedString.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Exception/UnopenedComment.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Parser/DomainPart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Parser/LocalPart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Parser/Parser.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/DNSCheckValidation.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/EmailValidation.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/Error/RFCWarnings.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/Error/SpoofEmail.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/MultipleErrors.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/RFCValidation.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Validation/SpoofCheckValidation.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/AddressLiteral.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/CFWSNearAt.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/CFWSWithFWS.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/Comment.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/DeprecatedComment.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/DomainLiteral.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/DomainTooLong.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/EmailTooLong.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6BadChar.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6ColonEnd.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6ColonStart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6Deprecated.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6DoubleColon.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6GroupCount.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/IPV6MaxGroups.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/LabelTooLong.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/LocalTooLong.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/NoDNSMXRecord.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/ObsoleteDTEXT.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/QuotedPart.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/QuotedString.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/TLD.php create mode 100644 plugins/email/vendor/egulias/email-validator/src/Warning/Warning.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.gitattributes create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.github/ISSUE_TEMPLATE.md create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.gitignore create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.php_cs.dist create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/.travis.yml create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/CHANGES create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/LICENSE create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/README.md create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/composer.json create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/headers.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/index.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/introduction.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/japanese.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/messages.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/plugins.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/doc/sending.rst create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder/IdnAddressEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder/Utf8AddressEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoderException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ConfigurableSpool.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandEvent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/Event.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventObject.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendEvent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/IdGenerator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Image.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/IoException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/OpenDKIMHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/IdGenerator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Logger.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Timer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Preferences.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/RfcComplianceException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/BodySigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Spool.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/EightBitMimeHandler.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/SmtpUtf8Handler.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/mime_types.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/preferences.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/swift_required.php create mode 100644 plugins/email/vendor/swiftmailer/swiftmailer/lib/swiftmailer_generate_mimes_config.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Iconv.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/LICENSE create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/README.md create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.big5.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp037.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1006.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1026.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp424.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp437.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp500.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp737.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp775.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp850.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp852.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp855.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp856.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp857.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp860.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp861.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp862.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp863.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp864.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp865.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp866.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp869.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp874.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp875.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp932.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp936.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp949.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.cp950.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-1.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-10.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-11.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-13.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-14.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-15.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-16.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-2.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-3.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-4.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-5.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-6.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-7.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-8.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-9.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-r.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-u.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.us-ascii.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1250.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1251.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1252.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1253.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1254.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1255.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1256.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1257.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1258.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/Resources/charset/translit.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/bootstrap.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/bootstrap80.php create mode 100644 plugins/email/vendor/symfony/polyfill-iconv/composer.json create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Idn.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Info.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/LICENSE create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/README.md create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/bootstrap.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/bootstrap80.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-idn/composer.json create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/LICENSE create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Normalizer.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/README.md create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/bootstrap.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php create mode 100644 plugins/email/vendor/symfony/polyfill-intl-normalizer/composer.json create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/README.md create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/bootstrap80.php create mode 100644 plugins/email/vendor/symfony/polyfill-mbstring/composer.json create mode 100644 plugins/email/vendor/symfony/polyfill-php72/LICENSE create mode 100644 plugins/email/vendor/symfony/polyfill-php72/Php72.php create mode 100644 plugins/email/vendor/symfony/polyfill-php72/README.md create mode 100644 plugins/email/vendor/symfony/polyfill-php72/bootstrap.php create mode 100644 plugins/email/vendor/symfony/polyfill-php72/composer.json create mode 100644 plugins/error/.gitignore create mode 100644 plugins/error/CHANGELOG.md create mode 100644 plugins/error/LICENSE create mode 100644 plugins/error/README.md create mode 100644 plugins/error/assets/readme_1.png create mode 100644 plugins/error/blueprints.yaml create mode 100644 plugins/error/cli/LogCommand.php create mode 100644 plugins/error/composer.json create mode 100644 plugins/error/error.php create mode 100644 plugins/error/error.yaml create mode 100644 plugins/error/hebe.json create mode 100644 plugins/error/languages.yaml create mode 100644 plugins/error/pages/error.md create mode 100644 plugins/error/templates/error.html.twig create mode 100644 plugins/error/templates/error.json.twig create mode 100644 plugins/error/vendor/autoload.php create mode 100644 plugins/error/vendor/composer/ClassLoader.php create mode 100644 plugins/error/vendor/composer/LICENSE create mode 100644 plugins/error/vendor/composer/autoload_classmap.php create mode 100644 plugins/error/vendor/composer/autoload_namespaces.php create mode 100644 plugins/error/vendor/composer/autoload_psr4.php create mode 100644 plugins/error/vendor/composer/autoload_real.php create mode 100644 plugins/error/vendor/composer/autoload_static.php create mode 100644 plugins/error/vendor/composer/installed.json create mode 100644 plugins/feed/CHANGELOG.md create mode 100644 plugins/feed/LICENSE create mode 100644 plugins/feed/README.md create mode 100644 plugins/feed/assets/readme_1.png create mode 100644 plugins/feed/blueprints.yaml create mode 100644 plugins/feed/blueprints/feed.yaml create mode 100644 plugins/feed/composer.json create mode 100644 plugins/feed/composer.lock create mode 100644 plugins/feed/feed.php create mode 100644 plugins/feed/feed.yaml create mode 100644 plugins/feed/templates/feed.atom.twig create mode 100644 plugins/feed/templates/feed.json.twig create mode 100644 plugins/feed/templates/feed.rss.twig create mode 100644 plugins/feed/vendor/autoload.php create mode 100644 plugins/feed/vendor/composer/ClassLoader.php create mode 100644 plugins/feed/vendor/composer/InstalledVersions.php create mode 100644 plugins/feed/vendor/composer/LICENSE create mode 100644 plugins/feed/vendor/composer/autoload_classmap.php create mode 100644 plugins/feed/vendor/composer/autoload_namespaces.php create mode 100644 plugins/feed/vendor/composer/autoload_psr4.php create mode 100644 plugins/feed/vendor/composer/autoload_real.php create mode 100644 plugins/feed/vendor/composer/autoload_static.php create mode 100644 plugins/feed/vendor/composer/installed.json create mode 100644 plugins/feed/vendor/composer/installed.php create mode 100644 plugins/flex-objects/.eslintrc create mode 100644 plugins/flex-objects/.gitignore create mode 100644 plugins/flex-objects/CHANGELOG.md create mode 100644 plugins/flex-objects/LICENSE create mode 100644 plugins/flex-objects/README.md create mode 100644 plugins/flex-objects/admin/pages/flex-objects.md create mode 100644 plugins/flex-objects/admin/templates/flex-objects.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects.json.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/layouts/404.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/layouts/accounts/partials/top.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/add.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/back.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/configuration.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/delete.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export-csv.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/languages.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview-open.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/save.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/configure.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/edit.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/list/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/list/list_actions.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/modals/remove.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/preview.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/configure.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/edit.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/preview.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/types.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/default/types.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/add.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/back.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/copy.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/delete.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/move.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-child.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-next.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-parent.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-prev.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/preview.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/save.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/edit.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/list/columns.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/list/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/pages/preview.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/configure.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/edit.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/user-groups/configure.html.twig create mode 100644 plugins/flex-objects/admin/templates/flex-objects/types/user-groups/list.html.twig create mode 100644 plugins/flex-objects/admin/templates/forms/fields/flex-objects/flex-objects.html.twig create mode 100644 plugins/flex-objects/admin/templates/forms/fields/save-redirect/save-redirect.html.twig create mode 100644 plugins/flex-objects/app/columns/finder.js create mode 100644 plugins/flex-objects/app/columns/index.js create mode 100644 plugins/flex-objects/app/filters/index.js create mode 100644 plugins/flex-objects/app/filters/panel.js create mode 100644 plugins/flex-objects/app/list/App.vue create mode 100644 plugins/flex-objects/app/list/VuetableCssConfig.js create mode 100644 plugins/flex-objects/app/list/components/ContentLoader.vue create mode 100644 plugins/flex-objects/app/list/components/FilterBar.vue create mode 100644 plugins/flex-objects/app/list/components/Table.vue create mode 100644 plugins/flex-objects/app/list/index.js create mode 100644 plugins/flex-objects/app/main.js create mode 100644 plugins/flex-objects/app/utils/finder.js create mode 100644 plugins/flex-objects/app/utils/get-filters.js create mode 100644 plugins/flex-objects/app/utils/indeterminate.js create mode 100644 plugins/flex-objects/assets/flex-objects-directory.png create mode 100644 plugins/flex-objects/assets/flex-objects-edit.png create mode 100644 plugins/flex-objects/assets/flex-objects-list.png create mode 100644 plugins/flex-objects/assets/flex-objects-options.png create mode 100644 plugins/flex-objects/assets/flex-objects-site.png create mode 100644 plugins/flex-objects/blueprints.yaml create mode 100644 plugins/flex-objects/blueprints/flex-objects.yaml create mode 100644 plugins/flex-objects/blueprints/flex-objects/contacts.yaml create mode 100644 plugins/flex-objects/blueprints/flex-objects/pages.yaml create mode 100644 plugins/flex-objects/blueprints/flex-objects/user-accounts.yaml create mode 100644 plugins/flex-objects/blueprints/flex-objects/user-groups.yaml create mode 100644 plugins/flex-objects/blueprints/pages/flex-objects.yaml create mode 100644 plugins/flex-objects/classes/Admin/AdminController.php create mode 100644 plugins/flex-objects/classes/Controllers/AbstractController.php create mode 100644 plugins/flex-objects/classes/Controllers/MediaController.php create mode 100644 plugins/flex-objects/classes/Controllers/ObjectController.php create mode 100644 plugins/flex-objects/classes/Flex.php create mode 100644 plugins/flex-objects/classes/FlexFormFactory.php create mode 100644 plugins/flex-objects/classes/FlexRouter.php create mode 100644 plugins/flex-objects/classes/Table/DataTable.php create mode 100644 plugins/flex-objects/cli/FlexConvertDataCommand.php create mode 100644 plugins/flex-objects/composer.json create mode 100644 plugins/flex-objects/composer.lock create mode 100644 plugins/flex-objects/css/admin.css create mode 100644 plugins/flex-objects/css/admin.css.map create mode 100644 plugins/flex-objects/css/admin.min.css create mode 100644 plugins/flex-objects/css/site.css create mode 100644 plugins/flex-objects/css/site.css.map create mode 100644 plugins/flex-objects/css/site.min.css create mode 100644 plugins/flex-objects/data/flex-objects/contacts.json create mode 100644 plugins/flex-objects/flex-objects.php create mode 100644 plugins/flex-objects/flex-objects.yaml create mode 100644 plugins/flex-objects/js/flex-objects.js create mode 100644 plugins/flex-objects/js/list.min.js create mode 100644 plugins/flex-objects/languages/de.yaml create mode 100644 plugins/flex-objects/languages/en.yaml create mode 100644 plugins/flex-objects/languages/ru.yaml create mode 100644 plugins/flex-objects/package.json create mode 100644 plugins/flex-objects/permissions.yaml create mode 100644 plugins/flex-objects/scss/_preset.scss create mode 100644 plugins/flex-objects/scss/admin.scss create mode 100644 plugins/flex-objects/scss/plugin/_admin.scss create mode 100644 plugins/flex-objects/scss/plugin/_site.scss create mode 100644 plugins/flex-objects/scss/site.scss create mode 100644 plugins/flex-objects/templates/flex-edit.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/directories/default.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/page.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/views/404.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/views/directories.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/views/directory.html.twig create mode 100644 plugins/flex-objects/templates/flex-objects/views/object.html.twig create mode 100644 plugins/flex-objects/templates/flex/contacts/collection/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/contacts/object/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/contacts/object/list-default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-accounts/collection/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-accounts/object/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-accounts/object/list-default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-groups/collection/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-groups/object/default.html.twig create mode 100644 plugins/flex-objects/templates/flex/user-groups/object/list-default.html.twig create mode 100644 plugins/flex-objects/templates/forms/fields/filepicker/filepicker.html.twig create mode 100644 plugins/flex-objects/templates/forms/fields/list/list.html.twig create mode 100644 plugins/flex-objects/templates/forms/fields/pagemedia/pagemedia.html.twig create mode 100644 plugins/flex-objects/templates/forms/fields/pagemedia/template.html.twig create mode 100644 plugins/flex-objects/vendor/autoload.php create mode 100644 plugins/flex-objects/vendor/composer/ClassLoader.php create mode 100644 plugins/flex-objects/vendor/composer/InstalledVersions.php create mode 100644 plugins/flex-objects/vendor/composer/LICENSE create mode 100644 plugins/flex-objects/vendor/composer/autoload_classmap.php create mode 100644 plugins/flex-objects/vendor/composer/autoload_namespaces.php create mode 100644 plugins/flex-objects/vendor/composer/autoload_psr4.php create mode 100644 plugins/flex-objects/vendor/composer/autoload_real.php create mode 100644 plugins/flex-objects/vendor/composer/autoload_static.php create mode 100644 plugins/flex-objects/vendor/composer/installed.json create mode 100644 plugins/flex-objects/vendor/composer/installed.php create mode 100644 plugins/flex-objects/vendor/composer/platform_check.php create mode 100644 plugins/flex-objects/watch.sh create mode 100644 plugins/flex-objects/webpack.conf.js create mode 100644 plugins/flex-objects/yarn.lock create mode 100644 plugins/form/.eslintrc create mode 100644 plugins/form/.gitignore create mode 100644 plugins/form/CHANGELOG.md create mode 100644 plugins/form/LICENSE create mode 100644 plugins/form/README.md create mode 100644 plugins/form/app/fields/array.js create mode 100644 plugins/form/app/fields/file.js create mode 100644 plugins/form/app/fields/form.js create mode 100644 plugins/form/app/fields/index.js create mode 100644 plugins/form/app/fields/media.js create mode 100644 plugins/form/app/fields/tabs.js create mode 100644 plugins/form/app/main.js create mode 100644 plugins/form/app/utils/keep-alive.js create mode 100644 plugins/form/assets/dropzone.min.css create mode 100644 plugins/form/assets/form-styles.css create mode 100644 plugins/form/assets/form-styles.min.css create mode 100644 plugins/form/assets/form.min.js create mode 100644 plugins/form/assets/form.vendor.js create mode 100644 plugins/form/assets/object.assign.polyfill.js create mode 100644 plugins/form/assets/signature_pad.js create mode 100644 plugins/form/blueprints.yaml create mode 100644 plugins/form/classes/Form.php create mode 100644 plugins/form/classes/FormFactory.php create mode 100644 plugins/form/classes/Forms.php create mode 100644 plugins/form/classes/TwigExtension.php create mode 100644 plugins/form/composer.json create mode 100644 plugins/form/composer.lock create mode 100644 plugins/form/form.php create mode 100644 plugins/form/form.yaml create mode 100644 plugins/form/gulpfile.js create mode 100644 plugins/form/hebe.json create mode 100644 plugins/form/languages.yaml create mode 100644 plugins/form/package.json create mode 100644 plugins/form/scss/form-styles.scss create mode 100644 plugins/form/templates/form-messages.html.twig create mode 100644 plugins/form/templates/form-messages.json.twig create mode 100644 plugins/form/templates/form.html.twig create mode 100644 plugins/form/templates/form.json.twig create mode 100644 plugins/form/templates/formdata.html.twig create mode 100644 plugins/form/templates/forms/ajax.json.twig create mode 100644 plugins/form/templates/forms/data.html.twig create mode 100644 plugins/form/templates/forms/data.txt.twig create mode 100644 plugins/form/templates/forms/default/data.html.twig create mode 100644 plugins/form/templates/forms/default/data.txt.twig create mode 100644 plugins/form/templates/forms/default/field.html.twig create mode 100644 plugins/form/templates/forms/default/fields.html.twig create mode 100644 plugins/form/templates/forms/default/form.html.twig create mode 100644 plugins/form/templates/forms/default/toggleable.html.twig create mode 100644 plugins/form/templates/forms/dropzone/template.html.twig create mode 100644 plugins/form/templates/forms/field.html.twig create mode 100644 plugins/form/templates/forms/fields/array/array.html.twig create mode 100644 plugins/form/templates/forms/fields/avatar/avatar.html.twig create mode 100644 plugins/form/templates/forms/fields/captcha/captcha.html.twig create mode 100644 plugins/form/templates/forms/fields/checkbox/checkbox.html.twig create mode 100644 plugins/form/templates/forms/fields/checkboxes/checkboxes.html.twig create mode 100644 plugins/form/templates/forms/fields/color/color.html.twig create mode 100644 plugins/form/templates/forms/fields/column/column.html.twig create mode 100644 plugins/form/templates/forms/fields/columns/columns.html.twig create mode 100644 plugins/form/templates/forms/fields/conditional/conditional.html.twig create mode 100644 plugins/form/templates/forms/fields/date/date.html.twig create mode 100644 plugins/form/templates/forms/fields/date/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/datetime/datetime.html.twig create mode 100644 plugins/form/templates/forms/fields/datetime/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/display/display.html.twig create mode 100644 plugins/form/templates/forms/fields/email/email.html.twig create mode 100644 plugins/form/templates/forms/fields/fieldset/fieldset.html.twig create mode 100644 plugins/form/templates/forms/fields/file/file.html.twig create mode 100644 plugins/form/templates/forms/fields/formname/formname.html.twig create mode 100644 plugins/form/templates/forms/fields/formtask/formtask.html.twig create mode 100644 plugins/form/templates/forms/fields/hidden/hidden.html.twig create mode 100644 plugins/form/templates/forms/fields/honeypot/honeypot.html.twig create mode 100644 plugins/form/templates/forms/fields/ignore/ignore.html.twig create mode 100644 plugins/form/templates/forms/fields/key/key.html.twig create mode 100644 plugins/form/templates/forms/fields/month/month.html.twig create mode 100644 plugins/form/templates/forms/fields/nonce/nonce.html.twig create mode 100644 plugins/form/templates/forms/fields/number/number.html.twig create mode 100644 plugins/form/templates/forms/fields/password/password.html.twig create mode 100644 plugins/form/templates/forms/fields/radio/radio.html.twig create mode 100644 plugins/form/templates/forms/fields/range/range.html.twig create mode 100644 plugins/form/templates/forms/fields/section/section.html.twig create mode 100644 plugins/form/templates/forms/fields/select/select.html.twig create mode 100644 plugins/form/templates/forms/fields/select_optgroup/select_optgroup.html.twig create mode 100644 plugins/form/templates/forms/fields/signature/signature.html.twig create mode 100644 plugins/form/templates/forms/fields/spacer/spacer.html.twig create mode 100644 plugins/form/templates/forms/fields/switch/switch.html.twig create mode 100644 plugins/form/templates/forms/fields/tab/tab.html.twig create mode 100644 plugins/form/templates/forms/fields/tabs/tabs.html.twig create mode 100644 plugins/form/templates/forms/fields/tel/tel.html.twig create mode 100644 plugins/form/templates/forms/fields/text/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/text/text.html.twig create mode 100644 plugins/form/templates/forms/fields/textarea/textarea.html.twig create mode 100644 plugins/form/templates/forms/fields/time/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/time/time.html.twig create mode 100644 plugins/form/templates/forms/fields/toggle/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/toggle/toggle.html.twig create mode 100644 plugins/form/templates/forms/fields/uniqueid/uniqueid.html.twig create mode 100644 plugins/form/templates/forms/fields/url/edit_list.html.twig create mode 100644 plugins/form/templates/forms/fields/url/url.html.twig create mode 100644 plugins/form/templates/forms/fields/value/value.html.twig create mode 100644 plugins/form/templates/forms/fields/week/week.html.twig create mode 100644 plugins/form/templates/forms/form.html.twig create mode 100644 plugins/form/templates/forms/layouts/button.html.twig create mode 100644 plugins/form/templates/forms/layouts/button/default-button.html.twig create mode 100644 plugins/form/templates/forms/layouts/field-variables.html.twig create mode 100644 plugins/form/templates/forms/layouts/field.html.twig create mode 100644 plugins/form/templates/forms/layouts/field/default-field.html.twig create mode 100644 plugins/form/templates/forms/layouts/form.html.twig create mode 100644 plugins/form/templates/forms/layouts/form/default-form.html.twig create mode 100644 plugins/form/templates/modular/form.html.twig create mode 100644 plugins/form/templates/partials/form-messages.html.twig create mode 100644 plugins/form/templates/partials/form-messages.json.twig create mode 100644 plugins/form/vendor/autoload.php create mode 100644 plugins/form/vendor/composer/ClassLoader.php create mode 100644 plugins/form/vendor/composer/InstalledVersions.php create mode 100644 plugins/form/vendor/composer/LICENSE create mode 100644 plugins/form/vendor/composer/autoload_classmap.php create mode 100644 plugins/form/vendor/composer/autoload_namespaces.php create mode 100644 plugins/form/vendor/composer/autoload_psr4.php create mode 100644 plugins/form/vendor/composer/autoload_real.php create mode 100644 plugins/form/vendor/composer/autoload_static.php create mode 100644 plugins/form/vendor/composer/installed.json create mode 100644 plugins/form/vendor/composer/installed.php create mode 100644 plugins/form/vendor/composer/platform_check.php create mode 100644 plugins/form/vendor/google/recaptcha/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 plugins/form/vendor/google/recaptcha/.gitignore create mode 100644 plugins/form/vendor/google/recaptcha/.travis.yml create mode 100644 plugins/form/vendor/google/recaptcha/ARCHITECTURE.md create mode 100644 plugins/form/vendor/google/recaptcha/CONTRIBUTING.md create mode 100644 plugins/form/vendor/google/recaptcha/LICENSE create mode 100644 plugins/form/vendor/google/recaptcha/README.md create mode 100644 plugins/form/vendor/google/recaptcha/app.yaml create mode 100644 plugins/form/vendor/google/recaptcha/composer.json create mode 100644 plugins/form/vendor/google/recaptcha/examples/appengine-https.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/config.php.dist create mode 100644 plugins/form/vendor/google/recaptcha/examples/examples.css create mode 100644 plugins/form/vendor/google/recaptcha/examples/google0afd8760fd68f119.html create mode 100644 plugins/form/vendor/google/recaptcha/examples/index.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-content-security-policy.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-v2-checkbox-explicit.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-v2-checkbox.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-v2-invisible.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-v3-request-scores.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/recaptcha-v3-verify.php create mode 100644 plugins/form/vendor/google/recaptcha/examples/robots.txt create mode 100644 plugins/form/vendor/google/recaptcha/phpunit.xml.dist create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/ReCaptcha.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Curl.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/RequestParameters.php create mode 100644 plugins/form/vendor/google/recaptcha/src/ReCaptcha/Response.php create mode 100644 plugins/form/vendor/google/recaptcha/src/autoload.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/ReCaptchaTest.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/CurlPostTest.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/PostTest.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/SocketPostTest.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/RequestParametersTest.php create mode 100644 plugins/form/vendor/google/recaptcha/tests/ReCaptcha/ResponseTest.php create mode 100644 plugins/form/webpack.conf.js create mode 100644 plugins/form/yarn.lock create mode 100644 plugins/git-sync/.eslintrc create mode 100644 plugins/git-sync/.gitignore create mode 100644 plugins/git-sync/CHANGELOG.md create mode 100644 plugins/git-sync/LICENSE create mode 100644 plugins/git-sync/README.md create mode 100644 plugins/git-sync/app/main.js create mode 100644 plugins/git-sync/app/wizard/index.js create mode 100644 plugins/git-sync/blueprints.yaml create mode 100644 plugins/git-sync/classes/AdminController.php create mode 100644 plugins/git-sync/classes/GitSync.php create mode 100644 plugins/git-sync/classes/Helper.php create mode 100644 plugins/git-sync/cli/InitCommand.php create mode 100644 plugins/git-sync/cli/PasswdCommand.php create mode 100644 plugins/git-sync/cli/StatusCommand.php create mode 100644 plugins/git-sync/cli/SyncCommand.php create mode 100644 plugins/git-sync/composer.json create mode 100644 plugins/git-sync/composer.lock create mode 100644 plugins/git-sync/css-compiled/git-sync-icon.css create mode 100644 plugins/git-sync/css-compiled/git-sync.css create mode 100644 plugins/git-sync/fonts/gitsync.svg create mode 100644 plugins/git-sync/fonts/gitsync.ttf create mode 100644 plugins/git-sync/fonts/gitsync.woff create mode 100644 plugins/git-sync/git-sync.php create mode 100644 plugins/git-sync/git-sync.yaml create mode 100644 plugins/git-sync/gosass.sh create mode 100644 plugins/git-sync/images/gitsync-logo.png create mode 100644 plugins/git-sync/images/repos/bitbucket.svg create mode 100644 plugins/git-sync/images/repos/github.svg create mode 100644 plugins/git-sync/images/repos/gitlab.svg create mode 100644 plugins/git-sync/images/repos/gitlogo.svg create mode 100644 plugins/git-sync/js/app.js create mode 100644 plugins/git-sync/js/vendor.js create mode 100644 plugins/git-sync/package.json create mode 100644 plugins/git-sync/scss/configuration/_colors.scss create mode 100644 plugins/git-sync/scss/git-sync.scss create mode 100644 plugins/git-sync/scss/plugin/_wizard.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/_bourbon-deprecated-upcoming.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/_bourbon.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_border-color.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_border-radius.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_border-style.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_border-width.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_buttons.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_clearfix.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_ellipsis.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_font-stacks.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_hide-text.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_margin.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_padding.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_position.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_prefixer.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_retina-image.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_size.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_text-inputs.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_timing-functions.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_triangle.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/addons/_word-wrap.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_animation.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_appearance.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_backface-visibility.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_background-image.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_background.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_border-image.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_calc.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_columns.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_filter.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_flex-box.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_font-face.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_font-feature-settings.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_hidpi-media-query.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_hyphens.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_image-rendering.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_keyframes.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_linear-gradient.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_perspective.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_placeholder.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_radial-gradient.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_selection.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_text-decoration.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_transform.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_transition.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/css3/_user-select.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_assign-inputs.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_contains-falsy.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_contains.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_is-length.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_is-light.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_is-number.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_is-size.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_modular-scale.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_px-to-em.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_px-to-rem.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_shade.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_strip-units.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_tint.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_transition-property-name.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/functions/_unpack.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_convert-units.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_directional-values.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_font-source-declaration.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_gradient-positions-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_linear-angle-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_linear-gradient-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_linear-positions-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_linear-side-corner-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_radial-arg-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_radial-gradient-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_radial-positions-parser.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_render-gradients.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_shape-size-stripper.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/helpers/_str-to-num.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/settings/_asset-pipeline.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/settings/_prefixer.scss create mode 100644 plugins/git-sync/scss/vendor/bourbon/settings/_px-to-em.scss create mode 100644 plugins/git-sync/templates/forms/fields/enc-password/enc-password.html.twig create mode 100644 plugins/git-sync/templates/forms/fields/git-wizard/git-wizard.html.twig create mode 100644 plugins/git-sync/templates/partials/modal-reset.html.twig create mode 100644 plugins/git-sync/templates/partials/modal-wizard.html.twig create mode 100644 plugins/git-sync/vendor/autoload.php create mode 100644 plugins/git-sync/vendor/bin/generate-defuse-key create mode 100644 plugins/git-sync/vendor/composer/ClassLoader.php create mode 100644 plugins/git-sync/vendor/composer/InstalledVersions.php create mode 100644 plugins/git-sync/vendor/composer/LICENSE create mode 100644 plugins/git-sync/vendor/composer/autoload_classmap.php create mode 100644 plugins/git-sync/vendor/composer/autoload_namespaces.php create mode 100644 plugins/git-sync/vendor/composer/autoload_psr4.php create mode 100644 plugins/git-sync/vendor/composer/autoload_real.php create mode 100644 plugins/git-sync/vendor/composer/autoload_static.php create mode 100644 plugins/git-sync/vendor/composer/installed.json create mode 100644 plugins/git-sync/vendor/composer/installed.php create mode 100644 plugins/git-sync/vendor/composer/platform_check.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/LICENSE create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/README.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/bin/generate-defuse-key create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/composer.json create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/dist/Makefile create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/dist/box.json create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/dist/signingkey-new.asc create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/dist/signingkey.asc create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/CryptoDetails.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/FAQ.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/InstallingAndVerifying.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/Tutorial.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/UpgradingFromV1.2.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/classes/Crypto.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/classes/File.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/classes/Key.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/docs/classes/KeyProtectedByPassword.md create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Core.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Crypto.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/DerivedKeys.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Encoding.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Exception/BadFormatException.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Exception/CryptoException.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Exception/EnvironmentIsBrokenException.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Exception/IOException.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Exception/WrongKeyOrModifiedCiphertextException.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/File.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/Key.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/KeyOrPassword.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/KeyProtectedByPassword.php create mode 100644 plugins/git-sync/vendor/defuse/php-encryption/src/RuntimeTests.php create mode 100644 plugins/git-sync/vendor/sebastian/git/.gitignore create mode 100644 plugins/git-sync/vendor/sebastian/git/LICENSE create mode 100644 plugins/git-sync/vendor/sebastian/git/README.md create mode 100644 plugins/git-sync/vendor/sebastian/git/build.xml create mode 100644 plugins/git-sync/vendor/sebastian/git/composer.json create mode 100644 plugins/git-sync/vendor/sebastian/git/src/Exception/Exception.php create mode 100644 plugins/git-sync/vendor/sebastian/git/src/Exception/RuntimeException.php create mode 100644 plugins/git-sync/vendor/sebastian/git/src/Git.php create mode 100644 plugins/git-sync/watch.sh create mode 100644 plugins/git-sync/webpack.conf.js create mode 100644 plugins/git-sync/wizard.png create mode 100644 plugins/git-sync/yarn.lock create mode 100644 plugins/langswitcher/CHANGELOG.md create mode 100644 plugins/langswitcher/LICENSE create mode 100644 plugins/langswitcher/README.md create mode 100644 plugins/langswitcher/assets/readme_1.png create mode 100644 plugins/langswitcher/blueprints.yaml create mode 100644 plugins/langswitcher/composer.json create mode 100644 plugins/langswitcher/composer.lock create mode 100644 plugins/langswitcher/css/langswitcher.css create mode 100644 plugins/langswitcher/langswitcher.php create mode 100644 plugins/langswitcher/langswitcher.yaml create mode 100644 plugins/langswitcher/languages.yaml create mode 100644 plugins/langswitcher/templates/partials/langswitcher-long.html.twig create mode 100644 plugins/langswitcher/templates/partials/langswitcher-short.html.twig create mode 100644 plugins/langswitcher/templates/partials/langswitcher.hreflang.html.twig create mode 100644 plugins/langswitcher/templates/partials/langswitcher.html.twig create mode 100644 plugins/langswitcher/vendor/autoload.php create mode 100644 plugins/langswitcher/vendor/composer/ClassLoader.php create mode 100644 plugins/langswitcher/vendor/composer/LICENSE create mode 100644 plugins/langswitcher/vendor/composer/autoload_classmap.php create mode 100644 plugins/langswitcher/vendor/composer/autoload_namespaces.php create mode 100644 plugins/langswitcher/vendor/composer/autoload_psr4.php create mode 100644 plugins/langswitcher/vendor/composer/autoload_real.php create mode 100644 plugins/langswitcher/vendor/composer/autoload_static.php create mode 100644 plugins/langswitcher/vendor/composer/installed.json create mode 100644 plugins/login/.gitignore create mode 100644 plugins/login/CHANGELOG.md create mode 100644 plugins/login/LICENSE create mode 100644 plugins/login/README.md create mode 100644 plugins/login/blueprints.yaml create mode 100644 plugins/login/classes/Controller.php create mode 100644 plugins/login/classes/Events/UserLoginEvent.php create mode 100644 plugins/login/classes/Invitations/Invitation.php create mode 100644 plugins/login/classes/Invitations/Invitations.php create mode 100644 plugins/login/classes/Login.php create mode 100644 plugins/login/classes/LoginCache.php create mode 100644 plugins/login/classes/RateLimiter.php create mode 100644 plugins/login/classes/RememberMe/RememberMe.php create mode 100644 plugins/login/classes/RememberMe/TokenStorage.php create mode 100644 plugins/login/classes/TwoFactorAuth/BaconQrProvider.php create mode 100644 plugins/login/classes/TwoFactorAuth/TwoFactorAuth.php create mode 100644 plugins/login/cli/ChangePasswordCommand.php create mode 100644 plugins/login/cli/ChangeUserStateCommand.php create mode 100644 plugins/login/cli/LookupUserCommand.php create mode 100644 plugins/login/cli/NewUserCommand.php create mode 100644 plugins/login/composer.json create mode 100644 plugins/login/composer.lock create mode 100644 plugins/login/css/login.css create mode 100644 plugins/login/hebe.json create mode 100644 plugins/login/js/2fa.js create mode 100644 plugins/login/languages/de.yaml create mode 100644 plugins/login/languages/en.yaml create mode 100644 plugins/login/languages/es.yaml create mode 100644 plugins/login/languages/fr.yaml create mode 100644 plugins/login/languages/hr.yaml create mode 100644 plugins/login/languages/hu.yaml create mode 100644 plugins/login/languages/lt.yaml create mode 100644 plugins/login/languages/no.yaml create mode 100644 plugins/login/languages/pt-BR.yaml create mode 100644 plugins/login/languages/ro.yaml create mode 100644 plugins/login/languages/ru.yaml create mode 100644 plugins/login/languages/uk.yaml create mode 100644 plugins/login/languages/zh.yaml create mode 100644 plugins/login/login.php create mode 100644 plugins/login/login.yaml create mode 100644 plugins/login/pages/forgot.md create mode 100644 plugins/login/pages/login.md create mode 100644 plugins/login/pages/profile.md create mode 100644 plugins/login/pages/register.md create mode 100644 plugins/login/pages/reset.md create mode 100644 plugins/login/pages/unauthorized.md create mode 100644 plugins/login/templates/forgot.html.twig create mode 100644 plugins/login/templates/forms/fields/2fa_secret/2fa_secret.html.twig create mode 100644 plugins/login/templates/login.html.twig create mode 100644 plugins/login/templates/login.json.twig create mode 100644 plugins/login/templates/partials/forgot-form.html.twig create mode 100644 plugins/login/templates/partials/login-form.html.twig create mode 100644 plugins/login/templates/partials/login-status.html.twig create mode 100644 plugins/login/templates/partials/login-twofa.html.twig create mode 100644 plugins/login/templates/partials/reset-form.html.twig create mode 100644 plugins/login/templates/profile.html.twig create mode 100644 plugins/login/templates/profile.json.twig create mode 100644 plugins/login/templates/register.html.twig create mode 100644 plugins/login/templates/reset.html.twig create mode 100644 plugins/login/templates/unauthorized.html.twig create mode 100644 plugins/login/vendor/autoload.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/.gitignore create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/.travis.yml create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/CHANGELOG.md create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/LICENSE create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/Module.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/README.md create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/autoload_classmap.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/autoload_function.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/autoload_register.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/composer.json create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/AbstractEnum.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitArray.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitMatrix.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitUtils.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/CharacterSetEci.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlock.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlocks.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ErrorCorrectionLevel.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/FormatInformation.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Mode.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ReedSolomonCodec.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Version.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/BlockPair.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/ByteMatrix.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/Encoder.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MaskUtil.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MatrixUtil.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/QrCode.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/ExceptionInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/InvalidArgumentException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/OutOfBoundsException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/RuntimeException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/UnexpectedValueException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/WriterException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Cmyk.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/ColorInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Gray.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Rgb.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/AbstractRenderer.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/DecoratorInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/FinderPattern.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Eps.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Png.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/RendererInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Svg.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/RendererInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Html.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/BitArray.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/Mode.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Common/Version.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/src/Writer.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitArrayTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitMatrixTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitUtilsTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ErrorCorrectionLevelTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/FormatInformationTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ModeTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ReedSolomonCodecTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/VersionTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/EncoderTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MaskUtilTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MatrixUtilTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/HtmlTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/TextTest.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/bootstrap.php create mode 100644 plugins/login/vendor/bacon/bacon-qr-code/tests/phpunit.xml create mode 100644 plugins/login/vendor/birke/rememberme/.gitignore create mode 100644 plugins/login/vendor/birke/rememberme/LICENSE create mode 100644 plugins/login/vendor/birke/rememberme/README.md create mode 100644 plugins/login/vendor/birke/rememberme/composer.json create mode 100644 plugins/login/vendor/birke/rememberme/example/action.php create mode 100644 plugins/login/vendor/birke/rememberme/example/css/style.css create mode 100644 plugins/login/vendor/birke/rememberme/example/index.php create mode 100644 plugins/login/vendor/birke/rememberme/example/templates/cookie_was_stolen.php create mode 100644 plugins/login/vendor/birke/rememberme/example/templates/login.php create mode 100644 plugins/login/vendor/birke/rememberme/example/templates/user_is_logged_in.php create mode 100644 plugins/login/vendor/birke/rememberme/phpunit.xml create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Authenticator.php create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Cookie.php create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Storage/DB.php create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Storage/File.php create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Storage/PDO.php create mode 100644 plugins/login/vendor/birke/rememberme/src/Rememberme/Storage/StorageInterface.php create mode 100644 plugins/login/vendor/birke/rememberme/test/CookieTest.php create mode 100644 plugins/login/vendor/birke/rememberme/test/RemembermeTest.php create mode 100644 plugins/login/vendor/birke/rememberme/test/Storage/PDO.php create mode 100644 plugins/login/vendor/birke/rememberme/test/Storage/tokens.xml create mode 100644 plugins/login/vendor/birke/rememberme/test/bootstrap.php create mode 100644 plugins/login/vendor/composer/ClassLoader.php create mode 100644 plugins/login/vendor/composer/InstalledVersions.php create mode 100644 plugins/login/vendor/composer/LICENSE create mode 100644 plugins/login/vendor/composer/autoload_classmap.php create mode 100644 plugins/login/vendor/composer/autoload_files.php create mode 100644 plugins/login/vendor/composer/autoload_namespaces.php create mode 100644 plugins/login/vendor/composer/autoload_psr4.php create mode 100644 plugins/login/vendor/composer/autoload_real.php create mode 100644 plugins/login/vendor/composer/autoload_static.php create mode 100644 plugins/login/vendor/composer/installed.json create mode 100644 plugins/login/vendor/composer/installed.php create mode 100644 plugins/login/vendor/composer/platform_check.php create mode 100644 plugins/login/vendor/dasprid/enum/.coveralls.yml create mode 100644 plugins/login/vendor/dasprid/enum/.gitignore create mode 100644 plugins/login/vendor/dasprid/enum/.travis.yml create mode 100644 plugins/login/vendor/dasprid/enum/README.md create mode 100644 plugins/login/vendor/dasprid/enum/composer.json create mode 100644 plugins/login/vendor/dasprid/enum/phpcs.xml create mode 100644 plugins/login/vendor/dasprid/enum/phpunit.xml.dist create mode 100644 plugins/login/vendor/dasprid/enum/src/AbstractEnum.php create mode 100644 plugins/login/vendor/dasprid/enum/src/EnumMap.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/ExceptionInterface.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/ExpectationException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/IllegalArgumentException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/MismatchException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/SerializeNotSupportedException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/Exception/UnserializeNotSupportedException.php create mode 100644 plugins/login/vendor/dasprid/enum/src/NullValue.php create mode 100644 plugins/login/vendor/dasprid/enum/test/AbstractEnumTest.php create mode 100644 plugins/login/vendor/dasprid/enum/test/EnumMapTest.php create mode 100644 plugins/login/vendor/dasprid/enum/test/NullValueTest.php create mode 100644 plugins/login/vendor/dasprid/enum/test/Planet.php create mode 100644 plugins/login/vendor/dasprid/enum/test/WeekDay.php create mode 100644 plugins/login/vendor/paragonie/random_compat/CHANGELOG.md create mode 100644 plugins/login/vendor/paragonie/random_compat/LICENSE create mode 100644 plugins/login/vendor/paragonie/random_compat/RATIONALE.md create mode 100644 plugins/login/vendor/paragonie/random_compat/README.md create mode 100644 plugins/login/vendor/paragonie/random_compat/SECURITY.md create mode 100644 plugins/login/vendor/paragonie/random_compat/build-phar.sh create mode 100644 plugins/login/vendor/paragonie/random_compat/composer.json create mode 100644 plugins/login/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey create mode 100644 plugins/login/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/byte_safe_strings.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/cast_to_int.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/error_polyfill.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_bytes_openssl.php create mode 100644 plugins/login/vendor/paragonie/random_compat/lib/random_int.php create mode 100644 plugins/login/vendor/paragonie/random_compat/other/build_phar.php create mode 100644 plugins/login/vendor/paragonie/random_compat/other/ide_stubs/COM.php create mode 100644 plugins/login/vendor/paragonie/random_compat/other/ide_stubs/README.md create mode 100644 plugins/login/vendor/paragonie/random_compat/other/ide_stubs/com_exception.php create mode 100644 plugins/login/vendor/paragonie/random_compat/other/ide_stubs/libsodium.php create mode 100644 plugins/login/vendor/paragonie/random_compat/psalm-autoload.php create mode 100644 plugins/login/vendor/paragonie/random_compat/psalm.xml create mode 100644 plugins/login/vendor/robthree/twofactorauth/.github/FUNDING.yml create mode 100644 plugins/login/vendor/robthree/twofactorauth/.github/workflows/test.yml create mode 100644 plugins/login/vendor/robthree/twofactorauth/.gitignore create mode 100644 plugins/login/vendor/robthree/twofactorauth/LICENSE create mode 100644 plugins/login/vendor/robthree/twofactorauth/README.md create mode 100644 plugins/login/vendor/robthree/twofactorauth/TwoFactorAuth.phpproj create mode 100644 plugins/login/vendor/robthree/twofactorauth/TwoFactorAuth.sln create mode 100644 plugins/login/vendor/robthree/twofactorauth/composer.json create mode 100644 plugins/login/vendor/robthree/twofactorauth/demo/demo.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/demo/loader.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/BaconQrCodeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Rng/RNGException.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/Providers/Time/TimeException.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/lib/TwoFactorAuthException.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/logo.png create mode 100644 plugins/login/vendor/robthree/twofactorauth/multifactorauthforeveryone.png create mode 100644 plugins/login/vendor/robthree/twofactorauth/phpunit.xml create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/MightNotMakeAssertions.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Qr/IQRCodeProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Qr/TestQrProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/CSRNGProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/HashRNGProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/IRNGProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/MCryptRNGProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/NeedsRngLengths.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/OpenSSLRNGProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Rng/TestRNGProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Time/ITimeProviderTest.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/Providers/Time/TestTimeProvider.php create mode 100644 plugins/login/vendor/robthree/twofactorauth/tests/TwoFactorAuthTest.php create mode 100644 plugins/page-toc/CHANGELOG.md create mode 100644 plugins/page-toc/LICENSE create mode 100644 plugins/page-toc/README.md create mode 100644 plugins/page-toc/assets/page-toc-anchors.css create mode 100644 plugins/page-toc/assets/page-toc.png create mode 100644 plugins/page-toc/blueprints.yaml create mode 100644 plugins/page-toc/blueprints/page-toc.yaml create mode 100644 plugins/page-toc/classes/HtmlHelper.php create mode 100644 plugins/page-toc/classes/MarkupFixer.php create mode 100644 plugins/page-toc/classes/OrderedListRenderer.php create mode 100644 plugins/page-toc/classes/TocGenerator.php create mode 100644 plugins/page-toc/classes/UniqueSlugify.php create mode 100644 plugins/page-toc/classes/shortcodes/AnchorShortcode.php create mode 100644 plugins/page-toc/composer.json create mode 100644 plugins/page-toc/composer.lock create mode 100644 plugins/page-toc/languages.yaml create mode 100644 plugins/page-toc/page-toc.php create mode 100644 plugins/page-toc/page-toc.yaml create mode 100644 plugins/page-toc/templates/components/page-toc.html.twig create mode 100644 plugins/page-toc/vendor/autoload.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/LICENSE create mode 100644 plugins/page-toc/vendor/cocur/slugify/README.md create mode 100644 plugins/page-toc/vendor/cocur/slugify/composer.json create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Laravel/SlugifyFacade.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Laravel/SlugifyServiceProvider.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Latte/SlugifyHelper.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/League/SlugifyServiceProvider.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Nette/SlugifyExtension.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Plum/SlugifyConverter.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Symfony/CocurSlugifyBundle.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Symfony/CocurSlugifyExtension.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Symfony/Configuration.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/Twig/SlugifyExtension.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/ZF2/Module.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/ZF2/SlugifyService.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/ZF2/SlugifyViewHelper.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Bridge/ZF2/SlugifyViewHelperFactory.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/RuleProvider/DefaultRuleProvider.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/RuleProvider/FileRuleProvider.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/RuleProvider/RuleProviderInterface.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/Slugify.php create mode 100644 plugins/page-toc/vendor/cocur/slugify/src/SlugifyInterface.php create mode 100644 plugins/page-toc/vendor/composer/ClassLoader.php create mode 100644 plugins/page-toc/vendor/composer/InstalledVersions.php create mode 100644 plugins/page-toc/vendor/composer/LICENSE create mode 100644 plugins/page-toc/vendor/composer/autoload_classmap.php create mode 100644 plugins/page-toc/vendor/composer/autoload_namespaces.php create mode 100644 plugins/page-toc/vendor/composer/autoload_psr4.php create mode 100644 plugins/page-toc/vendor/composer/autoload_real.php create mode 100644 plugins/page-toc/vendor/composer/autoload_static.php create mode 100644 plugins/page-toc/vendor/composer/installed.json create mode 100644 plugins/page-toc/vendor/composer/installed.php create mode 100644 plugins/page-toc/vendor/composer/platform_check.php create mode 100644 plugins/page-toc/vendor/composer/tmp-f711f3efca8baf836db7f0f0b18aef94~ create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/CHANGELOG.md create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/LICENSE create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/composer.json create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Factory/CoreExtension.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Factory/ExtensionInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/FactoryInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Integration/Symfony/RoutingExtension.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/ItemInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Iterator/CurrentItemFilterIterator.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Iterator/DisplayedItemFilterIterator.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Iterator/RecursiveItemIterator.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Loader/ArrayLoader.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Loader/LoaderInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Loader/NodeLoader.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/Matcher.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/MatcherInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/Voter/RegexVoter.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/Voter/RouteVoter.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/Voter/UriVoter.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Matcher/Voter/VoterInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/MenuFactory.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/MenuItem.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/NodeInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Provider/ArrayAccessProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Provider/ChainProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Provider/LazyProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Provider/MenuProviderInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Provider/PsrProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/ArrayAccessProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/ListRenderer.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/PsrProvider.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/Renderer.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/RendererInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/RendererProviderInterface.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/TwigRenderer.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views/knp_menu.html.twig create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views/knp_menu_base.html.twig create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views/knp_menu_ordered.html.twig create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Twig/Helper.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Twig/MenuExtension.php create mode 100644 plugins/page-toc/vendor/knplabs/knp-menu/src/Knp/Menu/Util/MenuManipulator.php create mode 100644 plugins/pagination/CHANGELOG.md create mode 100644 plugins/pagination/LICENSE create mode 100644 plugins/pagination/README.md create mode 100644 plugins/pagination/blueprints.yaml create mode 100644 plugins/pagination/classes/paginationhelper.php create mode 100644 plugins/pagination/classes/paginationpage.php create mode 100644 plugins/pagination/css/pagination.css create mode 100644 plugins/pagination/languages.yaml create mode 100644 plugins/pagination/pagination.php create mode 100644 plugins/pagination/pagination.yaml create mode 100644 plugins/pagination/templates/partials/pagination.html.twig create mode 100644 plugins/pagination/twig/PaginationTwigExtension.php create mode 100644 plugins/problems/CHANGELOG.md create mode 100644 plugins/problems/LICENSE create mode 100644 plugins/problems/README.md create mode 100644 plugins/problems/assets/cli.png create mode 100644 plugins/problems/assets/code-3.svg create mode 100644 plugins/problems/assets/grav-logo.svg create mode 100644 plugins/problems/assets/heart.svg create mode 100644 plugins/problems/assets/readme_1.jpg create mode 100644 plugins/problems/blueprints.yaml create mode 100644 plugins/problems/classes/Problems/Apache.php create mode 100644 plugins/problems/classes/Problems/Base/Problem.php create mode 100644 plugins/problems/classes/Problems/Base/ProblemChecker.php create mode 100644 plugins/problems/classes/Problems/EssentialFolders.php create mode 100644 plugins/problems/classes/Problems/PHPModules.php create mode 100644 plugins/problems/classes/Problems/PHPVersion.php create mode 100644 plugins/problems/classes/Problems/Permissions.php create mode 100644 plugins/problems/cli/CheckCommand.php create mode 100644 plugins/problems/composer.json create mode 100644 plugins/problems/composer.lock create mode 100644 plugins/problems/css/admin.css create mode 100644 plugins/problems/css/admin.min.css create mode 100755 plugins/problems/css/spectre-icons.css create mode 100755 plugins/problems/css/spectre-icons.min.css create mode 100755 plugins/problems/css/spectre.css create mode 100755 plugins/problems/css/spectre.min.css create mode 100644 plugins/problems/gulpfile.js create mode 100644 plugins/problems/languages.yaml create mode 100755 plugins/problems/package.json create mode 100644 plugins/problems/problems.php create mode 100644 plugins/problems/problems.yaml create mode 100755 plugins/problems/scss/_accordions.scss create mode 100755 plugins/problems/scss/_animations.scss create mode 100755 plugins/problems/scss/_asian.scss create mode 100755 plugins/problems/scss/_autocomplete.scss create mode 100755 plugins/problems/scss/_avatars.scss create mode 100755 plugins/problems/scss/_badges.scss create mode 100755 plugins/problems/scss/_bars.scss create mode 100755 plugins/problems/scss/_base.scss create mode 100755 plugins/problems/scss/_breadcrumbs.scss create mode 100755 plugins/problems/scss/_buttons.scss create mode 100755 plugins/problems/scss/_calendars.scss create mode 100755 plugins/problems/scss/_cards.scss create mode 100755 plugins/problems/scss/_carousels.scss create mode 100755 plugins/problems/scss/_chips.scss create mode 100755 plugins/problems/scss/_codes.scss create mode 100755 plugins/problems/scss/_comparison-sliders.scss create mode 100755 plugins/problems/scss/_dropdowns.scss create mode 100755 plugins/problems/scss/_empty.scss create mode 100755 plugins/problems/scss/_filters.scss create mode 100755 plugins/problems/scss/_forms.scss create mode 100755 plugins/problems/scss/_icons.scss create mode 100755 plugins/problems/scss/_labels.scss create mode 100755 plugins/problems/scss/_layout.scss create mode 100755 plugins/problems/scss/_media.scss create mode 100755 plugins/problems/scss/_menus.scss create mode 100755 plugins/problems/scss/_meters.scss create mode 100755 plugins/problems/scss/_mixins.scss create mode 100755 plugins/problems/scss/_modals.scss create mode 100755 plugins/problems/scss/_navbar.scss create mode 100755 plugins/problems/scss/_navs.scss create mode 100755 plugins/problems/scss/_normalize.scss create mode 100755 plugins/problems/scss/_off-canvas.scss create mode 100755 plugins/problems/scss/_pagination.scss create mode 100755 plugins/problems/scss/_panels.scss create mode 100755 plugins/problems/scss/_parallax.scss create mode 100755 plugins/problems/scss/_popovers.scss create mode 100644 plugins/problems/scss/_preset.scss create mode 100644 plugins/problems/scss/_problems.scss create mode 100755 plugins/problems/scss/_progress.scss create mode 100755 plugins/problems/scss/_sliders.scss create mode 100755 plugins/problems/scss/_steps.scss create mode 100755 plugins/problems/scss/_tables.scss create mode 100755 plugins/problems/scss/_tabs.scss create mode 100755 plugins/problems/scss/_tiles.scss create mode 100755 plugins/problems/scss/_timelines.scss create mode 100755 plugins/problems/scss/_toasts.scss create mode 100755 plugins/problems/scss/_tooltips.scss create mode 100755 plugins/problems/scss/_typography.scss create mode 100755 plugins/problems/scss/_utilities.scss create mode 100755 plugins/problems/scss/_variables.scss create mode 100644 plugins/problems/scss/admin.scss create mode 100755 plugins/problems/scss/icons/_icons-action.scss create mode 100755 plugins/problems/scss/icons/_icons-core.scss create mode 100755 plugins/problems/scss/icons/_icons-navigation.scss create mode 100755 plugins/problems/scss/icons/_icons-object.scss create mode 100755 plugins/problems/scss/mixins/_avatar.scss create mode 100755 plugins/problems/scss/mixins/_button.scss create mode 100755 plugins/problems/scss/mixins/_clearfix.scss create mode 100755 plugins/problems/scss/mixins/_color.scss create mode 100755 plugins/problems/scss/mixins/_label.scss create mode 100755 plugins/problems/scss/mixins/_position.scss create mode 100755 plugins/problems/scss/mixins/_shadow.scss create mode 100755 plugins/problems/scss/mixins/_text.scss create mode 100755 plugins/problems/scss/mixins/_toast.scss create mode 100755 plugins/problems/scss/mixins/_transition.scss create mode 100755 plugins/problems/scss/spectre-icons.scss create mode 100755 plugins/problems/scss/spectre.scss create mode 100755 plugins/problems/scss/utilities/_colors.scss create mode 100755 plugins/problems/scss/utilities/_cursors.scss create mode 100755 plugins/problems/scss/utilities/_display.scss create mode 100755 plugins/problems/scss/utilities/_divider.scss create mode 100755 plugins/problems/scss/utilities/_loading.scss create mode 100755 plugins/problems/scss/utilities/_position.scss create mode 100755 plugins/problems/scss/utilities/_shapes.scss create mode 100755 plugins/problems/scss/utilities/_text.scss create mode 100644 plugins/problems/templates/problems.html.twig create mode 100644 plugins/problems/templates/reports/problems-report.html.twig create mode 100644 plugins/problems/vendor/autoload.php create mode 100644 plugins/problems/vendor/composer/ClassLoader.php create mode 100644 plugins/problems/vendor/composer/InstalledVersions.php create mode 100644 plugins/problems/vendor/composer/LICENSE create mode 100644 plugins/problems/vendor/composer/autoload_classmap.php create mode 100644 plugins/problems/vendor/composer/autoload_namespaces.php create mode 100644 plugins/problems/vendor/composer/autoload_psr4.php create mode 100644 plugins/problems/vendor/composer/autoload_real.php create mode 100644 plugins/problems/vendor/composer/autoload_static.php create mode 100644 plugins/problems/vendor/composer/installed.json create mode 100644 plugins/problems/vendor/composer/installed.php create mode 100644 plugins/readingtime/CHANGELOG.md create mode 100644 plugins/readingtime/LICENSE create mode 100644 plugins/readingtime/README.md create mode 100644 plugins/readingtime/blueprints.yaml create mode 100644 plugins/readingtime/classes/TwigReadingTimeFilters.php create mode 100644 plugins/readingtime/composer.json create mode 100644 plugins/readingtime/composer.lock create mode 100644 plugins/readingtime/languages.yaml create mode 100644 plugins/readingtime/readingtime.php create mode 100644 plugins/readingtime/readingtime.yaml create mode 100644 plugins/readingtime/vendor/autoload.php create mode 100644 plugins/readingtime/vendor/composer/ClassLoader.php create mode 100644 plugins/readingtime/vendor/composer/LICENSE create mode 100644 plugins/readingtime/vendor/composer/autoload_classmap.php create mode 100644 plugins/readingtime/vendor/composer/autoload_namespaces.php create mode 100644 plugins/readingtime/vendor/composer/autoload_psr4.php create mode 100644 plugins/readingtime/vendor/composer/autoload_real.php create mode 100644 plugins/readingtime/vendor/composer/autoload_static.php create mode 100644 plugins/readingtime/vendor/composer/installed.json create mode 100644 plugins/relatedpages/CHANGELOG.md create mode 100644 plugins/relatedpages/LICENSE create mode 100644 plugins/relatedpages/README.md create mode 100644 plugins/relatedpages/assets/readme_1.png create mode 100644 plugins/relatedpages/blueprints.yaml create mode 100644 plugins/relatedpages/languages.yaml create mode 100644 plugins/relatedpages/relatedpages.php create mode 100644 plugins/relatedpages/relatedpages.yaml create mode 100644 plugins/relatedpages/templates/partials/relatedpages.html.twig create mode 100644 plugins/simplesearch/CHANGELOG.md create mode 100644 plugins/simplesearch/LICENSE create mode 100644 plugins/simplesearch/README.md create mode 100644 plugins/simplesearch/assets/readme_1.png create mode 100644 plugins/simplesearch/assets/search.svg create mode 100644 plugins/simplesearch/blueprints.yaml create mode 100644 plugins/simplesearch/composer.json create mode 100644 plugins/simplesearch/composer.lock create mode 100644 plugins/simplesearch/css/simplesearch.css create mode 100644 plugins/simplesearch/js/simplesearch.js create mode 100644 plugins/simplesearch/languages.yaml create mode 100644 plugins/simplesearch/pages/simplesearch.md create mode 100644 plugins/simplesearch/simplesearch.php create mode 100644 plugins/simplesearch/simplesearch.yaml create mode 100644 plugins/simplesearch/templates/partials/simplesearch_base.html.twig create mode 100644 plugins/simplesearch/templates/partials/simplesearch_item.html.twig create mode 100644 plugins/simplesearch/templates/partials/simplesearch_searchbox.html.twig create mode 100644 plugins/simplesearch/templates/simplesearch_results.html.twig create mode 100644 plugins/simplesearch/templates/simplesearch_results.json.twig create mode 100644 plugins/simplesearch/vendor/autoload.php create mode 100644 plugins/simplesearch/vendor/composer/ClassLoader.php create mode 100644 plugins/simplesearch/vendor/composer/LICENSE create mode 100644 plugins/simplesearch/vendor/composer/autoload_classmap.php create mode 100644 plugins/simplesearch/vendor/composer/autoload_namespaces.php create mode 100644 plugins/simplesearch/vendor/composer/autoload_psr4.php create mode 100644 plugins/simplesearch/vendor/composer/autoload_real.php create mode 100644 plugins/simplesearch/vendor/composer/autoload_static.php create mode 100644 plugins/simplesearch/vendor/composer/installed.json create mode 100644 plugins/sitemap/.gitignore create mode 100644 plugins/sitemap/CHANGELOG.md create mode 100644 plugins/sitemap/LICENSE create mode 100644 plugins/sitemap/README.md create mode 100644 plugins/sitemap/blueprints.yaml create mode 100644 plugins/sitemap/blueprints/sitemap.yaml create mode 100644 plugins/sitemap/classes/SitemapEntry.php create mode 100644 plugins/sitemap/composer.json create mode 100644 plugins/sitemap/composer.lock create mode 100644 plugins/sitemap/hebe.json create mode 100644 plugins/sitemap/languages.yaml create mode 100644 plugins/sitemap/pages/sitemap.md create mode 100644 plugins/sitemap/sitemap.php create mode 100644 plugins/sitemap/sitemap.xsl create mode 100644 plugins/sitemap/sitemap.yaml create mode 100644 plugins/sitemap/templates/sitemap.html.twig create mode 100644 plugins/sitemap/templates/sitemap.json.twig create mode 100644 plugins/sitemap/templates/sitemap.xml.twig create mode 100644 plugins/sitemap/vendor/autoload.php create mode 100644 plugins/sitemap/vendor/composer/ClassLoader.php create mode 100644 plugins/sitemap/vendor/composer/InstalledVersions.php create mode 100644 plugins/sitemap/vendor/composer/LICENSE create mode 100644 plugins/sitemap/vendor/composer/autoload_classmap.php create mode 100644 plugins/sitemap/vendor/composer/autoload_namespaces.php create mode 100644 plugins/sitemap/vendor/composer/autoload_psr4.php create mode 100644 plugins/sitemap/vendor/composer/autoload_real.php create mode 100644 plugins/sitemap/vendor/composer/autoload_static.php create mode 100644 plugins/sitemap/vendor/composer/installed.json create mode 100644 plugins/sitemap/vendor/composer/installed.php create mode 100644 plugins/sitemap/vendor/composer/platform_check.php create mode 100644 plugins/taxonomylist/CHANGELOG.md create mode 100644 plugins/taxonomylist/LICENSE create mode 100644 plugins/taxonomylist/README.md create mode 100644 plugins/taxonomylist/assets/readme_1.png create mode 100644 plugins/taxonomylist/blueprints.yaml create mode 100644 plugins/taxonomylist/classes/taxonomylist.php create mode 100644 plugins/taxonomylist/composer.json create mode 100644 plugins/taxonomylist/composer.lock create mode 100644 plugins/taxonomylist/taxonomylist.php create mode 100644 plugins/taxonomylist/taxonomylist.yaml create mode 100644 plugins/taxonomylist/templates/partials/taxonomylist.html.twig create mode 100644 plugins/taxonomylist/vendor/autoload.php create mode 100644 plugins/taxonomylist/vendor/composer/ClassLoader.php create mode 100644 plugins/taxonomylist/vendor/composer/LICENSE create mode 100644 plugins/taxonomylist/vendor/composer/autoload_classmap.php create mode 100644 plugins/taxonomylist/vendor/composer/autoload_namespaces.php create mode 100644 plugins/taxonomylist/vendor/composer/autoload_psr4.php create mode 100644 plugins/taxonomylist/vendor/composer/autoload_real.php create mode 100644 plugins/taxonomylist/vendor/composer/autoload_static.php create mode 100644 plugins/taxonomylist/vendor/composer/installed.json create mode 100644 themes/.gitkeep create mode 100755 themes/mytheme/css/content.css create mode 100755 themes/mytheme/css/fork-awesome.min.css create mode 100755 themes/mytheme/css/item.css create mode 100755 themes/mytheme/css/sidebar.css create mode 100755 themes/mytheme/css/style.css create mode 100755 themes/mytheme/fonts/forkawesome-webfont.eot create mode 100755 themes/mytheme/fonts/forkawesome-webfont.svg create mode 100755 themes/mytheme/fonts/forkawesome-webfont.ttf create mode 100755 themes/mytheme/fonts/forkawesome-webfont.woff create mode 100755 themes/mytheme/fonts/forkawesome-webfont.woff2 create mode 100755 themes/mytheme/images/bmenu.png create mode 100755 themes/mytheme/images/favicon.png create mode 100755 themes/mytheme/images/license.webp create mode 100755 themes/mytheme/images/org-navbar-logo-white.webp create mode 100755 themes/mytheme/mytheme.yaml create mode 100755 themes/mytheme/plugins/aura-authors/blueprints.yaml create mode 100755 themes/mytheme/templates/de/partials/author-bio.html.twig create mode 100755 themes/mytheme/templates/de/partials/base.html.twig create mode 100755 themes/mytheme/templates/de/partials/blog_item.html.twig create mode 100755 themes/mytheme/templates/de/partials/footer.html.twig create mode 100755 themes/mytheme/templates/de/partials/header.html.twig create mode 100755 themes/mytheme/templates/de/partials/langswitcher.html.twig create mode 100755 themes/mytheme/templates/de/partials/navigation.html.twig create mode 100755 themes/mytheme/templates/en/partials/author-bio.html.twig create mode 100755 themes/mytheme/templates/en/partials/base.html.twig create mode 100755 themes/mytheme/templates/en/partials/blog_item.html.twig create mode 100755 themes/mytheme/templates/en/partials/footer.html.twig create mode 100755 themes/mytheme/templates/en/partials/header.html.twig create mode 100755 themes/mytheme/templates/en/partials/langswitcher.html.twig create mode 100755 themes/mytheme/templates/en/partials/navigation.html.twig create mode 100755 themes/mytheme/templates/sidebar/blog.html.twig create mode 100644 themes/pinpress/CHANGELOG.md create mode 100644 themes/pinpress/LICENSE create mode 100644 themes/pinpress/README.md create mode 100644 themes/pinpress/assets/readme_1.png create mode 100644 themes/pinpress/blueprints.yaml create mode 100644 themes/pinpress/css/content.css create mode 100644 themes/pinpress/css/item.css create mode 100644 themes/pinpress/css/sidebar.css create mode 100644 themes/pinpress/css/style.css create mode 100644 themes/pinpress/css/widget.css create mode 100644 themes/pinpress/images/bmenu.png create mode 100644 themes/pinpress/images/favicon.png create mode 100644 themes/pinpress/js/scripts.js create mode 100644 themes/pinpress/js/video.js create mode 100644 themes/pinpress/pinpress.php create mode 100644 themes/pinpress/pinpress.yaml create mode 100644 themes/pinpress/screenshot.jpg create mode 100644 themes/pinpress/templates/blog.html.twig create mode 100644 themes/pinpress/templates/default.html.twig create mode 100644 themes/pinpress/templates/error.html.twig create mode 100644 themes/pinpress/templates/form.html.twig create mode 100644 themes/pinpress/templates/formdata.html.twig create mode 100644 themes/pinpress/templates/item.html.twig create mode 100644 themes/pinpress/templates/macros/macros.html.twig create mode 100644 themes/pinpress/templates/pagination.html.twig create mode 100644 themes/pinpress/templates/partials/base.html.twig create mode 100644 themes/pinpress/templates/partials/blog_item.html.twig create mode 100644 themes/pinpress/templates/partials/blog_sidebar_footer.html.twig create mode 100644 themes/pinpress/templates/partials/blog_sidebar_header.html.twig create mode 100644 themes/pinpress/templates/partials/footer.html.twig create mode 100644 themes/pinpress/templates/partials/header.html.twig create mode 100755 themes/pinpress/templates/partials/navigation.html.twig create mode 100644 themes/pinpress/templates/partials/relatedpages.html.twig create mode 100644 themes/pinpress/templates/partials/sidebar.html.twig create mode 100644 themes/pinpress/templates/partials/taxonomylist.html.twig create mode 100644 themes/pinpress/templates/sidebar/about.html.twig create mode 100644 themes/pinpress/templates/sidebar/widget.html.twig create mode 100644 themes/pinpress/templates/simplesearch_results.html.twig create mode 100644 themes/pinpress/thumbnail.jpg diff --git a/pages/01.blog/blog.de.md b/pages/01.blog/blog.de.md new file mode 100755 index 0000000..0e9aafa --- /dev/null +++ b/pages/01.blog/blog.de.md @@ -0,0 +1,20 @@ +--- +title: News +blog_url: blog +body_classes: 'header-image fullwidth' +sitemap: + changefreq: monthly + priority: 1.03 +content: + items: '@self.children' + order: + by: date + dir: desc + limit: 5 + pagination: true +feed: + description: 'Sample Blog Description' + limit: 10 +pagination: true +--- + diff --git a/pages/01.blog/blog.en.md b/pages/01.blog/blog.en.md new file mode 100644 index 0000000..0e9aafa --- /dev/null +++ b/pages/01.blog/blog.en.md @@ -0,0 +1,20 @@ +--- +title: News +blog_url: blog +body_classes: 'header-image fullwidth' +sitemap: + changefreq: monthly + priority: 1.03 +content: + items: '@self.children' + order: + by: date + dir: desc + limit: 5 + pagination: true +feed: + description: 'Sample Blog Description' + limit: 10 +pagination: true +--- + diff --git a/pages/01.blog/our-news-blog-is-online-with-grav/item.de.md b/pages/01.blog/our-news-blog-is-online-with-grav/item.de.md new file mode 100644 index 0000000..d41434f --- /dev/null +++ b/pages/01.blog/our-news-blog-is-online-with-grav/item.de.md @@ -0,0 +1,86 @@ +--- +title: 'Unser News/Blog ist online mit GRAV' +taxonomy: + category: + - news + tag: + - 'TECH SAVIOURS' +media_order: 'ts&grav.png' +aura: + author: dan +date: '01-12-2021 09:37' +published: false +--- + +Wir freuen uns sehr, unseren neuen News-Bereich zu veröffentlichen! + +# WordPress, Drupal, Grav ... welches?! +Nachdem wir einige Optionen wie WordPress, Drupal & Co. verglichen haben, haben wir uns für GRAV entschieden. Das ist ein großartiges CMS (Content Management System), das in php geschrieben ist. Eigentlich genau wie die anderen beiden genannten, aber GRAV braucht keine Datenbank. Es speichert Daten in einer Flat-File CMS, die in Ordnern organisiert sind, anstatt in einer Datenbank. Das macht es wirklich schnell und sehr leicht. +Die erste Version von GRAV wurde am 30. Juli 2014 veröffentlicht, es ist also relativ neu im Vergleich zu WordPress (2003) und Drupal (2001), aber es hat sich zu einer bekannten CMS-Alternative entwickelt. GRAV wird von weniger als 0,1% aller CMS-Systeme verwendet - [w3techs.com](https://w3techs.com/technologies/details/cm-grav). Das ist nicht viel im Vergleich zu den Großen - WordPress hat den Markt mit respektablen [65,1%](https://w3techs.com/technologies/details/cm-wordpress) im Griff und Drupals Marktanteil beträgt [2,1%](https://w3techs.com/technologies/details/cm-drupal). +Wirf einen Blick auf die Nutzungsstatistiken der beliebtesten [Content Management Systeme](https://w3techs.com/technologies/overview/content_management). + +# Drupal oder GRAV +Unser Hauptvergleich am Ende waren Drupal und GRAV. Beide haben ausgezeichnete Sicherheitspraktiken. +Bei der Überprüfung der neuesten Schwachstellenstatistiken auf CVE-Details für [Drupal](https://www.cvedetails.com/product/2387/Drupal-Drupal.html?vendor_id=1367) und [GRAV](https://www.cvedetails.com/product/59205/Getgrav-Grav-Cms.html?vendor_id=20511) haben wir uns mehr in Richtung GRAV bewegt. +Und am Ende sind unsere Newsfeeds nur ein paar Buchstaben und Bilder. Die anderen wären viel zu umfangreich für unser kleines Ziel. +GRAV verwendet [Markdown-Syntax](https://learn.getgrav.org/17/content/markdown), die wir bevorzugen, und die Konfigurationsdateien/Seiten sind in [YAML-Syntax](https://learn.getgrav.org/17/advanced/yaml), die man in vielen Tools wie Ansible, Kubernetes, Prometheus, Matrix ... findet, um nur einige zu nennen. +GRAV passt also nicht nur zu unseren Bedürfnissen, sondern auch zu unserer Infrastruktur. + +# Pinpress theme +Nachdem die Entscheidung gefallen war, begannen wir mit der Suche nach einem Theme. Und davon gibt es eine ganze Menge. Einfach und leicht zu lesen war nun das nächste Ziel. Und ein ähnliches Aussehen wie unsere Haupt-Website, die mit [Bootstrap](https://getbootstrap.com/) erstellt wurde. +Das [PinPress-Theme](https://demo.getgrav.org/pinpress-skeleton/) scheint eine gute Wahl zu sein, und bisher haben wir nicht wirklich etwas zu beanstanden. Es war ein bisschen schwierig, es an unser Design anzupassen, weil die Standardeinstellungen des Themes nicht so gut funktionierten, wie wir dachten. + +## Theme inheritance aka child theme +Wir begannen zunächst mit einem [_Inheriting theme_](https://learn.getgrav.org/16/themes/customization#inheriting-manually) (Child-Theme), mit dem wir unsere Änderungen vornehmen können und die Möglichkeit behalten, das Theme zu aktualisieren, ohne unsere Änderungen zu überschreiben. +Sobald wir alles fertig hatten, war unser erster Schritt "Aufräumen". Wir haben alle Verbindungen zu Drittanbietern entfernt, um noch mehr Leistung aus GRAV herauszuholen und eine bessere Benutzerfreundlichkeit beim Lesen unserer Nachrichten und vor allem beim Durchklicken des Inhalts zu erreichen, aber auch für uns, während wir daran arbeiten. +Um alles direkt vom Server aus zu hosten, haben wir uns außerdem entschlossen, das Icon Pack von [Fork Awesome](https://forkaweso.me/Fork-Awesome/) herunterzuladen. Ja, sie sind wirklich ... awesome! +Schließlich haben wir dem Theme unsere persönliche Note gegeben, wie Favicon, Logo, Footer etc. und die [twig-Dateien](https://en.wikipedia.org/wiki/Twig_(template_engine)) an unsere Bedürfnisse angepasst. + +# MIT license +GRAV ist lizenziert unter der [MIT-Lizenz](https://github.com/getgrav/grav/blob/develop/LICENSE.txt). Dies ist eine sehr unkomplizierte Lizenz. + +>The MIT License (MIT) +> +>Copyright (c) 2021 Grav +> +>Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +> +>The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +> +>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## Rechte +Du hast das Recht, Kopien der Software zu verwenden, zu vervielfältigen, zu modifizieren, zusammenzuführen, zu verbreiten, zu veröffentlichen, Unterlizenzen zu vergeben und zu verkaufen. + +## Bedingungen +Der MIT-Lizenztext und der Copyright-Hinweis müssen weiterhin in jedem unveränderten MIT-lizenzierten Code enthalten sein. Dein neuer Code kann unter einer anderen Lizenz stehen. + +# Fazit +Das Ergebnis ist nun sichtbar und wir sind sehr zufrieden damit. +Aber nicht alles ist perfekt. Es gibt ein großes Problem, das GRAV hat, insbesondere für Nachrichten- und Blog-Autoren. Das automatische Posten von Nachrichten auf verschiedenen Medienkanälen ist auch 2021 noch mühsam. Wahrscheinlich sogar im Jahr 2022, das nicht mehr weit entfernt ist. Du musst deine Nachrichten manuell posten oder andere Lösungen wie [IFTTT](https://ifttt.com/explore/new_to_ifttt) finden. +Unser Plan ist es, Nachrichten alle zwei Wochen oder wöchentlich zu veröffentlichen. Für uns ist es in Ordnung, diese manuell in den sozialen Medien zu posten, bis wir eine andere Lösung finden, die zu uns passt. +Wir werden also sehen, was die Zukunft bringt und wie GRAV auf lange Sicht funktioniert. + +Wenn du mehr über GRAV lesen möchtest, schau dir den Link an - [Was ist Grav?](https://learn.getgrav.org/17/basics/what-is-grav) + +# Und was jetzt? + +Wie wir im [Fazit](#fazit) erwähnt haben, ist unser Plan, alle zwei Wochen oder wöchentlich News zu veröffentlichen. +Damit du unsere News nach Belieben verfolgen kannst, haben wir einige Accounts in den sozialen Medien eingerichtet. Du findest die Links in der grauen Box, oben rechts oder unter den News, je nachdem, wie dein Gerät/deine Auflösung eingestellt ist. + +@reddit followers +Nicht jeder Artikel wird in unserem Subreddit veröffentlicht. Da die Regeln nicht dazu gedacht sind, für sich selbst zu werben, werden wir nur Informationen über den Datenschutz und andere Dinge posten, ohne unsere Nachrichten/Blogs zu erwaehnen. Das bedeutet, dass alle Änderungen an TECH SAVIOURS nur auf den anderen Kanälen erscheinen werden. + +Wenn du irgendwelche Vorschläge oder Feedback hast, lass es uns wissen. diff --git a/pages/01.blog/our-news-blog-is-online-with-grav/item.en.md b/pages/01.blog/our-news-blog-is-online-with-grav/item.en.md new file mode 100644 index 0000000..758c6b7 --- /dev/null +++ b/pages/01.blog/our-news-blog-is-online-with-grav/item.en.md @@ -0,0 +1,86 @@ +--- +title: 'Our News/Blog is online with GRAV' +taxonomy: + category: + - news + tag: + - 'TECH SAVIOURS' +media_order: 'ts&grav.png' +aura: + author: dan +date: '01-12-2021 09:37' +published: false +--- + +We are very excited to launch our new News section! + +# WordPress, Drupal, Grav ... which one?! +After comparing a few options out there like WordPress, Drupal & co. we've decided to go with GRAV. Which is a great CMS (Content Management System) written in php. Actually just like the other two mentioned, but GRAV doesn't need a database. It stores data in a type of flat-file CMS that are organised in folders rather than in a database. Which makes it really quick and very lightweight. +GRAV's first release was in July 30, 2014, so it's relatively new compared to WordPress (2003) and Drupal (2001) for example, but it has become a well-known CMS alternative. GRAV is used by less than 0.1% of all CMS systems - [w3techs.com](https://w3techs.com/technologies/details/cm-grav). It's not much compare to the big one - WordPress has the market under control with a respectable [65.1%](https://w3techs.com/technologies/details/cm-wordpress) and Drupal's market share is [2.1%](https://w3techs.com/technologies/details/cm-drupal). +Take a look at the usage statistics of the most popular [Content Management Systems](https://w3techs.com/technologies/overview/content_management). + +# Drupal or GRAV +Our main comparison at the end where Drupal and GRAV. Both have excellent security practices. +Checking the latest vulnerability statistics on CVE-Details for [Drupal](https://www.cvedetails.com/product/2387/Drupal-Drupal.html?vendor_id=1367) and [GRAV](https://www.cvedetails.com/product/59205/Getgrav-Grav-Cms.html?vendor_id=20511), we moved more into the direction of GRAV. +And in the end, our news feeds are just a few letters and pictures. The others would be way too heavy for our little goal. +GRAV uses [Markdown syntax](https://learn.getgrav.org/17/content/markdown), which we prefer, and the configuration files/pages are in [YAML syntax](https://learn.getgrav.org/17/advanced/yaml), which you will find in many tools like Ansible, Kubernetes, Prometheus, Matrix ... just to name a few. +So GRAV not only fits our needs, it also matches our infrastructure. + +# Pinpress theme +After the decision was made, we started looking for a theme. And there are quite a few of them. Simple and easy to read was now the next goal. And a similar look to our main website, which is made via [Bootstrap](https://getbootstrap.com/). +The [PinPress theme](https://demo.getgrav.org/pinpress-skeleton/) seems to be a good choice and so far we don't really have anything to complain about. It was a bit difficult to adapt it to our design because the default theme settings didn't work as good as we thought. + +## Theme inheritance aka child theme +We started first with an [_Inheriting theme_](https://learn.getgrav.org/16/themes/customization#inheriting-manually) (child theme), with that we can make our changes and keep the possibility to update the theme without overwriting our changes. +Once we had everything ready, our first step was a "clean up". We've removed all third-party connections to get even more performance out of GRAV to achieve a better usability when reading our news and especially clicking through the content, but also for us while we work on it. +In order to host everything directly from the server, we also decided to download [Fork Awesome's](https://forkaweso.me/Fork-Awesome/) icon pack. Yeah, they are really ... awesome! +Finally, we gave the theme our personal touch like favicon, logo, footer etc. and changed the [twig files](https://en.wikipedia.org/wiki/Twig_(template_engine)) to our needs. + +# MIT license +GRAV is licensed under the [MIT License](https://github.com/getgrav/grav/blob/develop/LICENSE.txt). This is a very straightforward license. + +>The MIT License (MIT) +> +>Copyright (c) 2021 Grav +> +>Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +> +>The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +> +>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## Rights +You have the right to use, copy, modify, merge, distribute, publish, sublicense, and sell copies of the software. + +## Conditions +MIT License text & copyright notice must still be included with any unmodified MIT-licensed code. Your new work can be another license. + +# Conclusion +The outcome is now visible and we are very happy with it. +But not everything is perfect. There is one big problem GRAV has, especially for news and blog writers. Posting news automatically to various media channels will still be a hassle in 2021. Probably even in 2022, which is not far away. You need to post your messages manually or find other solutions like [IFTTT](https://ifttt.com/explore/new_to_ifttt). +Our plan is to publish news every two weeks or weekly. It's fine for us to manually post this on social media until we find another solution that suits us. +So we will see what the future will bring and how GRAV works in the long run. + +If you want to read more about GRAV check the link - [What is Grav?](https://learn.getgrav.org/17/basics/what-is-grav) + +# What next? + +As we mentioned in [conclusion](#conclusion) our plan is to publish news every two weeks or weekly. +To allow you to follow our news as you like, we have set up a few more social media accounts. You can find the links in the gray box at the top right or below the news, depending on your device/resolution settings. + +@reddit followers +Not every article will be published in our subreddit. Reddit rules are not meant to promote yourself, so we will only post information about privacy and other things without promoting our news/blog. This means that any changes to TECH SAVIOURS will only appear on the other channels. + +If you have any suggestions or feedback, let us know. diff --git a/pages/01.blog/our-news-blog-is-online-with-grav/ts&grav.png b/pages/01.blog/our-news-blog-is-online-with-grav/ts&grav.png new file mode 100755 index 0000000000000000000000000000000000000000..46352255265f2d0bd1615799836d8d3b6faf022b GIT binary patch literal 150348 zcmeFZg-ihrpO-El*K23aoVm|A_qk`*@K;K*cy}o8AR!^)$-Q{4iiCu1jf8|2i-iH+ zS#OCS20ySJU+B0XA)(A%|3T&_c=sK=N#QE3?W*Qr?&@LUY=-3F;lXKTZ{uQW;%LU{ z;B1ky{ge_3={}O&b4hj2)XiC&GIKY-h4Y;`znxHf&H=>|ysrBKj4U6>)yD+i-=Q8+^+4PB;Ia6{X4kh}>m$+HMgun6c^j1r9 z4rE(p?wmJi6MWCMwDsPB3W#NB6pmN=i2D?aA6MqboQ>~@^YQW?1ZcM21qLI2nf|@} z2mc5aaX)$a-&;t>Dmb|wC)X}O{5p1f#_`{C;AiaW|DKU#n8r~4`wMx}E1dtHjo~IMe)LAUrlxwR z*>IvEeS3YpwuQsaN{VXwi4b^9GI#$&p{7_}_KqW+T3&abcS4%Oy0yni0<-G1GrMKm z&#S|m{Myg=l@vUjH!0e|!|kGSnYzD;PD_c7y^UR7q}>jpwN$jxooJ}3$}YCE%Soyc z+eu8KhPss2UR2WX9W|LYtdsroZdhOCD_zflwO)ugI#Z8H(#*8c@Ce~=lxbFFT}+o= zFn3p$PgJ!{-%Qx}@tW%eHcyY&)Oe*Vho@V*6*iWhH+&OmsP)mCg^yR|Fnecp`!u-~ zZ{(+2n^Jk4?0Y=g)*VgWhL@22o2#Us@ZXx)j~72VgWzxejM@xQ`tvtxr!HzEFUndH zC%JZje)WbukcS~A>H-thR2SR3op=PCxGIaUGtWW|F3RZKwLGeG_!@nZ8lmGgVgf?8 zZiPmN&GLHFDl||Yn$dC^7l9VGHngV?*IaLy2BvHLRhyk+~bLSzBG)=o7Av zqdN=?bfTHSP8()T8|g`#Sx=jjq#09J1OIwG8j?>zDb97UOq!V|TiMw(*7`IyHlC}9 z!wX8_K7OT`K4k-T_VRimIzHiEv8IwZ-qNLi4wZI}np;Rj%9ll2z)oDi0N6;b2QyZ_ zf6dd4sd)#g%0G(Ej?T_s7>x26OnsT1+X7A{IFwL6Iovi}-5ju8`{$KYQ?I04a{g1I zAe&?BXOELJvxm}}t9P!)i?FKij2yOK*Y&PPh4dj%P=EAX+0{kBLvg~@V8YE!%fqL( zwtk?|$4bOJ$GbpRq+U#;7`A#;xi$*zvL0QTd1aUWZ>pPcuRfhP|E}sj+=xZD;!)cq%)Y zo>`@Zf8AbB_a7!`XzFWh+3+dq_HODvi4?TS@y_wCpfAxC5TYyHE~U-)*A>+ked=}L zDrH$+KfV88qJHk{-qgD8D74A0uWo*Wj zB7b#06?1pfYIW0Zn#rJRvtadUzbI%%d1$7;a?GURpkJFt9v-d>el)$Y(H)&Q)4duN zzxIoZz{wls?QJu>#jy)$bfHgSW5GEkN|9^0U~|`-t!&A!r-B?$odK`~k_n6|oVYvGy6I_o zxFxvhOt=|r=*=teHoEiZQ9UR;FASs1F`DHOa>(}|;TEzncdi-u(l)kIWTHD^g4Z@) z$h5{r#pFyg$DL-gx2?UTevmxzi)QvTZC)sC)GBQpp!6Ru=1uS%zq~18{^JU~#SVVa z$CmS3jRw=%08Ic#(MOXdI-RSbTbL693Xq2EhLVPI`VsFc@7K=T$c=26(fAJs?gKILHC5k)3u1-yYn7uqgo}Q2kl7<&uh0kQCbhlguv_oG zsB7KWIa8Wn|4{Pha(kXntVJ!Zv0Bir|Nnwt$~ z?DkHjTh(c^Q(&u_%LUwDVQw|t>=IIw>-9|aguAAcYHi14zE_!3UZ^H&r2cuK(ppY0dH?wn+}Msq>! z$?@F8xo~5p-bhS+0Ako7Vru}TO`P=2o|27*mR|yA2bWDCmmU>oG)maGxH(8g9uYu) z<9!`JqqM=4Hq2S&L(^p|6wo45&s8rh$aXnN%+JvsiHX|$Ik@w0ZvI>(KUO&J?dmrD zwbe*h&+`DB%4$Il0!5GO_(#hySwlmi-e_`tc%^xPB9sK`QP5gaQtGcR%6ks$z}Fit z<5=S2|2Glgq28?(L77z|R8jGzxn|<{a&BJQV62U1CYZE;7WI1Yzyy(N^h4&%O{p3y z*c!jfpXq08EYhYora0u==eOwjRiB;1%j+9O`=?zyLW*m(ECdv0g{zX28)b`Z&DPuu z>HeSs?1Nh6;sFFJB&3DkFK_G>n4DSN-e}?6*}p6j-#9DT`9*7Iqi5l~_;Xub!Wop}wBcv!3W?1J+Bnrp4yhuGios4l0*a8`sz<%q_^J zs!7rps24L76|NWi+*-JnqSf3WT-i`2oV&PVA4NTGa^c)M6L#*nvzZ2x$IL9k8X>|P zYr<(a+b+Kb{895OU~8-ZShzSW`Us_gdQhSiI|w|Na2fX7x<{(XR)ESh@f+HPN0Nx2 zmOA9$?Ci|Bo{{tVqN&on_F}I8U~uhfYTT|Qg|gu;KDl>xPH=PN{#saEZ_qt&<6k9<)GgTDCD0=j?}nIXXw;#mDPp7wDIE&325H z%j*Y3C*K16pR9|`D$b6niSofx@XH4^pc$I;rT!x=WEP47okBQFYyNm9gIt=01>dMp zihjqsT-gn-8??@-3_MX-)}0`%;qYKlHl_D;!+JVb>pEzl}J?I{u}zYE`^npV)B($pv;d78O;1J7?Y+MH>qr8y`HqJ6agE~=o8Ng z55It6y2IiY=vz_2#x1-ItM@jXrDA#)Wz8a0N!uAU%uh2-9*^fkd+^E!_N{fQt4xwf zD{HGwC?_h{F7Q6je}optmeS?ZI{af6*3dv}mfNejHn||m@-G*|PVu0_xLOU!RDkdP8{9GV zE8-P#8Sg{8Uhc6sVy@qxY1ifb@|BN!O5g=kibK;ggx&hOemM>G(~p_^X58@YCv$em z3PuYiv|81RE#F(@c))rmiFjjOY^od1B;6FHn%ve_^jl$?wJxiCw)v-va09%I9vvCI zgOvG39}l{9hUVs44++eE@1*N_A%=3-`G7m8*lr6<&E}V_e3W0Zo}4~4CAw^0Pz{YP zP}T^T=bp86z^WqUvsLqSbdx!XhaZN@>4a5lIT#3v3gsBC=hLci5y$o z6k-YV!BHBOuT(I{FQlb;UJF|;0*zSdh3Z#8(6$4I=n6;o6w3Gy!+0?UV>w2`g0jjiFGfZh>dL(|W`P4yUmoIzv-Y6e~1(vvpLe)fnk%(OBq{?qlG1<(j`4yTxp4q~KF^iQ`O&lHc z7vkp)=8LH|mzz+|j1A7(OX3I@d^>wVw=Qt@QRz>}>X7*xvTM|o<&s=y(f)Ty=H59L zXKyk#mCr{(b*^yDaX=xTM^)FViLgqv~uEfkcFhud$;G>+hgv*+GM z8GlGXVi~eaz`izqQ|*Q%Rq~7~h;QZkl?)wWUPyYlb`Q?mDjt1-2dEp_4MkS2YLr^P zubi9Ry<#GmKkCyS%ZmE*J_>B^dLp1kpvNL%>h9J2VBikv;&(SXag+6Mm9IVg=07$& zdokl$!dEhZeG=M;jC;~MW{ZB^UicXT9zYZ9q1KmUIS3D7yZ}cxuUmkTsKSI@98pfuQ>?a#` zf5Hc#r+8|WhQGKqET03lAWxdZ!Rx#>pimc@pEeD8OSv@A&W|C-ni{1=Ru|gY*?^Xp z1R!I3r^bFGv}f-X!LJj_6YFukg37|*%i``0>p){r+Ne@mkGp=|UIBp6`}JXu4B~EQB@Z^f zcy^j*_Ltr4I4Fc1vm;WXRW_vMC1>66{ZPk^>Ek9jy@-O!0s^g8U7EUsS^y;f-1+tS zV+Xyd-g+In8@M)NUANMPAAA~X114HGO3yda*OL7CgH@$M!q$ zlI=#nT9Jlt(Bkc{wALHirlmFf3h9lNiyrHGP!2p;*fy(PC})wT##NSyUgt6_e?Hr5 zV54XdE`F5ZE#**_&3uE+<{NB^Si2RTCtUP_dQ;Ohwx^|6a9(hgd!{N?RLzXWh(lFl z>*L^Nc$5s!s}JZ`R|5$lLT?6?t~FOB3pdSf4_`pV`t&#@rZ8>oY(R4l6qD=L&`o20 zT?BMOcDAM|u$g{xx_`2TDFqJdMwXM0oJ@VXb|%%`UU$@dy=tJJ^A2wtS68E%-@DKW z7~k+|p1*FjktRiMNV70&ArX&M!2J`gS)6)pyC zCaOr8*FZ{RSh*HRpR^n0fEBjP);4Cbo%zr2e5Hl&(FUx?!VUXZ;cf6_I9DNCVTLBv z>Nb&xS%Yw$xAIXbWzHlAY>!U7dGx&SvOuGl(#-3|M$20p=TAV`s-;BjWy1xXct@nD{Rp@~h$y{%Vh6%3@cbsEKRzUCZ{ zqmsE_BEsLLbSIzbQC5rs0ZNL>yQsSXxJA_n9%}zb_QJB8p(o?&)AS^vonOt_{>o8T zef@<}l69i3hx<{hVu?6&j{ao(Wlrn*Y_red@9T1i_L_F>867SR2@ioi!^g0J{F*fVRnBFavA7~E|GUp_-o2RjIG*l z?{n@{aBj?PZzZK$ZRr1t5v9^H)VYX;!>tV(cTQ?UvGwTk{9A?3e$0DIk{#BIO^npf zAkMwXW3TJ-!jFIUtuVSHSy(_v1N?-tMrfufg7nB&zCb|ps>#Hsqhoco1_&WQpW`~| z1N_ik)1un8${Lo7 zgHSv9+T~C9>j!=V_QoaIVLQjmUaeFdO~F3()c_^R^{pH}?l5(*_z=_=OJ^1<%BX1Lf=FFkNgIQ@9NE zht6iTdGh*t`nHH)?$BXU%ft!Lou`FiqPVr{9s&xr4OI>KCdqRpjxtBhHRp{j6<>hL z(rC$Z?RyBjpWo%SAy_yh9YnXoa>SOEr_r)QL`{`&^I0)mtAJs8UBadyKfda_sc;U^ z697~}{@1K}Js6ME*awoWjSlE2LB|3Tsb8bR$&?uE$Y9=7bUePM>5yuuFsk&j6mFzt zRC4*fq1f9T{|edgXBwU!5A9z2ygwk6^Jk>Bo-6OJjX`peym37Z73}ZQsAqcK6#m9k z$vdbXRgIvp!$3`kU?!@!^3FPNddAVvbnAsh^YckH4r>)=rKsrRU-nz$V)JX~u*({% z29vcM+W`lx8Zng%^P?YdHE8X|5AQ*pshP4LaQA1$7P;>cw>FG-Zj|83s2?2mh6mGQ zIb{AF$atg0tB=Qp^MotUn&C9yRe_SJPi(q?*^b59O8F1$fQFR%O9LjGNI+rL#0 z>s)tL=A%8aIX;8Y+;dluo`CeoD^eM~cnJ+FIH0Ow`o{&;fF{@Ldv&xL9sBInvfD0F zi{D&1A&)3SfcX2H132^}fRHwFMKLLYKm5t+g>*48s8j|222})?W^XC38@a z2F3=*4a=evCz|lLhOb4KUm^|pDQB;ZHUo~u8!JUT?0d(N@$_QS4GdH+PT&sKK6YzL zvsXX20(`9G^~NiNyl=!(ZvGp7;tsepIAe)+DDCuCbhE9*sgBnq)4a;@K49NgyLi?* z3}jD-6Bv-56$L~asoKS?RU(8l~k_XS8%|zb_BfwEWV@W zUFBYzcX^NwvquHijply*;HHt;609*5DMM{+JqJq-)7UAo&r4|Xnf8b3;E`0#jVmb+ z>&`3z%5!c^w>fcE9kr#c_q9#FEKfRZ!s|LCjBxnn47pk*xCfj#1i(hg4wB(lC704t zWq_(KrfE;^K`{;gaag#oD$U$1a?${iP{0|{;p*JX!0f+vhr|;9+A~$RW&Al;L#fQ8 zR`s3y_|2JV&=v_ChWb~|ZvudQ!k?Dx(IJ((*2BkWGs3Sy*+Z|k`OuDtOv|BQ zu;{YvncLUtx59R5N!xGJZnU}+)yRo zm={qau49qYP;iz8&jF7%IvwBB<_qTxi}TW^%E7$rAe%&=>={mM0EFB5VK7WikAqU& zG9_^CnsLply1i}J>}y)+R{^ZFeD<*Q*b1+j&x{JCVF56mG|*QCzd(4L)`;x7EopiW z3Pctse7eMMPr%UV!sLhy$_rHP>qf+()W7=dcjy+eQPz#B$GO?=zj0-;GuW}r-gkM` zYQf|)@_l`7r1{;5YUVKMbntx^mI$1@`xSXC3kL46CPfIh0cA;GT~4B_rWB8*tJ1L)i6ml$IxPQk!05o z!=E%muv(Y2^xN)jl}g4ulmow2Yskm0pS}~s-ft_O=|$IrgUAm((t#;|?ak z)Ax-NJ6x3a4R_dA%;9D{`uH%LLoyhh-I$5jD-d(CGiOWyhRu#LP82CYgSiQ)3T^M# zr|k^53XG?$*HgqiWYxp9zJ3~!&CiZk-eX28QjSCgU0brB|WA|gqYh}4!Dij8X!bedbW+g?$!U*_kp;Q6-pq6w~J{0~@+))kf0kM2B#G3$rQ1cVDP!Eac<`L%`=_B@3eE)- zbMCjk`%-!8s{9XM>@qnx)1C0dCfSYag>koL zwIR$>_4yHA`K9<@{JgXHNoDHqCnJA9pZty;;tq8}likH@X=|faV9lm^RsP-9GAo>~ zXwlq$m50_8o$VOj{NPy#J??btNxy{{ zo3>QBKgo-g_R#u&1WXx}IlBeh8jTQ zYEB$07_}@I9xM3%?N0_SoO|+!8G4c4>RvzH4b{{QC&>-MsHynEl+2PH=iD34s1;{f z(-#+KR@_sawqycV4f_#%cJxZHvd2+Yo*2F_h(sr zp_R|I=ce!OswxSgQvAG+!4rs#YtD^I@q+H`)eCyBm1Z_-O$lU`tf@=VTW99$aU=W+ z-%qy8ih0Rj7NltVnr6ejb*@*lru^f8t+@znstrHcYS6vsYdFa~jfA`gzR;mkiP+)P z#U$w;%67s~-c%D@Q@Z1?0RFA0w;qR6An+d}45;7KpgVximaPR9OuOxlW<|_zb_;a2 z$zDz1rXx`{$p^6C9@xOQeD!l|FXO14-xI-Rvuz09lJ~rj;SOHJwZJv~lc4XnE>Cy% zN!g#Yh2+0Unr5 ztc#zt-120DMaBD9#N}Zwm*2W_Ko?Kc#j!SH+$Smg`jr?de4+<57sW4bk*Fz69NrlV zVXicIf4xol7M9sxUOvjt4CX5`@p5h+fU%oW=uKHO7uhp~QDg8XmPgLgEKm+u%J6*P ziTs+lWShWpYi-hT90HK4GEasj_@L@4KQQ>qKD}$|lxH_%)lgSS(RUl8=!cuU?qtbH zB!2lv(E(V7D)gyG!CbI|H8)l4@M{RMh{J!2=e%8f`{(;@GW-=Gj7@D+?8eCV)XQSN zsH@7c6;E-h7)Vf<;aUiOi?w+iD-_v5-a(%AywV{37I4|Uw|KjN=jR6B(X31s@O)d} z|J%*bf+Pj3)6-dQ{XHT5^_GzTl*r*tV^uJDKtj>`3T(OR%SwZs+i|w=5P|ibApX82 z2nm&L&6>v`(%D+NL2zvZrS%ljd+{-rVq{WSDi|vE zbT_B%CgQB1qDz?UdztJX`IN@2tiA4GJ3}5a9j3{_l6n8?88#|8#2AA&sfT)SQNfhb z?~fFb^h!+1*5g|+uQ%U%WDXR}M+Kg51w22Kc|`N*|9EtbU$6BD)W*O^#HJ(4Wj<}oGC`xzeYax)&;j=RFED2(e@3Vjb~DV*N0rsl-m59WJ+txY(5yH zf0g+hwnnu6lDd4+9n+T(!~zeDh&MHW5XedWP`cm+EI|>;?@lRkcDPYH!bXN zgnUMVRxd+@R^RoI?wc$8*9Sm+{5QKFGC83zbHAlH%+jjq`!6lJ+*a~!PRU@JO=Ef- zoz4feYfh`&VOzFC?p8ac*pq0s3Wiiz!P;yw6OV)Kb>L6;v4Zu^kx2r}(P-*1h+Nm< zvbh`W8qbO7mQAUL_8Mgwk8?c!zZv{)tK2q|WH6<5UQY69zXfTfXLy2k2W3q~wM*n< zTMT%hw=uJ%N6`<+vtaIV&ERcq5v(rq0-JCm*QH1Dh8ID8K~jOJL4JX+Gv6C;z9toM z`tkl(w14EAhhQJ&Qah2UC4_#*y^3jWzuieU0gUSF$Na{;Z&B#%3p(k)z0xhj4yHPD zY!mKTGX9CFCe*&uBu)6U07(<|qfVg$4aZAv87Jzt$N6jIQRHlALxY@h@cVz$Pw>VWM?jSXxFIEbs z)XOa2`WJ5N;P>Olh~#b{9gN0N^-7U1`an>5|KUN>kaPTK;>UP(r(h+Wk7%YiYp6p+ zu06U0wh)PU)dW;rBpGCeK&c=r2wHG?xDXnBDLyg%Gx0MgtS|rq-}s@&>3b`mWvdu) zJ|mVirg6JdgC$YIb1RCgj}vtImvqvzLzAPp9wOUf#v}IyO$2JiP8>&Z$%?9DJ92ZQ zC*o2+=jJcZGwpj%xOg9b2~BB1Fv|3f8cTMSX~d`7fxp~>Y!E=exh9 z6W9$F6uqiiDl*(mdlJDVdUU9vqb8=reJrNJqe4L>f=RIy1An4~{v&7>7Kli!up(>J z{`m|zq;+2llqO-gv^DlCLuX`Di$?zB&y7( zJ$pT&l~*zpqlsNQsXyK@@h1Q3d~bGae4GB$z95PT+*0vLIUty^0sDjmJQ=69=Dbcz zNuqUMGI=!_C0RDC7Vt8I@24`ldHg{8TKpEP>mjWyHxm!t>3*AL&Hh8>ee&o%<;x!T8jH&X!7^G;yhO~WI8A6zEG{kc zNBdCmF`_Wckz%pC9-6<3V>vIUvv6k0Scz3Ixg(Thzw;m6;JwY0NyN-b_cWS%Qf7uO zo(_zHmjiS$1- zeH?pAX|&9ZZ%W>=S@GXC8X>lk)fSt$=ndnEBSB@-z|+-V5>n;_c1(Zb`6BLT9z7~! zsFZy*AIclYr} ztJI-W>NcXy4zWc#1gamhQXwjpY5^eSx#=23OZMBV*y+YZ5sxQC3-KpW`Y~vc;*kmi zyZWh_*G01+uYxnjbFpL|;-h@PZiZcB7boaM`&(rj+>Tjd zttoql7QRa`EyF#si)~C>M*BW2Ao4qIFZwZh6tWU(4vDuhTY^6R?^i89$%HZvShJtZ zpx!#uEEo|9-r`{2jnN7A2m@B4+0C8)E*7D^!tO`D#D9vrdFKR6PUkNDpQ0na1#RO; zugJHFF8*{+r4Fp84!&WEl~St1yk&fMA`rt_$KIFZsAe}?-`)!?)RrbuT%;MfqmJ4a zbRMJwQO)FUVtDBGSS9$^`!EzErav`&?}vr$q{AO4w)rM2yMPuuT<)&Q-NDscN4CF4 z>J7&Fgn5^l?wbVrDfRt;=;&sF zIFc|AGo)n+(|s?SeJ|8k3I7^!6=3S5&jX1dWPwAdqxbunw59Jl-N|(%wb;WJleC|7 zA-fHUTY~pJolWwZuku&cho@+_6I*xK+Cfo@(9@B(F$|I22}2y?M1>?&_8&dOQoFb5 z^abU&M8=8+MjT;C`G@&6ugLq6_v8#88dY|0h>F+d{`E0rKK6{<*_(VxI9>2NZC8`# z6{;=s-+F5w+eS(+=1q-^rrNC*!jw){X_erN>bHR|K@5Svnhq*sL$Qbe@6K2Ft;%U8 zJi0DFe<*NUtK#qx6w*6g&2i0XYTZ4kiHgV8-373690jz z)DS{w%-xn)|Fx$ZxrwCZ5j~d8y#pmrw&)VBK@sF)VPmo~m+02bQABN@{;Bd+&f7nuhMVzm#laernhO`r|%{> zzHgUC36oZQn%~z;U$q)9kLui}aIt!U1Vy8%ynH?^YI9F=QaV4J(6#E(QrfTJZ&(d@ zTLh8xSQcM4_xOH-{avnL z;}5E%8Ta4wVUWvnXE|!`Ph*Ohx}g`N8PxED>Q;@mES|trS}pjDhvr+*5b_#HNbR$q z8oxhvfQ0Z)|7TCC0y6r#!z09G>m7)4Gj=idszZNuU-t6nx2G>@+!kGjtK5 zvA#daZnca4L~zJJt^&Ss`N@rin}}R)n3W{~l)5J(jE~-MptaHsprx(Nq0GH7yobhc zSAbcZti9BtmJGc&FdCH%X_P*4{T=#U?$6=>-qShVl~s|^IZJto2vKiwMEP)|I~qH9 zz~zi8z#S%JYvFU2QuEQzhqewRdhO`87y@E?EdAfeQdsTUVJOSkD7sQuD0=jfj%sB0 zn8{=7KHo1o;@^F|YrXH~vhVD=gt>u7jqXb$NXznYi&GECC+yw(M*qmv5?_biiW989 zxAXeBjqTl4cH$K{c%nRdS2LyX2yM1<8#TS{mmS@AtjUB-`SD9g8|V*yg*?tu6n$~8 zEF^Pd+}Bu0lDVY#@A-*j4$2xzE(+?%JZBiSSf54xCmf+r)AxVn*%3Z|hse9%OA13N z)0c((I~)@G^xZ3XFBDU-8qS^~&0rTXk$dIcchx{UWd0MyN0a!ByQPe-jlAZyw}K$s zvyjx44@3+vQ9T2GM<$T%d-{lOqXuC1*17FRry2UJd{C{#v*0GnT4}1 z5M5&&NiEI}y`X2oWh-6~ISAGWB|YUem)t{dfz@5Hc$QSZm_(zx_6ChOZFC)7kEcZQED9BjLgJhaS7dcGf4l4K5) z51^<-`;_Qf=jW!UZN34LM~{+w*<1L^^q@OD57ul{`|H{8x;@V>ljKBkJ(}s=#;Mxm z81lBnU!|xPBq5JRpQJ9P4ovB{GaeF{N+H~xzlIipGE|OA@Ir^1(RHgy@r$u7S6(Y6zC}U6q%t&3~j>v*T1`xV%Bj zf@^~HHl|S7`6!zUypJ#R{8-y=u|QOO{8*T3+JBW~r*f&&L);-N95iEWdQ<)8K+FO9 z4N1ymzqvcp1gHBJzW3G}i;4B=FZZ$R`AA$_Qlz-ETv^L-^9FRyrpQn+Q0I{b(Yij3 z@7Tw&bdYz|p7H}mfcwUn#q2glL?aQkG0lkKBPg}4D+y0~Vr^fmd4nX4qFWg>kIaRt zv938K{hK6`jaq6~po1aM2|^g`sL6bnL1vqlE&A!%Xa-ND2^s@=l792LqMY+RwWdZk zO}&Z2batgwZ}`*?PI%t8_~}`bVoAF9-nN0)kEI=73Bx+OVck1 zr@isDCAc}AEHv4AqdudV6jufkt=oN37Ry*t`xi*Z{f@PBL@wYq=Zc2iI(YPsrX#_L zBTj8u`cdbooH`>`J7qLdEs_JV>%=I=^LDbD(Co9r(bl%S`@pqy;O2TnC(H|2@&N~xV{Cv|_Q z#qe>8lR_8dvy`9!WM$$eGTY3xNV$IWP!uxM3}!5cY@%W6&igG8G9bZ|cO=f5KD#ZH z&0L7eEu7#DKQ+2c*r**+WgF zQWDn*A3|;EA@XQ)RD3i}q(S;(o?M~_k*3rMj@WCCQL|eJPWYVwp$@CAy^`l3*uOvF zL{qv)8SXktT!dI{7`W-4qAja(G5qOIkm<61$Z*Oz|65`3d)$a4 z{8nXa;J<~MW-!_pb!Tu{iC3U9zPd9!x5b2Um&K8!jL;G{cTkD(&NWAHe=2!W^cl^- zA&W-s8P5;g*Mw3Oy(ZLMpkqqviBo+^B<py~wIGV`GXpuzy{r~bmy_CXqh6Lg?iF5jWK{%&2!(5xdZ;`Qo!y*= zO$TVpN#adk7B2qmK-i6WW(ynVSr#zScI5n2=go0V>yisk*)y^emp*;?Z{u)ptzcG4 zefg;VGgWw4pi#iO>qRakb{A6hZG7C9? z$Yip*$hs#!Sa4hjgH)|-+>KN1?Mdy|(EmZ+MaV#E`0>AzaGNU3t44Z_{^GQ*POuwG zdZ%!p`(w`B*~I-?H~4@+5Lb{!5F=5d_uG$SP5O7#J)eD3qg}|ucmR;p(x;@d*=;g| zPW#uS4d39qfD_WZ9N_~@E(WalIdpcUWZr-`U0;aNUUFd`EBdAIL|&igxd?_myCd~T z31I|$450_y(PAqG&4&2e+SC4yF_naA8Ej)dNywskX3RFvDmNxjgZqW41kqTSOp%LG z?vS@(;V&SG4djCEg`(g14ojI$ymu-ZHl?L8rpUDf{Rz|Si0VhIk(g+u%W zR%0Opk*a&>XFy3DL<`NSQ4~9+9{8o-!3R?EitAXa7NQifirktctB15y`!7DJe}!Z2 zr5i&YGuD$Cnc;Uig_u3|Y#=${PN~ zd}*M~Rtyp($Q|I2l;LUnBTaB{zNgT%*NOd1cL*r}iIk{mK3kB8e`C4<#Sq;W_ouR5 zib~{?D(CN~gO!c99byA70z)HY%!8o2$D80znaXzY?{&AWMW(!;pDaf4$ zcjFEAg~!1X)^}caf)mldMB=Y0N8i8k#xJ^6BKHvfcxjL-cu(CCRlt$!L{-krnu-rK zBFG3i8d+lznt0C)D5l#wvdA5B^`rfm;e=lWnkm|_qSic>mL49Pil6-&+A~p2Ug`wL z0%q*6St}bxwyCa~T@gDz)O%?3P*{)|q{J~AqE>L>z~*x&GxGPwX@|rRFM1?M>EBr2vOIrSs_BZtAr_r92Xk!JdVYbqK`GT z{TKDXlN=Q#ufLdb)5Y<+pfp%`hWgYe)OxbL-U z=}V5R=RzMx>%d7kB*by!Hl8cG5v}2|UOREgvM`WvD6JIiV$&evfkwoxpRDjoTk!9p z%b;dpwqR_^5~^dVaMlCb1oS}gbrtH~uXkTbJo$na@;&ZH_^1SG>Heb=C%U11c6ptb zqDPCgW6y`pc9j;008%$ZAEVqwB||1dVo;lU(0(6dPs;!2RH`DE_dDGzgfHUI5fyZ+ z*&7Z3UmtG+%8S|t%P1~8n*W`C6zlfl@{YSm%Yl_a%FG#If==8C`n@csl%wDpgHVVR zd7t*{&UTUKs=d=Ptu0+P;9D*IW}L7oC4}J9q)2GpOrwo%VxQqu50Qj$1x6D!In<~T zNvC#M`DW}?a-9>?6WjlnOuBh)6nCo~aH0oD2T%=)^K0Cvo^!7{GL?yTE(xoOwasS^ zBDF}oYCM4qvBkP5-x>}y%1z0b<cG=;WG_ij-$xJimkwmHYU zka_GqQLYTWH>N^12s95WZp^Tjvr&m)PCp*!^G}X$VCC=!VY zc!gG$ZbKpx(Qd8JL)C^rk_p()ur-#lPO(M3e8CMbdklR442>Kk6~z~aT-I{75;O=v z^8HLA6y`$SEtvJZV@h8&_b&4wtZ4vTqx<%>_W|iUvgr?~r6^Zqo}U()YuU*0|B(xR zj6*5=9p@sH;KG`q`b@5_`j)sSncV1mBO*Z1{T^de7ur}Cv1RLU#iR)7gD7Knx$uSR znacbC1x_o73mFroe%*nJ@uh<|Z@8RqtOF2P+gO zZs|VJhM+8U!diQj7AO};Gas#>@Y>yXe z5e-~Zz?*^4{Y3>AP*`oz%z@s#ip=pfK0%1c_@N_;qujoi;Teon^(P>QKzq$k?R5-| zRrWull83t|TfWA#`708z#<~3(@cvBti;o*YKOk<9*1&;vha{Eez{)_jz+YRf&2g%n zYtAhLwd=}PpCWFP(lf*szH?~L{g#8lnL(!kS~AC|VU`H61+5{-o(3*DDQ z5UbtN^@|ifZ(>`0YM&Ezw=ssu2l)|0xlhJ48=f)DrwjorjD}f^kz+QZyH6cachN#V zBljg@albXbyVPyvVbS5cFBBeI7eqzgJ3QQXJO2oxw}j_YS}x#kFT5;Kuv^h&+eO;t zU4VXy==%<~KF|SqxqZr+@GUql5{jr4O#ap}rLGzcn$gjx1K>JX$5RD9=%VdEYDdvs zZb|0O!AA*TM(Iy4U5bbz7raZ>czwH^DsQ7q0TE@QzbMCd#s3l1I#D%FLR(TuAi4|Y z3j`7xe~;dAq8u`jJ9*M`zpIj^mI;3xX>u)2gF{**%vTbU)7dXoQz)%Hzi8Eegn=Wk zsZJ*1ha<46HmBOB#t;$N^h@Q@^t6c2DxA~ z9BqiSerI3P%%w`0(*o;)EF^-0g`31VNEs;sx%;6}t`!=?-#bQ&`h#XqzJ(Jj2B^uM zA%RODpWgMqVLEXU|Dq1=p5reJK^y`Z*BuggIs!8YU7z(k%oh_qNbL~%7m~ppOhmzQ z%b2XmZgQQfvWgU*ha={MBOcY%SnNOO2Zp{WJeZ9^tO3V@9bIwS}$q{ zGQfFiPZF+iAVc*-w>)q!1%hF}=Dxiw7GEBzsjD{6jc)-K3CXbtQ7h2(tFW2wQ_WhvD6Z6>$Tn$-&@o9l$ZmIO&7clyxf)N~B zL#o!fJK|5UoK;orl>`i&j+$L*@=5VuCg44|rg z;J@F9K6N^mrKv$-3)(?Zmhee&bgL5sLSF#tIZA!L!xvdv&fa5h3 z&IQ~-qg#^A`oO_Dbt5o98aB}gVn!18_e z>cu=$f<8Er$Egb(75pf6xJS3e=w?-1Rq^@bO#i@4Pg;?w0X*eL(4B=fz?bY6$Ht?X&s+z>;~B^%wy%Y(!o$Fhakl z|3hP@+waM6*@*xXmJH1$ZXHfukAk071fX;gpdeI?)xwnn0L2CoK+&hY-$RfqBL_zT z9kW;eGTFaiEzj(WwmJR*h$=`)?8X+Jd^wCLxTqz_N{r+YjR~(i69-*EyUxTrMO25# zYQ1QP+@hr^iEiOUI&|=~xTPeg&!k#g5yL1LP3&{~=2HFdX>{@`!w zA1WACV41g9D=oeLGpg2IYD7%(`U)0(nzUQSa8uXxY zvywd*KcJF5>8%biN0fJVs$+IZp3D9gUI9trqpPh{8jmRe@(jd;%3?r_CpNqFnfz|F z>SGG;g6K8Jdrtdrc7> zd;Z{^I!!*U0MG`4)ro=xuJM%vLNj*YF(qi+Eo&S8M-E>SbBz<$CN5n1=^5v5OgT3j zV9JrCLf@X4)x6doqQ3oz$>V#J%I!B)cXi;Eh`%n^2sE7_v6QHV&MW`NrYICNK$`Jh>RbGAj^#H`)QDG6FP$F~w83Y~IZG za>B)LacGMbCe$A}X1GnphxVNlrtNc8-|xTk2M7D0h&+Jyi_~(d#6QsZUQlp*d^fMr ze3SFZ!a^VvWS$96-yt09(miff zzBOL%$6klTMzHfk_M{t4{#HJ~gxoNpO5X#(;`Q!S04yRj@vU!x5+59eJ5`1=P#{g+ z{;DPW@gbTUpij(4u5RP>-40~m|0bKd0koK=$hUW5#T!H&0Xhvfx?!DWF;~Sly}a?{ zu6yL#b(8!HlT?$te;4kI?K?_!19E}#Q=I>)u53W&Uxrh>RMgQzFkw?H1%iGt(Y16H zOFVu#SGlM?rwMpd*}v7S;al0#G%s%h|LwEDVCvW&bLpyejtLZ{+sX+T;aHDPK%|L7 zE9cilmT*Qs0Db*WQC9xNNJfozsV?(S>gOo7-HK7tI{9y9GSmND@Pp^58q? znb)19K|N1M{Y?E)_VMXwHzrm4&sWRx#tVMiI>F)t3Wl7_s=1SD-pnHD#jenbXGS(* zg6nEq1->*#TczdsJ`=mPW(;-k(x`cdaQd$Mpp{EZUp2kUIqcR(?`7?8O)_Fos?^iN^C+bR=px#YZoYJXosUeWvnu)8*>ok7FsnF8vTzlzhHTV`=xDhJsi|$@p zp4?glf3su6rtL(5nhC|}r&sB24&?Xu-l0zZ7ND)p60Doe|4A}8MI)*!uu~*x)fgix zi>i4+djFr~9iibD2pFqbcJ(W{aJB@S*H@XgQvH6#){NQa<^G6ABzufu;M$i-s2Er1 zY4-P5xb>pkz#vwZ ze?MvHOXYvQiAT{{(3*v%{Q4yJBicxmWNt=Cu~5x1A4haB^8~Gb^wV=2Ulhd3XvOEX zQ0O;;r?Jg?8ujak*H?w(DP}ttRQ7{ex}G=-J;GIUExqKflUXqZfeKsttcnNOJX@Bf z{0vU~6B4)cfAJLBuhsOPkXqMCrj<2GJj@?QQrNm6zi9`!z1H*j#(a@qm4crRc^97C zQvA4s5Ku?Cm51=iH<~}-H7;rbQv?7H2|Dq|cfc!`+P_mabUq&H)$OGG@&iiWykZEq z_WTNOOK#jK_OdpLyx!l8DkbT|75e!b!J@ryuh6QdPoFNFC5_>!D%bB{(n{k@krx@~ zuZXshre)5qFRiDL&j=fvNM|FZT)WZZgwus{~T9S z3%i(-K+6ODFc!X~`!TzxG*KB6HIugnyqvswwT_@=CPn zgVrW%c#L$cUY)OBL`AsOnsfJKTV)Y-lb7A9`wdoKMtVJ%y6PmM;gxIgATk?r9y>>6 zP{hXh=&!=bd@@wQ(o(p2@hz!uKlSTotKwNYaZj=AWJ2HMy}$er7HMaP4?Z&Tk*G%7 z*++;Se^-%XuuXf5TT7)N%n&~q!M184BxN0J5`HRxoefmkD>q`WdY;c2`rBds{uJ;$ z%>VNxLa19bSoF)$Dj##7=Yhoz2Eyns9(u(lm6oBrDosNLvWOe`!WQ9_$he$}8Mieu zixwVpR&j4`I2s|fbHLPe3HH2>uo1zbX{Gn_SlqYoGqnY{s|!>VQ7G~BbPHcAlgQQZ z{^3<#OV(1&(?ibjTEBw>%R#mfcXJ81lpgtBZg_mBev$-VnhZgw7L;bRSARkx-?E91 zEr5ZN<9Wi2x@v)C5v?DQJ>K$kZ%Nj5+YKWY2LLJUJADsKav=@4U^<5qL7R z#G!|x(15UBPiaZoi)G1yD)n-pa($k?B^xlJcuf}(zOH8TdA_+kIxiq4UoE>^RVM%W z-I`$>=zxkTzYZ0e%MiZbB}7yG&7*s>Bo+l9MbBr6(EDY#uodpKnee!9tN9LH5$4Ck zQr6$nL#WTP=JqZT0nQV}VoiB-9Lbt-2J7)D8I(**BL~UMA)XqjG#RZ=)bY|SDYs83Z6!RL90*XJqKHG!H({ zCc^C-(o}!S`H&LBiT$Xg>D;-cZ@7N{A28ZBSaR9M zl1oqR#9EKD^+ce9+iy!=UaY;t5U;QFvXsJ4uf&c-FY0;BzZl8?>6ENpQ+ag>w z3+si;|8x76XKtSdYV|Um!DlE|Nu=(uIeQ&4s)1_PGl7S-VsU&1ZQ{z#X$C9t3RG+^^%zx7f=GlPDIuvDOa?gtRnt6?6 zm;ReZgX7r~eHxweg{)q_;R+KT{$8^1@!Ihl`zha~^eAoV7Ty?WvTQ5oq04A{W;dq)-To04#@#p`$+UvkJ!IF6=kF`vm-@vnK2{= zkbg8P`S3AuK`~|bmpBO9B~ zXKV{yD8r>TDcY!{ zcGh4~Jw2@b;O@V!nI+BgEG^3iZ~h}{+1{_TlM|CehcV%k4NmJe)=dmH$f;246vqqT zVd-Jd+TIBZ;WXVUTRs*zm!rA_3x$c|-?TwkN$nexkal_$25OSpP04$KrrwB;P5t-x z=gq)l4ScRBHMo$c<@tq`%q7R~m(I4q`NEbd_X_HdAB)(0!y}`O?vFaqRQ*%nssuaB zwbJIEoMwzXTAKPR*1-~^p@!TwAr0)}I+6x0)9raJS41yM zW#sR4IX;iCN_IaL8ny!ODT>tDlB+i<)`lcFkS4c1Ur2tv78k>+2(TtAc!?c!M*xNB> zB_G3~_&IN0LdTz^1N=z7eHyJR)YTkoMpn%EG!!{7^DD}F2a}n@IBhU7cc#+=hN{lI zNLp6tlQc~wb3ON=qojgts|*vcXRyc~Pi@)E6>=da5v~h*Cyiwl(vKf!3lYO-N|CCI z&usldw$XD6_0RndK#N-Q5|W#JN<(qyuy!NbXAVy^G6^pWf&oWB`Y z047pX;{OzN;0foCPYb*kT$svMe=?z_z?UTP8UtYMPa94fhNJ+3a+})Eo_{j7^ahdeyCveGBubWN6TEcJz9PrI)LP z8@0|87&q>s^F*a99=c{3){*bM0>S(*BHb=)F-zWN8K$446YDA`Xx<`mB?@sV9miFK zJz|=rmG;YrwIndUK|OZ3UHdBH%!xW1oyIQif?!D-of^*qo9R3{jIm0RS?8!aZ9t(8 z2CbY_x3c1#4IlprWk*|raZd>SnftL-EsVAj<3$v^Q+&u*c#Q#5Pt(Vk0l2_TN1Cwa zpTl>GE(ctH`Rd}btv%=__JNnLEe3&1gIInqd?F666pHrPgVf8HQ&Nq5=|dJ6GHdMn zl%_$Bu=X~#OZ3$LB?XM^r`FlJ@rvlUed0Lb#TuqChK1BR_RK_CfH9g3 zVf&m_dV>-^m=^TrY!@FBojIg(wol(l>Q$vOwA2DE>yfbt7)%#6rEVh&?a~L6Z=#ZH z{0^2hl&ZNJ6$K4uIcX{zk5&l-F<0~aCU+~(_h@uw6os&xh`M5FAW0uQF5BDEK{X`Lr)SW%?U zGQtRrYSK--JZF}cSdJ-M(WE1&0MDr;L;OF;Bl z)ZQhXC<>Mg6T0u8|3*_2KtV(jgA+$})dhjOGZK{w2Sj>=*2{T|=xs-4x3>yto7rL9 zA28>4_O!xrYLwPO)?17dj>VxJZjU{$r)Y(xEj`&DB(h}3x_umwXZ9NE0Kq))uC)eS zM5u#Xr>fnY*C}CS*dn_WGFDoE)r#vCt_cqjE{bL;D(4e^T-Z7>tB3z7IZ;|OMk;8t z;WikqC_E$(u|d+nP8j-WTWHL8XmAi2eDrF1^yvM|1VV0UzAeZec@RT-+W#Gym6@0z z0W+*O1m)^{_fN8yG^X#Aw4`q-*5SR`!Q=V&+Y-`vQ&cltXZWgCaNJYzOI8zIJjyl>&zIy|IG3DD7tTEbzH&7 zXT^j(J-ou7l)9nb&a`5v+od2X@p;A2EKU7u`x)}#hEjaco)KEhZqv|nXk;9Kh*J9l zB_(G8GABPwD(v?!uxOCpyW}6O7)fPpU#QO^CX`uXBHS2K=hL=bv|LmW$#Y?Ep7b*NbYK*Ps}7rokjigj5hs5w2l2Fl0mMH@>2FQn$QI*C`WKP| z=cc;g^!ePSArJs)J|z2z)M@AOgvd{0^|ZB{`EO;;)2iRk(8}&!)OPz!vhqTHdl3OM zCTOc|AawxTDlgurWOtu1ieGc^XNh*nV$pZIJpQftVM7Say9?Q~qlD}YVJ)W0Pcjyr z@ZPN^Fs^<>4-xsOGW&Qs8>2u7+D`@Z?H-bQwlK_6?_gu%3ipP}EZJR=rd!iLXzS;@ zxHy@%bFPpApvTY?SK0XA#`^#F;60xB@f|Rdl^0{oME1qLSF@#=+Wcwau(|?77u99+ z;}H!Q?g``&D@-{n~vt#)pxG~S)J;c(^)YPMZ$NL|CLH|Vl zUr1*6{+KiP*V2dS`Zp}8l{Ldq2(+W)n&ll|WF7m6L%MPjaLt=Z_KZt+GPaqhVUtX| zqMatdyq>a^`&x#(KiVkWC$npU+p1eUcD4w2ze1QXkz4QGopCPl#d zK1lB0sz;lH`Jv=qg8**F*Av!hHp*Cvpw7JsJt7kZt0nO`wCzgZ=9#;! zj+r~njrRC{#LWn0S9O}lcXU6hrp+!A?O&rFAwDGE$+Afg_uO^`NVdMIEEm40vH)Pp zSo$RZS6U`srY`ffEHvYeXoALZu#&NQ#(U5f65G^;;2^9NaFYlzEZrQL+k9a|xXplB zi=N9Ox2+ZP1_gLfkk?|0M1-{h3)XP;W;ar>h{1=sjpHMqr$}vI;0~h<&!7pN552*E z4*D8Czpe(5T`y+;3~w zuj$Ixt9%p{XKv9nQ50Ai&)-9FZ3ov6u zWPLKHUKjDcsDaQQJog$?%m7UEWQ!6LO&x90X@>^&MU{z#apX6(Y^ zkbg}SZsdiDhK1~EHzico%?`cVj%G5iDWbEe99vm+Yk;7?naO`A73{p{-TatRa^dUC znXm&>F2%NhVLmi2W3TQ)1sCQ!q>$FWHuAu|VD4-ilZ;NG8+!n=0~o07fwo=KWADq6 z_>w$XT7RRQyeRx%0g2O8>EU>z6MAaGcBf#EtzBuP&*Au5*L{?WM11%N)%pCCN!hC} zWFNa2Hg#3X^gO>Y%} zw7m2SqO1T5R29#Fez^gV2sa-c=_6~HJ^_rWOk8zt6YCaC<{-Gtj>WHE@(s~guiUAr zVqQsC-th1`C^w|YfbA_|QtHOHk7`cpj|~pM7;yo&-f*bt1-s_WLD~S#BdJe_f|{`v zsa+5xq$V#eb{L9QzpdXNZl(rFvF~nd4SrWU>|x?(T7@A)!hxJD458FY+$nol%f*Rh zD2z3fT1@xEu=V~gU`|z4Kg)b6Sg|($?2j`LZ};9j8jNI|Wmhu)!O+#zE1He}SQnY; zNa4!c@Vs&goOiDJG+wKBCvk{^gt28}d0Kn#CAY2XyqeD6;``-VWe;*SE*S?I^Ixg( zZdfN=)T?J&H%hL9n4o-l4i;xl)&fgYXMa^xA$QwH3Z1C;eXoo+qhscl-_$4jTk-f! z7_ttfIl-tWw8BOWN?dB@(<6K34zldQsBK%YkKb~7Ka;ssb%5G?nPsPK?Qo*UA)hC_ z19D=mGhH&KW7H-wzU$M_c6sAJ*A@aleO*lXY13Ck1_||Gu3{RE(3JkI$WKt-)w-}o z*mCClphokD80Rd(6@NV_W~qyWCnaG@F)Wr$FX<`cep&;| z-`lP^)*js1#1FY6&A}@BN_`EaZ?=tC$;{>Du6G^~evL<(}L1wf{Z$G4H<+ zZusxP?{%u1BJ~<6PdB~wPE_LL zrG`xjLHG#u%2WNckWo+CVYac`s8C#{q|9Nq0RI3|5s{iJ^Qz2_ssJ60WcJ07wf8b z_$6e*BnDSqvde#NqLnsNMz4j`tt5(Z@)eT^ez5_(3OhFjGsRyH<27|}q}k7?HydeTlC*xjnlSDhW~RSvs$_0SFBNogqeoABhj&}_TsBvAF3+PR@sVMC zc>(mxJ9?V`e8Sz+(n+$v@UR`@-Em!zx^Bb9na9!LSQ)SY6L zmBqzJ7IDBL#ri*GeZp5K9WrE3i7%vTk!&N^alR_(m>!5sCkK+oyQhMkJdSEg@@->d^QcZ0tT92RW2&e z_v&Q-0>UPLFc?&7H2|~gH9)G4rkA6a4T9Kx@9kBnC-v_y%(2V=@@L-Ko49(m1abd= z;nFnAPj=NuD{JJ(s&-pr`GAEB`!>EvHABs(eM#pTt#wXR(sDw*ZcB4@(61jgSZMv) zf#Le2ZHb&o-@_Yznae&0?#v3)W_vlN(Np3`vcKt!1|@5A=gYQz9q@1-+h)c?3fZwi6|uMXc%%&MHa`dLe@Ynw z7RBa%W+uH)&&)(VT`pU+^{O(v+eOz473omA6yXg>SZm131oHd;h;f`H(EY=&mBm4KNVl58ax=lrjO#O!*X{Vb`HFN!-{LsLl?IZO{YVNGqRks=8 z)|@Z*1hlZh6|tVJmTT@dhDSfgJr97bjBkL6zra?+l%Tle9cL6A8f*1=Fbw5*BR>f} z0+c5D*;2Z8o510b9~;9*{-3XL_dA8EdK}Xk0CF6qWVnSbZ%Hqu3%n2i&~d3|2X%>lbY|9V1Pj4>rK-BVR5G++c+ml**YH zw7zKhU?w4gfedEvaN#Z_Ry$XCTi`V%lr4Q@} z_Wb1Rg{_4!vjR1<0@<^G!su5N9CP06>>v2~0*_WpXH%kvt*1yY-HfN2!_7fbis6oh zrh(Hopf^yRQM=V~kTf6t;OeoJS!yB9*LC+e#(P%G zWn`b&l)p@{w{rpjIgw9MjMiB~_~i^_^bGpSHqz~iWoVcWPk_vei@Y4m+rauhT_(YIeo*N`0K($m%6W*P}+p%7rkLA!aaq) z;BO}GfMJPQL34}(Y+Blg+}`85z?W|^Z8v1D-+y8tfjN)L0a*l{MVwU@_%Zy`y$b=- z7$tj90fG*H4xUJzI&0UOELlA(Bum*g`5_~@sdBLPK;1SrmdZc>LsRmb{1>wK#Cr+e z`D4-~jDV>e9$RHv|GVmPse^S#Y25(FqvBYuM+-zJIW0aFu1t3EO;Ui_3ztV5UAwfK{T zHl~sya?+tSq{6w^({CGg1u?a`CmN&W+?BW1Sgl$(e(oYzZBa}cr*^S=hnW^iZycZ+ z8HM%xWe+@;j#7AG21=zCn_Za33qa@5FuRebqjdl4B}(8(d%VU`hTAb1MUgR~{!ZbV zQQAR0gnC$5LZI}Fz55luj=AD|DElKl%V|pPfvx;#a6DZ*%pMO_)f#BZwq9g%cy+No zxZGmeSpUssD7T#nspvWB=1Ez5U?%{T0bD_2cVb@nY4Dv-KHG^kaOb0HuxAH6blm-> z)Ejw(0nSh0TtiDXhoEkrVI4^A)nkuSC=ileQOVAMtfTXCO7VH{(Xf=6>kr@o)74Sq zgH$z~uLGAB*1L7L7s04vhT(5|Jdv3^wi)k%h9;9cv*DN#{`?*&On{_?N<;DfR|UhL zIr5TIS0lYf8OG;tHRXG_)1PQw!q_#BlI7rzbY^WWKYynd{Z4nH1?y<{(xFJnVur~J@$z>DZ zHa3$*nl42t-p8;;soS$(fcs$^s2;{e&?=0K4VWl|wFYY)4H)bRrmnEBt8@3cAhB)TFon=ouQU3z7&PIZr>n=vS z5)J*eIW_x`)~-cnQ&$NpOpz2%n`GksEs&TI06VV(yF2 zCbmop3ND*a+A2s@?)_wbcR6Q1dHW%EuE7ORtzQ@VW(=>o5gJl(m+nQ2>TW#{RS9T0MtJ9Fk zImxxFD(-_VOh4brOD;ZD(U$gfb`+WsxOjAB;!F!L8Ya!&4Bs4HTOU)lZyl^{5lE}f z1hhrsjCTj7dON50GPUT)P=u@Vuibt7b)J=jn%3ZTdGFNGA2lOmmwEX|*Y&jjOXT02 zW&vK+gu43g3dtLtX(Gw5_+|>|X}0ZL1~12&zI~}6^6bUvPUyl#C&5mfJ(8C3N@A>x{?%oe^Lss&TgFT;SG}VLS*(7q36Tpm{UW zObe=h#F-&Eju%o^9fI2)SbTVz6{mg>0f%%pmLhrK7}Ez9xSgUgbv_$^!Q!hpZ>obu z1oMID_(n{*jqT#nC7_B4_MP{hOE6+vkzk&iezD> zQmIoUXUqLG0`K;thvt07T?#aG2lQ(!4$oPZdygdxHy0M$Rdof^{SYS%wQDa9n~@pZ z>q8F#g_7@%;P{^Gi9QWJkb!E8Gh8zh0Fssogv^g{Fb7?*rRO-vg-z6hxW z_P#7RFU=Imk-V7*UfTF)nLF3rUFLtg9FyT|n zOshEarI~8!p$5xK_4V`NT$S`hrh4HZgMDB5lmgFL{_BbKreMlum7Uk-L0zZF#ARNG zG|IY#u0?8^rH!cugIyR#Xw9Q%xd}7lHEJ&gUL-oM zI%n66&YF-Xyf9snf%ixMcUVoAg zJnh{L)@2>LP5&$6Ep%kg#*qvPLR~@tQ1|E-Yzg~GlCY7(lCgbH(raMqFYg-%ll{n7 z+JzO8kLx@Y^!iF-%Ij8q+OyGCN*%h&Mm{4u#=YiRn&2*_=TQLX2KQn~ANAjf0>rg& zQ@({FHeio#wF%K@jtZ+sI`kI9GOIJet*tP#6=Nb&T-og6qvUNg7;fMQ^56`xZqOoaGyv=?ByyxdVP zridvmH>H}!<}Egh^gWpqC#<@zRm^N1|FEzBfiV2pmnKp$N$qVYKvrC5gXD_7HnNQ) zSSfEBOehh3IrIF(rz(N!V2du0lmL1!LM+s99o{OMx=>zVbGr@{#of*CK;(zp8*M`8 zBpTXW?#3Ix2Gs=+H`4UQzfGA59^RF6w=B6N6=ct0_f1EvV)0oBxO^FCMwxcN zF}lv5I&wuI%|{3!Owi}^8X~m=66TGfU?t(I70}B*?Q%#LJ9S=i*IP}FF$Nn6N!LJC z-r_O23K)SYGD5bZcvYwsetFk-&6p^5X&=_)fqegAWjh(wQcy`HLsR$be#}NH5x4`A zp5}~w>SZ14TJL6x{iJx=bAvp*RyV5c6g2AJ7p^x9aJXzY~{z@gp0SH~K+k zKcg6{mqwlcPCOTh1SkDQaAlY6EcR)gEn7shn5W@<8rhM+wd_fL^i#NEJ6a>VupZ!N zK*#AjA6&mO0@{Z%dGaHr7HV&X<|`+SdotKnf-^@`vj?=6@5nz{W#wjB55UI6rs@W` zXU-RCrCS&pjKeE0lI}g}KwNd|+EzIk&@o~d${Bf6zBr&ewg}*Krd@7v zn0~MeReJ22eei{eomv)S%qQ977cJ&nuqsHc3grb~opm77&T-^wE#|q+jeDx`mt3OrzXq&7;9F>6aRt!P?8ssj6)R-aD+C1++$Kr}a{RLyhU3>2mjU zTek_@E%h)B#(=5WSm+CfqJX63?{;)j$(G4L4|`1~nuM}GsAp^Zq zz^O0Lg5osD$mgOnyJWhXPX1d3l(v*$7Qwflwxqv%%%DvrGDWU-sbaX}??XPt&pM;$1d-(5ji;&EI14 zoE6|hKu7g5M&WNR@i#~$sI=*N_KZ%Jv@yW4KUq|aJ+zp4dU(^X`I6*Pt-2hu?7fnc zCTkq`l9@;i9Rh96t&u)0-d&pPl6rCMM}@4tev|aZ-CEU|X6g!I-Zr+i23;c`kUFGn z5AEcfr5tJZPMP`YdZ2HhsfjagKCs`Ta@BG+vgY%lN=jDN;>^Gq`AP4X5s9X@1(r=d zq7mrS8|goRR_pCF9b5yl=#N`)DjCX z1Um>S(%_D=0wA9@0(Xu>U%-~tS%)>!hu73=X`t9_pYl9z@&4=6J>eEp{Q@6Z}Mt^|x4Q57q zKPN`Zg&wGU&}QI-E{abmYC1=YlW$sU>Ra}adrk6*%2EWu!cLIDj}`7A8Ad0?3BO+R z!P?a&tvfB80s1<;Q?bj?;22wzxTwjzGu66AMMx!{NKT!Xa~AztSmsV~Ff|uvWcRex zLZrI4erG%59s;I+u#}IHVO;E}*XKQ~4rFm3H9Vndw-~j0-$2L3umOSOw!t*Gzsb8;Oo!neSHSyMLW5-F!)XqbvqgUat!Wrzfdz1 z3FR&*ozHha(f>>=jVA0H;7}N(mN&r-s6>I#C8lBkzE+V7O^ecN<*c9c0)qvBSQZSy z%XlB!FoT1n>)5v*!|XQPhGx4O)sQC!pvS~Dwgw1@RNNnBGL*A3*c1W%j0{5zyhuQ~ zxlvEM{N25c9|!jLC%mJS>|$U3`}|-9AI?^gU@?4P&u`SbkzTiqyckV?9{SH;;JjQB z&T-L7YSwoGND(MtHajW|{k=BKN7HFX29kI(X;<9ux|%q~qd^4t&5_9uo08I@p(9_=>2uRP z*~zZNvgiBoua^_PCVmHe`@0W~(BaI}I!HjYhU(k-B)sl-xRMn+(wB!jS``5dc6cG+ zJ?zCg#BjNCv}!(%7hSb$dt6#o7RS?ujgs`r;!K~>P*I+Rs+v3h_9eL#YAwB{=>)_K zbLexKL=>$LOqSW_)}rdcVD_kchWKtg!Ml4-e^K43y_+X760yNCYSc1a9dMpD{G`7x2fa z>r1*Sr9WiF*heO>>4$7X)+FoH64F>F3G@GauWggG3lm7*dJe*ZCjh*+Y|_?Y4cYKZ)VDo=0x?IP=vuK5xl$M1|5>WjH0l?e3^2 zC0JzzFfLpA;)_>r(M%glN@PIK9ZXU$hu$XfiaWnkmJRO5d@u)Q7sh+qKD(2aC>IW@ z3s%MjWjFB-UE$K9G)8BR*4>{x$i}W~p@x&a3Mg&A9ZRDPh>AyEP^(M+ z`75HW9Kt1PRiq;`A@MPqmzrW=>mS&ZVz?6?M4pA7zSC-`TBJSaGGC7B&Svi$^(Nju zr26fAbM6`aIqkw4B6l2$%sF*QUq>nfdU2vnz#SFT%A-t*MEs-soGrA2*@u-?_EA=M%+5NPaC!Q!}|1Y7~P7r)_k&g8N+A-Q;cepH;*^V1d5n38C|z1Khx4df^tdb4u) zx&%4&+f9e}EVuece6RJtmT)+i%!kR;LV1lX{YB(aznmprR2T^Ywqz^K@+V?4y>LoEX(G(ak!cdLmJDh0$7L4VnWXgI zcuU4Vu=YcNv9^S9AuKI`Mjvdp+r~$*I^NI16;-xozTV}yphsgCt1$HKJ<;&`EGP(fOw4GH{sfS<7dR^YQr5Gdgvk;a64d(zrD@IQk>W`R8h` zY-kJP>dV;JwG1dj@YFp|izf&xZ}JK3PwKo-Jh;U?NbuIe6V@LuqBNiN5HTt9n?u*Uc#L^3he4lECpg^We>vJbNqLqFN+SM}wJ=x=yx; z2WG>~oz}LEo`ac3 zyDFyIbGV^=$@KYx@;Y@B9`|nnY@eQcjqrKPm)bp#R{IgZR0!^H1;K_~`_c&8Demq3 zm{qt*cTgKwKm~z-8pfl0sh5=;Ubg4YEZRbcYq(;c5HUlQRQBvg^&%f|0q2o}=vJY{WO?oX;Sq1(zuW(E&Q@ms+7civ5x3h^f+pHw2eM zpWN}Xsk^OyYud=&Sx&t&_kU!9Xia4p@IEkcPTNR;hn0kxD?Q+NDOx$bvTzu!W zk#@`H${TAMoZf6iS@Vwo2LLq57%R5=ta)Kv|06xr?%@_zi?k=hR;EHqjm|g+bh^n`qfU8Fg%ks_y_Ac|7X){F4`gg# z8-j!4i>S04?N)l!R!(XIExLd%?Yt!e5Ezm-_1h$D)Gn3T>5Q_jnVFEO>BLht zEu^ql%Y7^gGf!Oet{KW-4M1;pZkkEE#@0_y>nfZIf4L+qUrOaW*K4 z)={*iHw%;6=Z>NO?CxFl#tTS}04ImH$&fxh1&Rj;NU}F&oSZ-Fi*PVGe5K&ALFVWC#mws8tl-nX^1Ta>Ni>gtIc_t^|b$r<^SMk18#(0uj4_+zWVlRqYI3ED}46cuRVp@l9BRk0<}f=LUdQmCgI zvB@>4+R4ixYSyjtfa~NZbi&Fxf1UTn5JGI%No=xYn(C3raGUQhV@LXv>0D@g14xAj zvxGsTVC{mEil;h4Ue8R6|5l2s^I8p2DMEd5n((^8m{?eS)Dq?1L;{df@`IvdMq8`F zE|9spR&1scNv{3k6`L~-0Np$UZzZQl#f$qT}qb;@mW+H>IGpzP`>v@R5U*_VOV9c>kb;Phw;U zUuqcZru;Uf)hv(#w5g0Q)nOUdlOLz;C{9w&%r-9vhA#m( z+FfOHZ`XiI=%mXTZOMY>KRMyWV%BAggq4H(wKiYA_$!pwHjOuk{k1K926s!$Auiks1%C-@g$%7d!p9 zcJOPf3k}!QeH*yluX7gxg*!4*FF$HIQs&V_0%lu-r1UNyPv3+QxJ3-$g{XRK68Kh# zboyD~5qE~4>TI~mtX)zLfb1LeK_-k3q?vz?fDWjFaS7+iiqaXqyxlUWdF-6i1+eZY zMFd*-kko4?1#pgBnnf3Qv98X~OSGkryxX(Gp!lCLJw!7U8+`eCl0O81YXBnh4s^u- zF?H2pQD$9y6%`c$QA!XnRystwRYX=PkscUQa!6?qP!Q0ec15I7L2_V*?nXeRB!;0= zTAHEbJG$bx|Ln8z?Cv}7d+)jT{OT|nCXDIt&`8$Yu1t2eV;r-}Oi{n-0xqX!)9xbg z5VARO09&&I!M1=LX8_BaQzs@=&bs5#yJsMeOOl3i2AlE(iT7Xpt+ zS{@L6g8fLiXsfI$)?6R&^>0Q(Ux)dVhDl+9N)>OK+j3cFJe*FZe3AW2^moVKBQ){; z!ZpV?Z#EV})W$vK8x8b+XENkWsoF`Jg$VV$5X=GFDU`+VXk~~&$360^Wnt*Vq;3uE z!htuSC_@ks8A+>_bJb@ABu9=w5Qqu$sxKYT#N2uLmI7aILS8Of6GnwY4U6qvGQrwz!&7zD_qG1EVAEH3Mjp(nsFd4OqQ}zyF5JG9HwrA?Fc&&A|8TuU%#jF3Q zI|Gb?AgX(jDeTsX3x-ekw^3ciq6aS$&*xh#zfOHpClV}x9eB~}8WT*m>?LJB@V%d5 zNvFP|_|AHUY7!vCd2yyME(`J6F2jR}O-9-6S1s_9GYDFCWC9vX=jead>y! zH?(Ylx5Ad_FQcI}vU}Kjd!SYX;s#U$b-|%F31M$XCEU_aK=-<5e^Ob?>X>n! z8Q>Y0DLxncY$$*HhQWKkB+knR(5j!08}Y2vvaPeem^JP8aPe~1iHlFea~^Hkw8YHY zy2`911&e=A0e+PR2lX2sIkNoQJrzK?Q>Esw@kQJ1kMZWIfx6~u$eQ#b#L@@ffF-oX zya-@CIsczW-q>bnV1Ob#DeqQI!bEvgI@oLZ>Gq=arZRc)$(;wR@)fU>K^pkufcE%V zdf*REbiW#~k5wrA?Bhs@S}I_Jz3L=)|7x!{MT7)l3Xb$pvKhY&wPqZ#4}^dG=KEiz zT;j-BVaI0vg1zMrY!JEt2X1%*r1gM-PF<}<*wZ1h-!w+>LdQP6S(HYmu??#KYXFR& zGzx&T@YxBgui3>-9;}A9vmtJL@{PC+Dlw29i9{6ZX-@+%~5$IxV8(nU9kH z!<4IP9=^-P1&1)?{4BVO`|Yn*K20yk%pemSXB53l)x&8SWdw;Wd-FJ4r4T1C?FYG_ zDak4C4bOq`g!O!oN^z*TgW{#E+!puN8$7UJq-a72=f4NVJq^a9tGKvn4iCo#T&v0| z`BiQHU%c&G*VhvnKG#>3S*ck@Wi@J9f(3fYP*RJccO!B)M8Xs{sz^&IFe*PiVW#r{(fm zfOpH1vKrDQKq3#W5-f4H#XQzV3cAqA-es`7(DV(lXv~8cm{FFO=mYziNz&P=k)v^; zFNHX>F&f!S-l3)#KD&-@?DAsmFJlDp#l?pO{l)QLgy@yi;Yu!l`{_+&JZ99dZ(K6u z!OR}@voAJwGWi^!O+y3kUjv)_jQj>CHefOqGD`HO#SRE0 z@EhWrT8GdS(RP*aNu@VRnvfu5Ojr)492ZSW&uV{};;L;r{E_*Q`KdG{=MUFvupa zB^h~s)+Ns<-SIIi%TpJFaES&bJRuBTwQOM!|mn~O2_R6``$KOyj^B;i^XCl`-TmMP_?{h{zB~z_SA}e71Fb)T1dJ0JOh3 z!6}||5uNf_my;9BW#Bi`X#x|^kV%Xsko?2jSykH@c_}L(kjpYx5d2EZ71u9x@}JMU zUbaVY-1B_r@W$9$*Kr3GZv4$GJh84{;;kP)wL&2dcb-ewR4?*IRN;Va?<~}}hy|WFd^k5S!q{d;z`B-*ndKCd>M%z{#JWAn> zd5wKK2_xeyF3fvxQL-J5qc^TW>_M6=pu`<7O{wxNSMyV)Mvhc1GmZzZzA0)JDjFba zp?IP)=;yawHfPDp10t8VCA|0U?!;`Nt2O(}B=;I|!%7oOxCqxRFWH^Bn{tLI(Kq#v z>D%`&h8oQuct<7b>V4*QDCqj|`H~+%EkHA}3g?vKg{<@jl8Gm6`pPGT43>_&7AFn# z^c7Wnpuez5MjY0`_#&6jpGmKL^7IHqQ?=M6sKy`e{&xJYDsMA_25GHzPLKohzDQyM+UT^mg7zyA2MEL zCMityZf{S6OHmorizuU0HqO4072hAR!8M9$?yrp-6piFge~#mMh*|@Lun*1G3PNo3 zMo+`I9~p=^dB!hY%F z9T~=ff(bzjP#b)=Q~|Cnw&#vo@3%+gm|nA;_bj0IO^Ma_9#@wuo_Q?yA}4|TBW`*0 zannXo)oMI0O!`0Ku(9~Vw;qzP^cHdy|GPZ39W9wANcSD{fLFU z#K7px2aOKyyxmS2u*z4haDiM;U9F7u9UgsezKyVScA;*VCO#*H>$YyiiL)%3q{L0chq zBWL20_9akWe`p!b&ng5m%s!c7v~j|g99H6K&R-|*ny^hDcnaiRZ_-+s;z)-PESf%4bYdE;6%<{kBe6;lV!5 zppTxBYu5`?>hW`gTGk$hCbhYX3gN6!%xzs(-QO0);H^AsnXM|f8ZMZ#>_k0!xD}E| zW7PeYy|#py;ag#!{P0#Cm@-|8bbpX_hbo#YM-LyBmj|IYb`CtxyEh!M2@Sk%AG#y( zU$q=E5*;6$+9QIomT9{Bc|Pqs4X7=%Mc#8aBBKp`-yjMxR&}xHfBeJ7U3M?<6&#cu z%M&;7yYl@8q#V6LpC#<1;s5-KM(=O;w}-A5;3&8LzQ(N@8%}&+(>Ji_Z9vrUSuI*& zoEmY8OYtsadl+1}moPSDV4OI~yl$TpM9%-A;s2)kU&Ki}MsoTV5bT`^*h)9y%3y=E zHV2209txSprN_Du+xC~dcmw}7p7Z6yMz{{!mdZcd9W(KuT%V_lI@r&n#Yp6pb3k-KrMacEURh14|STqJJ*T#dnWI~;IEB#ixT+Op6 z$E}imOF<6_3fQzo!{zVT-kdhR>NK)^72shN_-+xP(w%rk8U zU5Hryb<^%d6!;WKwb;$3~2XXW_d>tG*iG>W6*lj#{HVD;l4vRr(= zs5XBiJ*@}q*7ncd2e{mFIDFc6g~QX3QF4rmW!>n!Qf8&w6_-r8Hcw(DKI`ZD;p~emmrA4pWp;zs^qHp>aqIiTF)iaE@eXXTC0Q{_gycVajK%~ zg?U`deJ`0eu<>KM^TWKJe2xS^YecKK8znJ@aB=!()%x5@(tYz$d%gSS-aD@8M>cs1 z(<}3<_IVv%R?H*E6AvM*M7qO>k5o@Q2GnB`1FBxj+!q5B*!$g*b=||RsArp$On_Z` z_5qt1oJ>|aI!KGoNjW}9X#&X?UHR7%wy2bo=6h5GW8ZD2tP2zB*Ux!!c&}uqC+=vn z=``E`kD}DPr74%|&@<0>GbvD|A!=>%jZL@^+3-h7yj@@!IrT=YMg||Up3~MPuOL%n zF5~y(xt3-vKR>VBBcINq^)F;m0qg=C^ItUZWoh{w;$d;m#gGs5%;y3Hs7(m>6=hLf z7L=Z%EtUZnGy$6^(#(Rs1!7v*9zI1gUR77HGNtHBZq-`_a zxO_seKI-E$3q-zb+x5DGO_rh(CAs?3n%BQpJN0~*lKXxE;ndx7DyGJ%qX-U!uUZ+)Rm%2JQxK3=3 zU6Ol%Q7Pd8)gBG@dhH7a+U`AwF3>9L^XFXy`<%bX7r0KK+_)M>iLGMRYk$zxzvw_x zZ^ZFLoYvBmv9320763;?NO$V@mUofSHibaE-q(7=V!6!%S7ID;^mySs85d`v+38`q<`Hvqi94K36FjuQSLzctUSb3rtW> zP?lK%JY5Am9U!k9%KSr{D@k8zAJH;D48BlCflF&!ux=OPr2jy#v|(zEg$xwnH2ryi zKkDzf>$69<_fD!=T`m6GpHpJEC)#tzFQOS?8IgmxBP=wt(&;MWRxhbrm^ph0=yp1!rBy7U!ZeuTGKpDM>z$ zoNb}pOIcA_({awHm9>J4Vl$<2snZC@<+wz(&iSa&2x=25OmO;+9k3t`0=5o8Q&M1j z2h1YCU&@fOE3>yjSh)R8m`DDAlp(wHi!$n@vvVyNbZAh2T3^k)Gmg>lsf|r6f6VWF z9(`l``j0Q3$W}VM=TewQSN_0jnFPITavm<33Xle=}-i>AZ zJtT%~P4aCYd8_I~*h)_f*OUsq6SQD1Doxneqf`oVDK_Pq!&J^1lInhW7^H7Nd86Oj zV8fZNB<+cLmVA!Z4yr=uD4hubPICG&&7!`plmhIbSnP^N*sm0dX-jAw!3P#wrNQDZ zN+Lg!fKAH`4}tWpP{cKE%X=VaSub4FV0ze>@7~+g>RJh9vuv=!f+>G;?3CUMJND8X zFtH@xr8XPWht#XU9La$9i?vL)0T=cM_UUblCwOp+wal4;mK~2Ej@ddFl7;r9{I2{} z#IW$OtFN0dV>ZrTUp(MVrY}y=0~srY%k}D~yzIP(JH+GJshORh*hG8XZi5}bfmsO9 z`qF5PyUyayKa`_7*Oxx9;=L`_og+PZzQSr(Csr8nzM*xOOp}Tc|5-x4uVg^dGXF)0 zyR6B2(b|osqZ#azM*A&Q(QfMtwMn{`H0iHDej)qCneqEIz}f}kM#rV~c|Rg*Tts#8 z*=j{=qTV+PQhaUt;1C;}ZovLl++Fc_dAJI10gwf0r2JtT2D`^x-Yu-0R@%JMnyeTe zUb!vaQ`2f6kRliVUX!gaA6~RrqZp9BVw2pvHIwWO3<*i}0%8$zpFQNbU!UIQYRF#* zqI}<0%bZ~hzHbaDQG*CNZy914e9!))UJ?44?wHl~j zVD-S;*tN1T*^e!8JIyxoXjhJ3ICH2J$HQA;UTQ{&PCZFJ|*i(9jdoZ4Fa87sKixuNSM;n{f^&#E|5;575>-`Ga| z6wLnk#SpVh75oEx#M08smLa+_(|B6?dl*c`&3rc!o{ z8Qww?vxj^K!W3vsre?F$l+EW-Pm++=jI2*xl5l>9!v9=X+Et9#+0I}JtC$_$2)%RLK_$=790&q z$UB#>>ES9%=ZTFQ4u9ZRwBXJd<_Ri~vUk75q|-IFhi4>d)T37w-zUK8Ksj9=%EMpD z#W{Cp&*7SMk~(QTBzE42gpgt(Uh8EzOTA}Pp}S{|DYn0yr71_6^>&oaP07ojSA1-q z-@}jQNai!`qg+ORzR?Q4>q!~FA-+()XKm#pTshwR)w{XKU|4C+M^d-%?P~wq)joqM z&eFZ|ludoFQ*ER5>ptr)?@(4drT*4Y-6n#@Lcui_a&D;0rP0LBwpN#QrQtR2MXi|$ zo_2tx_#0j`CMh_CEckl@?M9yI>u{eKJzU2O@i6ZLx=Vjspr=a?+m=(j&gl>iZBWl zx>>Yg8ybD7+q3Ur@BuUdqZbv`f7rKuq%oT@5NB!7x@Q;bSb zaqTKwZrFLP;@%OCr#qnVG`XLJnSCTN_E;`5iF12)PCZrp81%T^y%RqBTu1jz@J)G7v;R-C~VaHf`t_j*4fb-ScoNe+g{!06IS6&yS8-JL( zkG?s4W4f#-LwC22`c^rC=IZ&k51%X!a4!lM*6^U;4IeFMIwsw0#L(0{a_HoHvFUpF z9r8$}ECgaT4*sanXcwB1Kw~9{#(%Un(y^~bZ>9)4M_?d{ih-`sE#JZcaHc8I@eqSz zKgHVKVr~ArxFPQM)2|BLcjid5eG~B4FmDhvNi+Kaq{~%k3cYI#toZm7a@DJ%Pd?su zCNLO1Phy(?gVX~1W^CrYSj>f9}ioPjx-} z879o@JX0GY9`}rqpEm44))C#J2Q?4m8Z*ghu3ndUcM?VZ#=bkzO4X@5#y5~UNtFeh zOe2~v6_t_NN5P?(!8N<&48~mG*-t4?=Uo13l@hz)C_QB+g5nXlN)-G4{^YT41w!G* zxJUh73L4~bPN^Gx%BaITN6yz@do@i9Y(fz2qbNXEZqFR5?v#?j#yA@J`m-Du=0H>T zjznk;8V9#=fUO2b0v=y}d9ZdxxuH!b>fTFaM&ikttRNLbvP>MkY0v74>!1STQ0+MS zY0IKRWFnbC#dDkeSoD=|u5kcMzUcp0SO}(f#-4YMD9rhTB}%|o{g^W=i^*M$Map&h zOU0Frv$13U;ksrcq$@HD1o>$h}800wxb@8o1Lh8O#h-k=N>Vc zh6Z}-De$2W46^P_(<<= zbAag)T8H7WR8k7RAXQ?DT+nLV6n$fqNvkhi+r#Jj3*UWf#T8gCVo%a(%y_7&0*!;5 z`NAyn${JEg9fAEFZwXELj##Fz44g~rcCyL2;7dbY6V0@&&z-F6+&a4&DzCPa6ei6e z1em#MlJqwCsc-r1Zy)$HM%h)0&4;;9TH5$DAA~iQyGr(z>XKo4-EQ$;S+?3`!aba) z?c&kM=C2G1;}k*=;~{bnUdZ*p3sx3W1VTuG6;Vyb`T5l^gOMp?7IKD|SY*dy#u3l) za~Ts$VD0DIe}(-wgBVs!`=O+*D>kzH5o5nwUniM<54vetqdCh98E=NF|5OL)Jd;(L z?tpRUjd_*XPY{Uqx8K0X2}g zrhOQthfZI(+W*Maoeq*QUY%9gC@f;x$@x(e|9_TUINTp>Jcx^nZmHr09*yy-%a)Qu zG!f3POdX`8)xBnJl6VnZK}Zp?(B*4MH8{=;+{NI+f*bpkW!%fR9Hr^bY<1bf(zxlB z!b}R+8wlzUh6A1_Fku9Pz(X8NhDJrBryy!yYa{b+NQ@v)AqpecR8?wSu_sISXy{qD>hNLAM?Z2IATPk>9cw`V5h8l%u#%4!uG2nW4~x; zG`NBa(s8jcTpnViFnSsbF=a~pzD3_Yeym>z-%QWA+;Qs!G`}vnYFg^QJ)1g(=FKXR}-T9S{Y%j*Rm56 z$=crFBPj%${dx1t20ia=#9S~F#is+p#F6rPxCiYs7Q4wb*_BdBVOh&bA0m~_S@7u| zxby7m!14|NFsRn`7lj7wWy$9?Zbjdij5g2x40)cXR5rt9N*bjA4U=D1A&!+0-r&+azU{NMLv9Ib!VG^xBOU zOAuP!r(%|`%867T*CVB&fw*VBJ&2YrOZ!dirKug>1^nRYKi$GQnG$V9DGeQ)XVG88 zKYtcQP`yes4(8{zzZEw98o1iH?~kU$wNUbE&OQ%zqop1MeW9&Iqi@z#(#x5v&}61T zthw~}IuNyi$k7=yhx3_ANQ;az2?Z`%f1|X`3rHk+slMg8?95*Da-2-PvwBl3uM1|B z`uk9h&EA?L#NABaBsr5NXFAw=MgS5%38jStL`N!$#^xWtM*2mp#(Z|SJPTy{^iMVZ z|Ex9q{W}~QfPBE0St`|dqc7d5=s8pLFoo)~nXqF7Ciq51gB*THAYoa^z%fV{B-vFC zr@dcva_?s=$h8Zh_%1$Ao@qAIls&TyOgRjj>5_;1)jc9Xo+YAH*_UX%+9J|;QN^Q! zWw*x0cJ%`rbQ!Ibwk>sPo2Rh#L8W$6RoQ1{|?OH zOL!(rL%8Wmcq*_&oK=un7zb0z<$$jL7sa&0h+HRE2z`jG(3|U<4YF&Pn)!6BqTb3< z53Q2X_bgo}k8yAsfGWb}cwrmZqhPz^b#>u+`>@Uu%Z8PK1Q>s zx7+C|+mHTR_6`F~7Zzauhx3&(B6H1J&{ z%-L0Ydo9D_h0FZkahuzk(cU_0UO9{uHLUTDpU`NH%&|J@?*h^$3c4`Vdg`Ji?Y&sx zHn)bw-B!_Y(DFkNmw-yOz$QPoL&{Hryyvt`Edx`3DFCo-8{8(*U~{f$=5K_Hm+$!u zpgw6f8Bz#^Sh;S};d&8ua%wx2E`W-%1tJB%Ntdj{uB#QQ)~fWPIKfi)fq1G$d&K0; zprX!)@=wlI)qa7S%cnp{s0LolSwjd^RZw!p-mX4p`x5pVrRwA;MjO_ZU2U~(>~#^w z-gX>n0sNU>Gia1tqM-r(b*M8ed2q~mmdk@D1Se!=oRO}-@(Ki3;ERQXfhJwDN|6X5 zx;A5O@1RJYp_^kq8HTcPp_CYg9(P@6Zfe;;Y*j~&LwXH<6zu$NA-_?ay6wz=-k_$f zEHPIu|HgjkHQMsbx8Amo!^1ZJ`tN5t#O)Wp+wGfi=|dKMkgnwD>+@AYd4rEV`y|l8SdmZ_g0mc2O#915uMrl_2$gJuFINJ}%gtuIhka zt4pOGEbrDV4flEgxC}7i0IpAAHJxo%> zE^g~gS7)D_$f!R2gE$8i3=n)%9$j#HR0-RFaV^yT`PQVCuHJK(#%b^Orzc-@4i%~ z#Z7$)e`xhR2TWYc7|r$eNR`zkQ`jB|D`uU`(mq!8@rbs1sw~1Wx(PfWQFXf?Rlwv9 zX+|9pU0Q-6v^;=El8u|p8((-Mf*I{XTw!s3t7->K|4^^2sn%B(ZeAwEBt z|5VbUAoXLFr||iI(fpVPWiBwgE18#vZ~y#yr@*s>R#E!EM3wp6TPMV7PPydilEh>* z4DSs>dKu7t2k+>X&&R20Xk9}r(Oi6PTDoG203Hks@dhi&nIgONmYtKQR6z6(XQ8`x zDl?8ZWBzz{4Ow3H&lOWffFzMAefiPI=`%YDbs_fxvvm+v^kMfR~R%oyI!BR(ou5)_>=&bM~X`4-M{*+X9rG6 z864air@ow}%ibjDRHkYDG%q{y3U%i#9t5{B72Il$^Je=ooe`1bqL69Wo-tPqg7h8` z13`xBDFvr}^F$WS#&o!?M9o;LIh@{ST*SM6a_WQ}YI*V8Cj~Zq-5GeedSIQKf_6sx zwR3-b4$fAM=f_dNl3ko~>x>PV{y#AP&%gTMD>2R5Cg6maH@zCsFy0f8-z6nnO?X{N z2C=FzFXnSfmGMFQg5z5_S2J^nEKYodnu_6;n6#YUXf6I*bGXg87&T+*`$4oxAuh#r zQr|8^MECCG;=Xi}7Wi|)W#_XQ2!>;(IVbOquLGO33m>J|HZ@x=h$>S(&NOLak^6f} z#Cx31+vq;7SGV6`HFmf?RQTiHD`P4n*W*v4g}btfbIPsDmmyDk3*~;u%RI?^L^S&O z7w2KciZ%k;9YJUCJY3Lw`=NPrQqSm8vBEwI4fP5DHM-&d0K(V+TW2%C)#wilmvW?MH> z*t8qpBHJ!`TlPf*qO6Zd#RR_`vW35s!&3HH3Dg6scP(e8_m#BOsr02nJXUT-h#%h> zjo<#l77e2>K)0jef=`08^b#pv#M#cd{&kh|F1=uL|7Li{(|KU|#;66FE$(O?VpZ*A zhezn2(o4@e<84c4O#R~o=5Q@onlj_hD;=W&I|+*bY~Yd3n3t@eSSe|BCT7{88n5=q zjuSjXYH>@B&4e7;ooN%Pxviio=p|^gZ*FYRu_$=0E#G^)rcecmiZHryugT?$*Xw6J zR8uChYx6_WbHXH3V-FNF7ykyuQKL8PB*$-$vS@iAQkcVR(A@u`wRD6*QbXV6 z?T+NgvoHNWef>XP`q1G#5mtxyWKyaskEf34A>AbgO>~~5mS<{U>~;$AS^7|SEYTdH zP9J2p)b`G+Ej)aFj~QR=9LS?h5y^h^EK_qeI2}|&A18Bp4NVc}bB-xCe?}BQww46w z@mwq0wllj!y{+5Prqr0TKK@jL!{$h{5z*b-gYWxNB~4+DMS}p1aJORs{n&#*22*wS zWsCYh8$<()Ze^hn^_*ekaM&$ z6YI(Zv=u<*v!SJUCELf@eid_r+Z1lMs5(3pP1r2GPMNbahfzF2f`U!OQ@qU`Kw9Z- z^-hzI*4$RAkRd@=R$Lk3et?w`*2ug)km7q{Zuy9JNM09BwoT{cPjxX-WoAwek-rJ4 z_1(D>^<-SEH(ZvC?9x*0W!-xL<_ke_+OZuzY|LRmv{WXtOf7!aYcZ1UZRja@o#ZFR z%A#=PPNrNtr8rl~=k0z#Ekl(`d`VET}SBMv~L~{^<{gdC2^ zeSyxm$azz++xvD8;_~}aCA_iP2&&iO^sDM$A4OaC81N5bLZ=P{JAqp;7k3OjgMt}r z^L7W@-3Z%IKJ}r8Qw5`sX5F`>>n;qfnc7j@F=Y`7*`hzs)7phL0?c1{Uj#GnXCNXF1$nQEeKad5oeXriY+7uIdU`I9yuf2;l6K@ooP!sO6KUZN)FYmK^ z6B&+z|3A}w4=Tm7V$o}O!^^cauaab_?nv=XB&w~n{(&6*M72&8uJb3J2V)SqbW18N zMX1QT66;}5K*H*7>tgW2bXxJV9-2twh|>(*0u;j^>xdCmV0G$g6dlj_o*{omsOuKR z4V7N9`oK9|8Nv&!_>9!<@$jZELyphLCO>gl9+orJswXQyy~6E&fI5I}EhV~u%%H*4 zqfs!cV5xp3_i_LjIHURpB8s}0QetLB8%sW3>&uT|xz1Fjk;!cR`nW@!@lhqx6BIla zw;DwoAW;bC&ILnIJRxoXsOtA*FzgmGKMzJ|GqKwK#pJM>$E~IO7gZN;{*V^mB!zrL zsK8fYr7PJW^hN*JY47r*!=)rh4r*XmN(o&5S*=>Xz-_5%Ue~QupEqO(m1P6hT&Oej$GUyFwUbve;FZEW zMlh}3cr(+(fZwu58!K5{6+qh*A3MmxUYa^10KuwsB^IG%s4O!fu4IJ$}N7&pB)0hm)Yl1JC3f1Xo`; z6RWVZ`WF@Jgd;*~`Fmb@2yj9jjmUy92B0QF{dKRzD6)82Td6_F=3U_q+*MB*QqB}z zrj#5Ev2UrW*uHyF0l-xdG;-;u7w0rESiG~_aq)UT*v83<62h?2bn+>{G$2qmuecl* zr9`pA3Q7XE=}&SKbc5#Xyx*$YU%*vV&RRoXxZ|&#J}nk6PP=prFk}|;WgQVjrCj&( zJ0tBG60xSwjr;lvyLRTkCxyX;B45!ToIz-zSPOsjXiNz(wkAu+GM@^CeqeS0HuS0YM-eT3k=I6HUeFThgMF^ zT;-1kr4Fs5o%J>s`FIw>7jS!hl9TD#B`*^A;d76jg&bBkuUr#S9}TJ}yLV{fTN=1} zRFGV&?A?>`llfw{$042}jZd_cUr8!>*^XXIAF>Gu~_trWW+PXj~JqMEz zm_1`-*|bu7c{8AtP%b<`TKu8>yAZBqh!|1y+hEvoxDro*D_$U8M}L!68B-pQolA{M zDKMPRrR4zyQbcAKeEM(XcCcNbw{>@j9jo1K!_(wX=NfGq)UUnWCo2Y{o(9Sm@Z6C_&3;tf0(T6ub7(~`5wZOsm)euL9@`P|-@FWsnD&oV0_qvhm-2{z#Jo0xaPLz?Y} zt4jRI<(oDagL5=olcU!1=qjN*#~WqWzz|;C7NYSsCza#ha@=Fb*x-#5amaZ;BDESh z9R^!;@K$8$YPp`ic-@(Uai4(+Y(|+?6sU>^7a-uKESsj^#OZ43EQD0Ow7v#@R5KB+ zA?3reBN+MXCdXg_jH5&7dhS0Qi|pNOLS-r@jVrk|C&1pR#6s&)&jotQp$xXm1PIVD z#UtP2jIDZ&qRJ{|X|tc6kGCL|5Zv34O0)tPWt74-st!1{eG(DP%xl)_?9=+Y=fay5 z8W|V=AlWuMF&PFu_DVo8E*SbLGE1E3$iw%TKuXxYl2-16s|ykn8oxy zoy-8p95$8YBnKaJl6$IENaOs3DX8YhnQ{NQQ7~_P{MWsI3xFYGI!{7b0oib)Kg0Py zX3>>Bq2Y(#$tC z!`xW3*u9v1J}cPT%U%`#ZN+E(6(4)YuY7_BScoTxPO{?U%RJ64Q#6+o&p{+Qt8jX0 zEN`?$A`D3rsnF4vyinC(@?-7MI&#xy;hwy>>^*5-ImWd;t7~dbRq-QBOWr5{>G4^a zX@yPl6B>AYRn$9eXT+;Hf9QSK<)ii5DnIJOP;tPKU?>#t_n^Vo0sfxN&S;?qA;`YG z#>;WA=zG{}MwuLL+)F@)nS}80l~dr%+ExIA~r7cP?G%kx^&~a z+xKw}Apj9H9`lBo&A=YGkKWg=T5%DdqNzs@oP(jVWcq3U`K%PbE{cLTV}&71a`(#i zojAhZZ%WN9gH;(WAsTK7+w~2q`@@71S8pwYWfSyL*9T6ChvjNJIakhT1s*xk)1(iZ z<%H0q0hK$8(67@L!hMD3;i7H3=0#sSwXLtE_e5WNtW>aURvS^onjDn@*>6!rlWZkP zHl{&QY%X|}KiTE;83DbqR{{CItFqJ~{d&T!w`sxI&V97PtrT`c%JF`~%9V~5YfYa& z5=j*WT41&x43Qq&SmG+zc2MK#IXSFG=t`jFDa=onWs13npknIEz&8lHl#jzK(n`O{ z+9N%;iElF$tEtdu?Ow7;j)v`91YDpI!P7$!@)#{2-|kVRog1rX6FB%lOTyZ{dg;(? zdghdT}eG>~~wu`ZZ2V@#hIKc^wAHeaQ844|kw3 z?WgioCljuj&doLcq9&ly>CqkpBf>dMJ=57!;`V6OxNNPCg?>o5d?WkAwfK=^Nx>Pp zm=|IGaN~gKPgWLQq})%FXfTEtK_>ap-jxomidk20^BBt?ZwkEs<&!*o1I%@tcB$iL z8C;JK0<#}l=;V*IukZejj6JNbP5P}!{*j9cVGv>6`vj0 z6g1puw{*W=iP%V)jlFVK%lHTxB(wt$_Qr$a#funN>gEy>A1?!yFnkLI^)4+}VD~&5 zJF7MRD|QeRRaq!5+cbVS&A{xWU;JlxdU|;bd0fW!?E2o1ZiaK?QN?PtIXW%xC>t}N~Sz>9eF(<8vTzrr;lEh>a z%ugdsv%K61n|8wsfUTP(O_UZjw42Etf1o0p)idu@V9K3hETI}h_u)@2)NsiU((3)l zu}IM~2g%q~^SX+_xi3usaXK_;{Qq!T%lvgXaYFVkp}0X&07X|BAi>xH?dVw3eZJ>K zRs})GH9{2?(zyrj+jH9I71{Zi15MPcR_xs`DoU07?Y+GfVAs>?f>?dSo7fNa7((i> zE?J9WK$q2O&c*}~EIaLw4RP~T4DW%{U_C|U;0@fiVavLY($Dt3>ap*1$m<~dQv~xx zT?G?=X9P^&+ESPKvBVN@Lsl$|a^ZV&C#NqXI;6pD!W8-$h|PodUD{p1>u}HgsgZc7 z=H7S*rM!{<_7{hS{9&XQ_@9M;q6dxu}q0%Bg)9=VU=qu^4E z%oBdY!v}&0aKXc8ya0j`-Ks3RFU@7J|hy39dzo1 zlztei-e7IJ=+;OoeSL5(!B$MV*3b{^n&20$B%!U#q1Q1|Q(M-Z?X}trHjf*7z49`& zqMEia``z&-vZ4m)O*Hv4WVv z&@O?GGfkD52EE=NnIDIsW_5XlRQZ+W_Rx$7W*PNNWiI}&H^IHuq@6OBlBj=P3B(id z?t}CNYmR|X#B)f%wA%(u?$PW2j8-2xL2vQy)(Nn={EQ8t&HcOmE}+&xZJp@OJ1@YQ z^ZXiU!L98)aUKOO4rJXm-lB>*8QG^*#;GrUm`oKHXtsY94kkS^owP(V1`|+n49@a8 z>deU*Q5n^xmc-%bsvz~e$+)f z9$3Rk4IbzW4MzO`;XdtOJwA>5Ct3aF`}2vy0|EC!rqjX^*g1|%ZOHY)5AU+ORUdYTP_;+;^jpkx&Y$GNmSV>AmgRPSCe)5cMJ6HKDzfhZubGksB= zFlxKJ$+1xFNFzjK-G6t|8ZN~i{#;L52${wa=orgjpl+F0-TM0r$ci-L>db+#qHxp5 z*|)FgGX>T8qwp3}>|Lkd@+R^(zi#Tsp~0{B6n+8zL3xgP>%+(aoJASMFcu$zPf0WfAyk~_o~)FS0jXbOMW*38w7QwLwG^aD{T*9j|LX52d~J201r4I-#NUu6~6k z26}R6rfZHqd~#uqzzZ3ptxje*N-G#TM{g20|Gm$@iGwv{a2SxJ5%Pf`XPP6^y^sV0 zmVX#d_paf0kMz&VOPik;{^OvKyDJi7X*OTGT#SRu;81FgnR_oxna@w=vP(^ZM})&4 zQf}%^98Q~3>P9vP85jcJGBD|qCd*^_`84CU8@LAHH$cQ29t(jHE!JO-HB}#K0bsUr z$-smXQ%8nrMmlh%P{MR8A#GqYkq?Y?FgW35M6$oMG=!JXH+H!upz0~mmo!2iC`XnD z3}?(eA)5OLclV$fEQ2+(K!XEX$TIuugCn|Ka5nczftpN zU2%NwS^*-G2)ZF`sU_E-sbjtWA_F2HD*yI$=ihI{$2e2~Bb)G_7me^((L?5v2xsD) z$aDqg#Xk={N{MET0nzz(pU(B1fO3M3oTDKSx;W-Q8Xq zZrhCf~jIF&NP%B)zy}hk4V(Ap?Ytp|=3ZdEPB@6^UDx6`*q>KDdMWEzD4v=$5y@hO$pbVH$4>I2QG_UtDjBC&?YK^5aS z%Mlv3mLf9vjTOStG_afoa(z@RBc|n{Maz?!!zxk4jYY28QH$eJ^{ZY_4-TA?Z$;@+ zv0p%sZXUbK$%+k$BJTLpynm}~L9pG;?2o_-emn~SLEz#Kbv}doBB-#sef_m~w>AX* z+nCOjnmUM9esFsAFjcXUN>pumRe;f^4Wrv5En6mWp&(|<*1_6{JK5)9ys%S!U@Pr}=&kK;REMp9z z9A2C(^s{HoEeP=66o(Sfr*3-I`}tOr0wifoc`t-Z>ln#8rhqmSa(|q$T*w)aBYMvp z#9px`GV8;{6Jk`@*fqIn<8!QS+bGvFTvn>jb0;6}HlKNTtWes2B3qIc=D`KDX3RYW zHm$!G`#2(*dxEjjNS2Yo#_9HDXRG$H*vc8WKukCqy=#uqQAHfU^Mez}nt~dvonqz>=lu!J(-u@-+|5NWi zZ8jdV@k0I!8OuY(Z6Vt6?@p?FpOBrciiJxL#A){r(iRm1)Coe8k5`Zf0#D9B1dH8n0}1m| zh8Bu$13+@pHm$GCcjBIgmbl& z$(9MUIK}q=!s+0vN0Hz+4>o@8>qLQsmDf{E*oLBUJ2Z!6i`5^69DKUX#*nQAP)V0s z!sEicrqsdmu;Gk#LSa`p& znP>~L=iW$&Zdw_mY$HLbcQt#8s^tXaL7|cuoMDZm5zc}5RY;kle^6%sy0o>7d?Ua( z#Oh^E1E`1p1J{Hcg6twYz}N@MB|H>YO_DD#lt@Nx-=#N#Qk$4W;f}}rVEf0v2AHI; zAvW3TKcu{RFTsPbHX<`vj!^8(FoGKB0)x731Y%1%B8E1+y+~z3I+tj;lTMl=Uo=u1 zrHIuimVb!C=2saDjjf|;?8jf9DC{eMqY*SpV2;}GHmK}dG_igTqZyxXq2_aTzCPK! z5TN<>FA3hpx`|{^+a~j7y?fcv`!!&aqra)&fZqn2!C@AU4`pm>g21fhhX0~thv7Se z;41jha~m~We!!k- z8;}4LDESD`$)RFcfeqB5Z;WbFevcj*7d2jO4W~N0m zb_r?BDZ6?UC)BbEH_&I9vY=XmG#EOR8_Pp;CQOS;3sy9LAN4thpgt?qv~R4PN;sq_ zbC}?VkoJdidq=6ACp+xnX;Y@N`Wqfa9fA(O5m>}}V`F9h_B)jBf5jH| z`SXoMgJ4I@i{`xReaQR;b{fzQ<5%~9(Ou77(_n1it&J%#7rhv(nj&MDql+vdn`Q%>}nJ4W--{N;Z_@qYnl)qN$@$VDf~Wgdps zv26VVxpD+=8?mMc6`}1Ym@(7)`F~7(1yGgU_ce{uNJ*=7cb9;qq%_h<*Cho+Qlvq; zJEbKgM7+}7Eg;=-DQWo*;QRZ3Gt77y9q)ObbIy*n*Irvm$;D*XS;f$cl#Y?&W^XJK z9TNPES-bV5{IqHP-EITmJn7CZt=iaYsR~M(v)} z#;f_Db3*Gqk8z?7h-RhvF0v^-+o)<0*>>FtZ^Eh%boqEkWN=$_abNadoG`TO4h8O4+A?MAKtG|oS7@$stWnVjMFxXcz8_w3^|6C_J}2cB z`t_wIRmNP%we%7(`zFoPiA~%3QSQ|L`YM1Q6p-D&q`vE1&XE&YPCgvB-L3!fbk{`* zeL_P4r5K3Yi0&ULzID8jAo48Bs2MRmU(T|NNFGn!v+&y0(u%iC_G(B_tWLf!e$Qa4t5NTLydIGu&2Sk=9vdc)3a^&%)$F{pp+R#p`9?!ZXI?9_91nSe+2dwl7eW?ib!^rGjwKfrGF zQD0Rz?NI&&-t7PPkpCg_e3p}YnsuO1UUojgc3t9uk5?;SYD$i-optE81<)6P0R}@p zX^y9xt7xgyFE~~|w?SI3$CNR7>s!oI3;`%DFi7O}6Nu+JyL~RNOmY%vpP>hQC0)D zhvNd!9hlev_fgbx>wWkCcJjY2FqZ%TjtYQK$hwm%2_$TSR>bWq8Mpb^&__(GLIVIQ znXxiq2R8-2WVFqrbZdppn1Lw3=5?<|)oJOe`|nG@)qlTZn&w!|=0#Mv__AKT6H&J; z6lckt-+5w^Umo|l_4w+EUzsi#J7E-n$ukCYt43sxZhGxRkBE&wc=Un6eJG^1zVLI^ zqBY351hLQoO$C%o22J%+mz|!>3Vn`~bsPT2%NB+gfW&4Y2FAd=!21R%{Qet-x6)qZ z^JH{rrRH0u7neitw^F8n(wFe|G#W{ff#G}5s{X$BQ36%v3rXFrBp*fzSDvPI5m23a zy8E9+e{tg3dc#C^`&NdJfo3y{!#Hb7c#wLXQ-zRi&auyW((fzH&u@?v)wAfbM^0v>bB_)4}vM2Ux`=z;sLZ>_6G zgt6E)vpGkY?id(APoLXoA(|V`S=Rv6a_=UO-uMtNjuwC>2_U`+0KDlp4g-zfdAE7z zf!taL5+0a6=8TD@pVgHe;jZ6YyGpXW;jrub>+ONE-2X z0_q&mUd<_qc@n5l0|5r1nh8|H_WjTC8ar`X1W}jr))|wTC#65Y&_9;>eoXZWsW5OS zD2~Pqk_GFQ1P&~71xrTVo3glHfGH)VcDvFp|Lcw<_>Vyp2Ew@6Wgxq-+k%ZRo^8$( z?pcmlVa{`udRwen@>)-<_-Ng!qt3fw@uWGo{6rTdWScGa5yxrkI}Sct^(KG(@)$xl zErOQh+LtGBGut#n8Pw3XVKddu7b(B52y3#G&*OMXjX@qhy959xU-*k{AcuHTRu5RB z#09DLDOMn80in~(D42r?WR0wp-}T!7C{O#9u zKd}!mMHzztuO8^pqKbkdE{pjWrCFVQFlc03yK}r80Nj8l>QS_Zc{tF99J&tuG@Yo( z)!#5s8zj}E~CNvUj;rN2(rjh`eK?2O5p_`b(8+Q*t{^S=OS{XYVR z6iA7IL!8|EF0ST~s4M?PwCtm1nP#=FnqoHyu*=`R_gFj{Q=72rH5xsv0?KG}dvn!? z)+-HSpXd!=pfgA2HZ%im!Qc# zdC)6f)Zo3v+!`lQ=x5hk{rO`ld?sYW;~Y>ZTGOes5YDxmC>wji9CY(j`wH1dy%b^B z5)R9tLp&62u7bdZ=B8hPOMm6rsN&nEWft|XYOY{P<8#0y1_HPZw(GmR{E{5vT&QG zZC6M`yA^4Gelp-#8dLReJ4XF#Aq2r;HMW&Vv9`t;6FIuoNwVwgZ^x>o^@hk#6Hfw4 z%~(J-2!K8Q<+ME)P$C9xi#hHG4Xoxji@rFb%@oyaS@2}01m(q%sK@mo(XfWv?e%>NNzRKKq^G(NgBJ1=kX zUmS^VCT7}PufwX!keZ~mj_|t9m~Phg>tMy@?E0_f zUEC;_B`nW6VDRSlR-@#Y+|)`{fFNv%P0I2~Ih*0)uRPIh(0-})&5}RCURH?QIdi1j z4PfH#%cLX!<1eT){R^I0J)wvN$(r9b-lquW4*8$-f)z6hIH1-03P zTC#P1(DegK_2sTCmOm*nQ^vsqgTcp#38$`xZ);2Rw_X7@RZIeNX4Np#a-!@JNeyq1HxYnMG*|shwbV`B)YXTP?TH8 z3YtJ);Mow>F4`)97{!A?Eld7mL!XVoyQy5StzNPf%+hc@OS5m4NynP~%Kn7d&f!R|g6Llg+D7C;y(2d~|U}9396Pe!rpU z&{!_Hypz%ihGknc9JY*e|E4pxGyf)fY$&3wtoon#3-MDkfW7sEd5@M)c|U9 z8~NKXVVZ-vL!1d#vO*_7BgIDlwE@4umxMCL%=`?yPXL4UoG7V`UIUGdfWZj_dUq*n zf7w($n{qB13E{jc#GYt757ltw;U)Mp`MYrfOi%)y51FSPk{Aq`+~d8VHu!+*D)Gjt z`3R(Uzh)+$Bih_d2bsRr%hFz*9#&XlOGw*00h!!S{0=841@sUuGjJ)au5#b7Ml-IGx|ENoz@&Bbb3p^FX z7J!yOm89+=ls<~Rosh_4&XHM6Ej}aw+BM(rF|jofm@-+L!2MA#{Zx`2B?`JPKzq@c z?2$)16VN$LwMdLfEq!o8#=U)d^4NEOvEnQ|#pXhEnG2`_gI>#*&FZ2W)>xoj7gX4R zh<6|psC)%rq+G+ZXlrozZN6Zh{VC*yE!JY}r9NM%{|#N=QtUEWcRK0Y8j$D{n)%WM zq5fOqk22rB8n^0|0c+bS{LS+PIGwLm&1Q7V=U*&ugP|afT(|BpgJWGay5|3#T8e*V zNtfFm^`9ROTY`%B^GDZOt3a9b^^DgVD1v)}rXjY;YNmb86I4GzYZ|Gd{I(v=uaT~d z);Z@OumgR;ZyUCA(dSzS4^XT1V^1m9I&rHbNkuQKkeL@yy%!!O0?m@upAk{fU~mAC z{hVs&trXvdPCRdKt2+7;oswOD!%o~uUy!eOKIk)dM<5M1RX8v57Z}5GtMoXHpQhMuDL zH`i-?F+XH(mv1Anp}lEE4ON*-ro67ONLrMYX&ee9Kg;NSO*NZMDNAvpCexB{} zip%KS5@9UU%Q{VqhcA=9O*}+c%L(B<`zyxApnoGccYLAA@;_#WT5sXRU0AOVQ@&v~ z{Cz^3;qZblz2?zcnf{2DAwWEz?v5?XDFZpO)j%xYfj-)Bv)4$G}6jzCk1B7sv0 z&_N{IwFHdGzNndZe0VnzRO5VdB~l!_yJ+o#^$Ag|K;Id3{(||(Qyr9H`>tC3rWC)A z6#*Xy`+BIURtW)p!N=mdIC}d6dw&V;DkQ2$y?NJ8>{t?z__UNDTSb7-#dc#>lwFIy z-tlMScR!|rN~u4~!CRlxk9>{i10|D&K7gj(1UcDyw^>QV@XMON6$6mC!mG$b?jG$n zJ|FuJR`Le~NrPj0%6J_sl9KpDX8VH+O*fvde)~V((^wS@^-8Y4FHb79J*L3`?O-Wz zGCgW+04E95Q)3k_2K_fd979}^VJyO;J$=(TpWfN4GjV$3(?31f?Nqf+{S^J-Ygz4= zzLi~!!P;fd$E`~Ob*)rYD>Z+;QVFZAS1-;H`?6Q>i>^Ca6)f~5Od{YZ{3C>i)3ROO zG1dM1Q4hUM*D@N)od;&QPRR@gkGdo&o!_rDv(h@RLCoj9L}3C(PeY!TkqMY{r79mV zh(b{xw?1~tAJJosq3Xmihpe&tRL;T$DA@ay-akIS0jC ztfKSaysB1?p_T(b$>u6A!5<_!!X6YWKOu__av1b)BoI~Sq?A@(%vip>=I3bKT(h_e z&ro?;Fpl5y)XEa^Z;X+)8F#J+dBw|3oaw^{Q4oQ|>V~naatDNcYSBE`XE1^VBze(+ zLI~RL)o)EHTBG8fI7%$^E}otOZ0lHi3uxt8wPWF}<_lyC-|(fMb<8}_lV7Zbh zY$R+v|tMZ;`3EnRu z@9OFF&fqFJ^CkP>mCzE&+f|uORON%ZA^~@Z@?0jNs>YoI`wHWXjy`_zf=U2Qf8HJe z>m{pIL2_6_65F8^_`kkcYRD4lH$|N~Qt>&lqb9Nnqntg0u)a`E)G#22t9RXI9x$QhY7MM_lh$xQs)b%JRt34!UmdXon6n2QgtHlrJ@1}ONV#}l{|3_r z!}@l2VyMRj0(8NL5gd^Y(;Z{w^PI9gBEsSil77RhFFV*jN(yju87G-Bo0|0nT>Qx6 z`vbvc=hOT1$e=~Npui>Ab|XI#oGklwHBQc36Fv-*x``;p*;$UD`m=HuAXb18s|9(Tu6&{d z{S5P5e5DsE9{lCy`N+|fF`>8akqWgl4oWsTHY9KQ_2bYK|8TA&O1OeASVzlKhU> zkK5@D+DlpjtAn>@`7Fggma zme3czNVX}>5gG-5b_0l>#tT^W}T)9 zbtomUkWcNFK$_6W;NpN*UovL+>SKf%^Qgp;7reRT=c@&G8`S@}0LJ}0C>dCZ>O+!V!M|atOYOoiQ#AMtC_Nio2i!jD0L?+&*q88C zl5z&h$FCSWI3i2xZy&IOOSHj~5oWaz*A-TdQjWw+z;-gyd!jeEe>V4N;5AzZSH=-P zo1Xi#Kz2Qv6U4fpUhh_isrYG1qi!J4AbQjq$mKgQ7RALs_X2q%p^AGq_TES^Nd5On z-2)J#2VKYOpH2NFTg~Vo5?eAMCpg##wnZA6d@#HRW*Z;#0wh$JhK8(2M)_m8x;2^z zl-#aj3=fG#V}%c4xC@jFF2N725auzjJPw^m?V1u#56$O=b0`OyZ3>e44y8qZ(#gMN zNLF#xZ77;7(`I2rpKZlib ziTjPoG~<^)taKmQc&C$L%uH589n=KdkQP=T(~e}FdTYQs%)B1-1Wsq8;G6pw)H58| zWiYyk*vzior#LOE?7)`|alQ57nz}*GZ!p#H6t4t)20G8(H_Od~;4?oYbvv*4RUo{j zWm!GP6tPEsX1jx$tUXiP9JpiM?)i@q}1fu7?g-FPv zew(WkNvL!7*m2!D&k)qcV>fv3?=i7x>#kh&D2gwspTi4-4fO>)XwgzW3W+7rCRK51lf7zt2S_BA}-t9@A z0%s8o_=NcrPZ)P{+RFLPss$%w@x&&(j3i$;nt+)o+d78LmT+fM@~D<529H=%duJhM zIgu=;#C%Rvh;l~_8F@pBOxeSl(Ff3XzRB$`1)Q3~6AzT;t?0@y1T&8sBDdv(j0f`B zFF4ts;nTagT_`_lWr#YYH(YutDQYpnGt%|a#6TS@m%X?m#ti}cV=u+(Fsyz$95^mw z4(zG4u_#XWk_RZYpdgKDTh!xtZ@$z${+%Z6jw;Bo8nhhzGw$3c=A6I%$hsbP8=RGJRk zl2pEooM;7syDD1h4YOXAKS3#azieL;Z3@3HVoRX&?TskQ$H`&JP2Gc7>f9foWV8E7 z#{c)xC1jYrf3U`h{nEEw-2A=Z9#UOosSs?)*{cJUa%^33^DIj;FX?{RY{4`(Rtw#SrxyLd$g6L=|4ol_roXgQe(Vtju_-uP{q6$wT zc$}zbL`E(Luc#uL!rmU_sL!B&9!arULn~iUJ|A82*MW*js;e~{B8V|I3n*te94aPM zxon{JS1Jh#B$#$bGa2$HN2!r0%q&RMZIh&DX_tG9!ue7%;K)G3e<=12dpHJ%sh#iSiDoT@hg;km-;# z5IZrDW&QDPi>i68Jhk(DSC3PRcn~3$@C)DlYTpdKr zJ|h&CnmD#JxbTvmXcW3keN;!_@`&{nC#6Jejnj&>Enk^|=Q(xe8=Dc^Mgpjhn){VxBq}TIK|`G{ zvR?mqP2fxdgL46U;C4gCv|P3LYrnT}ozi+6stf4UD0&Xdyxv5yjKz{++AmPaSHlDu z!VSybpcWaR=|6balW1pxrwn_6%%@~Xq`x>Bqv=oOYx69}xG)#{*0#vSY$b}bfDcxm za{P6_L%D7jOGd&f;7`@ETwlCmut%fZ>@|#L^j;p7AJdZ6kTc`pHn2r4D*M)u`mLVH z;{Y9Mic6IIKo42YBW^f+&ANOI2aEWSSmU*Y6RpFtU3UfXGDG+`j8)MisD+%@uGdG4 zGeN^bHbz`+Ly)T=@@ILeA_iue<{QTNU}sZWyq@lHO3-p&c2P8zuYak79ypm_s-wt$ z28w(;=5IA3sqR*t*YnRdj(}t=06g`DZ()g3TDAbQo)eNxo=@ZhAjQS^HVA#6W{TKc zcE&gML8QIVCqx~nKR!6#;7fcCGrLW{QXtufHVtk29)&s#L@z&LUGy5D>|oHa5pdG$ zYu9U&;->yS4tumPj!Sew4ohE3MSZ;B>=ij)O0gzaO(zpM%Fm+b&bf#i6HtpZrP=(3 zPRJuprqy^FBe^Z_0@K>gPX)2t`@$o%u-J+0Zr#)x3IAR?PVo;Z=JL-N``XA$TwOYPN$1A2Ac_RJxurlZ`zt4VQ7%Ceh2{`INFxY-Ep%D$E zUC<9N2GRa9P0~Dg0UcsCvvMC>;YCX~9_eyWKwS&! z9at)b4CP?Wbw${kJ0G-=pqXwV{6^!3cR<2oHLxyB2l1IsAITqqcuW}x639WjpC$+R z)!}+w8#BOI9{tGt(O#$B*=U@}WrMYdQ}FSXEhaQm-F;a&aKIh@rM85!xla)RX=gp; zjH`sa_A5eaiBa$cf$b5Ed5*d18qqa@HFamoyE$si}VL0eQPkIHS8fH_S z`haP|g)ebfl@B)P4M&uOK)_v}mwS(}$_Qs(eJk|um*TmrF^uoUBT z)#)QfgLvVd3S4)QknHbbBZ}E2nk}-;G|VBSfw~q291+BQ4~R4ci;!U|^>2V2LjN8< zud)nP#3EJ@CceL}&N~ZRRMmR4*mfWCdk8iUB{ zm-kVppW7K(i~VVAbtgBOT5^w&2VDd=A=?1lJdR`ZJKvx%hxvBa=7Gr|kCvU}mbm(? z39qcOmQ*pU9Y#ZNrAm#Y0{N7*DkX`b)Q=?dcxuC1&RXH_3^RD0C*AjE?t#Z)=^L|p z_L5ACb>Dy|3}Rm@LKOO5$duVPdVG*+3B(qs@8zL3_04TH3)AVdlrDt$&P?~2H@9eQ zfMo079rQ*@Z^d%KwViLh>wwXqT`rBgPmQreY29TWO4=38WZ;DfQCL8@hFZv8H8)56 za*vY<^6A0=A*HE5HX1vrL_`jX9hK_h5~`^=wRx9IK~Px1r|(&sVwIwLU!x-yajNgn z0cYpG^@37|=<&lXxXJ=>z?-mw&v!g&xva8jPL@CHm=Hy^_i-z1G^ydD!Y}tE){OKF zlYv?t19=WF#RB|o4sVPNBX~mT7_9}z73PouMf&^kM|S$3Me^@i$9$4m9BAtI4?*TUBrMujL z1XW;k(lR2EHvE;tK|e5=sBb~Y+$#3wx2%LE;VccX#Xc#&X_;Tkil9r26givzDXPDfR|jQkB>(YUy}ijDb5QzJ<* z$-DX#3I6ht6hA6@O6u&P_qNQY!0hhM4qlg48)Ep*xn-hN&% z0-9fs_@nej_(qr>MjgCHxoSRJ1DKD}UMcipb#6#O{imI523v}QSKqAmwY~>?>QhAg z=X%vO?xSRJZPL+3E1@@TB*TyWe+HYUB>xOACZk)yrFcjrf^7TJ_=s>J2{PTCme#UX z>&nG9Dye+X66Hrn#R_4DSRan8>WMD-+cA~}V9j@tTIJWeA5a@PE+B~DH`dc|Ph9f; z#)`@*qf+GN$UI+cLB3xMz{!my0TPiLI{;a4R;oH5m`Z_k^L`b$P`TUF&sb&$ySIjk zp*lx2Z~kF&Kb8x;;_6FU4h8{rRkJylAeq!v2A8odrA0VAIkLIB3K0L&()Me}WUT6V zce8~NdHUXj)IZ0n50)6R6YGTZ1!H{u+=M3(9mvdVU|9&$W3YfbL#9@o1tXUz))p5j z*{MjZR-RzV?}>h`NLK$lmlprr;XKC9Hf)UbQ*X&rF+dQ)V)^ zam%e^dUGGFe<;HKTo*ex98}#xqwg{t6Ib=Q3e(oe`IVrlAtH2{+U*zd*FYp06Gd}Q zRLFC*)X9PL+2pImo7`I?WJC+mJm?1|^I_tfrH1@1>+HZEYZX=s7as-jlE~_z*ZBS~ zE~mSs0kDad#!l+AlJqkib}CE9-VEZyk1DKgzJ4pwMa1J0=;SVOY}Q#rR-85{Pq@vh zGQGc6<}-Fi-(BlhtB=QS*Zgd?yA!$gtIFAsP}nnn-O(gzXB6FVzyKON&^yoZHqrsn z7NZ_#Y_h@|6X1%P0jY`CJ~#94QoA88MQ1$X0CE8l8%QZEXlUw>{UL-Fj_jyJYzhbi zShF5Nkaq|DK(ff$JLAf$Obu9mdg*vJYroKS$s>G;3V5d2N6y6K3eNmR$n31Q=>vs? z*k51RpzM8sVitMl@EJxZ{#3@7Ew)79i@xd43C2Dxb-6{$sK;)J7wlPzwfG5gnkrZossRF$ zgBGQQufgcx^)NIy_@MyLVwq!=M5q28sH%k37r8%`Srp)U3h`T|jug}Dw@#>hbB5X% z%-XmlXx%Ssd=xyi9jYGlWz#Z`!+y;AMMBBeGa+l_PQ+WR8{7})d#oWE+d<=85NwYJ;>mSdnn(I!WLzg9x=+$jW|w4!>hC zFipwiZAu{XN>P$d49T$4+M5E-T6beYh~>gSs$Wn{;@(oZaR##xEhmR?dBww5$@PsW z8%%~^R3%V}Ygvn*d@iZS&pp;(ruj_J+Af6QZgFz23da795`krYRyrQSJB4@Eq{DTU zC~A=9>Q@Msqu2P!sM(I6Z~6=v!}C7nO}N?vHSd%roY(*>gaMXj0hvgmgJ-k_G0dtW z#GU*~>&HuhC<{`c+7CzZgd^#k)ElJ17?)l;Lke86N$Sl-(JeOW`M-xf2qhFT-fgZD zXM6^UUNDxm6!%mMi`T1j@df!Xp~%u?`4xL=yXCpA&KrUeV(yp-I~> z@XJtFt)3PS!x|tnPsw6N;ENqZwn20qM#PJF3hpZwMB$)+x5k;)!rUaSz`7(}Q)w}7 zWxXYg{`WLJ_7z#op*9%U=sBUa_KBE1!fG+6Tjjvvv&BQVf$hRf*U}QOFtDL}u5@AK zwTC#dKkxGi;30he?WgC490hvak0e~jTK0sZNZnW3en&~hbz z30K^N8$YFws){dbN8k3Pd&UZ(hZr67r@K@owYLhVOZ$@v0Q_fVKQ$S@#e0?cDMt}# z|FiAe>6`xfk_@}y$3u0|qFQ8$(f5~|6{($#R^#T(z**iigARh!or7Q``Mki@12rGgoS zbysfnGQHt)3TQ+T@FYx4jxSV7GQD{#vq6wV)tIaK?)E!rADHZvnKb>#_?7(Q+R6kjI6X@Qn9iV@;9BWfttWm z^dM*Mi07S7wg(Xc!Jfr&U8WIvS(%c$JU18&YcM%4&rkUM$!h_&J{(@&9OU!9{!J}F|9NY z&&!_m%I)N7RZ;1YlMJ3ghP8vO2ze}RT4(^c@NOy=-1>3p*LpC1laV*$JUHXV_E^p% zq9OP1hmkp=?gV_y!?k+dr_j3lshi;iCVt~bq`ztrAqt>&;?G;fF{^4r6j-U5uSoOQ zayu*Fp#m^>GuoYkyk9=M8zWazEg^KqOqK0E$9jXN_R*tpr#BW1*8vDIP#o)=N44Y5 z1%Y_vcf*DuvT7n=Fq67o@Kzl}5n-XsWZ8mP3|d|3lVAnf2Ra3@7JNf9Y6+#eQcy^G z-j>Pd<`Uv?jYEWfZRRKb=^Macwk!}}J$8c|LQC$+;DM6~?8Ru2zdL*5ly^zTtGqH> zOd>m~RPi#hHtwF#3zctZpepB18guLfhw zzx!xvY^&pTzy}5Pf=fRZbqm0OE%*mkNHJb!pC7q>>d(?d1O}HQT<)5lgSV~5by{4n zuJC7yQl(lyy>tYquf9s4WfPV=-;-8xH|Uo)5RAqP@-D)7=dHfddG;6-pi-ye9_vl_ z+f#sw^!w&PSG`Uty*5%0Ds&xLQ%08PDhHqvZD8HJVcUaRn-P$=<}ip_tF)AdmR9+d z#40c1>!Fyl(X(@8A2?TYitMt$jja^XSN?oipk$^jokjauUlwN@W+6{D~SZ# z#rNDDb4?;f?PG5CAgtcVb51JkO&};;Kww?4E~n6>w-o4YND6C+VVaH` zqp<#9lNY_IKqs>oMdXApXdTGR*8DlsTl0(cix0nnsFuK((!&uze-S3%wmMz}+37c> zRo}_jfn@=FbYHF(GjyGIKFlu(xVRwItD?aTANk9=Mt1 zhkpyWQ-*8I*VL{TryEa8WZ5cNmk^v8Tzsbof0B{yy-||^$jp4t>vMQ9BVWHzy(4M+ z75VaTblOPv5OEe?)|P$sQiWy@MA9WeN^?EM09~rmTta9A$L{Af)yI5Eu(;A}9e2Tmq-c5W(GnTq_YZs&b5rL3%o*HoPBDlm3%<5yy!OMu;}}Lst-| z{=>pI*WH><3hh($;qL z@6d~2^gf1W1{wP{kiz6AMjbhNcVYJiseMH}MKnYzhyUxkfAfQ~MZ znCx{R+xg*DNRrzF^Eh7W-&bUV5y8VjirmBEGW8G>wA8_;kJZTs&lw~43jl}C= z7z?grA1VXf=uoG*4AYfy}Uy8zGx*P|^>S#!v_A{CGJ95^x6=-(E$M)@QrOmQcFmoV{Hz zFxnNh5ilZw&_W0x>>)P|V_@_xu4s!~8a@#{F}&c0>|W8h#94Z18NUCA{>$G@t}k51 zK$bI*)V48;&npJfjS#t-{E-1Ba(x#^(RF9G(*!nKlzFTxH1{kt)L&Xy{6uHy{x@=~ zk2@f^MD4En_ulW-+SrZHJTrI@4LNn0vf!AMF4YZnJQXeRGHyX@9z33BPQuG-Q%$^X zJJ*a=k&ul_zqTw*pR=7!bU`$_d5%Q!v!? zwxn3-Gi6bZN@Hj<^8mH>;?^EV#YO6pyR^CPzE-HeoHD9Gun6om=MusbV?tT3IAdyz zF)01>_6bbqkq~mhmij{O3*^A4HOqm;v>N66(~=kWFOL{M*=QwGy>_V{$_D9GeK|kJ zTn0)>bkXzIgwiiG<@x5i=azV-W<8ig(r0EYNpZ!?R+-o7uBbh}5S=}S!7nv_6G3c3 zJY$XPF?k=g|Ak@8ufnHwtBB{hi3(^5U%tI&sN{X728YYl70A#_Rc!w)%;trRFr66 zaqwVau4tRmG#sL%zT?P-!2}Wq-uEq*Je2|7uhGi#L>(^7q%up(L01qJi&Cvz`Py*`V=V^V^4cn#v8}=%ZsKLqkAzpY%*M{n*`dNHG3>6^&=%gu?G(E*)zL=fkQsMyunNHVkvA}A zJ-7pLT`vLXJ_27U=!|0V0WmuQ`pZ|$*xfjX41xxu_1}LKVM=D#`W}1E6VO~DVxhZL?io?Lp?BO$C~-a>~qA3 z>>S3Tph#UR8VrQWF#T?H4xMbmN10k+Y%2wqBxkEzRV<)Ic^q&o)V0>1y?<8`y&z5j zAmAX!gNsj8on&kHAXQh&IkvIF;zy0CVysTmI34`94sZ!NXQz4yH%xWmld&x?2Nnl!H*(m4{OSTTTGXkE&%io8lHVX=Gg4FH2AnpiNq3l$bvjDU z-r8#Lqw`dY?Q|}#kN`P~D+|j<>$&mKS%M=mDYQ)i9 zk>81Uqvz!u3BH}o^s(A7*ThJ>9vKmu2*DX6gfrk>Vj(;~ZheTvX_2pz;JM9TPaM)W z%5>>o!PsAXkq_Ql7vhXu9L$S3z(-OG=Nx%N;I}}0P`yykM1diAV(^R&c;EFyg{$y; zcFYKD%)9(H%vGl&F%g9yJhUjnC9lo-ORT0jIvgb6ABBhCm>P~RlK;qoBg!EpQa6Ho z;@XrO3inQ4J<>W8&pBUD9d@Eu`&J-k zBJCl4Ro!^u!U>_F=2_ax3OEwToJh(uOXrVQ69|a~oT1kCPPpGlqKd|8^LTMsuX)wn zG1#)$CmeKVJph6oxqeo^gpu08ZNGpr-^Q7sN-70$U0Ir=4=yx{-<(z@b=LK5v@(YelSPs>j2KsAq5a;*RUVD;7SHCI zG;V(hGULHBVz$-%)~P3#O0$`+lLgiVg9Th8mcTtbJO&pxK|hJ0B99k0eE?Ens`q!4;j5$XMC($h;OD*@RfBdi7 zWAN#-(wM7E847sFOwd!VD1|fws-)^FC2!z3)*AGl6^&<%(H0K?c>WD79VloNU^xfO zL5XBB-t8Kp@;Tyto8swHtg;hc2Ar;2n;@0T@ZoFEhnfP;_|v1mxI8h(9&BsvzF8ak-yxlez+Ns?<4eQH6^?}@6uA#H=X*d!qHEORSFeY_@0CBq6M>Z=vh`sHy8gw7*0jNph7=N{^(RdivMOL>3?ij${t&yRKpbEtq<~0Tg~{B>m@RO9!uwC91;0$s2P{DVCdA6{DMVPU|k4?UB+`KU!Di>Te3+J0NdvMIa0>%H+8>WQ^?hC`j@4aFE9% zM4rp7!b~svehnI)?IMDwOi`-&HN%?LPfHWqhTp%NQag=OizHizC~Z1=R^+i?IPzyu z`e-k`I}-8=>h$nRN_}G(NtOtCD7Jvw8O&T&+&)>t+jnLI$;zJ`yzOtUKp*SS<@T)zkQ6 zSC|eOQJR19xsz9z;^!7uRovac80+Q01N+ol(+VF#H53|F^-F{4Q)>4sI0nYYI9w?X zm0P7p+B7ahs^D!0wMFV)ACJD=heXCd?B_lrF^FyAM{`GR^`Y2yT*1sFIG8Z}v);S9$IxzqTasbA?&EmB9lk#*hg$v=ztxj$gSa(3C@wv3Z+iZtMX+*fcb{* zJ-sy~F?qK4aGn&Sz_Y!muquWsHFZJ|jSk@ug_7<~HBfsz3Xr+%=~-51ppm(Bm7Z+? zB};gejcg14&Yo~Jf%t9(Rs%~oB~)4r=Kx`t$U^tZD#!s}d)d4QMC1_$L4wTL1H%P$ zup#-a2?0aWq;wF3%tfv%q8kD-v2zLb*kr)ob7HDHbZs60OeLU+%HM%0SU)aH1$Ixt z-03ON?U_0~7oBussZLHG5%ar$|5Zg*H*#6vGq-;{8E#z#?`<+eh#(8Hj7PC8B;LH) z+Ap#&(a3Y9Lmk6&{XQ=JxIDmpJFmEOR2)PBQY!1*))DT^bF!bfS06I**;o-G5%wOh z(JCX>!QG@ZU0I2OxJ;2qzjaoYs-0fi5uOOV`~$n@esKTDXMbvb#o7`C8--#4lQ-zL zaaY`2SVLE*is+lUbbU$$pl0DV$t%j6PN#%wK%+9o1afL_Uq@vq!Rn+*@shg$FEvbu ztod|XJJL*W)aE+so??;KHffUa+|Tr zjnLn@SPl#UkAxx@QSG^5O!`au#S>%UWr0NJ*Z|#rs3D>l&EpRk7bGx2Bm0Aq@3Xz& zB|5A`w9dYuQWV;4N|-zZOPA(7#Pe>Mo9%y4%g0VDe{rDqYl=b1&7MI01P;xX6mXIOwkWlS z)F{?}wD2cB`=vyR?gS(S8RdQW1lPe%>oKcChg6tlM|E(pRgl_mTMpfKn+!r_pb~6QUM9^mol~paA3l%Tm)19vW6IS^nYJ8EMCUU%SimB z7+h%tS@4@mU14@G1^~u~G#O}a&q!P_dMRtO6_{<()v-vyqBgL^yvE7raUi>}f@XL8 z8``sy53;yXuN1#L>csndN6m2bADk>r`StdUzL64HSg4SjNMFhjDOz7!3x|YWHxh;XqpqQ2ka6jI!`IR1aHN(3^$A7^YAn-x&=f2SeO`oG(@bvP!@8=#Ab zGs=AbU2+udbw5HFZ0BE&Egv%v7F2rdf{5lIq93Zz@`FbdUM@L%m6_5}ybPGt#3Lss zx!)_xe!WF~4$~!m*s=T{xs)^Z5A~b7`MP8O|L^-(qp+U4)R@rD`f|%065J}fvvs7b zWHPIgjsT!%w#h@Tz1;?5!Xd)?BTb|C2mMUiKg*No^vSIX)599-T{`PV{iFz{EaB>j z>)AXSqC`d8g0xkO)06+(qu771P}d4GO3W6i60K)xid2R}K@^}ve`}`q|k{7Yx zP(418*8eQO?UA_sQJ4Ambu*Ssb8;4jR^cn8<)Dc5%jA{320O=^_$?+ADNYQ>yLE3U!ko9zJMOV6dF{vpYj|N9_M+O< zx#Y)qIt*nsoIwKZ=y-tXCA43FGbZoeN3oQROZ-f?&qQhA!%Dl-LO)JQ42c;Z4A)5V z@DQk)vP@QGtN(L1)C_9>d&V$yYem@`=70n`M&Ftc#pDMQF2e+@B$(lf#z*}~l!f+< z(>)XTycH3Ix=Djqw}rqYX!;RU62C)w5A?oIw?o~ z=bjG~d1ku@`dlbWJ`n2ir?tjX9;v9HqluS&Sf7X$?$({aI(1KWp|x-lETm&oLMlf} zVXT=>^rcLA{r8dKvJJtE!oS^&BmDPfH?lMdWhf<{7R3*pSQ@@RHUrRe zh+v}#=*dz6+X8^s4DL)2CL-_Vb&33AL9pEP?Pu=)?CIx%e+LWH8vw;* z(VY>muc*cjNyz$SI59cedo+oVH6^;G0};x#`too^r!@r}t#rT^PHPP#>Oeq$#tLH( zS;hu#$U*|!l3XYn&x58yfnt0bK@XlxFT39jUJEgbn(cJB(`Wyh_$V>Fy3`iA^^G(%tnA9^mKy;=M57V(;gfS+i!%T5G#Yzt=k`kn?H!ydM+V%`vm>w1b=GzNQr^D=6(3!y9zaXd4zf3wXEUO#}Q zqo_zMEpiF@4&ka|g8%oS=M)U#1q*?M@AS`RDeg176KZHQ2lEoQyu>Yd>EI0#5S%UC zs1wT0yWkdlo$z|8;3r~swGNSE=?kU`Y!%ckJrE|Cp0I7PTsh2t5S&9dw!gC_sB^XSGLem#wlrtzQA{1l%n9;qt=qxLZhH6d z*~RwtqDskT{O>{tAL!oD;LCU!XW{%UpF-u!w?01*eMd^p<#f2t_H?mzHs-^c_u0fL+7sBBVs;~cqdyB-+Mqv>Qa)2g` z?zK6e_WHSxs1t%uAD1V9D3oV|XmNQ3WIMJXQv#gp?TE;CF2!}*QcRI^kxbKG`M!Qb zU*jA_4?21Cqv1F=ncXjswXS>Kz=hxDE@sgm zA^xD{ex%+P_}3gSwvXCuY4(~-=A=If%j+#?@Y+SdF*XW6M-knvZF;-Ia+mxvh%Z0u zOEM?x9gu=Wc+X7lR9iLbqw?c*_-9P+zMB<*bF%`Lgvb_ue4~$jz$6Fm@nMfjL0`~F z^S%!P$sSy#4!q!JaTt2gr-QUmOecF!N)YFQ3iL0o9uYOJn8x3=mZf)iDGFc%y+?|A z@#=;|-3C+LRiJI-m!}}eG4fHLjvqrnsbc(bt3Ab!uqD?!H}`%2pUy_zLn}9M zVw+No{l>Lug<<}FrpI9>2CR_vB?i)YTT`-wcYhA(TU>qLr>sWdD`UcjU z=;r5w3|Y=n*sqeWI-b8h4@nsx2C5DIVzTVw>?Xwwe(bZ2J~9_&F+4Me_sC#C9!XU+ zrjTPmoKxS5#iSUA9zqV0*`q_zet1~)HT5hu0dv=TKiQvRs%QMt?O=mbyvI|8Xse`Z z`RQ}-FOqyO6Q2nL+%bIr^6s4!s+UhlXI}zniqxmw%Y7}I>H&^+wun^u{%al(7Wq3euP-DW!22wGH+@hntMF5;7 zK+lpAX9Sd=w26pxB=;L-3k1p39S{d>2$>vf*cX8qxr_4xLQ_>WAOWx2YmlrdHa)lq z;^cI73|9nboa4pA!lu-=4mnUqHW`7(_vo$pY-(APsUOoEJrrzImN9(oEW8>PDd>|6|I-Jl(n)$z%ugtc8XSihtBt#U?hF<_ zEf^=2A{>m?k4NTK@T1vun-5wA_aPXkyu!a=S9^+BR~qe>xvolu9#poawzJIx!Sf*2 z+SMff?FRxQMf9>;CeDxCPO61-~HtEsmCrDD->s0e7xbosI{HGW(X z=+yo|l6xi$#5w|6aAQm>1#sbs9v6qCn+3589Hb+}X0X|Nbsr`|%wBcU>T{loF_&Zt zhn=r2-J`Uw{qRU|hOIiG@Qvjp3mM*=d5caBb^Kv(h~U46~W^R=j~0c%`{&w&|SR%)<})PqsRc zeY=hIh{lh+c+XZn8rVJ*jG4drhF$HQFlSFfVXiuhBE;SiUb@y4f?P@=#`B9`FLG9g zQrXy|E$Q*WQEtPXBk}`zo7ZE^xfT&s&K>E*3opSmHt8j)0YS0plbp@t z__`Aq`=T{rK=p8q>yjOSJOJ|OcTC4JJD{o*&9u+IbZgn2rJ{p>q=bKalw`}QG4<5P zW*~;bKYZYqLO^@{qm>0hKcO(47nppX{2Kr_1Jd!8*?=<7)WL@R_Xky)!C$b8=OV02 zg?EJ|PEysc45$14Gv`+Q>hY>7jHYaN>ECNsFqE~}f>*W|Mpw_QrN*8^Qyhl&C%T)Tjyehx%)^1aR*$ciJ@fBey{{xdPA zH^Oen6!1cQGxQFYgZ&ufP7#1Y+TTnT93M%mHlRVvY5F#un1kYJBN_Cm= zW{msPZ-hWRWV5y2DxyHyTTYrheq*K5+)X$rR@4K)l-Dt1G9o4C#`%ThY=gsU%}oos zK#BxIp63;yo8Q6s?R+xeRPX_vlAVl^!}SCwkF8Tt>D0Pzx?i(;yLOgnYK~4-Vn_*N zTHd>4rNBRzq^|yHxmtl~K>&+Mk8Pqdd**|VVhN;nLUS+mKvc)+DsvNY4IpoKJBcTWyM^i_kA zZe|&UXl~QD-g<-uU7)Z+Y_;<9-%Du!FYYOAL>gs8qTDHTeW{yP}v;YD4nbr`_{%s{IM zELhNaf}_4&-ge5wR91f%$iM5e{ifDQx#uWmKN*_<{j)yjo-5M$-!3?VR z`T6h3G?PP28GEk-psWr1Kxdam@Vr(AyU=0-YPOs@d}C#0 zCf4*4wjOYf^*QwHei+3T+3Vm#om>`g^ z4H5@p7g=4y^5t$6tKO2mll%{VjtrEpJs&Li5M}hYl>KqseMGqPng@bx_{7CwXNIowFLr1 zTZP4UvgDo4Yi{4Gdh|wf5P=`PB-e%$GpBkg3x6EIu$FMR6l+qF=A=TS_0{;5veEMEn-Da<$y56^ZWhp4U_(J0$+y~0nZw|qgFF~iiNlfY^}HUPAY z1#tH(dsC$XaX0tGdAGw>p8kBmhUcgKj)ce&H=*hAnWxf5`0--Z)INq)WRCH|<8-vh z{H6XCM0%i_gkkOu&f|CS>>II5T(d4do=d7gZdal*HrJ-C zDsJ;^BI3s8uxh^E06}xKN%%XyJnGagxmq>@og#pp5v4a&7eOe>Qc-OXt0kbK?qqVV z>A$K{CMtoY)E9tZlhJ@=$5o!JRVWvwj5GV0H6tTZFPd|5v=b6xDlNLLI$aVVTL~cy zF`G^9kQYA~GC9g8|7}HyJA9xkVc)pqGNpE~gGFW$7Sr|W*_(t%I5?MEn5($>Y87hj$={z9BXdPb}tl#Vu0TKuRzmSe}qF$s2;NeDbshIN3 zenxEVe6b!8oTSm(A<}V1rK2@aYbpR40Nh%Fp5Kn>%NHHuv4#aJ=7h1TQ@qwMzX`;-z)2U_{$ib;j+a#O<=Wu{6*0w!@ z$D6J^jzZS-z`hbDEpaICw%+>SMkkDXF8Ia)Ckj&l*vo!WpF$DP(w(j`$Whx#!sFgN z_AQo9Tio}P9$fm?V-irJDN9>A!VDMer$qpo*VE@!xO60#8$NMRwsz~Y`z9oqsteS0 zd!19v6<-0h{0Z`LW`a_$qbgoVz1!^F>~Z(jc)5EeQvqQ(tI|;7Pt0w^Zd=Get{arK zWTaJp^BtDA-9=p)+WGe&OCCTJ(%HL#R#;RwkOCa89EvSeh2@pqFPp({k*V6$5X6kB zM4pB(|0)K?+W(E4>sHt7a1!7YWY`Ni&(TM zi=y;sa0Ls+V4{Z~)%Xbz0;V%nT=b#@P|W9H9HjV(_XBC=Ej?R~62-~fcDoPhrgx0W zK*HMzxVdyYj_G5H$e;W3wFH~34kPc*)fdXTLJ>%Q5Adv0utsTzl=k!osz#;XpCAq7 zf6OagH0Z2uorOMN&Ca}z#H!<>d+ROeZ#E--v1nt!6KE9lrgYT0LrP0u1<$cDOT`7h z2Fho_xoT{lN=Rll<5mHZZ~XzK5|JLfvWGT55l5FM2__R&BWFo=g7dxUp=Ft}<+Rg~ zO@)b3g#^~m!)ZTM=N>7KBq=@RoME+(XuZd;Y*9x3yf{!RZUK9evqdYAd&5G$yiv$y zP>-dktj48PUj@nL@-Wiqo$Lm1E`rYt{7{hM7luqrp1Ytt;uq`tWK27BG$f5L^(5A&kT>!F?(B zb6u_mXjey@)z12|Cc(16{cc&HcR$wuP(bqcqf{74RjMb{!hXNdkL%YROodJ*7yAVS zks>_+XIAXlnILM@3a)pXqyK7ZcFLZ%k`E~miy=Gm;9fUW9zT#B7s&ywdd^FnLj^!b z(sn%#Py9pn*E2{@a~Beme8c$>leoO-p(7cKBo}U_W}?r~PEc zwm=KY&#=d37SCuKwT~!VeW{M@jJ+BrIpI*~-KCgKhu*4zIF0hzAr(t-8-XH92f#z8 zf%39}L+9aw-C*jUvkmZ$%W0tNEq*U$iEBx**KxGdrHnLRY`c1w@k|OU0NT9RK>c($ zn~OiIvOq5CwLA3Ejt8xvspYK zlNXNGc+4i_*KYMJ2%scgnuVCqe-u~;vkr)+Ln^-JB0AqEYa-iQx2{lP*5z0<)yg@R| z3Fjj4%Gq;~ghDQY?7pY27J{J2)NZ^l#ATws{&nA5A+|=h)6Ed+lG6G+IUhgQaGtL=eOMpkF8Z}2*d1MBz%Zf##9Uv$3&aIK8J#aVsG*wB75>l) zbQ)H%E7rzUtG}GH3ussDHFEwpP>XteF^-H7YCJ@G%XZx3v%2*PMEbEnO<1iw%A>;m zY|}mo1hKYmyJb7e+~|dA%wn%ItIhK`R2(=jQtr#jYzN4njV4^OXX-1$Q`!N8*oTgT z)VMX>=Dxbkik!20I?W_tfn9F%E{2CJI_~0Yde4(=I@RinLFMR4L#1(GyDWX0MvDA0 zTgBwwdpyR0hx1P5LX%DJ*2m~dN4R#oSjK787@E-B4iDYLy8y!%Eb`onU{u3yxqG~I zzINKsmfo(-$7S+vTrR~k<}LGS*kNKrvFb1W%-@w`-&1g{!o4!?KGbKy#fj*hsKXy@ zjAZL7bErtN3->WUTV0py)7q$n&7jir2bu3-dQelBe9bf^-~ zg6aahikiaMMG;HV@$GSCSE>||+K23W+{i*N?^a9WV7KM6zN+0UqauA4#}x|_J9(AQ zHEtt{DXyD{A{D?<)ru>%;KTn~>pQe3lQP4MgJitWSSQA-a~xkG%E{jIIT=#{VCF|a z+Sy9iKUcRN>XF#ZIsR=ZJ2FYsti^?3WuEUMwbH_v}56C7R60F_sx1pZFe` zWX-(@uW6YwY%~aJ*a@KWfoi&B7yX)Nz%Tq|vi0TA>+z*%4gp=>=@Ik##iqq*u6?cj zx=Df79Gtvm-X1BwnbBUUAZy#9MJGEdQg=r52Q{Ng0r|oFh**R)Sq#%?BW|v3iEMU% z`NfTYBoF5v##q_J`15nPEk9a8LGa}7))k)@Z!%nWACXFrO{;FaZX@ng%*9fbW&ZJ` zYBYx{qohQOTteOKiL)S(JAR(A4>B=zrzZMUJf<2m0CzA?yu|9N?Mra!XpSG!MEBK{ z-kGleX%i*rXqX?Bc1u?s2*H||tkxPj6Z9vwgxFg9i=2gCTEy>WNjxF)w9`@+__zVJ zFMpbI&;=cUspWiN6vbL3gxxm@mJ+ohN{Xa7I62IVv+DbDxGusI@5e4OrAP0;D~;8! z^fO{wl6OprVR@B1U>p{Jlk*!|tEWrD`n}+G(sh+Pg(>5#z2~Om|MQrbOoocur(1coW# z0O~Xjh)4iC`M!iQ{%Jt_d*qjVVxcs5-y^J7WZ~vS!tTp*Cr8>dlN`=KCUWniO_l#z zr#RDXAI}L`3UJzTC$B%rChy`9nU+|D7S9F<+fdHxv_v<}!s~Q`7y$SWfh3a3_D>LS z^;gZIf@|l0Zc_wcEe!bS%tXId_hl*M0OaCy_ri-_$Dy$JY&UvlCH?l)!N;kZ-lP>$ zSTh+(Npr6w42RYHfKlVpg;;*=HXa&%!}CteD_;o*%E#HxBPTQQi$b5Ri9FB|zFBDe z@#)ko3EvM zPjhbPhUd$4@qc@@2T=UC9=*s|K%3b2bCVKH%+#tqzL=v2313`nv0@)OpppC`fuM00 z$0Pg^kdY5mUin#H5Ay7k?Cm?@oA&0_UG#3fvn?kId2Zb0b{vdF! z)<_cOO$q{esH_&?S85FIO=)R}XDEJ8+jj@)w~d@Zqx^=0LV1VTxBI9+&czGJa|3*E zD+g1RB2H=yOU6fgz>z(zhjc9rXCT_hf!PtcmQUZSNH1#PIb}r~H+=ZS2bT^U1w>R= zP-`{Np3P%?J9|XN?Des7vP5}^~QDQ^wq@Y7aK@0~)35IFxKi=%GyuMl1 zb7D6-^gOQ`?!lC69HkgpWD}U3T@roKhSbmDYlS)=5NZZEJLM}&G&VVy&57bO)Bx+5 zITz>^=SgED^uBurnA7vYU?^XOw6HM88Zfv9(QxvfeH0?zv@hyfvB)#K8cK(RL!!EZ zx^qB-ISUljayolFU>@XgN_?O<p>gt)ru_YU4&& zv4wj3Q=Ami+mWUyBTg&q)OL{*3+XGf(olm8HbAyi=weR&(;W?Xc6b#(z?Pn40!1}O zZ^U3ju$#9UF>YThxLNQw}jJ4@bpoM`gpIaq7DAdGLjOy zmJZ+hY+^EgoK-fgOhf}XLK{wB3lk**>1?aUk-M@g-XHDHJ>IrP^C6~X!!aw=(rT4|^z+p5F4E>V7z;g#f zKoVMLnv+CqnBuZFuZ36DAq#SX-?C-=d~YMBB*xnj$H~?}Ao_|ol>f9qy{l~NXKXb$>PVe7SM4BMUv;^Ib#gFWnBq9Lm%vb`&5LG!_3Ogg zzcf7`yk$5DL|Mj-$qp?J%hOrcYYlUZWPvVtN$&oGgjapdW9c*{8uGEeymM_M$j~1~ z%~SaP=;kR}mec!eI8MuQY%s+lc=n>XA9!Yv1gly5hU0f*Bv|K9t^p7{uK{yKxvttA zyCpi`<9F}E3&3W6Mw$t{ETM5e_nMR%8u$!r9YB5m>A4U3@pl< zs%k@78r*2o;=e@&hFKH5tnO45H}{OFnFy1c-UBEhfL^l#fSBWaOroi{w?8FC>!kuT z`clCk&X?ojgn302Jl<9~y>v@jyaHP$?+(S8hZGX_gaJD#*J|BBs8hK%lqlrZMwD*6 znh?M)&?p=BeW)?FX+eQ`{Klx3tVt1zfvHY@vNbA+sL3{7*lBDUq)x9p2Cnc&e*2>ajeYGFn zqf{8KjIP?H@opGFNvLNII9+dJlVo_272}btD_2B5QA&A1X4>Kvuxx>>O){zWf_+dD z2CPqVZCLttvLx2JUs&j+>;8Y>>zctVxB#R-3uq%W1mMVFGG%0L zIC2ir&~tWaB4K`FVCP4(s2b<~-B8Hq>KCyx_@nl#?o%+V5>B}v#)S6c-_5EL%w$m|h0SMu-XCe6LURO+z=NZ>c4HN)Cs(b*b^oa3V)dl3z7=0JZ@yd;gh{x+cM`Y3(1}aIakq1ZXo__eZTcQ^c|eH zsyRj!;otuiXaU@Mz{?&~uxUbL91yMBS6&~hf)M*GSE|Gf(-duqcbI;WuhwF%0+0ui zX#DbM=J95V`2Fmv$(*E}JVfmR21xQ)XfN+%)vt31M^}L9z#>bTVqZXMffzk!s9ray z*ORROKA$opSq0=ULy2M15yx(g?2P+fwIT&`X1vBZ_8SCg<(Er)3wA$4l^)Ze+O=M= zDKW6G7DWb#F^F%w96phNC$(VMZfTMo0ANXwwz1B$XThTX{;67A?O|Fo4%wL>GF7~& z&L@Shwu1?sc@xbWH%?*a?T@fek^Yp?Ur5@lL>7$1q5YC;JX3_R`h9?U##65hjI(V;Am zrHkJVT2-R=M04)M_>!iZZoa)UH8Ko}@gpjEC_&0OaSh`*< zv9%>)tj{BbV*p%jzt-s(9u&kat>1pIXV`Heol~t6nA zK(wfKpIO#PLnu#H24qp@N$p_DsvDMel>;E5(p!CDm?c)AR8aV9ei*q#>2YY{o4nI< zGBlPE6gl9MK(oT1oISYX#E-U|kaqhaZ6zCQiytV4z$s2bY0$o1vXuWTv5;NPAZfQ<)G}b*u6Q`m-{e*d3y9pX?z>^-0a{BmQ!j7Dy_=1q|vu>-Pk4I2|#EAFw;T$ zXHC2vZl)1hUT8qn3ykZk(l9vn#I1`m^_e%JGdv%dx*g}79NjJ-1b|N=#hUJ7;?gxo%6~< zY|dKE0FR4@K$ObG`^~uam-q z4Qr!AOgFs%cTtHq%p=NE9A_sZgM5O2XT^j!H3j@DjUz2)6V-_%^An8TNE?sZ7T<@UB?CBQ~ z-S&n3Ud24I2FLZ+Kc0B0+YuOLEYMx{!hN6$O-dpV5UotCLLTV-FB-xtJb86xfJva@ z4mv%=&H45-#ogNC%VAP+HvFirp8T+gVAiS04VIpAL2KDCxg5~hVI(h4uM%W8)5^ir z7X-_9a#)V)vCh_B{n^~VKqV1nWV8gOp(!WWY#CsVH+MM0-yAYjfPR&7oy9vSUUEkv z6zruf{z+Q|CPkF7TiH_4An|w+3OD*JKurz0b%xG*Piq7M6Gb3R;VOcJh7O&;bAXF_ zhB~B_|6AuoiY|Z7TT+;yIA;P)4n8Q1sDh~6F_RY^T3Ow9s)487C#+HS+qcL&%#uH! z+9X-bM`D&U{q!cpIt8iu_PsvmJ`v-(SsK!n$Y+xfNq#6XST~iH1fUL9NAbQ zox-#=Zb286aW~Iv#l>hYTuQO#o0oO2zo;AQ-uc@&dCq!(d%2y|_O>Yn zthcJ`SYbuy1x=K(rNb-)Uv|^f@wY1%2+xz|BrarJEERaKSn);b$619X1rl-5_E@~s z^q`c&7-v{IYGb6c+?PEnBkj^6&w&X=Z$;jkeoy)Be4r?RN~O$}i>a4O!Xe9V^0tcb z_U$0#dc)%wYa)&Aycnq=WP!fpoE*+l05_Q5U{(&-*qEhrDizz;9TJ(^?>FiZ3o9yy zs)j6s*Q}aefXEY=bG{-1>`iUrd4)E@G5GK7%SJbicfph{0uhHze5h5^I=AlS?OWFC z-AGCZ)V!(XGS&9RILbU$9J_MV`m^9>XK7fI)}4P8wn5uU1Lw+Mv#5%D3%qkNdX;NQ zH*4ro6Z)ZIg3WgX&V&G#4+Z^OuZjol`ynivAq;8yVt>7uHUD+W!KT=kxf-tAiE7t8 zQdu^@C^1jJpgUaAQxu=$#5rjbq|Kq8c<2ZWDm?G%pmrZKB0_CdscwJ#$^{cbvx{PN z1E}I8(v(T{XC5wS=5+sF6S5GXiPqrDbNXN7*~gb**F|>{P;_T0U3Mn_xhmG20)W~s zjNAIfvh)D)xnVB!jAJEy-Na0rC<1T8Qw+RbQMq?vjxP?5KIb@yYo(uwT=i&Mr^gsu zE+Ia%c%9b25IXv@CAwLBNLl=KyOG>#pxo`*nVdZ9{dE^mNHi1ZicsokJFyuwx zBg(BmThT4*vit^<>F9rlUYaFKGUL9}$Z+&Mw~4351}pw0ebs1puC;Dlv;qgfMuGk|5V6(4=6Qg%b=ohiSUd?gQ`C49N2qx9b-V}KVAbq;e%sQn zCR){eww6`ieM#mEHfe@dwyA9-B9(-+zg|@Bh9=KJWSk$juA)|6qZK^`8x6K3SL1}^A=G*=*9 zF0dhnK}oW`H`>8DYHas~Xwn$rP10=A1>%LE#|}7Vu#tdQc3g+5lCGtKw{UurT|-W>_$`U#^V^0f5_JN+phcPee8AO*NhH2Rb`VZD9J`%7?a(gZq_`K z0w_pF$<$;#7}rz*mgx~;Vd5})zF`;Y1hOu60PEWq!qSz$Gxsc0*>{OYKmpcF9vC|t zBnn@78%80-(Ld}m`7*h3-v;z{AVTshx>rXu|61!exiqHw`_HO7t2$6wWwT9)GF<(A z;3Bw+zw}+xlKMegmo~_gSCvKJnR?Z%48G;;X$@OQ1+FFZ?49yxZZm75UN=al4#b%v z(#YhP^Z_0{$U&q<>0!q(Wpw^!mzOsS&}+@qjvqY-bYeR(rNqTM5SB$mOwJ$y;^xM> z_3(SS9nwuIdSYMgK{NCP)bf9F;GMY2YeKHS1n7q{Kc|jsc#+KB2e@mC5Fj|6Z6NS0 zn5p9>RC)a3z|NNuAQWBR6#Qd4;Wmuj#R=zUePl4a zsX&r#qi2;XX%x;Vl-iQRx*$4;9w1&-5Q`=pR54kMF#{d-MF&@`fQC4oQWjpWZw?Wt{mX74pVc^y zf}Zf@_f}noZ{;UnPnfr{rE%>sJr>dujU#lBE4W*rlZ6YmZ`F+~>1UnsPko=K;N0%c zSP0_ReiI#(Z6LM`9T_V=+JF|0w30Bi*`VIpdGR|men)0~Hk7d;+Rv4Bi zSFc%wat=h<7(f5t0wP~A`F;VHxH5|7*M^1d6p@lO83d;q3Rl)9cXrR@k7r+Uo%$G3 zY2va95;qGzP22u2Hdklaoe|a-Qb8^&7`ig}?k}?%yh$dbGj+X^7Nw$hMjgtsW3Ac3 zNqGzWC2zQ)!UE1tGWWO>f`u9gl-@J5b zs7uhRB*#9Dwdqf`j*A3m;#f>sT9wOy&Ilg4)Fx;3d@4^sWWNz-J0ajSg%o!VW?$k6 zx{_sccc68^fB$bJv7{ufPX$aPppCsCxDz$~B_AI`ANd(dAPn3maH>ZNL?T+dFQm}^ zexapGYl(x!imt?%*?3?Pbmcyf7%YhT%f2)GuEPUDV_6tDK`r>0H3$Nyw`5u`y`T#q ztfGvoQ{oc9aX5`vRbM6acR)M<5l;?}S#~|-Y-1lQhG+hNKJe2U3|n)D+4qBAp02P4 zn)8got{V99DkW2mCA4_ihYE)B1s!HL0;u%&Eh&4FXx-ph@MUqkgwvIgzlU+JUk-Xw@YdlCCjj|I?GyS~4XhPNRn>Pc;pOay4QV7{^W(f6qmUUy`G z`OcRhiE%(n*S2t2&O0AVh2&^6{xvOq5jW*+WU=TqLkSv%M8{ck(UuuOYdC_H1s3Qd zU5W&(VI%tSun~!&(o#^&y_#_>@US#P1yO<9Z99da{2QI;FtuxAO!1espS-`eqjMdi zanNxE4~)(aJ3;btTs<^W8a{NYJCvdGIR`b6XC#KQuyDLhZz>z(Ma0-NrZXfU9uU=2 zTpo_4^7pgm-8?JhpR{2oYMIIoi{v>1Z>q5ZXtms@sUysnE&)lBsU?>MAFnONY^gRq zS6I22NTU)+t<0j8m8XVu|7GfL)o&Vy$v_;^gr281=zWep!CO-{ha#W>1NSOUOVnea zrod-?ZXz)igN6fvX}YLfQfS+id7brJ4%B-&snj z=qH3-DB1Rh0O`DXO^+3na)7O-gUrjJL&9QV#C!fN;cS^UJ<~SK!Q#8y9K#hqeW*(w z-?Bi#XVu+4XfQ)-`~lOC?<+n~>P965S(=`vxfNaTdh^7AohYa68eT5oH1;a7+Meq| z1ZylSVs{%kRWk?7(HDA$!Q}rtM~=^~BVO0R?5lKc>_Qf3&#W~7&XU`jaf6=z6y(`J zIRredTv0UUX@0np=^B556fmg=(<$L5pTRW+dFK}6qSX<}zs7Y>=4R@R0b{mHZ^7qO zYaiI9mBj4p)PV%j{R|P6{*NJ!Yvz9AL!}Eo*r0881?M|#=KYzB7|lbsjU|Y!MO?K1 zUn_p>FO*M+xcDnnL-F7Q>QnJabs-9B}8||NHLN^0%Mq%Tinv2duO~4h*1O zPwN_J8lkiGKm{%r^rlG!z3u>IBYf?SK)V*;YGh%a3A6G6?YgqXhF0;rDzgC`%-DZD zEcfUC;-Th$UNt{NW`8HG*suTmz~r3>_aUVyJ$+TX7(l0kFJeuL)Dq$h$77j)rT`1+ z?rLkdPph_0^Z}+S#P#9-nkwh@io$;avbMq$px_uN3mj)}jrVRx=VH_nt-c{#X*0yp zxO^6{z`;#uhwX3>!E#UfntkXL11SmTsil&L;F;T;D3~$d>zUGW$JdMGCr+wZ3tgts zG}~7$8pgZ83kAgO86>;PBH#*J!3U;1>)edcbG~nuX~oamBpYD!QC3FgtRoL3Oo|O* zR?>eBfE2~GvEE5iECRW#%ObmJ%@4SX7njqFMMX8NrF|(hEHeKhqJ@tnJ$3x~HZ1Zi zq>VT%b}-B|iM{=pkXv}Lxp}I^^Sh^ee+sRvhbo8iXzM{OXBFr9VcW|GSc?QBaZz*$ zco7jQjEB2iteiznkloQ!amqf)65N|xJ>M}N31GEg9^Hx3 zA;hCZ;JrKNH6n?<#rtoWMJ57r-Mrmb#4pi*&EV(nA0$PtR*BBTD4;L%i*LRW`s5Rx zzvlcswY$;h5e{2hcjh?OXDc{d-&ClKb~l{bnxL4=8Xm-);7_8v zbD>%jMAX)!4oYILg`9vkDA#s+fAWs7|Gj~BrRB*nKVpiFMEpq*CDSpJdHW`f~!Jh326k=5oHy%tGFEE2@ zgqYt_sE*=+?7=hNuVi#gz?&R@@`UxpUp|*od&jW`>H%xIzLIv-{>Ey(NUJVmWCKenB1-{v5P)_Qm3s&h1_w^x-9X|1GxsRp+r1VR`20)4u9a)2 znb*jtcSrU$YHKdGm6cWbHg*FhMSa8Lft|~Du}3OR+Msk;xa2vXBfIs;pFQ&r34Y4L z65ibWc5Z&&KPU)oKH-1v&^OTr#psVOL*pam>e9jm^b8eetbEGfba53gox>8+2)_wz zGfC_+*XnVJ(EcyQ-JX-0vaX~?((NV?c6feMR zb)Ek&hyJ=Nd!X*+p9PP`r`P2imnZ!$(E|TBwBEIzAfTtm9l;)HI)H~4!Dwy7A$a)c zuKJU2gAbYQ^fqQNC)euw#u@$dUvZuRp=Ly!~Awx08e-d_@~{%CTO zlaqsRxRkUszp4pcFgiLD3se6PID*MjvM6KLaC7hN9rSA#^^K1QHqF+r+Y%*k{ev6m zlacXKOIzFDKllX&g>QK|+uYpTyLX~bUaPBi6iw`ZDQQC!OFFLaofEI4<(ut%soPJfI%|^wK z$V>7gvi;qo2S16LeaYR+JYw$BTvDqq7{*ihMm}MA@u+-gNG=POm64g5c%VSHzi-3D z#PoAwP!tNKSvN7UwzZwJ#t4xy(vf*AEG(SzoH8srTo8h%+$nHh+vfDx-`E0uX^~!`lr?B82CPFTuxI6s1+)D{w-+7c~bUa$R)Z9ML)q|t* zhPL3T(MFd_`!~SK+(F5kX|P)1W86ZY;dg$MrD1WW?w%k59)3h!_jqjY@!2Obt%gU< zt#5fcSNHqJ$3;v`=$PT~!J(lKskq^{lIcnbtF z|2kIC3B3$K9&5s1?3@`(0Xb-2JzS75Zn0 zhN2MMNx!HyHG@v^>gh+Z_IG+kqXx#tDZnIfggQs-+;~q9*VC)B(fpdQHV*ixd3fTt z=i98N5b?}=*!3ANvWtM#Y7S;dy%iMnt>V5JL97Q5#A~Z%q*qg$dr{k6w!F^@=|ru* zH-Wn6lTpFQKrn(9w4;tI#-u#T@tlIYg980Yvfi2Jd<-a%$=T@Q951 zQ(SuL95L0^eJT1WVUdv^Tas*2ZXI&dr<>hF6#-qP0q3#QueyAk$Oj(Av#2mi4>N*@ z$rjbKxH@bR^(6nAe2R%is74B6fdoJQ0w{1!<$m|cJtrd3 z^fCOrdO|Q(j8;bqZBU7Z@|J$gJ{vJEH7{ey5D*l64IQG*tv)e=L^(W&N)`kT?K_q7 z{~oE6qZ0v>Ys+RP+uZKI-%{d9aEUPikk$)P63On^7cu!O|3 z$4l|^pLx&yF^BWgOH1Xji|@|ZR%K>oX$`an8&BkWl$P3l`SRtXe{hR23$*di=KW^_ z-;&I|Ufld3AhkeX1wqVZqf7nW8H1OV9Q=J?c~9!9RDSZQ?pam9KYQw9ly!`vu1TXD z92n!S?4EOvH5=zaHOfSQrUI%4OOax8(o?LEu!aV(py8wK2kYYw+I`SpOG{*Rswb3B zpL($GE?SPSmsxGUhV)wrhvs^4b`4iOZy!@T$2WCNlc1Qj9U01ZT7mro< zn~v*kou%u~-jVyK(k@Wvq6o;Jmww9u$oIW|s7f{V(IZK`Uums(^AI8kBcfkfFtY9< znLQM<{zMd(m|Ifv?W{XSvCy6Y(Fw(zBd&bX^xro*9$FjRcGe_NVJzRa&GB z3`q2`w{!Sf!EitE&p=6Pw7e&_sBVwBkYA1RV5r|c;#2mLrFjJ|FK#hDY4z{|4B+@x z|L3pYcE?o^TLQA` z7xHFZ@4VYFjYtG-VqubJZ7mNMsn=3Th>(1jD3xdipWFdk2d4Z#W_JiKI<-D((m^X?JNf%$>tv;X z%!TB?9u^j;Tj&}BpJD?3xxhYp_E1+P{ynwC*1a+d<*NZpsj7;(8n6m2#M6U~9Qk0(Q;^I>VSsMT6fKYyDkI89!*-}tXJ0n()+nmN#Z~6qY z{GVy7=1?`q(GI!A*Ac{)ua1eFD4OCs7qr?A)~k;iQE8p*2#^of(@RnjBcQKB*NNg) zAb2DsB*dJyLHx*=l5%o_N{$@u?d=M*;pSzOw-0&ojV9wyH22y&t3NuS61n2e8onA;cB4OZhcBf z6sy?-0O4p^&)Ats+ zf}Mc2T8$pWJK5@0A*^anafk9bNyRDNQ&UssWkY7b--{;j#8vDrS}efj87@0u<$Hx9 zQ5@^Wj~+exy}X{g&dSQlfWe-TH@<&wgwoe{;(VLPB=CMb_~>f$ zATZkbF;6#@6bQNWF{~H-4!I{5M};Se=uGf&TU|+vxhS&b9tE0zz8tZ|ug`5)+Crh1 zbMG`b@{!c-=^_a|5UG@P}l zbiJiODqwg(nKvu~Vzcowv!$GtK*f`xM_Dk~wmsLZY0k7L1vaqRiGzjl<4`k~z}+6+ z(7iqDq@<)*F;~f?hh$_DQ@{H}BVT#^`0=u%qvQA58k*f|ddq^Pl(edtgCfED`ubY| zq0e7qvzPx1-L8zw%kO%R*wwV;QN1x)EUgiF%=Wg&E?r+_-z@b2`{DYze#UBGWt= zoETMcSsm|(auhq0aFP#0wSfPw1|L+f^>(VAd-U8ozmScrP9(3 zf`oKQcPovQbc1w<#5Z`a_x<>b=i!{g@9daav(}ou#nIb?$*G%gpU7F`zJLGT{c_@e zI|TRd4tYkbw+)@uG0hhk^Ij@%DbH352(|bu-(RxeP#9+~5}H#*jmp{%TPWlPYGbY` ziE&Q0p-CbiB8hoVC{Y%Y9`l77sZEK~p>cP(E`^J#gvN)yyfD90nkSCup{%XF--HmiCE9H>cGFbfhs6~> z5|4?4-jZCCjJe(Gc)FsC7r#wHv-Ht(&$IQo=~d$oY%;`rB;26yYuTCa?wT*OQI)vM zNdrpuHd8I%JuB%gGG2V)?0hDSTQR?rHGN-4fYn7=qPyP=YJpcSJB9)DN@t}H4ivIHj#-NvO13dB&4*9Y0 zi;|r@Gd>hf^KbX(70hXvLv8!-Xf?IG%8+|{s}-M=5<(VRX}4BH^IG|Xlv@>q*YDI@ zMWmGu!ui^`kd@=ZwYDAkO3TW2dImo8?d`MT6XMStU@wKa7%~D-h-Edj?k-Cf%$uK} zz%hev*v?)YIm6U>Tb}Ife1j1&%CPWwF?)Lsg`C$pH~+I`2p3HBj#K_wCoD0a!`jFv zwAF4Sp7Gu!0^*<(oe$^7?dT}kCWaavzC`1jo%h10cd8qPQR6(TJ>%a_64V(P1b8i9 zzmLDv*ql@I4UdmGUEpGF{=nJD)O4ZO87TqcTcxHi1gU6DYu|JIy1@f?exWxyKx9P z>DTZde?!|-REB>sz29RDLICtYsd%IkRN!@B0|8V~MXx_TAY2rUJsG}qG-<5Y0 z?n9T{j)5>!!bO|B&Z^!QjHI_4{_N`7#)kfKaN^ml$0g-SJZDJOvd=%e81^yO-&t(Y5AU9wFyl+@e9Pn$ zPWB=Hv=O5Q6Q3m7exTEv4{oM!+%y(~*HH5bbBuYB!}&}(3?kZ0mN>GcN+;Ubds20s zFN0A_7`R0s6+iSiQolGI)x{?wn6>0;nw0A}Ftk?Edvzc8<1BCv653A?WzNpGOwTNl zIpQBpJo=BM#&n57qi~#AYfzpw|7TWv0@3l5^@=`5miEonbD?k{c)MSZBwaztN5ll* zmu#b{0c+TMsyC)u5XYj5_6H;cP8X8++=gaFPx2E(r0EY$V^f(j%_Bx zeSY2A1~=>LSB@#w3ks&%Z6umj8b?0V-V*Km%*yd@01SO;Y#xhn78l45H+Y=2F8G6oQ9Zh|DcMpGpw5n_8R_#JCs97E*Q)#TzOc zjIW;}Fyj>ByhCK9N+}%H#cx z2{xHFvw_5!xmJ~G5m8aa#zPOLlutR!p8EIldW^EB}){gBGXrEKK!pwNH% z>=^_d3CXTLr$_%oI>LXE4t7@z+?g3w2v;VY5iKK(dksM1!NE>JRJtx&nM@mZyY)Wf zEbcr(sP}VBW;puup&|E1DJf+rS_={>f?{aA4KgKixL3C4*m0=N2dh~fj*|CmB)+sy z1=VF(w5s<>YWT?VBC|@kcM8$zpPt8$LDN-{1H(PgS`}k3L5sSL-NWo$Uvw zR>_zp7ugeZBjtyLSG1Ij3>`IV_)BHwbVI$+hy+PnTQ-dlwDNKC0neEB`P9nn_kMn; zIyySHdF^v)P5!sQYIfgQI^6j)S;*8Od_bsCEIhgNz12|LfPMWQDZT=)=VHUg43o!@ z7-h)reK^lQ?KZ)uCDb;qwjH#K1~}}LA@3sKQNxJmWJ7>fDRa>@k7x2c#*wH z3DR^$kbm3SaLLJoI`uw%{YscQI95O*X~3FIPY+}ktMMzsRpQn3&!58+5+qI4)^~&= znl~E^)-v+Sg1#Pd#F50mF@2NrH9z?9E62pt;Zof#>%|9oiyIWe)gv^k@0TcGx@((DAc9&X7vzSxNgHGuGE6yt+~B2sqj zG&D5ujYH=?-F?8okj-x&2<6@2CXK9ldAv6o_V%s>(=7smR)RgjO!ohkcE}wI2hJl% zivHFA49uz^oitGKC)6Hnj8oUt(5`LqUwUaHQJ}i}%%0Z5!3$kFjPu1e**FS+zL_`Q zTvDHE#p}q*C2!#LlwGvSM@&L$LsLkS<_S=0d9CJ)BJr3PFD0iWoZV!&a3xZ4OjYUj zrafvTF-i|S_u?GVgEjDi9OFv7~fb@lENDQYOcGN5k$uA zswYJ2c7jJt-1)<3@c079qhZlzNvn)xJ^8<#9wwAq!nfUktclih!{MJ&a=?S|p`-x| z)9zjS^@{*8#MXvJ*z+=<8(i;v_fRHMXX|efCe-10VTZ-S+yZw*VLivP8R0s(Z=|}I^d24-byDVDPIM3;jwOzfj0^s+kRFg({ENg{(eL#=#iQI~*6?uI$ra+M zOOdg77so4~cszV(3R5(GKiDeJDEW-U*yKp=xi;DSaVXAe#`v+PmC(IHfLK;B}#= zPp=uRu09nb6?`v6i>Iut43$q&d12`0X1Iq&T(<#il&j*S-edcc*c)RGTvQEZ90ujB*V9fR6X~0q{zl87upc` z8U*fO$DDT_V3qc_wY$R2V^SnWjT;u%zT{@j0KUZI{b~m35^~fNdJe|m0LHp^%)0GK zJKQ9{NJndo@ZeFCD|_`=!V<%q6*p_VH76Y?>FMd8V6j2riyQv&>U+{>)8lW_rxY-8 z@tRJWb7Em(y?U*{VmLM7*<|)#*0p}|ciP0#Za*V6Gc_o=6lQ%)sDwQ#+^6JG;rU_) z6;pBR^~+}uvekMPMa(~hqhOT8JcFD&cauW8));GB>PHo(rfkl`Ygo>ncO)< zte&VOqdoRZ%ptY|-s98P2Ou|HUR)fRj#sh2d6GDLhleLlJUr9#;$%5_hnwQ;{8H}K zE1&NNWBqo9QZWsaM-$EJ(-i?79UT{?&MFTHF$OcFbenw8p)}|l8X|~TbL69V5KIB5 zzgYI{ueP+bTwCP%?>kX@{#)KQzvdXr)gjm@{mmrVT0W3}2gt)gW-TPkR4XHz$S!@x zF+H^E97MymE=+@MW=i>IkvoX!4VW|Pces>;@VIxRbmEaD+lY=?`-G68t3zsn?H*ks z76(O$zo5XGhik<}bGWqAM~_0Khk6EZ4LZ*!DBJ_}UtzSQ%FCXA) z7j0XVPulNJZam$VdPdsL1vV1_BqcLW;^!?y!`37}uzeV{crCFX zCwUIvA(WRyrvWvqf_3@gnM{3oVU+Fo=3r{IR&?ITiHMXAtdU_m- z@?!jM`fAf+I?%;GLZv*V(1`igO0dD`|y}>0IQ12~h^rK82i2R|5 zH8O7$mJj^V?xWUSODB$W&Pw&`-E+bf$9!Ug{N3k0y<}e^<>YIRJ>B1DY5y{`+3ymuEg(6;}*KVN}-!o6T8~m8x3cBlscr?ebO0J z%);>vx@$GkZ6G6zjEL##QooLj1eA`8M=s?o+9o~%w}_gmkr`zhy?XunrMfzKgt&=D zK{O0kL(6E<{BtP@@@Ds)NP%9Oo6tK>Q+_U zU&%{dy9H_jlt(kMkAX_>drs{#s_W`W5EH`GWq-e;+wBX=G)c>tP?S|A8jdf%oD9EB ztOO?W6LU+)Hx?GlpNTZ|T3xpO)NnnaKz}x7FfOZ zhK42EUwyk`Iky}`zZsMixr{Kv7NX}cn|SV^7_BX|_G%p4cAx;Y)N!Rn=-u-aj;Ia23)6^)HdF0%NlLq&c zyA`$MBgdTw`G_Bpco(jVy-D>w>7pCBZ^hXJQyo_C#M&!x&IV-rthwQHh*1-^d)-QT z!=A?R@o|p(VPY$rn*#3DoqBV>O!8;jm|VRkYWNz6@*j+r_%A2B1b4@C9Jr7#X0G9d zkmocmT8AZtJ$dosg%AVjBSH+IF|K4_IkmG`aV_M}usP!M;&XFN+X9KbY3^>b2mQCY zsbl^|{X}#;IMiJ(YQP|(;RTYjSGSLWnTE%x*WDTE1})wgEYe4%mdKo#W3OG_-?OGz zhDLhZn?ka5STX1|5-Y>X!!z*~+YC<|R#6J4_6xJv;J3D(ySrBlWw)VDi3MwR}*(wO#-Q6Iuh=ve1 zXXUv(+^pH)v!fT+ct2XLjXBsZH!WIY9+}0HzJXSl zX!rqgFp?s|PTQhJjcW_satw!sKfQTt0o6aL>L*VWqjJ-?qbc4rJLkE1`)cmx2^(TT z_nO&Pc|ASSK>9WxnvF|WobQdOe=i%+lz|`(k6K*JGUYmtrI4>g9I^UZU0wZ^!YlY9 z-B~Zwo=Zrus!hIOi7iy2&dSSM+)ka@5IlhJSzdaRl(ZRAXc>}KXvz3S>DR9V6BCk? zba*4ckza|}&z@b?@+B720`?wf%q|!h+=U*3{@CQ7YHAXo%?j2Lmx_k8t_bo07M87@ zy-xYKRrMrjK%R;p{wimImW!uEmVY+Ot%ktZ@rocKN3Ys-P|h)HOK z2t>b`>}KbzD3)*J&*V~_mOP-91abimM&Dy__eJ*Kc`|}{1pboKw-a}cDZ=%ShnWOK zgu=_nxQ6-3NKHW=2NZ8*ybd^~MC!hT9qsRaI3_w1yryyEq>&)nD=&Cfjg? zg|B0d@ z-4!f^i2z;(g6pEbJ_1Bn)YAMxJ(gQUL}D5m6wF1;3kwTyFPKy9LWONM5JF?a0n3x!9t6x zF*{V4Vo5t`p>yVl;NHupJJjw^xfkKOGp?Wk+glBnXtqf8UP8s{=S$Z#&~!Zgw|y@$ z;rce2V|3=0ZMb5RFzuERwI>t8K9%@R<&&%Gn;;eAuqxfnzChVe03X+NY$o0d6 zgO`Wmp^NfYh|)(K5Aaa_hm`aKG8w5}M!{)nJdnxW)Yk zEG!?3=G&O92JT%|T*emuIFtqlXj?X$PIX55xB{?tVGajj6Dk|g`(sngZKryZ3E0L| zRaLnsjzgxJoOE+NH*QRNJAVZ0Gb}#(`b7_XdEoZnZ{lPy`0-9AEgs(8@&Caonpr;6MJ_msj89s17m>( zCRA|@DBsp8#Adp2%#?yOeXUs5rwl=(l~a4|<(H(%I2 z(Y$|d30^UxzlY7Z$gthd5AVe9#I5@g zcskOV;YmqJ^SvSD^Il#c^CB;BcdZq=4y}LefXfWK3b&4v1|=R zEI~M})LkI9ppw5;cDH|ir*Cl3yOs%m{-Jl59#7refGGz!8&i7^o^-(902Nrs$kg}h ze^q)1#4-!Zz}7T-b8BY7=X}=KP$QOG#KfydYd3a^jt=?<#{-rzho8lF89IZicW(stK};65S*77+X|uazax;9uH8ex!R;eyAu)FJM2l%A)7h?1GUwWJu3euf z@{asI-Ry>HVbGbKcQS(vnBb#)UFt7Ot~bztSx|m-Y(^XY-pDXnN=N4|0wqK=Uld;| zO);bL@v-wAM)%(h7AI@d6m;zD2N7jp*a{@ND88NxJw4Ql->dav=(XuYVq!$Ub0xhBp#g(h#m0Bdr8cIC z=l0UrFJHcNr~8S81~BThif2moYXTOj0Hy=)xj~tVxJ0kkM1|Eo8X9K(U-*m(%*X*_ zft{uT6f+;Ucbse4*g1*}4vZD@9Sf$Hzjt)$&6<^40k_&L;Hg(WPS0cQGotB|n6{|j zhIWRLGxRMmfN?45@{G{R3emNQSNP!YuvquE{gg^g%rF2O0RbACNK%Vaq!A4VazOdl z$^S%bpWuJTyW^Yj}G*Z>- zSdh&-Mj2Lm^Mc3j*b{RG-8IBepw39Kap~H{Mdy}>7({7-CEcVM^t#?7|NZ$vN}$CS zEP9q#`qO63^+!9W6J*@f$;ZaV=+r4!0F}S75S-;G8S6UUF}y`eBqk$+gW_^1t0IT{ zB}zsMCQDVefyw=lmEv-Ix=>U!sgw~SW?*1o=(RG07ZMUq=Vc=m#~%aE^YtSxOpMHF z1qGAKqZt?H6DeoytI^C-2IqHVRaL)(7X;&qX=gR;oeM5-k0fR_fP6^0dH6O1d}jgeGyoJCRNn!mdQ$a>!<6X&;3ualYY1|UN&FKY(*@kl`zypKg+QNBdh9bppmW_qo2KLD z=Dx0uZDwDcNC5QtQTwH+lvFpdo4O85>}ZK0&d|`%#P1CYv{Z>dNwlx%KXUA!#z9;X zT1mJHjAU4=d8wX@lq--ammQxB#X#qnJeY`SF@iOIEKs{ERNd=(s1yf?7G7BUHyggh zE6wO=k;+moED0>49L~qPa!>{qD^l>W4R%RQJiYtAamykUDEnNcx&()5_xR1tO<+pb zE7TYV1_omuTg{1!pj?GBZrd0;lS^jl$JEr`<8`jQ#IdntJdUAdCc}R0PnWGLfdFp7 z)t&_p3-_uXIxt|b^$Ety&C-sNGrUns==__XIIEDzXGmk69*BN|a2Qp)haJMdd)%~l<(k5@-SWd@Ev|HT`%ZZ1c=6D7UwwENtzoN6_| zbOE?Aq}_&(Z1l%yi`V&Yq&OL9Go-9C@lk=rwEqvX2>pOr{_3X{PyeVh(yybD)B@@I_c@#GoMCAM-GnOo?!L{sZCE` z{}z<8>XGO7|9SyjKX%s_kD1o&Hw8pQMa)=oNvi-GD{lHOBLytczl=?k&z5v}czA@Z zyTibMx;3y z>9oKMr3LUe7q!3dGd&`=F5vXCcHskK17fW3@Zezcz-Ng!+}>sG&69PtE>Nl~)(iFk z5e@DV#9uG2V9`C-zwXm(#ah~T@syiz=d)F^g>VW{ruEVr^Rb^da4LVF@gFnEqKefs zU?pW0Ia*c%8l%USjBB*pT&*Gy=NoDU(ptj`{o@pSq%=?PYlOyP5S3evhq{|eD{5LW z!82=5#L!3$2>{=F1m@dgiOv3g~EPe1k{@ z^hW3yf>BjmUHLTY=CL>HmIW&ohdt(ZxufxJX{Y9Y-DG`27~c650-ZsCF9uW1OuAR@ zuV2PrEyiD%n5=moIkSLZAmBnN{{DS}M@9UuQ?u?Jf9VU$|5E$`^xs04qfOSNjDzf$nA?oC>n!FMb3|xaynn)1Vc*k#+62Ok zk?<-4sta#_j=k&U;>Dc0VvNA$Rgd5wC^1=a!s}s(!`MoqL~;!_V=bPA;qCV4}c!AL;51$0=pzFip*3Pov#d{)6$0r3I%|bA%1Ox=2*+xcdIEMLCoFSWx1^3Xl@ADo3W9swDjF0N=SF3TANMnwd{ z=Q?*71(HbXE$0zz|CsD>HU1@F0%a9)LGNP;d*9Zo+;A>rT3AhTr`=Oi=#DBD==F4G zK2t)6J6P7@_jU{~x}dQHZCk*Ov(C;Zbu4&E9)%C}wrLgIZ|_Zp`Ap1P7;0fs4%3v1 ztmlZ)H}5ksz;ZigH8};^*lLH)T^L#>DkkfMq6b%3j-I~r03E0CjG+KvU46%KNgEyk z0gBKoTQ~DM+RBDWNftFgA&*MAX8RVSC5srZ~|_+DmAk;T@ZVWxpl4ia@Ip>Te;e`?-V9_!^QiPL z`?u8>l9GBo36((gV+$GnDS2oA8l$cs5!5wF8juiW%*M+Rn7!h9zK>AvEyS^0X}NO~ z$I5ed2lWRC;rC=%5?8&*Z=#%$9W&n4mgSZGg6RE-U!#U>e)QdS%*@HkL8F@e z{r!OZgrO%$#@Rzh4p+WcARgQS3Huj*r>N_Pcyxx9YK&E8lgPVEE33PXd{DE#%TxUd zkcA|H3?8yX|t{OVT<`QUJCTt-Ahq_4oPv?ig}(w)Jz|8S8}&o>{U!& zu_C%9VR2C}TwTvR523y+RLOIvvxCZj*|{qwd}`T}XZzy&!WRgtadB}?xW`Zdfh+~& z7(o1hCVzLRy{s3uwFzOQ=q?U9zdXp<-#G=uhvs-uxqP4DQR}L$Uo|=L9gs6#GbrxP z?e&(-Hsb)BkL@5Kq5x(eF>LZ1on_!l{lj#L1^X;Gr$)s^wM8mwfXXoEnNU!e5;`z| z>+IrxVSK=9mz&`SUg!Rw1D6G6^LV&ihNrd}((xP!iGO??KFNOzrv!97PD|uH~z*Y+eq z@UuMbqmmlp@l8sifaTTxovE&6Er8I?;6a=aV0Ez&g+9)=&DhPaK~ds6Sda%lvjWv3 zYab|%Q*VWXDX_F`*AeKM7!1J>(`-Gb367WWOzBy0`lBwm0)M?eRu*6N^Cu$rv}{B@ zcQOc4XnMXDU?@~ncN_XQZ?SOQ|Hrp^SE+ED*Imr~4tnlt0}e5de3>aUMxYehrTJ4p z;Vxk2oaWpB zJ#k>o49}FDt#{vcGp{_jGU;H31Ox>w*6j5P&VJ>0x$(x_+yIL1tGM$f8FtLGg1Q&4 z^%o7N5FjH%+_Twkcmn+u4g>QgB_;1aeBhb=3WfW(7vE7!dj}V-Dzr}mSmX+1t5;@!-%KOOhALa<|xCuCe;{g0P}`E*4!O(LFd3vh)8uWaw;9e z=G#MT`kyt6xx2ehSk4E%Vf$9o(b?UdT2Y}Cmh!P=b$wm$(l8mi^K@+vL21I+c%ZXiC(dUv46KW=k$An3pl)m)z(eJB*5u$2$9X(Kn2sVzda*g6EfC zbMoT6G!)Z}-$W!gG zk)enbpukKLbXDFK%P~y(rWAg`cugkY*g-?*3HD@GIv2*-*;&PeDxS|nPZ{N$J`DcI;8n8Hlx1D=Wc|3D} z#>I2o(&6(>)@_o)p{nNcLSMnX<=OQ&PgnbPHhM1yQ%R3e5&9c6Jx%Z>YO57!l^Xu0mi z0A>B1*7r4tf{tH30gtu1kmW-75g4xysZtq1um9O(%3*VtDWv}5q}O!%Yj=Ka){rsG zGtdYX)zxWx+YQal$TBiAFwHyL+ZFp3=H}*a*hro=VGPS=zw+_%+YUE$ZyT+sxW%1W zn0zLmIeNTV4ga)C58=5{>$7JG{4P-(ynGH^9-Cy<_M7QxwYn|6{J4C4d=+-*&J%VD z0-6*;7ul{iFmB*yFFpjQn(SH}d&)CTdGz`LL4QB9WHPgeSI<8KZ%H;>8~F;BILwFD z>vyzqTYGL4i!b+A3S76Xwdl90W-v#7U^Wa2eOtb)Mxqu?T6Tgi8SXBt_wS{RfABTp zA%Oc#yNPW(NXN4t5eJzU-&7PiH^rlSj^KFSLfx`Y9Fp&@wN3W@f>0xo<}1)%y;RgT^M`^h`s`{q0-3GK&mjEC{IHv&8{bgaIh| zH-nXnZHX@sqYF6rV;$Zm%(oM4nPq_|;QObw0$s`d+b-og4wc;8HOK8lqnBfb_8TI3 z3gHnEPg_=A-n(}%WpMR6Hn#SUm3~JjC&a$d(dSOe^adrd!%+%=FthTqXXjc2_74uQ zR4pDv-VhWNOuB5QjN!5S6+P^HW5jlS<>gzEx5Rk-e$bQaQa;~@P0rWR8ZczfUEcpD zy{am1B7v-Uxwk|Dr@6Da*}H7be36N%*5`>}g9#PG!qS4}*(fthhLpT5ZYFgOC{aH; zs-v6dt^*U~{v{>bb1Mzf)B&^T889>c$eJbahN<&rW$;?lfLisBm|i?$rCW?|r;) z7>L7VY#*tIvWF8JX&cO z0)ik>Z_%_TIYXc1vSo9I-u(C_(I^zq`nFTANvB9_b*)*CW6+QTI$x!qwQ>iO^EbVp z;Jbl=VPs*Um@ZSMA_X9!-g#3wLo)U*RbI}!My;7XFYg+P!v`UJr->3?Ppm4ze|oiA zT7L!DugwbU(@@r2)=8k2y?Q`^h=};G#{8D5;H0o(G=a-tfl$GSyxJ>C@t4eav{J9K zB-#(b8rwhdBmH?E$WsPg9b`pD!GC5;I1nG*_@97A#W?RzDL6|v@hz{k&wA0jWF`6Q zeskE0B%;9#fz~Zc3`I;6<-)@7M80+#koMB-!lGsBj(5c_-rXRu*hVEZ`KXBAzze?D zTco6Y2sjAgXacq*gW%~Um05{_eVk{O2SmR}h7tY4du$P{64AxhLk}Q~_^XMf^*`oe z`FK@iI!w98LpVA;JsmC6MT4Qe!^#@&w72|HLB%+FE48|scg>hMPC1ZSZ{BGpHJNKuFJ@0*9Z|toCA?|F|mxv39+jr+R$0sMu>~0TiN=k^6qeLB* zZchmaz(!K$A6v|ME9dp(NgxS--1~6afx$@;H#dH<5DM+BO@92bn?DEMusv;W*SXp(r4WGJ#ctLq_h^7NLchgxH20jw*1buR$B|FsfvNM&S<9HQbKg z6R=G0F;l7%4ZlFqNWc7@*xN^EqK?DIwXLmEnrm=yQ)cei+1Z&3)L_6q%~itd#`7B+ z-JhNXC{-HMG*VGYPPmUGCVUfYT|FDzC&7fy|03OSd+4s}Na73`7?1-w@r%&W zu#JNQ9c=!C@@c=2g00UXM1=TP_T!#JLBTn^cvS1N73Q8t++tv*BMEAo+6c@7q^dDq z=p}-NJ&@YBkj?Nu_`P=HTNJ&XIB`?chg7MljxH{mgexV!DtT?q>}jCO=kQwzM23 zm!zlr@K@UdqC+$`G0Dr%?tgPTI;MjfF1%zl?1=~+UKSP+LBD}bv8yLU6B8&3`5TZ0 z+2K|3bk%dR(u@E4O@r|`PI?}EQ2u|KH*&cP*eehGAk<|l8`8x zM&&ZaXRcED5jMm#<1eos0PkD5b@AKjs*Yk}Xopk|fnTS+&3f=#WNyVQsxhO+y~|g1 zcbCcD!JCb{Zr7c3P(KxYrhdb+w6t{l!ez_mY}Cpb%kS2z{$nWK?lV5PtNW9!saah& zF}G~WeeIFG>A19w&0ZnuN?Thiv&V&NhGEYgX8QNr+uOI$`Had`goTB#qoZGaHds)V zD&9~*kJ|is&{qF|_2O!RN?ugN&V1$3#czO9G(?Mnnf-4nXc+<)IdcowNQ6qp0vokb zpcNS-lIZ>;dMYN)=wH8nX>%t(DacHjc}Q7zDKLFDT<*6>*7JagGvwn(op^7N7gyFI z@Kk}R3=e;Sr#GY?k|q4-Tc9!Tj~d^iKIm?*Z-6DH@O0GTHPM?h9DjU@Ld7E4Bzy;%NggT6qBOTU^+i70^Q_GGg+@5xVpM3 zRhbfx=;?=XSRnyr2B43@ozVnhB{QQHS&^=;_zQ6=ZthtA>Z8I-Xzp5BIhK=^${AwO zo_lIuJ#SyU+}+&XZbzYOc7@0TKiuV~MxOSFPcUR^>!mXp8X2ov^D);2bVUx$9(cu#A?sazuOWU4?XwRjKD|YXp z{DTn>`p*{V1S^r>l{irUGtJlAKM6lWLSNTs8p7O`wr0PHwSFy5EQOmUW<_(>fm|sZ z?LkHi*IZ1;(`aR{>o+AI6YE)eBL9%Lm<$s3JP|^WMYToLjN}|ZN^NlPOh(epV@Q7S zpm&EXsbc9>WPXn{HW^n3Ko#3gjQGRH;8<22$)D(Qso1B?v=1K1(l0LW!&AHl>8|6i&V=OhbwO$vY z!*ubSd%c`fDW7U4QZq{rNHFhZrb7>l>Bwty>PDTSJ}@(EC3_@IB&cCFKVIw_91Iti zr!6^+V$W5njSDm)zJ`j*(_$>ZyM?ZWmDU;4 zz0Ms3a4>)5DS3jCGXz4|X_s49yr5=STu+xyk!4X;oM7$oU2t$>`ro4& zzN!p`9UmWq;wu3iyI}3+7-ET)Jl9?uRRW(vq*0$&se|qIFNT89`1qWT^M;y}J>?ob z^fb{RxfI?%6HY}YU3snSpHzBN^E-~<-FGw80!nH;T5bj9 zC8%`UySt}9Q=+4ziHdaF=a#o*3R0uN=FF&|nVz4Y6dHQd0Fok1hh3Q+8z)1&5*8+= z-s%2ou1d*Lu@M>MCev|HB`z-3TPk4l!itg;It;S+byoHSf#QGTkJ;pCv9qFT>)bF$hDKdhGW$N#fybz;Q-t12e9-lwOxIu0e=m+{>>!nvcZhLlE4y)oHSxVo|N834+%`#I^awY-E^ zZ)jjbU%kSYh-R7}K3Izl9R!-hO<1 zn4H0yD7Y&IU~2*^@wtNoC!KV{Ok(-;R|f`0sz;B4#On6$&*QdZ{krQ8hb%E&?1X?M zf{h{*E8=EU1w4^76#|&TMeRRa6wTUU5rkCi{Yc0-VO$>+Az2 zY@bHf(Ac#_Kg-Rot$mMKVTPtc%e^nJbJc3&79#N3NU&f7gNR>j_nq+K=%_xks_JLz z2>AtFq>7ZVFduyS2G|6ked5Q+(9SOg($R8@;9KI#o-rd(}>yjKd;YJ8(ZSut+I^IjZc-q}c62G=;%VS=%N^78Q z6C~m1==+C)JXSjyI#IayPjGHY3DhMMoD(|}yr6VOb>uv`d#X5fZhVhN{yEFO)SK9qM=W<2 z#1A(n+ry~EV1?@r#j*2UEZ~e)yWjvvwQzP~1Mlevw_T%F!y7g*-21=y3?uuo-sy;pp+u7LY0+~Hwy`~bCr!;GwgXC+{@$K6uI9Dd4jTVGY)1(Jr z1n&6WomTaQL{oD*$NGx`Y*o@}C!&%dO^IX0VFOx5}9nmY>ZSb>+hzabB zA~XJ>jq}%kx!5uMlSOZTWY3+|6)<2>EpSaib-X!xE#aylwZ3_*Ib-;^Z@88=&hbMg zxci#&h?^Jnz%ozd6z1>v?(T>Dnq4`>@R*jZ6Mp)1%rz%62!0qRnY$a4euINfD@v8l z1dsuU2U>h*LT^G9(YI`F+I;+j4Hy<-#}-8y5;&V> zt_+KG^sBz-Z*8=Ut$z8}ub*|d2DDVosHDXO5M7me`}_O%736b)Wq(F3OYa(hr+z)6GiE|DnsU=jo0`ubFvL>RjM#l?kW5|3|@ zl@)jpnDvc$pu7H+p4}!LrAOB;slv^hH)pKn%Yc3AOo;7_9n7TXG8qquhiwV$Q=!>+ zh2h-VXK)iy=GP3rjq$Gx3R`ixxlaUf{^i<;|I35gk&l}k<1)v3-K$orb{mTtLOg$4 zB@w)%ouRoyuGHyi@*Dbk#FG}BlG<@bsw}far8vfF+FhU-cU`-;(5LKGR>!^Y`aOq_ z;tDl&X(u|qgUX~#yXqSglasNJweL>#28DBeq<%FT5)k(0=WUEsI_u+E>>hwej9hNgV|jkQd9=bYer;6M?ll33g^WZ$ zSZ-rp!ARY4j%RD4K(Yi`2($nj8XX#C>By59%splUJy1)Zi8M={z7T@;{JU~zDL%g{ z!*;`tYZodcAW|1+F3vyv7&I>H(tMl@ zZ0WOK{}TQkYHJ&h{w)r*BcGt+Y$N>in%YZ6QgFMdM?{jr{!HLVcE4nEo72(TV;kqR zaN})I+6yY*5vN4TJ>9pm_K{Kuh_3OF$}BVqs2+Jj5`;q;@%iq(dp?&J zCzndKr`>PZL;7*9^#Ri7VW~ZfI zIA5C@&(T(1ZXbP928@2yK~I0R#2&WM1Xu50Qm5VR?CN@zdy%AG{l?hzRc;dXdve|= zfcl~gk2kW*%cBA8LjEwtb{mtod(95+q0cWnjyN;X*{^k_+lKhXqUg(Mj|Me*(WRWno*x86@$GP-CK?4Ttr3u2;v zo%Nh1vVNQB>R8jcUrr;gKFOJf7){vp>_?rnTL=>=ks zV0Jo)DgbYuDL8R|fPDyLFqi8};U_yvw{>PhMm4TVkQ=D~Z>?uTS<_Pm#lx0C>9k*A71X zuwkR0mlv0QX&~hQW}|q)i(@&*3F6nU)uE?G zHg&wI#ymURqdSz_h8&{(Ym}Ltvt0J-Am7wo!1yNigx?i&3yoig0uTo?wBp4M4)_+q zZj$!-v+tv1*Kez5uD~FI+ViGN1)}SNNH}3s8axEuoRqGi76RLMrq6rQT#tA|ta}q3 zu8hk(>wH*JpXE{&xW~zVMT47JZn{s%EQkg1nwacMjhp{v2oHp&L*rNrOA_hR3fKiRb=HZG1N6Z27dS((-0y7E=+l+6jN z0ys^Yh=+eNTs}$9u3*=DcvK|&faSF z1(_5qTD2!GJ~Tuo9c|-Cn&*xxj(Ca-3s@MP=G`3#7jLi6y@N4#|0Z+dBjXrfuH4R3 zvt4|Y3HKsA>W+w1u2hs)6U`X{{LsaJH0fWET=4q;n7YbF@%51zdF^OAv66%?~&N0U)4$1dk z?FD*h`5JOYFRt5$oIv*=#-L$xrYkFZ6G#x{?D3L@r%K@SaFG0=*gNBA!wx)S%kPxZ z`51G83}snaDd{kCDYIi~G+%G9P~uQ183}9a=-h={{2n*=;fo6*Rt6u$xYyeo$fct) zRRg@UtgLsdf!x;wYG4HK^4wDm&rpNT7|2CV>tmJQuS%)EL4I0FK$s58ErJX#>sn+V zAK(8T_xDZpOS*{F1nKG~yEN>)XaDUm=PU3!%{!u|bZX-zD|XEV3MX<(o_jhfX5QxY zjIZ0+RjkMzLy;7ol1Hc2&CbD6ycu6VI1c|#X(n^3*rJUwLB5vH)V(l`<%)v6hYc9o zU^!tL0UzgQ#VqCUs3?;?OJE)_urcd9I@Vqg<9WEdcbi@8(S`pVOx}1^NXqI?MW(7F zd;)MrfoX2C;4E-nk^_O0#c|vl;XJNxl?@Uh5wN4h2`NAMv-$uCyh0$Bp>viim;mpE zG^j<%KYWO=adJ}rntEgZ#w~)U!+scneVI8KjXEW~K5Fp!&Q5y!I{Z*C2pGAJnOph! zA7*2;YS&szON%C$RNPFBq&bYN@JIvFRc6V%DCy~=(^+$i$9eA=@<%^<#N#sU*FpIW zMn%E%MQUgqLyL=xd;RQyhG^~TqFXq$jWy3uVDRzrDOo>WF^suHIZHCRn+v@zkGNm` zGfICtmmXM>67jkj$+&#noxm9_U$0jRos7RV;?6t^k$IC%=?w~Z$l79SrHQpLVhwsG zN%j6QhN(wxPEH8GSj;bN@lY@^unjv$Edc*JX$$(L-8?oH-|&^jO3mdFZ#>Q-Xz-m| z@tW?@Y8|V%x$%LJd}dEsduDa0P+8-Nf~;(<(8MXgSRRruUxrvF4&HD$aDaA(76?zr;`7=?hIUwAC%!oSdMm-T|{(CDA{dX(VFer?6 zuKhAxuR+i9=BO!}R49!XoW!2g%vSRr6vhnO;Z`gWdoO%Ht*FRfjqj>kT)b2oHO$2T zcVRCHdp&jLb{ch|3lrSGR5kA;6#iwOqV!g?nm#57K zSYSu+?dYds^pB9Te*E|dQi=O`v$pJT`$EI@t4+@68-V!+JE>u&rj7}D{ZJL*cz&fS z0??$yrJuopT&ZG9{PI;Nrt;dldD%)~soqaM{h*B}xmkmbj#Pc6E})#zzX)Xl<$5-s zJH-hM6N^nQO2)2BJVRZHLW#qSl3D8Xlr}U zfLi%6*3Zfogf-l;1aqh?@3-h#9vJdq4)irQdvC_HNDcTR>D=TcX5d z@(J_2vTeYQ0A*-#sX)&!FCOsm2rmZh@VisQ5z=$4(*HayjgYttX1B|yb*=n4b%?kN zfs^?@iPV*LJTKG^7^44VYntzLmEQ=3ua1YOcd}fc^#l+W zlwrQ#hH) zDI(9~m9h+{UIo3qh6}(MJQip`w=giEU%AgVmR^t?4&oVZr}emwqC2u6WZofu@HnlP zUT&kXYhTvoyh1Oc?~MrLYrB+|e*E-#SmOn7FlM{=iI`QX!d(7&8q=9HPagiggrhbNm@HvzvUFY{B2K)h4#y6gjN`k5?O7o z??@E@DG)JhNkYYw^0F<=DsRuA>sZ=z&17KiPOl;OSd(=3Gn01eV`X7(@t)A4fqe?+Rk@_<6Nxtw3^(Fdb!};$?xv$6DTbg(x zt1D`Am++7&=~ryGxD?%{{N0JNdTAS?HN-81s z%;;>bcx(EF7bw02T7Rh)GL=8h{%vv%3k%Sp@8%0qASxqVsT~_5-RS>=iOy_&$nKI&&5@IQ=qtK7h05%kbNut7KXO=QkyBC4tyCv2z7OnH6lKJ zlQ94T8D(X>*E@-1{?Yq!adCZsY?PNTNc(2|;6%C3V^O7i zA#icexX-*W`z`|bq+yNro1(!ajV~FMhj;m>C)UOaV*|JC9uPI3@NmU;+~ITmXurT< zkqeC7HB3zXrJis9Y6tB<{7*Y5e3RD!6jPE0(>3VkudPvnKr5(glW_iisL>mDEhP-r z=1gqyxymx>P{lz73Xtsma#0s2mQp)15)1W#|FB!6;`o@<{e*9Vl9v`ON9p8KF)0}U z7&a{Bj%#1@AD3dhf@FQLP)==Z2+fj!CIg6R`acmx(5XcWIN^XqFHrODPjnAy+?Uu= zclt8ZWemQV>d4%<-J3QuH}?&3l0JjNfPtaSGIwTXW~V3&KX-C7Sp?K)_vP9L1|s>^ z%giOTnc-Mil^q!&Bcl*5A+U4m031fS_TN`gQCYd%n7prhfQM)VkTN zJ4w|}jNg@MB~N3t3!^(!G@SAL4qeyC$bQhXylfbP+i`k&#(CE*Y^%*Y&u#+cV1`0R zQ^L$))Fqa5CZ`CaIgI{4o{2Q+82MoGlxepAIs`eLS%s4*U!}3I|mC*u@DkFUW*gT62J8O!{62`5dXjS5e(L z#&ka5^u4>e6Ycd#*pD&)-P|ji1Ax8&iX$Q~_bt&sIoi@PGTlj56i|mClDGw`#F|&t zHx+FlK2*!sm7t#^?OSu;CF9CdYZW+{;9Bewr8f(CgMm-WyLT)CuMD(7z!~ma8A_O$ zL$x+7D3#KYc`r$HlPROHFd{I}9x%iqjrR5t(hz*<8xbt@l9Z@Ot9(2gT_vO&ff!KHEO%?EWv=J7fnzFh5ypzS$M>AZ>~Rr<;nbA(bB+>iXIxxdkmYP{ z?ahS@Xah)y7SyvrHBdtLk+L_L5luUDK{fk*`Xtn|KUj?yD2 z7-?D_*Sbf{9op`uXyv6|KQtO!h_5uSFSNUri;L1Ne%S6M~LYtuf2i1D6W{FIAe_T8n+3eh$ zteRZrW2ZK5=gGTZs{(8`*4+P%Kd@0WK$a3LN?!Jc3v;7h9haT8F!xuMxo z>?uf|*SElbqnbOi%8gAw(mb0X?>w1oZL@Ox3e;@~!a}n;RNbob z)8L?rC{r8G8-UOO<$~B8@K>@%OG;JC^;>ZEA|N|Xw4C{AQDAZ{aFVW~qDMr1G$^h~ zyiuQ#oSOgwr~7i|r-up^9_|2INI-+f?KU4w#rOdQ1tprtoE97@oCBcS1mPeyC<$ZD zp|O=!01VblTpZEiEEg5u-;S%%D|m0e%AK}DW_*3)&p*0rv2ZoWO42Ad3Fn{x2bO%B zl~DNb*56*58;Ots;0I8b0Fownoa^q}3YU=OYul?N3O%fo&nBf`57Y!)gjC;ra#eb( zkA;i&j(?T7H1NZfBez%u1qHJ;iUQ4vA0qUO@NJ1QwHzHDB7g}HeH-?QQxuqWkic;R zxRi5Xe|wvXhv)VIhdCfY6LJzMH2yR|3n0>=J_5HXT=1+Ao;v_9D>dk!0HLU#Ku8{=J0sb<*O?NdnYfO%(uG9!i|ty%T&6m(_F))f-{PG8h>8o(^-dgiXU~| z9skzda^0Gm9e!zsjBFiL5)0huYt3MU^{r|yt!MuOPY=GXU3-psG?$m4tbWsdyMjYZ zt#K{re02*{N>n_;$M_t-FMsAZyw9%N2=5UzThL+$fm;i)X`m_>Cq4ij3F+JbLfbzW zwnMr@(bA4tdR|&pRYLxz4JhHN_e%iCkV@cw0{AB39AV$UK=0`2Q+a)S2-98M%Vqu6 zvH0~#&U~toE5RW-T=sZ`0%G2wel~YNg6`u}XfaWx8UD%?DlX8}jK@*a*8qBgPA?fK zzoJ2CcpI9V5yUSl?+VvWj4DE8gt+{w!vJepy;yw&(gC?}dd<+Mzy!cW3A&7o^z<5& z83%UX+Q;Wh?%UGwdbLFZ4DiTTM~cJB%3MW#{A_J)5m;T3k=o@wpiK9_D$(PE8g#e01_x{y{EBh#@)ZK9(T)nlCTWemSP>f4Hg4r74s;58lQ8en@+I4l+;7>=K zioV^9?5a7Uc_U*+U>StE5W8<+76ux_{ctMaLB%<5qmNoQ#h<{iumuER&TWbZkPZ}7 zkVU=(_ytrroG&+_377${4#DwfEG>;z*v%=E8yBc7E-%-0bRhJo!u56CWo? z(JB){L#1GFNiUOmCaZfBym?WQsgwss%tjIKa7fdN20<8sOG}!Tdd2y~8K0ay_p!Jz zcPQqkPoN2ntV1?T=nj!y({@`lTj_x!E1{}-8?ACp_a^}NM!({o$-E~tZ_Z(dp98vE zDeyVKWy;y#v$6+_^5#&L2W<70OvWJ#P|Gm_SBAy-k9WD9Qn9`-?};`-E5rgqii(Qt zTSI(U2s{z6)DHaqqzfL6=VlBMY4?d~E+rOq(f@%O*=((|)rZW0V6w8*_@{GEs_F=I z^CEZ9XAqT;4r0?_yE|jt8*Q(wXjBh=lA2NST}z)C92(Hlsvsm~XQ!a`Yiv`@f-zda zg1Co+1RIPjhbJd+CMAKfgYgCL&YkQ<-UpySQc=03yR*Qkw1Zj1!2zkGQI_gId;a`s z$~MoXq@tQ;4BOk^)&peySIaNhNN1W?`&dK-1vG8Ili2eLC4!6{u>M5_A?x`n!LoRk zmO(i8VdFom;NWlV?KQ&Kn4IgEU)=;^>eca%^|5k7OnU7{eC>0d($KXJm3pAVRm?d6 zs^8#{AOOQZBgbnpfyz4om+T9;QRg>h?d2aOdTwK25g07iW@GweeypofW3BN z<%moi%oQvw?@C}{~c|d!M1mF}L&2+>S+9LN7gG3F0`QAAnHONqk zZrxSA=1|3?!uAk&(uVHWk*<#_@9pl&*vvnG2<__*^HB(qN`5|z zXaX*T+t~q7S1#GU3d;x1LP!Z!x3YelAYh&d+E(_zV{X-CaHQbhXDJ2lCpfXU8`HgU z_pf?hl_XowedCQfh;@1gjf5Ocr=bOnb5r>|@aBlJ2}X0DaY48748e8r6qtcPp>yto zI%>aBDVe}#__Pz`{MW9Z52&TVBCY%1KN!6&Y5*H`?s(woU0JhSyCY!t5g}mgJvs{Pa{%HW z&NJ|3$^B)2^xh)QyNtGUBJz`UKU)mRu3rjCS@Q5~lCduk^X|+xW+%zu*KQ534`5|rNqz+FJvfDKkm2V% zcDgKMC20RD|HT>zQaANIgK@@c&`*%MP}*?OZg~>vplrI;1aj4==Woh;wv|`#{R+Ww zV~q}WjDEus2c;Sz2K+~4A^no9U?)>Z+w0KZrx2B$t9Y;?)U*WNqXN*kfUn*?L)lkL zTJ{O$M%7L(mAQYCP#=qv7NZPy)wGO)@Ue2otsYF~ ze6I=PTOn_OADus?Y@}rU1VxUXpb6U-J5g^}{o_`@Jspr1zjLLgr1{8&1Tc3ky zYRoIASBO6vjX;{@`b?#J|SHw3ze(Mm_x zfj%Ho!-@X#&6N4?2Bcy)DT&~V?s8X9DZnwH-4uBIXfz(%muWJx#&{RK7!7iLh31=Q z-#>y!q{|0Q`MiO#{Ro-U`=}`HFAGXp{m#y(E5ZdJ_y8@5!>gexUbB*0Az~moX|Jk0 zF)=YIS)Blq?P&Atfd2k{nN^=6xV$?@OGnE*1t1M1y+8CUjRM>xm|9uH)0s&FE07K` z74I}Y_n zlwzQdKo~1n>09U3;C2E=OmKYnCYrx+Tc{C;aGy3mWn@FmEz1n-+Fv6pSm1$D$f9^OZ0+ zZ@f1in=<@p%jG2he96Y~p5IGAI6#YH+@GoVH8o_ECWkp)(aeFIJkldO`$uqRXXnk0 zMm0l2Lx8yXfXhFAabZ-Tl5TA>=~V5J06=78of;U=Ktr0yw^14k7^DINV_kvpHC9Mx5DFGY;r;nO;#Cv6Hx1&y+)8*@(sqgwrbS zshL^~-1bB8qC~|ADu!?PLo{PVM=aqH3HO)DNuAWLsN@!fhtR@2dq#hf_0T?8m7;Eu8nCS9780$**4Om=SlHI)n zU_EpZR$4`JzsvUF5r8nBX2Cg>s`o3vc~RW9RFIb-n^ew-KxXXh*u1^HIS1HcJHP=3 zImENy<%_<9gNBb&DO?R38Tl{RUgEfL(H*}xI=*v}8YDr@zUiU%-SByV6OBbM=`7n2#>(8);3M7Ocf zv|P7DX(c7}U5#kTFIYJ&(tUh=OC6_*;)J|Hi^osXs5m~QDrMO^B^Mb9b7z9B3X1j; znE^}cK=%u1Cj9+T!CU$S8WVU!gT+#)vVK=RZ%CKT)-1-Mph(osux1t*8>`rxj}7z~ z15X^pFTV@y``!c~MJw22fL~DfI_|bn^+MR4AHm)C+0%eYHasS#DZ1C#1Yn2^C2==& zkRK*xX9vTG?9Y4324@QL!vk>1<-Tf3NLHT5fZ){y5D>W{ded0XL8hQ-d zqXdjO&ymg@S87L%Q&)uk+~MTl;F%rR@8BBOK`=LFW+a;`pPq|Ce_DOCmv@w?ef|Mb zAVvwUF#}Eorgd-$5z&@pZ~=wGX&GcjHX250I< z(MI30oUmdp`vt?o^`9eeWps+7vJn131djz_n5Nd|q`QHN2%nrqYH=~Kua?m2K{32S zlF@AbhK!%f``YUNDR(i4vojrmR}n%fkhJ>RK2yrZS8f?B;WjepoJ72%7!uZJ4wzX3 z*|kDHY@!nq3cPdFQW{6NPc zsi6_~;*9(fuu1;U61PhALE=2P0uM@=riSE0%Dh*sd-QM%m=pUFrV>jKNN&HYCzi~1bn6FmD}97Pu^9KIF`o3@Gh_w z=Ni8Z*ld%(fADbIXOQax^mHlu(KQ5A^uH@Y?0lH{vUcRh9{pMfIK7d>u|c_o>WNE( zzb=+7P~BT*N*En#zzjeasZ~Yzk9YXpF2SRyQ+ayq z(Xeo>d{rL=wo#IyHw9TpLgIK`0x!;>2q0!qcAVpVaa@Y2Pr&e-nr7&E0K&l{V2=ib zRI$N3!?Ag z9upBqXWl>mP(>Sbwn~0jICI@v&T{RvCl3I&XCZch$6+&xAxzQo<-_RPw=ebu{ycse z!-iPitDzY%eo}skfA~K6AO3MIfK_MGYTXEx(IS=v_I6;gWQ|2XZ+q?LUHFqs>j~jFXkL@$3kJSJhYL?Fw>d&s2YXzZx@rb*G>nZFrAv_gOCF-M!Y_o=v$R`M zTFzG%;<>ZAD`TLjjMyAFH+S8E{YT#b*C2;#i&;_6Xy4Os!pS~U*=fb%;d#_%JB2DL zKb&u7Dd*K%kY`RTYHG^sQ)kep@kCBkb0lihxw^9h#0E^|eYrd#;2z!ug;CQ&#dGyX zMKv%q>gi_TAE=Q^VDoSI`c%{my4a6%Dq!ehi!RW==5wCPlkRlcdcDl- z%co~%laTo9ug_MD=8=(SEAwsh_Vfo2^N|Lx4_4p&#Ttq%gr;^Z*cbQ-B4Td}efjXb zh!3B^mZKDB=p8bY?SAut8ze+;#ygju>@R~PsG=h7^Jg!QEpCy;bVz%HSmpE6G$Ghm zrt9juiYW#XwC^YNnibo{)#35+IT9^(jg9_*;98CSB-9oXN^>5)f`ujkP)?{-%7nYe znT_IINqAHZ-=<%{hkrVlajf%r0`~B7EUI_6zyvWh>XPF<&|G1!jRb zv-j)-q+#-3$46au-o6cXXc@2tiF`{G>jSOtD&elsTDyO@rug>l8`MG06d&<$7G31p z6!8(wEWqG@1!J*2Vq4Yvc4!DW-EkcPFQh`*@UK%-QAhK;^yI5+U(U#WAL3@x?EZpp zHy?&SC7)p(wOKjQd9=yGBE6QYpocn+PJYGW4(&D*+!9qUf*vk0O*sV9QbVLd%E+zv z(7XX~vPAGC=JWh~mQ)mUG>h1wnBnl@g(rM&!u0ZZ^4pXkl35$Z;jxPSwk-IZ8RP~` z*a~cWX@6Qyi1jqQle&4g4~`pd?K`z6PrOUYM>Z4s1CHOg0t&fiE%7#w)oThFw8hf| zc?Ve_?UR(2nm=CQ0$Jk5q9efoSUo_1MV}@`FV{6Ok+{^_diCnn`*PNI-90>>CGbSl z)I1hlhNl#s7|E5SnBFOsHvr!MhTYkvz&>;ETofs5Dee|9Ffh^X?V3W(YX8hk&2s-* zyjA+SQpn{ITL!}a@}KIa*iBU0Y^SalXpt};(n*M6qdkjg-JzUfS!uY2n)AtM;J zVH;5nR&}gOeSB8ytCn0r$pjwXq@=q6(!IzqklcN^_pADB2cBF2>J1o8p1tJhxTxG^ zD;GMI`Hew*MG?R%(AizME#2#kllqoYS)c1l5`rca6j* z;UBG`Nk-yV&>S57D4xpT55)LEGxyI`y75K7X=dv6J8d}LU*q^2+nFmH62{6EF^BsU zlnady$P?W5RizS6gXfJ%#kVwlv$7Z&mGh?ECcIwrZ5-3S`25gtwZt}xP-SjF+tn9| znK|!Cb#7&_7`33_xTBB}0F?wpL^86ul5a)cW&ugclr@lR_$!Jv)M}0b%ntZ?_@#y` zN+4L`cp#z%kQ}52*=^RO1@=8633;HBeomZ6L1d#vJ4;=v=k;zIgnT0)7t|ZK?}-1OQpdCPyaN8EGVd5=Ir%l;7r5h zzkxG#rjQH7f{Xv$WCBRzq8bmZv3#Y6n`Dy&%1TuG$?=Zl)0A41s2Jwhl;jEIB39pD zLxuu~4oFE?x--bMVRoJGYmK49on`__Q$2r}344H1G8O9PkE^^@s@ckS$JuKF7^m$!<`5Jfr%Q#$1V+%2b zW$<5$=4JvhH&Gr(cQA&^wtmW2O|}eBmhbT8Z=sjU82l*nAuWwgYdo|%W0*oIix8ON zB>Zdv3rov;0uMs~QaKx`#>B*>V`a7NrZq$8a5XhM)^UYqais-1e%FiVt655@G93WVAVkP7Z=37ZIkGQHq7_ zF5A^b*2d+Bnm@6at*slEhuVSgz$WEl*mvi3+`WH$X~}oLiZ|*M<@8w$_dC{P&QrEP z?9RDFgme%r>sTdX5YKMh1)dKD11BNZN`!SXl}@_(ZtsuFwsJAzUjwL=XjsCaWX5d8{#ZVY>biVg#^jF6nkVxEv4=P-uC=2_|Zs#y_f> zL698MHJx_+st*qwgkFzdkG(=D5h7xqYihEUcilF(bv>}a$ z|H$PiF#GV8*woD_paGv342<(xS6U9V)j^g1&Q`c6GkJ0ikR?vb@!+(yg(NS_OVUyA zK1o&Ln@fGo4Uu8#Bl-pI=9{6r9-AtY$~BgcQ`$l@=2-Ia4>@$|ZIXgCX3O0p2b@D# z>bmc8iN<|`pISbfemM`+!mbKxOU6ZN1<)Y={AqVS$^*^e^ zj+VU6h#@f=0*)BvM!NKL;ShdJlK(U-0PW!oeU@7g@;G_E;gxuVNj%AhOuHV}-n9U-eBj$g zG+(6k7MSfZJRoXMx|(kJ4UExydxm?%MW<_XkG2d`_ejPdjxLo;?GK|vX<)B0UUXFW(%gO0;p2n0ym-MB!D=zxK15WRA z4YIvC^S!S#m06p#K62Z zS6Ws!y|nZ$=y&?!E_IP=juQA(x3>3{400f(5YoQhKzAvX_5V*?a0?US-(v?6d(Y4i&;5bbAoyA!G2HN2 z;IkO~@ouenLQF*^ii+#mL-0sNbG|%F`kciGeyL0?5ldLkO3hE@Q|E(RzTDUM2R0j8 zzmR#6-U$pIS}tEH`uX$wK}se3 z8Y`2lMs;ULXB#aYUqF-CiC29iD4D*sN8SWAh|^!fLG1d!7<$|v_EbcsCB?z-VC-ra zPazv5XT`Nng`W0LNzshT=jz9|J{UH(Y3*-c!QH$nJ=s1fNrZQn@{eD>Zen60mypAE zDab~_(^C+!nYKG*4`9x~pdg;u2oYGV45bF>J+Sgix{0I1M0s{S7sPZv;^>8-jpMW) zs)KbQ-AfiKVZ4vwQ$Yl7?`|YcM}!HbZf_fwDaNpH%D}I~i?t0nZg@m|N6yGkHtTbD z;Ahq{S0Dt^30u9Sy!7TBHnqK#bW^DOK>d!8^)0V1PSzb^x>s0JK=J#WK_koo!-#Bc zib|#9L;5s%ZVv|0Pb*i$$UE8;8CBuefHZb?b`FkOcm+!!qHjkle2g5?Y=@WU9X=f% zG4aC3h!!x7fEE3L+V`k1#|^M3w&uFRwvDf8-@-pdi`MyF^)GWE2l*GcWuJ#95!JlY zZ&oR=6Rq}D11bDHAtC8-azsqUcY}A?{Fe~)7m9zAS8UXH9o&7bZG7-gqlNSvUDxnW zp=nEd9pu}cL_z{|v2D%uV=VK%o_5lT+WTVgi6uvdxk$CPkHjV=B~jw{9oIpFhG6Ca zU*=5g1r!C;R;CcuW@sQMqapzT%J3Jg2{|9}d!P;)mJhTqXT@;^VdBxxKRn5D70Cxb zJcLB;)M=kT_tYYXpA2Q$jRkhyKo{K#LvC@HKvPDS)OXJrG(3EKba(mctgQC+*tMTF z_D*y(G*1zae|6!>!+YRb*zD2PMyPkCZnxa14*;n+8^Z^(gHv>&^C{en%uKl-o?u2E zupa;Qij-?|Wra^K)x?96jxM0k*nVkg2^zH4{!fPOpQo0WAzf%0bSReQzcmNmW9Kt|2~WZ#1p>l6i90n-!|!tXytH_lv~sCyoaG$U%Gheu`an;%u#FcH6Kj2wi# z+pzO4>%-nhUNjr4Lr8mCz*%}GutjiIg(_t=!bA%bk78a5C!~NiiG@)c1fO{q!h6TY z#&$S)c7RCdf+UHm1n7lodg5y7Bzh;CZ@+uvX-l;s`|`GZ2moF@d)U`Cyfj89RLn7KkkNIDbL&JVTQC6 zTyrsPR_AX@H`Q%T%sX~L@*e#z3eMA)L zH?P>B9h1=P`)hAvYE9pB&G+*0mH8YNhU@Ju!uTGX%1zknKX2T+HJC@*z{JD^kso-l zpJ6-rcD73ChY_o4c+5(ZOLP4jf{3}{1DH^wa^&y7rwPjn0smoLN5uZ$i9mO)LrqgJIUGEzt&eERk6wM&3B#O!sX_d_zY{$ zf2<7+&3i<=KV5-#(+eygzUb({k-!mE4WU3&X9g zO^G`fW7H^hfw8j{uGoUPCQ?Xz_|ACOkTdr8(hrCw?G<=EDc?7EACY+gmp0m{??Wc- zs$cNK^4J}+fO9xg>xCuYCeR}yb`@xOF5OEw9ov92+=U1h1hS&qu}ujE+34tKNP90& zJs)2EpB6xafk~-I92#jK5wR@SkXk$r#|N-ID^L<=d2Q_;SYZ(XCGa+*mf=sYfSeif zuMo`s%$F2G%~Dk$M#bIs5u*D>GaS@3!IR*fh0Y;OaZvT&xKXpM$Vj+oW&=&*$IZ7k zqE$p%We)EkLkJd6S$OG7iRBI86A(1`_+$QFS<_Y>M_in0yr`(C9^|nR@%5#r_CM}# zmK>j)JTh$iNGWt%{*v4f&%cOxeL3$4V|`FB@yFDd)FoecGy90XNjmw!=0>|7wobFL$qt~#m*Fj?dOpbW*P7&aQ~%1WlsmJH;rc1f3r+k{H0DN>V-fP0H~eOZvu@DXh&}d3RYc2ne-11K7R59sX3H<4i=w5gPk=To0o^H ztE-!-1vTL4=w{;k$8ayZ76KWa3^fHt{+b!GC?|VuK z?$b`7fMNK)UIa=*Xn4lm&#;?9NShC%ZlRXFvbq=fyhWlb3A88c2+H$mb1)q*ubOu! znm9;hp5fC$o{~%Esyh~t-L0L!sHg>e;n36fCGW6AOJ=K+F~EICtbjEDpNO*OIN2NFzk2;*G2{6JXo{slo;4Q{b)T2^&DliFsb&|hQpm_y>f zK6-r?N7&aaAKA@2(dJ&ZVZG6p=M12v2NPuJFU4XZUHlv+gj5ZvFZk2A%i{CqmY3TA z$g-$Da}=ee0V>&cvR8WOtTupvkZ^BB14KU>?);cU@DA%0lt-GInwn0XmfCA@dp+r2 z;YQ@1!&L*43BMHa(8+}baj3L_olQda0wE*VoFJwHYq(7SQj!1_QmF3Kf#TEwN@+q2 zGo+87K5ey4Tu43Exr>31M-Yz~?Gf26_AW;iJNqMnF9|KIt?3?7`zoKGU!SPFaC64i zIa`xKgj0ixD7|GsCa78{DDr`yD>}Ww6 z43rP3OTj7pevDDLy}iBlSBnmOGEYN7j)(OH`E28k%XrIkQQ?YxCTW4iN_`j7oc=lX zBnErQm*-zk0)yr~Xy~c(x6m#KCW~K(#b{<^V>;g+#2Dm$zxcp-s7=W(z(Uya5R^>! z7?zj0y5hW*vhErDx`oKu5JhH31Ud+~`zc?XUx$@EX9+~QTg5DH>vw3SVho&^JwUZf z#rP9OO%?r4w#5-wWU+bu-7D4aCUe3PE&f9qBuQxA!AVCj8+E-ydhW+pY|=om23+U?-P8T+&?WX zEk#{6SSyc?is8c%<~;l_1X(A?S$W&FZX5DiTDdK}yp*~3*dGLUa9L1tauQW)m5O2^ zR)OyH$pg-eGt#XKn{*(mVC5iiA`3zm5K12rJLG6E(;?&-PlqWE*O!*2>_kz~_r0Kx z>x2vWyUlMZVC)H_W1P3@P^Hqo$|$R!SYPBqbe=%DQ*XD)#jzzZF)`dD;*g>?_BR6S zR>r@5@~scKGrXQPxE6eaS5~iBDHNtW=|(=i?u>ane0=CneP_yZJuP^OCq(D|*8V=c zS#_oZ2hcRIxOLtsKY@323NqLD_ZRiyX~5o+{tXgOB20kTXgQfWbG0mFU5?mHO^uH$ zV`Q;Lp~wMYVDCU02#L`8jcuP0(6>?{v}jyfZXuc!?h=ZIpZtpamgkwHy1q09VUQ4h zZTU!1f>#1jnsdL!$&4l_49M!}I zV(x**{=28=3p^*tKYRqJJU_uTCZ|`gY^P390l2)FOFY=${}7%4p+-1lYx_AWR}q3Q z;pwYB;$c6_|3c{0pZ*=HMLu9MjW&B&81uPWL>*7ULM;^pYLtakh2dWFiC&%aFe#rsU*?=B@fQV;A@6U*-h-~t#K{e>6TVkPMfJ-r8ft27&{kw*yM8xi#g`>F5$wR*e_fBs)%+Ws~inomfo{E07y6oyP`=E!j^#(M)P zQLoqFA*0g%_sGOe{LF$2+Ap`bDJZPdGzs&(B(eGsZSz$40So{PqwUkj{ZMT z+qp}E*FH}sVbt)91Yn?VWF?Hbx3{)*+e5h6oW}V@MFOrcS07TPNhc~jV4ubk96Dg# z!`{#Pi1LBjjk@Qktq_#=LgzuIV(5sFEhEqxp~+ zDSjNyxDw~)=9ZC_XWW%L2EE;g=0t!0r-rW$lw|+Y(cb>AoBSH0izU5Hqkr3c1Y^cq z=t`Sqs$DRqMs)Tky^$%U?24A4)3+4Az0b_08)}?S4&O(81m3Mm$=cewx(fm(Xs89^ z-8M>LH>}6!P@Izl?JT7{*msW;FJ-JurjF=rR##Vbi{G?IADx`wlaOROzi(At+;gR( zqCT82uKMP@22wAr(-m!(!-4A5uV0^T9sAy6q>ccazj!g_@eKh_e)EAm<81;%x&_37 z=2`se8H@EHq?eiwVjI;bOd!a09Dp44hK42RrIY0VotevhDy>06a_#|Ce`-i#h=Depu?9=LXU zJl_aGOo#J&SJ!rpQ+4yw$6lyF!~OMe^F&qa2vX{QELC-R2r}$D{5J1T`J+=gqCl^G zc`0RX@9!J!#c#(X@EyHR>Y=8PmiB3ccca)x6_fD;AgBegOoWQ@Wy zUFE*r@a~dhPAkzR1FAv!uP*+5nrOS)A3Np)y_)U=4A)7iNutMR$pXs-$fmG6sK7D} zwu9pH*Us=u;nv$Tct3(Uc8)uqBw_*b*=9#;MglLpn6crV>vb0aRy7+0_+BE~-D->H)t^ z6tbEJR)_DB_GMCV+aQ;&6c2M8;%Ix2NIRuPBZeTY0xb*_d4KfD|Q=->Hn3 z&*ft50OBMmJ~Q6X)X-4*VNgJ|5r*Knh>3Tg{Ms#cQ$orLfy*y&kGu;B0wcxP`d*CcN=@Tog3~bM zPS@iKPFhIe!0`(ly|TNvGqdjIc;k^LziZ|Ay6b?PvU2l|m*;0_fxwTJ0oy61!37Nn z{0AW0GtZq?O#s*jS``%Q+dJC?UJ1}T$SSM1`|m6~lYT)5^UcNU*H2V$4NLL0Nddc@CWAS=Rd(%WXOQpQc-Apv_o+rVg4d$Y!4X)MYX{09#nkC zvVpC~r6ncZK72PljqNs_U8N#;-`e`|3 z_2$x3chTc=t9mpdCN)2Z!lc^!3nA4q;cO%Z{!cDJ@W_aK_KB2z41QeAbBd{(%9F~E zQEePOzU+mo8?n;*0Xe{rfqtLpUM4g&Ji`yr&{;!-@cf=hiROQG z9Xv~ceeOGZ1CWEt3gQmn9%;e3pV6BNDph@_``=S$o903cNu!1Y~~EAYod|4k1E~@VEZFd*_P6!gT{u=A@y}CEW}Ux2Uw_10;1eULdQj zts2re5zkv!7fCf*6*T(Mw;vg^L5$C+06#(XcoCpH(BE}J835_mhqzUXMv-{EO^=%_ z<3C^}J8%++SFvvmdTL2C1`ssd2&(pnwR=9U2bld}Y0s2DVx3cUinc-(1{bi(>M|s`~ zblOoMA$-a01rS5L809sjB-qb) z-s5)uk)r;WfgJ2!8!feGys@+>_V+dyrYB*4iuVo;8=Xgj*<+Mo;EI0fcGiPL*x6V)M$-beXXNHFNfFrY;mm~pQqV9&c+Yuno zJkFC>U|ULHp35ns#=>rXVx3A`vb@<8J)R4Af|3A=rw*d zghUkRFA(Ph_FI{mefjncp@#=7N-amJVEB0laLZ)tIrSG4gO3=zdU?@OV zU{ROS^dN(+(*Q7gSBxTdgea&k9lnCQ7bNq#^VtxLBZ@uzs&Sz=yeZW11Og(2sy(A% zX<_4^10!R@t@ROWd=ertn8v9%`k`2MLVOo67MT*2ps||9n=Vj!0JpUmpbFp){SfsL zA!sQo*MgZQF`oMg9Dv%CfQgT35IamuBQ@#pJWxJ6RP%?!J9#v{OY;3z+kd_EPj-{R zRw;&zST||wFKER+d#PB zIL7;(?a|Wuy3(rAfsCGwtuCx(hg0P*Wn6z)j0EXxpnGAmuHO4BKe~Iz6nMBOu(Kg~ zdxu&zCIeoS4|w;|>Y~AhIEAdbI-kja6*NU4KH2@jKKXo*o`&YCP!I(rB~a&B&;w2z z7wE9vhCeM8v^VgmTwUEvt<1gvNeq)pCLz`WmS1(X5KMQvJD(o{QEv7XR11jE^3`mM zapyG-VAKdRMj+`LvW8sdti7o3v%Gy>b47HSAt$vg23*(-L{f1a#t8XMy%k%ZGU`<{ z1m}r}7-`XWn(ReE7)T(9M6ue-<|>R?)A)FxVWeSv)SFy+sQTbn!XtDF(6{Vg673B( zk1B+aE@3B1u?pGXX<70)D&p3=DI53|uP;zDU#Bo|rTtWzOw&;HDnYTh{XtO#n{Ti- z@erR;HN(n_I!-GOu_udvXSWx~uHXt#m-qs+)VQpeIiB=WEvK)qZ!>ZsAuac()vQ3L zln%Vx!ME-2VX^l#HZ*;Ib;5bYacx*sU&L4B7;!`)%m{ef&aVl!61ZmweZl6Y4#My` z`a_nsf*a!drq4HoYKBHN1%150&yz4$fUFr5+0k$9%J10YYa-MY8G`qMgR zju?0!xL6GxS~g>^?R&H_KY^+}xl0^m>-EvyWBP1sdV^CTH;?CtFx_$~@%f7>{ z&8;m%#9}k{w(NoNVkhP!7ni_3J5K0FBwr**J$^ky+YX&?zT=u&MMWjqAK%LwU;iI= zbU9V**n5WJ3jT~Iz~)EB3V5lxSL20bt-Hh9Y}a;#GePMaT%{~_z1(8dT|lskQ;<2} zCinwB(noCV?kcRNt|^01%PylN3KC;|AdfPwd`Soocttkb>8D`4gn3jR_TJ9_ssgg2f4ax^&bEIhg8ysptG}XZzqe5yMMOl!LO@hXL_tDA zN<~Ck1wlHcyBkbYN?LM!q$CC;hAu@!x?|`bU?>@C$akMnKi@y${pE4F7BeoKbLKv~ z_qDHmBfJ?|wbvLe(sQw=d&UtVJevMB9&eo+|K~eD`(M3``N!#kC1|T-CKKPEE;_ow zl$9yTFl!E*g7@-v!nN#+-^L0x+hIyhRDFL-`_^CSterBZ(b^iOO*OkL5MWeaM)pIM zC!c4XzV~QW+L7-bjXN~f2t^ERffs$hO{LfO^4+a!APX8^uV?^F8Wh6;j6B9!0Hc?D z#?3&rBbgHeNd^!BFGCutnwe4#XmX(_lu}EcZi!F4 zUk)w;Af~pv18!2Y!m$u_q_o^eCNnlMtL|bjRzk5YrKrSy|n!m)N^_Bww$WVKgVmgKir({oU^} zf^coa=B>Yf*!6ZC5Pi1z?0B*RJM`Cv252OE2h3ywg zzI59b=|0@=NxO0Ei(P9gXW6%L(V(tw+PjsmZXS7-M0-eoZk9yc)_3NkWn@HaTt@@x z5ZJMh=#YK93Kp%9NP;3isnoB2bL7%W6yOqos|b?+WrFUmU~Ja#ODNGM_S+wV9y#>Y zko`BVBNP%BAm(v9O1%#tk90u2>^gJe&X1RuRe}F83J|)x8!Jqgxw+LWV;=jQI&&(_ zn=KFuOQi^XAyms70IYIPUT7-=Y<}T@d&Z@X7+`e$S>MPa$gT-h;9zK~gUNXNHjptK z@Ab<&-+1sQrTU-gs7wEYJl#t=cE|NO`=Od2dI5q<4thM*<6$Zswluc;zl>Ix(1?k) z5aOot>jML|9Dsb0jm`LOX0#n&>G4yil4a+iTMMJX-=Ii>l$9bZ-dON~DTS3_py?;I zUkMBVD2>;yodwySwXpYfoleAh?v494;6uXLl&1Uuann>da7W8?;0<*qwbTME0l(o^O+M1ISMh>ucL+ZH!uu4;SMks-CbUvxAim!_0h6w%L8m;IP&YcC-avYOt+wV?mbk3Q7KYZk{5e)Ud4DwCW zU{h23R?U1eyC0YVXOubSHkTwJq&%6;y$P1$*LtCCN7L~8_f2GgR0hrfY>^r5y2KJ0 zBmuP&Rl{voX|kyu$IqRs4-_2yURdeC1Tm7a{PbC`Xu4N_u>k5$LjM50PL4sBEK+bh z$7^Y6IWbr`GzII1_yzc(L3cVLin9)oH=v{o8X!l%a(KWpxqVmcc+MF{*uHu?l1uv? zP>Bw%!T=jUmo9N~$~{|%3kIMApGnjAVcnf|NZxh3vvegs!Hxlvh6p|1{x12all%#7 za4L8SI4cU`j~x&_@I3?Db>Sw>0A*ZC%Z)dxnR5nbYJ~(21qO-&q70hWJQq34dMUI3 zUqngCnCLp_KqSuXOfy3@^h!pAAfXzArHiRfb(YwE{pDw$w}6ZcfKGn2EW$TCUSlP;M}BE=}3c24A(v8 z(c{M(6T~#T@GvF{G8--KRg&KGhluC@YX0BouG{hnIxwy4e>d%y>F^yUuO8LOJtb5d zapMiE7t@doI}8ub=VuJ`{yfQRd<1OV#Yf2)-)3Z7$Cr$r9gF=8+Zlt`Jio&n3ElTV^aTtz~8B7OEC_R%JrMv~im_|@A2#@StqW0epRZLh#j??n47{maz7L5O9 zKFQf%u9JPsMN)TVgT&6ZFsko@hF~3@OOfm7r~UE5Ob|M&W@~56vIsz-5}Ri-{%_T= z-*3}7*7tu|$uGxg$V!~QkTVLrq{^?_KcZfxG&pqd)hQv$0h-<~4^1Vugq!UmV$T%= z$3mE>;g2un4?!D%cj;ZG$mShs4-r`WJk_Bj9unbqbOHbz05-WVD{Jq_S^W;u_B`XJ zu`C-ef1CNDSPZ@=gx~H`g}3A)_2moKeJAMndOfR8SL_Tf+HS?eTz)w0=%}KW21--_ zw7fh(bp|Mb&OR@^4Y(Sn`Ju%7w)Ll>lnFWJGl0vKT0~3Gd;w*u<41F=7Z?bi_6LqD zARtdlP33shfQ7U%l;7+U4-Zdz=But5M_?j)O{6+~MduH*@vp^+9+y7`WB+x73GkAK zueb*GOeYsEh6#{8ty0o^a^yoFdD*^!gIeR~4XAI-nMhED#0r}utx0GC8$kkzeM=i; zEqz>9o(7-ClbT~FstdlgZgD4Mg}#MUC|%z#;@ePV^Nh=BOIe$5iBpfyHc(#? znrC0>=ZsRVXn)?VR7enwhSPr^8^&iUnAG*D%N$sNr7}9~(u&TaRWnR)C4Tz!JW9v& zZ9bn#oWN(^6A%{XnAVNyR~B^8Aqj`cf>x+WBT@_oeCiYsG;3vj{s@@=sVU>q{dd-Y z8wOM!YK^ez3gPUJ$WY}0QtPXy{jYTB#RZo7iGWm{Jbn6T(QBBGQL$Zmug#p^gNHdn z+?vQ@(#Ma!pgmHv0Am~By?;>xLNcf$w?XEE?%vk}!XCgV7z6`ihn)pQVG8k!=`VwK zhy5=Xxwd81Vomu+M`zOXT$*c)cyqv6?rt|SLDBc$!k*WWAcbwY^{mbKIs|c-=5WJIi#!7 zDp(pZ@B8P7qAqhlo6+~0np+A^)MuJeh4>%IiR#-s#ZGwD6!~~rNFE@H4e&o-yL^gs zE^83V8V=CQ@bXxPwnpl$LW2w7ufbQ0WtCRG!df~ziZH{Oz=AkGC`sGxOf`WuhZQ+; zYHET{(9@1Lp_-za@i>QmQw<~uY6PHIV+#vGPy~1@^VYJr=-J-JS|QeZYaY0=03|PA zlq$KZW}`$y9T*6h6ukqE?&VEBP}KtHAB6Bo*Z{m?XLEyNVR1`sKRrmgv#M$(lYjQE zos-kkndPT2rFe3W%%^J$Fac9gwm;0J13FECR_s|!2)xHUZfF43RrNi{$~^e;`7GO1^vfGw8HHhl*k)ZhM&tX8U0j z3Bc3FJFoHZoq~2-{%o;gDY{JicRAS@=ZX6xh1-$TmLH$L12HF;pfE4ay=gmbY@X#x zQM7MqcT=)thAl$n#Qn3GS@+_A6AVe%%*|)tYfp}Y$|I3L3BFqykQdO2eP};(f{}4e zX$zv`xxES6A&+(KE8M!OA2oR%Af1MOTgKD=HErks(~ht(Fb<6_73*SLah12sXU*Cl zwY-msk+pl+Cb3^r_o(%%U{!LLIS8mJe+*|>4*$8vtSrDak$7!m_}{+#eiv4ObZ#gy z@FGc?U5gkX#|bmLJ3BXf^sXPHJ5|>`-w#RJq5x4^rV-BxVVDw zg#)*sNdBDBTMSwV@XIhDZU`fLtq+D<7tcZFlUcfO6C7LS9lz=qC=}DWH%|Q9rEfBF zVjYWbeZdn$eHl2f!l7>M6ytaTLOcNe)iezTl5a`Cs1BgZA(y@SB>z1qsy=V@$=OH0 z6`}1+V3+wI#Z^1Uzq!#Jsls>&Y*??qP+iN+s41@K)1G!F|2;30H4xu@r<289|cRfTpTAVprLSlWu7Z3GU zP{Z27MPjgz{LSM*qi_%%g4SdG!1%AjW+xQL{p|@fJ)d}>RUSVMiH(($aubf?It4w3 zeYg6e`G7K}pim7QKg_@lhz-Cp`%6%O8ELx+wThAP`M@;-rH<~);(q{)NHdKOQ_Yad z?xD%3%}GtIU0BTza@T_JKC3M9;4xmPuuQLR9?x0sIIo(q$`nkvb)>eZ5z|YE+vWxF zRZOMN6bjekvelLx> zjpnU4O{8`iph(O(UI&9LF!i;JeLD^l^NnruD-FOA*;{1BtUo#m>%ze*a)k8&M zKEKF#kgmR*=9KO~eG{t&^lplOU}X7q>`cGQd@nc7-E@RWu+E3I!5hcLdXF8VquM@S zbn5=&;@g;&{WDe9dc-qdpQAKSlZSS`^MFu=UBfkmAVp0LHyvqt0zeV{u%r0HhYvo* zGdIQAUf1|XEsatzJ$S4xvozhdlcfzEU&+etQ-CFNbauRqEtpOPrhFhnM#f>Fso~XX zjybFF!)MzkID-M8@3%U8Kl@}#cA7bz)jD$G+i%Q05^Xw_k2VA= z`45&N9H(7J344s`?>5Dgf^PPisZ~ZDZw53JbTVK7-0FVjNdiD(YQ@&ygX6u|QCVS( zu$)6B7dVuXq31h{0hR|>A|UAZ>eyj%5l3gv**AbmkG!Va41C82`RNpdn96m6>sI#q zOV=-y{m|IZMh?-e@P}nHcGAv9CeD$=%jeY6RN6sE3C%DIAMdS^h}%{KPv+J`Eojs> zCY9E;yAv%2D-$6eucI?b2)SX=J=d1kldX$d9CA=vDB4*&LVYx-%V_P6oSfW{{Tfzy zypgX1s5GX9;U>sztB#rPBO?pAr;t6Kt^^p)xA9| z*1@5cu^>3O|=tnlC1SwQ*2`d&8zE_fCjD_~X6Od}CmSvg;j>1t5(r12>el*`$puBwN= zl4gnrjP<=1H~}(W@^=rY$jJ0)7(ykNiJsy%jr7tkk~iwQWW*DU?tIlZwAx(Yo>6qs zVD9Wi!LXiv&11ExIENMmv?~3X991Bfo#0Tm@9I*+ZO|&hSrM!kfuu%OO|8c|n;tmT z#)HKopXw52y|)vYQgvLOYcfN*bgG?IZh1<|zrBO+T?{SqKsK)30qO7+TzFuFCT^1uS<9MLb6NLdkZNVA(}R#=yN@7pUKP zF4q-Lw9D156!#a}v~(zmMPv`zNqaBtESeY@8Ofts5}>o!q;BIT$5poRNj}#3BjfQy z$koSR{62%nk6@ir&%0bPhh6Zb% zLG~1T^iC;vT1rf!y-G~pR?oo0A2TL#39M1q>PGWSf@hsxu*##v#c**Rib29_y*wUM zkSM~E&YJDPD4PbLB8v`$x*Bo^pfwQj)uTM8Uqlm1gsHdG$>GYrFP@Rkfaz-er|rkP zS33B-90eU&h+!;D^6fgdy%ihfEPUSUtW9Rkl*0OzjiVASlbXXZRNNJp`HUOyV@iDX z-VL|4g%}2laLI91dNwAgXZH}6s~U(XpRGb-cVR_DproYXn&p}n$P8@yS`LxeG7XX# zefc_J=pb?g6y*P&2CWb`l~v|yt|{gbOc5DOEKQ5lX1BPezJ<5$qS-a6vP;EU(or&s_&pL;Uczu|TG-gmKH$md95j zR#w+>gFZ_MaSjW`AP80~EXZYrMkq1xW9=bpgcb@YHMdt_1UT7yYJVIgkXFsP0rHQ}al%fJ_J$=xlV z9h>6y1P@+*AtAW@;tJq=>YmCiZ}sT(PjevGwQc=vf}W-DPsV74(cr3Q?GqefgdmII5YDU;`^q>^ey})Yqu*&ec=Rm| z$|E?{rV@QNQ;XM!JoqlRn-}fMgxR;%oWYeZdg#W)x)7NDL9VOUNs=_fq#J1B6YY6h_WX*4n2dFE){~63W?B2T1@73`V)byT8r*ev5Es9uxadM{2ZgMX%~@D1a&1pX zaNS9Gs@HIhD9p^vjBGPsHu2dE5nUO1L3fTpzFddt#j80q@H^nX`Exav?k&;4f{l(p zruV_GN-3~^0spS$N)v%bD3SPmWqLOzxc{v>{tefuN zbN1=zWI@R-n};s4Vo`pFG3>IO5SnY+~?f%KBbDD3CT2&%~h$E9R|WFNNxr z2-!q-#28oImi`P5;lVAFn-0p>vez)4;wU9A{>iQtmO?f+n^2pR=Qk|SGP{@SnAori zQLtCHXR5EUp={@RKzUbpcO;ZoC#-BL*%Z1`1}ZGo3#|GDj9Y9Lr|)}6*Xj&vLVUW^ zE?2yjRcenDTx>Ly*eh0J3?lDHQD``DM(0CAR*@(H*P?{E@*R;B-xDN3dF7ZYf@);X zW3$M;+K?-jD0E}`J&R9-kyohSqqQ4vnq(r`hb)f_~84ALoSuEXA*q8 zsPIawmSdY#@yc=ougiiKyBTsmw{9y44!MqFWTyDt!Ejf7{mjfLEXkk_UPjXq0QhQWKvHVOcK7)$dAQQ&7l1&Vh5Cc9sYDIVU z?9Xnr<~s48jQRdTllpLu=t{lY5Q{r|>_9p|I<38mEr;6qLY#=paC}5|S*{ZOS$aU} zG_%TaHBG8%g#h2(n|!!8vX7a#-v{QD!snkSL{9fp+0EQB`}Uloy>aL+3uow&z|oH~ zSf_X0siBU63z2ya&byah+YuU@rt}ETJjh$;05y}166WO% zMQi%Oe0_{0jmTAP?Y&<#4`E$#Oqa#-hG8(Se|S^XTDRb;#7>=3t`okyeAn^^Y__f2 zK0sw(6QO2YHyMTd63r)t_!qJV2_#|n`J5anr5^4_u=Nhn4dCiFms?I@sbz8FscVo~ ztH{Q#rdKD1ZU?jUu*{qtw4&v`SU3^M5Y4+02Xu(*!0UKa%g1$Eo+$05M$!F`hBYM!VIqZgw@Zdr#jA)^z&>Jb{(HO&g|vkz1@ zaubHi1YM?@#Y*ioL%G?DS?iQSEr(xtWXJ@`+e?Nf({*JW^+9uL6CK6lC7PKQzf$n( zSPfT*6>@7vW_zt>5K~k4I6(NYsjlgzsqE}=ws)F^2muW4z51ZYh*&5qiAVdLcfC$d zPL2gVI_rI44h`RYZEdX)B_YAI(MsVkCc_Rel=8Mb2jU5Aj0Q?U_Le6#E5lLS8?|tTVPRQE?ZF-cQdW3jW1R3y$@>zxa#>|%^*)LM+|Dm)n_6$I?}<0JmT?zuP0k-Fi+}Gbx&+ zPM<)&^|`x`1MQ&M;7`u{Wf->RpMr)S} z>}_DOC;bZtLUnhR)dCZ$&t|9sFOG?#wQGxqJ$5oG8H%KBVZRSlp7h!GL6NoyyPjgY zEd`bqD{=g(!eI0~ub}D!8ckOi4rlb>vAIv>yw|1^iS6jZDUWq;K@pdQuXrK4!V+^# zoO@rIThD3_?q_0sA46*qPdcbJ0b@h!dIh4qc-X&3Zdghyxi3o-69+!fcf@qR zp4Z!h)~AJz=dYRphxI{X`x%?2jO>cOX_>hfkUUT2He~-q%s7 zCVspaJ%Xzkh>~bQ;c`SH8L>IT;-xX>L5(3q74Zmyy-r_8#jtoR5al{?aqht5;JXVN5T>88lOT(gW0-}g+pdxuNw12O~y$SSUW_tSPbLOC*GVJl; z%1RQ~V8Nl5#sQMCwY@+J@fhyE=8J2>#zhhARgI+1HyEl%N2teQupa_v?n|4eJ#|kp z@t(rbpwEBwe8)LS7vx~c@khDp+hzGw2>qj1}tN#z6b@lmuUy%_!@0e{Ql z$3?!}rRhY6S+mrqZDTdCrQYh#2egpFVP7$*X63ner4RTF?-b*+V5_{3mjH0`HBU9g z(u>XeLVo@Tzn}=y<2rkrJ-BPQxNEIQR_jZSLNtr4S5Q(?(rxJ(#d5IjmWFDkD=&R_ zb_@Jx@p8bAY}w|BFNJsyY776 zXZx4u>RP|UFwH_kOjkyp7ts6m<|MY|{YVC*46RYf2f*E!%yy;;FFq$Y)FnqvEn)LI zU`}cJEqnx7RWC_p$P5u-o$tdCzphtA*=&#Z5D2I}QMlE>gc}RU;W|1R{ie)v`K$+|pp)#fMSp=6w#?1pAO!^yZMaR0`VkWS zyu(pqo2KBN+Na&NYLaBakY`2ku<>>X65B0e;5EEgQeqz6Dtr-2B7q4M$OneAcOu8X zhJxT1N*~7aB~ETmO);W`mKH=?NE%afMpx8SvESUnrUmfxc@S(|72TX}ge*`#L6n2m z!vi*H$0dM42PZ3r9k7lM9S`Lij6@2zxWO1RK+IXS?9It%a@P7d1J?GX9m@Y0w!kpx%pLDN#t@Pg&Tnv z;pcTOsF&@q`O1dEh>0-__^FpVTXmzgV#|>E0QZpOG`tF>+P_K=pk8^tD4mc@`Cio_XWv^{(kfEI!RSYZ*J+6WasxU zeIwbU-@o*VWLkc|KKxskNN-NEkz|+j`ZCGu|Nfl^A4sNz^ya?{AnHx}^WPEuJqfb^ zr0DNa`2MG8e~;onQ}Lgv_$>?nIh?;b@t;p7g|*0W{C|upnq<7gjWiSe{yr5lhNSa5 Zm3LYA_n3&S`pCb^NGaaUx}*2}{{fI3q@(}< literal 0 HcmV?d00001 diff --git a/pages/01.blog/tech-saviours-org-nz-online-de-why/item.de.md b/pages/01.blog/tech-saviours-org-nz-online-de-why/item.de.md new file mode 100644 index 0000000..22730d3 --- /dev/null +++ b/pages/01.blog/tech-saviours-org-nz-online-de-why/item.de.md @@ -0,0 +1,38 @@ +--- +title: 'TECH SAVIOURS .ORG, .NZ, .ONLINE, .DE ... Warum?' +taxonomy: + category: + - news + tag: + - 'TECH SAVIOURS' +aura: + author: dan +media_order: techsaviours-hierarchy.png +published: false +--- + +# Hierarchie von TECH SAVIOURS + +1. [techsaviours.org](https://techsaviours.org) +2. [techsaviours.online](https://techsaviours.online) +3. [techsaviours.nz](https://techsaviours.nz) +4. [tech-saviours.de](https://tech-saviours.de) + +Nun, eigentlich ist nur .ORG so etwas wie an erster Stelle. Du kannst wählen, was für dich wichtig ist. +Das kann für manche verwirrend sein, aber es gibt einen triftigen Grund für all dies. Wenn wir uns nur für eine Domäne entscheiden müssten, welche wäre es dann? .ORG oder .ONLINE? Wir haben es unten beschrieben. + +# Community - _.ORG_ +"Sharing is caring" ist eine art Redewendung, die sehr wichtig ist. Ohne die gemeinsame Nutzung von Wissen und Diensten wäre es nicht wirklich möglich, ein angemessenes Datenschutzziel zu erreichen. Um eine freie Welt für alle zu erreichen, braucht es offene Codes, Vertrauen und mehr Auswahlmöglichkeiten. +Deshalb wollen wir dir die Möglichkeit geben, deinen eigenen Server einzurichten und andere Online-Dienste zu nutzen, die nicht Facebook, Google, Apple, Microsoft, ... heißen. +Es gibt andere Dienste/Software/Unternehmen, die deine persönlichen Daten nicht sammeln, und wir können dir einen Weg zeigen, von dem du vielleicht nicht einmal wusstest, dass er existiert. +TECH **SAVIOURS** _.ORG_ ist ein weiterer Teil der vielen verschiedenen Datenschutz-Communities da draußen. Deine Möglichkeiten werden also immer größer und größer. + +# Lokale Unterstützung - _.NZ_ & _.DE_ +Wir wollten spezifische Domains für unseren lokalen Support, der sich in Neuseeland und Deutschland befindet. Für eine angemessene Vermarktung/Werbung wollten wir vertrauenswürdige Domains für die einzelnen Länder haben - .DE & .NZ. +Alles unter einer Domain zu haben, kann zu Konflikten führen. Das gilt nicht nur für die Sprache. Deshalb halten wir alles getrennt, um unsere lokalen Informationen nur für die spezifischen Länder/Domains zu nutzen. + +# Rest of the world - _.ONLINE_ +Wenn du in einem Land lebst, das nicht unter [Lokale Unterstützung](#lokale-unterstuetzung-nz-de) aufgeführt ist, und nicht die [Zeit oder das Wissen](#community-org) hast, um deinen eigenen Server zu erstellen, können wir dir dabei helfen, aber nur online. +Ein weiterer Grund ist, dass die Werbung in anderen Ländern mit .DE oder .NZ unseriös und verwirrend ist. + +Ich hoffe, dies hilft ein wenig zu verstehen, wie TECH **SAVIOURS** aufgebaut ist. Wenn du noch Fragen hast, schick uns einfach eine E-Mail. \ No newline at end of file diff --git a/pages/01.blog/tech-saviours-org-nz-online-de-why/item.en.md b/pages/01.blog/tech-saviours-org-nz-online-de-why/item.en.md new file mode 100644 index 0000000..008b8da --- /dev/null +++ b/pages/01.blog/tech-saviours-org-nz-online-de-why/item.en.md @@ -0,0 +1,38 @@ +--- +title: 'TECH SAVIOURS .ORG, .NZ, .ONLINE, .DE ... Why?' +taxonomy: + category: + - news + tag: + - 'TECH SAVIOURS' +aura: + author: dan +media_order: techsaviours-hierarchy.png +published: false +--- + +# Hierarchy of TECH SAVIOURS + +1. [techsaviours.org](https://techsaviours.org) +2. [techsaviours.online](https://techsaviours.online) +3. [techsaviours.nz](https://techsaviours.nz) +4. [tech-saviours.de](https://tech-saviours.de) + +Well, actually only .ORG is something like at the first place. You can choose whatever is important for you. +This can be confusing for some, but there is a valid reason for all of this. If we would choose only one domain, which one would it be? .ORG or .ONLINE? We described it below. + +# Community - _.ORG_ +Sharing is caring is a phrase that is very important. Without sharing of knowledge and services, it would not really be possible to achieve an adequate data privacy goal. Reaching an open world for everyone, it needs open codes, trust and more options to choose from. +So we want to give you the opportunity to set up your own server and use other online services not called Facebook, Google, Apple, Microsoft, ... . +There are other services/software/companies that won't collect your personal data and we can show you a way that you may not even have known that it exists. +TECH **SAVIOURS** _.ORG_ is another part of many different privacy communities out there. So your options are getting just bigger and bigger. + +# Local Support - _.NZ_ & _.DE_ +We wanted to have specific domains for our local support, which are located in New Zealand and Germany. For proper marketing/advertising we wanted to have trusted domains for the specific countries - .DE & .NZ. +Having everything under one domain can create conflicts. Which is not only the language. So we keep everything separate to keep our local information for the specific countries/domain only. + +# Rest of the world - _.ONLINE_ +If you live in a country not listed under [local support](#local-support-nz-de) and don't have the [time or knowledge](#community-org) to create your own server, we can help you with that, but only online. +Another reason is that advertising in other countries with .DE or .NZ is untrustworthy and confusing. + +I hope this helps a little to understand how TECH **SAVIOURS** is structured. If you still have questions, just send us an email. \ No newline at end of file diff --git a/pages/01.blog/tech-saviours-org-nz-online-de-why/techsaviours-hierarchy.png b/pages/01.blog/tech-saviours-org-nz-online-de-why/techsaviours-hierarchy.png new file mode 100755 index 0000000000000000000000000000000000000000..ac949ca8944c5f1dd090909e573f520e7942ea3c GIT binary patch literal 85417 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
?kyQa!Ja_tFf$y;C_Xe@m$$ZH=);f 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' => 'Next page', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php new file mode 100644 index 0000000..213849d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://onhax.net/process-lasso-8-9-1-4-pro-key-portable-is-here-latest', + 'body' => array( + '//div[@class="postcontent"]', + ), + 'strip' => array( + '//*[@class="sharedaddy sd-sharing-enabled"]', + '//*[@class="yarpp-related"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php new file mode 100644 index 0000000..7382612 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.onlinekosten.de/news/android-8-0-die-neuen-features-im-ueberblick_209619.html?utm_source=rss&utm_medium=feed&utm_campaign=android-8-0-die-neuen-features-im-ueberblick', + 'body' => array( + '//p[@class="cms-widget_article_lead"]', + '//img[@class="bec_img"]', + '//div[@class="cms-widget_article_body"]', + ), + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php new file mode 100644 index 0000000..f66ac4b --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php @@ -0,0 +1,24 @@ + array( + '%.*%' => array( + 'test_url' => 'http://onmilwaukee.com/movies/articles/downerspelunking.html', + 'body' => array( + '//article[contains(@class, "show")]', + ), + 'strip' => array( + '//h1', + '//div[contains(@class,"-ad")]', + '//div[contains(@class,"_ad")]', + '//div[@id="pub_wrapper"]', + '//div[contains(@class,"share_tools")]', + '//div[@class="clearfix"]', + '//div[contains(@class,"image_control")]', + '//section[@class="ribboned"]', + '//div[contains(@class,"sidebar")]', + '//aside[@class="article_tag_list"]', + '//section[contains(@id,"more_posts")]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php new file mode 100644 index 0000000..84f2bee --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.openculture.com/2017/03/are-we-living-inside-a-computer-simulation-watch-the-simulation-argument.html', + 'body' => array( + '//div[@class="entry"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php new file mode 100644 index 0000000..1fb7722 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.opennet.ru/opennews/art.shtml?num=46549', + 'body' => array( + '//*[@id="r_memo"]', + ), + 'strip' => array( + ), + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php new file mode 100644 index 0000000..94139a7 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.openrightsgroup.org/blog/2014/3-days-to-go-till-orgcon2014', + 'body' => array( + '//div[contains(@class, "content")]/div', + ), + 'strip' => array( + '//h2[1]', + '//div[@class="info"]', + '//div[@class="tags"]', + '//div[@class="comments"]', + '//div[@class="breadcrumbs"]', + '//h1[@class="pageTitle"]', + '//p[@class="bookmarkThis"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php new file mode 100644 index 0000000..60f3577 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php @@ -0,0 +1,22 @@ + array( + '%.*%' => array( + 'test_url' => 'http://opensource.com/life/15/10/how-internet-things-will-change-way-we-think', + 'body' => array( + '//div[@id="article-template"]', + ), + 'strip' => array( + '//div[contains(@class,"os-article__sidebar")]', + '//div[@class="panel-pane pane-node-title"]', + '//div[@class="panel-pane pane-os-article-byline"]', + '//ul', + '//div[contains(@class,"-license")]', + '//div[contains(@class,"-tags")]', + '//div[@class="panel-pane pane-os-article-byline"]', + '//div[@class="os-article__content-below"]', + '//div[@id="comments"]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php new file mode 100644 index 0000000..3214c62 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%title="(.+)" */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php new file mode 100644 index 0000000..7bd9496 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.origo.hu/itthon/20171019-hamisan-tanuskodott-az-ugyved-ezert-nem-praktizalhat.html', + 'body' => array( + '//header[@id="article-head"]/h1', + '//article[@id="article-center"]' + ), + 'strip' => array( + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php new file mode 100644 index 0000000..1d1396c --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'http://osnews.com/story/28863/Google_said_to_be_under_US_antitrust_scrutiny_over_Android', + 'body' => array( + '//div[@class="newscontent1"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php new file mode 100644 index 0000000..b20bf41 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://pastebin.com/ed1pP9Ak', + 'body' => array( + '//div[@class="text"]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php new file mode 100644 index 0000000..f180aee --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.pcgameshardware.de/Dragon-Age-Thema-259929/News/Plaene-fuer-Teil-4-und-5-der-Serie-1235682/', + 'body' => array( + '//p[@class="introText"]', + '//figure[contains(@class, "articleBigTeaser")]', + '//div[@id="articleTextBody"]//p | //div[@id="articleTextBody"]//h2[@class="anchorHeadline"]', + ), + 'strip' => array( + '//p[@class="introText"]//time', + ) + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php new file mode 100644 index 0000000..ce4891d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php @@ -0,0 +1,9 @@ + array( + '%.*%' => array( + // the extra space is required to strip the title cleanly + '%title="(.+) " */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php new file mode 100644 index 0000000..dd39983 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php @@ -0,0 +1,21 @@ + array( + '%/news/.*%' => array( + 'test_url' => 'http://penny-arcade.com/news/post/2015/04/15/101-part-two', + 'body' => array( + '//*[@class="postBody"]/*', + ), + 'strip' => array( + ), + ), + '%/comic/.*%' => array( + 'test_url' => 'http://penny-arcade.com/comic/2015/04/15', + 'body' => array( + '//*[@id="comicFrame"]/a/img', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php new file mode 100644 index 0000000..fa9052e --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php @@ -0,0 +1,12 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.pixelbeat.org/programming/sigpipe_handling.html#1425573246', + 'body' => array( + '//div[@class="contentText"]', + ), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php new file mode 100644 index 0000000..5e48a6c --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'https://plus.google.com/+LarryPage/posts/Lh8SKC6sED1', + 'body' => array( + '//div[@role="article"]/div[contains(@class, "eE")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php new file mode 100644 index 0000000..801a281 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%( '$1$2$1bonus.png"/>', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php new file mode 100644 index 0000000..ad01dad --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.portfolio.hu/gazdasag/mennybe-vagy-pokolba-megy-ma-a-cseh-trump.265833.html', + 'body' => array( + '//div[@id="cikk"]/h1', + '//div[@class="smscontent"]' + ), + 'strip' => array( + '//div[@class="traderhirdetes ga_viewanalytics"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php new file mode 100644 index 0000000..bc76630 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.pro-linux.de/news/1/25252/chrome-62-erschienen.html', + 'body' => array( + '//div[@id="news"]', + ), + 'strip' => array( + '//h3[@class="topic"]', + '//h2[@class="title"]', + '//div[@class="picto"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php new file mode 100644 index 0000000..5dc8be8 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'https://publicpolicyforum.org/blog/going-extra-mile', + 'body' => array( + '//div[contains(@class,"field-name-post-date")]', + '//div[contains(@class,"field-name-body")]', + ), + 'strip' => array( + '//img[@src="http://publicpolicyforum.org/sites/default/files/logo3.jpg"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php new file mode 100644 index 0000000..bcfeeb9 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php @@ -0,0 +1,24 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.publy.ru/post/19988', + 'body' => array( + '//div[@class="singlepost"]', + ), + 'strip' => array( + '//script', + '//form', + '//style', + '//*[@class="featured"]', + '//*[@class="toc_white no_bullets"]', + '//*[@class="toc_title"]', + '//*[@class="pba"]', + '//*[@class="comments"]', + '//*[contains(@class, "g-single")]', + '//*[@class="ts-fab-wrapper"]', + '//*[contains(@class, "wp_rp_wrap")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php new file mode 100644 index 0000000..9fa5568 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'http://putaindecode.fr/posts/js/etat-lieux-js-modulaire-front/', + 'body' => array( + '//*[@class="putainde-Post-md"]', + ), + 'strip' => array( + '//*[contains(@class, "inlineimg")]', + '//*[contains(@class, "comment-respond")]', + '//header', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php new file mode 100644 index 0000000..343cd12 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'http://recode.net/2015/09/26/big-tech-rolls-out-red-carpet-for-indian-prime-minister-lobbies-behind-closed-doors/', + 'body' => array( + '//img[contains(@class,"attachment-large")]', + '//div[contains(@class,"postarea")]', + '//li[@class,"author"]', + ), + 'strip' => array( + '//script', + '//div[contains(@class,"sharedaddy")]', + '//div[@class="post-send-off"]', + '//div[@class="large-12 columns"]', + '//div[contains(@class,"inner-related-article")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php new file mode 100644 index 0000000..b97c73e --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'http://retractionwatch.com/2015/11/12/psychologist-jens-forster-settles-case-by-agreeing-to-2-retractions/', + 'body' => array( + '//*[@class="main"]', + '//*[@class="entry-content"]', + ), + 'strip' => array( + '//*[contains(@class, "sharedaddy")]', + '//*[contains(@class, "jp-relatedposts")]', + '//p[@class="p1"]', + ) + ) + ) +); + diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php new file mode 100644 index 0000000..7111078 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.rockpapershotgun.com/2016/08/26/the-divisions-expansions-delayed-to-improve-the-game/', + 'body' => array( + '//div[@class="entry"]', + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php new file mode 100644 index 0000000..cb9116a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://rue89.feedsportal.com/c/33822/f/608948/s/30999fa0/sc/24/l/0L0Srue890N0C20A130C0A80C30A0Cfaisait0Eboris0Eboillon0Eex0Esarko0Eboy0E350A0E0A0A0A0Eeuros0Egare0Enord0E245315/story01.htm', + 'body' => array( + '//*[@id="article"]/div[contains(@class, "content")]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php new file mode 100644 index 0000000..9915c23 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.rugbyrama.fr/rugby/top-14/2015-2016/top-14-hayman-coupe-du-monde-finale-2012-lutte.-voici-levan-chilachava-toulon_sto5283863/story.shtml', + 'body' => array( + '//div[@class="storyfull__content"]', + ), + 'strip' => array( + '//script', + '//form', + '//style', + '//*[@class="share-buttons"]', + '//*[@class="ad"]', + '//*[@class="hide-desktop"]', + '//*[@id="tracking_img"]', + ) + ) + ) +); \ No newline at end of file diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com new file mode 100644 index 0000000..37f43e9 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.salonkolumnisten.com/schulpolitik-niedersachsen/', + 'body' => array( + '//div[@id="main"]/div[contains(@class, "featimg")]', + '//div[@id="main"]/article/div[contains(@class, "entry-content")]', + ), + 'strip' => array( + '//div[@id="main"]/article/div[contains(@class, "entry-content")]/a[1]', + '//div[@id="main"]/article/div[contains(@class, "entry-content")]/a[1]', + ), + ), + ), +); + diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php new file mode 100644 index 0000000..d63fc11 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://satwcomic.com/day-at-the-beach', + 'body' => array( + '//div[@class="container"]/center/a/img', + '//span[@itemprop="articleBody"]', + ), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php new file mode 100644 index 0000000..fcf045f --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.science-skeptical.de/politik/diesel-die-lueckenmedien-im-glashaus-6/0016080/', + 'body' => array( + '//div[@class="pf-content"]', + ), + 'strip' => array( + '//div[contains(@class, "printfriendly")]', + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php new file mode 100644 index 0000000..7835fd9 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php @@ -0,0 +1,12 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.scrumalliance.org/community/articles/2015/march/an-introduction-to-agile-project-intake?feed=articles', + 'body' => array( + '//div[@class="article_content"]', + ), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php new file mode 100644 index 0000000..0104514 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.securityfocus.com/archive/1/540139', + 'body' => array( + '//div[@id="vulnerability"]', + '//div[@class="comments_reply"]', + ), + 'strip' => array( + '//span[@class="title"]', + '//div[@id="logo_new"]', + '//div[@id="bannerAd"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php new file mode 100644 index 0000000..f435417 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'body' => array( + '//div[@class="comicpane"]/a/img', + '//div[@class="entry"]', + ), + 'strip' => array(), + 'test_url' => 'http://sentfromthemoon.com/archives/1417', + ), + ), + 'filter' => array( + '%.*%' => array( + '%title="(.+)" */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php new file mode 100644 index 0000000..ab0eb7d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.sitepoint.com/creating-hello-world-app-swift/', + 'body' => array( + '//section[@class="article_body"]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php new file mode 100644 index 0000000..89ced8b --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'http://science.slashdot.org/story/15/04/20/0528253/pull-top-can-tabs-at-50-reach-historic-archaeological-status', + 'body' => array( + '//article/div[@class="body"] | //article[@class="layout-article"]/div[@class="elips"]', ), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php new file mode 100644 index 0000000..8c13c44 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php @@ -0,0 +1,19 @@ + array( + '%.*%' => array( + 'test_url' => 'http://smallhousebliss.com/2013/08/29/house-g-by-lode-architecture/', + 'body' => array( + '//div[@class="post-content"]', + ), + 'strip' => array( + '//*[contains(@class, "gallery")]', + '//*[contains(@class, "share")]', + '//*[contains(@class, "wpcnt")]', + '//*[contains(@class, "meta")]', + '//*[contains(@class, "postitle")]', + '//*[@id="nav-below"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php new file mode 100644 index 0000000..7463abc --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://smarthomewelt.de/apple-tv-amazon-echo-smart-home/', + 'body' => array('//div[@class="entry-inner"]/p | //div[@class="entry-inner"]/div[contains(@class,"wp-caption")]'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php new file mode 100644 index 0000000..cbe1072 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.smashingmagazine.com/2015/04/17/using-sketch-for-responsive-web-design-case-study/', + 'body' => array('//article[contains(@class,"post")]/p'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php new file mode 100644 index 0000000..42262dc --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.smbc-comics.com/comic/the-troll-toll', + 'body' => array( + '//div[@id="cc-comicbody"]', + '//div[@id="aftercomic"]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php new file mode 100644 index 0000000..b0fe655 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php @@ -0,0 +1,22 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.snopes.com/bacca-brides-on-tour/', + 'body' => array( + '//article', + ), + 'strip' => array( + '//span[@itemprop="author"]', + '//div[contains(@class,"author-")]', + '//h1', + '//style', + '//div[contains(@class,"socialShares")]', + '//div[contains(@class,"ad-unit")]', + '//aside', + '//div[contains(@class,"boomtrain")]', + '//footer' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php new file mode 100644 index 0000000..6448bb0 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php @@ -0,0 +1,21 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.soundandvision.com/content/james-guthrie-mixing-roger-waters-and-pink-floyd-51', + 'body' => array( + '//div[@id="left"]', + ), + 'strip' => array( + '//div[@class="meta"]', + '//div[@class="ratingsbox"]', + '//h1', + '//h2', + '//addthis', + '//comment-links', + '//div[@class="book-navigation"]', + '//div[@class="comment-links"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php new file mode 100644 index 0000000..b42c3aa --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.spiegel.de/politik/ausland/afrika-angola-geht-gegen-islam-vor-und-schliesst-moscheen-a-935788.html', + 'body' => array( + '//div[@class="spArticleContent"]/p | //div[@class="spArticleContent"]//img[@class="spResponsiveImage "]', + ), + 'strip' => array( + '//div[@class="author-details"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php new file mode 100644 index 0000000..8e410be --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.stereophile.com/content/2015-rocky-mountain-audio-fest-starts-friday', + 'body' => array( + '//div[@class="content clear-block"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php new file mode 100644 index 0000000..61182d7 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://stupidfox.net/134-sleepy-time', + 'body' => array( + '//div[@class="comicmid"]/center/a/img', + '//div[@class="stand_high"]', + ), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php new file mode 100644 index 0000000..6d74427 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.subtraction.com/2015/06/06/time-lapse-video-of-one-world-trade-center/', + 'body' => array('//article/div[@class="entry-content"]'), + 'strip' => array(), + ), + ), + 'filter' => array( + '%.*%' => array( + '%\+%' => '', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php new file mode 100644 index 0000000..90bde5a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://sz.de/1.2443161', + 'body' => array('//article[@id="sitecontent"]/section[@class="topenrichment"]//img | //article[@id="sitecontent"]/section[@class="body"]/section[@class="authors"]/preceding-sibling::*[not(contains(@class, "ad"))]'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php new file mode 100644 index 0000000..624ef90 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php @@ -0,0 +1,21 @@ + array( + '%.*%' => array( + 'test_url' => 'http://takprosto.cc/kokteyl-dlya-pohudeniya-v-domashnih-usloviyah/', + 'body' => array( + '//div[contains(@class, "entry-contentt")]', + ), + 'strip' => array( + '//script', + '//form', + '//style', + '//*[@class="views_post"]', + '//*[contains(@class, "mailchimp-box")]', + '//*[contains(@class, "essb_links")]', + '//*[contains(@rel, "nofollow")]', + '//*[contains(@class, "ads")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php new file mode 100644 index 0000000..230b791 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://techcrunch.com/2013/08/31/indias-visa-maze/', + 'body' => array( + '//div[contains(@class, "media-container")]', + '//div[contains(@class, "article-entry")]', + ), + 'strip' => array( + '//*[contains(@class, "module-crunchbase")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php new file mode 100644 index 0000000..3b01eb9 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://blog.the-ebook-reader.com/2015/09/25/kobo-glo-hd-and-kobo-touch-2-0-covers-and-cases-roundup/', + 'body' => array( + '//div[@class="entry"]', + ), + 'strip' => array( + '//div[@id="share"]', + '//div[contains(@class,"ItemCenter")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php new file mode 100644 index 0000000..bfad4ab --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php @@ -0,0 +1,23 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.theatlantic.com/politics/archive/2015/09/what-does-it-mean-to-lament-the-poor-inside-panem/407317/', + 'body' => array( + '//picture[@class="img"]', + '//figure/figcaption/span', + '//div/p[@itemprop="description"]', + '//div[@class="article-body"]', + '//ul[@class="photos"]', + ), + 'strip' => array( + '//aside[@class="callout"]', + '//span[@class="credit"]', + '//figcaption[@class="credit"]', + '//aside[contains(@class,"partner-box")]', + '//div[contains(@class,"ad")]', + '//a[contains(@class,"social-icon")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php new file mode 100644 index 0000000..fd4f3d5 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php @@ -0,0 +1,12 @@ + array( + '%/comic/.*%' => array( + 'test_url' => 'http://theawkwardyeti.com/comic/things-to-do/', + 'body' => array( + '//div[@id="comic"]' + ), + 'strip' => array() + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php new file mode 100644 index 0000000..c6ec5bf --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://thecodinglove.com/post/116897934767', + 'body' => array('//div[@class="bodytype"]'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php new file mode 100644 index 0000000..d2f840d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'body' => array( + '//div[@class="comicpane"]/a/img', + '//div[@class="entry"]', + ), + 'strip' => array(), + 'test_url' => 'http://thedoghousediaries.com/6023', + ), + ), + 'filter' => array( + '%.*%' => array( + '%title="(.+)" */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php new file mode 100644 index 0000000..f9b4637 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.thegamercat.com/comic/just-no/', + 'body' => array('//div[@id="comic"] | //div[@class="post-content"]/div[@class="entry"]/p'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php new file mode 100644 index 0000000..1e6735b --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php @@ -0,0 +1,19 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.thehindu.com/sci-tech/science/why-is-the-shape-of-cells-in-a-honeycomb-always-hexagonal/article7692306.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication', + 'body' => array( + '//div/img[@class="main-image"]', + '//div[@class="photo-caption"]', + '//div[@class="articleLead"]', + '//p', + '//span[@class="upper"]', + ), + 'strip' => array( + '//div[@id="articleKeywords"]', + '//div[@class="photo-source"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php new file mode 100644 index 0000000..c3ec250 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'www.thelocal.se/20161219/this-swede-can-memorize-hundreds-of-numbers-in-only-five-minutes', + 'body' => array( + '//div[@id="article-photo"]', + '//div[@id="article-description"]', + '//div[@id="article-body"]', + ), + 'strip' => array( + '//div[@id="article-info-middle"]', + ) + ) + ) +); + diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php new file mode 100644 index 0000000..bc47b27 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.themerepublic.net/2015/04/david-lopez-pitoko.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+blogspot%2FDngUJ+%28Theme+Republic%29&utm_content=FeedBurner', + 'body' => array('//*[@class="post-body"]'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php new file mode 100644 index 0000000..0f5bf75 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.themoscowtimes.com/business/article/535500.html', + 'body' => array( + '//div[@class="article_main_img"]', + '//div[@class="article_text"]', + ), + 'strip' => array( + '//div[@class="articlebottom"]', + '//p/b', + '//p/a[contains(@href, "/article.php?id=")]', + '//div[@class="disqus_wrap"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php new file mode 100644 index 0000000..7538170 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php @@ -0,0 +1,21 @@ + array( + '%.*%' => array( + 'test_url' => 'http://international.thenewslens.com/post/255032/', + 'body' => array( + '//div[@class="article-section"]', + ), + 'strip' => array( + '//div[contains(@class,"ad-")]', + '//div[@class="article-title-box"]', + '//div[@class="function-box"]', + '//p/span', + '//aside', + '//footer', + '//div[@class="article-infoBot-box"]', + '//div[contains(@class,"standard-container")]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php new file mode 100644 index 0000000..d06ed12 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%-150x150%' => '', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php new file mode 100644 index 0000000..acbfd36 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php @@ -0,0 +1,12 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.theonion.com/article/wild-eyed-jim-harbaugh-informs-players-they-must-k-51397?utm_medium=RSS&utm_campaign=feeds', + 'body' => array( + '//div[@class="content-masthead"]/figure/div/noscript/img', + '//div[@class="content-text"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php new file mode 100644 index 0000000..896365a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.theregister.co.uk/2017/10/21/purism_cleanses_laptops_of_intel_management_engine/', + 'body' => array( + '//div[@id="article"]', + ), + 'strip' => array( + '//div[@class="byline_and_share"]', + '//div[@class="social_btns alt_colour dcl"]', + '//div[@class="promo_article"]', + '//div[@id="article_body_btm"]', + '//p[@class="wptl btm"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php new file mode 100644 index 0000000..1163b34 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php @@ -0,0 +1,22 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.thestandard.com.hk/breaking_news_detail.asp?id=67156', + 'body' => array( + '//table/tr/td/span[@class="bodyCopy"]', + ), + 'strip' => array( + '//script', + '//br', + '//map[@name="gif_bar"]', + '//img[contains(@usemap,"gif_bar")]', + '//a', + '//span[@class="bodyHeadline"]', + '//i', + '//b', + '//table', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php new file mode 100644 index 0000000..09e876d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.theverge.com/2017/11/11/16624298/mindhunter-netflix-show-david-fincher-review', + 'body' => array( + '//figure[@class="e-image e-image--hero"]/span[@class="e-image__inner"]', + '//div[@class="c-entry-content"]', + ), + 'strip' => array( + '//div[@class="c-related-list"]', + '//div[@class="c-page-title"]', + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php new file mode 100644 index 0000000..4af6196 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'body' => array( + '//img[@id="cc-comic"]', + ), + 'test_url' => 'http://www.threepanelsoul.com/comic/uncloaking', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php new file mode 100644 index 0000000..6fba3df --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php @@ -0,0 +1,22 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.tichyseinblick.de/daili-es-sentials/jamaika-reaktionen-der-enttaeuschten/', + 'body' => array( + '//article' + ), + 'strip' => array( + '//header', + '//footer', + '//div[@class="mod-cad2"]', + '//ul[contains(@class, "social")]', + '//div[@class="rty-pop-up"]', + '//div[@class="pagelink"]', + '//div[@id="reward"]', + '//div[@class="rty-block-plista"]' + ) + ), + ), +); + diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php new file mode 100644 index 0000000..1924680 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://timesofindia.indiatimes.com/city/mangaluru/Adani-UPCL-to-release-CSR-grant-of-Rs-3-74-crore-to-YellurGram-Panchayat/articleshow/50512116.cms', + 'body' => array( + '//div[@class="article_content clearfix"]', + '//section[@class="highlight clearfix"]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php new file mode 100644 index 0000000..f2e009d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'http://totalcar.hu/tesztek/2017/10/21/veteran_fiat-abarth_1000tc_1968/', + 'body' => array( + '//div[@class="content-title"]', + '//div[@class="lead-container"]/div[@class="lead"]', + '//div[@class="cikk-torzs"]' + ), + 'strip' => array( + '//span[@class="gallery_title newline"]', + '//div[@class="social-stripe cikk-bottom-box"]', + '//div[@class="cikk-bottom-text-ad"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php new file mode 100644 index 0000000..97a0da0 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.tozsdeforum.hu/szemelyes-penzugyek/napi-penzugyek/ezek-a-legnepszerubb-turistacelpontok-voltal-mar-mindenhol-87181.html', + 'body' => array( + '//header/h1', + '//div[@class="title_img"]', + '//article/div[@class="tf-post"]/div[@class="p"]/p|//article/div[@class="tf-post"]/div[@class="p"]/h3|//article/div[@class="tf-post"]/div[@class="p"]/blockquote' + ), + 'strip' => array( + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php new file mode 100644 index 0000000..4ee4fcd --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php @@ -0,0 +1,15 @@ + array( + '%^/blog.*%' => array( + 'test_url' => 'http://travel-dealz.de/blog/venere-gutschein/', + 'body' => array('//div[@class="post-entry"]'), + 'strip' => array( + '//*[@id="jp-relatedposts"]', + '//*[@class="post-meta"]', + '//*[@class="post-data"]', + '//*[@id="author-meta"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php new file mode 100644 index 0000000..3ab8ca4 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'http://travelo.hu/csaladbarat/2017/10/20/mar_csak_egy_het_es_kezdodik_az_oszi_szunet/', + 'body' => array( + '//div[@id="content"]/h1', + '//div[@id="kopf"]', + '//div[@id="szoveg"]' + ), + 'strip' => array( + '//div[@class="goAdverticum"]', + '//h1[@class="border"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php new file mode 100644 index 0000000..55eb7e0 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.treehugger.com/uncategorized/top-ten-posts-week-bunnies-2.html', + 'body' => array( + '//div[contains(@class, "promo-image")]', + '//div[contains(@id, "entry-body")]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php new file mode 100644 index 0000000..3214c62 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%title="(.+)" */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php new file mode 100644 index 0000000..7e39145 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'https://tutorialzine.com/2017/10/15-interesting-javascript-and-css-libraries-for-october-2017', + 'body' => array( + '//article' + ), + 'strip' => array( + '//div[@class="article__header"]', + '//div[@class="article__share"]', + '//div[@class="article__footer"]', + '//div[@id="article__related-articles"]', + '//div[@class="webappstudio-animation"]', + '//div[@class="ad-container adsbygoogle hidden-xs hidden-sm"]', + '//script' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php new file mode 100644 index 0000000..79f4f62 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%http://www.twogag.com/comics-rss/([^.]+)\\.jpg%' => 'http://www.twogag.com/comics/$1.jpg', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php new file mode 100644 index 0000000..3428fcb --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php @@ -0,0 +1,10 @@ + array( + '%.*%' => array( + 'test_url' => 'http://twokinds.keenspot.com/archive.php?p=0', + 'body' => array('//*[@class="comic"]/div/a/img | //*[@class="comic"]/div/img | //*[@id="cg_img"]/img | //*[@id="cg_img"]/a/img'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php new file mode 100644 index 0000000..8b15900 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://undeadly.org/cgi?action=article&sid=20141101181155', + 'body' => array( + '/html/body/table[3]/tbody/tr/td[1]/table[2]/tr/td[1]', + ), + 'strip' => array( + '//font', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php new file mode 100644 index 0000000..ec8d1a1 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.upi.com/Top_News/US/2015/09/26/Tech-giants-Hollywood-stars-among-guests-at-state-dinner-for-Chinas-Xi-Jinping/4541443281006/', + 'body' => array( + '//div[@class="img"]', + '//div/article[@itemprop="articleBody"]', + ), + 'strip' => array( + '//div[@align="center"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php new file mode 100644 index 0000000..edd6aa4 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php @@ -0,0 +1,27 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.usatoday.com/story/life/music/2017/02/13/things-you-should-know-happened-grammy-awards-2017/97833734/', + 'body' => array( + '//div[@itemprop="articleBody"]', + ), + 'strip' => array( + '//script', + '//h1', + '//iframe', + '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', + '//div[@class="close-wrap"]', + '//div[contains(@class,"ui-video-wrapper")]', + '//div[contains(@class,"media-mob")]', + '//div[contains(@class,"left-mob")]', + '//div[contains(@class,"nerdbox")]', + '//div[contains(@class,"oembed-asset")]', + '//*[contains(@class,"share")]', + '//div[contains(@class,"gallery-asset")]', + '//div[contains(@class,"oembed-asset")]', + '//div[@class="article-print-url"]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php new file mode 100644 index 0000000..a6d49f2 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php @@ -0,0 +1,12 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.version2.dk/artikel/surface-pro-2-fungerer-bedre-til-arbejde-end-fornoejelse-55195', + 'body' => array( + '//section[contains(@class, "teaser")]', + '//section[contains(@class, "body")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php new file mode 100644 index 0000000..acd68c0 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.vezess.hu/hirek/2017/10/20/audi-a7-2018-bemutato/', + 'body' => array( + '//article[@id="news"]/h1', + '//article[@id="news"]/h2', + '//article[@id="news"]/p[@class="lead"]', + '//article[@id="news"]/p[@class="main-pic responsive-img-container"]', + '//div[@class="article-body"]' + ), + 'strip' => array( + '//div[@class="info-bar"]', + '//ul[@class="breadcrumb"]', + '//div[@class="embed-link ce_widget"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php new file mode 100644 index 0000000..b2830a3 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php @@ -0,0 +1,15 @@ + array( + '%/comics.*%' => array( + 'test_url' => 'http://www.vgcats.com/comics/?strip_id=358', + 'body' => array('//*[@align="center"]/img'), + 'strip' => array(), + ), + '%/super.*%' => array( + 'test_url' => 'http://www.vgcats.com/super/?strip_id=84', + 'body' => array('//*[@align="center"]/p/img'), + 'strip' => array(), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php new file mode 100644 index 0000000..b9bef7a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.vuxml.org/freebsd/a5f160fa-deee-11e4-99f8-080027ef73ec.html', + 'body' => array( + '//body', + ), + 'strip' => array( + '//h1', + '//div[@class="blurb"]', + '//hr', + '//p[@class="copyright"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php new file mode 100644 index 0000000..58aceea --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php @@ -0,0 +1,27 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.wausaudailyherald.com/story/news/2017/04/01/hundreds-gather-remember-attorney-killed-shooting-spree/99826062/?from=global&sessionKey=&autologin=', + 'body' => array( + '//div[@itemprop="articleBody"]', + ), + 'strip' => array( + '//h1', + '//iframe', + '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', + '//div[@class="close-wrap"]', + '//div[contains(@class,"ui-video-wrapper")]', + '//div[contains(@class,"media-mob")]', + '//div[contains(@class,"left-mob")]', + '//div[contains(@class,"nerdbox")]', + '//p/span', + '//div[contains(@class,"oembed-asset")]', + '//*[contains(@class,"share")]', + '//div[contains(@class,"gallery-asset")]', + '//div[contains(@class,"oembed-asset")]', + '//div[@class="article-print-url"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php new file mode 100644 index 0000000..83a2ebe --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'https://www.welt.de/debatte/kommentare/article169740590/Bloss-keine-sozialdemokratische-Konsenssause.html', + 'body' => array( + '//main/article/header/div/div[contains(@class, "c-summary")]/div', + '//main/article/header/div[3]/div/figure/div/div/div/picture[1]', + '//main/article/header/div[3]/div/figure/figcaption/child::*', + '//main/article/div[contains(@class, "c-article-text")]' + ), + 'strip' => array( + '//*[contains(@class, "c-inline-element--has-commercials")]', + '//*[contains(@class, "c-inline-teaser")]', + '//figure[contains(@class, "c-video-element")]', + '//main/article/div[contains(@class, "c-article-text")]/div[@class="c-inline-element"]/div[contains(@class, "c-image-element")]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php new file mode 100644 index 0000000..adcf417 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.westfalen-blatt.de/OWL/Lokales/Kreis-Hoexter/Warburg/3024113-Polizei-in-Warburg-Hier-waren-keine-kriminellen-Profis-am-Werk-Wurstautomat-Sprengung-mit-Polen-Boellern', + 'body' => array( + '//div[contains(@class, "articleimage")]', + '//div[@class="attribute-short"]', + '//div[@class="attribute-long"]', + ), + 'strip' => array( + '//div[@class="fb-post"]' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php new file mode 100644 index 0000000..98fc368 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php @@ -0,0 +1,33 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.bbc.co.uk/news/world-middle-east-23911833', + 'body' => array( + '//div[@class="story-body__inner"] | //div[@class="article"]', + '//div[@class="indPost"]', + ), + 'strip' => array( + '//form', + '//div[@id="headline"]', + '//*[@class="warning"]', + '//span[@class="off-screen"]', + '//span[@class="story-image-copyright"]', + '//ul[@class="story-body__unordered-list"]', + '//div[@class="ad_wrapper"]', + '//div[@id="article-sidebar"]', + '//div[@class="data-table-outer"]', + '//*[@class="story-date"]', + '//*[@class="story-header"]', + '//figure[contains(@class,"has-caption")]', + '//*[@class="story-related"]', + '//*[contains(@class, "byline")]', + '//p[contains(@class, "media-message")]', + '//*[contains(@class, "story-feature")]', + '//*[@id="video-carousel-container"]', + '//*[@id="also-related-links"]', + '//*[contains(@class, "share") or contains(@class, "hidden") or contains(@class, "hyper")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php new file mode 100644 index 0000000..41ef68d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.bdgest.com/chronique-6027-BD-Adrastee-Tome-2.html', + 'body' => array( + '//*[contains(@class, "chronique")]', + ), + 'strip' => array( + '//*[contains(@class, "post-review")]', + '//*[contains(@class, "footer-review")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php new file mode 100644 index 0000000..63ca069 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php @@ -0,0 +1,23 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.bgr.in/news/xiaomi-redmi-3-with-13-megapixel-camera-snapdragon-616-launched-price-specifications-and-features/', + 'body' => array( + '//div[@class="article-content"]', + ), + 'strip' => array( + '//*[@class="article-meta"]', + '//*[@class="contentAdsense300"]', + '//*[@class="iwpl-social-hide"]', + '//iframe[@class="iframeads"]', + '//*[@class="disqus_thread"]', + '//*[@class="outb-mobile OUTBRAIN"]', + '//*[@class="wdt_smart_alerts"]', + '//*[@class="footnote"]', + '//*[@id="gadget-widget"]', + '//header[@class="article-title entry-header"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php new file mode 100644 index 0000000..0acc44e --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.businessweek.com/articles/2013-09-18/elon-musks-hyperloop-will-work-says-some-very-smart-software', + 'body' => array( + '//div[@id="lead_graphic"]', + '//div[@id="article_body"]', + ), + 'strip' => array( + '//*[contains(@class, "related_item")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php new file mode 100644 index 0000000..31d03ed --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php @@ -0,0 +1,24 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.cnn.com/2013/08/31/world/meast/syria-civil-war/index.html?hpt=hp_t1', + 'body' => array( + '//div[@class="cnn_strycntntlft"]', + ), + 'strip' => array( + '//div[@class="cnn_stryshrwdgtbtm"]', + '//div[@class="cnn_strybtmcntnt"]', + '//div[@class="cnn_strylftcntnt"]', + '//div[contains(@class, "cnnGalleryContainer")]', + '//div[contains(@class, "cnn_strylftcexpbx")]', + '//div[contains(@class, "articleGalleryNavContainer")]', + '//div[contains(@class, "cnnArticleGalleryCaptionControl")]', + '//div[contains(@class, "cnnArticleGalleryNavPrevNextDisabled")]', + '//div[contains(@class, "cnnArticleGalleryNavPrevNext")]', + '//div[contains(@class, "cnn_html_media_title_new")]', + '//div[contains(@id, "disqus")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php new file mode 100644 index 0000000..1535e43 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php @@ -0,0 +1,21 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.developpez.com/actu/81757/Mozilla-annonce-la-disponibilite-de-Firefox-36-qui-passe-au-HTTP-2-et-permet-la-synchronisation-de-son-ecran-d-accueil/', + 'body' => array( + '//*[@itemprop="articleBody"]', + ), + 'strip' => array( + '//form', + '//div[@class="content"]/img', + '//a[last()]/following-sibling::*', + '//*[contains(@class,"actuTitle")]', + '//*[contains(@class,"date")]', + '//*[contains(@class,"inlineimg")]', + '//*[@id="signaler"]', + '//*[@id="signalerFrame"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php new file mode 100644 index 0000000..263f075 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php @@ -0,0 +1,12 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.egscomics.com/index.php?id=1690', + 'title' => '/html/head/title', + 'body' => array( + '//img[@id="comic"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php new file mode 100644 index 0000000..c948c77 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.fakingnews.firstpost.com/2016/01/engineering-student-creates-record-in-a-decade-becomes-the-first-to-completely-exhaust-ball-pen-refill/', + 'body' => array( + '//div[@class="entry"]', + ), + 'strip' => array( + '//*[@class="socialshare_bar"]', + '//*[@class="authorbox"]', + '//*[@class="cf5_rps"]', + '//*[@class="60563 fb-comments fb-social-plugin"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php new file mode 100644 index 0000000..fd16ed5 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php @@ -0,0 +1,20 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.forbes.com/sites/andygreenberg/2013/09/05/follow-the-bitcoins-how-we-got-busted-buying-drugs-on-silk-roads-black-market/', + 'body' => array( + '//div[@id="leftRail"]/div[contains(@class, body)]', + ), + 'strip' => array( + '//aside', + '//div[contains(@class, "entity_block")]', + '//div[contains(@class, "vestpocket") and not contains(@class, "body")]', + '//div[contains(@style, "display")]', + '//div[contains(@id, "comment")]', + '//div[contains(@class, "widget")]', + '//div[contains(@class, "pagination")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php new file mode 100644 index 0000000..f7ec0d8 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.franceculture.fr/emission-culture-eco-la-finance-aime-toujours-la-france-2016-01-08', + 'body' => array( + '//div[@class="text-zone"]', + ), + 'strip' => array( + '//ul[@class="tags"]', + ), + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php new file mode 100644 index 0000000..ea94a0f --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php @@ -0,0 +1,19 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.futura-sciences.com/magazines/espace/infos/actu/d/astronautique-curiosity-franchi-succes-dune-dingo-gap-52289/#xtor=RSS-8', + 'body' => array( + '//div[contains(@class, "content fiche-")]', + ), + 'strip' => array( + '//h1', + '//*[contains(@class, "content-date")]', + '//*[contains(@class, "diaporama")]', + '//*[contains(@class, "slider")]', + '//*[contains(@class, "cartouche")]', + '//*[contains(@class, "noprint")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php new file mode 100644 index 0000000..3d0b6c7 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.geekculture.com/joyoftech/joyarchives/2180.html', + 'body' => array( + '//p[contains(@class,"Maintext")][2]/a/img[contains(@src,"joyimages")]', + ), + 'strip' => array(), + ), + ), +); + diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php new file mode 100644 index 0000000..6879e76 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.howtogeek.com/235283/what-is-a-wireless-hard-drive-and-should-i-get-one/', + 'body' => array( + '//div[@class="thecontent"]', + ), + 'strip' => array( + '//*[@class="relatedside"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php new file mode 100644 index 0000000..dcb7e48 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.lepoint.fr/c-est-arrive-aujourd-hui/19-septembre-1783-pour-la-premiere-fois-un-mouton-un-canard-et-un-coq-s-envoient-en-l-air-devant-louis-xvi-18-09-2012-1507704_494.php', + 'body' => array( + '//article', + ), + 'strip' => array( + '//*[contains(@class, "info_article")]', + '//*[contains(@class, "fildariane_titre")]', + '//*[contains(@class, "entete2_article")]', + '//*[contains(@class, "signature_article")]', + '//*[contains(@id, "share")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php new file mode 100644 index 0000000..0137e20 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php @@ -0,0 +1,25 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.lesnumeriques.com/blender/kitchenaid-diamond-5ksb1585-p27473/test.html', + 'body' => array( + '//*[@id="product-content"]', + '//*[@id="news-content"]', + '//*[@id="article-content"]', + ), + 'strip' => array( + '//form', + '//div[contains(@class, "price-v4"])', + '//div[contains(@class, "authors-and-date")]', + '//div[contains(@class, "mini-product")]', + '//div[@id="articles-related-authors"]', + '//div[@id="tags-socials"]', + '//div[@id="user-reviews"]', + '//div[@id="product-reviews"]', + '//div[@id="publication-breadcrumbs-and-date"]', + '//div[@id="publication-breadcrumbs-and-date"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php new file mode 100644 index 0000000..60bc1bd --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php @@ -0,0 +1,13 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.mac4ever.com/actu/87392_video-quand-steve-jobs-et-bill-gates-jouaient-au-bachelor-avec-le-mac', + 'body' => array( + '//div[contains(@class, "news-news-content")]', + ), + 'strip' => array( + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php new file mode 100644 index 0000000..a274564 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php @@ -0,0 +1,18 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.makeuseof.com/tag/having-problems-with-audio-in-windows-10-heres-a-likely-fix/', + 'body' => array( + '//div[@class="entry"]', + ), + 'strip' => array( + '//*[@class="new_sharebar"]', + '//*[@class="author"]', + '//*[@class="wdt_grouvi"]', + '//*[@class="wdt_smart_alerts"]', + '//*[@class="modal fade grouvi"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php new file mode 100644 index 0000000..5f5e987 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php @@ -0,0 +1,11 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.monsieur-le-chien.fr/index.php?planche=672', + 'body' => array( + '//img[starts-with(@src, "i/planches/")]', + ), + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php new file mode 100644 index 0000000..ecc0213 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php @@ -0,0 +1,28 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.npr.org/blogs/thesalt/2013/09/17/223345977/auto-brewery-syndrome-apparently-you-can-make-beer-in-your-gut', + 'body' => array( + '//article[contains(@class,"story")]', + ), + 'strip' => array( + '//div[@class="story-tools"]', + '//h3[@class="slug"]', + '//div[@class="storytitle"]', + '//div[@id="story-meta"]', + '//a[@id="mainContent"]', + '//div[@class="credit-caption"]', + '//div[@class="enlarge_html"]', + '//button', + '//div[contains(@id,"pullquote")]', + '//div[contains(@class,"internallink")]', + '//div[contains(@class,"video")]', + '//div[@class="simplenodate"]', + '//div[contains(@class,"share-")]', + '//div[@class="tags"]', + '//aside' + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php new file mode 100644 index 0000000..fe4971c --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.numerama.com/sciences/125959-recherches-ladn-recompensees-nobel-de-chimie.html', + 'body' => array( + '//article', + ), + 'strip' => array( + '//footer', + '//section[@class="related-article"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php new file mode 100644 index 0000000..320c214 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php @@ -0,0 +1,14 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.oneindia.com/india/b-luru-govt-likely-remove-word-eunuch-from-sec-36-a-karnataka-police-act-1981173.html', + 'body' => array( + '//div[@class="ecom-ad-content"]', + ), + 'strip' => array( + '//*[@id="view_cmtns"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php new file mode 100644 index 0000000..9e467ed --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.pseudo-sciences.org/spip.php?article2275', + 'body' => array( + '//div[@id="art_main"]', + ), + 'strip' => array( + '//div[@id="art_print"]', + '//div[@id="art_chapo"]', + '//img[@class="puce"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php new file mode 100644 index 0000000..ae7a93a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php @@ -0,0 +1,16 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.sciencemag.org/news/2016/01/could-bright-foamy-wak$', + 'body' => array( + '//div[@class="row--hero"]', + '//article[contains(@class,"primary")]', + ), + 'strip' => array( + '//header[@class="article__header"]', + '//footer[@class="article__foot"]', + ), + ), + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php new file mode 100644 index 0000000..8c8dc89 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php @@ -0,0 +1,19 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.slate.fr/monde/77034/allemagne-2013-couacs-campagne', + 'body' => array( + '//div[@class="article_content"]', + ), + 'strip' => array( + '//*[@id="slate_associated_bn"]', + '//*[@id="ligatus-article"]', + '//*[@id="article_sidebar"]', + '//div[contains(@id, "reseaux")]', + '//*[contains(@class, "smart") or contains(@class, "article_tags") or contains(@class, "article_reactions")]', + '//*[contains(@class, "OUTBRAIN") or contains(@class, "related_item") or contains(@class, "share")]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php new file mode 100644 index 0000000..0747d0f --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php @@ -0,0 +1,15 @@ + array( + '%.*%' => array( + 'test_url' => 'http://www.universfreebox.com/article/24305/4G-Bouygues-Telecom-lance-une-vente-flash-sur-son-forfait-Sensation-3Go', + 'body' => array( + '//div[@id="corps_corps"]', + ), + 'strip' => array( + '//*[@id="formulaire"]', + '//*[@id="commentaire"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php new file mode 100644 index 0000000..316c265 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php @@ -0,0 +1,41 @@ + array( + '%^/zeit-magazin.*%' => array( + 'test_url' => 'http://www.zeit.de/zeit-magazin/2015/15/pegida-kathrin-oertel-lutz-bachmann', + 'body' => array( + '//article[@class="article"]', + ), + 'strip' => array( + '//header/div/h1', + '//header/div/div[@class="article__head__subtitle"]', + '//header/div/div[@class="article__column__author"]', + '//header/div/div[@class="article__column__author"]', + '//header/div/span[@class="article__head__meta-wrap"]', + '//form', + '//style', + '//div[contains(@class, "ad-tile")]', + '//div[@class="iqd-mobile-adplace"]', + '//div[@id="iq-artikelanker"]', + '//div[@id="js-social-services"]', + '//section[@id="js-comments"]', + '//aside', + ), + ), + '%.*%' => array( + 'test_url' => 'http://www.zeit.de/politik/ausland/2015-04/thessaloniki-krise-griechenland-yannis-boutaris/', + 'body' => array( + '//div[@class="article-body"]', + ), + 'strip' => array( + '//*[@class="articleheader"]', + '//*[@class="excerpt"]', + '//div[contains(@class, "ad")]', + '//div[@itemprop="video"]', + '//*[@class="articlemeta"]', + '//*[@class="articlemeta-clear"]', + '//*[@class="zol_inarticletools"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php new file mode 100644 index 0000000..8495726 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php @@ -0,0 +1,8 @@ + array( + '%.*%' => array( + '%alt="(.+)" */>%' => '/>
$1', + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php new file mode 100644 index 0000000..9fd83f1 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php @@ -0,0 +1,21 @@ + array( + '%.*%' => array( + 'test_url' => 'https://ymatuhin.ru/tools/git-default-editor/', + 'body' => array( + '//section', + ), + 'strip' => array( + "//script", + "//style", + "//h1", + "//time", + "//aside", + "/html/body/section/ul", + "//amp-iframe", + "/html/body/section/h4" + ), + ) + ) +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php new file mode 100644 index 0000000..36d3bdf --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php @@ -0,0 +1,19 @@ + array( + '%.*%' => array( + 'test_url' => 'https://zarojel.hu/meg-egyszer-a-foldi-ugyrol-is/', + 'body' => array( + '//div[@class="entry-category"]/h1', + '//div[@class="entry-content"]/div[@class="vc_row wpb_row vc_row-fluid"]' + ), + 'strip' => array( + '//ins[@class="adsbygoogle"]', + '//script', + '//figcaption', + '//p[contains(text(),"Kapcsolódó")]', + '//div[@class="wpb_wrapper"]/p[@class="entry-title"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php new file mode 100644 index 0000000..79b35dd --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php @@ -0,0 +1,23 @@ + array( + '%.*%' => array( + 'test_url' => 'http://zdnet.com.feedsportal.com/c/35462/f/675637/s/4a33c93e/sc/11/l/0L0Szdnet0N0Carticle0Cchina0Eus0Eagree0Eon0Ecybercrime0Ecooperation0Eamid0Econtinued0Etension0C0Tftag0FRSSbaffb68/story01.htm', + 'body' => array( + '//p[@class="summary"]', + '//div[contains(@class,"storyBody")]', + ), + 'strip' => array( + '//*[contains(@class,"ad-")]', + '//p/span', + '//script', + '//p[@class="summary"]', + '//div[contains(@class,"relatedContent")]', + '//div[contains(@class,"loader")]', + '//p[@class="photoDetails"]', + '//div[@class="thumbnailSlider"]', + '//div[@class="shortcodeGalleryWrapper"]', + ), + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php new file mode 100644 index 0000000..3e38781 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php @@ -0,0 +1,17 @@ + array( + '%.*%' => array( + 'test_url' => 'https://zoom.hu/2017/10/20/mar-nem-nyomoznak-a-vegrehajtok-botranyai-miatt', + 'body' => array( + '//div[@class="title-wrapper"]/h1', + '//div[@class="entry-excerpt"]', + '//div[@class="thumbnail-wrapper"]', + '//div[@id="entry-content-id"]' + ), + 'strip' => array( + '//div[@class="place first normal"]' + ) + ), + ), +); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php new file mode 100644 index 0000000..0f74b3d --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php @@ -0,0 +1,281 @@ +dom = XmlParser::getHtmlDocument(''.$html); + $this->xpath = new DOMXPath($this->dom); + } + + /** + * Get the relevant content with the list of potential attributes. + * + * @return string + */ + public function execute() + { + $content = $this->findContentWithCandidates(); + + if (strlen($content) < 200) { + $content = $this->findContentWithArticle(); + } + + if (strlen($content) < 50) { + $content = $this->findContentWithBody(); + } + + return $this->stripGarbage($content); + } + + /** + * Find content based on the list of tag candidates. + * + * @return string + */ + public function findContentWithCandidates() + { + foreach ($this->candidatesAttributes as $candidate) { + Logger::setMessage(get_called_class().': Try this candidate: "'.$candidate.'"'); + + $nodes = $this->xpath->query('//*[(contains(@class, "'.$candidate.'") or @id="'.$candidate.'") and not (contains(@class, "nav") or contains(@class, "page"))]'); + + if ($nodes !== false && $nodes->length > 0) { + Logger::setMessage(get_called_class().': Find candidate "'.$candidate.'"'); + + return $this->dom->saveXML($nodes->item(0)); + } + } + + return ''; + } + + /** + * Find
tag. + * + * @return string + */ + public function findContentWithArticle() + { + $nodes = $this->xpath->query('//article'); + + if ($nodes !== false && $nodes->length > 0) { + Logger::setMessage(get_called_class().': Find
tag'); + + return $this->dom->saveXML($nodes->item(0)); + } + + return ''; + } + + /** + * Find tag. + * + * @return string + */ + public function findContentWithBody() + { + $nodes = $this->xpath->query('//body'); + + if ($nodes !== false && $nodes->length > 0) { + Logger::setMessage(get_called_class().' Find '); + + return $this->dom->saveXML($nodes->item(0)); + } + + return ''; + } + + /** + * Strip useless tags. + * + * @param string $content + * @return string + */ + public function stripGarbage($content) + { + $dom = XmlParser::getDomDocument($content); + + if ($dom !== false) { + $xpath = new DOMXPath($dom); + + $this->stripTags($xpath); + $this->stripAttributes($dom, $xpath); + + $content = $dom->saveXML($dom->documentElement); + } + + return $content; + } + + /** + * Remove blacklisted tags. + * + * @param DOMXPath $xpath + */ + public function stripTags(DOMXPath $xpath) + { + foreach ($this->stripTags as $tag) { + $nodes = $xpath->query('//'.$tag); + + if ($nodes !== false && $nodes->length > 0) { + Logger::setMessage(get_called_class().': Strip tag: "'.$tag.'"'); + + foreach ($nodes as $node) { + $node->parentNode->removeChild($node); + } + } + } + } + + /** + * Remove blacklisted attributes. + * + * @param DomDocument $dom + * @param DOMXPath $xpath + */ + public function stripAttributes(DomDocument $dom, DOMXPath $xpath) + { + foreach ($this->stripAttributes as $attribute) { + $nodes = $xpath->query('//*[contains(@class, "'.$attribute.'") or contains(@id, "'.$attribute.'")]'); + + if ($nodes !== false && $nodes->length > 0) { + Logger::setMessage(get_called_class().': Strip attribute: "'.$attribute.'"'); + + foreach ($nodes as $node) { + if ($this->shouldRemove($dom, $node)) { + $node->parentNode->removeChild($node); + } + } + } + } + } + + /** + * Find link for next page of the article. + * + * @return string + */ + public function findNextLink() + { + return null; + } + + /** + * Return false if the node should not be removed. + * + * @param DomDocument $dom + * @param \DomNode $node + * @return bool + */ + public function shouldRemove(DomDocument $dom, $node) + { + $document_length = strlen($dom->textContent); + $node_length = strlen($node->textContent); + + if ($document_length === 0) { + return true; + } + + $ratio = $node_length * 100 / $document_length; + + if ($ratio >= 90) { + Logger::setMessage(get_called_class().': Should not remove this node ('.$node->nodeName.') ratio: '.$ratio.'%'); + + return false; + } + + return true; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php new file mode 100644 index 0000000..3ded4b1 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php @@ -0,0 +1,20 @@ +getRulesFileList($hostname); + + foreach ($this->getRulesFolders() as $folder) { + $rule = $this->loadRuleFile($folder, $files); + + if (!empty($rule)) { + return $rule; + } + } + } + + return array(); + } + + /** + * Get the list of possible rules file names for a given hostname. + * + * @param string $hostname Hostname + * @return array + */ + public function getRulesFileList($hostname) + { + $files = array($hostname); // subdomain.domain.tld + $parts = explode('.', $hostname); + $len = count($parts); + + if ($len > 2) { + $subdomain = array_shift($parts); + $files[] = implode('.', $parts); // domain.tld + $files[] = '.'.implode('.', $parts); // .domain.tld + $files[] = $subdomain; // subdomain + } elseif ($len === 2) { + $files[] = '.'.implode('.', $parts); // .domain.tld + $files[] = $parts[0]; // domain + } + + return $files; + } + + /** + * Load a rule file from the defined folder. + * + * @param string $folder Rule directory + * @param array $files List of possible file names + * @return array + */ + public function loadRuleFile($folder, array $files) + { + foreach ($files as $file) { + $filename = $folder.'/'.$file.'.php'; + if (file_exists($filename)) { + Logger::setMessage(get_called_class().' Load rule: '.$file); + + return include $filename; + } + } + + return array(); + } + + /** + * Get the list of folders that contains rules. + * + * @return array + */ + public function getRulesFolders() + { + $folders = array(); + + if ($this->config !== null && $this->config->getGrabberRulesFolder() !== null) { + $folders[] = $this->config->getGrabberRulesFolder(); + } + + $folders[] = __DIR__ . '/../Rules'; + + return $folders; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php new file mode 100644 index 0000000..9beb59c --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php @@ -0,0 +1,102 @@ +rules = $rules; + $this->dom = XmlParser::getHtmlDocument(''.$html); + $this->xpath = new DOMXPath($this->dom); + } + + /** + * Get the relevant content with predefined rules. + * + * @return string + */ + public function execute() + { + $this->stripTags(); + + return $this->findContent(); + } + + /** + * Remove HTML tags. + */ + public function stripTags() + { + if (isset($this->rules['strip']) && is_array($this->rules['strip'])) { + foreach ($this->rules['strip'] as $pattern) { + $nodes = $this->xpath->query($pattern); + + if ($nodes !== false && $nodes->length > 0) { + foreach ($nodes as $node) { + $node->parentNode->removeChild($node); + } + } + } + } + } + + /** + * Fetch content based on Xpath rules. + */ + public function findContent() + { + $content = ''; + if (isset($this->rules['body']) && is_array($this->rules['body'])) { + foreach ($this->rules['body'] as $pattern) { + $nodes = $this->xpath->query($pattern); + + if ($nodes !== false && $nodes->length > 0) { + foreach ($nodes as $node) { + $content .= $this->dom->saveXML($node); + } + } + } + } + + return $content; + } + + /** + * Fetch next link based on Xpath rules. + * + * @return string + */ + public function findNextLink() + { + if (isset($this->rules['next_page']) && is_array($this->rules['next_page'])) { + foreach ($this->rules['next_page'] as $pattern) { + $nodes = $this->xpath->query($pattern); + if ($nodes !== false && $nodes->length > 0) { + foreach ($nodes as $node) { + return $node->getAttribute('href'); + } + } + } + } + return null; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php new file mode 100644 index 0000000..29383b2 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php @@ -0,0 +1,282 @@ +enableCandidateParser = false; + return $this; + } + + /** + * Get encoding. + * + * @return string + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Set encoding. + * + * @param string $encoding + * + * @return Scraper + */ + public function setEncoding($encoding) + { + $this->encoding = $encoding; + + return $this; + } + + /** + * Get URL to download. + * + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * Set URL to download. + * + * @param string $url URL + * + * @return Scraper + */ + public function setUrl($url) + { + $this->url = $url; + + return $this; + } + + /** + * Return true if the scraper found relevant content. + * + * @return bool + */ + public function hasRelevantContent() + { + return !empty($this->content); + } + + /** + * Get relevant content. + * + * @return string + */ + public function getRelevantContent() + { + return $this->content; + } + + /** + * Get raw content (unfiltered). + * + * @return string + */ + public function getRawContent() + { + return $this->html; + } + + /** + * Set raw content (unfiltered). + * + * @param string $html + * + * @return Scraper + */ + public function setRawContent($html) + { + $this->html = $html; + + return $this; + } + + /** + * Get filtered relevant content. + * + * @return string + */ + public function getFilteredContent() + { + $filter = Filter::html($this->content, $this->url); + $filter->setConfig($this->config); + + return $filter->execute(); + } + + /** + * Download the HTML content. + * + * @return bool + */ + public function download() + { + if (!empty($this->url)) { + + // Clear everything + $this->html = ''; + $this->content = ''; + $this->encoding = ''; + + try { + $client = Client::getInstance(); + $client->setConfig($this->config); + $client->setTimeout($this->config->getGrabberTimeout()); + $client->setUserAgent($this->config->getGrabberUserAgent()); + $client->execute($this->url); + + $this->url = $client->getUrl(); + $this->html = $client->getContent(); + $this->encoding = $client->getEncoding(); + + return true; + } catch (ClientException $e) { + Logger::setMessage(get_called_class().': '.$e->getMessage()); + } + } + + return false; + } + + /** + * Execute the scraper. + * + * @param string $pageContent + * @param int $recursionDepth + */ + public function execute($pageContent = '', $recursionDepth = 0) + { + $this->html = ''; + $this->encoding = ''; + $this->content = ''; + $this->download(); + $this->prepareHtml(); + + $parser = $this->getParser(); + + if ($parser !== null) { + $maxRecursions = $this->config->getMaxRecursions(); + if(!isset($maxRecursions)){ + $maxRecursions = 25; + } + $pageContent .= $parser->execute(); + // check if there is a link to next page and recursively get content (max 25 pages) + if((($nextLink = $parser->findNextLink()) !== null) && $recursionDepth < $maxRecursions){ + $nextLink = Url::resolve($nextLink,$this->url); + $this->setUrl($nextLink); + $this->execute($pageContent,$recursionDepth+1); + } + else{ + $this->content = $pageContent; + } + Logger::setMessage(get_called_class().': Content length: '.strlen($this->content).' bytes'); + } + } + + /** + * Get the parser. + * + * @return ParserInterface + */ + public function getParser() + { + $ruleLoader = new RuleLoader($this->config); + $rules = $ruleLoader->getRules($this->url); + + if (!empty($rules['grabber'])) { + Logger::setMessage(get_called_class().': Parse content with rules'); + + foreach ($rules['grabber'] as $pattern => $rule) { + $url = new Url($this->url); + $sub_url = $url->getFullPath(); + + if (preg_match($pattern, $sub_url)) { + Logger::setMessage(get_called_class().': Matched url '.$sub_url); + return new RuleParser($this->html, $rule); + } + } + } elseif ($this->enableCandidateParser) { + Logger::setMessage(get_called_class().': Parse content with candidates'); + } + + return new CandidateParser($this->html); + } + + /** + * Normalize encoding and strip head tag. + */ + public function prepareHtml() + { + $html_encoding = XmlParser::getEncodingFromMetaTag($this->html); + + $this->html = Encoding::convert($this->html, $html_encoding ?: $this->encoding); + $this->html = Filter::stripHeadTags($this->html); + + Logger::setMessage(get_called_class().': HTTP Encoding "'.$this->encoding.'" ; HTML Encoding "'.$html_encoding.'"'); + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php new file mode 100644 index 0000000..12eccfd --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php @@ -0,0 +1,175 @@ +title = $title; + return $this; + } + + /** + * Get title + * + * @access public + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set feed URL + * + * @access public + * @param string $feedUrl + * @return Subscription + */ + public function setFeedUrl($feedUrl) + { + $this->feedUrl = $feedUrl; + return $this; + } + + /** + * Get feed URL + * + * @access public + * @return string + */ + public function getFeedUrl() + { + return $this->feedUrl; + } + + /** + * Set site URL + * + * @access public + * @param string $siteUrl + * @return Subscription + */ + public function setSiteUrl($siteUrl) + { + $this->siteUrl = $siteUrl; + return $this; + } + + /** + * Get site URL + * + * @access public + * @return string + */ + public function getSiteUrl() + { + return $this->siteUrl; + } + + /** + * Set category + * + * @access public + * @param string $category + * @return Subscription + */ + public function setCategory($category) + { + $this->category = $category; + return $this; + } + + /** + * Get category + * + * @access public + * @return string + */ + public function getCategory() + { + return $this->category; + } + + /** + * Set description + * + * @access public + * @param string $description + * @return Subscription + */ + public function setDescription($description) + { + $this->description = $description; + return $this; + } + + /** + * Get description + * + * @access public + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set type + * + * @access public + * @param string $type + * @return Subscription + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * Get type + * + * @access public + * @return string + */ + public function getType() + { + return $this->type; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php new file mode 100644 index 0000000..b173f89 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php @@ -0,0 +1,75 @@ +title = $title; + return $this; + } + + /** + * Get title + * + * @access public + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Add subscription + * + * @access public + * @param Subscription $subscription + * @return SubscriptionList + */ + public function addSubscription(Subscription $subscription) + { + $this->subscriptions[] = $subscription; + return $this; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php new file mode 100644 index 0000000..838e4cb --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php @@ -0,0 +1,204 @@ +subscriptionList = $subscriptionList; + } + + /** + * Get object instance + * + * @static + * @access public + * @param SubscriptionList $subscriptionList + * @return SubscriptionListBuilder + */ + public static function create(SubscriptionList $subscriptionList) + { + return new static($subscriptionList); + } + + /** + * Build OPML feed + * + * @access public + * @param string $filename + * @return string + */ + public function build($filename = '') + { + $this->document = new DomDocument('1.0', 'UTF-8'); + $this->document->formatOutput = true; + + $opmlElement = $this->document->createElement('opml'); + $opmlElement->setAttribute('version', '1.0'); + + $headElement = $this->document->createElement('head'); + + if ($this->subscriptionList->getTitle() !== '') { + $titleElement = $this->document->createElement('title'); + $titleElement->appendChild($this->document->createTextNode($this->subscriptionList->getTitle())); + $headElement->appendChild($titleElement); + } + + $opmlElement->appendChild($headElement); + $opmlElement->appendChild($this->buildBody()); + $this->document->appendChild($opmlElement); + + if ($filename !== '') { + $this->document->save($filename); + return ''; + } + + return $this->document->saveXML(); + } + + /** + * Return true if the list has categories + * + * @access public + * @return bool + */ + public function hasCategories() + { + foreach ($this->subscriptionList->subscriptions as $subscription) { + if ($subscription->getCategory() !== '') { + return true; + } + } + + return false; + } + + /** + * Build OPML body + * + * @access protected + * @return DOMElement + */ + protected function buildBody() + { + $bodyElement = $this->document->createElement('body'); + + if ($this->hasCategories()) { + $this->buildCategories($bodyElement); + return $bodyElement; + } + + foreach ($this->subscriptionList->subscriptions as $subscription) { + $bodyElement->appendChild($this->buildSubscription($subscription)); + } + + return $bodyElement; + } + + /** + * Build categories section + * + * @access protected + * @param DOMElement $bodyElement + */ + protected function buildCategories(DOMElement $bodyElement) + { + $categories = $this->groupByCategories(); + + foreach ($categories as $category => $subscriptions) { + $bodyElement->appendChild($this->buildCategory($category, $subscriptions)); + } + } + + /** + * Build category tag + * + * @access protected + * @param string $category + * @param array $subscriptions + * @return DOMElement + */ + protected function buildCategory($category, array $subscriptions) + { + $outlineElement = $this->document->createElement('outline'); + $outlineElement->setAttribute('text', $category); + + foreach ($subscriptions as $subscription) { + $outlineElement->appendChild($this->buildSubscription($subscription)); + } + + return $outlineElement; + } + + /** + * Build subscription entry + * + * @access public + * @param Subscription $subscription + * @return DOMElement + */ + protected function buildSubscription(Subscription $subscription) + { + $outlineElement = $this->document->createElement('outline'); + $outlineElement->setAttribute('type', $subscription->getType() ?: 'rss'); + $outlineElement->setAttribute('text', $subscription->getTitle() ?: $subscription->getFeedUrl()); + $outlineElement->setAttribute('xmlUrl', $subscription->getFeedUrl()); + + if ($subscription->getTitle() !== '') { + $outlineElement->setAttribute('title', $subscription->getTitle()); + } + + if ($subscription->getDescription() !== '') { + $outlineElement->setAttribute('description', $subscription->getDescription()); + } + + if ($subscription->getSiteUrl() !== '') { + $outlineElement->setAttribute('htmlUrl', $subscription->getSiteUrl()); + } + + return $outlineElement; + } + + /** + * Group subscriptions by category + * + * @access private + * @return array + */ + private function groupByCategories() + { + $categories = array(); + + foreach ($this->subscriptionList->subscriptions as $subscription) { + $categories[$subscription->getCategory()][] = $subscription; + } + + return $categories; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php new file mode 100644 index 0000000..9085588 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php @@ -0,0 +1,100 @@ +subscriptionList = new SubscriptionList(); + $this->data = trim($data); + } + + /** + * Get object instance + * + * @static + * @access public + * @param string $data + * @return SubscriptionListParser + */ + public static function create($data) + { + return new static($data); + } + + /** + * Parse a subscription list entry + * + * @access public + * @throws MalformedXmlException + * @return SubscriptionList + */ + public function parse() + { + $xml = XmlParser::getSimpleXml($this->data); + + if (! $xml || !isset($xml->head) || !isset($xml->body)) { + throw new MalformedXmlException('Unable to parse OPML file: invalid XML'); + } + + $this->parseTitle($xml->head); + $this->parseEntries($xml->body); + + return $this->subscriptionList; + } + + /** + * Parse title + * + * @access protected + * @param SimpleXMLElement $xml + */ + protected function parseTitle(SimpleXMLElement $xml) + { + $this->subscriptionList->setTitle((string) $xml->title); + } + + /** + * Parse entries + * + * @access protected + * @param SimpleXMLElement $body + */ + private function parseEntries(SimpleXMLElement $body) + { + foreach ($body->outline as $outlineElement) { + if (isset($outlineElement->outline)) { + $this->parseEntries($outlineElement); + } else { + $this->subscriptionList->subscriptions[] = SubscriptionParser::create($body, $outlineElement)->parse(); + } + } + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php new file mode 100644 index 0000000..caff07c --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php @@ -0,0 +1,142 @@ +parentElement = $parentElement; + $this->outlineElement = $outlineElement; + $this->subscription = new Subscription(); + } + + /** + * Get object instance + * + * @static + * @access public + * @param SimpleXMLElement $parentElement + * @param SimpleXMLElement $outlineElement + * @return SubscriptionParser + */ + public static function create(SimpleXMLElement $parentElement, SimpleXMLElement $outlineElement) + { + return new static($parentElement, $outlineElement); + } + + /** + * Parse subscription entry + * + * @access public + * @return Subscription + */ + public function parse() + { + $this->subscription->setCategory($this->findCategory()); + $this->subscription->setTitle($this->findTitle()); + $this->subscription->setFeedUrl($this->findFeedUrl()); + $this->subscription->setSiteUrl($this->findSiteUrl()); + $this->subscription->setType($this->findType()); + $this->subscription->setDescription($this->findDescription()); + + return $this->subscription; + } + + /** + * Find category. + * + * @access protected + * @return string + */ + protected function findCategory() + { + return isset($this->parentElement['text']) ? (string) $this->parentElement['text'] : ''; + } + + /** + * Find title. + * + * @access protected + * @return string + */ + protected function findTitle() + { + return isset($this->outlineElement['title']) ? (string) $this->outlineElement['title'] : (string) $this->outlineElement['text']; + } + + /** + * Find feed url. + * + * @access protected + * @return string + */ + protected function findFeedUrl() + { + return (string) $this->outlineElement['xmlUrl']; + } + + /** + * Find site url. + * + * @access protected + * @return string + */ + protected function findSiteUrl() + { + return isset($this->outlineElement['htmlUrl']) ? (string) $this->outlineElement['htmlUrl'] : $this->findFeedUrl(); + } + + /** + * Find type. + * + * @access protected + * @return string + */ + protected function findType() + { + return isset($this->outlineElement['version']) ? (string) $this->outlineElement['version'] : + isset($this->outlineElement['type']) ? (string) $this->outlineElement['type'] : 'rss'; + } + + /** + * Find description. + * + * @access protected + * @return string + */ + protected function findDescription() + { + return isset($this->outlineElement['description']) ? (string) $this->outlineElement['description'] : $this->findTitle(); + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php new file mode 100644 index 0000000..34f3780 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php @@ -0,0 +1,65 @@ +helper = new AtomHelper($this->getDocument()); + + $this->feedElement = $this->getDocument()->createElement('feed'); + $this->feedElement->setAttributeNodeNS(new DomAttr('xmlns', 'http://www.w3.org/2005/Atom')); + + $generator = $this->getDocument()->createElement('generator', 'PicoFeed'); + $generator->setAttribute('uri', 'https://github.com/miniflux/picoFeed'); + $this->feedElement->appendChild($generator); + + $this->helper + ->buildTitle($this->feedElement, $this->feedTitle) + ->buildId($this->feedElement, $this->feedUrl) + ->buildDate($this->feedElement, $this->feedDate) + ->buildLink($this->feedElement, $this->siteUrl) + ->buildLink($this->feedElement, $this->feedUrl, 'self', 'application/atom+xml') + ->buildAuthor($this->feedElement, $this->authorName, $this->authorEmail, $this->authorUrl) + ; + + foreach ($this->items as $item) { + $this->feedElement->appendChild($item->build()); + } + + $this->getDocument()->appendChild($this->feedElement); + + if ($filename !== '') { + $this->getDocument()->save($filename); + } + + return $this->getDocument()->saveXML(); + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php new file mode 100644 index 0000000..def6b0b --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php @@ -0,0 +1,139 @@ +document = $document; + } + + /** + * Build node + * + * @access public + * @param DOMElement $element + * @param string $tag + * @param string $value + * @return AtomHelper + */ + public function buildNode(DOMElement $element, $tag, $value) + { + $node = $this->document->createElement($tag); + $node->appendChild($this->document->createTextNode($value)); + $element->appendChild($node); + return $this; + } + + /** + * Build title + * + * @access public + * @param DOMElement $element + * @param string $title + * @return AtomHelper + */ + public function buildTitle(DOMElement $element, $title) + { + return $this->buildNode($element, 'title', $title); + } + + /** + * Build id + * + * @access public + * @param DOMElement $element + * @param string $id + * @return AtomHelper + */ + public function buildId(DOMElement $element, $id) + { + return $this->buildNode($element, 'id', $id); + } + + /** + * Build date element + * + * @access public + * @param DOMElement $element + * @param DateTime $date + * @param string $type + * @return AtomHelper + */ + public function buildDate(DOMElement $element, DateTime $date, $type = 'updated') + { + return $this->buildNode($element, $type, $date->format(DateTime::ATOM)); + } + + /** + * Build link element + * + * @access public + * @param DOMElement $element + * @param string $url + * @param string $rel + * @param string $type + * @return AtomHelper + */ + public function buildLink(DOMElement $element, $url, $rel = 'alternate', $type = 'text/html') + { + $node = $this->document->createElement('link'); + $node->setAttribute('rel', $rel); + $node->setAttribute('type', $type); + $node->setAttribute('href', $url); + $element->appendChild($node); + + return $this; + } + + /** + * Build author element + * + * @access public + * @param DOMElement $element + * @param string $authorName + * @param string $authorEmail + * @param string $authorUrl + * @return AtomHelper + */ + public function buildAuthor(DOMElement $element, $authorName, $authorEmail, $authorUrl) + { + if (!empty($authorName)) { + $author = $this->document->createElement('author'); + $this->buildNode($author, 'name', $authorName); + + if (!empty($authorEmail)) { + $this->buildNode($author, 'email', $authorEmail); + } + + if (!empty($authorUrl)) { + $this->buildNode($author, 'uri', $authorUrl); + } + + $element->appendChild($author); + } + + return $this; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php new file mode 100644 index 0000000..dfdfe68 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php @@ -0,0 +1,63 @@ +itemElement = $this->feedBuilder->getDocument()->createElement('entry'); + $this->helper = new AtomHelper($this->feedBuilder->getDocument()); + + if (!empty($this->itemId)) { + $this->helper->buildId($this->itemElement, $this->itemId); + } else { + $this->helper->buildId($this->itemElement, $this->itemUrl); + } + + $this->helper + ->buildTitle($this->itemElement, $this->itemTitle) + ->buildLink($this->itemElement, $this->itemUrl) + ->buildDate($this->itemElement, $this->itemUpdatedDate, 'updated') + ->buildDate($this->itemElement, $this->itemPublishedDate, 'published') + ->buildAuthor($this->itemElement, $this->authorName, $this->authorEmail, $this->authorUrl) + ; + + if (!empty($this->itemSummary)) { + $this->helper->buildNode($this->itemElement, 'summary', $this->itemSummary); + } + + if (!empty($this->itemContent)) { + $node = $this->feedBuilder->getDocument()->createElement('content'); + $node->setAttribute('type', 'html'); + $node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent)); + $this->itemElement->appendChild($node); + } + + return $this->itemElement; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php new file mode 100644 index 0000000..cf9d024 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php @@ -0,0 +1,185 @@ +document = new DomDocument('1.0', 'UTF-8'); + $this->document->formatOutput = true; + } + + /** + * Get new object instance + * + * @access public + * @return static + */ + public static function create() + { + return new static(); + } + + /** + * Add feed title + * + * @access public + * @param string $title + * @return $this + */ + public function withTitle($title) + { + $this->feedTitle = $title; + return $this; + } + + /** + * Add feed url + * + * @access public + * @param string $url + * @return $this + */ + public function withFeedUrl($url) + { + $this->feedUrl = $url; + return $this; + } + + /** + * Add website url + * + * @access public + * @param string $url + * @return $this + */ + public function withSiteUrl($url) + { + $this->siteUrl = $url; + return $this; + } + + /** + * Add feed date + * + * @access public + * @param DateTime $date + * @return $this + */ + public function withDate(DateTime $date) + { + $this->feedDate = $date; + return $this; + } + + /** + * Add feed author + * + * @access public + * @param string $name + * @param string $email + * @param string $url + * @return $this + */ + public function withAuthor($name, $email = '', $url ='') + { + $this->authorName = $name; + $this->authorEmail = $email; + $this->authorUrl = $url; + return $this; + } + + /** + * Add feed item + * + * @access public + * @param ItemBuilder $item + * @return $this + */ + public function withItem(ItemBuilder $item) + { + $this->items[] = $item; + return $this; + } + + /** + * Get DOM document + * + * @access public + * @return DOMDocument + */ + public function getDocument() + { + return $this->document; + } + + /** + * Build feed + * + * @abstract + * @access public + * @param string $filename + * @return string + */ + abstract public function build($filename = ''); +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php new file mode 100644 index 0000000..86985bc --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php @@ -0,0 +1,209 @@ +feedBuilder = $feedBuilder; + } + + /** + * Get new object instance + * + * @access public + * @param FeedBuilder $feedBuilder + * @return static + */ + public static function create(FeedBuilder $feedBuilder) + { + return new static($feedBuilder); + } + + /** + * Add item title + * + * @access public + * @param string $title + * @return $this + */ + public function withTitle($title) + { + $this->itemTitle = $title; + return $this; + } + + /** + * Add item id + * + * @access public + * @param string $id + * @return $this + */ + public function withId($id) + { + $this->itemId = $id; + return $this; + } + + /** + * Add item url + * + * @access public + * @param string $url + * @return $this + */ + public function withUrl($url) + { + $this->itemUrl = $url; + return $this; + } + + /** + * Add item summary + * + * @access public + * @param string $summary + * @return $this + */ + public function withSummary($summary) + { + $this->itemSummary = $summary; + return $this; + } + + /** + * Add item content + * + * @access public + * @param string $content + * @return $this + */ + public function withContent($content) + { + $this->itemContent = $content; + return $this; + } + + /** + * Add item updated date + * + * @access public + * @param DateTime $date + * @return $this + */ + public function withUpdatedDate(DateTime $date) + { + $this->itemUpdatedDate = $date; + return $this; + } + + /** + * Add item published date + * + * @access public + * @param DateTime $date + * @return $this + */ + public function withPublishedDate(DateTime $date) + { + $this->itemPublishedDate = $date; + return $this; + } + + /** + * Add item author + * + * @access public + * @param string $name + * @param string $email + * @param string $url + * @return $this + */ + public function withAuthor($name, $email = '', $url ='') + { + $this->authorName = $name; + $this->authorEmail = $email; + $this->authorUrl = $url; + return $this; + } + + /** + * Build item + * + * @abstract + * @access public + * @return DOMElement + */ + abstract public function build(); +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php new file mode 100644 index 0000000..bc3f513 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php @@ -0,0 +1,76 @@ +helper = new Rss20Helper($this->getDocument()); + + $this->rssElement = $this->getDocument()->createElement('rss'); + $this->rssElement->setAttribute('version', '2.0'); + $this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:content', 'http://purl.org/rss/1.0/modules/content/')); + $this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:atom', 'http://www.w3.org/2005/Atom')); + + $this->channelElement = $this->getDocument()->createElement('channel'); + $this->helper + ->buildNode($this->channelElement, 'generator', 'PicoFeed (https://github.com/miniflux/picoFeed)') + ->buildTitle($this->channelElement, $this->feedTitle) + ->buildNode($this->channelElement, 'description', $this->feedTitle) + ->buildDate($this->channelElement, $this->feedDate) + ->buildAuthor($this->channelElement, 'webMaster', $this->authorName, $this->authorEmail) + ->buildLink($this->channelElement, $this->siteUrl) + ; + + $link = $this->getDocument()->createElement('atom:link'); + $link->setAttribute('href', $this->feedUrl); + $link->setAttribute('rel', 'self'); + $link->setAttribute('type', 'application/rss+xml'); + $this->channelElement->appendChild($link); + + foreach ($this->items as $item) { + $this->channelElement->appendChild($item->build()); + } + + $this->rssElement->appendChild($this->channelElement); + $this->getDocument()->appendChild($this->rssElement); + + if ($filename !== '') { + $this->getDocument()->save($filename); + } + + return $this->getDocument()->saveXML(); + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php new file mode 100644 index 0000000..72a19e5 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php @@ -0,0 +1,115 @@ +document = $document; + } + + /** + * Build node + * + * @access public + * @param DOMElement $element + * @param string $tag + * @param string $value + * @return $this + */ + public function buildNode(DOMElement $element, $tag, $value) + { + $node = $this->document->createElement($tag); + $node->appendChild($this->document->createTextNode($value)); + $element->appendChild($node); + return $this; + } + + /** + * Build title + * + * @access public + * @param DOMElement $element + * @param string $title + * @return $this + */ + public function buildTitle(DOMElement $element, $title) + { + return $this->buildNode($element, 'title', $title); + } + + /** + * Build date element + * + * @access public + * @param DOMElement $element + * @param DateTime $date + * @param string $type + * @return $this + */ + public function buildDate(DOMElement $element, DateTime $date, $type = 'pubDate') + { + return $this->buildNode($element, $type, $date->format(DateTime::RSS)); + } + + /** + * Build link element + * + * @access public + * @param DOMElement $element + * @param string $url + * @return $this + */ + public function buildLink(DOMElement $element, $url) + { + return $this->buildNode($element, 'link', $url); + } + + /** + * Build author element + * + * @access public + * @param DOMElement $element + * @param string $tag + * @param string $authorName + * @param string $authorEmail + * @return $this + */ + public function buildAuthor(DOMElement $element, $tag, $authorName, $authorEmail) + { + if (!empty($authorName)) { + $value = ''; + + if (!empty($authorEmail)) { + $value .= $authorEmail.' ('.$authorName.')'; + } else { + $value = $authorName; + } + + $this->buildNode($element, $tag, $value); + } + + return $this; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php new file mode 100644 index 0000000..125dc6a --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php @@ -0,0 +1,67 @@ +itemElement = $this->feedBuilder->getDocument()->createElement('item'); + $this->helper = new Rss20Helper($this->feedBuilder->getDocument()); + + if (!empty($this->itemId)) { + $guid = $this->feedBuilder->getDocument()->createElement('guid'); + $guid->setAttribute('isPermaLink', 'false'); + $guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemId)); + $this->itemElement->appendChild($guid); + } else { + $guid = $this->feedBuilder->getDocument()->createElement('guid'); + $guid->setAttribute('isPermaLink', 'true'); + $guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemUrl)); + $this->itemElement->appendChild($guid); + } + + $this->helper + ->buildTitle($this->itemElement, $this->itemTitle) + ->buildLink($this->itemElement, $this->itemUrl) + ->buildDate($this->itemElement, $this->itemPublishedDate) + ->buildAuthor($this->itemElement, 'author', $this->authorName, $this->authorEmail) + ; + + if (!empty($this->itemSummary)) { + $this->helper->buildNode($this->itemElement, 'description', $this->itemSummary); + } + + if (!empty($this->itemContent)) { + $node = $this->feedBuilder->getDocument()->createElement('content:encoded'); + $node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent)); + $this->itemElement->appendChild($node); + } + + return $this->itemElement; + } +} diff --git a/plugins/admin/vendor/p3k/picofeed/picofeed b/plugins/admin/vendor/p3k/picofeed/picofeed new file mode 100644 index 0000000..8f35737 --- /dev/null +++ b/plugins/admin/vendor/p3k/picofeed/picofeed @@ -0,0 +1,135 @@ +#!/usr/bin/env php +discover($url); + + $parser = $reader->getParser( + $resource->getUrl(), + $resource->getContent(), + $resource->getEncoding() + ); + + if ($disable_filtering) { + $parser->disableContentFiltering(); + } + + return $parser->execute(); + } + catch (PicoFeedException $e) { + echo 'Exception thrown ===> "'.$e->getMessage().'"'.PHP_EOL; + return false; + } +} + +function get_item($feed, $item_id) +{ + foreach ($feed->items as $item) { + if ($item->getId() === $item_id) { + echo $item; + echo "============= CONTENT ================\n"; + echo $item->getContent(); + echo "\n============= CONTENT ================\n"; + break; + } + } +} + +function dump_feed($url) +{ + $feed = get_feed($url); + echo $feed; +} + +function debug_feed($url) +{ + get_feed($url); + print_r(Logger::getMessages()); +} + +function dump_item($url, $item_id) +{ + $feed = get_feed($url); + + if ($feed !== false) { + get_item($feed, $item_id); + } +} + +function nofilter_item($url, $item_id) +{ + $feed = get_feed($url, true); + + if ($feed !== false) { + get_item($feed, $item_id); + } +} + +function grabber($url) +{ + $grabber = new Scraper(new Config); + $grabber->setUrl($url); + $grabber->execute(); + + print_r(Logger::getMessages()); + echo "============= CONTENT ================\n"; + echo $grabber->getRelevantContent().PHP_EOL; + echo "============= FILTERED ================\n"; + echo $grabber->getFilteredContent().PHP_EOL; +} + +function fetch_favicon($url) +{ + $favicon = new Favicon(); + echo $favicon->find($url) . PHP_EOL; +} + +// Parse command line arguments +if ($argc === 4) { + switch ($argv[1]) { + case 'item': + dump_item($argv[2], $argv[3]); + die; + case 'nofilter': + nofilter_item($argv[2], $argv[3]); + die; + } +} else if ($argc === 3) { + switch ($argv[1]) { + case 'feed': + dump_feed($argv[2]); + die; + case 'debug': + debug_feed($argv[2]); + die; + case 'grabber': + grabber($argv[2]); + die; + case 'favicon': + fetch_favicon($argv[2]); + die; + } +} + +printf("Usage:\n"); +printf("%s feed \n", $argv[0]); +printf("%s debug \n", $argv[0]); +printf("%s item \n", $argv[0]); +printf("%s nofilter \n", $argv[0]); +printf("%s grabber \n", $argv[0]); +printf("%s favicon \n", $argv[0]); diff --git a/plugins/admin/vendor/scssphp/scssphp/LICENSE.md b/plugins/admin/vendor/scssphp/scssphp/LICENSE.md new file mode 100644 index 0000000..afcfdfb --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/admin/vendor/scssphp/scssphp/README.md b/plugins/admin/vendor/scssphp/scssphp/README.md new file mode 100644 index 0000000..65bb93e --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/README.md @@ -0,0 +1,71 @@ +# scssphp +### + +![Build](https://github.com/scssphp/scssphp/workflows/CI/badge.svg) +[![License](https://poser.pugx.org/scssphp/scssphp/license)](https://packagist.org/packages/scssphp/scssphp) + +`scssphp` is a compiler for SCSS written in PHP. + +Checkout the homepage, , for directions on how to use. + +## Running Tests + +`scssphp` uses [PHPUnit](https://github.com/sebastianbergmann/phpunit) for testing. + +Run the following command from the root directory to run every test: + + vendor/bin/phpunit tests + +There are several tests in the `tests/` directory: + +* `ApiTest.php` contains various unit tests that test the PHP interface. +* `ExceptionTest.php` contains unit tests that test for exceptions thrown by the parser and compiler. +* `FailingTest.php` contains tests reported in Github issues that demonstrate compatibility bugs. +* `InputTest.php` compiles every `.scss` file in the `tests/inputs` directory + then compares to the respective `.css` file in the `tests/outputs` directory. +* `SassSpecTest.php` extracts tests from the `sass/sass-spec` repository. + +When changing any of the tests in `tests/inputs`, the tests will most likely +fail because the output has changed. Once you verify that the output is correct +you can run the following command to rebuild all the tests: + + BUILD=1 vendor/bin/phpunit tests + +This will compile all the tests, and save results into `tests/outputs`. It also +updates the list of excluded specs from sass-spec. + +To enable the full `sass-spec` compatibility tests: + + TEST_SASS_SPEC=1 vendor/bin/phpunit tests + +## Coding Standard + +`scssphp` source conforms to [PSR12](https://www.php-fig.org/psr/psr-12/). + +Run the following command from the root directory to check the code for "sniffs". + + vendor/bin/phpcs --standard=PSR12 --extensions=php bin src tests *.php + +## Static Analysis + +`scssphp` uses [phpstan](https://phpstan.org/) for static analysis. + +Run the following command from the root directory to analyse the codebase: + + make phpstan + +As most of the codebase is composed of legacy code which cannot be type-checked +fully, the setup contains a baseline file with all errors we want to ignore. In +particular, we ignore all errors related to not specifying the types inside arrays +when these arrays correspond to the representation of Sass values and Sass AST nodes +in the parser and compiler. +When contributing, the proper process to deal with static analysis is the following: + +1. Make your change in the codebase +2. Run `make phpstan` +3. Fix errors reported by phpstan when possible +4. Repeat step 2 and 3 until nothing gets fixed anymore at step 3 +5. Run `make phpstan-baseline` to regenerate the phpstan baseline + +Additions to the baseline will be reviewed to avoid ignoring errors that should have +been fixed. diff --git a/plugins/admin/vendor/scssphp/scssphp/bin/pscss b/plugins/admin/vendor/scssphp/scssphp/bin/pscss new file mode 100644 index 0000000..e622398 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/bin/pscss @@ -0,0 +1,244 @@ +#!/usr/bin/env php +parse($data)), true)); + + fwrite(STDERR, 'Warning: the --dump-tree option is deprecated. Use proper debugging tools instead.'); + + exit(); +} + +$scss = new Compiler(); + +if ($loadPaths) { + $scss->setImportPaths($loadPaths); +} + +if ($style) { + if ($style === OutputStyle::COMPRESSED || $style === OutputStyle::EXPANDED) { + $scss->setOutputStyle($style); + } else { + fwrite(STDERR, "WARNING: the $style style is deprecated.\n"); + $scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($style)); + } +} + +$outputFile = isset($arguments[1]) ? $arguments[1] : null; +$sourceMapFile = null; + +if ($sourceMap) { + $sourceMapOptions = array( + 'outputSourceFiles' => $embedSources, + ); + if ($embedSourceMap || $outputFile === null) { + $scss->setSourceMap(Compiler::SOURCE_MAP_INLINE); + } else { + $sourceMapFile = $outputFile . '.map'; + $sourceMapOptions['sourceMapWriteTo'] = $sourceMapFile; + $sourceMapOptions['sourceMapURL'] = basename($sourceMapFile); + $sourceMapOptions['sourceMapBasepath'] = getcwd(); + $sourceMapOptions['sourceMapFilename'] = basename($outputFile); + + $scss->setSourceMap(Compiler::SOURCE_MAP_FILE); + } + + $scss->setSourceMapOptions($sourceMapOptions); +} + +if ($encoding) { + $scss->setEncoding($encoding); +} + +try { + $result = $scss->compileString($data, $inputFile); +} catch (SassException $e) { + fwrite(STDERR, 'Error: '.$e->getMessage()."\n"); + exit(1); +} + +if ($outputFile) { + file_put_contents($outputFile, $result->getCss()); + + if ($sourceMapFile !== null && $result->getSourceMap() !== null) { + file_put_contents($sourceMapFile, $result->getSourceMap()); + } +} else { + echo $result->getCss(); +} diff --git a/plugins/admin/vendor/scssphp/scssphp/composer.json b/plugins/admin/vendor/scssphp/scssphp/composer.json new file mode 100644 index 0000000..86cd396 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/composer.json @@ -0,0 +1,108 @@ +{ + "name": "scssphp/scssphp", + "type": "library", + "description": "scssphp is a compiler for SCSS written in PHP.", + "keywords": ["css", "stylesheet", "scss", "sass", "less"], + "homepage": "http://scssphp.github.io/scssphp/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "homepage": "https://github.com/robocoder" + }, + { + "name": "Cédric Morin", + "email": "cedric@yterium.com", + "homepage": "https://github.com/Cerdic" + } + ], + "autoload": { + "psr-4": { "ScssPhp\\ScssPhp\\": "src/" } + }, + "autoload-dev": { + "psr-4": { "ScssPhp\\ScssPhp\\Tests\\": "tests/" } + }, + "require": { + "php": ">=5.6.0", + "ext-json": "*", + "ext-ctype": "*" + }, + "suggest": { + "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv", + "ext-iconv": "Can be used as fallback when ext-mbstring is not available" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4", + "sass/sass-spec": "*", + "squizlabs/php_codesniffer": "~3.5", + "symfony/phpunit-bridge": "^5.1", + "thoughtbot/bourbon": "^7.0", + "twbs/bootstrap": "~5.0", + "twbs/bootstrap4": "4.6.0", + "zurb/foundation": "~6.5" + }, + "repositories": [ + { + "type": "package", + "package": { + "name": "sass/sass-spec", + "version": "2021.09.15", + "source": { + "type": "git", + "url": "https://github.com/sass/sass-spec.git", + "reference": "eb2d7a0865c1faf0b55a39ff962b24aca9b4c955" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sass/sass-spec/zipball/eb2d7a0865c1faf0b55a39ff962b24aca9b4c955", + "reference": "eb2d7a0865c1faf0b55a39ff962b24aca9b4c955", + "shasum": "" + } + } + }, + { + "type": "package", + "package": { + "name": "thoughtbot/bourbon", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/thoughtbot/bourbon.git", + "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thoughtbot/bourbon/zipball/fbe338ee6807e7f7aa996d82c8a16f248bb149b3", + "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3", + "shasum": "" + } + } + }, + { + "type": "package", + "package": { + "name": "twbs/bootstrap4", + "version": "v4.6.0", + "source": { + "type": "git", + "url": "https://github.com/twbs/bootstrap.git", + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/6ffb0b48e455430f8a5359ed689ad64c1143fac2", + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2", + "shasum": "" + } + } + } + ], + "bin": ["bin/pscss"], + "config": { + "sort-packages": true + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/phpcs.xml.dist b/plugins/admin/vendor/scssphp/scssphp/phpcs.xml.dist new file mode 100644 index 0000000..b162dbd --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/phpcs.xml.dist @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/plugins/admin/vendor/scssphp/scssphp/scss.inc.php b/plugins/admin/vendor/scssphp/scssphp/scss.inc.php new file mode 100644 index 0000000..4598378 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/scss.inc.php @@ -0,0 +1,21 @@ + + * + * @internal + */ +class Range +{ + /** + * @var float|int + */ + public $first; + + /** + * @var float|int + */ + public $last; + + /** + * Initialize range + * + * @param integer|float $first + * @param integer|float $last + */ + public function __construct($first, $last) + { + $this->first = $first; + $this->last = $last; + } + + /** + * Test for inclusion in range + * + * @param integer|float $value + * + * @return boolean + */ + public function includes($value) + { + return $value >= $this->first && $value <= $this->last; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block.php b/plugins/admin/vendor/scssphp/scssphp/src/Block.php new file mode 100644 index 0000000..3ae49d0 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Block.php @@ -0,0 +1,73 @@ + + * + * @internal + */ +class Block +{ + /** + * @var string + */ + public $type; + + /** + * @var \ScssPhp\ScssPhp\Block + */ + public $parent; + + /** + * @var string + */ + public $sourceName; + + /** + * @var integer + */ + public $sourceIndex; + + /** + * @var integer + */ + public $sourceLine; + + /** + * @var integer + */ + public $sourceColumn; + + /** + * @var array|null + */ + public $selectors; + + /** + * @var array + */ + public $comments; + + /** + * @var array + */ + public $children; + + /** + * @var \ScssPhp\ScssPhp\Block|null + */ + public $selfParent; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Cache.php b/plugins/admin/vendor/scssphp/scssphp/src/Cache.php new file mode 100644 index 0000000..9731c60 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Cache.php @@ -0,0 +1,272 @@ + + * + * @internal + */ +class Cache +{ + const CACHE_VERSION = 1; + + /** + * directory used for storing data + * + * @var string|false + */ + public static $cacheDir = false; + + /** + * prefix for the storing data + * + * @var string + */ + public static $prefix = 'scssphp_'; + + /** + * force a refresh : 'once' for refreshing the first hit on a cache only, true to never use the cache in this hit + * + * @var bool|string + */ + public static $forceRefresh = false; + + /** + * specifies the number of seconds after which data cached will be seen as 'garbage' and potentially cleaned up + * + * @var int + */ + public static $gcLifetime = 604800; + + /** + * array of already refreshed cache if $forceRefresh==='once' + * + * @var array + */ + protected static $refreshed = []; + + /** + * Constructor + * + * @param array $options + * + * @phpstan-param array{cacheDir?: string, prefix?: string, forceRefresh?: string} $options + */ + public function __construct($options) + { + // check $cacheDir + if (isset($options['cacheDir'])) { + self::$cacheDir = $options['cacheDir']; + } + + if (empty(self::$cacheDir)) { + throw new Exception('cacheDir not set'); + } + + if (isset($options['prefix'])) { + self::$prefix = $options['prefix']; + } + + if (empty(self::$prefix)) { + throw new Exception('prefix not set'); + } + + if (isset($options['forceRefresh'])) { + self::$forceRefresh = $options['forceRefresh']; + } + + self::checkCacheDir(); + } + + /** + * Get the cached result of $operation on $what, + * which is known as dependant from the content of $options + * + * @param string $operation parse, compile... + * @param mixed $what content key (e.g., filename to be treated) + * @param array $options any option that affect the operation result on the content + * @param int|null $lastModified last modified timestamp + * + * @return mixed + * + * @throws \Exception + */ + public function getCache($operation, $what, $options = [], $lastModified = null) + { + $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options); + + if ( + ((self::$forceRefresh === false) || (self::$forceRefresh === 'once' && + isset(self::$refreshed[$fileCache]))) && file_exists($fileCache) + ) { + $cacheTime = filemtime($fileCache); + + if ( + (\is_null($lastModified) || $cacheTime > $lastModified) && + $cacheTime + self::$gcLifetime > time() + ) { + $c = file_get_contents($fileCache); + $c = unserialize($c); + + if (\is_array($c) && isset($c['value'])) { + return $c['value']; + } + } + } + + return null; + } + + /** + * Put in cache the result of $operation on $what, + * which is known as dependant from the content of $options + * + * @param string $operation + * @param mixed $what + * @param mixed $value + * @param array $options + * + * @return void + */ + public function setCache($operation, $what, $value, $options = []) + { + $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options); + + $c = ['value' => $value]; + $c = serialize($c); + + file_put_contents($fileCache, $c); + + if (self::$forceRefresh === 'once') { + self::$refreshed[$fileCache] = true; + } + } + + /** + * Get the cache name for the caching of $operation on $what, + * which is known as dependant from the content of $options + * + * @param string $operation + * @param mixed $what + * @param array $options + * + * @return string + */ + private static function cacheName($operation, $what, $options = []) + { + $t = [ + 'version' => self::CACHE_VERSION, + 'scssphpVersion' => Version::VERSION, + 'operation' => $operation, + 'what' => $what, + 'options' => $options + ]; + + $t = self::$prefix + . sha1(json_encode($t)) + . ".$operation" + . ".scsscache"; + + return $t; + } + + /** + * Check that the cache dir exists and is writeable + * + * @return void + * + * @throws \Exception + */ + public static function checkCacheDir() + { + self::$cacheDir = str_replace('\\', '/', self::$cacheDir); + self::$cacheDir = rtrim(self::$cacheDir, '/') . '/'; + + if (! is_dir(self::$cacheDir)) { + throw new Exception('Cache directory doesn\'t exist: ' . self::$cacheDir); + } + + if (! is_writable(self::$cacheDir)) { + throw new Exception('Cache directory isn\'t writable: ' . self::$cacheDir); + } + } + + /** + * Delete unused cached files + * + * @return void + */ + public static function cleanCache() + { + static $clean = false; + + if ($clean || empty(self::$cacheDir)) { + return; + } + + $clean = true; + + // only remove files with extensions created by SCSSPHP Cache + // css files removed based on the list files + $removeTypes = ['scsscache' => 1]; + + $files = scandir(self::$cacheDir); + + if (! $files) { + return; + } + + $checkTime = time() - self::$gcLifetime; + + foreach ($files as $file) { + // don't delete if the file wasn't created with SCSSPHP Cache + if (strpos($file, self::$prefix) !== 0) { + continue; + } + + $parts = explode('.', $file); + $type = array_pop($parts); + + if (! isset($removeTypes[$type])) { + continue; + } + + $fullPath = self::$cacheDir . $file; + $mtime = filemtime($fullPath); + + // don't delete if it's a relatively new file + if ($mtime > $checkTime) { + continue; + } + + unlink($fullPath); + } + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Colors.php b/plugins/admin/vendor/scssphp/scssphp/src/Colors.php new file mode 100644 index 0000000..e836e3f --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Colors.php @@ -0,0 +1,247 @@ + + * + * @internal + */ +class Colors +{ + /** + * CSS Colors + * + * @see http://www.w3.org/TR/css3-color + * + * @var array + */ + protected static $cssColors = [ + 'aliceblue' => '240,248,255', + 'antiquewhite' => '250,235,215', + 'aqua' => '0,255,255', + 'cyan' => '0,255,255', + 'aquamarine' => '127,255,212', + 'azure' => '240,255,255', + 'beige' => '245,245,220', + 'bisque' => '255,228,196', + 'black' => '0,0,0', + 'blanchedalmond' => '255,235,205', + 'blue' => '0,0,255', + 'blueviolet' => '138,43,226', + 'brown' => '165,42,42', + 'burlywood' => '222,184,135', + 'cadetblue' => '95,158,160', + 'chartreuse' => '127,255,0', + 'chocolate' => '210,105,30', + 'coral' => '255,127,80', + 'cornflowerblue' => '100,149,237', + 'cornsilk' => '255,248,220', + 'crimson' => '220,20,60', + 'darkblue' => '0,0,139', + 'darkcyan' => '0,139,139', + 'darkgoldenrod' => '184,134,11', + 'darkgray' => '169,169,169', + 'darkgrey' => '169,169,169', + 'darkgreen' => '0,100,0', + 'darkkhaki' => '189,183,107', + 'darkmagenta' => '139,0,139', + 'darkolivegreen' => '85,107,47', + 'darkorange' => '255,140,0', + 'darkorchid' => '153,50,204', + 'darkred' => '139,0,0', + 'darksalmon' => '233,150,122', + 'darkseagreen' => '143,188,143', + 'darkslateblue' => '72,61,139', + 'darkslategray' => '47,79,79', + 'darkslategrey' => '47,79,79', + 'darkturquoise' => '0,206,209', + 'darkviolet' => '148,0,211', + 'deeppink' => '255,20,147', + 'deepskyblue' => '0,191,255', + 'dimgray' => '105,105,105', + 'dimgrey' => '105,105,105', + 'dodgerblue' => '30,144,255', + 'firebrick' => '178,34,34', + 'floralwhite' => '255,250,240', + 'forestgreen' => '34,139,34', + 'fuchsia' => '255,0,255', + 'magenta' => '255,0,255', + 'gainsboro' => '220,220,220', + 'ghostwhite' => '248,248,255', + 'gold' => '255,215,0', + 'goldenrod' => '218,165,32', + 'gray' => '128,128,128', + 'grey' => '128,128,128', + 'green' => '0,128,0', + 'greenyellow' => '173,255,47', + 'honeydew' => '240,255,240', + 'hotpink' => '255,105,180', + 'indianred' => '205,92,92', + 'indigo' => '75,0,130', + 'ivory' => '255,255,240', + 'khaki' => '240,230,140', + 'lavender' => '230,230,250', + 'lavenderblush' => '255,240,245', + 'lawngreen' => '124,252,0', + 'lemonchiffon' => '255,250,205', + 'lightblue' => '173,216,230', + 'lightcoral' => '240,128,128', + 'lightcyan' => '224,255,255', + 'lightgoldenrodyellow' => '250,250,210', + 'lightgray' => '211,211,211', + 'lightgrey' => '211,211,211', + 'lightgreen' => '144,238,144', + 'lightpink' => '255,182,193', + 'lightsalmon' => '255,160,122', + 'lightseagreen' => '32,178,170', + 'lightskyblue' => '135,206,250', + 'lightslategray' => '119,136,153', + 'lightslategrey' => '119,136,153', + 'lightsteelblue' => '176,196,222', + 'lightyellow' => '255,255,224', + 'lime' => '0,255,0', + 'limegreen' => '50,205,50', + 'linen' => '250,240,230', + 'maroon' => '128,0,0', + 'mediumaquamarine' => '102,205,170', + 'mediumblue' => '0,0,205', + 'mediumorchid' => '186,85,211', + 'mediumpurple' => '147,112,219', + 'mediumseagreen' => '60,179,113', + 'mediumslateblue' => '123,104,238', + 'mediumspringgreen' => '0,250,154', + 'mediumturquoise' => '72,209,204', + 'mediumvioletred' => '199,21,133', + 'midnightblue' => '25,25,112', + 'mintcream' => '245,255,250', + 'mistyrose' => '255,228,225', + 'moccasin' => '255,228,181', + 'navajowhite' => '255,222,173', + 'navy' => '0,0,128', + 'oldlace' => '253,245,230', + 'olive' => '128,128,0', + 'olivedrab' => '107,142,35', + 'orange' => '255,165,0', + 'orangered' => '255,69,0', + 'orchid' => '218,112,214', + 'palegoldenrod' => '238,232,170', + 'palegreen' => '152,251,152', + 'paleturquoise' => '175,238,238', + 'palevioletred' => '219,112,147', + 'papayawhip' => '255,239,213', + 'peachpuff' => '255,218,185', + 'peru' => '205,133,63', + 'pink' => '255,192,203', + 'plum' => '221,160,221', + 'powderblue' => '176,224,230', + 'purple' => '128,0,128', + 'red' => '255,0,0', + 'rosybrown' => '188,143,143', + 'royalblue' => '65,105,225', + 'saddlebrown' => '139,69,19', + 'salmon' => '250,128,114', + 'sandybrown' => '244,164,96', + 'seagreen' => '46,139,87', + 'seashell' => '255,245,238', + 'sienna' => '160,82,45', + 'silver' => '192,192,192', + 'skyblue' => '135,206,235', + 'slateblue' => '106,90,205', + 'slategray' => '112,128,144', + 'slategrey' => '112,128,144', + 'snow' => '255,250,250', + 'springgreen' => '0,255,127', + 'steelblue' => '70,130,180', + 'tan' => '210,180,140', + 'teal' => '0,128,128', + 'thistle' => '216,191,216', + 'tomato' => '255,99,71', + 'turquoise' => '64,224,208', + 'violet' => '238,130,238', + 'wheat' => '245,222,179', + 'white' => '255,255,255', + 'whitesmoke' => '245,245,245', + 'yellow' => '255,255,0', + 'yellowgreen' => '154,205,50', + 'rebeccapurple' => '102,51,153', + 'transparent' => '0,0,0,0', + ]; + + /** + * Convert named color in a [r,g,b[,a]] array + * + * @param string $colorName + * + * @return int[]|null + */ + public static function colorNameToRGBa($colorName) + { + if (\is_string($colorName) && isset(static::$cssColors[$colorName])) { + $rgba = explode(',', static::$cssColors[$colorName]); + + // only case with opacity is transparent, with opacity=0, so we can intval on opacity also + $rgba = array_map('intval', $rgba); + + return $rgba; + } + + return null; + } + + /** + * Reverse conversion : from RGBA to a color name if possible + * + * @param integer $r + * @param integer $g + * @param integer $b + * @param integer|float $a + * + * @return string|null + */ + public static function RGBaToColorName($r, $g, $b, $a = 1) + { + static $reverseColorTable = null; + + if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b) || ! is_numeric($a)) { + return null; + } + + if ($a < 1) { + return null; + } + + if (\is_null($reverseColorTable)) { + $reverseColorTable = []; + + foreach (static::$cssColors as $name => $rgb_str) { + $rgb_str = explode(',', $rgb_str); + + if ( + \count($rgb_str) == 3 && + ! isset($reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])]) + ) { + $reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])] = $name; + } + } + } + + if (isset($reverseColorTable[\intval($r)][\intval($g)][\intval($b)])) { + return $reverseColorTable[\intval($r)][\intval($g)][\intval($b)]; + } + + return null; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php b/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php new file mode 100644 index 0000000..36adb0d --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php @@ -0,0 +1,69 @@ +css = $css; + $this->sourceMap = $sourceMap; + $this->includedFiles = $includedFiles; + } + + /** + * @return string + */ + public function getCss() + { + return $this->css; + } + + /** + * @return string[] + */ + public function getIncludedFiles() + { + return $this->includedFiles; + } + + /** + * The sourceMap content, if it was generated + * + * @return null|string + */ + public function getSourceMap() + { + return $this->sourceMap; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php new file mode 100644 index 0000000..58ba795 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php @@ -0,0 +1,10087 @@ + + * + * @final Extending the Compiler is deprecated + */ +class Compiler +{ + /** + * @deprecated + */ + const LINE_COMMENTS = 1; + /** + * @deprecated + */ + const DEBUG_INFO = 2; + + /** + * @deprecated + */ + const WITH_RULE = 1; + /** + * @deprecated + */ + const WITH_MEDIA = 2; + /** + * @deprecated + */ + const WITH_SUPPORTS = 4; + /** + * @deprecated + */ + const WITH_ALL = 7; + + const SOURCE_MAP_NONE = 0; + const SOURCE_MAP_INLINE = 1; + const SOURCE_MAP_FILE = 2; + + /** + * @var array + */ + protected static $operatorNames = [ + '+' => 'add', + '-' => 'sub', + '*' => 'mul', + '/' => 'div', + '%' => 'mod', + + '==' => 'eq', + '!=' => 'neq', + '<' => 'lt', + '>' => 'gt', + + '<=' => 'lte', + '>=' => 'gte', + ]; + + /** + * @var array + */ + protected static $namespaces = [ + 'special' => '%', + 'mixin' => '@', + 'function' => '^', + ]; + + public static $true = [Type::T_KEYWORD, 'true']; + public static $false = [Type::T_KEYWORD, 'false']; + /** @deprecated */ + public static $NaN = [Type::T_KEYWORD, 'NaN']; + /** @deprecated */ + public static $Infinity = [Type::T_KEYWORD, 'Infinity']; + public static $null = [Type::T_NULL]; + public static $nullString = [Type::T_STRING, '', []]; + public static $defaultValue = [Type::T_KEYWORD, '']; + public static $selfSelector = [Type::T_SELF]; + public static $emptyList = [Type::T_LIST, '', []]; + public static $emptyMap = [Type::T_MAP, [], []]; + public static $emptyString = [Type::T_STRING, '"', []]; + public static $with = [Type::T_KEYWORD, 'with']; + public static $without = [Type::T_KEYWORD, 'without']; + + /** + * @var array + */ + protected $importPaths = []; + /** + * @var array + */ + protected $importCache = []; + + /** + * @var string[] + */ + protected $importedFiles = []; + + /** + * @var array + * @phpstan-var array + */ + protected $userFunctions = []; + /** + * @var array + */ + protected $registeredVars = []; + /** + * @var array + */ + protected $registeredFeatures = [ + 'extend-selector-pseudoclass' => false, + 'at-error' => true, + 'units-level-3' => true, + 'global-variable-shadowing' => false, + ]; + + /** + * @var string|null + */ + protected $encoding = null; + /** + * @var null + * @deprecated + */ + protected $lineNumberStyle = null; + + /** + * @var int|SourceMapGenerator + * @phpstan-var self::SOURCE_MAP_*|SourceMapGenerator + */ + protected $sourceMap = self::SOURCE_MAP_NONE; + + /** + * @var array + * @phpstan-var array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} + */ + protected $sourceMapOptions = []; + + /** + * @var bool + */ + private $charset = true; + + /** + * @var string|\ScssPhp\ScssPhp\Formatter + */ + protected $formatter = Expanded::class; + + /** + * @var Environment + */ + protected $rootEnv; + /** + * @var OutputBlock|null + */ + protected $rootBlock; + + /** + * @var \ScssPhp\ScssPhp\Compiler\Environment + */ + protected $env; + /** + * @var OutputBlock|null + */ + protected $scope; + /** + * @var Environment|null + */ + protected $storeEnv; + /** + * @var bool|null + * + * @deprecated + */ + protected $charsetSeen; + /** + * @var array + */ + protected $sourceNames; + + /** + * @var Cache|null + */ + protected $cache; + + /** + * @var bool + */ + protected $cacheCheckImportResolutions = false; + + /** + * @var int + */ + protected $indentLevel; + /** + * @var array[] + */ + protected $extends; + /** + * @var array + */ + protected $extendsMap; + + /** + * @var array + */ + protected $parsedFiles = []; + + /** + * @var Parser|null + */ + protected $parser; + /** + * @var int|null + */ + protected $sourceIndex; + /** + * @var int|null + */ + protected $sourceLine; + /** + * @var int|null + */ + protected $sourceColumn; + /** + * @var bool|null + */ + protected $shouldEvaluate; + /** + * @var null + * @deprecated + */ + protected $ignoreErrors; + /** + * @var bool + */ + protected $ignoreCallStackMessage = false; + + /** + * @var array[] + */ + protected $callStack = []; + + /** + * @var array + * @phpstan-var list + */ + private $resolvedImports = []; + + /** + * The directory of the currently processed file + * + * @var string|null + */ + private $currentDirectory; + + /** + * The directory of the input file + * + * @var string + */ + private $rootDirectory; + + /** + * @var bool + */ + private $legacyCwdImportPath = true; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var array + */ + private $warnedChildFunctions = []; + + /** + * Constructor + * + * @param array|null $cacheOptions + * @phpstan-param array{cacheDir?: string, prefix?: string, forceRefresh?: string, checkImportResolutions?: bool}|null $cacheOptions + */ + public function __construct($cacheOptions = null) + { + $this->sourceNames = []; + + if ($cacheOptions) { + $this->cache = new Cache($cacheOptions); + if (!empty($cacheOptions['checkImportResolutions'])) { + $this->cacheCheckImportResolutions = true; + } + } + + $this->logger = new StreamLogger(fopen('php://stderr', 'w'), true); + } + + /** + * Get compiler options + * + * @return array + * + * @internal + */ + public function getCompileOptions() + { + $options = [ + 'importPaths' => $this->importPaths, + 'registeredVars' => $this->registeredVars, + 'registeredFeatures' => $this->registeredFeatures, + 'encoding' => $this->encoding, + 'sourceMap' => serialize($this->sourceMap), + 'sourceMapOptions' => $this->sourceMapOptions, + 'formatter' => $this->formatter, + 'legacyImportPath' => $this->legacyCwdImportPath, + ]; + + return $options; + } + + /** + * Sets an alternative logger. + * + * Changing the logger in the middle of the compilation is not + * supported and will result in an undefined behavior. + * + * @param LoggerInterface $logger + * + * @return void + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Set an alternative error output stream, for testing purpose only + * + * @param resource $handle + * + * @return void + * + * @deprecated Use {@see setLogger} instead + */ + public function setErrorOuput($handle) + { + @trigger_error('The method "setErrorOuput" is deprecated. Use "setLogger" instead.', E_USER_DEPRECATED); + + $this->logger = new StreamLogger($handle); + } + + /** + * Compile scss + * + * @param string $code + * @param string|null $path + * + * @return string + * + * @throws SassException when the source fails to compile + * + * @deprecated Use {@see compileString} instead. + */ + public function compile($code, $path = null) + { + @trigger_error(sprintf('The "%s" method is deprecated. Use "compileString" instead.', __METHOD__), E_USER_DEPRECATED); + + $result = $this->compileString($code, $path); + + $sourceMap = $result->getSourceMap(); + + if ($sourceMap !== null) { + if ($this->sourceMap instanceof SourceMapGenerator) { + $this->sourceMap->saveMap($sourceMap); + } elseif ($this->sourceMap === self::SOURCE_MAP_FILE) { + $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions); + $sourceMapGenerator->saveMap($sourceMap); + } + } + + return $result->getCss(); + } + + /** + * Compile scss + * + * @param string $source + * @param string|null $path + * + * @return CompilationResult + * + * @throws SassException when the source fails to compile + */ + public function compileString($source, $path = null) + { + if ($this->cache) { + $cacheKey = ($path ? $path : '(stdin)') . ':' . md5($source); + $compileOptions = $this->getCompileOptions(); + $cachedResult = $this->cache->getCache('compile', $cacheKey, $compileOptions); + + if ($cachedResult instanceof CachedResult && $this->isFreshCachedResult($cachedResult)) { + return $cachedResult->getResult(); + } + } + + $this->indentLevel = -1; + $this->extends = []; + $this->extendsMap = []; + $this->sourceIndex = null; + $this->sourceLine = null; + $this->sourceColumn = null; + $this->env = null; + $this->scope = null; + $this->storeEnv = null; + $this->shouldEvaluate = null; + $this->ignoreCallStackMessage = false; + $this->parsedFiles = []; + $this->importedFiles = []; + $this->resolvedImports = []; + + if (!\is_null($path) && is_file($path)) { + $path = realpath($path) ?: $path; + $this->currentDirectory = dirname($path); + $this->rootDirectory = $this->currentDirectory; + } else { + $this->currentDirectory = null; + $this->rootDirectory = getcwd(); + } + + try { + $this->parser = $this->parserFactory($path); + $tree = $this->parser->parse($source); + $this->parser = null; + + $this->formatter = new $this->formatter(); + $this->rootBlock = null; + $this->rootEnv = $this->pushEnv($tree); + + $warnCallback = function ($message, $deprecation) { + $this->logger->warn($message, $deprecation); + }; + $previousWarnCallback = Warn::setCallback($warnCallback); + + try { + $this->injectVariables($this->registeredVars); + $this->compileRoot($tree); + $this->popEnv(); + } finally { + Warn::setCallback($previousWarnCallback); + } + + $sourceMapGenerator = null; + + if ($this->sourceMap) { + if (\is_object($this->sourceMap) && $this->sourceMap instanceof SourceMapGenerator) { + $sourceMapGenerator = $this->sourceMap; + $this->sourceMap = self::SOURCE_MAP_FILE; + } elseif ($this->sourceMap !== self::SOURCE_MAP_NONE) { + $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions); + } + } + + $out = $this->formatter->format($this->scope, $sourceMapGenerator); + + $prefix = ''; + + if ($this->charset && strlen($out) !== Util::mbStrlen($out)) { + $prefix = '@charset "UTF-8";' . "\n"; + $out = $prefix . $out; + } + + $sourceMap = null; + + if (! empty($out) && $this->sourceMap && $this->sourceMap !== self::SOURCE_MAP_NONE) { + $sourceMap = $sourceMapGenerator->generateJson($prefix); + $sourceMapUrl = null; + + switch ($this->sourceMap) { + case self::SOURCE_MAP_INLINE: + $sourceMapUrl = sprintf('data:application/json,%s', Util::encodeURIComponent($sourceMap)); + break; + + case self::SOURCE_MAP_FILE: + if (isset($this->sourceMapOptions['sourceMapURL'])) { + $sourceMapUrl = $this->sourceMapOptions['sourceMapURL']; + } + break; + } + + if ($sourceMapUrl !== null) { + $out .= sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl); + } + } + } catch (SassScriptException $e) { + throw new CompilerException($this->addLocationToMessage($e->getMessage()), 0, $e); + } + + $includedFiles = []; + + foreach ($this->resolvedImports as $resolvedImport) { + $includedFiles[$resolvedImport['filePath']] = $resolvedImport['filePath']; + } + + $result = new CompilationResult($out, $sourceMap, array_values($includedFiles)); + + if ($this->cache && isset($cacheKey) && isset($compileOptions)) { + $this->cache->setCache('compile', $cacheKey, new CachedResult($result, $this->parsedFiles, $this->resolvedImports), $compileOptions); + } + + // Reset state to free memory + // TODO in 2.0, reset parsedFiles as well when the getter is removed. + $this->resolvedImports = []; + $this->importedFiles = []; + + return $result; + } + + /** + * @param CachedResult $result + * + * @return bool + */ + private function isFreshCachedResult(CachedResult $result) + { + // check if any dependency file changed since the result was compiled + foreach ($result->getParsedFiles() as $file => $mtime) { + if (! is_file($file) || filemtime($file) !== $mtime) { + return false; + } + } + + if ($this->cacheCheckImportResolutions) { + $resolvedImports = []; + + foreach ($result->getResolvedImports() as $import) { + $currentDir = $import['currentDir']; + $path = $import['path']; + // store the check across all the results in memory to avoid multiple findImport() on the same path + // with same context. + // this is happening in a same hit with multiple compilations (especially with big frameworks) + if (empty($resolvedImports[$currentDir][$path])) { + $resolvedImports[$currentDir][$path] = $this->findImport($path, $currentDir); + } + + if ($resolvedImports[$currentDir][$path] !== $import['filePath']) { + return false; + } + } + } + + return true; + } + + /** + * Instantiate parser + * + * @param string|null $path + * + * @return \ScssPhp\ScssPhp\Parser + */ + protected function parserFactory($path) + { + // https://sass-lang.com/documentation/at-rules/import + // CSS files imported by Sass don’t allow any special Sass features. + // In order to make sure authors don’t accidentally write Sass in their CSS, + // all Sass features that aren’t also valid CSS will produce errors. + // Otherwise, the CSS will be rendered as-is. It can even be extended! + $cssOnly = false; + + if ($path !== null && substr($path, -4) === '.css') { + $cssOnly = true; + } + + $parser = new Parser($path, \count($this->sourceNames), $this->encoding, $this->cache, $cssOnly, $this->logger); + + $this->sourceNames[] = $path; + $this->addParsedFile($path); + + return $parser; + } + + /** + * Is self extend? + * + * @param array $target + * @param array $origin + * + * @return boolean + */ + protected function isSelfExtend($target, $origin) + { + foreach ($origin as $sel) { + if (\in_array($target, $sel)) { + return true; + } + } + + return false; + } + + /** + * Push extends + * + * @param array $target + * @param array $origin + * @param array|null $block + * + * @return void + */ + protected function pushExtends($target, $origin, $block) + { + $i = \count($this->extends); + $this->extends[] = [$target, $origin, $block]; + + foreach ($target as $part) { + if (isset($this->extendsMap[$part])) { + $this->extendsMap[$part][] = $i; + } else { + $this->extendsMap[$part] = [$i]; + } + } + } + + /** + * Make output block + * + * @param string|null $type + * @param string[]|null $selectors + * + * @return \ScssPhp\ScssPhp\Formatter\OutputBlock + */ + protected function makeOutputBlock($type, $selectors = null) + { + $out = new OutputBlock(); + $out->type = $type; + $out->lines = []; + $out->children = []; + $out->parent = $this->scope; + $out->selectors = $selectors; + $out->depth = $this->env->depth; + + if ($this->env->block instanceof Block) { + $out->sourceName = $this->env->block->sourceName; + $out->sourceLine = $this->env->block->sourceLine; + $out->sourceColumn = $this->env->block->sourceColumn; + } else { + $out->sourceName = null; + $out->sourceLine = null; + $out->sourceColumn = null; + } + + return $out; + } + + /** + * Compile root + * + * @param \ScssPhp\ScssPhp\Block $rootBlock + * + * @return void + */ + protected function compileRoot(Block $rootBlock) + { + $this->rootBlock = $this->scope = $this->makeOutputBlock(Type::T_ROOT); + + $this->compileChildrenNoReturn($rootBlock->children, $this->scope); + $this->flattenSelectors($this->scope); + $this->missingSelectors(); + } + + /** + * Report missing selectors + * + * @return void + */ + protected function missingSelectors() + { + foreach ($this->extends as $extend) { + if (isset($extend[3])) { + continue; + } + + list($target, $origin, $block) = $extend; + + // ignore if !optional + if ($block[2]) { + continue; + } + + $target = implode(' ', $target); + $origin = $this->collapseSelectors($origin); + + $this->sourceLine = $block[Parser::SOURCE_LINE]; + throw $this->error("\"$origin\" failed to @extend \"$target\". The selector \"$target\" was not found."); + } + } + + /** + * Flatten selectors + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * @param string $parentKey + * + * @return void + */ + protected function flattenSelectors(OutputBlock $block, $parentKey = null) + { + if ($block->selectors) { + $selectors = []; + + foreach ($block->selectors as $s) { + $selectors[] = $s; + + if (! \is_array($s)) { + continue; + } + + // check extends + if (! empty($this->extendsMap)) { + $this->matchExtends($s, $selectors); + + // remove duplicates + array_walk($selectors, function (&$value) { + $value = serialize($value); + }); + + $selectors = array_unique($selectors); + + array_walk($selectors, function (&$value) { + $value = unserialize($value); + }); + } + } + + $block->selectors = []; + $placeholderSelector = false; + + foreach ($selectors as $selector) { + if ($this->hasSelectorPlaceholder($selector)) { + $placeholderSelector = true; + continue; + } + + $block->selectors[] = $this->compileSelector($selector); + } + + if ($placeholderSelector && 0 === \count($block->selectors) && null !== $parentKey) { + unset($block->parent->children[$parentKey]); + + return; + } + } + + foreach ($block->children as $key => $child) { + $this->flattenSelectors($child, $key); + } + } + + /** + * Glue parts of :not( or :nth-child( ... that are in general split in selectors parts + * + * @param array $parts + * + * @return array + */ + protected function glueFunctionSelectors($parts) + { + $new = []; + + foreach ($parts as $part) { + if (\is_array($part)) { + $part = $this->glueFunctionSelectors($part); + $new[] = $part; + } else { + // a selector part finishing with a ) is the last part of a :not( or :nth-child( + // and need to be joined to this + if ( + \count($new) && \is_string($new[\count($new) - 1]) && + \strlen($part) && substr($part, -1) === ')' && strpos($part, '(') === false + ) { + while (\count($new) > 1 && substr($new[\count($new) - 1], -1) !== '(') { + $part = array_pop($new) . $part; + } + $new[\count($new) - 1] .= $part; + } else { + $new[] = $part; + } + } + } + + return $new; + } + + /** + * Match extends + * + * @param array $selector + * @param array $out + * @param integer $from + * @param boolean $initial + * + * @return void + */ + protected function matchExtends($selector, &$out, $from = 0, $initial = true) + { + static $partsPile = []; + $selector = $this->glueFunctionSelectors($selector); + + if (\count($selector) == 1 && \in_array(reset($selector), $partsPile)) { + return; + } + + $outRecurs = []; + + foreach ($selector as $i => $part) { + if ($i < $from) { + continue; + } + + // check that we are not building an infinite loop of extensions + // if the new part is just including a previous part don't try to extend anymore + if (\count($part) > 1) { + foreach ($partsPile as $previousPart) { + if (! \count(array_diff($previousPart, $part))) { + continue 2; + } + } + } + + $partsPile[] = $part; + + if ($this->matchExtendsSingle($part, $origin, $initial)) { + $after = \array_slice($selector, $i + 1); + $before = \array_slice($selector, 0, $i); + list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before); + + foreach ($origin as $new) { + $k = 0; + + // remove shared parts + if (\count($new) > 1) { + while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) { + $k++; + } + } + + if (\count($nonBreakableBefore) && $k === \count($new)) { + $k--; + } + + $replacement = []; + $tempReplacement = $k > 0 ? \array_slice($new, $k) : $new; + + for ($l = \count($tempReplacement) - 1; $l >= 0; $l--) { + $slice = []; + + foreach ($tempReplacement[$l] as $chunk) { + if (! \in_array($chunk, $slice)) { + $slice[] = $chunk; + } + } + + array_unshift($replacement, $slice); + + if (! $this->isImmediateRelationshipCombinator(end($slice))) { + break; + } + } + + $afterBefore = $l != 0 ? \array_slice($tempReplacement, 0, $l) : []; + + // Merge shared direct relationships. + $mergedBefore = $this->mergeDirectRelationships($afterBefore, $nonBreakableBefore); + + $result = array_merge( + $before, + $mergedBefore, + $replacement, + $after + ); + + if ($result === $selector) { + continue; + } + + $this->pushOrMergeExtentedSelector($out, $result); + + // recursively check for more matches + $startRecurseFrom = \count($before) + min(\count($nonBreakableBefore), \count($mergedBefore)); + + if (\count($origin) > 1) { + $this->matchExtends($result, $out, $startRecurseFrom, false); + } else { + $this->matchExtends($result, $outRecurs, $startRecurseFrom, false); + } + + // selector sequence merging + if (! empty($before) && \count($new) > 1) { + $preSharedParts = $k > 0 ? \array_slice($before, 0, $k) : []; + $postSharedParts = $k > 0 ? \array_slice($before, $k) : $before; + + list($betweenSharedParts, $nonBreakabl2) = $this->extractRelationshipFromFragment($afterBefore); + + $result2 = array_merge( + $preSharedParts, + $betweenSharedParts, + $postSharedParts, + $nonBreakabl2, + $nonBreakableBefore, + $replacement, + $after + ); + + $this->pushOrMergeExtentedSelector($out, $result2); + } + } + } + array_pop($partsPile); + } + + while (\count($outRecurs)) { + $result = array_shift($outRecurs); + $this->pushOrMergeExtentedSelector($out, $result); + } + } + + /** + * Test a part for being a pseudo selector + * + * @param string $part + * @param array $matches + * + * @return boolean + */ + protected function isPseudoSelector($part, &$matches) + { + if ( + strpos($part, ':') === 0 && + preg_match(",^::?([\w-]+)\((.+)\)$,", $part, $matches) + ) { + return true; + } + + return false; + } + + /** + * Push extended selector except if + * - this is a pseudo selector + * - same as previous + * - in a white list + * in this case we merge the pseudo selector content + * + * @param array $out + * @param array $extended + * + * @return void + */ + protected function pushOrMergeExtentedSelector(&$out, $extended) + { + if (\count($out) && \count($extended) === 1 && \count(reset($extended)) === 1) { + $single = reset($extended); + $part = reset($single); + + if ( + $this->isPseudoSelector($part, $matchesExtended) && + \in_array($matchesExtended[1], [ 'slotted' ]) + ) { + $prev = end($out); + $prev = $this->glueFunctionSelectors($prev); + + if (\count($prev) === 1 && \count(reset($prev)) === 1) { + $single = reset($prev); + $part = reset($single); + + if ( + $this->isPseudoSelector($part, $matchesPrev) && + $matchesPrev[1] === $matchesExtended[1] + ) { + $extended = explode($matchesExtended[1] . '(', $matchesExtended[0], 2); + $extended[1] = $matchesPrev[2] . ', ' . $extended[1]; + $extended = implode($matchesExtended[1] . '(', $extended); + $extended = [ [ $extended ]]; + array_pop($out); + } + } + } + } + $out[] = $extended; + } + + /** + * Match extends single + * + * @param array $rawSingle + * @param array $outOrigin + * @param boolean $initial + * + * @return boolean + */ + protected function matchExtendsSingle($rawSingle, &$outOrigin, $initial = true) + { + $counts = []; + $single = []; + + // simple usual cases, no need to do the whole trick + if (\in_array($rawSingle, [['>'],['+'],['~']])) { + return false; + } + + foreach ($rawSingle as $part) { + // matches Number + if (! \is_string($part)) { + return false; + } + + if (! preg_match('/^[\[.:#%]/', $part) && \count($single)) { + $single[\count($single) - 1] .= $part; + } else { + $single[] = $part; + } + } + + $extendingDecoratedTag = false; + + if (\count($single) > 1) { + $matches = null; + $extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false; + } + + $outOrigin = []; + $found = false; + + foreach ($single as $k => $part) { + if (isset($this->extendsMap[$part])) { + foreach ($this->extendsMap[$part] as $idx) { + $counts[$idx] = isset($counts[$idx]) ? $counts[$idx] + 1 : 1; + } + } + + if ( + $initial && + $this->isPseudoSelector($part, $matches) && + ! \in_array($matches[1], [ 'not' ]) + ) { + $buffer = $matches[2]; + $parser = $this->parserFactory(__METHOD__); + + if ($parser->parseSelector($buffer, $subSelectors, false)) { + foreach ($subSelectors as $ksub => $subSelector) { + $subExtended = []; + $this->matchExtends($subSelector, $subExtended, 0, false); + + if ($subExtended) { + $subSelectorsExtended = $subSelectors; + $subSelectorsExtended[$ksub] = $subExtended; + + foreach ($subSelectorsExtended as $ksse => $sse) { + $subSelectorsExtended[$ksse] = $this->collapseSelectors($sse); + } + + $subSelectorsExtended = implode(', ', $subSelectorsExtended); + $singleExtended = $single; + $singleExtended[$k] = str_replace('(' . $buffer . ')', "($subSelectorsExtended)", $part); + $outOrigin[] = [ $singleExtended ]; + $found = true; + } + } + } + } + } + + foreach ($counts as $idx => $count) { + list($target, $origin, /* $block */) = $this->extends[$idx]; + + $origin = $this->glueFunctionSelectors($origin); + + // check count + if ($count !== \count($target)) { + continue; + } + + $this->extends[$idx][3] = true; + + $rem = array_diff($single, $target); + + foreach ($origin as $j => $new) { + // prevent infinite loop when target extends itself + if ($this->isSelfExtend($single, $origin) && ! $initial) { + return false; + } + + $replacement = end($new); + + // Extending a decorated tag with another tag is not possible. + if ( + $extendingDecoratedTag && $replacement[0] != $extendingDecoratedTag && + preg_match('/^[a-z0-9]+$/i', $replacement[0]) + ) { + unset($origin[$j]); + continue; + } + + $combined = $this->combineSelectorSingle($replacement, $rem); + + if (\count(array_diff($combined, $origin[$j][\count($origin[$j]) - 1]))) { + $origin[$j][\count($origin[$j]) - 1] = $combined; + } + } + + $outOrigin = array_merge($outOrigin, $origin); + + $found = true; + } + + return $found; + } + + /** + * Extract a relationship from the fragment. + * + * When extracting the last portion of a selector we will be left with a + * fragment which may end with a direction relationship combinator. This + * method will extract the relationship fragment and return it along side + * the rest. + * + * @param array $fragment The selector fragment maybe ending with a direction relationship combinator. + * + * @return array The selector without the relationship fragment if any, the relationship fragment. + */ + protected function extractRelationshipFromFragment(array $fragment) + { + $parents = []; + $children = []; + + $j = $i = \count($fragment); + + for (;;) { + $children = $j != $i ? \array_slice($fragment, $j, $i - $j) : []; + $parents = \array_slice($fragment, 0, $j); + $slice = end($parents); + + if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) { + break; + } + + $j -= 2; + } + + return [$parents, $children]; + } + + /** + * Combine selector single + * + * @param array $base + * @param array $other + * + * @return array + */ + protected function combineSelectorSingle($base, $other) + { + $tag = []; + $out = []; + $wasTag = false; + $pseudo = []; + + while (\count($other) && strpos(end($other), ':') === 0) { + array_unshift($pseudo, array_pop($other)); + } + + foreach ([array_reverse($base), array_reverse($other)] as $single) { + $rang = count($single); + + foreach ($single as $part) { + if (preg_match('/^[\[:]/', $part)) { + $out[] = $part; + $wasTag = false; + } elseif (preg_match('/^[\.#]/', $part)) { + array_unshift($out, $part); + $wasTag = false; + } elseif (preg_match('/^[^_-]/', $part) && $rang === 1) { + $tag[] = $part; + $wasTag = true; + } elseif ($wasTag) { + $tag[\count($tag) - 1] .= $part; + } else { + array_unshift($out, $part); + } + $rang--; + } + } + + if (\count($tag)) { + array_unshift($out, $tag[0]); + } + + while (\count($pseudo)) { + $out[] = array_shift($pseudo); + } + + return $out; + } + + /** + * Compile media + * + * @param \ScssPhp\ScssPhp\Block $media + * + * @return void + */ + protected function compileMedia(Block $media) + { + $this->pushEnv($media); + + $mediaQueries = $this->compileMediaQuery($this->multiplyMedia($this->env)); + + if (! empty($mediaQueries)) { + $previousScope = $this->scope; + $parentScope = $this->mediaParent($this->scope); + + foreach ($mediaQueries as $mediaQuery) { + $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]); + + $parentScope->children[] = $this->scope; + $parentScope = $this->scope; + } + + // top level properties in a media cause it to be wrapped + $needsWrap = false; + + foreach ($media->children as $child) { + $type = $child[0]; + + if ( + $type !== Type::T_BLOCK && + $type !== Type::T_MEDIA && + $type !== Type::T_DIRECTIVE && + $type !== Type::T_IMPORT + ) { + $needsWrap = true; + break; + } + } + + if ($needsWrap) { + $wrapped = new Block(); + $wrapped->sourceName = $media->sourceName; + $wrapped->sourceIndex = $media->sourceIndex; + $wrapped->sourceLine = $media->sourceLine; + $wrapped->sourceColumn = $media->sourceColumn; + $wrapped->selectors = []; + $wrapped->comments = []; + $wrapped->parent = $media; + $wrapped->children = $media->children; + + $media->children = [[Type::T_BLOCK, $wrapped]]; + } + + $this->compileChildrenNoReturn($media->children, $this->scope); + + $this->scope = $previousScope; + } + + $this->popEnv(); + } + + /** + * Media parent + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope + * + * @return \ScssPhp\ScssPhp\Formatter\OutputBlock + */ + protected function mediaParent(OutputBlock $scope) + { + while (! empty($scope->parent)) { + if (! empty($scope->type) && $scope->type !== Type::T_MEDIA) { + break; + } + + $scope = $scope->parent; + } + + return $scope; + } + + /** + * Compile directive + * + * @param \ScssPhp\ScssPhp\Block|array $directive + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * + * @return void + */ + protected function compileDirective($directive, OutputBlock $out) + { + if (\is_array($directive)) { + $directiveName = $this->compileDirectiveName($directive[0]); + $s = '@' . $directiveName; + + if (! empty($directive[1])) { + $s .= ' ' . $this->compileValue($directive[1]); + } + // sass-spec compliance on newline after directives, a bit tricky :/ + $appendNewLine = (! empty($directive[2]) || strpos($s, "\n")) ? "\n" : ""; + if (\is_array($directive[0]) && empty($directive[1])) { + $appendNewLine = "\n"; + } + + if (empty($directive[3])) { + $this->appendRootDirective($s . ';' . $appendNewLine, $out, [Type::T_COMMENT, Type::T_DIRECTIVE]); + } else { + $this->appendOutputLine($out, Type::T_DIRECTIVE, $s . ';'); + } + } else { + $directive->name = $this->compileDirectiveName($directive->name); + $s = '@' . $directive->name; + + if (! empty($directive->value)) { + $s .= ' ' . $this->compileValue($directive->value); + } + + if ($directive->name === 'keyframes' || substr($directive->name, -10) === '-keyframes') { + $this->compileKeyframeBlock($directive, [$s]); + } else { + $this->compileNestedBlock($directive, [$s]); + } + } + } + + /** + * directive names can include some interpolation + * + * @param string|array $directiveName + * @return string + * @throws CompilerException + */ + protected function compileDirectiveName($directiveName) + { + if (is_string($directiveName)) { + return $directiveName; + } + + return $this->compileValue($directiveName); + } + + /** + * Compile at-root + * + * @param \ScssPhp\ScssPhp\Block $block + * + * @return void + */ + protected function compileAtRoot(Block $block) + { + $env = $this->pushEnv($block); + $envs = $this->compactEnv($env); + list($with, $without) = $this->compileWith(isset($block->with) ? $block->with : null); + + // wrap inline selector + if ($block->selector) { + $wrapped = new Block(); + $wrapped->sourceName = $block->sourceName; + $wrapped->sourceIndex = $block->sourceIndex; + $wrapped->sourceLine = $block->sourceLine; + $wrapped->sourceColumn = $block->sourceColumn; + $wrapped->selectors = $block->selector; + $wrapped->comments = []; + $wrapped->parent = $block; + $wrapped->children = $block->children; + $wrapped->selfParent = $block->selfParent; + + $block->children = [[Type::T_BLOCK, $wrapped]]; + $block->selector = null; + } + + $selfParent = $block->selfParent; + assert($selfParent !== null, 'at-root blocks must have a selfParent set.'); + + if ( + ! $selfParent->selectors && + isset($block->parent) && $block->parent && + isset($block->parent->selectors) && $block->parent->selectors + ) { + $selfParent = $block->parent; + } + + $this->env = $this->filterWithWithout($envs, $with, $without); + + $saveScope = $this->scope; + $this->scope = $this->filterScopeWithWithout($saveScope, $with, $without); + + // propagate selfParent to the children where they still can be useful + $this->compileChildrenNoReturn($block->children, $this->scope, $selfParent); + + $this->scope = $this->completeScope($this->scope, $saveScope); + $this->scope = $saveScope; + $this->env = $this->extractEnv($envs); + + $this->popEnv(); + } + + /** + * Filter at-root scope depending of with/without option + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope + * @param array $with + * @param array $without + * + * @return OutputBlock + */ + protected function filterScopeWithWithout($scope, $with, $without) + { + $filteredScopes = []; + $childStash = []; + + if ($scope->type === Type::T_ROOT) { + return $scope; + } + + // start from the root + while ($scope->parent && $scope->parent->type !== Type::T_ROOT) { + array_unshift($childStash, $scope); + $scope = $scope->parent; + } + + for (;;) { + if (! $scope) { + break; + } + + if ($this->isWith($scope, $with, $without)) { + $s = clone $scope; + $s->children = []; + $s->lines = []; + $s->parent = null; + + if ($s->type !== Type::T_MEDIA && $s->type !== Type::T_DIRECTIVE) { + $s->selectors = []; + } + + $filteredScopes[] = $s; + } + + if (\count($childStash)) { + $scope = array_shift($childStash); + } elseif ($scope->children) { + $scope = end($scope->children); + } else { + $scope = null; + } + } + + if (! \count($filteredScopes)) { + return $this->rootBlock; + } + + $newScope = array_shift($filteredScopes); + $newScope->parent = $this->rootBlock; + + $this->rootBlock->children[] = $newScope; + + $p = &$newScope; + + while (\count($filteredScopes)) { + $s = array_shift($filteredScopes); + $s->parent = $p; + $p->children[] = $s; + $newScope = &$p->children[0]; + $p = &$p->children[0]; + } + + return $newScope; + } + + /** + * found missing selector from a at-root compilation in the previous scope + * (if at-root is just enclosing a property, the selector is in the parent tree) + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $previousScope + * + * @return OutputBlock + */ + protected function completeScope($scope, $previousScope) + { + if (! $scope->type && (! $scope->selectors || ! \count($scope->selectors)) && \count($scope->lines)) { + $scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth); + } + + if ($scope->children) { + foreach ($scope->children as $k => $c) { + $scope->children[$k] = $this->completeScope($c, $previousScope); + } + } + + return $scope; + } + + /** + * Find a selector by the depth node in the scope + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope + * @param integer $depth + * + * @return array + */ + protected function findScopeSelectors($scope, $depth) + { + if ($scope->depth === $depth && $scope->selectors) { + return $scope->selectors; + } + + if ($scope->children) { + foreach (array_reverse($scope->children) as $c) { + if ($s = $this->findScopeSelectors($c, $depth)) { + return $s; + } + } + } + + return []; + } + + /** + * Compile @at-root's with: inclusion / without: exclusion into 2 lists uses to filter scope/env later + * + * @param array $withCondition + * + * @return array + */ + protected function compileWith($withCondition) + { + // just compile what we have in 2 lists + $with = []; + $without = ['rule' => true]; + + if ($withCondition) { + if ($withCondition[0] === Type::T_INTERPOLATE) { + $w = $this->compileValue($withCondition); + + $buffer = "($w)"; + $parser = $this->parserFactory(__METHOD__); + + if ($parser->parseValue($buffer, $reParsedWith)) { + $withCondition = $reParsedWith; + } + } + + if ($this->mapHasKey($withCondition, static::$with)) { + $without = []; // cancel the default + $list = $this->coerceList($this->libMapGet([$withCondition, static::$with])); + + foreach ($list[2] as $item) { + $keyword = $this->compileStringContent($this->coerceString($item)); + + $with[$keyword] = true; + } + } + + if ($this->mapHasKey($withCondition, static::$without)) { + $without = []; // cancel the default + $list = $this->coerceList($this->libMapGet([$withCondition, static::$without])); + + foreach ($list[2] as $item) { + $keyword = $this->compileStringContent($this->coerceString($item)); + + $without[$keyword] = true; + } + } + } + + return [$with, $without]; + } + + /** + * Filter env stack + * + * @param Environment[] $envs + * @param array $with + * @param array $without + * + * @return Environment + * + * @phpstan-param non-empty-array $envs + */ + protected function filterWithWithout($envs, $with, $without) + { + $filtered = []; + + foreach ($envs as $e) { + if ($e->block && ! $this->isWith($e->block, $with, $without)) { + $ec = clone $e; + $ec->block = null; + $ec->selectors = []; + + $filtered[] = $ec; + } else { + $filtered[] = $e; + } + } + + return $this->extractEnv($filtered); + } + + /** + * Filter WITH rules + * + * @param \ScssPhp\ScssPhp\Block|\ScssPhp\ScssPhp\Formatter\OutputBlock $block + * @param array $with + * @param array $without + * + * @return boolean + */ + protected function isWith($block, $with, $without) + { + if (isset($block->type)) { + if ($block->type === Type::T_MEDIA) { + return $this->testWithWithout('media', $with, $without); + } + + if ($block->type === Type::T_DIRECTIVE) { + if (isset($block->name)) { + return $this->testWithWithout($this->compileDirectiveName($block->name), $with, $without); + } elseif (isset($block->selectors) && preg_match(',@(\w+),ims', json_encode($block->selectors), $m)) { + return $this->testWithWithout($m[1], $with, $without); + } else { + return $this->testWithWithout('???', $with, $without); + } + } + } elseif (isset($block->selectors)) { + // a selector starting with number is a keyframe rule + if (\count($block->selectors)) { + $s = reset($block->selectors); + + while (\is_array($s)) { + $s = reset($s); + } + + if (\is_object($s) && $s instanceof Number) { + return $this->testWithWithout('keyframes', $with, $without); + } + } + + return $this->testWithWithout('rule', $with, $without); + } + + return true; + } + + /** + * Test a single type of block against with/without lists + * + * @param string $what + * @param array $with + * @param array $without + * + * @return boolean + * true if the block should be kept, false to reject + */ + protected function testWithWithout($what, $with, $without) + { + // if without, reject only if in the list (or 'all' is in the list) + if (\count($without)) { + return (isset($without[$what]) || isset($without['all'])) ? false : true; + } + + // otherwise reject all what is not in the with list + return (isset($with[$what]) || isset($with['all'])) ? true : false; + } + + + /** + * Compile keyframe block + * + * @param \ScssPhp\ScssPhp\Block $block + * @param string[] $selectors + * + * @return void + */ + protected function compileKeyframeBlock(Block $block, $selectors) + { + $env = $this->pushEnv($block); + + $envs = $this->compactEnv($env); + + $this->env = $this->extractEnv(array_filter($envs, function (Environment $e) { + return ! isset($e->block->selectors); + })); + + $this->scope = $this->makeOutputBlock($block->type, $selectors); + $this->scope->depth = 1; + $this->scope->parent->children[] = $this->scope; + + $this->compileChildrenNoReturn($block->children, $this->scope); + + $this->scope = $this->scope->parent; + $this->env = $this->extractEnv($envs); + + $this->popEnv(); + } + + /** + * Compile nested properties lines + * + * @param \ScssPhp\ScssPhp\Block $block + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * + * @return void + */ + protected function compileNestedPropertiesBlock(Block $block, OutputBlock $out) + { + $prefix = $this->compileValue($block->prefix) . '-'; + + $nested = $this->makeOutputBlock($block->type); + $nested->parent = $out; + + if ($block->hasValue) { + $nested->depth = $out->depth + 1; + } + + $out->children[] = $nested; + + foreach ($block->children as $child) { + switch ($child[0]) { + case Type::T_ASSIGN: + array_unshift($child[1][2], $prefix); + break; + + case Type::T_NESTED_PROPERTY: + array_unshift($child[1]->prefix[2], $prefix); + break; + } + + $this->compileChild($child, $nested); + } + } + + /** + * Compile nested block + * + * @param \ScssPhp\ScssPhp\Block $block + * @param string[] $selectors + * + * @return void + */ + protected function compileNestedBlock(Block $block, $selectors) + { + $this->pushEnv($block); + + $this->scope = $this->makeOutputBlock($block->type, $selectors); + $this->scope->parent->children[] = $this->scope; + + // wrap assign children in a block + // except for @font-face + if ($block->type !== Type::T_DIRECTIVE || $this->compileDirectiveName($block->name) !== 'font-face') { + // need wrapping? + $needWrapping = false; + + foreach ($block->children as $child) { + if ($child[0] === Type::T_ASSIGN) { + $needWrapping = true; + break; + } + } + + if ($needWrapping) { + $wrapped = new Block(); + $wrapped->sourceName = $block->sourceName; + $wrapped->sourceIndex = $block->sourceIndex; + $wrapped->sourceLine = $block->sourceLine; + $wrapped->sourceColumn = $block->sourceColumn; + $wrapped->selectors = []; + $wrapped->comments = []; + $wrapped->parent = $block; + $wrapped->children = $block->children; + $wrapped->selfParent = $block->selfParent; + + $block->children = [[Type::T_BLOCK, $wrapped]]; + } + } + + $this->compileChildrenNoReturn($block->children, $this->scope); + + $this->scope = $this->scope->parent; + + $this->popEnv(); + } + + /** + * Recursively compiles a block. + * + * A block is analogous to a CSS block in most cases. A single SCSS document + * is encapsulated in a block when parsed, but it does not have parent tags + * so all of its children appear on the root level when compiled. + * + * Blocks are made up of selectors and children. + * + * The children of a block are just all the blocks that are defined within. + * + * Compiling the block involves pushing a fresh environment on the stack, + * and iterating through the props, compiling each one. + * + * @see Compiler::compileChild() + * + * @param \ScssPhp\ScssPhp\Block $block + * + * @return void + */ + protected function compileBlock(Block $block) + { + $env = $this->pushEnv($block); + $env->selectors = $this->evalSelectors($block->selectors); + + $out = $this->makeOutputBlock(null); + + $this->scope->children[] = $out; + + if (\count($block->children)) { + $out->selectors = $this->multiplySelectors($env, $block->selfParent); + + // propagate selfParent to the children where they still can be useful + $selfParentSelectors = null; + + if (isset($block->selfParent->selectors)) { + $selfParentSelectors = $block->selfParent->selectors; + $block->selfParent->selectors = $out->selectors; + } + + $this->compileChildrenNoReturn($block->children, $out, $block->selfParent); + + // and revert for the following children of the same block + if ($selfParentSelectors) { + $block->selfParent->selectors = $selfParentSelectors; + } + } + + $this->popEnv(); + } + + + /** + * Compile the value of a comment that can have interpolation + * + * @param array $value + * @param boolean $pushEnv + * + * @return string + */ + protected function compileCommentValue($value, $pushEnv = false) + { + $c = $value[1]; + + if (isset($value[2])) { + if ($pushEnv) { + $this->pushEnv(); + } + + try { + $c = $this->compileValue($value[2]); + } catch (SassScriptException $e) { + $this->logger->warn('Ignoring interpolation errors in multiline comments is deprecated and will be removed in ScssPhp 2.0. ' . $this->addLocationToMessage($e->getMessage()), true); + // ignore error in comment compilation which are only interpolation + } catch (SassException $e) { + $this->logger->warn('Ignoring interpolation errors in multiline comments is deprecated and will be removed in ScssPhp 2.0. ' . $e->getMessage(), true); + // ignore error in comment compilation which are only interpolation + } + + if ($pushEnv) { + $this->popEnv(); + } + } + + return $c; + } + + /** + * Compile root level comment + * + * @param array $block + * + * @return void + */ + protected function compileComment($block) + { + $out = $this->makeOutputBlock(Type::T_COMMENT); + $out->lines[] = $this->compileCommentValue($block, true); + + $this->scope->children[] = $out; + } + + /** + * Evaluate selectors + * + * @param array $selectors + * + * @return array + */ + protected function evalSelectors($selectors) + { + $this->shouldEvaluate = false; + + $selectors = array_map([$this, 'evalSelector'], $selectors); + + // after evaluating interpolates, we might need a second pass + if ($this->shouldEvaluate) { + $selectors = $this->replaceSelfSelector($selectors, '&'); + $buffer = $this->collapseSelectors($selectors); + $parser = $this->parserFactory(__METHOD__); + + try { + $isValid = $parser->parseSelector($buffer, $newSelectors, true); + } catch (ParserException $e) { + throw $this->error($e->getMessage()); + } + + if ($isValid) { + $selectors = array_map([$this, 'evalSelector'], $newSelectors); + } + } + + return $selectors; + } + + /** + * Evaluate selector + * + * @param array $selector + * + * @return array + */ + protected function evalSelector($selector) + { + return array_map([$this, 'evalSelectorPart'], $selector); + } + + /** + * Evaluate selector part; replaces all the interpolates, stripping quotes + * + * @param array $part + * + * @return array + */ + protected function evalSelectorPart($part) + { + foreach ($part as &$p) { + if (\is_array($p) && ($p[0] === Type::T_INTERPOLATE || $p[0] === Type::T_STRING)) { + $p = $this->compileValue($p); + + // force re-evaluation if self char or non standard char + if (preg_match(',[^\w-],', $p)) { + $this->shouldEvaluate = true; + } + } elseif ( + \is_string($p) && \strlen($p) >= 2 && + ($first = $p[0]) && ($first === '"' || $first === "'") && + substr($p, -1) === $first + ) { + $p = substr($p, 1, -1); + } + } + + return $this->flattenSelectorSingle($part); + } + + /** + * Collapse selectors + * + * @param array $selectors + * + * @return string + */ + protected function collapseSelectors($selectors) + { + $parts = []; + + foreach ($selectors as $selector) { + $output = []; + + foreach ($selector as $node) { + $compound = ''; + + array_walk_recursive( + $node, + function ($value, $key) use (&$compound) { + $compound .= $value; + } + ); + + $output[] = $compound; + } + + $parts[] = implode(' ', $output); + } + + return implode(', ', $parts); + } + + /** + * Collapse selectors + * + * @param array $selectors + * + * @return array + */ + private function collapseSelectorsAsList($selectors) + { + $parts = []; + + foreach ($selectors as $selector) { + $output = []; + $glueNext = false; + + foreach ($selector as $node) { + $compound = ''; + + array_walk_recursive( + $node, + function ($value, $key) use (&$compound) { + $compound .= $value; + } + ); + + if ($this->isImmediateRelationshipCombinator($compound)) { + if (\count($output)) { + $output[\count($output) - 1] .= ' ' . $compound; + } else { + $output[] = $compound; + } + + $glueNext = true; + } elseif ($glueNext) { + $output[\count($output) - 1] .= ' ' . $compound; + $glueNext = false; + } else { + $output[] = $compound; + } + } + + foreach ($output as &$o) { + $o = [Type::T_STRING, '', [$o]]; + } + + $parts[] = [Type::T_LIST, ' ', $output]; + } + + return [Type::T_LIST, ',', $parts]; + } + + /** + * Parse down the selector and revert [self] to "&" before a reparsing + * + * @param array $selectors + * @param string|null $replace + * + * @return array + */ + protected function replaceSelfSelector($selectors, $replace = null) + { + foreach ($selectors as &$part) { + if (\is_array($part)) { + if ($part === [Type::T_SELF]) { + if (\is_null($replace)) { + $replace = $this->reduce([Type::T_SELF]); + $replace = $this->compileValue($replace); + } + $part = $replace; + } else { + $part = $this->replaceSelfSelector($part, $replace); + } + } + } + + return $selectors; + } + + /** + * Flatten selector single; joins together .classes and #ids + * + * @param array $single + * + * @return array + */ + protected function flattenSelectorSingle($single) + { + $joined = []; + + foreach ($single as $part) { + if ( + empty($joined) || + ! \is_string($part) || + preg_match('/[\[.:#%]/', $part) + ) { + $joined[] = $part; + continue; + } + + if (\is_array(end($joined))) { + $joined[] = $part; + } else { + $joined[\count($joined) - 1] .= $part; + } + } + + return $joined; + } + + /** + * Compile selector to string; self(&) should have been replaced by now + * + * @param string|array $selector + * + * @return string + */ + protected function compileSelector($selector) + { + if (! \is_array($selector)) { + return $selector; // media and the like + } + + return implode( + ' ', + array_map( + [$this, 'compileSelectorPart'], + $selector + ) + ); + } + + /** + * Compile selector part + * + * @param array $piece + * + * @return string + */ + protected function compileSelectorPart($piece) + { + foreach ($piece as &$p) { + if (! \is_array($p)) { + continue; + } + + switch ($p[0]) { + case Type::T_SELF: + $p = '&'; + break; + + default: + $p = $this->compileValue($p); + break; + } + } + + return implode($piece); + } + + /** + * Has selector placeholder? + * + * @param array $selector + * + * @return boolean + */ + protected function hasSelectorPlaceholder($selector) + { + if (! \is_array($selector)) { + return false; + } + + foreach ($selector as $parts) { + foreach ($parts as $part) { + if (\strlen($part) && '%' === $part[0]) { + return true; + } + } + } + + return false; + } + + /** + * @param string $name + * + * @return void + */ + protected function pushCallStack($name = '') + { + $this->callStack[] = [ + 'n' => $name, + Parser::SOURCE_INDEX => $this->sourceIndex, + Parser::SOURCE_LINE => $this->sourceLine, + Parser::SOURCE_COLUMN => $this->sourceColumn + ]; + + // infinite calling loop + if (\count($this->callStack) > 25000) { + // not displayed but you can var_dump it to deep debug + $msg = $this->callStackMessage(true, 100); + $msg = 'Infinite calling loop'; + + throw $this->error($msg); + } + } + + /** + * @return void + */ + protected function popCallStack() + { + array_pop($this->callStack); + } + + /** + * Compile children and return result + * + * @param array $stms + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * @param string $traceName + * + * @return array|Number|null + */ + protected function compileChildren($stms, OutputBlock $out, $traceName = '') + { + $this->pushCallStack($traceName); + + foreach ($stms as $stm) { + $ret = $this->compileChild($stm, $out); + + if (isset($ret)) { + $this->popCallStack(); + + return $ret; + } + } + + $this->popCallStack(); + + return null; + } + + /** + * Compile children and throw exception if unexpected `@return` + * + * @param array $stms + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * @param \ScssPhp\ScssPhp\Block $selfParent + * @param string $traceName + * + * @return void + * + * @throws \Exception + */ + protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null, $traceName = '') + { + $this->pushCallStack($traceName); + + foreach ($stms as $stm) { + if ($selfParent && isset($stm[1]) && \is_object($stm[1]) && $stm[1] instanceof Block) { + $stm[1]->selfParent = $selfParent; + $ret = $this->compileChild($stm, $out); + $stm[1]->selfParent = null; + } elseif ($selfParent && \in_array($stm[0], [Type::T_INCLUDE, Type::T_EXTEND])) { + $stm['selfParent'] = $selfParent; + $ret = $this->compileChild($stm, $out); + unset($stm['selfParent']); + } else { + $ret = $this->compileChild($stm, $out); + } + + if (isset($ret)) { + throw $this->error('@return may only be used within a function'); + } + } + + $this->popCallStack(); + } + + + /** + * evaluate media query : compile internal value keeping the structure unchanged + * + * @param array $queryList + * + * @return array + */ + protected function evaluateMediaQuery($queryList) + { + static $parser = null; + + $outQueryList = []; + + foreach ($queryList as $kql => $query) { + $shouldReparse = false; + + foreach ($query as $kq => $q) { + for ($i = 1; $i < \count($q); $i++) { + $value = $this->compileValue($q[$i]); + + // the parser had no mean to know if media type or expression if it was an interpolation + // so you need to reparse if the T_MEDIA_TYPE looks like anything else a media type + if ( + $q[0] == Type::T_MEDIA_TYPE && + (strpos($value, '(') !== false || + strpos($value, ')') !== false || + strpos($value, ':') !== false || + strpos($value, ',') !== false) + ) { + $shouldReparse = true; + } + + $queryList[$kql][$kq][$i] = [Type::T_KEYWORD, $value]; + } + } + + if ($shouldReparse) { + if (\is_null($parser)) { + $parser = $this->parserFactory(__METHOD__); + } + + $queryString = $this->compileMediaQuery([$queryList[$kql]]); + $queryString = reset($queryString); + + if (strpos($queryString, '@media ') === 0) { + $queryString = substr($queryString, 7); + $queries = []; + + if ($parser->parseMediaQueryList($queryString, $queries)) { + $queries = $this->evaluateMediaQuery($queries[2]); + + while (\count($queries)) { + $outQueryList[] = array_shift($queries); + } + + continue; + } + } + } + + $outQueryList[] = $queryList[$kql]; + } + + return $outQueryList; + } + + /** + * Compile media query + * + * @param array $queryList + * + * @return string[] + */ + protected function compileMediaQuery($queryList) + { + $start = '@media '; + $default = trim($start); + $out = []; + $current = ''; + + foreach ($queryList as $query) { + $type = null; + $parts = []; + + $mediaTypeOnly = true; + + foreach ($query as $q) { + if ($q[0] !== Type::T_MEDIA_TYPE) { + $mediaTypeOnly = false; + break; + } + } + + foreach ($query as $q) { + switch ($q[0]) { + case Type::T_MEDIA_TYPE: + $newType = array_map([$this, 'compileValue'], \array_slice($q, 1)); + + // combining not and anything else than media type is too risky and should be avoided + if (! $mediaTypeOnly) { + if (\in_array(Type::T_NOT, $newType) || ($type && \in_array(Type::T_NOT, $type) )) { + if ($type) { + array_unshift($parts, implode(' ', array_filter($type))); + } + + if (! empty($parts)) { + if (\strlen($current)) { + $current .= $this->formatter->tagSeparator; + } + + $current .= implode(' and ', $parts); + } + + if ($current) { + $out[] = $start . $current; + } + + $current = ''; + $type = null; + $parts = []; + } + } + + if ($newType === ['all'] && $default) { + $default = $start . 'all'; + } + + // all can be safely ignored and mixed with whatever else + if ($newType !== ['all']) { + if ($type) { + $type = $this->mergeMediaTypes($type, $newType); + + if (empty($type)) { + // merge failed : ignore this query that is not valid, skip to the next one + $parts = []; + $default = ''; // if everything fail, no @media at all + continue 3; + } + } else { + $type = $newType; + } + } + break; + + case Type::T_MEDIA_EXPRESSION: + if (isset($q[2])) { + $parts[] = '(' + . $this->compileValue($q[1]) + . $this->formatter->assignSeparator + . $this->compileValue($q[2]) + . ')'; + } else { + $parts[] = '(' + . $this->compileValue($q[1]) + . ')'; + } + break; + + case Type::T_MEDIA_VALUE: + $parts[] = $this->compileValue($q[1]); + break; + } + } + + if ($type) { + array_unshift($parts, implode(' ', array_filter($type))); + } + + if (! empty($parts)) { + if (\strlen($current)) { + $current .= $this->formatter->tagSeparator; + } + + $current .= implode(' and ', $parts); + } + } + + if ($current) { + $out[] = $start . $current; + } + + // no @media type except all, and no conflict? + if (! $out && $default) { + $out[] = $default; + } + + return $out; + } + + /** + * Merge direct relationships between selectors + * + * @param array $selectors1 + * @param array $selectors2 + * + * @return array + */ + protected function mergeDirectRelationships($selectors1, $selectors2) + { + if (empty($selectors1) || empty($selectors2)) { + return array_merge($selectors1, $selectors2); + } + + $part1 = end($selectors1); + $part2 = end($selectors2); + + if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) { + return array_merge($selectors1, $selectors2); + } + + $merged = []; + + do { + $part1 = array_pop($selectors1); + $part2 = array_pop($selectors2); + + if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) { + if ($this->isImmediateRelationshipCombinator(reset($merged)[0])) { + array_unshift($merged, [$part1[0] . $part2[0]]); + $merged = array_merge($selectors1, $selectors2, $merged); + } else { + $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged); + } + + break; + } + + array_unshift($merged, $part1); + } while (! empty($selectors1) && ! empty($selectors2)); + + return $merged; + } + + /** + * Merge media types + * + * @param array $type1 + * @param array $type2 + * + * @return array|null + */ + protected function mergeMediaTypes($type1, $type2) + { + if (empty($type1)) { + return $type2; + } + + if (empty($type2)) { + return $type1; + } + + if (\count($type1) > 1) { + $m1 = strtolower($type1[0]); + $t1 = strtolower($type1[1]); + } else { + $m1 = ''; + $t1 = strtolower($type1[0]); + } + + if (\count($type2) > 1) { + $m2 = strtolower($type2[0]); + $t2 = strtolower($type2[1]); + } else { + $m2 = ''; + $t2 = strtolower($type2[0]); + } + + if (($m1 === Type::T_NOT) ^ ($m2 === Type::T_NOT)) { + if ($t1 === $t2) { + return null; + } + + return [ + $m1 === Type::T_NOT ? $m2 : $m1, + $m1 === Type::T_NOT ? $t2 : $t1, + ]; + } + + if ($m1 === Type::T_NOT && $m2 === Type::T_NOT) { + // CSS has no way of representing "neither screen nor print" + if ($t1 !== $t2) { + return null; + } + + return [Type::T_NOT, $t1]; + } + + if ($t1 !== $t2) { + return null; + } + + // t1 == t2, neither m1 nor m2 are "not" + return [empty($m1) ? $m2 : $m1, $t1]; + } + + /** + * Compile import; returns true if the value was something that could be imported + * + * @param array $rawPath + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * @param boolean $once + * + * @return boolean + */ + protected function compileImport($rawPath, OutputBlock $out, $once = false) + { + if ($rawPath[0] === Type::T_STRING) { + $path = $this->compileStringContent($rawPath); + + if (strpos($path, 'url(') !== 0 && $filePath = $this->findImport($path, $this->currentDirectory)) { + $this->registerImport($this->currentDirectory, $path, $filePath); + + if (! $once || ! \in_array($filePath, $this->importedFiles)) { + $this->importFile($filePath, $out); + $this->importedFiles[] = $filePath; + } + + return true; + } + + $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); + + return false; + } + + if ($rawPath[0] === Type::T_LIST) { + // handle a list of strings + if (\count($rawPath[2]) === 0) { + return false; + } + + foreach ($rawPath[2] as $path) { + if ($path[0] !== Type::T_STRING) { + $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); + + return false; + } + } + + foreach ($rawPath[2] as $path) { + $this->compileImport($path, $out, $once); + } + + return true; + } + + $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); + + return false; + } + + /** + * @param array $rawPath + * @return string + * @throws CompilerException + */ + protected function compileImportPath($rawPath) + { + $path = $this->compileValue($rawPath); + + // case url() without quotes : suppress \r \n remaining in the path + // if this is a real string there can not be CR or LF char + if (strpos($path, 'url(') === 0) { + $path = str_replace(array("\r", "\n"), array('', ' '), $path); + } else { + // if this is a file name in a string, spaces should be escaped + $path = $this->reduce($rawPath); + $path = $this->escapeImportPathString($path); + $path = $this->compileValue($path); + } + + return $path; + } + + /** + * @param array $path + * @return array + * @throws CompilerException + */ + protected function escapeImportPathString($path) + { + switch ($path[0]) { + case Type::T_LIST: + foreach ($path[2] as $k => $v) { + $path[2][$k] = $this->escapeImportPathString($v); + } + break; + case Type::T_STRING: + if ($path[1]) { + $path = $this->compileValue($path); + $path = str_replace(' ', '\\ ', $path); + $path = [Type::T_KEYWORD, $path]; + } + break; + } + + return $path; + } + + /** + * Append a root directive like @import or @charset as near as the possible from the source code + * (keeping before comments, @import and @charset coming before in the source code) + * + * @param string $line + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * @param array $allowed + * + * @return void + */ + protected function appendRootDirective($line, $out, $allowed = [Type::T_COMMENT]) + { + $root = $out; + + while ($root->parent) { + $root = $root->parent; + } + + $i = 0; + + while ($i < \count($root->children)) { + if (! isset($root->children[$i]->type) || ! \in_array($root->children[$i]->type, $allowed)) { + break; + } + + $i++; + } + + // remove incompatible children from the bottom of the list + $saveChildren = []; + + while ($i < \count($root->children)) { + $saveChildren[] = array_pop($root->children); + } + + // insert the directive as a comment + $child = $this->makeOutputBlock(Type::T_COMMENT); + $child->lines[] = $line; + $child->sourceName = $this->sourceNames[$this->sourceIndex]; + $child->sourceLine = $this->sourceLine; + $child->sourceColumn = $this->sourceColumn; + + $root->children[] = $child; + + // repush children + while (\count($saveChildren)) { + $root->children[] = array_pop($saveChildren); + } + } + + /** + * Append lines to the current output block: + * directly to the block or through a child if necessary + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * @param string $type + * @param string $line + * + * @return void + */ + protected function appendOutputLine(OutputBlock $out, $type, $line) + { + $outWrite = &$out; + + // check if it's a flat output or not + if (\count($out->children)) { + $lastChild = &$out->children[\count($out->children) - 1]; + + if ( + $lastChild->depth === $out->depth && + \is_null($lastChild->selectors) && + ! \count($lastChild->children) + ) { + $outWrite = $lastChild; + } else { + $nextLines = $this->makeOutputBlock($type); + $nextLines->parent = $out; + $nextLines->depth = $out->depth; + + $out->children[] = $nextLines; + $outWrite = &$nextLines; + } + } + + $outWrite->lines[] = $line; + } + + /** + * Compile child; returns a value to halt execution + * + * @param array $child + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * + * @return array|Number|null + */ + protected function compileChild($child, OutputBlock $out) + { + if (isset($child[Parser::SOURCE_LINE])) { + $this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null; + $this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1; + $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1; + } elseif (\is_array($child) && isset($child[1]->sourceLine)) { + $this->sourceIndex = $child[1]->sourceIndex; + $this->sourceLine = $child[1]->sourceLine; + $this->sourceColumn = $child[1]->sourceColumn; + } elseif (! empty($out->sourceLine) && ! empty($out->sourceName)) { + $this->sourceLine = $out->sourceLine; + $sourceIndex = array_search($out->sourceName, $this->sourceNames); + $this->sourceColumn = $out->sourceColumn; + + if ($sourceIndex === false) { + $sourceIndex = null; + } + $this->sourceIndex = $sourceIndex; + } + + switch ($child[0]) { + case Type::T_SCSSPHP_IMPORT_ONCE: + $rawPath = $this->reduce($child[1]); + + $this->compileImport($rawPath, $out, true); + break; + + case Type::T_IMPORT: + $rawPath = $this->reduce($child[1]); + + $this->compileImport($rawPath, $out); + break; + + case Type::T_DIRECTIVE: + $this->compileDirective($child[1], $out); + break; + + case Type::T_AT_ROOT: + $this->compileAtRoot($child[1]); + break; + + case Type::T_MEDIA: + $this->compileMedia($child[1]); + break; + + case Type::T_BLOCK: + $this->compileBlock($child[1]); + break; + + case Type::T_CHARSET: + break; + + case Type::T_CUSTOM_PROPERTY: + list(, $name, $value) = $child; + $compiledName = $this->compileValue($name); + + // if the value reduces to null from something else then + // the property should be discarded + if ($value[0] !== Type::T_NULL) { + $value = $this->reduce($value); + + if ($value[0] === Type::T_NULL || $value === static::$nullString) { + break; + } + } + + $compiledValue = $this->compileValue($value); + + $line = $this->formatter->customProperty( + $compiledName, + $compiledValue + ); + + $this->appendOutputLine($out, Type::T_ASSIGN, $line); + break; + + case Type::T_ASSIGN: + list(, $name, $value) = $child; + + if ($name[0] === Type::T_VARIABLE) { + $flags = isset($child[3]) ? $child[3] : []; + $isDefault = \in_array('!default', $flags); + $isGlobal = \in_array('!global', $flags); + + if ($isGlobal) { + $this->set($name[1], $this->reduce($value), false, $this->rootEnv, $value); + break; + } + + $shouldSet = $isDefault && + (\is_null($result = $this->get($name[1], false)) || + $result === static::$null); + + if (! $isDefault || $shouldSet) { + $this->set($name[1], $this->reduce($value), true, null, $value); + } + break; + } + + $compiledName = $this->compileValue($name); + + // handle shorthand syntaxes : size / line-height... + if (\in_array($compiledName, ['font', 'grid-row', 'grid-column', 'border-radius'])) { + if ($value[0] === Type::T_VARIABLE) { + // if the font value comes from variable, the content is already reduced + // (i.e., formulas were already calculated), so we need the original unreduced value + $value = $this->get($value[1], true, null, true); + } + + $shorthandValue=&$value; + + $shorthandDividerNeedsUnit = false; + $maxListElements = null; + $maxShorthandDividers = 1; + + switch ($compiledName) { + case 'border-radius': + $maxListElements = 4; + $shorthandDividerNeedsUnit = true; + break; + } + + if ($compiledName === 'font' && $value[0] === Type::T_LIST && $value[1] === ',') { + // this is the case if more than one font is given: example: "font: 400 1em/1.3 arial,helvetica" + // we need to handle the first list element + $shorthandValue=&$value[2][0]; + } + + if ($shorthandValue[0] === Type::T_EXPRESSION && $shorthandValue[1] === '/') { + $revert = true; + + if ($shorthandDividerNeedsUnit) { + $divider = $shorthandValue[3]; + + if (\is_array($divider)) { + $divider = $this->reduce($divider, true); + } + + if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) { + $revert = false; + } + } + + if ($revert) { + $shorthandValue = $this->expToString($shorthandValue); + } + } elseif ($shorthandValue[0] === Type::T_LIST) { + foreach ($shorthandValue[2] as &$item) { + if ($item[0] === Type::T_EXPRESSION && $item[1] === '/') { + if ($maxShorthandDividers > 0) { + $revert = true; + + // if the list of values is too long, this has to be a shorthand, + // otherwise it could be a real division + if (\is_null($maxListElements) || \count($shorthandValue[2]) <= $maxListElements) { + if ($shorthandDividerNeedsUnit) { + $divider = $item[3]; + + if (\is_array($divider)) { + $divider = $this->reduce($divider, true); + } + + if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) { + $revert = false; + } + } + } + + if ($revert) { + $item = $this->expToString($item); + $maxShorthandDividers--; + } + } + } + } + } + } + + // if the value reduces to null from something else then + // the property should be discarded + if ($value[0] !== Type::T_NULL) { + $value = $this->reduce($value); + + if ($value[0] === Type::T_NULL || $value === static::$nullString) { + break; + } + } + + $compiledValue = $this->compileValue($value); + + // ignore empty value + if (\strlen($compiledValue)) { + $line = $this->formatter->property( + $compiledName, + $compiledValue + ); + $this->appendOutputLine($out, Type::T_ASSIGN, $line); + } + break; + + case Type::T_COMMENT: + if ($out->type === Type::T_ROOT) { + $this->compileComment($child); + break; + } + + $line = $this->compileCommentValue($child, true); + $this->appendOutputLine($out, Type::T_COMMENT, $line); + break; + + case Type::T_MIXIN: + case Type::T_FUNCTION: + list(, $block) = $child; + // the block need to be able to go up to it's parent env to resolve vars + $block->parentEnv = $this->getStoreEnv(); + $this->set(static::$namespaces[$block->type] . $block->name, $block, true); + break; + + case Type::T_EXTEND: + foreach ($child[1] as $sel) { + $replacedSel = $this->replaceSelfSelector($sel); + + if ($replacedSel !== $sel) { + throw $this->error('Parent selectors aren\'t allowed here.'); + } + + $results = $this->evalSelectors([$sel]); + + foreach ($results as $result) { + if (\count($result) !== 1) { + throw $this->error('complex selectors may not be extended.'); + } + + // only use the first one + $result = $result[0]; + $selectors = $out->selectors; + + if (! $selectors && isset($child['selfParent'])) { + $selectors = $this->multiplySelectors($this->env, $child['selfParent']); + } + + if (\count($result) > 1) { + $replacement = implode(', ', $result); + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + + $message = <<logger->warn($message); + } + + $this->pushExtends($result, $selectors, $child); + } + } + break; + + case Type::T_IF: + list(, $if) = $child; + + if ($this->isTruthy($this->reduce($if->cond, true))) { + return $this->compileChildren($if->children, $out); + } + + foreach ($if->cases as $case) { + if ( + $case->type === Type::T_ELSE || + $case->type === Type::T_ELSEIF && $this->isTruthy($this->reduce($case->cond)) + ) { + return $this->compileChildren($case->children, $out); + } + } + break; + + case Type::T_EACH: + list(, $each) = $child; + + $list = $this->coerceList($this->reduce($each->list), ',', true); + + $this->pushEnv(); + + foreach ($list[2] as $item) { + if (\count($each->vars) === 1) { + $this->set($each->vars[0], $item, true); + } else { + list(,, $values) = $this->coerceList($item); + + foreach ($each->vars as $i => $var) { + $this->set($var, isset($values[$i]) ? $values[$i] : static::$null, true); + } + } + + $ret = $this->compileChildren($each->children, $out); + + if ($ret) { + $store = $this->env->store; + $this->popEnv(); + $this->backPropagateEnv($store, $each->vars); + + return $ret; + } + } + $store = $this->env->store; + $this->popEnv(); + $this->backPropagateEnv($store, $each->vars); + + break; + + case Type::T_WHILE: + list(, $while) = $child; + + while ($this->isTruthy($this->reduce($while->cond, true))) { + $ret = $this->compileChildren($while->children, $out); + + if ($ret) { + return $ret; + } + } + break; + + case Type::T_FOR: + list(, $for) = $child; + + $startNumber = $this->assertNumber($this->reduce($for->start, true)); + $endNumber = $this->assertNumber($this->reduce($for->end, true)); + + $start = $this->assertInteger($startNumber); + + $numeratorUnits = $startNumber->getNumeratorUnits(); + $denominatorUnits = $startNumber->getDenominatorUnits(); + + $end = $this->assertInteger($endNumber->coerce($numeratorUnits, $denominatorUnits)); + + $d = $start < $end ? 1 : -1; + + $this->pushEnv(); + + for (;;) { + if ( + (! $for->until && $start - $d == $end) || + ($for->until && $start == $end) + ) { + break; + } + + $this->set($for->var, new Number($start, $numeratorUnits, $denominatorUnits)); + $start += $d; + + $ret = $this->compileChildren($for->children, $out); + + if ($ret) { + $store = $this->env->store; + $this->popEnv(); + $this->backPropagateEnv($store, [$for->var]); + + return $ret; + } + } + + $store = $this->env->store; + $this->popEnv(); + $this->backPropagateEnv($store, [$for->var]); + + break; + + case Type::T_RETURN: + return $this->reduce($child[1], true); + + case Type::T_NESTED_PROPERTY: + $this->compileNestedPropertiesBlock($child[1], $out); + break; + + case Type::T_INCLUDE: + // including a mixin + list(, $name, $argValues, $content, $argUsing) = $child; + + $mixin = $this->get(static::$namespaces['mixin'] . $name, false); + + if (! $mixin) { + throw $this->error("Undefined mixin $name"); + } + + $callingScope = $this->getStoreEnv(); + + // push scope, apply args + $this->pushEnv(); + $this->env->depth--; + + // Find the parent selectors in the env to be able to know what '&' refers to in the mixin + // and assign this fake parent to childs + $selfParent = null; + + if (isset($child['selfParent']) && isset($child['selfParent']->selectors)) { + $selfParent = $child['selfParent']; + } else { + $parentSelectors = $this->multiplySelectors($this->env); + + if ($parentSelectors) { + $parent = new Block(); + $parent->selectors = $parentSelectors; + + foreach ($mixin->children as $k => $child) { + if (isset($child[1]) && \is_object($child[1]) && $child[1] instanceof Block) { + $mixin->children[$k][1]->parent = $parent; + } + } + } + } + + // clone the stored content to not have its scope spoiled by a further call to the same mixin + // i.e., recursive @include of the same mixin + if (isset($content)) { + $copyContent = clone $content; + $copyContent->scope = clone $callingScope; + + $this->setRaw(static::$namespaces['special'] . 'content', $copyContent, $this->env); + } else { + $this->setRaw(static::$namespaces['special'] . 'content', null, $this->env); + } + + // save the "using" argument list for applying it to when "@content" is invoked + if (isset($argUsing)) { + $this->setRaw(static::$namespaces['special'] . 'using', $argUsing, $this->env); + } else { + $this->setRaw(static::$namespaces['special'] . 'using', null, $this->env); + } + + if (isset($mixin->args)) { + $this->applyArguments($mixin->args, $argValues); + } + + $this->env->marker = 'mixin'; + + if (! empty($mixin->parentEnv)) { + $this->env->declarationScopeParent = $mixin->parentEnv; + } else { + throw $this->error("@mixin $name() without parentEnv"); + } + + $this->compileChildrenNoReturn($mixin->children, $out, $selfParent, $this->env->marker . ' ' . $name); + + $this->popEnv(); + break; + + case Type::T_MIXIN_CONTENT: + $env = isset($this->storeEnv) ? $this->storeEnv : $this->env; + $content = $this->get(static::$namespaces['special'] . 'content', false, $env); + $argUsing = $this->get(static::$namespaces['special'] . 'using', false, $env); + $argContent = $child[1]; + + if (! $content) { + break; + } + + $storeEnv = $this->storeEnv; + $varsUsing = []; + + if (isset($argUsing) && isset($argContent)) { + // Get the arguments provided for the content with the names provided in the "using" argument list + $this->storeEnv = null; + $varsUsing = $this->applyArguments($argUsing, $argContent, false); + } + + // restore the scope from the @content + $this->storeEnv = $content->scope; + + // append the vars from using if any + foreach ($varsUsing as $name => $val) { + $this->set($name, $val, true, $this->storeEnv); + } + + $this->compileChildrenNoReturn($content->children, $out); + + $this->storeEnv = $storeEnv; + break; + + case Type::T_DEBUG: + list(, $value) = $child; + + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + $value = $this->compileDebugValue($value); + + $this->logger->debug("$fname:$line DEBUG: $value"); + break; + + case Type::T_WARN: + list(, $value) = $child; + + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + $value = $this->compileDebugValue($value); + + $this->logger->warn("$value\n on line $line of $fname"); + break; + + case Type::T_ERROR: + list(, $value) = $child; + + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + $value = $this->compileValue($this->reduce($value, true)); + + throw $this->error("File $fname on line $line ERROR: $value\n"); + + default: + throw $this->error("unknown child type: $child[0]"); + } + } + + /** + * Reduce expression to string + * + * @param array $exp + * @param bool $keepParens + * + * @return array + */ + protected function expToString($exp, $keepParens = false) + { + list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp; + + $content = []; + + if ($keepParens && $inParens) { + $content[] = '('; + } + + $content[] = $this->reduce($left); + + if ($whiteLeft) { + $content[] = ' '; + } + + $content[] = $op; + + if ($whiteRight) { + $content[] = ' '; + } + + $content[] = $this->reduce($right); + + if ($keepParens && $inParens) { + $content[] = ')'; + } + + return [Type::T_STRING, '', $content]; + } + + /** + * Is truthy? + * + * @param array|Number $value + * + * @return boolean + */ + public function isTruthy($value) + { + return $value !== static::$false && $value !== static::$null; + } + + /** + * Is the value a direct relationship combinator? + * + * @param string $value + * + * @return boolean + */ + protected function isImmediateRelationshipCombinator($value) + { + return $value === '>' || $value === '+' || $value === '~'; + } + + /** + * Should $value cause its operand to eval + * + * @param array $value + * + * @return boolean + */ + protected function shouldEval($value) + { + switch ($value[0]) { + case Type::T_EXPRESSION: + if ($value[1] === '/') { + return $this->shouldEval($value[2]) || $this->shouldEval($value[3]); + } + + // fall-thru + case Type::T_VARIABLE: + case Type::T_FUNCTION_CALL: + return true; + } + + return false; + } + + /** + * Reduce value + * + * @param array|Number $value + * @param boolean $inExp + * + * @return array|Number + */ + protected function reduce($value, $inExp = false) + { + if ($value instanceof Number) { + return $value; + } + + switch ($value[0]) { + case Type::T_EXPRESSION: + list(, $op, $left, $right, $inParens) = $value; + + $opName = isset(static::$operatorNames[$op]) ? static::$operatorNames[$op] : $op; + $inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right); + + $left = $this->reduce($left, true); + + if ($op !== 'and' && $op !== 'or') { + $right = $this->reduce($right, true); + } + + // special case: looks like css shorthand + if ( + $opName == 'div' && ! $inParens && ! $inExp && + (($right[0] !== Type::T_NUMBER && isset($right[2]) && $right[2] != '') || + ($right[0] === Type::T_NUMBER && ! $right->unitless())) + ) { + return $this->expToString($value); + } + + $left = $this->coerceForExpression($left); + $right = $this->coerceForExpression($right); + $ltype = $left[0]; + $rtype = $right[0]; + + $ucOpName = ucfirst($opName); + $ucLType = ucfirst($ltype); + $ucRType = ucfirst($rtype); + + // this tries: + // 1. op[op name][left type][right type] + // 2. op[left type][right type] (passing the op as first arg + // 3. op[op name] + $fn = "op${ucOpName}${ucLType}${ucRType}"; + + if ( + \is_callable([$this, $fn]) || + (($fn = "op${ucLType}${ucRType}") && + \is_callable([$this, $fn]) && + $passOp = true) || + (($fn = "op${ucOpName}") && + \is_callable([$this, $fn]) && + $genOp = true) + ) { + $shouldEval = $inParens || $inExp; + + if (isset($passOp)) { + $out = $this->$fn($op, $left, $right, $shouldEval); + } else { + $out = $this->$fn($left, $right, $shouldEval); + } + + if (isset($out)) { + return $out; + } + } + + return $this->expToString($value); + + case Type::T_UNARY: + list(, $op, $exp, $inParens) = $value; + + $inExp = $inExp || $this->shouldEval($exp); + $exp = $this->reduce($exp); + + if ($exp instanceof Number) { + switch ($op) { + case '+': + return $exp; + + case '-': + return $exp->unaryMinus(); + } + } + + if ($op === 'not') { + if ($inExp || $inParens) { + if ($exp === static::$false || $exp === static::$null) { + return static::$true; + } + + return static::$false; + } + + $op = $op . ' '; + } + + return [Type::T_STRING, '', [$op, $exp]]; + + case Type::T_VARIABLE: + return $this->reduce($this->get($value[1])); + + case Type::T_LIST: + foreach ($value[2] as &$item) { + $item = $this->reduce($item); + } + unset($item); + + if (isset($value[3]) && \is_array($value[3])) { + foreach ($value[3] as &$item) { + $item = $this->reduce($item); + } + unset($item); + } + + return $value; + + case Type::T_MAP: + foreach ($value[1] as &$item) { + $item = $this->reduce($item); + } + + foreach ($value[2] as &$item) { + $item = $this->reduce($item); + } + + return $value; + + case Type::T_STRING: + foreach ($value[2] as &$item) { + if (\is_array($item) || $item instanceof Number) { + $item = $this->reduce($item); + } + } + + return $value; + + case Type::T_INTERPOLATE: + $value[1] = $this->reduce($value[1]); + + if ($inExp) { + return [Type::T_KEYWORD, $this->compileValue($value, false)]; + } + + return $value; + + case Type::T_FUNCTION_CALL: + return $this->fncall($value[1], $value[2]); + + case Type::T_SELF: + $selfParent = ! empty($this->env->block->selfParent) ? $this->env->block->selfParent : null; + $selfSelector = $this->multiplySelectors($this->env, $selfParent); + $selfSelector = $this->collapseSelectorsAsList($selfSelector); + + return $selfSelector; + + default: + return $value; + } + } + + /** + * Function caller + * + * @param string|array $functionReference + * @param array $argValues + * + * @return array|Number + */ + protected function fncall($functionReference, $argValues) + { + // a string means this is a static hard reference coming from the parsing + if (is_string($functionReference)) { + $name = $functionReference; + + $functionReference = $this->getFunctionReference($name); + if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) { + $functionReference = [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]]; + } + } + + // a function type means we just want a plain css function call + if ($functionReference[0] === Type::T_FUNCTION) { + // for CSS functions, simply flatten the arguments into a list + $listArgs = []; + + foreach ((array) $argValues as $arg) { + if (empty($arg[0]) || count($argValues) === 1) { + $listArgs[] = $this->reduce($this->stringifyFncallArgs($arg[1])); + } + } + + return [Type::T_FUNCTION, $functionReference[1], [Type::T_LIST, ',', $listArgs]]; + } + + if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) { + return static::$defaultValue; + } + + + switch ($functionReference[1]) { + // SCSS @function + case 'scss': + return $this->callScssFunction($functionReference[3], $argValues); + + // native PHP functions + case 'user': + case 'native': + list(,,$name, $fn, $prototype) = $functionReference; + + // special cases of css valid functions min/max + $name = strtolower($name); + if (\in_array($name, ['min', 'max']) && count($argValues) >= 1) { + $cssFunction = $this->cssValidArg( + [Type::T_FUNCTION_CALL, $name, $argValues], + ['min', 'max', 'calc', 'env', 'var'] + ); + if ($cssFunction !== false) { + return $cssFunction; + } + } + $returnValue = $this->callNativeFunction($name, $fn, $prototype, $argValues); + + if (! isset($returnValue)) { + return $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $argValues); + } + + return $returnValue; + + default: + return static::$defaultValue; + } + } + + /** + * @param array|Number $arg + * @param string[] $allowed_function + * @param bool $inFunction + * + * @return array|Number|false + */ + protected function cssValidArg($arg, $allowed_function = [], $inFunction = false) + { + if ($arg instanceof Number) { + return $this->stringifyFncallArgs($arg); + } + + switch ($arg[0]) { + case Type::T_INTERPOLATE: + return [Type::T_KEYWORD, $this->CompileValue($arg)]; + + case Type::T_FUNCTION: + if (! \in_array($arg[1], $allowed_function)) { + return false; + } + if ($arg[2][0] === Type::T_LIST) { + foreach ($arg[2][2] as $k => $subarg) { + $arg[2][2][$k] = $this->cssValidArg($subarg, $allowed_function, $arg[1]); + if ($arg[2][2][$k] === false) { + return false; + } + } + } + return $arg; + + case Type::T_FUNCTION_CALL: + if (! \in_array($arg[1], $allowed_function)) { + return false; + } + $cssArgs = []; + foreach ($arg[2] as $argValue) { + if ($argValue === static::$null) { + return false; + } + $cssArg = $this->cssValidArg($argValue[1], $allowed_function, $arg[1]); + if (empty($argValue[0]) && $cssArg !== false) { + $cssArgs[] = [$argValue[0], $cssArg]; + } else { + return false; + } + } + + return $this->fncall([Type::T_FUNCTION, $arg[1], [Type::T_LIST, ',', []]], $cssArgs); + + case Type::T_STRING: + case Type::T_KEYWORD: + if (!$inFunction or !\in_array($inFunction, ['calc', 'env', 'var'])) { + return false; + } + return $this->stringifyFncallArgs($arg); + + case Type::T_LIST: + if (!$inFunction) { + return false; + } + if (empty($arg['enclosing']) and $arg[1] === '') { + foreach ($arg[2] as $k => $subarg) { + $arg[2][$k] = $this->cssValidArg($subarg, $allowed_function, $inFunction); + if ($arg[2][$k] === false) { + return false; + } + } + $arg[0] = Type::T_STRING; + return $arg; + } + return false; + + case Type::T_EXPRESSION: + if (! \in_array($arg[1], ['+', '-', '/', '*'])) { + return false; + } + $arg[2] = $this->cssValidArg($arg[2], $allowed_function, $inFunction); + $arg[3] = $this->cssValidArg($arg[3], $allowed_function, $inFunction); + if ($arg[2] === false || $arg[3] === false) { + return false; + } + return $this->expToString($arg, true); + + case Type::T_VARIABLE: + case Type::T_SELF: + default: + return false; + } + } + + + /** + * Reformat fncall arguments to proper css function output + * + * @param array|Number $arg + * + * @return array|Number + */ + protected function stringifyFncallArgs($arg) + { + if ($arg instanceof Number) { + return $arg; + } + + switch ($arg[0]) { + case Type::T_LIST: + foreach ($arg[2] as $k => $v) { + $arg[2][$k] = $this->stringifyFncallArgs($v); + } + break; + + case Type::T_EXPRESSION: + if ($arg[1] === '/') { + $arg[2] = $this->stringifyFncallArgs($arg[2]); + $arg[3] = $this->stringifyFncallArgs($arg[3]); + $arg[5] = $arg[6] = false; // no space around / + $arg = $this->expToString($arg); + } + break; + + case Type::T_FUNCTION_CALL: + $name = strtolower($arg[1]); + + if (in_array($name, ['max', 'min', 'calc'])) { + $args = $arg[2]; + $arg = $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $args); + } + break; + } + + return $arg; + } + + /** + * Find a function reference + * @param string $name + * @param bool $safeCopy + * @return array + */ + protected function getFunctionReference($name, $safeCopy = false) + { + // SCSS @function + if ($func = $this->get(static::$namespaces['function'] . $name, false)) { + if ($safeCopy) { + $func = clone $func; + } + + return [Type::T_FUNCTION_REFERENCE, 'scss', $name, $func]; + } + + // native PHP functions + + // try to find a native lib function + $normalizedName = $this->normalizeName($name); + + if (isset($this->userFunctions[$normalizedName])) { + // see if we can find a user function + list($f, $prototype) = $this->userFunctions[$normalizedName]; + + return [Type::T_FUNCTION_REFERENCE, 'user', $name, $f, $prototype]; + } + + $lowercasedName = strtolower($normalizedName); + + // Special functions overriding a CSS function are case-insensitive. We normalize them as lowercase + // to avoid the deprecation warning about the wrong case being used. + if ($lowercasedName === 'min' || $lowercasedName === 'max') { + $normalizedName = $lowercasedName; + } + + if (($f = $this->getBuiltinFunction($normalizedName)) && \is_callable($f)) { + $libName = $f[1]; + $prototype = isset(static::$$libName) ? static::$$libName : null; + + // All core functions have a prototype defined. Not finding the + // prototype can mean 2 things: + // - the function comes from a child class (deprecated just after) + // - the function was found with a different case, which relates to calling the + // wrong Sass function due to our camelCase usage (`fade-in()` vs `fadein()`), + // because PHP method names are case-insensitive while property names are + // case-sensitive. + if ($prototype === null || strtolower($normalizedName) !== $normalizedName) { + $r = new \ReflectionMethod($this, $libName); + $actualLibName = $r->name; + + if ($actualLibName !== $libName || strtolower($normalizedName) !== $normalizedName) { + $kebabCaseName = preg_replace('~(?<=\\w)([A-Z])~', '-$1', substr($actualLibName, 3)); + assert($kebabCaseName !== null); + $originalName = strtolower($kebabCaseName); + $warning = "Calling built-in functions with a non-standard name is deprecated since Scssphp 1.8.0 and will not work anymore in 2.0 (they will be treated as CSS function calls instead).\nUse \"$originalName\" instead of \"$name\"."; + @trigger_error($warning, E_USER_DEPRECATED); + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + Warn::deprecation("$warning\n on line $line of $fname"); + + // Use the actual function definition + $prototype = isset(static::$$actualLibName) ? static::$$actualLibName : null; + $f[1] = $libName = $actualLibName; + } + } + + if (\get_class($this) !== __CLASS__ && !isset($this->warnedChildFunctions[$libName])) { + $r = new \ReflectionMethod($this, $libName); + $declaringClass = $r->getDeclaringClass()->name; + + $needsWarning = $this->warnedChildFunctions[$libName] = $declaringClass !== __CLASS__; + + if ($needsWarning) { + if (method_exists(__CLASS__, $libName)) { + @trigger_error(sprintf('Overriding the "%s" core function by extending the Compiler is deprecated and will be unsupported in 2.0. Remove the "%s::%s" method.', $normalizedName, $declaringClass, $libName), E_USER_DEPRECATED); + } else { + @trigger_error(sprintf('Registering custom functions by extending the Compiler and using the lib* discovery mechanism is deprecated and will be removed in 2.0. Replace the "%s::%s" method with registering the "%s" function through "Compiler::registerFunction".', $declaringClass, $libName, $normalizedName), E_USER_DEPRECATED); + } + } + } + + return [Type::T_FUNCTION_REFERENCE, 'native', $name, $f, $prototype]; + } + + return static::$null; + } + + + /** + * Normalize name + * + * @param string $name + * + * @return string + */ + protected function normalizeName($name) + { + return str_replace('-', '_', $name); + } + + /** + * Normalize value + * + * @internal + * + * @param array|Number $value + * + * @return array|Number + */ + public function normalizeValue($value) + { + $value = $this->coerceForExpression($this->reduce($value)); + + if ($value instanceof Number) { + return $value; + } + + switch ($value[0]) { + case Type::T_LIST: + $value = $this->extractInterpolation($value); + + if ($value[0] !== Type::T_LIST) { + return [Type::T_KEYWORD, $this->compileValue($value)]; + } + + foreach ($value[2] as $key => $item) { + $value[2][$key] = $this->normalizeValue($item); + } + + if (! empty($value['enclosing'])) { + unset($value['enclosing']); + } + + return $value; + + case Type::T_STRING: + return [$value[0], '"', [$this->compileStringContent($value)]]; + + case Type::T_INTERPOLATE: + return [Type::T_KEYWORD, $this->compileValue($value)]; + + default: + return $value; + } + } + + /** + * Add numbers + * + * @param Number $left + * @param Number $right + * + * @return Number + */ + protected function opAddNumberNumber(Number $left, Number $right) + { + return $left->plus($right); + } + + /** + * Multiply numbers + * + * @param Number $left + * @param Number $right + * + * @return Number + */ + protected function opMulNumberNumber(Number $left, Number $right) + { + return $left->times($right); + } + + /** + * Subtract numbers + * + * @param Number $left + * @param Number $right + * + * @return Number + */ + protected function opSubNumberNumber(Number $left, Number $right) + { + return $left->minus($right); + } + + /** + * Divide numbers + * + * @param Number $left + * @param Number $right + * + * @return Number + */ + protected function opDivNumberNumber(Number $left, Number $right) + { + return $left->dividedBy($right); + } + + /** + * Mod numbers + * + * @param Number $left + * @param Number $right + * + * @return Number + */ + protected function opModNumberNumber(Number $left, Number $right) + { + return $left->modulo($right); + } + + /** + * Add strings + * + * @param array $left + * @param array $right + * + * @return array|null + */ + protected function opAdd($left, $right) + { + if ($strLeft = $this->coerceString($left)) { + if ($right[0] === Type::T_STRING) { + $right[1] = ''; + } + + $strLeft[2][] = $right; + + return $strLeft; + } + + if ($strRight = $this->coerceString($right)) { + if ($left[0] === Type::T_STRING) { + $left[1] = ''; + } + + array_unshift($strRight[2], $left); + + return $strRight; + } + + return null; + } + + /** + * Boolean and + * + * @param array|Number $left + * @param array|Number $right + * @param boolean $shouldEval + * + * @return array|Number|null + */ + protected function opAnd($left, $right, $shouldEval) + { + $truthy = ($left === static::$null || $right === static::$null) || + ($left === static::$false || $left === static::$true) && + ($right === static::$false || $right === static::$true); + + if (! $shouldEval) { + if (! $truthy) { + return null; + } + } + + if ($left !== static::$false && $left !== static::$null) { + return $this->reduce($right, true); + } + + return $left; + } + + /** + * Boolean or + * + * @param array|Number $left + * @param array|Number $right + * @param boolean $shouldEval + * + * @return array|Number|null + */ + protected function opOr($left, $right, $shouldEval) + { + $truthy = ($left === static::$null || $right === static::$null) || + ($left === static::$false || $left === static::$true) && + ($right === static::$false || $right === static::$true); + + if (! $shouldEval) { + if (! $truthy) { + return null; + } + } + + if ($left !== static::$false && $left !== static::$null) { + return $left; + } + + return $this->reduce($right, true); + } + + /** + * Compare colors + * + * @param string $op + * @param array $left + * @param array $right + * + * @return array + */ + protected function opColorColor($op, $left, $right) + { + if ($op !== '==' && $op !== '!=') { + $warning = "Color arithmetic is deprecated and will be an error in future versions.\n" + . "Consider using Sass's color functions instead."; + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + + Warn::deprecation("$warning\n on line $line of $fname"); + } + + $out = [Type::T_COLOR]; + + foreach ([1, 2, 3] as $i) { + $lval = isset($left[$i]) ? $left[$i] : 0; + $rval = isset($right[$i]) ? $right[$i] : 0; + + switch ($op) { + case '+': + $out[] = $lval + $rval; + break; + + case '-': + $out[] = $lval - $rval; + break; + + case '*': + $out[] = $lval * $rval; + break; + + case '%': + if ($rval == 0) { + throw $this->error("color: Can't take modulo by zero"); + } + + $out[] = $lval % $rval; + break; + + case '/': + if ($rval == 0) { + throw $this->error("color: Can't divide by zero"); + } + + $out[] = (int) ($lval / $rval); + break; + + case '==': + return $this->opEq($left, $right); + + case '!=': + return $this->opNeq($left, $right); + + default: + throw $this->error("color: unknown op $op"); + } + } + + if (isset($left[4])) { + $out[4] = $left[4]; + } elseif (isset($right[4])) { + $out[4] = $right[4]; + } + + return $this->fixColor($out); + } + + /** + * Compare color and number + * + * @param string $op + * @param array $left + * @param Number $right + * + * @return array + */ + protected function opColorNumber($op, $left, Number $right) + { + if ($op === '==') { + return static::$false; + } + + if ($op === '!=') { + return static::$true; + } + + $value = $right->getDimension(); + + return $this->opColorColor( + $op, + $left, + [Type::T_COLOR, $value, $value, $value] + ); + } + + /** + * Compare number and color + * + * @param string $op + * @param Number $left + * @param array $right + * + * @return array + */ + protected function opNumberColor($op, Number $left, $right) + { + if ($op === '==') { + return static::$false; + } + + if ($op === '!=') { + return static::$true; + } + + $value = $left->getDimension(); + + return $this->opColorColor( + $op, + [Type::T_COLOR, $value, $value, $value], + $right + ); + } + + /** + * Compare number1 == number2 + * + * @param array|Number $left + * @param array|Number $right + * + * @return array + */ + protected function opEq($left, $right) + { + if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) { + $lStr[1] = ''; + $rStr[1] = ''; + + $left = $this->compileValue($lStr); + $right = $this->compileValue($rStr); + } + + return $this->toBool($left === $right); + } + + /** + * Compare number1 != number2 + * + * @param array|Number $left + * @param array|Number $right + * + * @return array + */ + protected function opNeq($left, $right) + { + if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) { + $lStr[1] = ''; + $rStr[1] = ''; + + $left = $this->compileValue($lStr); + $right = $this->compileValue($rStr); + } + + return $this->toBool($left !== $right); + } + + /** + * Compare number1 == number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opEqNumberNumber(Number $left, Number $right) + { + return $this->toBool($left->equals($right)); + } + + /** + * Compare number1 != number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opNeqNumberNumber(Number $left, Number $right) + { + return $this->toBool(!$left->equals($right)); + } + + /** + * Compare number1 >= number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opGteNumberNumber(Number $left, Number $right) + { + return $this->toBool($left->greaterThanOrEqual($right)); + } + + /** + * Compare number1 > number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opGtNumberNumber(Number $left, Number $right) + { + return $this->toBool($left->greaterThan($right)); + } + + /** + * Compare number1 <= number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opLteNumberNumber(Number $left, Number $right) + { + return $this->toBool($left->lessThanOrEqual($right)); + } + + /** + * Compare number1 < number2 + * + * @param Number $left + * @param Number $right + * + * @return array + */ + protected function opLtNumberNumber(Number $left, Number $right) + { + return $this->toBool($left->lessThan($right)); + } + + /** + * Cast to boolean + * + * @api + * + * @param bool $thing + * + * @return array + */ + public function toBool($thing) + { + return $thing ? static::$true : static::$false; + } + + /** + * Escape non printable chars in strings output as in dart-sass + * + * @internal + * + * @param string $string + * @param bool $inKeyword + * + * @return string + */ + public function escapeNonPrintableChars($string, $inKeyword = false) + { + static $replacement = []; + if (empty($replacement[$inKeyword])) { + for ($i = 0; $i < 32; $i++) { + if ($i !== 9 || $inKeyword) { + $replacement[$inKeyword][chr($i)] = '\\' . dechex($i) . ($inKeyword ? ' ' : chr(0)); + } + } + } + $string = str_replace(array_keys($replacement[$inKeyword]), array_values($replacement[$inKeyword]), $string); + // chr(0) is not a possible char from the input, so any chr(0) comes from our escaping replacement + if (strpos($string, chr(0)) !== false) { + if (substr($string, -1) === chr(0)) { + $string = substr($string, 0, -1); + } + $string = str_replace( + [chr(0) . '\\',chr(0) . ' '], + [ '\\', ' '], + $string + ); + if (strpos($string, chr(0)) !== false) { + $parts = explode(chr(0), $string); + $string = array_shift($parts); + while (count($parts)) { + $next = array_shift($parts); + if (strpos("0123456789abcdefABCDEF" . chr(9), $next[0]) !== false) { + $string .= " "; + } + $string .= $next; + } + } + } + + return $string; + } + + /** + * Compiles a primitive value into a CSS property value. + * + * Values in scssphp are typed by being wrapped in arrays, their format is + * typically: + * + * array(type, contents [, additional_contents]*) + * + * The input is expected to be reduced. This function will not work on + * things like expressions and variables. + * + * @api + * + * @param array|Number $value + * @param bool $quote + * + * @return string + */ + public function compileValue($value, $quote = true) + { + $value = $this->reduce($value); + + if ($value instanceof Number) { + return $value->output($this); + } + + switch ($value[0]) { + case Type::T_KEYWORD: + return $this->escapeNonPrintableChars($value[1], true); + + case Type::T_COLOR: + // [1] - red component (either number for a %) + // [2] - green component + // [3] - blue component + // [4] - optional alpha component + list(, $r, $g, $b) = $value; + + $r = $this->compileRGBAValue($r); + $g = $this->compileRGBAValue($g); + $b = $this->compileRGBAValue($b); + + if (\count($value) === 5) { + $alpha = $this->compileRGBAValue($value[4], true); + + if (! is_numeric($alpha) || $alpha < 1) { + $colorName = Colors::RGBaToColorName($r, $g, $b, $alpha); + + if (! \is_null($colorName)) { + return $colorName; + } + + if (is_numeric($alpha)) { + $a = new Number($alpha, ''); + } else { + $a = $alpha; + } + + return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')'; + } + } + + if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b)) { + return 'rgb(' . $r . ', ' . $g . ', ' . $b . ')'; + } + + $colorName = Colors::RGBaToColorName($r, $g, $b); + + if (! \is_null($colorName)) { + return $colorName; + } + + $h = sprintf('#%02x%02x%02x', $r, $g, $b); + + // Converting hex color to short notation (e.g. #003399 to #039) + if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) { + $h = '#' . $h[1] . $h[3] . $h[5]; + } + + return $h; + + case Type::T_STRING: + $content = $this->compileStringContent($value, $quote); + + if ($value[1] && $quote) { + $content = str_replace('\\', '\\\\', $content); + + $content = $this->escapeNonPrintableChars($content); + + // force double quote as string quote for the output in certain cases + if ( + $value[1] === "'" && + (strpos($content, '"') === false or strpos($content, "'") !== false) && + strpbrk($content, '{}\\\'') !== false + ) { + $value[1] = '"'; + } elseif ( + $value[1] === '"' && + (strpos($content, '"') !== false and strpos($content, "'") === false) + ) { + $value[1] = "'"; + } + + $content = str_replace($value[1], '\\' . $value[1], $content); + } + + return $value[1] . $content . $value[1]; + + case Type::T_FUNCTION: + $args = ! empty($value[2]) ? $this->compileValue($value[2], $quote) : ''; + + return "$value[1]($args)"; + + case Type::T_FUNCTION_REFERENCE: + $name = ! empty($value[2]) ? $value[2] : ''; + + return "get-function(\"$name\")"; + + case Type::T_LIST: + $value = $this->extractInterpolation($value); + + if ($value[0] !== Type::T_LIST) { + return $this->compileValue($value, $quote); + } + + list(, $delim, $items) = $value; + $pre = $post = ''; + + if (! empty($value['enclosing'])) { + switch ($value['enclosing']) { + case 'parent': + //$pre = '('; + //$post = ')'; + break; + case 'forced_parent': + $pre = '('; + $post = ')'; + break; + case 'bracket': + case 'forced_bracket': + $pre = '['; + $post = ']'; + break; + } + } + + $prefix_value = ''; + + if ($delim !== ' ') { + $prefix_value = ' '; + } + + $filtered = []; + + $same_string_quote = null; + foreach ($items as $item) { + if (\is_null($same_string_quote)) { + $same_string_quote = false; + if ($item[0] === Type::T_STRING) { + $same_string_quote = $item[1]; + foreach ($items as $ii) { + if ($ii[0] !== Type::T_STRING) { + $same_string_quote = false; + break; + } + } + } + } + if ($item[0] === Type::T_NULL) { + continue; + } + if ($same_string_quote === '"' && $item[0] === Type::T_STRING && $item[1]) { + $item[1] = $same_string_quote; + } + + $compiled = $this->compileValue($item, $quote); + + if ($prefix_value && \strlen($compiled)) { + $compiled = $prefix_value . $compiled; + } + + $filtered[] = $compiled; + } + + return $pre . substr(implode("$delim", $filtered), \strlen($prefix_value)) . $post; + + case Type::T_MAP: + $keys = $value[1]; + $values = $value[2]; + $filtered = []; + + for ($i = 0, $s = \count($keys); $i < $s; $i++) { + $filtered[$this->compileValue($keys[$i], $quote)] = $this->compileValue($values[$i], $quote); + } + + array_walk($filtered, function (&$value, $key) { + $value = $key . ': ' . $value; + }); + + return '(' . implode(', ', $filtered) . ')'; + + case Type::T_INTERPOLATED: + // node created by extractInterpolation + list(, $interpolate, $left, $right) = $value; + list(,, $whiteLeft, $whiteRight) = $interpolate; + + $delim = $left[1]; + + if ($delim && $delim !== ' ' && ! $whiteLeft) { + $delim .= ' '; + } + + $left = \count($left[2]) > 0 + ? $this->compileValue($left, $quote) . $delim . $whiteLeft + : ''; + + $delim = $right[1]; + + if ($delim && $delim !== ' ') { + $delim .= ' '; + } + + $right = \count($right[2]) > 0 ? + $whiteRight . $delim . $this->compileValue($right, $quote) : ''; + + return $left . $this->compileValue($interpolate, $quote) . $right; + + case Type::T_INTERPOLATE: + // strip quotes if it's a string + $reduced = $this->reduce($value[1]); + + if ($reduced instanceof Number) { + return $this->compileValue($reduced, $quote); + } + + switch ($reduced[0]) { + case Type::T_LIST: + $reduced = $this->extractInterpolation($reduced); + + if ($reduced[0] !== Type::T_LIST) { + break; + } + + list(, $delim, $items) = $reduced; + + if ($delim !== ' ') { + $delim .= ' '; + } + + $filtered = []; + + foreach ($items as $item) { + if ($item[0] === Type::T_NULL) { + continue; + } + + if ($item[0] === Type::T_STRING) { + $filtered[] = $this->compileStringContent($item, $quote); + } elseif ($item[0] === Type::T_KEYWORD) { + $filtered[] = $item[1]; + } else { + $filtered[] = $this->compileValue($item, $quote); + } + } + + $reduced = [Type::T_KEYWORD, implode("$delim", $filtered)]; + break; + + case Type::T_STRING: + $reduced = [Type::T_STRING, '', [$this->compileStringContent($reduced)]]; + break; + + case Type::T_NULL: + $reduced = [Type::T_KEYWORD, '']; + } + + return $this->compileValue($reduced, $quote); + + case Type::T_NULL: + return 'null'; + + case Type::T_COMMENT: + return $this->compileCommentValue($value); + + default: + throw $this->error('unknown value type: ' . json_encode($value)); + } + } + + /** + * @param array|Number $value + * + * @return string + */ + protected function compileDebugValue($value) + { + $value = $this->reduce($value, true); + + if ($value instanceof Number) { + return $this->compileValue($value); + } + + switch ($value[0]) { + case Type::T_STRING: + return $this->compileStringContent($value); + + default: + return $this->compileValue($value); + } + } + + /** + * Flatten list + * + * @param array $list + * + * @return string + * + * @deprecated + */ + protected function flattenList($list) + { + @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); + + return $this->compileValue($list); + } + + /** + * Gets the text of a Sass string + * + * Calling this method on anything else than a SassString is unsupported. Use {@see assertString} first + * to ensure that the value is indeed a string. + * + * @param array $value + * + * @return string + */ + public function getStringText(array $value) + { + if ($value[0] !== Type::T_STRING) { + throw new \InvalidArgumentException('The argument is not a sass string. Did you forgot to use "assertString"?'); + } + + return $this->compileStringContent($value); + } + + /** + * Compile string content + * + * @param array $string + * @param bool $quote + * + * @return string + */ + protected function compileStringContent($string, $quote = true) + { + $parts = []; + + foreach ($string[2] as $part) { + if (\is_array($part) || $part instanceof Number) { + $parts[] = $this->compileValue($part, $quote); + } else { + $parts[] = $part; + } + } + + return implode($parts); + } + + /** + * Extract interpolation; it doesn't need to be recursive, compileValue will handle that + * + * @param array $list + * + * @return array + */ + protected function extractInterpolation($list) + { + $items = $list[2]; + + foreach ($items as $i => $item) { + if ($item[0] === Type::T_INTERPOLATE) { + $before = [Type::T_LIST, $list[1], \array_slice($items, 0, $i)]; + $after = [Type::T_LIST, $list[1], \array_slice($items, $i + 1)]; + + return [Type::T_INTERPOLATED, $item, $before, $after]; + } + } + + return $list; + } + + /** + * Find the final set of selectors + * + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param \ScssPhp\ScssPhp\Block $selfParent + * + * @return array + */ + protected function multiplySelectors(Environment $env, $selfParent = null) + { + $envs = $this->compactEnv($env); + $selectors = []; + $parentSelectors = [[]]; + + $selfParentSelectors = null; + + if (! \is_null($selfParent) && $selfParent->selectors) { + $selfParentSelectors = $this->evalSelectors($selfParent->selectors); + } + + while ($env = array_pop($envs)) { + if (empty($env->selectors)) { + continue; + } + + $selectors = $env->selectors; + + do { + $stillHasSelf = false; + $prevSelectors = $selectors; + $selectors = []; + + foreach ($parentSelectors as $parent) { + foreach ($prevSelectors as $selector) { + if ($selfParentSelectors) { + foreach ($selfParentSelectors as $selfParent) { + // if no '&' in the selector, each call will give same result, only add once + $s = $this->joinSelectors($parent, $selector, $stillHasSelf, $selfParent); + $selectors[serialize($s)] = $s; + } + } else { + $s = $this->joinSelectors($parent, $selector, $stillHasSelf); + $selectors[serialize($s)] = $s; + } + } + } + } while ($stillHasSelf); + + $parentSelectors = $selectors; + } + + $selectors = array_values($selectors); + + // case we are just starting a at-root : nothing to multiply but parentSelectors + if (! $selectors && $selfParentSelectors) { + $selectors = $selfParentSelectors; + } + + return $selectors; + } + + /** + * Join selectors; looks for & to replace, or append parent before child + * + * @param array $parent + * @param array $child + * @param boolean $stillHasSelf + * @param array $selfParentSelectors + + * @return array + */ + protected function joinSelectors($parent, $child, &$stillHasSelf, $selfParentSelectors = null) + { + $setSelf = false; + $out = []; + + foreach ($child as $part) { + $newPart = []; + + foreach ($part as $p) { + // only replace & once and should be recalled to be able to make combinations + if ($p === static::$selfSelector && $setSelf) { + $stillHasSelf = true; + } + + if ($p === static::$selfSelector && ! $setSelf) { + $setSelf = true; + + if (\is_null($selfParentSelectors)) { + $selfParentSelectors = $parent; + } + + foreach ($selfParentSelectors as $i => $parentPart) { + if ($i > 0) { + $out[] = $newPart; + $newPart = []; + } + + foreach ($parentPart as $pp) { + if (\is_array($pp)) { + $flatten = []; + + array_walk_recursive($pp, function ($a) use (&$flatten) { + $flatten[] = $a; + }); + + $pp = implode($flatten); + } + + $newPart[] = $pp; + } + } + } else { + $newPart[] = $p; + } + } + + $out[] = $newPart; + } + + return $setSelf ? $out : array_merge($parent, $child); + } + + /** + * Multiply media + * + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param array $childQueries + * + * @return array + */ + protected function multiplyMedia(Environment $env = null, $childQueries = null) + { + if ( + ! isset($env) || + ! empty($env->block->type) && $env->block->type !== Type::T_MEDIA + ) { + return $childQueries; + } + + // plain old block, skip + if (empty($env->block->type)) { + return $this->multiplyMedia($env->parent, $childQueries); + } + + $parentQueries = isset($env->block->queryList) + ? $env->block->queryList + : [[[Type::T_MEDIA_VALUE, $env->block->value]]]; + + $store = [$this->env, $this->storeEnv]; + + $this->env = $env; + $this->storeEnv = null; + $parentQueries = $this->evaluateMediaQuery($parentQueries); + + list($this->env, $this->storeEnv) = $store; + + if (\is_null($childQueries)) { + $childQueries = $parentQueries; + } else { + $originalQueries = $childQueries; + $childQueries = []; + + foreach ($parentQueries as $parentQuery) { + foreach ($originalQueries as $childQuery) { + $childQueries[] = array_merge( + $parentQuery, + [[Type::T_MEDIA_TYPE, [Type::T_KEYWORD, 'all']]], + $childQuery + ); + } + } + } + + return $this->multiplyMedia($env->parent, $childQueries); + } + + /** + * Convert env linked list to stack + * + * @param Environment $env + * + * @return Environment[] + * + * @phpstan-return non-empty-array + */ + protected function compactEnv(Environment $env) + { + for ($envs = []; $env; $env = $env->parent) { + $envs[] = $env; + } + + return $envs; + } + + /** + * Convert env stack to singly linked list + * + * @param Environment[] $envs + * + * @return Environment + * + * @phpstan-param non-empty-array $envs + */ + protected function extractEnv($envs) + { + for ($env = null; $e = array_pop($envs);) { + $e->parent = $env; + $env = $e; + } + + return $env; + } + + /** + * Push environment + * + * @param \ScssPhp\ScssPhp\Block $block + * + * @return \ScssPhp\ScssPhp\Compiler\Environment + */ + protected function pushEnv(Block $block = null) + { + $env = new Environment(); + $env->parent = $this->env; + $env->parentStore = $this->storeEnv; + $env->store = []; + $env->block = $block; + $env->depth = isset($this->env->depth) ? $this->env->depth + 1 : 0; + + $this->env = $env; + $this->storeEnv = null; + + return $env; + } + + /** + * Pop environment + * + * @return void + */ + protected function popEnv() + { + $this->storeEnv = $this->env->parentStore; + $this->env = $this->env->parent; + } + + /** + * Propagate vars from a just poped Env (used in @each and @for) + * + * @param array $store + * @param null|string[] $excludedVars + * + * @return void + */ + protected function backPropagateEnv($store, $excludedVars = null) + { + foreach ($store as $key => $value) { + if (empty($excludedVars) || ! \in_array($key, $excludedVars)) { + $this->set($key, $value, true); + } + } + } + + /** + * Get store environment + * + * @return \ScssPhp\ScssPhp\Compiler\Environment + */ + protected function getStoreEnv() + { + return isset($this->storeEnv) ? $this->storeEnv : $this->env; + } + + /** + * Set variable + * + * @param string $name + * @param mixed $value + * @param boolean $shadow + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param mixed $valueUnreduced + * + * @return void + */ + protected function set($name, $value, $shadow = false, Environment $env = null, $valueUnreduced = null) + { + $name = $this->normalizeName($name); + + if (! isset($env)) { + $env = $this->getStoreEnv(); + } + + if ($shadow) { + $this->setRaw($name, $value, $env, $valueUnreduced); + } else { + $this->setExisting($name, $value, $env, $valueUnreduced); + } + } + + /** + * Set existing variable + * + * @param string $name + * @param mixed $value + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param mixed $valueUnreduced + * + * @return void + */ + protected function setExisting($name, $value, Environment $env, $valueUnreduced = null) + { + $storeEnv = $env; + $specialContentKey = static::$namespaces['special'] . 'content'; + + $hasNamespace = $name[0] === '^' || $name[0] === '@' || $name[0] === '%'; + + $maxDepth = 10000; + + for (;;) { + if ($maxDepth-- <= 0) { + break; + } + + if (\array_key_exists($name, $env->store)) { + break; + } + + if (! $hasNamespace && isset($env->marker)) { + if (! empty($env->store[$specialContentKey])) { + $env = $env->store[$specialContentKey]->scope; + continue; + } + + if (! empty($env->declarationScopeParent)) { + $env = $env->declarationScopeParent; + continue; + } else { + $env = $storeEnv; + break; + } + } + + if (isset($env->parentStore)) { + $env = $env->parentStore; + } elseif (isset($env->parent)) { + $env = $env->parent; + } else { + $env = $storeEnv; + break; + } + } + + $env->store[$name] = $value; + + if ($valueUnreduced) { + $env->storeUnreduced[$name] = $valueUnreduced; + } + } + + /** + * Set raw variable + * + * @param string $name + * @param mixed $value + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param mixed $valueUnreduced + * + * @return void + */ + protected function setRaw($name, $value, Environment $env, $valueUnreduced = null) + { + $env->store[$name] = $value; + + if ($valueUnreduced) { + $env->storeUnreduced[$name] = $valueUnreduced; + } + } + + /** + * Get variable + * + * @internal + * + * @param string $name + * @param boolean $shouldThrow + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * @param boolean $unreduced + * + * @return mixed|null + */ + public function get($name, $shouldThrow = true, Environment $env = null, $unreduced = false) + { + $normalizedName = $this->normalizeName($name); + $specialContentKey = static::$namespaces['special'] . 'content'; + + if (! isset($env)) { + $env = $this->getStoreEnv(); + } + + $hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%'; + + $maxDepth = 10000; + + for (;;) { + if ($maxDepth-- <= 0) { + break; + } + + if (\array_key_exists($normalizedName, $env->store)) { + if ($unreduced && isset($env->storeUnreduced[$normalizedName])) { + return $env->storeUnreduced[$normalizedName]; + } + + return $env->store[$normalizedName]; + } + + if (! $hasNamespace && isset($env->marker)) { + if (! empty($env->store[$specialContentKey])) { + $env = $env->store[$specialContentKey]->scope; + continue; + } + + if (! empty($env->declarationScopeParent)) { + $env = $env->declarationScopeParent; + } else { + $env = $this->rootEnv; + } + continue; + } + + if (isset($env->parentStore)) { + $env = $env->parentStore; + } elseif (isset($env->parent)) { + $env = $env->parent; + } else { + break; + } + } + + if ($shouldThrow) { + throw $this->error("Undefined variable \$$name" . ($maxDepth <= 0 ? ' (infinite recursion)' : '')); + } + + // found nothing + return null; + } + + /** + * Has variable? + * + * @param string $name + * @param \ScssPhp\ScssPhp\Compiler\Environment $env + * + * @return boolean + */ + protected function has($name, Environment $env = null) + { + return ! \is_null($this->get($name, false, $env)); + } + + /** + * Inject variables + * + * @param array $args + * + * @return void + */ + protected function injectVariables(array $args) + { + if (empty($args)) { + return; + } + + $parser = $this->parserFactory(__METHOD__); + + foreach ($args as $name => $strValue) { + if ($name[0] === '$') { + $name = substr($name, 1); + } + + if (!\is_string($strValue) || ! $parser->parseValue($strValue, $value)) { + $value = $this->coerceValue($strValue); + } + + $this->set($name, $value); + } + } + + /** + * Replaces variables. + * + * @param array $variables + * + * @return void + */ + public function replaceVariables(array $variables) + { + $this->registeredVars = []; + $this->addVariables($variables); + } + + /** + * Replaces variables. + * + * @param array $variables + * + * @return void + */ + public function addVariables(array $variables) + { + $triggerWarning = false; + + foreach ($variables as $name => $value) { + if (!$value instanceof Number && !\is_array($value)) { + $triggerWarning = true; + } + + $this->registeredVars[$name] = $value; + } + + if ($triggerWarning) { + @trigger_error('Passing raw values to as custom variables to the Compiler is deprecated. Use "\ScssPhp\ScssPhp\ValueConverter::parseValue" or "\ScssPhp\ScssPhp\ValueConverter::fromPhp" to convert them instead.', E_USER_DEPRECATED); + } + } + + /** + * Set variables + * + * @api + * + * @param array $variables + * + * @return void + * + * @deprecated Use "addVariables" or "replaceVariables" instead. + */ + public function setVariables(array $variables) + { + @trigger_error('The method "setVariables" of the Compiler is deprecated. Use the "addVariables" method for the equivalent behavior or "replaceVariables" if merging with previous variables was not desired.'); + + $this->addVariables($variables); + } + + /** + * Unset variable + * + * @api + * + * @param string $name + * + * @return void + */ + public function unsetVariable($name) + { + unset($this->registeredVars[$name]); + } + + /** + * Returns list of variables + * + * @api + * + * @return array + */ + public function getVariables() + { + return $this->registeredVars; + } + + /** + * Adds to list of parsed files + * + * @internal + * + * @param string|null $path + * + * @return void + */ + public function addParsedFile($path) + { + if (! \is_null($path) && is_file($path)) { + $this->parsedFiles[realpath($path)] = filemtime($path); + } + } + + /** + * Returns list of parsed files + * + * @deprecated + * @return array + */ + public function getParsedFiles() + { + @trigger_error('The method "getParsedFiles" of the Compiler is deprecated. Use the "getIncludedFiles" method on the CompilationResult instance returned by compileString() instead. Be careful that the signature of the method is different.', E_USER_DEPRECATED); + return $this->parsedFiles; + } + + /** + * Add import path + * + * @api + * + * @param string|callable $path + * + * @return void + */ + public function addImportPath($path) + { + if (! \in_array($path, $this->importPaths)) { + $this->importPaths[] = $path; + } + } + + /** + * Set import paths + * + * @api + * + * @param string|array $path + * + * @return void + */ + public function setImportPaths($path) + { + $paths = (array) $path; + $actualImportPaths = array_filter($paths, function ($path) { + return $path !== ''; + }); + + $this->legacyCwdImportPath = \count($actualImportPaths) !== \count($paths); + + if ($this->legacyCwdImportPath) { + @trigger_error('Passing an empty string in the import paths to refer to the current working directory is deprecated. If that\'s the intended behavior, the value of "getcwd()" should be used directly instead. If this was used for resolving relative imports of the input alongside "chdir" with the source directory, the path of the input file should be passed to "compileString()" instead.', E_USER_DEPRECATED); + } + + $this->importPaths = $actualImportPaths; + } + + /** + * Set number precision + * + * @api + * + * @param integer $numberPrecision + * + * @return void + * + * @deprecated The number precision is not configurable anymore. The default is enough for all browsers. + */ + public function setNumberPrecision($numberPrecision) + { + @trigger_error('The number precision is not configurable anymore. ' + . 'The default is enough for all browsers.', E_USER_DEPRECATED); + } + + /** + * Sets the output style. + * + * @api + * + * @param string $style One of the OutputStyle constants + * + * @return void + * + * @phpstan-param OutputStyle::* $style + */ + public function setOutputStyle($style) + { + switch ($style) { + case OutputStyle::EXPANDED: + $this->formatter = Expanded::class; + break; + + case OutputStyle::COMPRESSED: + $this->formatter = Compressed::class; + break; + + default: + throw new \InvalidArgumentException(sprintf('Invalid output style "%s".', $style)); + } + } + + /** + * Set formatter + * + * @api + * + * @param string $formatterName + * + * @return void + * + * @deprecated Use {@see setOutputStyle} instead. + */ + public function setFormatter($formatterName) + { + if (!\in_array($formatterName, [Expanded::class, Compressed::class], true)) { + @trigger_error('Formatters other than Expanded and Compressed are deprecated.', E_USER_DEPRECATED); + } + @trigger_error('The method "setFormatter" is deprecated. Use "setOutputStyle" instead.', E_USER_DEPRECATED); + + $this->formatter = $formatterName; + } + + /** + * Set line number style + * + * @api + * + * @param string $lineNumberStyle + * + * @return void + * + * @deprecated The line number output is not supported anymore. Use source maps instead. + */ + public function setLineNumberStyle($lineNumberStyle) + { + @trigger_error('The line number output is not supported anymore. ' + . 'Use source maps instead.', E_USER_DEPRECATED); + } + + /** + * Configures the handling of non-ASCII outputs. + * + * If $charset is `true`, this will include a `@charset` declaration or a + * UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII + * characters. Otherwise, it will never include a `@charset` declaration or a + * byte-order mark. + * + * [byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 + * + * @param bool $charset + * + * @return void + */ + public function setCharset($charset) + { + $this->charset = $charset; + } + + /** + * Enable/disable source maps + * + * @api + * + * @param integer $sourceMap + * + * @return void + * + * @phpstan-param self::SOURCE_MAP_* $sourceMap + */ + public function setSourceMap($sourceMap) + { + $this->sourceMap = $sourceMap; + } + + /** + * Set source map options + * + * @api + * + * @param array $sourceMapOptions + * + * @phpstan-param array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} $sourceMapOptions + * + * @return void + */ + public function setSourceMapOptions($sourceMapOptions) + { + $this->sourceMapOptions = $sourceMapOptions; + } + + /** + * Register function + * + * @api + * + * @param string $name + * @param callable $callback + * @param string[]|null $argumentDeclaration + * + * @return void + */ + public function registerFunction($name, $callback, $argumentDeclaration = null) + { + if (self::isNativeFunction($name)) { + @trigger_error(sprintf('The "%s" function is a core sass function. Overriding it with a custom implementation through "%s" is deprecated and won\'t be supported in ScssPhp 2.0 anymore.', $name, __METHOD__), E_USER_DEPRECATED); + } + + if ($argumentDeclaration === null) { + @trigger_error('Omitting the argument declaration when registering custom function is deprecated and won\'t be supported in ScssPhp 2.0 anymore.', E_USER_DEPRECATED); + } + + $this->userFunctions[$this->normalizeName($name)] = [$callback, $argumentDeclaration]; + } + + /** + * Unregister function + * + * @api + * + * @param string $name + * + * @return void + */ + public function unregisterFunction($name) + { + unset($this->userFunctions[$this->normalizeName($name)]); + } + + /** + * Add feature + * + * @api + * + * @param string $name + * + * @return void + * + * @deprecated Registering additional features is deprecated. + */ + public function addFeature($name) + { + @trigger_error('Registering additional features is deprecated.', E_USER_DEPRECATED); + + $this->registeredFeatures[$name] = true; + } + + /** + * Import file + * + * @param string $path + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out + * + * @return void + */ + protected function importFile($path, OutputBlock $out) + { + $this->pushCallStack('import ' . $this->getPrettyPath($path)); + // see if tree is cached + $realPath = realpath($path); + + if (substr($path, -5) === '.sass') { + $this->sourceIndex = \count($this->sourceNames); + $this->sourceNames[] = $path; + $this->sourceLine = 1; + $this->sourceColumn = 1; + + throw $this->error('The Sass indented syntax is not implemented.'); + } + + if (isset($this->importCache[$realPath])) { + $this->handleImportLoop($realPath); + + $tree = $this->importCache[$realPath]; + } else { + $code = file_get_contents($path); + $parser = $this->parserFactory($path); + $tree = $parser->parse($code); + + $this->importCache[$realPath] = $tree; + } + + $currentDirectory = $this->currentDirectory; + $this->currentDirectory = dirname($path); + + $this->compileChildrenNoReturn($tree->children, $out); + $this->currentDirectory = $currentDirectory; + $this->popCallStack(); + } + + /** + * Save the imported files with their resolving path context + * + * @param string|null $currentDirectory + * @param string $path + * @param string $filePath + * + * @return void + */ + private function registerImport($currentDirectory, $path, $filePath) + { + $this->resolvedImports[] = ['currentDir' => $currentDirectory, 'path' => $path, 'filePath' => $filePath]; + } + + /** + * Detects whether the import is a CSS import. + * + * For legacy reasons, custom importers are called for those, allowing them + * to replace them with an actual Sass import. However this behavior is + * deprecated. Custom importers are expected to return null when they receive + * a CSS import. + * + * @param string $url + * + * @return bool + */ + public static function isCssImport($url) + { + return 1 === preg_match('~\.css$|^https?://|^//~', $url); + } + + /** + * Return the file path for an import url if it exists + * + * @internal + * + * @param string $url + * @param string|null $currentDir + * + * @return string|null + */ + public function findImport($url, $currentDir = null) + { + // Vanilla css and external requests. These are not meant to be Sass imports. + // Callback importers are still called for BC. + if (self::isCssImport($url)) { + foreach ($this->importPaths as $dir) { + if (\is_string($dir)) { + continue; + } + + if (\is_callable($dir)) { + // check custom callback for import path + $file = \call_user_func($dir, $url); + + if (! \is_null($file)) { + if (\is_array($dir)) { + $callableDescription = (\is_object($dir[0]) ? \get_class($dir[0]) : $dir[0]).'::'.$dir[1]; + } elseif ($dir instanceof \Closure) { + $r = new \ReflectionFunction($dir); + if (false !== strpos($r->name, '{closure}')) { + $callableDescription = sprintf('closure{%s:%s}', $r->getFileName(), $r->getStartLine()); + } elseif ($class = $r->getClosureScopeClass()) { + $callableDescription = $class->name.'::'.$r->name; + } else { + $callableDescription = $r->name; + } + } elseif (\is_object($dir)) { + $callableDescription = \get_class($dir) . '::__invoke'; + } else { + $callableDescription = 'callable'; // Fallback if we don't have a dedicated description + } + @trigger_error(sprintf('Returning a file to import for CSS or external references in custom importer callables is deprecated and will not be supported anymore in ScssPhp 2.0. This behavior is not compliant with the Sass specification. Update your "%s" importer.', $callableDescription), E_USER_DEPRECATED); + + return $file; + } + } + } + return null; + } + + if (!\is_null($currentDir)) { + $relativePath = $this->resolveImportPath($url, $currentDir); + + if (!\is_null($relativePath)) { + return $relativePath; + } + } + + foreach ($this->importPaths as $dir) { + if (\is_string($dir)) { + $path = $this->resolveImportPath($url, $dir); + + if (!\is_null($path)) { + return $path; + } + } elseif (\is_callable($dir)) { + // check custom callback for import path + $file = \call_user_func($dir, $url); + + if (! \is_null($file)) { + return $file; + } + } + } + + if ($this->legacyCwdImportPath) { + $path = $this->resolveImportPath($url, getcwd()); + + if (!\is_null($path)) { + @trigger_error('Resolving imports relatively to the current working directory is deprecated. If that\'s the intended behavior, the value of "getcwd()" should be added as an import path explicitly instead. If this was used for resolving relative imports of the input alongside "chdir" with the source directory, the path of the input file should be passed to "compileString()" instead.', E_USER_DEPRECATED); + + return $path; + } + } + + throw $this->error("`$url` file not found for @import"); + } + + /** + * @param string $url + * @param string $baseDir + * + * @return string|null + */ + private function resolveImportPath($url, $baseDir) + { + $path = Path::join($baseDir, $url); + + $hasExtension = preg_match('/.s[ac]ss$/', $url); + + if ($hasExtension) { + return $this->checkImportPathConflicts($this->tryImportPath($path)); + } + + $result = $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path)); + + if (!\is_null($result)) { + return $result; + } + + return $this->tryImportPathAsDirectory($path); + } + + /** + * @param string[] $paths + * + * @return string|null + */ + private function checkImportPathConflicts(array $paths) + { + if (\count($paths) === 0) { + return null; + } + + if (\count($paths) === 1) { + return $paths[0]; + } + + $formattedPrettyPaths = []; + + foreach ($paths as $path) { + $formattedPrettyPaths[] = ' ' . $this->getPrettyPath($path); + } + + throw $this->error("It's not clear which file to import. Found:\n" . implode("\n", $formattedPrettyPaths)); + } + + /** + * @param string $path + * + * @return string[] + */ + private function tryImportPathWithExtensions($path) + { + $result = array_merge( + $this->tryImportPath($path.'.sass'), + $this->tryImportPath($path.'.scss') + ); + + if ($result) { + return $result; + } + + return $this->tryImportPath($path.'.css'); + } + + /** + * @param string $path + * + * @return string[] + */ + private function tryImportPath($path) + { + $partial = dirname($path).'/_'.basename($path); + + $candidates = []; + + if (is_file($partial)) { + $candidates[] = $partial; + } + + if (is_file($path)) { + $candidates[] = $path; + } + + return $candidates; + } + + /** + * @param string $path + * + * @return string|null + */ + private function tryImportPathAsDirectory($path) + { + if (!is_dir($path)) { + return null; + } + + return $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path.'/index')); + } + + /** + * @param string|null $path + * + * @return string + */ + private function getPrettyPath($path) + { + if ($path === null) { + return '(unknown file)'; + } + + $normalizedPath = $path; + $normalizedRootDirectory = $this->rootDirectory.'/'; + + if (\DIRECTORY_SEPARATOR === '\\') { + $normalizedRootDirectory = str_replace('\\', '/', $normalizedRootDirectory); + $normalizedPath = str_replace('\\', '/', $path); + } + + if (0 === strpos($normalizedPath, $normalizedRootDirectory)) { + return substr($path, \strlen($normalizedRootDirectory)); + } + + return $path; + } + + /** + * Set encoding + * + * @api + * + * @param string|null $encoding + * + * @return void + * + * @deprecated Non-compliant support for other encodings than UTF-8 is deprecated. + */ + public function setEncoding($encoding) + { + if (!$encoding || strtolower($encoding) === 'utf-8') { + @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); + } else { + @trigger_error(sprintf('The "%s" method is deprecated. Parsing will only support UTF-8 in ScssPhp 2.0. The non-UTF-8 parsing of ScssPhp 1.x is not spec compliant.', __METHOD__), E_USER_DEPRECATED); + } + + $this->encoding = $encoding; + } + + /** + * Ignore errors? + * + * @api + * + * @param boolean $ignoreErrors + * + * @return \ScssPhp\ScssPhp\Compiler + * + * @deprecated Ignoring Sass errors is not longer supported. + */ + public function setIgnoreErrors($ignoreErrors) + { + @trigger_error('Ignoring Sass errors is not longer supported.', E_USER_DEPRECATED); + + return $this; + } + + /** + * Get source position + * + * @api + * + * @return array + * + * @deprecated + */ + public function getSourcePosition() + { + @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); + + $sourceFile = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] : ''; + + return [$sourceFile, $this->sourceLine, $this->sourceColumn]; + } + + /** + * Throw error (exception) + * + * @api + * + * @param string $msg Message with optional sprintf()-style vararg parameters + * + * @throws \ScssPhp\ScssPhp\Exception\CompilerException + * + * @deprecated use "error" and throw the exception in the caller instead. + */ + public function throwError($msg) + { + @trigger_error( + 'The method "throwError" is deprecated. Use "error" and throw the exception in the caller instead', + E_USER_DEPRECATED + ); + + throw $this->error(...func_get_args()); + } + + /** + * Build an error (exception) + * + * @internal + * + * @param string $msg Message with optional sprintf()-style vararg parameters + * + * @return CompilerException + */ + public function error($msg, ...$args) + { + if ($args) { + $msg = sprintf($msg, ...$args); + } + + if (! $this->ignoreCallStackMessage) { + $msg = $this->addLocationToMessage($msg); + } + + return new CompilerException($msg); + } + + /** + * @param string $msg + * + * @return string + */ + private function addLocationToMessage($msg) + { + $line = $this->sourceLine; + $column = $this->sourceColumn; + + $loc = isset($this->sourceNames[$this->sourceIndex]) + ? $this->getPrettyPath($this->sourceNames[$this->sourceIndex]) . " on line $line, at column $column" + : "line: $line, column: $column"; + + $msg = "$msg: $loc"; + + $callStackMsg = $this->callStackMessage(); + + if ($callStackMsg) { + $msg .= "\nCall Stack:\n" . $callStackMsg; + } + + return $msg; + } + + /** + * @param string $functionName + * @param array $ExpectedArgs + * @param int $nbActual + * @return CompilerException + * + * @deprecated + */ + public function errorArgsNumber($functionName, $ExpectedArgs, $nbActual) + { + @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); + + $nbExpected = \count($ExpectedArgs); + + if ($nbActual > $nbExpected) { + return $this->error( + 'Error: Only %d arguments allowed in %s(), but %d were passed.', + $nbExpected, + $functionName, + $nbActual + ); + } else { + $missing = []; + + while (count($ExpectedArgs) && count($ExpectedArgs) > $nbActual) { + array_unshift($missing, array_pop($ExpectedArgs)); + } + + return $this->error( + 'Error: %s() argument%s %s missing.', + $functionName, + count($missing) > 1 ? 's' : '', + implode(', ', $missing) + ); + } + } + + /** + * Beautify call stack for output + * + * @param boolean $all + * @param int|null $limit + * + * @return string + */ + protected function callStackMessage($all = false, $limit = null) + { + $callStackMsg = []; + $ncall = 0; + + if ($this->callStack) { + foreach (array_reverse($this->callStack) as $call) { + if ($all || (isset($call['n']) && $call['n'])) { + $msg = '#' . $ncall++ . ' ' . $call['n'] . ' '; + $msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]]) + ? $this->getPrettyPath($this->sourceNames[$call[Parser::SOURCE_INDEX]]) + : '(unknown file)'); + $msg .= ' on line ' . $call[Parser::SOURCE_LINE]; + + $callStackMsg[] = $msg; + + if (! \is_null($limit) && $ncall > $limit) { + break; + } + } + } + } + + return implode("\n", $callStackMsg); + } + + /** + * Handle import loop + * + * @param string $name + * + * @throws \Exception + */ + protected function handleImportLoop($name) + { + for ($env = $this->env; $env; $env = $env->parent) { + if (! $env->block) { + continue; + } + + $file = $this->sourceNames[$env->block->sourceIndex]; + + if ($file === null) { + continue; + } + + if (realpath($file) === $name) { + throw $this->error('An @import loop has been found: %s imports %s', $file, basename($file)); + } + } + } + + /** + * Call SCSS @function + * + * @param Object $func + * @param array $argValues + * + * @return array|Number + */ + protected function callScssFunction($func, $argValues) + { + if (! $func) { + return static::$defaultValue; + } + $name = $func->name; + + $this->pushEnv(); + + // set the args + if (isset($func->args)) { + $this->applyArguments($func->args, $argValues); + } + + // throw away lines and children + $tmp = new OutputBlock(); + $tmp->lines = []; + $tmp->children = []; + + $this->env->marker = 'function'; + + if (! empty($func->parentEnv)) { + $this->env->declarationScopeParent = $func->parentEnv; + } else { + throw $this->error("@function $name() without parentEnv"); + } + + $ret = $this->compileChildren($func->children, $tmp, $this->env->marker . ' ' . $name); + + $this->popEnv(); + + return ! isset($ret) ? static::$defaultValue : $ret; + } + + /** + * Call built-in and registered (PHP) functions + * + * @param string $name + * @param callable $function + * @param array $prototype + * @param array $args + * + * @return array|Number|null + */ + protected function callNativeFunction($name, $function, $prototype, $args) + { + $libName = (is_array($function) ? end($function) : null); + $sorted_kwargs = $this->sortNativeFunctionArgs($libName, $prototype, $args); + + if (\is_null($sorted_kwargs)) { + return null; + } + @list($sorted, $kwargs) = $sorted_kwargs; + + if ($name !== 'if') { + foreach ($sorted as &$val) { + if ($val !== null) { + $val = $this->reduce($val, true); + } + } + } + + $returnValue = \call_user_func($function, $sorted, $kwargs); + + if (! isset($returnValue)) { + return null; + } + + if (\is_array($returnValue) || $returnValue instanceof Number) { + return $returnValue; + } + + @trigger_error(sprintf('Returning a PHP value from the "%s" custom function is deprecated. A sass value must be returned instead.', $name), E_USER_DEPRECATED); + + return $this->coerceValue($returnValue); + } + + /** + * Get built-in function + * + * @param string $name Normalized name + * + * @return array + */ + protected function getBuiltinFunction($name) + { + $libName = self::normalizeNativeFunctionName($name); + return [$this, $libName]; + } + + /** + * Normalize native function name + * + * @internal + * + * @param string $name + * + * @return string + */ + public static function normalizeNativeFunctionName($name) + { + $name = str_replace("-", "_", $name); + $libName = 'lib' . preg_replace_callback( + '/_(.)/', + function ($m) { + return ucfirst($m[1]); + }, + ucfirst($name) + ); + return $libName; + } + + /** + * Check if a function is a native built-in scss function, for css parsing + * + * @internal + * + * @param string $name + * + * @return bool + */ + public static function isNativeFunction($name) + { + return method_exists(Compiler::class, self::normalizeNativeFunctionName($name)); + } + + /** + * Sorts keyword arguments + * + * @param string $functionName + * @param array|null $prototypes + * @param array $args + * + * @return array|null + */ + protected function sortNativeFunctionArgs($functionName, $prototypes, $args) + { + static $parser = null; + + if (! isset($prototypes)) { + $keyArgs = []; + $posArgs = []; + + if (\is_array($args) && \count($args) && \end($args) === static::$null) { + array_pop($args); + } + + // separate positional and keyword arguments + foreach ($args as $arg) { + list($key, $value) = $arg; + + if (empty($key) or empty($key[1])) { + $posArgs[] = empty($arg[2]) ? $value : $arg; + } else { + $keyArgs[$key[1]] = $value; + } + } + + return [$posArgs, $keyArgs]; + } + + // specific cases ? + if (\in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) { + // notation 100 127 255 / 0 is in fact a simple list of 4 values + foreach ($args as $k => $arg) { + if ($arg[1][0] === Type::T_LIST && \count($arg[1][2]) === 3) { + $args[$k][1][2] = $this->extractSlashAlphaInColorFunction($arg[1][2]); + } + } + } + + list($positionalArgs, $namedArgs, $names, $separator, $hasSplat) = $this->evaluateArguments($args, false); + + if (! \is_array(reset($prototypes))) { + $prototypes = [$prototypes]; + } + + $parsedPrototypes = array_map([$this, 'parseFunctionPrototype'], $prototypes); + assert(!empty($parsedPrototypes)); + $matchedPrototype = $this->selectFunctionPrototype($parsedPrototypes, \count($positionalArgs), $names); + + $this->verifyPrototype($matchedPrototype, \count($positionalArgs), $names, $hasSplat); + + $vars = $this->applyArgumentsToDeclaration($matchedPrototype, $positionalArgs, $namedArgs, $separator); + + $finalArgs = []; + $keyArgs = []; + + foreach ($matchedPrototype['arguments'] as $argument) { + list($normalizedName, $originalName, $default) = $argument; + + if (isset($vars[$normalizedName])) { + $value = $vars[$normalizedName]; + } else { + $value = $default; + } + + // special null value as default: translate to real null here + if ($value === [Type::T_KEYWORD, 'null']) { + $value = null; + } + + $finalArgs[] = $value; + $keyArgs[$originalName] = $value; + } + + if ($matchedPrototype['rest_argument'] !== null) { + $value = $vars[$matchedPrototype['rest_argument']]; + + $finalArgs[] = $value; + $keyArgs[$matchedPrototype['rest_argument']] = $value; + } + + return [$finalArgs, $keyArgs]; + } + + /** + * Parses a function prototype to the internal representation of arguments. + * + * The input is an array of strings describing each argument, as supported + * in {@see registerFunction}. Argument names don't include the `$`. + * The output contains the list of positional argument, with their normalized + * name (underscores are replaced by dashes), their original name (to be used + * in case of error reporting) and their default value. The output also contains + * the normalized name of the rest argument, or null if the function prototype + * is not variadic. + * + * @param string[] $prototype + * + * @return array + * @phpstan-return array{arguments: list, rest_argument: string|null} + */ + private function parseFunctionPrototype(array $prototype) + { + static $parser = null; + + $arguments = []; + $restArgument = null; + + foreach ($prototype as $p) { + if (null !== $restArgument) { + throw new \InvalidArgumentException('The argument declaration is invalid. The rest argument must be the last one.'); + } + + $default = null; + $p = explode(':', $p, 2); + $name = str_replace('_', '-', $p[0]); + + if (isset($p[1])) { + $defaultSource = trim($p[1]); + + if ($defaultSource === 'null') { + // differentiate this null from the static::$null + $default = [Type::T_KEYWORD, 'null']; + } else { + if (\is_null($parser)) { + $parser = $this->parserFactory(__METHOD__); + } + + $parser->parseValue($defaultSource, $default); + } + } + + if (substr($name, -3) === '...') { + $restArgument = substr($name, 0, -3); + } else { + $arguments[] = [$name, $p[0], $default]; + } + } + + return [ + 'arguments' => $arguments, + 'rest_argument' => $restArgument, + ]; + } + + /** + * Returns the function prototype for the given positional and named arguments. + * + * If no exact match is found, finds the closest approximation. Note that this + * doesn't guarantee that $positional and $names are valid for the returned + * prototype. + * + * @param array[] $prototypes + * @param int $positional + * @param array $names A set of names, as both keys and values + * + * @return array + * + * @phpstan-param non-empty-list, rest_argument: string|null}> $prototypes + * @phpstan-return array{arguments: list, rest_argument: string|null} + */ + private function selectFunctionPrototype(array $prototypes, $positional, array $names) + { + $fuzzyMatch = null; + $minMismatchDistance = null; + + foreach ($prototypes as $prototype) { + // Ideally, find an exact match. + if ($this->checkPrototypeMatches($prototype, $positional, $names)) { + return $prototype; + } + + $mismatchDistance = \count($prototype['arguments']) - $positional; + + if ($minMismatchDistance !== null) { + if (abs($mismatchDistance) > abs($minMismatchDistance)) { + continue; + } + + // If two overloads have the same mismatch distance, favor the overload + // that has more arguments. + if (abs($mismatchDistance) === abs($minMismatchDistance) && $mismatchDistance < 0) { + continue; + } + } + + $minMismatchDistance = $mismatchDistance; + $fuzzyMatch = $prototype; + } + + return $fuzzyMatch; + } + + /** + * Checks whether the argument invocation matches the callable prototype. + * + * The rules are similar to {@see verifyPrototype}. The boolean return value + * avoids the overhead of building and catching exceptions when the reason of + * not matching the prototype does not need to be known. + * + * @param array $prototype + * @param int $positional + * @param array $names + * + * @return bool + * + * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype + */ + private function checkPrototypeMatches(array $prototype, $positional, array $names) + { + $nameUsed = 0; + + foreach ($prototype['arguments'] as $i => $argument) { + list ($name, $originalName, $default) = $argument; + + if ($i < $positional) { + if (isset($names[$name])) { + return false; + } + } elseif (isset($names[$name])) { + $nameUsed++; + } elseif ($default === null) { + return false; + } + } + + if ($prototype['rest_argument'] !== null) { + return true; + } + + if ($positional > \count($prototype['arguments'])) { + return false; + } + + if ($nameUsed < \count($names)) { + return false; + } + + return true; + } + + /** + * Verifies that the argument invocation is valid for the callable prototype. + * + * @param array $prototype + * @param int $positional + * @param array $names + * @param bool $hasSplat + * + * @return void + * + * @throws SassScriptException + * + * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype + */ + private function verifyPrototype(array $prototype, $positional, array $names, $hasSplat) + { + $nameUsed = 0; + + foreach ($prototype['arguments'] as $i => $argument) { + list ($name, $originalName, $default) = $argument; + + if ($i < $positional) { + if (isset($names[$name])) { + throw new SassScriptException(sprintf('Argument $%s was passed both by position and by name.', $originalName)); + } + } elseif (isset($names[$name])) { + $nameUsed++; + } elseif ($default === null) { + throw new SassScriptException(sprintf('Missing argument $%s', $originalName)); + } + } + + if ($prototype['rest_argument'] !== null) { + return; + } + + if ($positional > \count($prototype['arguments'])) { + $message = sprintf( + 'Only %d %sargument%s allowed, but %d %s passed.', + \count($prototype['arguments']), + empty($names) ? '' : 'positional ', + \count($prototype['arguments']) === 1 ? '' : 's', + $positional, + $positional === 1 ? 'was' : 'were' + ); + if (!$hasSplat) { + throw new SassScriptException($message); + } + + $message = $this->addLocationToMessage($message); + $message .= "\nThis will be an error in future versions of Sass."; + $this->logger->warn($message, true); + } + + if ($nameUsed < \count($names)) { + $unknownNames = array_values(array_diff($names, array_column($prototype['arguments'], 0))); + $lastName = array_pop($unknownNames); + $message = sprintf( + 'No argument%s named $%s%s.', + $unknownNames ? 's' : '', + $unknownNames ? implode(', $', $unknownNames) . ' or $' : '', + $lastName + ); + throw new SassScriptException($message); + } + } + + /** + * Evaluates the argument from the invocation. + * + * This returns several things about this invocation: + * - the list of positional arguments + * - the map of named arguments, indexed by normalized names + * - the set of names used in the arguments (that's an array using the normalized names as keys for O(1) access) + * - the separator used by the list using the splat operator, if any + * - a boolean indicator whether any splat argument (list or map) was used, to support the incomplete error reporting. + * + * @param array[] $args + * @param bool $reduce Whether arguments should be reduced to their value + * + * @return array + * + * @throws SassScriptException + * + * @phpstan-return array{0: list, 1: array, 2: array, 3: string|null, 4: bool} + */ + private function evaluateArguments(array $args, $reduce = true) + { + // this represents trailing commas + if (\count($args) && end($args) === static::$null) { + array_pop($args); + } + + $splatSeparator = null; + $keywordArgs = []; + $names = []; + $positionalArgs = []; + $hasKeywordArgument = false; + $hasSplat = false; + + foreach ($args as $arg) { + if (!empty($arg[0])) { + $hasKeywordArgument = true; + + assert(\is_string($arg[0][1])); + $name = str_replace('_', '-', $arg[0][1]); + + if (isset($keywordArgs[$name])) { + throw new SassScriptException(sprintf('Duplicate named argument $%s.', $arg[0][1])); + } + + $keywordArgs[$name] = $this->maybeReduce($reduce, $arg[1]); + $names[$name] = $name; + } elseif (! empty($arg[2])) { + // $arg[2] means a var followed by ... in the arg ($list... ) + $val = $this->reduce($arg[1], true); + $hasSplat = true; + + if ($val[0] === Type::T_LIST) { + foreach ($val[2] as $item) { + if (\is_null($splatSeparator)) { + $splatSeparator = $val[1]; + } + + $positionalArgs[] = $this->maybeReduce($reduce, $item); + } + + if (isset($val[3]) && \is_array($val[3])) { + foreach ($val[3] as $name => $item) { + assert(\is_string($name)); + + $normalizedName = str_replace('_', '-', $name); + + if (isset($keywordArgs[$normalizedName])) { + throw new SassScriptException(sprintf('Duplicate named argument $%s.', $name)); + } + + $keywordArgs[$normalizedName] = $this->maybeReduce($reduce, $item); + $names[$normalizedName] = $normalizedName; + $hasKeywordArgument = true; + } + } + } elseif ($val[0] === Type::T_MAP) { + foreach ($val[1] as $i => $name) { + $name = $this->compileStringContent($this->coerceString($name)); + $item = $val[2][$i]; + + if (! is_numeric($name)) { + $normalizedName = str_replace('_', '-', $name); + + if (isset($keywordArgs[$normalizedName])) { + throw new SassScriptException(sprintf('Duplicate named argument $%s.', $name)); + } + + $keywordArgs[$normalizedName] = $this->maybeReduce($reduce, $item); + $names[$normalizedName] = $normalizedName; + $hasKeywordArgument = true; + } else { + if (\is_null($splatSeparator)) { + $splatSeparator = $val[1]; + } + + $positionalArgs[] = $this->maybeReduce($reduce, $item); + } + } + } elseif ($val[0] !== Type::T_NULL) { // values other than null are treated a single-element lists, while null is the empty list + $positionalArgs[] = $this->maybeReduce($reduce, $val); + } + } elseif ($hasKeywordArgument) { + throw new SassScriptException('Positional arguments must come before keyword arguments.'); + } else { + $positionalArgs[] = $this->maybeReduce($reduce, $arg[1]); + } + } + + return [$positionalArgs, $keywordArgs, $names, $splatSeparator, $hasSplat]; + } + + /** + * @param bool $reduce + * @param array|Number $value + * + * @return array|Number + */ + private function maybeReduce($reduce, $value) + { + if ($reduce) { + return $this->reduce($value, true); + } + + return $value; + } + + /** + * Apply argument values per definition + * + * @param array[] $argDef + * @param array|null $argValues + * @param boolean $storeInEnv + * @param boolean $reduce + * only used if $storeInEnv = false + * + * @return array + * + * @phpstan-param list $argDef + * + * @throws \Exception + */ + protected function applyArguments($argDef, $argValues, $storeInEnv = true, $reduce = true) + { + $output = []; + + if (\is_null($argValues)) { + $argValues = []; + } + + if ($storeInEnv) { + $storeEnv = $this->getStoreEnv(); + + $env = new Environment(); + $env->store = $storeEnv->store; + } + + $prototype = ['arguments' => [], 'rest_argument' => null]; + $originalRestArgumentName = null; + + foreach ($argDef as $i => $arg) { + list($name, $default, $isVariable) = $arg; + $normalizedName = str_replace('_', '-', $name); + + if ($isVariable) { + $originalRestArgumentName = $name; + $prototype['rest_argument'] = $normalizedName; + } else { + $prototype['arguments'][] = [$normalizedName, $name, !empty($default) ? $default : null]; + } + } + + list($positionalArgs, $namedArgs, $names, $splatSeparator, $hasSplat) = $this->evaluateArguments($argValues, $reduce); + + $this->verifyPrototype($prototype, \count($positionalArgs), $names, $hasSplat); + + $vars = $this->applyArgumentsToDeclaration($prototype, $positionalArgs, $namedArgs, $splatSeparator); + + foreach ($prototype['arguments'] as $argument) { + list($normalizedName, $name) = $argument; + + if (!isset($vars[$normalizedName])) { + continue; + } + + $val = $vars[$normalizedName]; + + if ($storeInEnv) { + $this->set($name, $this->reduce($val, true), true, $env); + } else { + $output[$name] = ($reduce ? $this->reduce($val, true) : $val); + } + } + + if ($prototype['rest_argument'] !== null) { + assert($originalRestArgumentName !== null); + $name = $originalRestArgumentName; + $val = $vars[$prototype['rest_argument']]; + + if ($storeInEnv) { + $this->set($name, $this->reduce($val, true), true, $env); + } else { + $output[$name] = ($reduce ? $this->reduce($val, true) : $val); + } + } + + if ($storeInEnv) { + $storeEnv->store = $env->store; + } + + foreach ($prototype['arguments'] as $argument) { + list($normalizedName, $name, $default) = $argument; + + if (isset($vars[$normalizedName])) { + continue; + } + assert($default !== null); + + if ($storeInEnv) { + $this->set($name, $this->reduce($default, true), true); + } else { + $output[$name] = ($reduce ? $this->reduce($default, true) : $default); + } + } + + return $output; + } + + /** + * Apply argument values per definition. + * + * This method assumes that the arguments are valid for the provided prototype. + * The validation with {@see verifyPrototype} must have been run before calling + * it. + * Arguments are returned as a map from the normalized argument names to the + * value. Additional arguments are collected in a sass argument list available + * under the name of the rest argument in the result. + * + * Defaults are not applied as they are resolved in a different environment. + * + * @param array $prototype + * @param array $positionalArgs + * @param array $namedArgs + * @param string|null $splatSeparator + * + * @return array + * + * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype + */ + private function applyArgumentsToDeclaration(array $prototype, array $positionalArgs, array $namedArgs, $splatSeparator) + { + $output = []; + $minLength = min(\count($positionalArgs), \count($prototype['arguments'])); + + for ($i = 0; $i < $minLength; $i++) { + list($name) = $prototype['arguments'][$i]; + $val = $positionalArgs[$i]; + + $output[$name] = $val; + } + + $restNamed = $namedArgs; + + for ($i = \count($positionalArgs); $i < \count($prototype['arguments']); $i++) { + $argument = $prototype['arguments'][$i]; + list($name) = $argument; + + if (isset($namedArgs[$name])) { + $val = $namedArgs[$name]; + unset($restNamed[$name]); + } else { + continue; + } + + $output[$name] = $val; + } + + if ($prototype['rest_argument'] !== null) { + $name = $prototype['rest_argument']; + $rest = array_values(array_slice($positionalArgs, \count($prototype['arguments']))); + + $val = [Type::T_LIST, \is_null($splatSeparator) ? ',' : $splatSeparator , $rest, $restNamed]; + + $output[$name] = $val; + } + + return $output; + } + + /** + * Coerce a php value into a scss one + * + * @param mixed $value + * + * @return array|Number + */ + protected function coerceValue($value) + { + if (\is_array($value) || $value instanceof Number) { + return $value; + } + + if (\is_bool($value)) { + return $this->toBool($value); + } + + if (\is_null($value)) { + return static::$null; + } + + if (is_numeric($value)) { + return new Number($value, ''); + } + + if ($value === '') { + return static::$emptyString; + } + + $value = [Type::T_KEYWORD, $value]; + $color = $this->coerceColor($value); + + if ($color) { + return $color; + } + + return $value; + } + + /** + * Coerce something to map + * + * @param array|Number $item + * + * @return array|Number + */ + protected function coerceMap($item) + { + if ($item[0] === Type::T_MAP) { + return $item; + } + + if ( + $item[0] === Type::T_LIST && + $item[2] === [] + ) { + return static::$emptyMap; + } + + return $item; + } + + /** + * Coerce something to list + * + * @param array|Number $item + * @param string $delim + * @param boolean $removeTrailingNull + * + * @return array + */ + protected function coerceList($item, $delim = ',', $removeTrailingNull = false) + { + if ($item instanceof Number) { + return [Type::T_LIST, $delim, [$item]]; + } + + if ($item[0] === Type::T_LIST) { + // remove trailing null from the list + if ($removeTrailingNull && end($item[2]) === static::$null) { + array_pop($item[2]); + } + + return $item; + } + + if ($item[0] === Type::T_MAP) { + $keys = $item[1]; + $values = $item[2]; + $list = []; + + for ($i = 0, $s = \count($keys); $i < $s; $i++) { + $key = $keys[$i]; + $value = $values[$i]; + + switch ($key[0]) { + case Type::T_LIST: + case Type::T_MAP: + case Type::T_STRING: + case Type::T_NULL: + break; + + default: + $key = [Type::T_KEYWORD, $this->compileStringContent($this->coerceString($key))]; + break; + } + + $list[] = [ + Type::T_LIST, + '', + [$key, $value] + ]; + } + + return [Type::T_LIST, ',', $list]; + } + + return [Type::T_LIST, $delim, [$item]]; + } + + /** + * Coerce color for expression + * + * @param array|Number $value + * + * @return array|Number + */ + protected function coerceForExpression($value) + { + if ($color = $this->coerceColor($value)) { + return $color; + } + + return $value; + } + + /** + * Coerce value to color + * + * @param array|Number $value + * @param bool $inRGBFunction + * + * @return array|null + */ + protected function coerceColor($value, $inRGBFunction = false) + { + if ($value instanceof Number) { + return null; + } + + switch ($value[0]) { + case Type::T_COLOR: + for ($i = 1; $i <= 3; $i++) { + if (! is_numeric($value[$i])) { + $cv = $this->compileRGBAValue($value[$i]); + + if (! is_numeric($cv)) { + return null; + } + + $value[$i] = $cv; + } + + if (isset($value[4])) { + if (! is_numeric($value[4])) { + $cv = $this->compileRGBAValue($value[4], true); + + if (! is_numeric($cv)) { + return null; + } + + $value[4] = $cv; + } + } + } + + return $value; + + case Type::T_LIST: + if ($inRGBFunction) { + if (\count($value[2]) == 3 || \count($value[2]) == 4) { + $color = $value[2]; + array_unshift($color, Type::T_COLOR); + + return $this->coerceColor($color); + } + } + + return null; + + case Type::T_KEYWORD: + if (! \is_string($value[1])) { + return null; + } + + $name = strtolower($value[1]); + + // hexa color? + if (preg_match('/^#([0-9a-f]+)$/i', $name, $m)) { + $nofValues = \strlen($m[1]); + + if (\in_array($nofValues, [3, 4, 6, 8])) { + $nbChannels = 3; + $color = []; + $num = hexdec($m[1]); + + switch ($nofValues) { + case 4: + $nbChannels = 4; + // then continuing with the case 3: + case 3: + for ($i = 0; $i < $nbChannels; $i++) { + $t = $num & 0xf; + array_unshift($color, $t << 4 | $t); + $num >>= 4; + } + + break; + + case 8: + $nbChannels = 4; + // then continuing with the case 6: + case 6: + for ($i = 0; $i < $nbChannels; $i++) { + array_unshift($color, $num & 0xff); + $num >>= 8; + } + + break; + } + + if ($nbChannels === 4) { + if ($color[3] === 255) { + $color[3] = 1; // fully opaque + } else { + $color[3] = round($color[3] / 255, Number::PRECISION); + } + } + + array_unshift($color, Type::T_COLOR); + + return $color; + } + } + + if ($rgba = Colors::colorNameToRGBa($name)) { + return isset($rgba[3]) + ? [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2], $rgba[3]] + : [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2]]; + } + + return null; + } + + return null; + } + + /** + * @param integer|Number $value + * @param boolean $isAlpha + * + * @return integer|mixed + */ + protected function compileRGBAValue($value, $isAlpha = false) + { + if ($isAlpha) { + return $this->compileColorPartValue($value, 0, 1, false); + } + + return $this->compileColorPartValue($value, 0, 255, true); + } + + /** + * @param mixed $value + * @param integer|float $min + * @param integer|float $max + * @param boolean $isInt + * + * @return integer|mixed + */ + protected function compileColorPartValue($value, $min, $max, $isInt = true) + { + if (! is_numeric($value)) { + if (\is_array($value)) { + $reduced = $this->reduce($value); + + if ($reduced instanceof Number) { + $value = $reduced; + } + } + + if ($value instanceof Number) { + if ($value->unitless()) { + $num = $value->getDimension(); + } elseif ($value->hasUnit('%')) { + $num = $max * $value->getDimension() / 100; + } else { + throw $this->error('Expected %s to have no units or "%%".', $value); + } + + $value = $num; + } elseif (\is_array($value)) { + $value = $this->compileValue($value); + } + } + + if (is_numeric($value)) { + if ($isInt) { + $value = round($value); + } + + $value = min($max, max($min, $value)); + + return $value; + } + + return $value; + } + + /** + * Coerce value to string + * + * @param array|Number $value + * + * @return array + */ + protected function coerceString($value) + { + if ($value[0] === Type::T_STRING) { + return $value; + } + + return [Type::T_STRING, '', [$this->compileValue($value)]]; + } + + /** + * Assert value is a string + * + * This method deals with internal implementation details of the value + * representation where unquoted strings can sometimes be stored under + * other types. + * The returned value is always using the T_STRING type. + * + * @api + * + * @param array|Number $value + * @param string|null $varName + * + * @return array + * + * @throws SassScriptException + */ + public function assertString($value, $varName = null) + { + // case of url(...) parsed a a function + if ($value[0] === Type::T_FUNCTION) { + $value = $this->coerceString($value); + } + + if (! \in_array($value[0], [Type::T_STRING, Type::T_KEYWORD])) { + $value = $this->compileValue($value); + throw SassScriptException::forArgument("$value is not a string.", $varName); + } + + return $this->coerceString($value); + } + + /** + * Coerce value to a percentage + * + * @param array|Number $value + * + * @return integer|float + * + * @deprecated + */ + protected function coercePercent($value) + { + @trigger_error(sprintf('"%s" is deprecated since 1.7.0.', __METHOD__), E_USER_DEPRECATED); + + if ($value instanceof Number) { + if ($value->hasUnit('%')) { + return $value->getDimension() / 100; + } + + return $value->getDimension(); + } + + return 0; + } + + /** + * Assert value is a map + * + * @api + * + * @param array|Number $value + * @param string|null $varName + * + * @return array + * + * @throws SassScriptException + */ + public function assertMap($value, $varName = null) + { + $value = $this->coerceMap($value); + + if ($value[0] !== Type::T_MAP) { + $value = $this->compileValue($value); + + throw SassScriptException::forArgument("$value is not a map.", $varName); + } + + return $value; + } + + /** + * Assert value is a list + * + * @api + * + * @param array|Number $value + * + * @return array + * + * @throws \Exception + */ + public function assertList($value) + { + if ($value[0] !== Type::T_LIST) { + throw $this->error('expecting list, %s received', $value[0]); + } + + return $value; + } + + /** + * Gets the keywords of an argument list. + * + * Keys in the returned array are normalized names (underscores are replaced with dashes) + * without the leading `$`. + * Calling this helper with anything that an argument list received for a rest argument + * of the function argument declaration is not supported. + * + * @param array|Number $value + * + * @return array + */ + public function getArgumentListKeywords($value) + { + if ($value[0] !== Type::T_LIST || !isset($value[3]) || !\is_array($value[3])) { + throw new \InvalidArgumentException('The argument is not a sass argument list.'); + } + + return $value[3]; + } + + /** + * Assert value is a color + * + * @api + * + * @param array|Number $value + * @param string|null $varName + * + * @return array + * + * @throws SassScriptException + */ + public function assertColor($value, $varName = null) + { + if ($color = $this->coerceColor($value)) { + return $color; + } + + $value = $this->compileValue($value); + + throw SassScriptException::forArgument("$value is not a color.", $varName); + } + + /** + * Assert value is a number + * + * @api + * + * @param array|Number $value + * @param string|null $varName + * + * @return Number + * + * @throws SassScriptException + */ + public function assertNumber($value, $varName = null) + { + if (!$value instanceof Number) { + $value = $this->compileValue($value); + throw SassScriptException::forArgument("$value is not a number.", $varName); + } + + return $value; + } + + /** + * Assert value is a integer + * + * @api + * + * @param array|Number $value + * @param string|null $varName + * + * @return integer + * + * @throws SassScriptException + */ + public function assertInteger($value, $varName = null) + { + $value = $this->assertNumber($value, $varName)->getDimension(); + if (round($value - \intval($value), Number::PRECISION) > 0) { + throw SassScriptException::forArgument("$value is not an integer.", $varName); + } + + return intval($value); + } + + /** + * Extract the ... / alpha on the last argument of channel arg + * in color functions + * + * @param array $args + * @return array + */ + private function extractSlashAlphaInColorFunction($args) + { + $last = end($args); + if (\count($args) === 3 && $last[0] === Type::T_EXPRESSION && $last[1] === '/') { + array_pop($args); + $args[] = $last[2]; + $args[] = $last[3]; + } + return $args; + } + + + /** + * Make sure a color's components don't go out of bounds + * + * @param array $c + * + * @return array + */ + protected function fixColor($c) + { + foreach ([1, 2, 3] as $i) { + if ($c[$i] < 0) { + $c[$i] = 0; + } + + if ($c[$i] > 255) { + $c[$i] = 255; + } + + if (!\is_int($c[$i])) { + $c[$i] = round($c[$i]); + } + } + + return $c; + } + + /** + * Convert RGB to HSL + * + * @internal + * + * @param integer $red + * @param integer $green + * @param integer $blue + * + * @return array + */ + public function toHSL($red, $green, $blue) + { + $min = min($red, $green, $blue); + $max = max($red, $green, $blue); + + $l = $min + $max; + $d = $max - $min; + + if ((int) $d === 0) { + $h = $s = 0; + } else { + if ($l < 255) { + $s = $d / $l; + } else { + $s = $d / (510 - $l); + } + + if ($red == $max) { + $h = 60 * ($green - $blue) / $d; + } elseif ($green == $max) { + $h = 60 * ($blue - $red) / $d + 120; + } elseif ($blue == $max) { + $h = 60 * ($red - $green) / $d + 240; + } + } + + return [Type::T_HSL, fmod($h + 360, 360), $s * 100, $l / 5.1]; + } + + /** + * Hue to RGB helper + * + * @param float $m1 + * @param float $m2 + * @param float $h + * + * @return float + */ + protected function hueToRGB($m1, $m2, $h) + { + if ($h < 0) { + $h += 1; + } elseif ($h > 1) { + $h -= 1; + } + + if ($h * 6 < 1) { + return $m1 + ($m2 - $m1) * $h * 6; + } + + if ($h * 2 < 1) { + return $m2; + } + + if ($h * 3 < 2) { + return $m1 + ($m2 - $m1) * (2 / 3 - $h) * 6; + } + + return $m1; + } + + /** + * Convert HSL to RGB + * + * @internal + * + * @param int|float $hue H from 0 to 360 + * @param int|float $saturation S from 0 to 100 + * @param int|float $lightness L from 0 to 100 + * + * @return array + */ + public function toRGB($hue, $saturation, $lightness) + { + if ($hue < 0) { + $hue += 360; + } + + $h = $hue / 360; + $s = min(100, max(0, $saturation)) / 100; + $l = min(100, max(0, $lightness)) / 100; + + $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s; + $m1 = $l * 2 - $m2; + + $r = $this->hueToRGB($m1, $m2, $h + 1 / 3) * 255; + $g = $this->hueToRGB($m1, $m2, $h) * 255; + $b = $this->hueToRGB($m1, $m2, $h - 1 / 3) * 255; + + $out = [Type::T_COLOR, $r, $g, $b]; + + return $out; + } + + /** + * Convert HWB to RGB + * https://www.w3.org/TR/css-color-4/#hwb-to-rgb + * + * @api + * + * @param integer $hue H from 0 to 360 + * @param integer $whiteness W from 0 to 100 + * @param integer $blackness B from 0 to 100 + * + * @return array + */ + private function HWBtoRGB($hue, $whiteness, $blackness) + { + $w = min(100, max(0, $whiteness)) / 100; + $b = min(100, max(0, $blackness)) / 100; + + $sum = $w + $b; + if ($sum > 1.0) { + $w = $w / $sum; + $b = $b / $sum; + } + $b = min(1.0 - $w, $b); + + $rgb = $this->toRGB($hue, 100, 50); + for($i = 1; $i < 4; $i++) { + $rgb[$i] *= (1.0 - $w - $b); + $rgb[$i] = round($rgb[$i] + 255 * $w + 0.0001); + } + + return $rgb; + } + + /** + * Convert RGB to HWB + * + * @api + * + * @param integer $red + * @param integer $green + * @param integer $blue + * + * @return array + */ + private function RGBtoHWB($red, $green, $blue) + { + $min = min($red, $green, $blue); + $max = max($red, $green, $blue); + + $d = $max - $min; + + if ((int) $d === 0) { + $h = 0; + } else { + + if ($red == $max) { + $h = 60 * ($green - $blue) / $d; + } elseif ($green == $max) { + $h = 60 * ($blue - $red) / $d + 120; + } elseif ($blue == $max) { + $h = 60 * ($red - $green) / $d + 240; + } + } + + return [Type::T_HWB, fmod($h, 360), $min / 255 * 100, 100 - $max / 255 *100]; + } + + + // Built in functions + + protected static $libCall = ['function', 'args...']; + protected function libCall($args) + { + $functionReference = $args[0]; + + if (in_array($functionReference[0], [Type::T_STRING, Type::T_KEYWORD])) { + $name = $this->compileStringContent($this->coerceString($functionReference)); + $warning = "Passing a string to call() is deprecated and will be illegal\n" + . "in Sass 4.0. Use call(function-reference($name)) instead."; + Warn::deprecation($warning); + $functionReference = $this->libGetFunction([$this->assertString($functionReference, 'function')]); + } + + if ($functionReference === static::$null) { + return static::$null; + } + + if (! in_array($functionReference[0], [Type::T_FUNCTION_REFERENCE, Type::T_FUNCTION])) { + throw $this->error('Function reference expected, got ' . $functionReference[0]); + } + + $callArgs = [ + [null, $args[1], true] + ]; + + return $this->reduce([Type::T_FUNCTION_CALL, $functionReference, $callArgs]); + } + + + protected static $libGetFunction = [ + ['name'], + ['name', 'css'] + ]; + protected function libGetFunction($args) + { + $name = $this->compileStringContent($this->assertString(array_shift($args), 'name')); + $isCss = false; + + if (count($args)) { + $isCss = array_shift($args); + $isCss = (($isCss === static::$true) ? true : false); + } + + if ($isCss) { + return [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]]; + } + + return $this->getFunctionReference($name, true); + } + + protected static $libIf = ['condition', 'if-true', 'if-false:']; + protected function libIf($args) + { + list($cond, $t, $f) = $args; + + if (! $this->isTruthy($this->reduce($cond, true))) { + return $this->reduce($f, true); + } + + return $this->reduce($t, true); + } + + protected static $libIndex = ['list', 'value']; + protected function libIndex($args) + { + list($list, $value) = $args; + + if ( + $list[0] === Type::T_MAP || + $list[0] === Type::T_STRING || + $list[0] === Type::T_KEYWORD || + $list[0] === Type::T_INTERPOLATE + ) { + $list = $this->coerceList($list, ' '); + } + + if ($list[0] !== Type::T_LIST) { + return static::$null; + } + + // Numbers are represented with value objects, for which the PHP equality operator does not + // match the Sass rules (and we cannot overload it). As they are the only type of values + // represented with a value object for now, they require a special case. + if ($value instanceof Number) { + $key = 0; + foreach ($list[2] as $item) { + $key++; + $itemValue = $this->normalizeValue($item); + + if ($itemValue instanceof Number && $value->equals($itemValue)) { + return new Number($key, ''); + } + } + return static::$null; + } + + $values = []; + + + foreach ($list[2] as $item) { + $values[] = $this->normalizeValue($item); + } + + $key = array_search($this->normalizeValue($value), $values); + + return false === $key ? static::$null : new Number($key + 1, ''); + } + + protected static $libRgb = [ + ['color'], + ['color', 'alpha'], + ['channels'], + ['red', 'green', 'blue'], + ['red', 'green', 'blue', 'alpha'] ]; + protected function libRgb($args, $kwargs, $funcName = 'rgb') + { + switch (\count($args)) { + case 1: + if (! $color = $this->coerceColor($args[0], true)) { + $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']]; + } + break; + + case 3: + $color = [Type::T_COLOR, $args[0], $args[1], $args[2]]; + + if (! $color = $this->coerceColor($color)) { + $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']]; + } + + return $color; + + case 2: + if ($color = $this->coerceColor($args[0], true)) { + $alpha = $this->compileRGBAValue($args[1], true); + + if (is_numeric($alpha)) { + $color[4] = $alpha; + } else { + $color = [Type::T_STRING, '', + [$funcName . '(', $color[1], ', ', $color[2], ', ', $color[3], ', ', $alpha, ')']]; + } + } else { + $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ')']]; + } + break; + + case 4: + default: + $color = [Type::T_COLOR, $args[0], $args[1], $args[2], $args[3]]; + + if (! $color = $this->coerceColor($color)) { + $color = [Type::T_STRING, '', + [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']]; + } + break; + } + + return $color; + } + + protected static $libRgba = [ + ['color'], + ['color', 'alpha'], + ['channels'], + ['red', 'green', 'blue'], + ['red', 'green', 'blue', 'alpha'] ]; + protected function libRgba($args, $kwargs) + { + return $this->libRgb($args, $kwargs, 'rgba'); + } + + /** + * Helper function for adjust_color, change_color, and scale_color + * + * @param array $args + * @param string $operation + * @param callable $fn + * + * @return array + * + * @phpstan-param callable(float|int, float|int|null, float|int): (float|int) $fn + */ + protected function alterColor(array $args, $operation, $fn) + { + $color = $this->assertColor($args[0], 'color'); + + if ($args[1][2]) { + throw new SassScriptException('Only one positional argument is allowed. All other arguments must be passed by name.'); + } + + $kwargs = $this->getArgumentListKeywords($args[1]); + + $scale = $operation === 'scale'; + $change = $operation === 'change'; + + /** + * @param string $name + * @param float|int $max + * @param bool $checkPercent + * @param bool $assertPercent + * + * @return float|int|null + */ + $getParam = function ($name, $max, $checkPercent = false, $assertPercent = false) use (&$kwargs, $scale, $change) { + if (!isset($kwargs[$name])) { + return null; + } + + $number = $this->assertNumber($kwargs[$name], $name); + unset($kwargs[$name]); + + if (!$scale && $checkPercent) { + if (!$number->hasUnit('%')) { + $warning = $this->error("{$name} Passing a number `$number` without unit % is deprecated."); + $this->logger->warn($warning->getMessage(), true); + } + } + + if ($scale || $assertPercent) { + $number->assertUnit('%', $name); + } + + if ($scale) { + $max = 100; + } + + return $number->valueInRange($change ? 0 : -$max, $max, $name); + }; + + $alpha = $getParam('alpha', 1); + $red = $getParam('red', 255); + $green = $getParam('green', 255); + $blue = $getParam('blue', 255); + + if ($scale || !isset($kwargs['hue'])) { + $hue = null; + } else { + $hueNumber = $this->assertNumber($kwargs['hue'], 'hue'); + unset($kwargs['hue']); + $hue = $hueNumber->getDimension(); + } + $saturation = $getParam('saturation', 100, true); + $lightness = $getParam('lightness', 100, true); + $whiteness = $getParam('whiteness', 100, false, true); + $blackness = $getParam('blackness', 100, false, true); + + if (!empty($kwargs)) { + $unknownNames = array_keys($kwargs); + $lastName = array_pop($unknownNames); + $message = sprintf( + 'No argument%s named $%s%s.', + $unknownNames ? 's' : '', + $unknownNames ? implode(', $', $unknownNames) . ' or $' : '', + $lastName + ); + throw new SassScriptException($message); + } + + $hasRgb = $red !== null || $green !== null || $blue !== null; + $hasSL = $saturation !== null || $lightness !== null; + $hasWB = $whiteness !== null || $blackness !== null; + $found = false; + + if ($hasRgb && ($hasSL || $hasWB || $hue !== null)) { + throw new SassScriptException(sprintf('RGB parameters may not be passed along with %s parameters.', $hasWB ? 'HWB' : 'HSL')); + } + + if ($hasWB && $hasSL) { + throw new SassScriptException('HSL parameters may not be passed along with HWB parameters.'); + } + + if ($hasRgb) { + $color[1] = round($fn($color[1], $red, 255)); + $color[2] = round($fn($color[2], $green, 255)); + $color[3] = round($fn($color[3], $blue, 255)); + } elseif ($hasWB) { + $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); + if ($hue !== null) { + $hwb[1] = $change ? $hue : $hwb[1] + $hue; + } + $hwb[2] = $fn($hwb[2], $whiteness, 100); + $hwb[3] = $fn($hwb[3], $blackness, 100); + + $rgb = $this->HWBtoRGB($hwb[1], $hwb[2], $hwb[3]); + + if (isset($color[4])) { + $rgb[4] = $color[4]; + } + + $color = $rgb; + } elseif ($hue !== null || $hasSL) { + $hsl = $this->toHSL($color[1], $color[2], $color[3]); + + if ($hue !== null) { + $hsl[1] = $change ? $hue : $hsl[1] + $hue; + } + $hsl[2] = $fn($hsl[2], $saturation, 100); + $hsl[3] = $fn($hsl[3], $lightness, 100); + + $rgb = $this->toRGB($hsl[1], $hsl[2], $hsl[3]); + + if (isset($color[4])) { + $rgb[4] = $color[4]; + } + + $color = $rgb; + } + + if ($alpha !== null) { + $existingAlpha = isset($color[4]) ? $color[4] : 1; + $color[4] = $fn($existingAlpha, $alpha, 1); + } + + return $color; + } + + protected static $libAdjustColor = ['color', 'kwargs...']; + protected function libAdjustColor($args) + { + return $this->alterColor($args, 'adjust', function ($base, $alter, $max) { + if ($alter === null) { + return $base; + } + + $new = $base + $alter; + + if ($new < 0) { + return 0; + } + + if ($new > $max) { + return $max; + } + + return $new; + }); + } + + protected static $libChangeColor = ['color', 'kwargs...']; + protected function libChangeColor($args) + { + return $this->alterColor($args,'change', function ($base, $alter, $max) { + if ($alter === null) { + return $base; + } + + return $alter; + }); + } + + protected static $libScaleColor = ['color', 'kwargs...']; + protected function libScaleColor($args) + { + return $this->alterColor($args, 'scale', function ($base, $scale, $max) { + if ($scale === null) { + return $base; + } + + $scale = $scale / 100; + + if ($scale < 0) { + return $base * $scale + $base; + } + + return ($max - $base) * $scale + $base; + }); + } + + protected static $libIeHexStr = ['color']; + protected function libIeHexStr($args) + { + $color = $this->coerceColor($args[0]); + + if (\is_null($color)) { + throw $this->error('Error: argument `$color` of `ie-hex-str($color)` must be a color'); + } + + $color[4] = isset($color[4]) ? round(255 * $color[4]) : 255; + + return [Type::T_STRING, '', [sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3])]]; + } + + protected static $libRed = ['color']; + protected function libRed($args) + { + $color = $this->coerceColor($args[0]); + + if (\is_null($color)) { + throw $this->error('Error: argument `$color` of `red($color)` must be a color'); + } + + return new Number((int) $color[1], ''); + } + + protected static $libGreen = ['color']; + protected function libGreen($args) + { + $color = $this->coerceColor($args[0]); + + if (\is_null($color)) { + throw $this->error('Error: argument `$color` of `green($color)` must be a color'); + } + + return new Number((int) $color[2], ''); + } + + protected static $libBlue = ['color']; + protected function libBlue($args) + { + $color = $this->coerceColor($args[0]); + + if (\is_null($color)) { + throw $this->error('Error: argument `$color` of `blue($color)` must be a color'); + } + + return new Number((int) $color[3], ''); + } + + protected static $libAlpha = ['color']; + protected function libAlpha($args) + { + if ($color = $this->coerceColor($args[0])) { + return new Number(isset($color[4]) ? $color[4] : 1, ''); + } + + // this might be the IE function, so return value unchanged + return null; + } + + protected static $libOpacity = ['color']; + protected function libOpacity($args) + { + $value = $args[0]; + + if ($value instanceof Number) { + return null; + } + + return $this->libAlpha($args); + } + + // mix two colors + protected static $libMix = [ + ['color1', 'color2', 'weight:50%'], + ['color-1', 'color-2', 'weight:50%'] + ]; + protected function libMix($args) + { + list($first, $second, $weight) = $args; + + $first = $this->assertColor($first, 'color1'); + $second = $this->assertColor($second, 'color2'); + $weightScale = $this->assertNumber($weight, 'weight')->valueInRange(0, 100, 'weight') / 100; + + $firstAlpha = isset($first[4]) ? $first[4] : 1; + $secondAlpha = isset($second[4]) ? $second[4] : 1; + + $normalizedWeight = $weightScale * 2 - 1; + $alphaDistance = $firstAlpha - $secondAlpha; + + $combinedWeight = $normalizedWeight * $alphaDistance == -1 ? $normalizedWeight : ($normalizedWeight + $alphaDistance) / (1 + $normalizedWeight * $alphaDistance); + $weight1 = ($combinedWeight + 1) / 2.0; + $weight2 = 1.0 - $weight1; + + $new = [Type::T_COLOR, + $weight1 * $first[1] + $weight2 * $second[1], + $weight1 * $first[2] + $weight2 * $second[2], + $weight1 * $first[3] + $weight2 * $second[3], + ]; + + if ($firstAlpha != 1.0 || $secondAlpha != 1.0) { + $new[] = $firstAlpha * $weightScale + $secondAlpha * (1 - $weightScale); + } + + return $this->fixColor($new); + } + + protected static $libHsl = [ + ['channels'], + ['hue', 'saturation'], + ['hue', 'saturation', 'lightness'], + ['hue', 'saturation', 'lightness', 'alpha'] ]; + protected function libHsl($args, $kwargs, $funcName = 'hsl') + { + $args_to_check = $args; + + if (\count($args) == 1) { + if ($args[0][0] !== Type::T_LIST || \count($args[0][2]) < 3 || \count($args[0][2]) > 4) { + return [Type::T_STRING, '', [$funcName . '(', $args[0], ')']]; + } + + $args = $args[0][2]; + $args_to_check = $kwargs['channels'][2]; + } + + if (\count($args) === 2) { + // if var() is used as an argument, return as a css function + foreach ($args as $arg) { + if ($arg[0] === Type::T_FUNCTION && in_array($arg[1], ['var'])) { + return null; + } + } + + throw new SassScriptException('Missing argument $lightness.'); + } + + foreach ($kwargs as $k => $arg) { + if (in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && in_array($arg[1], ['min', 'max'])) { + return null; + } + } + + foreach ($args_to_check as $k => $arg) { + if (in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && in_array($arg[1], ['min', 'max'])) { + if (count($kwargs) > 1 || ($k >= 2 && count($args) === 4)) { + return null; + } + + $args[$k] = $this->stringifyFncallArgs($arg); + } + + if ( + $k >= 2 && count($args) === 4 && + in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && + in_array($arg[1], ['calc','env']) + ) { + return null; + } + } + + $hue = $this->reduce($args[0]); + $saturation = $this->reduce($args[1]); + $lightness = $this->reduce($args[2]); + $alpha = null; + + if (\count($args) === 4) { + $alpha = $this->compileColorPartValue($args[3], 0, 100, false); + + if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number || ! is_numeric($alpha)) { + return [Type::T_STRING, '', + [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']]; + } + } else { + if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number) { + return [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']]; + } + } + + $hueValue = fmod($hue->getDimension(), 360); + + while ($hueValue < 0) { + $hueValue += 360; + } + + $color = $this->toRGB($hueValue, max(0, min($saturation->getDimension(), 100)), max(0, min($lightness->getDimension(), 100))); + + if (! \is_null($alpha)) { + $color[4] = $alpha; + } + + return $color; + } + + protected static $libHsla = [ + ['channels'], + ['hue', 'saturation'], + ['hue', 'saturation', 'lightness'], + ['hue', 'saturation', 'lightness', 'alpha']]; + protected function libHsla($args, $kwargs) + { + return $this->libHsl($args, $kwargs, 'hsla'); + } + + protected static $libHue = ['color']; + protected function libHue($args) + { + $color = $this->assertColor($args[0], 'color'); + $hsl = $this->toHSL($color[1], $color[2], $color[3]); + + return new Number($hsl[1], 'deg'); + } + + protected static $libSaturation = ['color']; + protected function libSaturation($args) + { + $color = $this->assertColor($args[0], 'color'); + $hsl = $this->toHSL($color[1], $color[2], $color[3]); + + return new Number($hsl[2], '%'); + } + + protected static $libLightness = ['color']; + protected function libLightness($args) + { + $color = $this->assertColor($args[0], 'color'); + $hsl = $this->toHSL($color[1], $color[2], $color[3]); + + return new Number($hsl[3], '%'); + } + + /* + * Todo : a integrer dans le futur module color + protected static $libHwb = [ + ['channels'], + ['hue', 'whiteness', 'blackness'], + ['hue', 'whiteness', 'blackness', 'alpha'] ]; + protected function libHwb($args, $kwargs, $funcName = 'hwb') + { + $args_to_check = $args; + + if (\count($args) == 1) { + if ($args[0][0] !== Type::T_LIST) { + throw $this->error("Missing elements \$whiteness and \$blackness"); + } + + if (\trim($args[0][1])) { + throw $this->error("\$channels must be a space-separated list."); + } + + if (! empty($args[0]['enclosing'])) { + throw $this->error("\$channels must be an unbracketed list."); + } + + $args = $args[0][2]; + if (\count($args) > 3) { + throw $this->error("hwb() : Only 3 elements are allowed but ". \count($args) . "were passed"); + } + + $args_to_check = $this->extractSlashAlphaInColorFunction($kwargs['channels'][2]); + if (\count($args_to_check) !== \count($kwargs['channels'][2])) { + $args = $args_to_check; + } + } + + if (\count($args_to_check) < 2) { + throw $this->error("Missing elements \$whiteness and \$blackness"); + } + if (\count($args_to_check) < 3) { + throw $this->error("Missing element \$blackness"); + } + if (\count($args_to_check) > 4) { + throw $this->error("hwb() : Only 4 elements are allowed but ". \count($args) . "were passed"); + } + + foreach ($kwargs as $k => $arg) { + if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) { + return null; + } + } + + foreach ($args_to_check as $k => $arg) { + if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) { + if (count($kwargs) > 1 || ($k >= 2 && count($args) === 4)) { + return null; + } + + $args[$k] = $this->stringifyFncallArgs($arg); + } + + if ( + $k >= 2 && count($args) === 4 && + in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && + in_array($arg[1], ['calc','env']) + ) { + return null; + } + } + + $hue = $this->reduce($args[0]); + $whiteness = $this->reduce($args[1]); + $blackness = $this->reduce($args[2]); + $alpha = null; + + if (\count($args) === 4) { + $alpha = $this->compileColorPartValue($args[3], 0, 1, false); + + if (! \is_numeric($alpha)) { + $val = $this->compileValue($args[3]); + throw $this->error("\$alpha: $val is not a number"); + } + } + + $this->assertNumber($hue, 'hue'); + $this->assertUnit($whiteness, ['%'], 'whiteness'); + $this->assertUnit($blackness, ['%'], 'blackness'); + + $this->assertRange($whiteness, 0, 100, "0% and 100%", "whiteness"); + $this->assertRange($blackness, 0, 100, "0% and 100%", "blackness"); + + $w = $whiteness->getDimension(); + $b = $blackness->getDimension(); + + $hueValue = $hue->getDimension() % 360; + + while ($hueValue < 0) { + $hueValue += 360; + } + + $color = $this->HWBtoRGB($hueValue, $w, $b); + + if (! \is_null($alpha)) { + $color[4] = $alpha; + } + + return $color; + } + + protected static $libWhiteness = ['color']; + protected function libWhiteness($args, $kwargs, $funcName = 'whiteness') { + + $color = $this->assertColor($args[0]); + $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); + + return new Number($hwb[2], '%'); + } + + protected static $libBlackness = ['color']; + protected function libBlackness($args, $kwargs, $funcName = 'blackness') { + + $color = $this->assertColor($args[0]); + $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); + + return new Number($hwb[3], '%'); + } + */ + + protected function adjustHsl($color, $idx, $amount) + { + $hsl = $this->toHSL($color[1], $color[2], $color[3]); + $hsl[$idx] += $amount; + + if ($idx !== 1) { + // Clamp the saturation and lightness + $hsl[$idx] = min(max(0, $hsl[$idx]), 100); + } + + $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]); + + if (isset($color[4])) { + $out[4] = $color[4]; + } + + return $out; + } + + protected static $libAdjustHue = ['color', 'degrees']; + protected function libAdjustHue($args) + { + $color = $this->assertColor($args[0], 'color'); + $degrees = $this->assertNumber($args[1], 'degrees')->getDimension(); + + return $this->adjustHsl($color, 1, $degrees); + } + + protected static $libLighten = ['color', 'amount']; + protected function libLighten($args) + { + $color = $this->assertColor($args[0], 'color'); + $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%'); + + return $this->adjustHsl($color, 3, $amount); + } + + protected static $libDarken = ['color', 'amount']; + protected function libDarken($args) + { + $color = $this->assertColor($args[0], 'color'); + $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%'); + + return $this->adjustHsl($color, 3, -$amount); + } + + protected static $libSaturate = [['color', 'amount'], ['amount']]; + protected function libSaturate($args) + { + $value = $args[0]; + + if (count($args) === 1) { + $this->assertNumber($args[0], 'amount'); + + return null; + } + + $color = $this->assertColor($args[0], 'color'); + $amount = $this->assertNumber($args[1], 'amount'); + + return $this->adjustHsl($color, 2, $amount->valueInRange(0, 100, 'amount')); + } + + protected static $libDesaturate = ['color', 'amount']; + protected function libDesaturate($args) + { + $color = $this->assertColor($args[0], 'color'); + $amount = $this->assertNumber($args[1], 'amount'); + + return $this->adjustHsl($color, 2, -$amount->valueInRange(0, 100, 'amount')); + } + + protected static $libGrayscale = ['color']; + protected function libGrayscale($args) + { + $value = $args[0]; + + if ($value instanceof Number) { + return null; + } + + return $this->adjustHsl($this->assertColor($value, 'color'), 2, -100); + } + + protected static $libComplement = ['color']; + protected function libComplement($args) + { + return $this->adjustHsl($this->assertColor($args[0], 'color'), 1, 180); + } + + protected static $libInvert = ['color', 'weight:100%']; + protected function libInvert($args) + { + $value = $args[0]; + + $weight = $this->assertNumber($args[1], 'weight'); + + if ($value instanceof Number) { + if ($weight->getDimension() != 100 || !$weight->hasUnit('%')) { + throw new SassScriptException('Only one argument may be passed to the plain-CSS invert() function.'); + } + + return null; + } + + $color = $this->assertColor($value, 'color'); + $inverted = $color; + $inverted[1] = 255 - $inverted[1]; + $inverted[2] = 255 - $inverted[2]; + $inverted[3] = 255 - $inverted[3]; + + return $this->libMix([$inverted, $color, $weight]); + } + + // increases opacity by amount + protected static $libOpacify = ['color', 'amount']; + protected function libOpacify($args) + { + $color = $this->assertColor($args[0], 'color'); + $amount = $this->assertNumber($args[1], 'amount'); + + $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount->valueInRange(0, 1, 'amount'); + $color[4] = min(1, max(0, $color[4])); + + return $color; + } + + protected static $libFadeIn = ['color', 'amount']; + protected function libFadeIn($args) + { + return $this->libOpacify($args); + } + + // decreases opacity by amount + protected static $libTransparentize = ['color', 'amount']; + protected function libTransparentize($args) + { + $color = $this->assertColor($args[0], 'color'); + $amount = $this->assertNumber($args[1], 'amount'); + + $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount->valueInRange(0, 1, 'amount'); + $color[4] = min(1, max(0, $color[4])); + + return $color; + } + + protected static $libFadeOut = ['color', 'amount']; + protected function libFadeOut($args) + { + return $this->libTransparentize($args); + } + + protected static $libUnquote = ['string']; + protected function libUnquote($args) + { + try { + $str = $this->assertString($args[0], 'string'); + } catch (SassScriptException $e) { + $value = $this->compileValue($args[0]); + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + + $message = "Passing $value, a non-string value, to unquote() +will be an error in future versions of Sass.\n on line $line of $fname"; + + $this->logger->warn($message, true); + + return $args[0]; + } + + $str[1] = ''; + + return $str; + } + + protected static $libQuote = ['string']; + protected function libQuote($args) + { + $value = $this->assertString($args[0], 'string'); + + $value[1] = '"'; + + return $value; + } + + protected static $libPercentage = ['number']; + protected function libPercentage($args) + { + $num = $this->assertNumber($args[0], 'number'); + $num->assertNoUnits('number'); + + return new Number($num->getDimension() * 100, '%'); + } + + protected static $libRound = ['number']; + protected function libRound($args) + { + $num = $this->assertNumber($args[0], 'number'); + + return new Number(round($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); + } + + protected static $libFloor = ['number']; + protected function libFloor($args) + { + $num = $this->assertNumber($args[0], 'number'); + + return new Number(floor($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); + } + + protected static $libCeil = ['number']; + protected function libCeil($args) + { + $num = $this->assertNumber($args[0], 'number'); + + return new Number(ceil($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); + } + + protected static $libAbs = ['number']; + protected function libAbs($args) + { + $num = $this->assertNumber($args[0], 'number'); + + return new Number(abs($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); + } + + protected static $libMin = ['numbers...']; + protected function libMin($args) + { + /** + * @var Number|null + */ + $min = null; + + foreach ($args[0][2] as $arg) { + $number = $this->assertNumber($arg); + + if (\is_null($min) || $min->greaterThan($number)) { + $min = $number; + } + } + + if (!\is_null($min)) { + return $min; + } + + throw $this->error('At least one argument must be passed.'); + } + + protected static $libMax = ['numbers...']; + protected function libMax($args) + { + /** + * @var Number|null + */ + $max = null; + + foreach ($args[0][2] as $arg) { + $number = $this->assertNumber($arg); + + if (\is_null($max) || $max->lessThan($number)) { + $max = $number; + } + } + + if (!\is_null($max)) { + return $max; + } + + throw $this->error('At least one argument must be passed.'); + } + + protected static $libLength = ['list']; + protected function libLength($args) + { + $list = $this->coerceList($args[0], ',', true); + + return new Number(\count($list[2]), ''); + } + + protected static $libListSeparator = ['list']; + protected function libListSeparator($args) + { + if (! \in_array($args[0][0], [Type::T_LIST, Type::T_MAP])) { + return [Type::T_KEYWORD, 'space']; + } + + $list = $this->coerceList($args[0]); + + if (\count($list[2]) <= 1 && empty($list['enclosing'])) { + return [Type::T_KEYWORD, 'space']; + } + + if ($list[1] === ',') { + return [Type::T_KEYWORD, 'comma']; + } + + return [Type::T_KEYWORD, 'space']; + } + + protected static $libNth = ['list', 'n']; + protected function libNth($args) + { + $list = $this->coerceList($args[0], ',', false); + $n = $this->assertNumber($args[1])->getDimension(); + + if ($n > 0) { + $n--; + } elseif ($n < 0) { + $n += \count($list[2]); + } + + return isset($list[2][$n]) ? $list[2][$n] : static::$defaultValue; + } + + protected static $libSetNth = ['list', 'n', 'value']; + protected function libSetNth($args) + { + $list = $this->coerceList($args[0]); + $n = $this->assertNumber($args[1])->getDimension(); + + if ($n > 0) { + $n--; + } elseif ($n < 0) { + $n += \count($list[2]); + } + + if (! isset($list[2][$n])) { + throw $this->error('Invalid argument for "n"'); + } + + $list[2][$n] = $args[2]; + + return $list; + } + + protected static $libMapGet = ['map', 'key']; + protected function libMapGet($args) + { + $map = $this->assertMap($args[0], 'map'); + $key = $args[1]; + + if (! \is_null($key)) { + $key = $this->compileStringContent($this->coerceString($key)); + + for ($i = \count($map[1]) - 1; $i >= 0; $i--) { + if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) { + return $map[2][$i]; + } + } + } + + return static::$null; + } + + protected static $libMapKeys = ['map']; + protected function libMapKeys($args) + { + $map = $this->assertMap($args[0], 'map'); + $keys = $map[1]; + + return [Type::T_LIST, ',', $keys]; + } + + protected static $libMapValues = ['map']; + protected function libMapValues($args) + { + $map = $this->assertMap($args[0], 'map'); + $values = $map[2]; + + return [Type::T_LIST, ',', $values]; + } + + protected static $libMapRemove = [ + ['map'], + ['map', 'key', 'keys...'], + ]; + protected function libMapRemove($args) + { + $map = $this->assertMap($args[0], 'map'); + + if (\count($args) === 1) { + return $map; + } + + $keys = []; + $keys[] = $this->compileStringContent($this->coerceString($args[1])); + + foreach ($args[2][2] as $key) { + $keys[] = $this->compileStringContent($this->coerceString($key)); + } + + for ($i = \count($map[1]) - 1; $i >= 0; $i--) { + if (in_array($this->compileStringContent($this->coerceString($map[1][$i])), $keys)) { + array_splice($map[1], $i, 1); + array_splice($map[2], $i, 1); + } + } + + return $map; + } + + protected static $libMapHasKey = ['map', 'key']; + protected function libMapHasKey($args) + { + $map = $this->assertMap($args[0], 'map'); + + return $this->toBool($this->mapHasKey($map, $args[1])); + } + + /** + * @param array|Number $keyValue + * + * @return bool + */ + private function mapHasKey(array $map, $keyValue) + { + $key = $this->compileStringContent($this->coerceString($keyValue)); + + for ($i = \count($map[1]) - 1; $i >= 0; $i--) { + if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) { + return true; + } + } + + return false; + } + + protected static $libMapMerge = [ + ['map1', 'map2'], + ['map-1', 'map-2'] + ]; + protected function libMapMerge($args) + { + $map1 = $this->assertMap($args[0], 'map1'); + $map2 = $this->assertMap($args[1], 'map2'); + + foreach ($map2[1] as $i2 => $key2) { + $key = $this->compileStringContent($this->coerceString($key2)); + + foreach ($map1[1] as $i1 => $key1) { + if ($key === $this->compileStringContent($this->coerceString($key1))) { + $map1[2][$i1] = $map2[2][$i2]; + continue 2; + } + } + + $map1[1][] = $map2[1][$i2]; + $map1[2][] = $map2[2][$i2]; + } + + return $map1; + } + + protected static $libKeywords = ['args']; + protected function libKeywords($args) + { + $value = $args[0]; + + if ($value[0] !== Type::T_LIST || !isset($value[3]) || !\is_array($value[3])) { + $compiledValue = $this->compileValue($value); + + throw SassScriptException::forArgument($compiledValue . ' is not an argument list.', 'args'); + } + + $keys = []; + $values = []; + + foreach ($this->getArgumentListKeywords($value) as $name => $arg) { + $keys[] = [Type::T_KEYWORD, $name]; + $values[] = $arg; + } + + return [Type::T_MAP, $keys, $values]; + } + + protected static $libIsBracketed = ['list']; + protected function libIsBracketed($args) + { + $list = $args[0]; + $this->coerceList($list, ' '); + + if (! empty($list['enclosing']) && $list['enclosing'] === 'bracket') { + return self::$true; + } + + return self::$false; + } + + /** + * @param array $list1 + * @param array|Number|null $sep + * + * @return string + * @throws CompilerException + */ + protected function listSeparatorForJoin($list1, $sep) + { + if (! isset($sep)) { + return $list1[1]; + } + + switch ($this->compileValue($sep)) { + case 'comma': + return ','; + + case 'space': + return ' '; + + default: + return $list1[1]; + } + } + + protected static $libJoin = ['list1', 'list2', 'separator:null', 'bracketed:auto']; + protected function libJoin($args) + { + list($list1, $list2, $sep, $bracketed) = $args; + + $list1 = $this->coerceList($list1, ' ', true); + $list2 = $this->coerceList($list2, ' ', true); + $sep = $this->listSeparatorForJoin($list1, $sep); + + if ($bracketed === static::$true) { + $bracketed = true; + } elseif ($bracketed === static::$false) { + $bracketed = false; + } elseif ($bracketed === [Type::T_KEYWORD, 'auto']) { + $bracketed = 'auto'; + } elseif ($bracketed === static::$null) { + $bracketed = false; + } else { + $bracketed = $this->compileValue($bracketed); + $bracketed = ! ! $bracketed; + + if ($bracketed === true) { + $bracketed = true; + } + } + + if ($bracketed === 'auto') { + $bracketed = false; + + if (! empty($list1['enclosing']) && $list1['enclosing'] === 'bracket') { + $bracketed = true; + } + } + + $res = [Type::T_LIST, $sep, array_merge($list1[2], $list2[2])]; + + if (isset($list1['enclosing'])) { + $res['enlcosing'] = $list1['enclosing']; + } + + if ($bracketed) { + $res['enclosing'] = 'bracket'; + } + + return $res; + } + + protected static $libAppend = ['list', 'val', 'separator:null']; + protected function libAppend($args) + { + list($list1, $value, $sep) = $args; + + $list1 = $this->coerceList($list1, ' ', true); + $sep = $this->listSeparatorForJoin($list1, $sep); + $res = [Type::T_LIST, $sep, array_merge($list1[2], [$value])]; + + if (isset($list1['enclosing'])) { + $res['enclosing'] = $list1['enclosing']; + } + + return $res; + } + + protected static $libZip = ['lists...']; + protected function libZip($args) + { + $argLists = []; + foreach ($args[0][2] as $arg) { + $argLists[] = $this->coerceList($arg); + } + + $lists = []; + $firstList = array_shift($argLists); + + $result = [Type::T_LIST, ',', $lists]; + if (! \is_null($firstList)) { + foreach ($firstList[2] as $key => $item) { + $list = [Type::T_LIST, '', [$item]]; + + foreach ($argLists as $arg) { + if (isset($arg[2][$key])) { + $list[2][] = $arg[2][$key]; + } else { + break 2; + } + } + + $lists[] = $list; + } + + $result[2] = $lists; + } else { + $result['enclosing'] = 'parent'; + } + + return $result; + } + + protected static $libTypeOf = ['value']; + protected function libTypeOf($args) + { + $value = $args[0]; + + return [Type::T_KEYWORD, $this->getTypeOf($value)]; + } + + /** + * @param array|Number $value + * + * @return string + */ + private function getTypeOf($value) + { + switch ($value[0]) { + case Type::T_KEYWORD: + if ($value === static::$true || $value === static::$false) { + return 'bool'; + } + + if ($this->coerceColor($value)) { + return 'color'; + } + + // fall-thru + case Type::T_FUNCTION: + return 'string'; + + case Type::T_FUNCTION_REFERENCE: + return 'function'; + + case Type::T_LIST: + if (isset($value[3]) && \is_array($value[3])) { + return 'arglist'; + } + + // fall-thru + default: + return $value[0]; + } + } + + protected static $libUnit = ['number']; + protected function libUnit($args) + { + $num = $this->assertNumber($args[0], 'number'); + + return [Type::T_STRING, '"', [$num->unitStr()]]; + } + + protected static $libUnitless = ['number']; + protected function libUnitless($args) + { + $value = $this->assertNumber($args[0], 'number'); + + return $this->toBool($value->unitless()); + } + + protected static $libComparable = [ + ['number1', 'number2'], + ['number-1', 'number-2'] + ]; + protected function libComparable($args) + { + list($number1, $number2) = $args; + + if ( + ! $number1 instanceof Number || + ! $number2 instanceof Number + ) { + throw $this->error('Invalid argument(s) for "comparable"'); + } + + return $this->toBool($number1->isComparableTo($number2)); + } + + protected static $libStrIndex = ['string', 'substring']; + protected function libStrIndex($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + $substring = $this->assertString($args[1], 'substring'); + $substringContent = $this->compileStringContent($substring); + + if (! \strlen($substringContent)) { + $result = 0; + } else { + $result = Util::mbStrpos($stringContent, $substringContent); + } + + return $result === false ? static::$null : new Number($result + 1, ''); + } + + protected static $libStrInsert = ['string', 'insert', 'index']; + protected function libStrInsert($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + $insert = $this->assertString($args[1], 'insert'); + $insertContent = $this->compileStringContent($insert); + + $index = $this->assertInteger($args[2], 'index'); + if ($index > 0) { + $index = $index - 1; + } + if ($index < 0) { + $index = Util::mbStrlen($stringContent) + 1 + $index; + } + + $string[2] = [ + Util::mbSubstr($stringContent, 0, $index), + $insertContent, + Util::mbSubstr($stringContent, $index) + ]; + + return $string; + } + + protected static $libStrLength = ['string']; + protected function libStrLength($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + return new Number(Util::mbStrlen($stringContent), ''); + } + + protected static $libStrSlice = ['string', 'start-at', 'end-at:-1']; + protected function libStrSlice($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + $start = $this->assertNumber($args[1], 'start-at'); + $start->assertNoUnits('start-at'); + $startInt = $this->assertInteger($start, 'start-at'); + $end = $this->assertNumber($args[2], 'end-at'); + $end->assertNoUnits('end-at'); + $endInt = $this->assertInteger($end, 'end-at'); + + if ($endInt === 0) { + return [Type::T_STRING, $string[1], []]; + } + + if ($startInt > 0) { + $startInt--; + } + + if ($endInt < 0) { + $endInt = Util::mbStrlen($stringContent) + $endInt; + } else { + $endInt--; + } + + if ($endInt < $startInt) { + return [Type::T_STRING, $string[1], []]; + } + + $length = $endInt - $startInt + 1; // The end of the slice is inclusive + + $string[2] = [Util::mbSubstr($stringContent, $startInt, $length)]; + + return $string; + } + + protected static $libToLowerCase = ['string']; + protected function libToLowerCase($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + $string[2] = [$this->stringTransformAsciiOnly($stringContent, 'strtolower')]; + + return $string; + } + + protected static $libToUpperCase = ['string']; + protected function libToUpperCase($args) + { + $string = $this->assertString($args[0], 'string'); + $stringContent = $this->compileStringContent($string); + + $string[2] = [$this->stringTransformAsciiOnly($stringContent, 'strtoupper')]; + + return $string; + } + + /** + * Apply a filter on a string content, only on ascii chars + * let extended chars untouched + * + * @param string $stringContent + * @param callable $filter + * @return string + */ + protected function stringTransformAsciiOnly($stringContent, $filter) + { + $mblength = Util::mbStrlen($stringContent); + if ($mblength === strlen($stringContent)) { + return $filter($stringContent); + } + $filteredString = ""; + for ($i = 0; $i < $mblength; $i++) { + $char = Util::mbSubstr($stringContent, $i, 1); + if (strlen($char) > 1) { + $filteredString .= $char; + } else { + $filteredString .= $filter($char); + } + } + + return $filteredString; + } + + protected static $libFeatureExists = ['feature']; + protected function libFeatureExists($args) + { + $string = $this->assertString($args[0], 'feature'); + $name = $this->compileStringContent($string); + + return $this->toBool( + \array_key_exists($name, $this->registeredFeatures) ? $this->registeredFeatures[$name] : false + ); + } + + protected static $libFunctionExists = ['name']; + protected function libFunctionExists($args) + { + $string = $this->assertString($args[0], 'name'); + $name = $this->compileStringContent($string); + + // user defined functions + if ($this->has(static::$namespaces['function'] . $name)) { + return self::$true; + } + + $name = $this->normalizeName($name); + + if (isset($this->userFunctions[$name])) { + return self::$true; + } + + // built-in functions + $f = $this->getBuiltinFunction($name); + + return $this->toBool(\is_callable($f)); + } + + protected static $libGlobalVariableExists = ['name']; + protected function libGlobalVariableExists($args) + { + $string = $this->assertString($args[0], 'name'); + $name = $this->compileStringContent($string); + + return $this->toBool($this->has($name, $this->rootEnv)); + } + + protected static $libMixinExists = ['name']; + protected function libMixinExists($args) + { + $string = $this->assertString($args[0], 'name'); + $name = $this->compileStringContent($string); + + return $this->toBool($this->has(static::$namespaces['mixin'] . $name)); + } + + protected static $libVariableExists = ['name']; + protected function libVariableExists($args) + { + $string = $this->assertString($args[0], 'name'); + $name = $this->compileStringContent($string); + + return $this->toBool($this->has($name)); + } + + protected static $libCounter = ['args...']; + /** + * Workaround IE7's content counter bug. + * + * @param array $args + * + * @return array + */ + protected function libCounter($args) + { + $list = array_map([$this, 'compileValue'], $args[0][2]); + + return [Type::T_STRING, '', ['counter(' . implode(',', $list) . ')']]; + } + + protected static $libRandom = ['limit:null']; + protected function libRandom($args) + { + if (isset($args[0]) && $args[0] !== static::$null) { + $n = $this->assertInteger($args[0], 'limit'); + + if ($n < 1) { + throw new SassScriptException("\$limit: Must be greater than 0, was $n."); + } + + return new Number(mt_rand(1, $n), ''); + } + + $max = mt_getrandmax(); + return new Number(mt_rand(0, $max - 1) / $max, ''); + } + + protected static $libUniqueId = []; + protected function libUniqueId() + { + static $id; + + if (! isset($id)) { + $id = PHP_INT_SIZE === 4 + ? mt_rand(0, pow(36, 5)) . str_pad(mt_rand(0, pow(36, 5)) % 10000000, 7, '0', STR_PAD_LEFT) + : mt_rand(0, pow(36, 8)); + } + + $id += mt_rand(0, 10) + 1; + + return [Type::T_STRING, '', ['u' . str_pad(base_convert($id, 10, 36), 8, '0', STR_PAD_LEFT)]]; + } + + /** + * @param array|Number $value + * @param bool $force_enclosing_display + * + * @return array + */ + protected function inspectFormatValue($value, $force_enclosing_display = false) + { + if ($value === static::$null) { + $value = [Type::T_KEYWORD, 'null']; + } + + $stringValue = [$value]; + + if ($value instanceof Number) { + return [Type::T_STRING, '', $stringValue]; + } + + if ($value[0] === Type::T_LIST) { + if (end($value[2]) === static::$null) { + array_pop($value[2]); + $value[2][] = [Type::T_STRING, '', ['']]; + $force_enclosing_display = true; + } + + if ( + ! empty($value['enclosing']) && + ($force_enclosing_display || + ($value['enclosing'] === 'bracket') || + ! \count($value[2])) + ) { + $value['enclosing'] = 'forced_' . $value['enclosing']; + $force_enclosing_display = true; + } + + foreach ($value[2] as $k => $listelement) { + $value[2][$k] = $this->inspectFormatValue($listelement, $force_enclosing_display); + } + + $stringValue = [$value]; + } + + return [Type::T_STRING, '', $stringValue]; + } + + protected static $libInspect = ['value']; + protected function libInspect($args) + { + $value = $args[0]; + + return $this->inspectFormatValue($value); + } + + /** + * Preprocess selector args + * + * @param array $arg + * @param string|null $varname + * @param bool $allowParent + * + * @return array + */ + protected function getSelectorArg($arg, $varname = null, $allowParent = false) + { + static $parser = null; + + if (\is_null($parser)) { + $parser = $this->parserFactory(__METHOD__); + } + + if (! $this->checkSelectorArgType($arg)) { + $var_value = $this->compileValue($arg); + throw SassScriptException::forArgument("$var_value is not a valid selector: it must be a string, a list of strings, or a list of lists of strings", $varname); + } + + + if ($arg[0] === Type::T_STRING) { + $arg[1] = ''; + } + $arg = $this->compileValue($arg); + + $parsedSelector = []; + + if ($parser->parseSelector($arg, $parsedSelector, true)) { + $selector = $this->evalSelectors($parsedSelector); + $gluedSelector = $this->glueFunctionSelectors($selector); + + if (! $allowParent) { + foreach ($gluedSelector as $selector) { + foreach ($selector as $s) { + if (in_array(static::$selfSelector, $s)) { + throw SassScriptException::forArgument("Parent selectors aren't allowed here.", $varname); + } + } + } + } + + return $gluedSelector; + } + + throw SassScriptException::forArgument("expected more input, invalid selector.", $varname); + } + + /** + * Check variable type for getSelectorArg() function + * @param array $arg + * @param int $maxDepth + * @return bool + */ + protected function checkSelectorArgType($arg, $maxDepth = 2) + { + if ($arg[0] === Type::T_LIST && $maxDepth > 0) { + foreach ($arg[2] as $elt) { + if (! $this->checkSelectorArgType($elt, $maxDepth - 1)) { + return false; + } + } + return true; + } + if (!in_array($arg[0], [Type::T_STRING, Type::T_KEYWORD])) { + return false; + } + return true; + } + + /** + * Postprocess selector to output in right format + * + * @param array $selectors + * + * @return array + */ + protected function formatOutputSelector($selectors) + { + $selectors = $this->collapseSelectorsAsList($selectors); + + return $selectors; + } + + protected static $libIsSuperselector = ['super', 'sub']; + protected function libIsSuperselector($args) + { + list($super, $sub) = $args; + + $super = $this->getSelectorArg($super, 'super'); + $sub = $this->getSelectorArg($sub, 'sub'); + + return $this->toBool($this->isSuperSelector($super, $sub)); + } + + /** + * Test a $super selector again $sub + * + * @param array $super + * @param array $sub + * + * @return boolean + */ + protected function isSuperSelector($super, $sub) + { + // one and only one selector for each arg + if (! $super) { + throw $this->error('Invalid super selector for isSuperSelector()'); + } + + if (! $sub) { + throw $this->error('Invalid sub selector for isSuperSelector()'); + } + + if (count($sub) > 1) { + foreach ($sub as $s) { + if (! $this->isSuperSelector($super, [$s])) { + return false; + } + } + return true; + } + + if (count($super) > 1) { + foreach ($super as $s) { + if ($this->isSuperSelector([$s], $sub)) { + return true; + } + } + return false; + } + + $super = reset($super); + $sub = reset($sub); + + $i = 0; + $nextMustMatch = false; + + foreach ($super as $node) { + $compound = ''; + + array_walk_recursive( + $node, + function ($value, $key) use (&$compound) { + $compound .= $value; + } + ); + + if ($this->isImmediateRelationshipCombinator($compound)) { + if ($node !== $sub[$i]) { + return false; + } + + $nextMustMatch = true; + $i++; + } else { + while ($i < \count($sub) && ! $this->isSuperPart($node, $sub[$i])) { + if ($nextMustMatch) { + return false; + } + + $i++; + } + + if ($i >= \count($sub)) { + return false; + } + + $nextMustMatch = false; + $i++; + } + } + + return true; + } + + /** + * Test a part of super selector again a part of sub selector + * + * @param array $superParts + * @param array $subParts + * + * @return boolean + */ + protected function isSuperPart($superParts, $subParts) + { + $i = 0; + + foreach ($superParts as $superPart) { + while ($i < \count($subParts) && $subParts[$i] !== $superPart) { + $i++; + } + + if ($i >= \count($subParts)) { + return false; + } + + $i++; + } + + return true; + } + + protected static $libSelectorAppend = ['selector...']; + protected function libSelectorAppend($args) + { + // get the selector... list + $args = reset($args); + $args = $args[2]; + + if (\count($args) < 1) { + throw $this->error('selector-append() needs at least 1 argument'); + } + + $selectors = []; + foreach ($args as $arg) { + $selectors[] = $this->getSelectorArg($arg, 'selector'); + } + + return $this->formatOutputSelector($this->selectorAppend($selectors)); + } + + /** + * Append parts of the last selector in the list to the previous, recursively + * + * @param array $selectors + * + * @return array + * + * @throws \ScssPhp\ScssPhp\Exception\CompilerException + */ + protected function selectorAppend($selectors) + { + $lastSelectors = array_pop($selectors); + + if (! $lastSelectors) { + throw $this->error('Invalid selector list in selector-append()'); + } + + while (\count($selectors)) { + $previousSelectors = array_pop($selectors); + + if (! $previousSelectors) { + throw $this->error('Invalid selector list in selector-append()'); + } + + // do the trick, happening $lastSelector to $previousSelector + $appended = []; + + foreach ($lastSelectors as $lastSelector) { + $previous = $previousSelectors; + + foreach ($lastSelector as $lastSelectorParts) { + foreach ($lastSelectorParts as $lastSelectorPart) { + foreach ($previous as $i => $previousSelector) { + foreach ($previousSelector as $j => $previousSelectorParts) { + $previous[$i][$j][] = $lastSelectorPart; + } + } + } + } + + foreach ($previous as $ps) { + $appended[] = $ps; + } + } + + $lastSelectors = $appended; + } + + return $lastSelectors; + } + + protected static $libSelectorExtend = [ + ['selector', 'extendee', 'extender'], + ['selectors', 'extendee', 'extender'] + ]; + protected function libSelectorExtend($args) + { + list($selectors, $extendee, $extender) = $args; + + $selectors = $this->getSelectorArg($selectors, 'selector'); + $extendee = $this->getSelectorArg($extendee, 'extendee'); + $extender = $this->getSelectorArg($extender, 'extender'); + + if (! $selectors || ! $extendee || ! $extender) { + throw $this->error('selector-extend() invalid arguments'); + } + + $extended = $this->extendOrReplaceSelectors($selectors, $extendee, $extender); + + return $this->formatOutputSelector($extended); + } + + protected static $libSelectorReplace = [ + ['selector', 'original', 'replacement'], + ['selectors', 'original', 'replacement'] + ]; + protected function libSelectorReplace($args) + { + list($selectors, $original, $replacement) = $args; + + $selectors = $this->getSelectorArg($selectors, 'selector'); + $original = $this->getSelectorArg($original, 'original'); + $replacement = $this->getSelectorArg($replacement, 'replacement'); + + if (! $selectors || ! $original || ! $replacement) { + throw $this->error('selector-replace() invalid arguments'); + } + + $replaced = $this->extendOrReplaceSelectors($selectors, $original, $replacement, true); + + return $this->formatOutputSelector($replaced); + } + + /** + * Extend/replace in selectors + * used by selector-extend and selector-replace that use the same logic + * + * @param array $selectors + * @param array $extendee + * @param array $extender + * @param boolean $replace + * + * @return array + */ + protected function extendOrReplaceSelectors($selectors, $extendee, $extender, $replace = false) + { + $saveExtends = $this->extends; + $saveExtendsMap = $this->extendsMap; + + $this->extends = []; + $this->extendsMap = []; + + foreach ($extendee as $es) { + if (\count($es) !== 1) { + throw $this->error('Can\'t extend complex selector.'); + } + + // only use the first one + $this->pushExtends(reset($es), $extender, null); + } + + $extended = []; + + foreach ($selectors as $selector) { + if (! $replace) { + $extended[] = $selector; + } + + $n = \count($extended); + + $this->matchExtends($selector, $extended); + + // if didnt match, keep the original selector if we are in a replace operation + if ($replace && \count($extended) === $n) { + $extended[] = $selector; + } + } + + $this->extends = $saveExtends; + $this->extendsMap = $saveExtendsMap; + + return $extended; + } + + protected static $libSelectorNest = ['selector...']; + protected function libSelectorNest($args) + { + // get the selector... list + $args = reset($args); + $args = $args[2]; + + if (\count($args) < 1) { + throw $this->error('selector-nest() needs at least 1 argument'); + } + + $selectorsMap = []; + foreach ($args as $arg) { + $selectorsMap[] = $this->getSelectorArg($arg, 'selector', true); + } + + $envs = []; + + foreach ($selectorsMap as $selectors) { + $env = new Environment(); + $env->selectors = $selectors; + + $envs[] = $env; + } + + $envs = array_reverse($envs); + $env = $this->extractEnv($envs); + $outputSelectors = $this->multiplySelectors($env); + + return $this->formatOutputSelector($outputSelectors); + } + + protected static $libSelectorParse = [ + ['selector'], + ['selectors'] + ]; + protected function libSelectorParse($args) + { + $selectors = reset($args); + $selectors = $this->getSelectorArg($selectors, 'selector'); + + return $this->formatOutputSelector($selectors); + } + + protected static $libSelectorUnify = ['selectors1', 'selectors2']; + protected function libSelectorUnify($args) + { + list($selectors1, $selectors2) = $args; + + $selectors1 = $this->getSelectorArg($selectors1, 'selectors1'); + $selectors2 = $this->getSelectorArg($selectors2, 'selectors2'); + + if (! $selectors1 || ! $selectors2) { + throw $this->error('selector-unify() invalid arguments'); + } + + // only consider the first compound of each + $compound1 = reset($selectors1); + $compound2 = reset($selectors2); + + // unify them and that's it + $unified = $this->unifyCompoundSelectors($compound1, $compound2); + + return $this->formatOutputSelector($unified); + } + + /** + * The selector-unify magic as its best + * (at least works as expected on test cases) + * + * @param array $compound1 + * @param array $compound2 + * + * @return array + */ + protected function unifyCompoundSelectors($compound1, $compound2) + { + if (! \count($compound1)) { + return $compound2; + } + + if (! \count($compound2)) { + return $compound1; + } + + // check that last part are compatible + $lastPart1 = array_pop($compound1); + $lastPart2 = array_pop($compound2); + $last = $this->mergeParts($lastPart1, $lastPart2); + + if (! $last) { + return [[]]; + } + + $unifiedCompound = [$last]; + $unifiedSelectors = [$unifiedCompound]; + + // do the rest + while (\count($compound1) || \count($compound2)) { + $part1 = end($compound1); + $part2 = end($compound2); + + if ($part1 && ($match2 = $this->matchPartInCompound($part1, $compound2))) { + list($compound2, $part2, $after2) = $match2; + + if ($after2) { + $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after2); + } + + $c = $this->mergeParts($part1, $part2); + $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]); + + $part1 = $part2 = null; + + array_pop($compound1); + } + + if ($part2 && ($match1 = $this->matchPartInCompound($part2, $compound1))) { + list($compound1, $part1, $after1) = $match1; + + if ($after1) { + $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after1); + } + + $c = $this->mergeParts($part2, $part1); + $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]); + + $part1 = $part2 = null; + + array_pop($compound2); + } + + $new = []; + + if ($part1 && $part2) { + array_pop($compound1); + array_pop($compound2); + + $s = $this->prependSelectors($unifiedSelectors, [$part2]); + $new = array_merge($new, $this->prependSelectors($s, [$part1])); + $s = $this->prependSelectors($unifiedSelectors, [$part1]); + $new = array_merge($new, $this->prependSelectors($s, [$part2])); + } elseif ($part1) { + array_pop($compound1); + + $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part1])); + } elseif ($part2) { + array_pop($compound2); + + $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part2])); + } + + if ($new) { + $unifiedSelectors = $new; + } + } + + return $unifiedSelectors; + } + + /** + * Prepend each selector from $selectors with $parts + * + * @param array $selectors + * @param array $parts + * + * @return array + */ + protected function prependSelectors($selectors, $parts) + { + $new = []; + + foreach ($selectors as $compoundSelector) { + array_unshift($compoundSelector, $parts); + + $new[] = $compoundSelector; + } + + return $new; + } + + /** + * Try to find a matching part in a compound: + * - with same html tag name + * - with some class or id or something in common + * + * @param array $part + * @param array $compound + * + * @return array|false + */ + protected function matchPartInCompound($part, $compound) + { + $partTag = $this->findTagName($part); + $before = $compound; + $after = []; + + // try to find a match by tag name first + while (\count($before)) { + $p = array_pop($before); + + if ($partTag && $partTag !== '*' && $partTag == $this->findTagName($p)) { + return [$before, $p, $after]; + } + + $after[] = $p; + } + + // try again matching a non empty intersection and a compatible tagname + $before = $compound; + $after = []; + + while (\count($before)) { + $p = array_pop($before); + + if ($this->checkCompatibleTags($partTag, $this->findTagName($p))) { + if (\count(array_intersect($part, $p))) { + return [$before, $p, $after]; + } + } + + $after[] = $p; + } + + return false; + } + + /** + * Merge two part list taking care that + * - the html tag is coming first - if any + * - the :something are coming last + * + * @param array $parts1 + * @param array $parts2 + * + * @return array + */ + protected function mergeParts($parts1, $parts2) + { + $tag1 = $this->findTagName($parts1); + $tag2 = $this->findTagName($parts2); + $tag = $this->checkCompatibleTags($tag1, $tag2); + + // not compatible tags + if ($tag === false) { + return []; + } + + if ($tag) { + if ($tag1) { + $parts1 = array_diff($parts1, [$tag1]); + } + + if ($tag2) { + $parts2 = array_diff($parts2, [$tag2]); + } + } + + $mergedParts = array_merge($parts1, $parts2); + $mergedOrderedParts = []; + + foreach ($mergedParts as $part) { + if (strpos($part, ':') === 0) { + $mergedOrderedParts[] = $part; + } + } + + $mergedParts = array_diff($mergedParts, $mergedOrderedParts); + $mergedParts = array_merge($mergedParts, $mergedOrderedParts); + + if ($tag) { + array_unshift($mergedParts, $tag); + } + + return $mergedParts; + } + + /** + * Check the compatibility between two tag names: + * if both are defined they should be identical or one has to be '*' + * + * @param string $tag1 + * @param string $tag2 + * + * @return array|false + */ + protected function checkCompatibleTags($tag1, $tag2) + { + $tags = [$tag1, $tag2]; + $tags = array_unique($tags); + $tags = array_filter($tags); + + if (\count($tags) > 1) { + $tags = array_diff($tags, ['*']); + } + + // not compatible nodes + if (\count($tags) > 1) { + return false; + } + + return $tags; + } + + /** + * Find the html tag name in a selector parts list + * + * @param string[] $parts + * + * @return string + */ + protected function findTagName($parts) + { + foreach ($parts as $part) { + if (! preg_match('/^[\[.:#%_-]/', $part)) { + return $part; + } + } + + return ''; + } + + protected static $libSimpleSelectors = ['selector']; + protected function libSimpleSelectors($args) + { + $selector = reset($args); + $selector = $this->getSelectorArg($selector, 'selector'); + + // remove selectors list layer, keeping the first one + $selector = reset($selector); + + // remove parts list layer, keeping the first part + $part = reset($selector); + + $listParts = []; + + foreach ($part as $p) { + $listParts[] = [Type::T_STRING, '', [$p]]; + } + + return [Type::T_LIST, ',', $listParts]; + } + + protected static $libScssphpGlob = ['pattern']; + protected function libScssphpGlob($args) + { + @trigger_error(sprintf('The "scssphp-glob" function is deprecated an will be removed in ScssPhp 2.0. Register your own alternative through "%s::registerFunction', __CLASS__), E_USER_DEPRECATED); + + $this->logger->warn('The "scssphp-glob" function is deprecated an will be removed in ScssPhp 2.0.', true); + + $string = $this->assertString($args[0], 'pattern'); + $pattern = $this->compileStringContent($string); + $matches = glob($pattern); + $listParts = []; + + foreach ($matches as $match) { + if (! is_file($match)) { + continue; + } + + $listParts[] = [Type::T_STRING, '"', [$match]]; + } + + return [Type::T_LIST, ',', $listParts]; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php new file mode 100644 index 0000000..a662919 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php @@ -0,0 +1,77 @@ + + */ + private $parsedFiles; + + /** + * @var array + * @phpstan-var list + */ + private $resolvedImports; + + /** + * @param CompilationResult $result + * @param array $parsedFiles + * @param array $resolvedImports + * + * @phpstan-param list $resolvedImports + */ + public function __construct(CompilationResult $result, array $parsedFiles, array $resolvedImports) + { + $this->result = $result; + $this->parsedFiles = $parsedFiles; + $this->resolvedImports = $resolvedImports; + } + + /** + * @return CompilationResult + */ + public function getResult() + { + return $this->result; + } + + /** + * @return array + */ + public function getParsedFiles() + { + return $this->parsedFiles; + } + + /** + * @return array + * + * @phpstan-return list + */ + public function getResolvedImports() + { + return $this->resolvedImports; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php new file mode 100644 index 0000000..306b15a --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php @@ -0,0 +1,48 @@ + + * + * @internal + */ +class Environment +{ + /** + * @var \ScssPhp\ScssPhp\Block|null + */ + public $block; + + /** + * @var \ScssPhp\ScssPhp\Compiler\Environment|null + */ + public $parent; + + /** + * @var array + */ + public $store; + + /** + * @var array + */ + public $storeUnreduced; + + /** + * @var integer + */ + public $depth; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php new file mode 100644 index 0000000..0b00cf5 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php @@ -0,0 +1,24 @@ + + * + * @internal + */ +class CompilerException extends \Exception implements SassException +{ +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php new file mode 100644 index 0000000..00d77ec --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php @@ -0,0 +1,50 @@ + + * + * @internal + */ +class ParserException extends \Exception implements SassException +{ + /** + * @var array + */ + private $sourcePosition; + + /** + * Get source position + * + * @api + */ + public function getSourcePosition() + { + return $this->sourcePosition; + } + + /** + * Set source position + * + * @api + * + * @param array $sourcePosition + */ + public function setSourcePosition($sourcePosition) + { + $this->sourcePosition = $sourcePosition; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php new file mode 100644 index 0000000..4be4dee --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php @@ -0,0 +1,24 @@ + + * + * @internal + */ +class RangeException extends \Exception implements SassException +{ +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php new file mode 100644 index 0000000..9f62b3c --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php @@ -0,0 +1,7 @@ + + * + * @deprecated The Scssphp server should define its own exception instead. + */ +class ServerException extends \Exception implements SassException +{ +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php new file mode 100644 index 0000000..cc42ae8 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php @@ -0,0 +1,364 @@ + + * + * @internal + */ +abstract class Formatter +{ + /** + * @var integer + */ + public $indentLevel; + + /** + * @var string + */ + public $indentChar; + + /** + * @var string + */ + public $break; + + /** + * @var string + */ + public $open; + + /** + * @var string + */ + public $close; + + /** + * @var string + */ + public $tagSeparator; + + /** + * @var string + */ + public $assignSeparator; + + /** + * @var boolean + */ + public $keepSemicolons; + + /** + * @var \ScssPhp\ScssPhp\Formatter\OutputBlock + */ + protected $currentBlock; + + /** + * @var integer + */ + protected $currentLine; + + /** + * @var integer + */ + protected $currentColumn; + + /** + * @var \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null + */ + protected $sourceMapGenerator; + + /** + * @var string + */ + protected $strippedSemicolon; + + /** + * Initialize formatter + * + * @api + */ + abstract public function __construct(); + + /** + * Return indentation (whitespace) + * + * @return string + */ + protected function indentStr() + { + return ''; + } + + /** + * Return property assignment + * + * @api + * + * @param string $name + * @param mixed $value + * + * @return string + */ + public function property($name, $value) + { + return rtrim($name) . $this->assignSeparator . $value . ';'; + } + + /** + * Return custom property assignment + * differs in that you have to keep spaces in the value as is + * + * @api + * + * @param string $name + * @param mixed $value + * + * @return string + */ + public function customProperty($name, $value) + { + return rtrim($name) . trim($this->assignSeparator) . $value . ';'; + } + + /** + * Output lines inside a block + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return void + */ + protected function blockLines(OutputBlock $block) + { + $inner = $this->indentStr(); + $glue = $this->break . $inner; + + $this->write($inner . implode($glue, $block->lines)); + + if (! empty($block->children)) { + $this->write($this->break); + } + } + + /** + * Output block selectors + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return void + */ + protected function blockSelectors(OutputBlock $block) + { + assert(! empty($block->selectors)); + + $inner = $this->indentStr(); + + $this->write($inner + . implode($this->tagSeparator, $block->selectors) + . $this->open . $this->break); + } + + /** + * Output block children + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return void + */ + protected function blockChildren(OutputBlock $block) + { + foreach ($block->children as $child) { + $this->block($child); + } + } + + /** + * Output non-empty block + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return void + */ + protected function block(OutputBlock $block) + { + if (empty($block->lines) && empty($block->children)) { + return; + } + + $this->currentBlock = $block; + + $pre = $this->indentStr(); + + if (! empty($block->selectors)) { + $this->blockSelectors($block); + + $this->indentLevel++; + } + + if (! empty($block->lines)) { + $this->blockLines($block); + } + + if (! empty($block->children)) { + $this->blockChildren($block); + } + + if (! empty($block->selectors)) { + $this->indentLevel--; + + if (! $this->keepSemicolons) { + $this->strippedSemicolon = ''; + } + + if (empty($block->children)) { + $this->write($this->break); + } + + $this->write($pre . $this->close . $this->break); + } + } + + /** + * Test and clean safely empty children + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return boolean + */ + protected function testEmptyChildren($block) + { + $isEmpty = empty($block->lines); + + if ($block->children) { + foreach ($block->children as $k => &$child) { + if (! $this->testEmptyChildren($child)) { + $isEmpty = false; + continue; + } + + if ($child->type === Type::T_MEDIA || $child->type === Type::T_DIRECTIVE) { + $child->children = []; + $child->selectors = null; + } + } + } + + return $isEmpty; + } + + /** + * Entry point to formatting a block + * + * @api + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree + * @param \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator + * + * @return string + */ + public function format(OutputBlock $block, SourceMapGenerator $sourceMapGenerator = null) + { + $this->sourceMapGenerator = null; + + if ($sourceMapGenerator) { + $this->currentLine = 1; + $this->currentColumn = 0; + $this->sourceMapGenerator = $sourceMapGenerator; + } + + $this->testEmptyChildren($block); + + ob_start(); + + $this->block($block); + + $out = ob_get_clean(); + + return $out; + } + + /** + * Output content + * + * @param string $str + * + * @return void + */ + protected function write($str) + { + if (! empty($this->strippedSemicolon)) { + echo $this->strippedSemicolon; + + $this->strippedSemicolon = ''; + } + + /* + * Maybe Strip semi-colon appended by property(); it's a separator, not a terminator + * will be striped for real before a closing, otherwise displayed unchanged starting the next write + */ + if ( + ! $this->keepSemicolons && + $str && + (strpos($str, ';') !== false) && + (substr($str, -1) === ';') + ) { + $str = substr($str, 0, -1); + + $this->strippedSemicolon = ';'; + } + + if ($this->sourceMapGenerator) { + $lines = explode("\n", $str); + $lastLine = array_pop($lines); + + foreach ($lines as $line) { + // If the written line starts is empty, adding a mapping would add it for + // a non-existent column as we are at the end of the line + if ($line !== '') { + $this->sourceMapGenerator->addMapping( + $this->currentLine, + $this->currentColumn, + $this->currentBlock->sourceLine, + //columns from parser are off by one + $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0, + $this->currentBlock->sourceName + ); + } + + $this->currentLine++; + $this->currentColumn = 0; + } + + if ($lastLine !== '') { + $this->sourceMapGenerator->addMapping( + $this->currentLine, + $this->currentColumn, + $this->currentBlock->sourceLine, + //columns from parser are off by one + $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0, + $this->currentBlock->sourceName + ); + } + + $this->currentColumn += \strlen($lastLine); + } + + echo $str; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php new file mode 100644 index 0000000..22f2268 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php @@ -0,0 +1,52 @@ + + * + * @deprecated since 1.4.0. Use the Compressed formatter instead. + * + * @internal + */ +class Compact extends Formatter +{ + /** + * {@inheritdoc} + */ + public function __construct() + { + @trigger_error('The Compact formatter is deprecated since 1.4.0. Use the Compressed formatter instead.', E_USER_DEPRECATED); + + $this->indentLevel = 0; + $this->indentChar = ''; + $this->break = ''; + $this->open = ' {'; + $this->close = "}\n\n"; + $this->tagSeparator = ','; + $this->assignSeparator = ':'; + $this->keepSemicolons = true; + } + + /** + * {@inheritdoc} + */ + public function indentStr() + { + return ' '; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php new file mode 100644 index 0000000..de13c18 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php @@ -0,0 +1,85 @@ + + * + * @internal + */ +class Compressed extends Formatter +{ + /** + * {@inheritdoc} + */ + public function __construct() + { + $this->indentLevel = 0; + $this->indentChar = ' '; + $this->break = ''; + $this->open = '{'; + $this->close = '}'; + $this->tagSeparator = ','; + $this->assignSeparator = ':'; + $this->keepSemicolons = false; + } + + /** + * {@inheritdoc} + */ + public function blockLines(OutputBlock $block) + { + $inner = $this->indentStr(); + + $glue = $this->break . $inner; + + foreach ($block->lines as $index => $line) { + if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') { + unset($block->lines[$index]); + } elseif (substr($line, 0, 3) === '/*!') { + $block->lines[$index] = '/*' . substr($line, 3); + } + } + + $this->write($inner . implode($glue, $block->lines)); + + if (! empty($block->children)) { + $this->write($this->break); + } + } + + /** + * Output block selectors + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + */ + protected function blockSelectors(OutputBlock $block) + { + assert(! empty($block->selectors)); + + $inner = $this->indentStr(); + + $this->write( + $inner + . implode( + $this->tagSeparator, + str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors) + ) + . $this->open . $this->break + ); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php new file mode 100644 index 0000000..2bc1e92 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php @@ -0,0 +1,87 @@ + + * + * @deprecated since 1.4.0. Use the Compressed formatter instead. + * + * @internal + */ +class Crunched extends Formatter +{ + /** + * {@inheritdoc} + */ + public function __construct() + { + @trigger_error('The Crunched formatter is deprecated since 1.4.0. Use the Compressed formatter instead.', E_USER_DEPRECATED); + + $this->indentLevel = 0; + $this->indentChar = ' '; + $this->break = ''; + $this->open = '{'; + $this->close = '}'; + $this->tagSeparator = ','; + $this->assignSeparator = ':'; + $this->keepSemicolons = false; + } + + /** + * {@inheritdoc} + */ + public function blockLines(OutputBlock $block) + { + $inner = $this->indentStr(); + + $glue = $this->break . $inner; + + foreach ($block->lines as $index => $line) { + if (substr($line, 0, 2) === '/*') { + unset($block->lines[$index]); + } + } + + $this->write($inner . implode($glue, $block->lines)); + + if (! empty($block->children)) { + $this->write($this->break); + } + } + + /** + * Output block selectors + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + */ + protected function blockSelectors(OutputBlock $block) + { + assert(! empty($block->selectors)); + + $inner = $this->indentStr(); + + $this->write( + $inner + . implode( + $this->tagSeparator, + str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors) + ) + . $this->open . $this->break + ); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php new file mode 100644 index 0000000..b3f4422 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php @@ -0,0 +1,127 @@ + + * + * @deprecated since 1.4.0. + * + * @internal + */ +class Debug extends Formatter +{ + /** + * {@inheritdoc} + */ + public function __construct() + { + @trigger_error('The Debug formatter is deprecated since 1.4.0.', E_USER_DEPRECATED); + + $this->indentLevel = 0; + $this->indentChar = ''; + $this->break = "\n"; + $this->open = ' {'; + $this->close = ' }'; + $this->tagSeparator = ', '; + $this->assignSeparator = ': '; + $this->keepSemicolons = true; + } + + /** + * {@inheritdoc} + */ + protected function indentStr() + { + return str_repeat(' ', $this->indentLevel); + } + + /** + * {@inheritdoc} + */ + protected function blockLines(OutputBlock $block) + { + $indent = $this->indentStr(); + + if (empty($block->lines)) { + $this->write("{$indent}block->lines: []\n"); + + return; + } + + foreach ($block->lines as $index => $line) { + $this->write("{$indent}block->lines[{$index}]: $line\n"); + } + } + + /** + * {@inheritdoc} + */ + protected function blockSelectors(OutputBlock $block) + { + $indent = $this->indentStr(); + + if (empty($block->selectors)) { + $this->write("{$indent}block->selectors: []\n"); + + return; + } + + foreach ($block->selectors as $index => $selector) { + $this->write("{$indent}block->selectors[{$index}]: $selector\n"); + } + } + + /** + * {@inheritdoc} + */ + protected function blockChildren(OutputBlock $block) + { + $indent = $this->indentStr(); + + if (empty($block->children)) { + $this->write("{$indent}block->children: []\n"); + + return; + } + + $this->indentLevel++; + + foreach ($block->children as $i => $child) { + $this->block($child); + } + + $this->indentLevel--; + } + + /** + * {@inheritdoc} + */ + protected function block(OutputBlock $block) + { + $indent = $this->indentStr(); + + $this->write("{$indent}block->type: {$block->type}\n" . + "{$indent}block->depth: {$block->depth}\n"); + + $this->currentBlock = $block; + + $this->blockSelectors($block); + $this->blockLines($block); + $this->blockChildren($block); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php new file mode 100644 index 0000000..a280416 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php @@ -0,0 +1,70 @@ + + * + * @internal + */ +class Expanded extends Formatter +{ + /** + * {@inheritdoc} + */ + public function __construct() + { + $this->indentLevel = 0; + $this->indentChar = ' '; + $this->break = "\n"; + $this->open = ' {'; + $this->close = '}'; + $this->tagSeparator = ', '; + $this->assignSeparator = ': '; + $this->keepSemicolons = true; + } + + /** + * {@inheritdoc} + */ + protected function indentStr() + { + return str_repeat($this->indentChar, $this->indentLevel); + } + + /** + * {@inheritdoc} + */ + protected function blockLines(OutputBlock $block) + { + $inner = $this->indentStr(); + + $glue = $this->break . $inner; + + foreach ($block->lines as $index => $line) { + if (substr($line, 0, 2) === '/*') { + $block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line); + } + } + + $this->write($inner . implode($glue, $block->lines)); + + if (empty($block->selectors) || ! empty($block->children)) { + $this->write($this->break); + } + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php new file mode 100644 index 0000000..9e72956 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php @@ -0,0 +1,236 @@ + + * + * @deprecated since 1.4.0. Use the Expanded formatter instead. + * + * @internal + */ +class Nested extends Formatter +{ + /** + * @var integer + */ + private $depth; + + /** + * {@inheritdoc} + */ + public function __construct() + { + @trigger_error('The Nested formatter is deprecated since 1.4.0. Use the Expanded formatter instead.', E_USER_DEPRECATED); + + $this->indentLevel = 0; + $this->indentChar = ' '; + $this->break = "\n"; + $this->open = ' {'; + $this->close = ' }'; + $this->tagSeparator = ', '; + $this->assignSeparator = ': '; + $this->keepSemicolons = true; + } + + /** + * {@inheritdoc} + */ + protected function indentStr() + { + $n = $this->depth - 1; + + return str_repeat($this->indentChar, max($this->indentLevel + $n, 0)); + } + + /** + * {@inheritdoc} + */ + protected function blockLines(OutputBlock $block) + { + $inner = $this->indentStr(); + $glue = $this->break . $inner; + + foreach ($block->lines as $index => $line) { + if (substr($line, 0, 2) === '/*') { + $block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line); + } + } + + $this->write($inner . implode($glue, $block->lines)); + } + + /** + * {@inheritdoc} + */ + protected function block(OutputBlock $block) + { + static $depths; + static $downLevel; + static $closeBlock; + static $previousEmpty; + static $previousHasSelector; + + if ($block->type === 'root') { + $depths = [ 0 ]; + $downLevel = ''; + $closeBlock = ''; + $this->depth = 0; + $previousEmpty = false; + $previousHasSelector = false; + } + + $isMediaOrDirective = \in_array($block->type, [Type::T_DIRECTIVE, Type::T_MEDIA]); + $isSupport = ($block->type === Type::T_DIRECTIVE + && $block->selectors && strpos(implode('', $block->selectors), '@supports') !== false); + + while ($block->depth < end($depths) || ($block->depth == 1 && end($depths) == 1)) { + array_pop($depths); + $this->depth--; + + if ( + ! $this->depth && ($block->depth <= 1 || (! $this->indentLevel && $block->type === Type::T_COMMENT)) && + (($block->selectors && ! $isMediaOrDirective) || $previousHasSelector) + ) { + $downLevel = $this->break; + } + + if (empty($block->lines) && empty($block->children)) { + $previousEmpty = true; + } + } + + if (empty($block->lines) && empty($block->children)) { + return; + } + + $this->currentBlock = $block; + + if (! empty($block->lines) || (! empty($block->children) && ($this->depth < 1 || $isSupport))) { + if ($block->depth > end($depths)) { + if (! $previousEmpty || $this->depth < 1) { + $this->depth++; + + $depths[] = $block->depth; + } else { + // keep the current depth unchanged but take the block depth as a new reference for following blocks + array_pop($depths); + + $depths[] = $block->depth; + } + } + } + + $previousEmpty = ($block->type === Type::T_COMMENT); + $previousHasSelector = false; + + if (! empty($block->selectors)) { + if ($closeBlock) { + $this->write($closeBlock); + $closeBlock = ''; + } + + if ($downLevel) { + $this->write($downLevel); + $downLevel = ''; + } + + $this->blockSelectors($block); + + $this->indentLevel++; + } + + if (! empty($block->lines)) { + if ($closeBlock) { + $this->write($closeBlock); + $closeBlock = ''; + } + + if ($downLevel) { + $this->write($downLevel); + $downLevel = ''; + } + + $this->blockLines($block); + + $closeBlock = $this->break; + } + + if (! empty($block->children)) { + if ($this->depth > 0 && ($isMediaOrDirective || ! $this->hasFlatChild($block))) { + array_pop($depths); + + $this->depth--; + $this->blockChildren($block); + $this->depth++; + + $depths[] = $block->depth; + } else { + $this->blockChildren($block); + } + } + + // reclear to not be spoiled by children if T_DIRECTIVE + if ($block->type === Type::T_DIRECTIVE) { + $previousHasSelector = false; + } + + if (! empty($block->selectors)) { + $this->indentLevel--; + + if (! $this->keepSemicolons) { + $this->strippedSemicolon = ''; + } + + $this->write($this->close); + + $closeBlock = $this->break; + + if ($this->depth > 1 && ! empty($block->children)) { + array_pop($depths); + $this->depth--; + } + + if (! $isMediaOrDirective) { + $previousHasSelector = true; + } + } + + if ($block->type === 'root') { + $this->write($this->break); + } + } + + /** + * Block has flat child + * + * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block + * + * @return boolean + */ + private function hasFlatChild($block) + { + foreach ($block->children as $child) { + if (empty($child->selectors)) { + return true; + } + } + + return false; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php new file mode 100644 index 0000000..88deb2d --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php @@ -0,0 +1,68 @@ + + * + * @internal + */ +class OutputBlock +{ + /** + * @var string + */ + public $type; + + /** + * @var integer + */ + public $depth; + + /** + * @var array|null + */ + public $selectors; + + /** + * @var string[] + */ + public $lines; + + /** + * @var OutputBlock[] + */ + public $children; + + /** + * @var OutputBlock|null + */ + public $parent; + + /** + * @var string|null + */ + public $sourceName; + + /** + * @var integer|null + */ + public $sourceLine; + + /** + * @var integer|null + */ + public $sourceColumn; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php b/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php new file mode 100644 index 0000000..7c0a2f7 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php @@ -0,0 +1,48 @@ +stream = $stream; + $this->closeOnDestruct = $closeOnDestruct; + } + + /** + * @internal + */ + public function __destruct() + { + if ($this->closeOnDestruct) { + fclose($this->stream); + } + } + + /** + * @inheritDoc + */ + public function warn($message, $deprecation = false) + { + $prefix = ($deprecation ? 'DEPRECATION ' : '') . 'WARNING: '; + + fwrite($this->stream, $prefix . $message . "\n\n"); + } + + /** + * @inheritDoc + */ + public function debug($message) + { + fwrite($this->stream, $message . "\n"); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Node.php b/plugins/admin/vendor/scssphp/scssphp/src/Node.php new file mode 100644 index 0000000..5301937 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Node.php @@ -0,0 +1,43 @@ + + * + * @internal + */ +abstract class Node +{ + /** + * @var string + */ + public $type; + + /** + * @var integer + */ + public $sourceIndex; + + /** + * @var int|null + */ + public $sourceLine; + + /** + * @var int|null + */ + public $sourceColumn; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php b/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php new file mode 100644 index 0000000..b326906 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php @@ -0,0 +1,804 @@ + + * + * @template-implements \ArrayAccess + */ +class Number extends Node implements \ArrayAccess +{ + const PRECISION = 10; + + /** + * @var integer + * @deprecated use {Number::PRECISION} instead to read the precision. Configuring it is not supported anymore. + */ + public static $precision = self::PRECISION; + + /** + * @see http://www.w3.org/TR/2012/WD-css3-values-20120308/ + * + * @var array + * @phpstan-var array> + */ + protected static $unitTable = [ + 'in' => [ + 'in' => 1, + 'pc' => 6, + 'pt' => 72, + 'px' => 96, + 'cm' => 2.54, + 'mm' => 25.4, + 'q' => 101.6, + ], + 'turn' => [ + 'deg' => 360, + 'grad' => 400, + 'rad' => 6.28318530717958647692528676, // 2 * M_PI + 'turn' => 1, + ], + 's' => [ + 's' => 1, + 'ms' => 1000, + ], + 'Hz' => [ + 'Hz' => 1, + 'kHz' => 0.001, + ], + 'dpi' => [ + 'dpi' => 1, + 'dpcm' => 1 / 2.54, + 'dppx' => 1 / 96, + ], + ]; + + /** + * @var integer|float + */ + private $dimension; + + /** + * @var string[] + * @phpstan-var list + */ + private $numeratorUnits; + + /** + * @var string[] + * @phpstan-var list + */ + private $denominatorUnits; + + /** + * Initialize number + * + * @param integer|float $dimension + * @param string[]|string $numeratorUnits + * @param string[] $denominatorUnits + * + * @phpstan-param list|string $numeratorUnits + * @phpstan-param list $denominatorUnits + */ + public function __construct($dimension, $numeratorUnits, array $denominatorUnits = []) + { + if (is_string($numeratorUnits)) { + $numeratorUnits = $numeratorUnits ? [$numeratorUnits] : []; + } elseif (isset($numeratorUnits['numerator_units'], $numeratorUnits['denominator_units'])) { + // TODO get rid of this once `$number[2]` is not used anymore + $denominatorUnits = $numeratorUnits['denominator_units']; + $numeratorUnits = $numeratorUnits['numerator_units']; + } + + $this->dimension = $dimension; + $this->numeratorUnits = $numeratorUnits; + $this->denominatorUnits = $denominatorUnits; + } + + /** + * @return float|int + */ + public function getDimension() + { + return $this->dimension; + } + + /** + * @return string[] + */ + public function getNumeratorUnits() + { + return $this->numeratorUnits; + } + + /** + * @return string[] + */ + public function getDenominatorUnits() + { + return $this->denominatorUnits; + } + + /** + * {@inheritdoc} + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + if ($offset === -3) { + return ! \is_null($this->sourceColumn); + } + + if ($offset === -2) { + return ! \is_null($this->sourceLine); + } + + if ( + $offset === -1 || + $offset === 0 || + $offset === 1 || + $offset === 2 + ) { + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + switch ($offset) { + case -3: + return $this->sourceColumn; + + case -2: + return $this->sourceLine; + + case -1: + return $this->sourceIndex; + + case 0: + return Type::T_NUMBER; + + case 1: + return $this->dimension; + + case 2: + return array('numerator_units' => $this->numeratorUnits, 'denominator_units' => $this->denominatorUnits); + } + } + + /** + * {@inheritdoc} + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + throw new \BadMethodCallException('Number is immutable'); + } + + /** + * {@inheritdoc} + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new \BadMethodCallException('Number is immutable'); + } + + /** + * Returns true if the number is unitless + * + * @return boolean + */ + public function unitless() + { + return \count($this->numeratorUnits) === 0 && \count($this->denominatorUnits) === 0; + } + + /** + * Checks whether the number has exactly this unit + * + * @param string $unit + * + * @return bool + */ + public function hasUnit($unit) + { + return \count($this->numeratorUnits) === 1 && \count($this->denominatorUnits) === 0 && $this->numeratorUnits[0] === $unit; + } + + /** + * Returns unit(s) as the product of numerator units divided by the product of denominator units + * + * @return string + */ + public function unitStr() + { + if ($this->unitless()) { + return ''; + } + + return self::getUnitString($this->numeratorUnits, $this->denominatorUnits); + } + + /** + * @param float|int $min + * @param float|int $max + * @param string|null $name + * + * @return float|int + * @throws SassScriptException + */ + public function valueInRange($min, $max, $name = null) + { + try { + return Util::checkRange('', new Range($min, $max), $this); + } catch (RangeException $e) { + throw SassScriptException::forArgument(sprintf('Expected %s to be within %s%s and %s%3$s', $this, $min, $this->unitStr(), $max), $name); + } + } + + /** + * @param string|null $varName + * + * @return void + */ + public function assertNoUnits($varName = null) + { + if ($this->unitless()) { + return; + } + + throw SassScriptException::forArgument(sprintf('Expected %s to have no units.', $this), $varName); + } + + /** + * @param string $unit + * @param string|null $varName + * + * @return void + */ + public function assertUnit($unit, $varName = null) + { + if ($this->hasUnit($unit)) { + return; + } + + throw SassScriptException::forArgument(sprintf('Expected %s to have unit "%s".', $this, $unit), $varName); + } + + /** + * @param Number $other + * + * @return void + */ + public function assertSameUnitOrUnitless(Number $other) + { + if ($other->unitless()) { + return; + } + + if ($this->numeratorUnits === $other->numeratorUnits && $this->denominatorUnits === $other->denominatorUnits) { + return; + } + + throw new SassScriptException(sprintf( + 'Incompatible units %s and %s.', + self::getUnitString($this->numeratorUnits, $this->denominatorUnits), + self::getUnitString($other->numeratorUnits, $other->denominatorUnits) + )); + } + + /** + * Returns a copy of this number, converted to the units represented by $newNumeratorUnits and $newDenominatorUnits. + * + * This does not throw an error if this number is unitless and + * $newNumeratorUnits/$newDenominatorUnits are not empty, or vice versa. Instead, + * it treats all unitless numbers as convertible to and from all units without + * changing the value. + * + * @param string[] $newNumeratorUnits + * @param string[] $newDenominatorUnits + * + * @return Number + * + * @phpstan-param list $newNumeratorUnits + * @phpstan-param list $newDenominatorUnits + * + * @throws SassScriptException if this number's units are not compatible with $newNumeratorUnits and $newDenominatorUnits + */ + public function coerce(array $newNumeratorUnits, array $newDenominatorUnits) + { + return new Number($this->valueInUnits($newNumeratorUnits, $newDenominatorUnits), $newNumeratorUnits, $newDenominatorUnits); + } + + /** + * @param Number $other + * + * @return bool + */ + public function isComparableTo(Number $other) + { + if ($this->unitless() || $other->unitless()) { + return true; + } + + try { + $this->greaterThan($other); + return true; + } catch (SassScriptException $e) { + return false; + } + } + + /** + * @param Number $other + * + * @return bool + */ + public function lessThan(Number $other) + { + return $this->coerceUnits($other, function ($num1, $num2) { + return $num1 < $num2; + }); + } + + /** + * @param Number $other + * + * @return bool + */ + public function lessThanOrEqual(Number $other) + { + return $this->coerceUnits($other, function ($num1, $num2) { + return $num1 <= $num2; + }); + } + + /** + * @param Number $other + * + * @return bool + */ + public function greaterThan(Number $other) + { + return $this->coerceUnits($other, function ($num1, $num2) { + return $num1 > $num2; + }); + } + + /** + * @param Number $other + * + * @return bool + */ + public function greaterThanOrEqual(Number $other) + { + return $this->coerceUnits($other, function ($num1, $num2) { + return $num1 >= $num2; + }); + } + + /** + * @param Number $other + * + * @return Number + */ + public function plus(Number $other) + { + return $this->coerceNumber($other, function ($num1, $num2) { + return $num1 + $num2; + }); + } + + /** + * @param Number $other + * + * @return Number + */ + public function minus(Number $other) + { + return $this->coerceNumber($other, function ($num1, $num2) { + return $num1 - $num2; + }); + } + + /** + * @return Number + */ + public function unaryMinus() + { + return new Number(-$this->dimension, $this->numeratorUnits, $this->denominatorUnits); + } + + /** + * @param Number $other + * + * @return Number + */ + public function modulo(Number $other) + { + return $this->coerceNumber($other, function ($num1, $num2) { + if ($num2 == 0) { + return NAN; + } + + $result = fmod($num1, $num2); + + if ($result == 0) { + return 0; + } + + if ($num2 < 0 xor $num1 < 0) { + $result += $num2; + } + + return $result; + }); + } + + /** + * @param Number $other + * + * @return Number + */ + public function times(Number $other) + { + return $this->multiplyUnits($this->dimension * $other->dimension, $this->numeratorUnits, $this->denominatorUnits, $other->numeratorUnits, $other->denominatorUnits); + } + + /** + * @param Number $other + * + * @return Number + */ + public function dividedBy(Number $other) + { + if ($other->dimension == 0) { + if ($this->dimension == 0) { + $value = NAN; + } elseif ($this->dimension > 0) { + $value = INF; + } else { + $value = -INF; + } + } else { + $value = $this->dimension / $other->dimension; + } + + return $this->multiplyUnits($value, $this->numeratorUnits, $this->denominatorUnits, $other->denominatorUnits, $other->numeratorUnits); + } + + /** + * @param Number $other + * + * @return bool + */ + public function equals(Number $other) + { + // Unitless numbers are convertable to unit numbers, but not equal, so we special-case unitless here. + if ($this->unitless() !== $other->unitless()) { + return false; + } + + // In Sass, neither NaN nor Infinity are equal to themselves, while PHP defines INF==INF + if (is_nan($this->dimension) || is_nan($other->dimension) || !is_finite($this->dimension) || !is_finite($other->dimension)) { + return false; + } + + if ($this->unitless()) { + return round($this->dimension, self::PRECISION) == round($other->dimension, self::PRECISION); + } + + try { + return $this->coerceUnits($other, function ($num1, $num2) { + return round($num1,self::PRECISION) == round($num2, self::PRECISION); + }); + } catch (SassScriptException $e) { + return false; + } + } + + /** + * Output number + * + * @param \ScssPhp\ScssPhp\Compiler $compiler + * + * @return string + */ + public function output(Compiler $compiler = null) + { + $dimension = round($this->dimension, self::PRECISION); + + if (is_nan($dimension)) { + return 'NaN'; + } + + if ($dimension === INF) { + return 'Infinity'; + } + + if ($dimension === -INF) { + return '-Infinity'; + } + + if ($compiler) { + $unit = $this->unitStr(); + } elseif (isset($this->numeratorUnits[0])) { + $unit = $this->numeratorUnits[0]; + } else { + $unit = ''; + } + + $dimension = number_format($dimension, self::PRECISION, '.', ''); + + return rtrim(rtrim($dimension, '0'), '.') . $unit; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->output(); + } + + /** + * @param Number $other + * @param callable $operation + * + * @return Number + * + * @phpstan-param callable(int|float, int|float): (int|float) $operation + */ + private function coerceNumber(Number $other, $operation) + { + $result = $this->coerceUnits($other, $operation); + + if (!$this->unitless()) { + return new Number($result, $this->numeratorUnits, $this->denominatorUnits); + } + + return new Number($result, $other->numeratorUnits, $other->denominatorUnits); + } + + /** + * @param Number $other + * @param callable $operation + * + * @return mixed + * + * @phpstan-template T + * @phpstan-param callable(int|float, int|float): T $operation + * @phpstan-return T + */ + private function coerceUnits(Number $other, $operation) + { + if (!$this->unitless()) { + $num1 = $this->dimension; + $num2 = $other->valueInUnits($this->numeratorUnits, $this->denominatorUnits); + } else { + $num1 = $this->valueInUnits($other->numeratorUnits, $other->denominatorUnits); + $num2 = $other->dimension; + } + + return \call_user_func($operation, $num1, $num2); + } + + /** + * @param string[] $numeratorUnits + * @param string[] $denominatorUnits + * + * @return int|float + * + * @phpstan-param list $numeratorUnits + * @phpstan-param list $denominatorUnits + * + * @throws SassScriptException if this number's units are not compatible with $numeratorUnits and $denominatorUnits + */ + private function valueInUnits(array $numeratorUnits, array $denominatorUnits) + { + if ( + $this->unitless() + || (\count($numeratorUnits) === 0 && \count($denominatorUnits) === 0) + || ($this->numeratorUnits === $numeratorUnits && $this->denominatorUnits === $denominatorUnits) + ) { + return $this->dimension; + } + + $value = $this->dimension; + $oldNumerators = $this->numeratorUnits; + + foreach ($numeratorUnits as $newNumerator) { + foreach ($oldNumerators as $key => $oldNumerator) { + $conversionFactor = self::getConversionFactor($newNumerator, $oldNumerator); + + if (\is_null($conversionFactor)) { + continue; + } + + $value *= $conversionFactor; + unset($oldNumerators[$key]); + continue 2; + } + + throw new SassScriptException(sprintf( + 'Incompatible units %s and %s.', + self::getUnitString($this->numeratorUnits, $this->denominatorUnits), + self::getUnitString($numeratorUnits, $denominatorUnits) + )); + } + + $oldDenominators = $this->denominatorUnits; + + foreach ($denominatorUnits as $newDenominator) { + foreach ($oldDenominators as $key => $oldDenominator) { + $conversionFactor = self::getConversionFactor($newDenominator, $oldDenominator); + + if (\is_null($conversionFactor)) { + continue; + } + + $value /= $conversionFactor; + unset($oldDenominators[$key]); + continue 2; + } + + throw new SassScriptException(sprintf( + 'Incompatible units %s and %s.', + self::getUnitString($this->numeratorUnits, $this->denominatorUnits), + self::getUnitString($numeratorUnits, $denominatorUnits) + )); + } + + if (\count($oldNumerators) || \count($oldDenominators)) { + throw new SassScriptException(sprintf( + 'Incompatible units %s and %s.', + self::getUnitString($this->numeratorUnits, $this->denominatorUnits), + self::getUnitString($numeratorUnits, $denominatorUnits) + )); + } + + return $value; + } + + /** + * @param int|float $value + * @param string[] $numerators1 + * @param string[] $denominators1 + * @param string[] $numerators2 + * @param string[] $denominators2 + * + * @return Number + * + * @phpstan-param list $numerators1 + * @phpstan-param list $denominators1 + * @phpstan-param list $numerators2 + * @phpstan-param list $denominators2 + */ + private function multiplyUnits($value, array $numerators1, array $denominators1, array $numerators2, array $denominators2) + { + $newNumerators = array(); + + foreach ($numerators1 as $numerator) { + foreach ($denominators2 as $key => $denominator) { + $conversionFactor = self::getConversionFactor($numerator, $denominator); + + if (\is_null($conversionFactor)) { + continue; + } + + $value /= $conversionFactor; + unset($denominators2[$key]); + continue 2; + } + + $newNumerators[] = $numerator; + } + + foreach ($numerators2 as $numerator) { + foreach ($denominators1 as $key => $denominator) { + $conversionFactor = self::getConversionFactor($numerator, $denominator); + + if (\is_null($conversionFactor)) { + continue; + } + + $value /= $conversionFactor; + unset($denominators1[$key]); + continue 2; + } + + $newNumerators[] = $numerator; + } + + $newDenominators = array_values(array_merge($denominators1, $denominators2)); + + return new Number($value, $newNumerators, $newDenominators); + } + + /** + * Returns the number of [unit1]s per [unit2]. + * + * Equivalently, `1unit1 * conversionFactor(unit1, unit2) = 1unit2`. + * + * @param string $unit1 + * @param string $unit2 + * + * @return float|int|null + */ + private static function getConversionFactor($unit1, $unit2) + { + if ($unit1 === $unit2) { + return 1; + } + + foreach (static::$unitTable as $unitVariants) { + if (isset($unitVariants[$unit1]) && isset($unitVariants[$unit2])) { + return $unitVariants[$unit1] / $unitVariants[$unit2]; + } + } + + return null; + } + + /** + * Returns unit(s) as the product of numerator units divided by the product of denominator units + * + * @param string[] $numerators + * @param string[] $denominators + * + * @phpstan-param list $numerators + * @phpstan-param list $denominators + * + * @return string + */ + private static function getUnitString(array $numerators, array $denominators) + { + if (!\count($numerators)) { + if (\count($denominators) === 0) { + return 'no units'; + } + + if (\count($denominators) === 1) { + return $denominators[0] . '^-1'; + } + + return '(' . implode('*', $denominators) . ')^-1'; + } + + return implode('*', $numerators) . (\count($denominators) ? '/' . implode('*', $denominators) : ''); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php b/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php new file mode 100644 index 0000000..c284639 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php @@ -0,0 +1,9 @@ + + * + * @internal + */ +class Parser +{ + const SOURCE_INDEX = -1; + const SOURCE_LINE = -2; + const SOURCE_COLUMN = -3; + + /** + * @var array + */ + protected static $precedence = [ + '=' => 0, + 'or' => 1, + 'and' => 2, + '==' => 3, + '!=' => 3, + '<=' => 4, + '>=' => 4, + '<' => 4, + '>' => 4, + '+' => 5, + '-' => 5, + '*' => 6, + '/' => 6, + '%' => 6, + ]; + + /** + * @var string + */ + protected static $commentPattern; + /** + * @var string + */ + protected static $operatorPattern; + /** + * @var string + */ + protected static $whitePattern; + + /** + * @var Cache|null + */ + protected $cache; + + private $sourceName; + private $sourceIndex; + /** + * @var array + */ + private $sourcePositions; + /** + * @var array|null + */ + private $charset; + /** + * The current offset in the buffer + * + * @var int + */ + private $count; + /** + * @var Block|null + */ + private $env; + /** + * @var bool + */ + private $inParens; + /** + * @var bool + */ + private $eatWhiteDefault; + /** + * @var bool + */ + private $discardComments; + private $allowVars; + /** + * @var string + */ + private $buffer; + private $utf8; + /** + * @var string|null + */ + private $encoding; + private $patternModifiers; + private $commentsSeen; + + private $cssOnly; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * Constructor + * + * @api + * + * @param string|null $sourceName + * @param integer $sourceIndex + * @param string|null $encoding + * @param Cache|null $cache + * @param bool $cssOnly + * @param LoggerInterface|null $logger + */ + public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8', Cache $cache = null, $cssOnly = false, LoggerInterface $logger = null) + { + $this->sourceName = $sourceName ?: '(stdin)'; + $this->sourceIndex = $sourceIndex; + $this->charset = null; + $this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8'; + $this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais'; + $this->commentsSeen = []; + $this->commentsSeen = []; + $this->allowVars = true; + $this->cssOnly = $cssOnly; + $this->logger = $logger ?: new QuietLogger(); + + if (empty(static::$operatorPattern)) { + static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=?|and|or)'; + + $commentSingle = '\/\/'; + $commentMultiLeft = '\/\*'; + $commentMultiRight = '\*\/'; + + static::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight; + static::$whitePattern = $this->utf8 + ? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS' + : '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS'; + } + + $this->cache = $cache; + } + + /** + * Get source file name + * + * @api + * + * @return string + */ + public function getSourceName() + { + return $this->sourceName; + } + + /** + * Throw parser error + * + * @api + * + * @param string $msg + * + * @phpstan-return never-return + * + * @throws ParserException + * + * @deprecated use "parseError" and throw the exception in the caller instead. + */ + public function throwParseError($msg = 'parse error') + { + @trigger_error( + 'The method "throwParseError" is deprecated. Use "parseError" and throw the exception in the caller instead', + E_USER_DEPRECATED + ); + + throw $this->parseError($msg); + } + + /** + * Creates a parser error + * + * @api + * + * @param string $msg + * + * @return ParserException + */ + public function parseError($msg = 'parse error') + { + list($line, $column) = $this->getSourcePosition($this->count); + + $loc = empty($this->sourceName) + ? "line: $line, column: $column" + : "$this->sourceName on line $line, at column $column"; + + if ($this->peek('(.*?)(\n|$)', $m, $this->count)) { + $this->restoreEncoding(); + + $e = new ParserException("$msg: failed at `$m[1]` $loc"); + $e->setSourcePosition([$this->sourceName, $line, $column]); + + return $e; + } + + $this->restoreEncoding(); + + $e = new ParserException("$msg: $loc"); + $e->setSourcePosition([$this->sourceName, $line, $column]); + + return $e; + } + + /** + * Parser buffer + * + * @api + * + * @param string $buffer + * + * @return Block + */ + public function parse($buffer) + { + if ($this->cache) { + $cacheKey = $this->sourceName . ':' . md5($buffer); + $parseOptions = [ + 'charset' => $this->charset, + 'utf8' => $this->utf8, + ]; + $v = $this->cache->getCache('parse', $cacheKey, $parseOptions); + + if (! \is_null($v)) { + return $v; + } + } + + // strip BOM (byte order marker) + if (substr($buffer, 0, 3) === "\xef\xbb\xbf") { + $buffer = substr($buffer, 3); + } + + $this->buffer = rtrim($buffer, "\x00..\x1f"); + $this->count = 0; + $this->env = null; + $this->inParens = false; + $this->eatWhiteDefault = true; + + $this->saveEncoding(); + $this->extractLineNumbers($buffer); + + $this->pushBlock(null); // root block + $this->whitespace(); + $this->pushBlock(null); + $this->popBlock(); + + while ($this->parseChunk()) { + ; + } + + if ($this->count !== \strlen($this->buffer)) { + throw $this->parseError(); + } + + if (! empty($this->env->parent)) { + throw $this->parseError('unclosed block'); + } + + if ($this->charset) { + array_unshift($this->env->children, $this->charset); + } + + $this->restoreEncoding(); + + if ($this->cache) { + $this->cache->setCache('parse', $cacheKey, $this->env, $parseOptions); + } + + return $this->env; + } + + /** + * Parse a value or value list + * + * @api + * + * @param string $buffer + * @param string|array $out + * + * @return boolean + */ + public function parseValue($buffer, &$out) + { + $this->count = 0; + $this->env = null; + $this->inParens = false; + $this->eatWhiteDefault = true; + $this->buffer = (string) $buffer; + + $this->saveEncoding(); + $this->extractLineNumbers($this->buffer); + + $list = $this->valueList($out); + + $this->restoreEncoding(); + + return $list; + } + + /** + * Parse a selector or selector list + * + * @api + * + * @param string $buffer + * @param string|array $out + * @param bool $shouldValidate + * + * @return boolean + */ + public function parseSelector($buffer, &$out, $shouldValidate = true) + { + $this->count = 0; + $this->env = null; + $this->inParens = false; + $this->eatWhiteDefault = true; + $this->buffer = (string) $buffer; + + $this->saveEncoding(); + $this->extractLineNumbers($this->buffer); + + // discard space/comments at the start + $this->discardComments = true; + $this->whitespace(); + $this->discardComments = false; + + $selector = $this->selectors($out); + + $this->restoreEncoding(); + + if ($shouldValidate && $this->count !== strlen($buffer)) { + throw $this->parseError("`" . substr($buffer, $this->count) . "` is not a valid Selector in `$buffer`"); + } + + return $selector; + } + + /** + * Parse a media Query + * + * @api + * + * @param string $buffer + * @param string|array $out + * + * @return boolean + */ + public function parseMediaQueryList($buffer, &$out) + { + $this->count = 0; + $this->env = null; + $this->inParens = false; + $this->eatWhiteDefault = true; + $this->buffer = (string) $buffer; + + $this->saveEncoding(); + $this->extractLineNumbers($this->buffer); + + $isMediaQuery = $this->mediaQueryList($out); + + $this->restoreEncoding(); + + return $isMediaQuery; + } + + /** + * Parse a single chunk off the head of the buffer and append it to the + * current parse environment. + * + * Returns false when the buffer is empty, or when there is an error. + * + * This function is called repeatedly until the entire document is + * parsed. + * + * This parser is most similar to a recursive descent parser. Single + * functions represent discrete grammatical rules for the language, and + * they are able to capture the text that represents those rules. + * + * Consider the function Compiler::keyword(). (All parse functions are + * structured the same.) + * + * The function takes a single reference argument. When calling the + * function it will attempt to match a keyword on the head of the buffer. + * If it is successful, it will place the keyword in the referenced + * argument, advance the position in the buffer, and return true. If it + * fails then it won't advance the buffer and it will return false. + * + * All of these parse functions are powered by Compiler::match(), which behaves + * the same way, but takes a literal regular expression. Sometimes it is + * more convenient to use match instead of creating a new function. + * + * Because of the format of the functions, to parse an entire string of + * grammatical rules, you can chain them together using &&. + * + * But, if some of the rules in the chain succeed before one fails, then + * the buffer position will be left at an invalid state. In order to + * avoid this, Compiler::seek() is used to remember and set buffer positions. + * + * Before parsing a chain, use $s = $this->count to remember the current + * position into $s. Then if a chain fails, use $this->seek($s) to + * go back where we started. + * + * @return boolean + */ + protected function parseChunk() + { + $s = $this->count; + + // the directives + if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] === '@') { + if ( + $this->literal('@at-root', 8) && + ($this->selectors($selector) || true) && + ($this->map($with) || true) && + (($this->matchChar('(') && + $this->interpolation($with) && + $this->matchChar(')')) || true) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $atRoot = $this->pushSpecialBlock(Type::T_AT_ROOT, $s); + $atRoot->selector = $selector; + $atRoot->with = $with; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@media', 6) && + $this->mediaQueryList($mediaQueryList) && + $this->matchChar('{', false) + ) { + $media = $this->pushSpecialBlock(Type::T_MEDIA, $s); + $media->queryList = $mediaQueryList[2]; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@mixin', 6) && + $this->keyword($mixinName) && + ($this->argumentDef($args) || true) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $mixin = $this->pushSpecialBlock(Type::T_MIXIN, $s); + $mixin->name = $mixinName; + $mixin->args = $args; + + return true; + } + + $this->seek($s); + + if ( + ($this->literal('@include', 8) && + $this->keyword($mixinName) && + ($this->matchChar('(') && + ($this->argValues($argValues) || true) && + $this->matchChar(')') || true) && + ($this->end()) || + ($this->literal('using', 5) && + $this->argumentDef($argUsing) && + ($this->end() || $this->matchChar('{') && $hasBlock = true)) || + $this->matchChar('{') && $hasBlock = true) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $child = [ + Type::T_INCLUDE, + $mixinName, + isset($argValues) ? $argValues : null, + null, + isset($argUsing) ? $argUsing : null + ]; + + if (! empty($hasBlock)) { + $include = $this->pushSpecialBlock(Type::T_INCLUDE, $s); + $include->child = $child; + } else { + $this->append($child, $s); + } + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@scssphp-import-once', 20) && + $this->valueList($importPath) && + $this->end() + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + list($line, $column) = $this->getSourcePosition($s); + $file = $this->sourceName; + $this->logger->warn("The \"@scssphp-import-once\" directive is deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); + + $this->append([Type::T_SCSSPHP_IMPORT_ONCE, $importPath], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@import', 7) && + $this->valueList($importPath) && + $importPath[0] !== Type::T_FUNCTION_CALL && + $this->end() + ) { + if ($this->cssOnly) { + $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s); + $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]); + return true; + } + + $this->append([Type::T_IMPORT, $importPath], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@import', 7) && + $this->url($importPath) && + $this->end() + ) { + if ($this->cssOnly) { + $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s); + $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]); + return true; + } + + $this->append([Type::T_IMPORT, $importPath], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@extend', 7) && + $this->selectors($selectors) && + $this->end() + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + // check for '!flag' + $optional = $this->stripOptionalFlag($selectors); + $this->append([Type::T_EXTEND, $selectors, $optional], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@function', 9) && + $this->keyword($fnName) && + $this->argumentDef($args) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $func = $this->pushSpecialBlock(Type::T_FUNCTION, $s); + $func->name = $fnName; + $func->args = $args; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@return', 7) && + ($this->valueList($retVal) || true) && + $this->end() + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $this->append([Type::T_RETURN, isset($retVal) ? $retVal : [Type::T_NULL]], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@each', 5) && + $this->genericList($varNames, 'variable', ',', false) && + $this->literal('in', 2) && + $this->valueList($list) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $each = $this->pushSpecialBlock(Type::T_EACH, $s); + + foreach ($varNames[2] as $varName) { + $each->vars[] = $varName[1]; + } + + $each->list = $list; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@while', 6) && + $this->expression($cond) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + while ( + $cond[0] === Type::T_LIST && + ! empty($cond['enclosing']) && + $cond['enclosing'] === 'parent' && + \count($cond[2]) == 1 + ) { + $cond = reset($cond[2]); + } + + $while = $this->pushSpecialBlock(Type::T_WHILE, $s); + $while->cond = $cond; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@for', 4) && + $this->variable($varName) && + $this->literal('from', 4) && + $this->expression($start) && + ($this->literal('through', 7) || + ($forUntil = true && $this->literal('to', 2))) && + $this->expression($end) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $for = $this->pushSpecialBlock(Type::T_FOR, $s); + $for->var = $varName[1]; + $for->start = $start; + $for->end = $end; + $for->until = isset($forUntil); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@if', 3) && + $this->functionCallArgumentsList($cond, false, '{', false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $if = $this->pushSpecialBlock(Type::T_IF, $s); + + while ( + $cond[0] === Type::T_LIST && + ! empty($cond['enclosing']) && + $cond['enclosing'] === 'parent' && + \count($cond[2]) == 1 + ) { + $cond = reset($cond[2]); + } + + $if->cond = $cond; + $if->cases = []; + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@debug', 6) && + $this->functionCallArgumentsList($value, false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $this->append([Type::T_DEBUG, $value], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@warn', 5) && + $this->functionCallArgumentsList($value, false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $this->append([Type::T_WARN, $value], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@error', 6) && + $this->functionCallArgumentsList($value, false) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $this->append([Type::T_ERROR, $value], $s); + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@content', 8) && + ($this->end() || + $this->matchChar('(') && + $this->argValues($argContent) && + $this->matchChar(')') && + $this->end()) + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + $this->append([Type::T_MIXIN_CONTENT, isset($argContent) ? $argContent : null], $s); + + return true; + } + + $this->seek($s); + + $last = $this->last(); + + if (isset($last) && $last[0] === Type::T_IF) { + list(, $if) = $last; + + if ($this->literal('@else', 5)) { + if ($this->matchChar('{', false)) { + $else = $this->pushSpecialBlock(Type::T_ELSE, $s); + } elseif ( + $this->literal('if', 2) && + $this->functionCallArgumentsList($cond, false, '{', false) + ) { + $else = $this->pushSpecialBlock(Type::T_ELSEIF, $s); + $else->cond = $cond; + } + + if (isset($else)) { + $else->dontAppend = true; + $if->cases[] = $else; + + return true; + } + } + + $this->seek($s); + } + + // only retain the first @charset directive encountered + if ( + $this->literal('@charset', 8) && + $this->valueList($charset) && + $this->end() + ) { + if (! isset($this->charset)) { + $statement = [Type::T_CHARSET, $charset]; + + list($line, $column) = $this->getSourcePosition($s); + + $statement[static::SOURCE_LINE] = $line; + $statement[static::SOURCE_COLUMN] = $column; + $statement[static::SOURCE_INDEX] = $this->sourceIndex; + + $this->charset = $statement; + } + + return true; + } + + $this->seek($s); + + if ( + $this->literal('@supports', 9) && + ($t1 = $this->supportsQuery($supportQuery)) && + ($t2 = $this->matchChar('{', false)) + ) { + $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s); + $directive->name = 'supports'; + $directive->value = $supportQuery; + + return true; + } + + $this->seek($s); + + // doesn't match built in directive, do generic one + if ( + $this->matchChar('@', false) && + $this->mixedKeyword($dirName) && + $this->directiveValue($dirValue, '{') + ) { + if (count($dirName) === 1 && is_string(reset($dirName))) { + $dirName = reset($dirName); + } else { + $dirName = [Type::T_STRING, '', $dirName]; + } + if ($dirName === 'media') { + $directive = $this->pushSpecialBlock(Type::T_MEDIA, $s); + } else { + $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s); + $directive->name = $dirName; + } + + if (isset($dirValue)) { + ! $this->cssOnly || ($dirValue = $this->assertPlainCssValid($dirValue)); + $directive->value = $dirValue; + } + + return true; + } + + $this->seek($s); + + // maybe it's a generic blockless directive + if ( + $this->matchChar('@', false) && + $this->mixedKeyword($dirName) && + ! $this->isKnownGenericDirective($dirName) && + ($this->end(false) || ($this->directiveValue($dirValue, '') && $this->end(false))) + ) { + if (\count($dirName) === 1 && \is_string(\reset($dirName))) { + $dirName = \reset($dirName); + } else { + $dirName = [Type::T_STRING, '', $dirName]; + } + if ( + ! empty($this->env->parent) && + $this->env->type && + ! \in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA]) + ) { + $plain = \trim(\substr($this->buffer, $s, $this->count - $s)); + throw $this->parseError( + "Unknown directive `{$plain}` not allowed in `" . $this->env->type . "` block" + ); + } + // blockless directives with a blank line after keeps their blank lines after + // sass-spec compliance purpose + $s = $this->count; + $hasBlankLine = false; + if ($this->match('\s*?\n\s*\n', $out, false)) { + $hasBlankLine = true; + $this->seek($s); + } + $isNotRoot = ! empty($this->env->parent); + $this->append([Type::T_DIRECTIVE, [$dirName, $dirValue, $hasBlankLine, $isNotRoot]], $s); + $this->whitespace(); + + return true; + } + + $this->seek($s); + + return false; + } + + $inCssSelector = null; + if ($this->cssOnly) { + $inCssSelector = (! empty($this->env->parent) && + ! in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA])); + } + // custom properties : right part is static + if (($this->customProperty($name) ) && $this->matchChar(':', false)) { + $start = $this->count; + + // but can be complex and finish with ; or } + foreach ([';','}'] as $ending) { + if ( + $this->openString($ending, $stringValue, '(', ')', false) && + $this->end() + ) { + $end = $this->count; + $value = $stringValue; + + // check if we have only a partial value due to nested [] or { } to take in account + $nestingPairs = [['[', ']'], ['{', '}']]; + + foreach ($nestingPairs as $nestingPair) { + $p = strpos($this->buffer, $nestingPair[0], $start); + + if ($p && $p < $end) { + $this->seek($start); + + if ( + $this->openString($ending, $stringValue, $nestingPair[0], $nestingPair[1], false) && + $this->end() && + $this->count > $end + ) { + $end = $this->count; + $value = $stringValue; + } + } + } + + $this->seek($end); + $this->append([Type::T_CUSTOM_PROPERTY, $name, $value], $s); + + return true; + } + } + + // TODO: output an error here if nothing found according to sass spec + } + + $this->seek($s); + + // property shortcut + // captures most properties before having to parse a selector + if ( + $this->keyword($name, false) && + $this->literal(': ', 2) && + $this->valueList($value) && + $this->end() + ) { + $name = [Type::T_STRING, '', [$name]]; + $this->append([Type::T_ASSIGN, $name, $value], $s); + + return true; + } + + $this->seek($s); + + // variable assigns + if ( + $this->variable($name) && + $this->matchChar(':') && + $this->valueList($value) && + $this->end() + ) { + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + + // check for '!flag' + $assignmentFlags = $this->stripAssignmentFlags($value); + $this->append([Type::T_ASSIGN, $name, $value, $assignmentFlags], $s); + + return true; + } + + $this->seek($s); + + // opening css block + if ( + $this->selectors($selectors) && + $this->matchChar('{', false) + ) { + ! $this->cssOnly || ! $inCssSelector || $this->assertPlainCssValid(false); + + $this->pushBlock($selectors, $s); + + if ($this->eatWhiteDefault) { + $this->whitespace(); + $this->append(null); // collect comments at the beginning if needed + } + + return true; + } + + $this->seek($s); + + // property assign, or nested assign + if ( + $this->propertyName($name) && + $this->matchChar(':') + ) { + $foundSomething = false; + + if ($this->valueList($value)) { + if (empty($this->env->parent)) { + throw $this->parseError('expected "{"'); + } + + $this->append([Type::T_ASSIGN, $name, $value], $s); + $foundSomething = true; + } + + if ($this->matchChar('{', false)) { + ! $this->cssOnly || $this->assertPlainCssValid(false); + + $propBlock = $this->pushSpecialBlock(Type::T_NESTED_PROPERTY, $s); + $propBlock->prefix = $name; + $propBlock->hasValue = $foundSomething; + + $foundSomething = true; + } elseif ($foundSomething) { + $foundSomething = $this->end(); + } + + if ($foundSomething) { + return true; + } + } + + $this->seek($s); + + // closing a block + if ($this->matchChar('}', false)) { + $block = $this->popBlock(); + + if (! isset($block->type) || $block->type !== Type::T_IF) { + if ($this->env->parent) { + $this->append(null); // collect comments before next statement if needed + } + } + + if (isset($block->type) && $block->type === Type::T_INCLUDE) { + $include = $block->child; + unset($block->child); + $include[3] = $block; + $this->append($include, $s); + } elseif (empty($block->dontAppend)) { + $type = isset($block->type) ? $block->type : Type::T_BLOCK; + $this->append([$type, $block], $s); + } + + // collect comments just after the block closing if needed + if ($this->eatWhiteDefault) { + $this->whitespace(); + + if ($this->env->comments) { + $this->append(null); + } + } + + return true; + } + + // extra stuff + if ($this->matchChar(';')) { + return true; + } + + return false; + } + + /** + * Push block onto parse tree + * + * @param array|null $selectors + * @param integer $pos + * + * @return Block + */ + protected function pushBlock($selectors, $pos = 0) + { + list($line, $column) = $this->getSourcePosition($pos); + + $b = new Block(); + $b->sourceName = $this->sourceName; + $b->sourceLine = $line; + $b->sourceColumn = $column; + $b->sourceIndex = $this->sourceIndex; + $b->selectors = $selectors; + $b->comments = []; + $b->parent = $this->env; + + if (! $this->env) { + $b->children = []; + } elseif (empty($this->env->children)) { + $this->env->children = $this->env->comments; + $b->children = []; + $this->env->comments = []; + } else { + $b->children = $this->env->comments; + $this->env->comments = []; + } + + $this->env = $b; + + // collect comments at the beginning of a block if needed + if ($this->eatWhiteDefault) { + $this->whitespace(); + + if ($this->env->comments) { + $this->append(null); + } + } + + return $b; + } + + /** + * Push special (named) block onto parse tree + * + * @param string $type + * @param integer $pos + * + * @return Block + */ + protected function pushSpecialBlock($type, $pos) + { + $block = $this->pushBlock(null, $pos); + $block->type = $type; + + return $block; + } + + /** + * Pop scope and return last block + * + * @return Block + * + * @throws \Exception + */ + protected function popBlock() + { + + // collect comments ending just before of a block closing + if ($this->env->comments) { + $this->append(null); + } + + // pop the block + $block = $this->env; + + if (empty($block->parent)) { + throw $this->parseError('unexpected }'); + } + + if ($block->type == Type::T_AT_ROOT) { + // keeps the parent in case of self selector & + $block->selfParent = $block->parent; + } + + $this->env = $block->parent; + + unset($block->parent); + + return $block; + } + + /** + * Peek input stream + * + * @param string $regex + * @param array $out + * @param integer $from + * + * @return integer + */ + protected function peek($regex, &$out, $from = null) + { + if (! isset($from)) { + $from = $this->count; + } + + $r = '/' . $regex . '/' . $this->patternModifiers; + $result = preg_match($r, $this->buffer, $out, 0, $from); + + return $result; + } + + /** + * Seek to position in input stream (or return current position in input stream) + * + * @param integer $where + */ + protected function seek($where) + { + $this->count = $where; + } + + /** + * Assert a parsed part is plain CSS Valid + * + * @param array|false $parsed + * @param int $startPos + * @throws ParserException + */ + protected function assertPlainCssValid($parsed, $startPos = null) + { + $type = ''; + if ($parsed) { + $type = $parsed[0]; + $parsed = $this->isPlainCssValidElement($parsed); + } + if (! $parsed) { + if (! \is_null($startPos)) { + $plain = rtrim(substr($this->buffer, $startPos, $this->count - $startPos)); + $message = "Error : `{$plain}` isn't allowed in plain CSS"; + } else { + $message = 'Error: SCSS syntax not allowed in CSS file'; + } + if ($type) { + $message .= " ($type)"; + } + throw $this->parseError($message); + } + + return $parsed; + } + + /** + * Check a parsed element is plain CSS Valid + * @param array $parsed + * @return bool|array + */ + protected function isPlainCssValidElement($parsed, $allowExpression = false) + { + // keep string as is + if (is_string($parsed)) { + return $parsed; + } + + if ( + \in_array($parsed[0], [Type::T_FUNCTION, Type::T_FUNCTION_CALL]) && + !\in_array($parsed[1], [ + 'alpha', + 'attr', + 'calc', + 'cubic-bezier', + 'env', + 'grayscale', + 'hsl', + 'hsla', + 'hwb', + 'invert', + 'linear-gradient', + 'min', + 'max', + 'radial-gradient', + 'repeating-linear-gradient', + 'repeating-radial-gradient', + 'rgb', + 'rgba', + 'rotate', + 'saturate', + 'var', + ]) && + Compiler::isNativeFunction($parsed[1]) + ) { + return false; + } + + switch ($parsed[0]) { + case Type::T_BLOCK: + case Type::T_KEYWORD: + case Type::T_NULL: + case Type::T_NUMBER: + case Type::T_MEDIA: + return $parsed; + + case Type::T_COMMENT: + if (isset($parsed[2])) { + return false; + } + return $parsed; + + case Type::T_DIRECTIVE: + if (\is_array($parsed[1])) { + $parsed[1][1] = $this->isPlainCssValidElement($parsed[1][1]); + if (! $parsed[1][1]) { + return false; + } + } + + return $parsed; + + case Type::T_IMPORT: + if ($parsed[1][0] === Type::T_LIST) { + return false; + } + $parsed[1] = $this->isPlainCssValidElement($parsed[1]); + if ($parsed[1] === false) { + return false; + } + return $parsed; + + case Type::T_STRING: + foreach ($parsed[2] as $k => $substr) { + if (\is_array($substr)) { + $parsed[2][$k] = $this->isPlainCssValidElement($substr); + if (! $parsed[2][$k]) { + return false; + } + } + } + return $parsed; + + case Type::T_LIST: + if (!empty($parsed['enclosing'])) { + return false; + } + foreach ($parsed[2] as $k => $listElement) { + $parsed[2][$k] = $this->isPlainCssValidElement($listElement); + if (! $parsed[2][$k]) { + return false; + } + } + return $parsed; + + case Type::T_ASSIGN: + foreach ([1, 2, 3] as $k) { + if (! empty($parsed[$k])) { + $parsed[$k] = $this->isPlainCssValidElement($parsed[$k]); + if (! $parsed[$k]) { + return false; + } + } + } + return $parsed; + + case Type::T_EXPRESSION: + list( ,$op, $lhs, $rhs, $inParens, $whiteBefore, $whiteAfter) = $parsed; + if (! $allowExpression && ! \in_array($op, ['and', 'or', '/'])) { + return false; + } + $lhs = $this->isPlainCssValidElement($lhs, true); + if (! $lhs) { + return false; + } + $rhs = $this->isPlainCssValidElement($rhs, true); + if (! $rhs) { + return false; + } + + return [ + Type::T_STRING, + '', [ + $this->inParens ? '(' : '', + $lhs, + ($whiteBefore ? ' ' : '') . $op . ($whiteAfter ? ' ' : ''), + $rhs, + $this->inParens ? ')' : '' + ] + ]; + + case Type::T_CUSTOM_PROPERTY: + case Type::T_UNARY: + $parsed[2] = $this->isPlainCssValidElement($parsed[2]); + if (! $parsed[2]) { + return false; + } + return $parsed; + + case Type::T_FUNCTION: + $argsList = $parsed[2]; + foreach ($argsList[2] as $argElement) { + if (! $this->isPlainCssValidElement($argElement)) { + return false; + } + } + return $parsed; + + case Type::T_FUNCTION_CALL: + $parsed[0] = Type::T_FUNCTION; + $argsList = [Type::T_LIST, ',', []]; + foreach ($parsed[2] as $arg) { + if ($arg[0] || ! empty($arg[2])) { + // no named arguments possible in a css function call + // nor ... argument + return false; + } + $arg = $this->isPlainCssValidElement($arg[1], $parsed[1] === 'calc'); + if (! $arg) { + return false; + } + $argsList[2][] = $arg; + } + $parsed[2] = $argsList; + return $parsed; + } + + return false; + } + + /** + * Match string looking for either ending delim, escape, or string interpolation + * + * {@internal This is a workaround for preg_match's 250K string match limit. }} + * + * @param array $m Matches (passed by reference) + * @param string $delim Delimiter + * + * @return boolean True if match; false otherwise + */ + protected function matchString(&$m, $delim) + { + $token = null; + + $end = \strlen($this->buffer); + + // look for either ending delim, escape, or string interpolation + foreach (['#{', '\\', "\r", $delim] as $lookahead) { + $pos = strpos($this->buffer, $lookahead, $this->count); + + if ($pos !== false && $pos < $end) { + $end = $pos; + $token = $lookahead; + } + } + + if (! isset($token)) { + return false; + } + + $match = substr($this->buffer, $this->count, $end - $this->count); + $m = [ + $match . $token, + $match, + $token + ]; + $this->count = $end + \strlen($token); + + return true; + } + + /** + * Try to match something on head of buffer + * + * @param string $regex + * @param array $out + * @param boolean $eatWhitespace + * + * @return boolean + */ + protected function match($regex, &$out, $eatWhitespace = null) + { + $r = '/' . $regex . '/' . $this->patternModifiers; + + if (! preg_match($r, $this->buffer, $out, 0, $this->count)) { + return false; + } + + $this->count += \strlen($out[0]); + + if (! isset($eatWhitespace)) { + $eatWhitespace = $this->eatWhiteDefault; + } + + if ($eatWhitespace) { + $this->whitespace(); + } + + return true; + } + + /** + * Match a single string + * + * @param string $char + * @param boolean $eatWhitespace + * + * @return boolean + */ + protected function matchChar($char, $eatWhitespace = null) + { + if (! isset($this->buffer[$this->count]) || $this->buffer[$this->count] !== $char) { + return false; + } + + $this->count++; + + if (! isset($eatWhitespace)) { + $eatWhitespace = $this->eatWhiteDefault; + } + + if ($eatWhitespace) { + $this->whitespace(); + } + + return true; + } + + /** + * Match literal string + * + * @param string $what + * @param integer $len + * @param boolean $eatWhitespace + * + * @return boolean + */ + protected function literal($what, $len, $eatWhitespace = null) + { + if (strcasecmp(substr($this->buffer, $this->count, $len), $what) !== 0) { + return false; + } + + $this->count += $len; + + if (! isset($eatWhitespace)) { + $eatWhitespace = $this->eatWhiteDefault; + } + + if ($eatWhitespace) { + $this->whitespace(); + } + + return true; + } + + /** + * Match some whitespace + * + * @return boolean + */ + protected function whitespace() + { + $gotWhite = false; + + while (preg_match(static::$whitePattern, $this->buffer, $m, 0, $this->count)) { + if (isset($m[1]) && empty($this->commentsSeen[$this->count])) { + // comment that are kept in the output CSS + $comment = []; + $startCommentCount = $this->count; + $endCommentCount = $this->count + \strlen($m[1]); + + // find interpolations in comment + $p = strpos($this->buffer, '#{', $this->count); + + while ($p !== false && $p < $endCommentCount) { + $c = substr($this->buffer, $this->count, $p - $this->count); + $comment[] = $c; + $this->count = $p; + $out = null; + + if ($this->interpolation($out)) { + // keep right spaces in the following string part + if ($out[3]) { + while ($this->buffer[$this->count - 1] !== '}') { + $this->count--; + } + + $out[3] = ''; + } + + $comment[] = [Type::T_COMMENT, substr($this->buffer, $p, $this->count - $p), $out]; + } else { + list($line, $column) = $this->getSourcePosition($this->count); + $file = $this->sourceName; + if (!$this->discardComments) { + $this->logger->warn("Unterminated interpolations in multiline comments are deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); + } + $comment[] = substr($this->buffer, $this->count, 2); + + $this->count += 2; + } + + $p = strpos($this->buffer, '#{', $this->count); + } + + // remaining part + $c = substr($this->buffer, $this->count, $endCommentCount - $this->count); + + if (! $comment) { + // single part static comment + $this->appendComment([Type::T_COMMENT, $c]); + } else { + $comment[] = $c; + $staticComment = substr($this->buffer, $startCommentCount, $endCommentCount - $startCommentCount); + $commentStatement = [Type::T_COMMENT, $staticComment, [Type::T_STRING, '', $comment]]; + + list($line, $column) = $this->getSourcePosition($startCommentCount); + $commentStatement[self::SOURCE_LINE] = $line; + $commentStatement[self::SOURCE_COLUMN] = $column; + $commentStatement[self::SOURCE_INDEX] = $this->sourceIndex; + + $this->appendComment($commentStatement); + } + + $this->commentsSeen[$startCommentCount] = true; + $this->count = $endCommentCount; + } else { + // comment that are ignored and not kept in the output css + $this->count += \strlen($m[0]); + // silent comments are not allowed in plain CSS files + ! $this->cssOnly + || ! \strlen(trim($m[0])) + || $this->assertPlainCssValid(false, $this->count - \strlen($m[0])); + } + + $gotWhite = true; + } + + return $gotWhite; + } + + /** + * Append comment to current block + * + * @param array $comment + */ + protected function appendComment($comment) + { + if (! $this->discardComments) { + $this->env->comments[] = $comment; + } + } + + /** + * Append statement to current block + * + * @param array|null $statement + * @param integer $pos + */ + protected function append($statement, $pos = null) + { + if (! \is_null($statement)) { + ! $this->cssOnly || ($statement = $this->assertPlainCssValid($statement, $pos)); + + if (! \is_null($pos)) { + list($line, $column) = $this->getSourcePosition($pos); + + $statement[static::SOURCE_LINE] = $line; + $statement[static::SOURCE_COLUMN] = $column; + $statement[static::SOURCE_INDEX] = $this->sourceIndex; + } + + $this->env->children[] = $statement; + } + + $comments = $this->env->comments; + + if ($comments) { + $this->env->children = array_merge($this->env->children, $comments); + $this->env->comments = []; + } + } + + /** + * Returns last child was appended + * + * @return array|null + */ + protected function last() + { + $i = \count($this->env->children) - 1; + + if (isset($this->env->children[$i])) { + return $this->env->children[$i]; + } + } + + /** + * Parse media query list + * + * @param array $out + * + * @return boolean + */ + protected function mediaQueryList(&$out) + { + return $this->genericList($out, 'mediaQuery', ',', false); + } + + /** + * Parse media query + * + * @param array $out + * + * @return boolean + */ + protected function mediaQuery(&$out) + { + $expressions = null; + $parts = []; + + if ( + ($this->literal('only', 4) && ($only = true) || + $this->literal('not', 3) && ($not = true) || true) && + $this->mixedKeyword($mediaType) + ) { + $prop = [Type::T_MEDIA_TYPE]; + + if (isset($only)) { + $prop[] = [Type::T_KEYWORD, 'only']; + } + + if (isset($not)) { + $prop[] = [Type::T_KEYWORD, 'not']; + } + + $media = [Type::T_LIST, '', []]; + + foreach ((array) $mediaType as $type) { + if (\is_array($type)) { + $media[2][] = $type; + } else { + $media[2][] = [Type::T_KEYWORD, $type]; + } + } + + $prop[] = $media; + $parts[] = $prop; + } + + if (empty($parts) || $this->literal('and', 3)) { + $this->genericList($expressions, 'mediaExpression', 'and', false); + + if (\is_array($expressions)) { + $parts = array_merge($parts, $expressions[2]); + } + } + + $out = $parts; + + return true; + } + + /** + * Parse supports query + * + * @param array $out + * + * @return boolean + */ + protected function supportsQuery(&$out) + { + $expressions = null; + $parts = []; + + $s = $this->count; + + $not = false; + + if ( + ($this->literal('not', 3) && ($not = true) || true) && + $this->matchChar('(') && + ($this->expression($property)) && + $this->literal(': ', 2) && + $this->valueList($value) && + $this->matchChar(')') + ) { + $support = [Type::T_STRING, '', [[Type::T_KEYWORD, ($not ? 'not ' : '') . '(']]]; + $support[2][] = $property; + $support[2][] = [Type::T_KEYWORD, ': ']; + $support[2][] = $value; + $support[2][] = [Type::T_KEYWORD, ')']; + + $parts[] = $support; + $s = $this->count; + } else { + $this->seek($s); + } + + if ( + $this->matchChar('(') && + $this->supportsQuery($subQuery) && + $this->matchChar(')') + ) { + $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, '('], $subQuery, [Type::T_KEYWORD, ')']]]; + $s = $this->count; + } else { + $this->seek($s); + } + + if ( + $this->literal('not', 3) && + $this->supportsQuery($subQuery) + ) { + $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, 'not '], $subQuery]]; + $s = $this->count; + } else { + $this->seek($s); + } + + if ( + $this->literal('selector(', 9) && + $this->selector($selector) && + $this->matchChar(')') + ) { + $support = [Type::T_STRING, '', [[Type::T_KEYWORD, 'selector(']]]; + + $selectorList = [Type::T_LIST, '', []]; + + foreach ($selector as $sc) { + $compound = [Type::T_STRING, '', []]; + + foreach ($sc as $scp) { + if (\is_array($scp)) { + $compound[2][] = $scp; + } else { + $compound[2][] = [Type::T_KEYWORD, $scp]; + } + } + + $selectorList[2][] = $compound; + } + + $support[2][] = $selectorList; + $support[2][] = [Type::T_KEYWORD, ')']; + $parts[] = $support; + $s = $this->count; + } else { + $this->seek($s); + } + + if ($this->variable($var) or $this->interpolation($var)) { + $parts[] = $var; + $s = $this->count; + } else { + $this->seek($s); + } + + if ( + $this->literal('and', 3) && + $this->genericList($expressions, 'supportsQuery', ' and', false) + ) { + array_unshift($expressions[2], [Type::T_STRING, '', $parts]); + + $parts = [$expressions]; + $s = $this->count; + } else { + $this->seek($s); + } + + if ( + $this->literal('or', 2) && + $this->genericList($expressions, 'supportsQuery', ' or', false) + ) { + array_unshift($expressions[2], [Type::T_STRING, '', $parts]); + + $parts = [$expressions]; + $s = $this->count; + } else { + $this->seek($s); + } + + if (\count($parts)) { + if ($this->eatWhiteDefault) { + $this->whitespace(); + } + + $out = [Type::T_STRING, '', $parts]; + + return true; + } + + return false; + } + + + /** + * Parse media expression + * + * @param array $out + * + * @return boolean + */ + protected function mediaExpression(&$out) + { + $s = $this->count; + $value = null; + + if ( + $this->matchChar('(') && + $this->expression($feature) && + ($this->matchChar(':') && + $this->expression($value) || true) && + $this->matchChar(')') + ) { + $out = [Type::T_MEDIA_EXPRESSION, $feature]; + + if ($value) { + $out[] = $value; + } + + return true; + } + + $this->seek($s); + + return false; + } + + /** + * Parse argument values + * + * @param array $out + * + * @return boolean + */ + protected function argValues(&$out) + { + $discardComments = $this->discardComments; + $this->discardComments = true; + + if ($this->genericList($list, 'argValue', ',', false)) { + $out = $list[2]; + + $this->discardComments = $discardComments; + + return true; + } + + $this->discardComments = $discardComments; + + return false; + } + + /** + * Parse argument value + * + * @param array $out + * + * @return boolean + */ + protected function argValue(&$out) + { + $s = $this->count; + + $keyword = null; + + if (! $this->variable($keyword) || ! $this->matchChar(':')) { + $this->seek($s); + + $keyword = null; + } + + if ($this->genericList($value, 'expression', '', true)) { + $out = [$keyword, $value, false]; + $s = $this->count; + + if ($this->literal('...', 3)) { + $out[2] = true; + } else { + $this->seek($s); + } + + return true; + } + + return false; + } + + /** + * Check if a generic directive is known to be able to allow almost any syntax or not + * @param mixed $directiveName + * @return bool + */ + protected function isKnownGenericDirective($directiveName) + { + if (\is_array($directiveName) && \is_string(reset($directiveName))) { + $directiveName = reset($directiveName); + } + if (! \is_string($directiveName)) { + return false; + } + if ( + \in_array($directiveName, [ + 'at-root', + 'media', + 'mixin', + 'include', + 'scssphp-import-once', + 'import', + 'extend', + 'function', + 'break', + 'continue', + 'return', + 'each', + 'while', + 'for', + 'if', + 'debug', + 'warn', + 'error', + 'content', + 'else', + 'charset', + 'supports', + // Todo + 'use', + 'forward', + ]) + ) { + return true; + } + return false; + } + + /** + * Parse directive value list that considers $vars as keyword + * + * @param array $out + * @param boolean|string $endChar + * + * @return boolean + */ + protected function directiveValue(&$out, $endChar = false) + { + $s = $this->count; + + if ($this->variable($out)) { + if ($endChar && $this->matchChar($endChar, false)) { + return true; + } + + if (! $endChar && $this->end()) { + return true; + } + } + + $this->seek($s); + + if (\is_string($endChar) && $this->openString($endChar ? $endChar : ';', $out, null, null, true, ";}{")) { + if ($endChar && $this->matchChar($endChar, false)) { + return true; + } + $ss = $this->count; + if (!$endChar && $this->end()) { + $this->seek($ss); + return true; + } + } + + $this->seek($s); + + $allowVars = $this->allowVars; + $this->allowVars = false; + + $res = $this->genericList($out, 'spaceList', ','); + $this->allowVars = $allowVars; + + if ($res) { + if ($endChar && $this->matchChar($endChar, false)) { + return true; + } + + if (! $endChar && $this->end()) { + return true; + } + } + + $this->seek($s); + + if ($endChar && $this->matchChar($endChar, false)) { + return true; + } + + return false; + } + + /** + * Parse comma separated value list + * + * @param array $out + * + * @return boolean + */ + protected function valueList(&$out) + { + $discardComments = $this->discardComments; + $this->discardComments = true; + $res = $this->genericList($out, 'spaceList', ','); + $this->discardComments = $discardComments; + + return $res; + } + + /** + * Parse a function call, where externals () are part of the call + * and not of the value list + * + * @param $out + * @param bool $mandatoryEnclos + * @param null|string $charAfter + * @param null|bool $eatWhiteSp + * @return bool + */ + protected function functionCallArgumentsList(&$out, $mandatoryEnclos = true, $charAfter = null, $eatWhiteSp = null) + { + $s = $this->count; + + if ( + $this->matchChar('(') && + $this->valueList($out) && + $this->matchChar(')') && + ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end()) + ) { + return true; + } + + if (! $mandatoryEnclos) { + $this->seek($s); + + if ( + $this->valueList($out) && + ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end()) + ) { + return true; + } + } + + $this->seek($s); + + return false; + } + + /** + * Parse space separated value list + * + * @param array $out + * + * @return boolean + */ + protected function spaceList(&$out) + { + return $this->genericList($out, 'expression'); + } + + /** + * Parse generic list + * + * @param array $out + * @param string $parseItem The name of the method used to parse items + * @param string $delim + * @param boolean $flatten + * + * @return boolean + */ + protected function genericList(&$out, $parseItem, $delim = '', $flatten = true) + { + $s = $this->count; + $items = []; + $value = null; + + while ($this->$parseItem($value)) { + $trailing_delim = false; + $items[] = $value; + + if ($delim) { + if (! $this->literal($delim, \strlen($delim))) { + break; + } + + $trailing_delim = true; + } else { + // if no delim watch that a keyword didn't eat the single/double quote + // from the following starting string + if ($value[0] === Type::T_KEYWORD) { + $word = $value[1]; + + $last_char = substr($word, -1); + + if ( + strlen($word) > 1 && + in_array($last_char, [ "'", '"']) && + substr($word, -2, 1) !== '\\' + ) { + // if there is a non escaped opening quote in the keyword, this seems unlikely a mistake + $word = str_replace('\\' . $last_char, '\\\\', $word); + if (strpos($word, $last_char) < strlen($word) - 1) { + continue; + } + + $currentCount = $this->count; + + // let's try to rewind to previous char and try a parse + $this->count--; + // in case the keyword also eat spaces + while (substr($this->buffer, $this->count, 1) !== $last_char) { + $this->count--; + } + + $nextValue = null; + if ($this->$parseItem($nextValue)) { + if ($nextValue[0] === Type::T_KEYWORD && $nextValue[1] === $last_char) { + // bad try, forget it + $this->seek($currentCount); + continue; + } + if ($nextValue[0] !== Type::T_STRING) { + // bad try, forget it + $this->seek($currentCount); + continue; + } + + // OK it was a good idea + $value[1] = substr($value[1], 0, -1); + array_pop($items); + $items[] = $value; + $items[] = $nextValue; + } else { + // bad try, forget it + $this->seek($currentCount); + continue; + } + } + } + } + } + + if (! $items) { + $this->seek($s); + + return false; + } + + if ($trailing_delim) { + $items[] = [Type::T_NULL]; + } + + if ($flatten && \count($items) === 1) { + $out = $items[0]; + } else { + $out = [Type::T_LIST, $delim, $items]; + } + + return true; + } + + /** + * Parse expression + * + * @param array $out + * @param boolean $listOnly + * @param boolean $lookForExp + * + * @return boolean + */ + protected function expression(&$out, $listOnly = false, $lookForExp = true) + { + $s = $this->count; + $discard = $this->discardComments; + $this->discardComments = true; + $allowedTypes = ($listOnly ? [Type::T_LIST] : [Type::T_LIST, Type::T_MAP]); + + if ($this->matchChar('(')) { + if ($this->enclosedExpression($lhs, $s, ')', $allowedTypes)) { + if ($lookForExp) { + $out = $this->expHelper($lhs, 0); + } else { + $out = $lhs; + } + + $this->discardComments = $discard; + + return true; + } + + $this->seek($s); + } + + if (\in_array(Type::T_LIST, $allowedTypes) && $this->matchChar('[')) { + if ($this->enclosedExpression($lhs, $s, ']', [Type::T_LIST])) { + if ($lookForExp) { + $out = $this->expHelper($lhs, 0); + } else { + $out = $lhs; + } + + $this->discardComments = $discard; + + return true; + } + + $this->seek($s); + } + + if (! $listOnly && $this->value($lhs)) { + if ($lookForExp) { + $out = $this->expHelper($lhs, 0); + } else { + $out = $lhs; + } + + $this->discardComments = $discard; + + return true; + } + + $this->discardComments = $discard; + + return false; + } + + /** + * Parse expression specifically checking for lists in parenthesis or brackets + * + * @param array $out + * @param integer $s + * @param string $closingParen + * @param array $allowedTypes + * + * @return boolean + */ + protected function enclosedExpression(&$out, $s, $closingParen = ')', $allowedTypes = [Type::T_LIST, Type::T_MAP]) + { + if ($this->matchChar($closingParen) && \in_array(Type::T_LIST, $allowedTypes)) { + $out = [Type::T_LIST, '', []]; + + switch ($closingParen) { + case ')': + $out['enclosing'] = 'parent'; // parenthesis list + break; + + case ']': + $out['enclosing'] = 'bracket'; // bracketed list + break; + } + + return true; + } + + if ( + $this->valueList($out) && + $this->matchChar($closingParen) && ! ($closingParen === ')' && + \in_array($out[0], [Type::T_EXPRESSION, Type::T_UNARY])) && + \in_array(Type::T_LIST, $allowedTypes) + ) { + if ($out[0] !== Type::T_LIST || ! empty($out['enclosing'])) { + $out = [Type::T_LIST, '', [$out]]; + } + + switch ($closingParen) { + case ')': + $out['enclosing'] = 'parent'; // parenthesis list + break; + + case ']': + $out['enclosing'] = 'bracket'; // bracketed list + break; + } + + return true; + } + + $this->seek($s); + + if (\in_array(Type::T_MAP, $allowedTypes) && $this->map($out)) { + return true; + } + + return false; + } + + /** + * Parse left-hand side of subexpression + * + * @param array $lhs + * @param integer $minP + * + * @return array + */ + protected function expHelper($lhs, $minP) + { + $operators = static::$operatorPattern; + + $ss = $this->count; + $whiteBefore = isset($this->buffer[$this->count - 1]) && + ctype_space($this->buffer[$this->count - 1]); + + while ($this->match($operators, $m, false) && static::$precedence[$m[1]] >= $minP) { + $whiteAfter = isset($this->buffer[$this->count]) && + ctype_space($this->buffer[$this->count]); + $varAfter = isset($this->buffer[$this->count]) && + $this->buffer[$this->count] === '$'; + + $this->whitespace(); + + $op = $m[1]; + + // don't turn negative numbers into expressions + if ($op === '-' && $whiteBefore && ! $whiteAfter && ! $varAfter) { + break; + } + + if (! $this->value($rhs) && ! $this->expression($rhs, true, false)) { + break; + } + + if ($op === '-' && ! $whiteAfter && $rhs[0] === Type::T_KEYWORD) { + break; + } + + // consume higher-precedence operators on the right-hand side + $rhs = $this->expHelper($rhs, static::$precedence[$op] + 1); + + $lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter]; + + $ss = $this->count; + $whiteBefore = isset($this->buffer[$this->count - 1]) && + ctype_space($this->buffer[$this->count - 1]); + } + + $this->seek($ss); + + return $lhs; + } + + /** + * Parse value + * + * @param array $out + * + * @return boolean + */ + protected function value(&$out) + { + if (! isset($this->buffer[$this->count])) { + return false; + } + + $s = $this->count; + $char = $this->buffer[$this->count]; + + if ( + $this->literal('url(', 4) && + $this->match('data:([a-z]+)\/([a-z0-9.+-]+);base64,', $m, false) + ) { + $len = strspn( + $this->buffer, + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwyxz0123456789+/=', + $this->count + ); + + $this->count += $len; + + if ($this->matchChar(')')) { + $content = substr($this->buffer, $s, $this->count - $s); + $out = [Type::T_KEYWORD, $content]; + + return true; + } + } + + $this->seek($s); + + if ( + $this->literal('url(', 4, false) && + $this->match('\s*(\/\/[^\s\)]+)\s*', $m) + ) { + $content = 'url(' . $m[1]; + + if ($this->matchChar(')')) { + $content .= ')'; + $out = [Type::T_KEYWORD, $content]; + + return true; + } + } + + $this->seek($s); + + // not + if ($char === 'n' && $this->literal('not', 3, false)) { + if ( + $this->whitespace() && + $this->value($inner) + ) { + $out = [Type::T_UNARY, 'not', $inner, $this->inParens]; + + return true; + } + + $this->seek($s); + + if ($this->parenValue($inner)) { + $out = [Type::T_UNARY, 'not', $inner, $this->inParens]; + + return true; + } + + $this->seek($s); + } + + // addition + if ($char === '+') { + $this->count++; + + $follow_white = $this->whitespace(); + + if ($this->value($inner)) { + $out = [Type::T_UNARY, '+', $inner, $this->inParens]; + + return true; + } + + if ($follow_white) { + $out = [Type::T_KEYWORD, $char]; + return true; + } + + $this->seek($s); + + return false; + } + + // negation + if ($char === '-') { + if ($this->customProperty($out)) { + return true; + } + + $this->count++; + + $follow_white = $this->whitespace(); + + if ($this->variable($inner) || $this->unit($inner) || $this->parenValue($inner)) { + $out = [Type::T_UNARY, '-', $inner, $this->inParens]; + + return true; + } + + if ( + $this->keyword($inner) && + ! $this->func($inner, $out) + ) { + $out = [Type::T_UNARY, '-', $inner, $this->inParens]; + + return true; + } + + if ($follow_white) { + $out = [Type::T_KEYWORD, $char]; + + return true; + } + + $this->seek($s); + } + + // paren + if ($char === '(' && $this->parenValue($out)) { + return true; + } + + if ($char === '#') { + if ($this->interpolation($out) || $this->color($out)) { + return true; + } + + $this->count++; + + if ($this->keyword($keyword)) { + $out = [Type::T_KEYWORD, '#' . $keyword]; + + return true; + } + + $this->count--; + } + + if ($this->matchChar('&', true)) { + $out = [Type::T_SELF]; + + return true; + } + + if ($char === '$' && $this->variable($out)) { + return true; + } + + if ($char === 'p' && $this->progid($out)) { + return true; + } + + if (($char === '"' || $char === "'") && $this->string($out)) { + return true; + } + + if ($this->unit($out)) { + return true; + } + + // unicode range with wildcards + if ( + $this->literal('U+', 2) && + $this->match('\?+|([0-9A-F]+(\?+|(-[0-9A-F]+))?)', $m, false) + ) { + $unicode = explode('-', $m[0]); + if (strlen(reset($unicode)) <= 6 && strlen(end($unicode)) <= 6) { + $out = [Type::T_KEYWORD, 'U+' . $m[0]]; + + return true; + } + $this->count -= strlen($m[0]) + 2; + } + + if ($this->keyword($keyword, false)) { + if ($this->func($keyword, $out)) { + return true; + } + + $this->whitespace(); + + if ($keyword === 'null') { + $out = [Type::T_NULL]; + } else { + $out = [Type::T_KEYWORD, $keyword]; + } + + return true; + } + + return false; + } + + /** + * Parse parenthesized value + * + * @param array $out + * + * @return boolean + */ + protected function parenValue(&$out) + { + $s = $this->count; + + $inParens = $this->inParens; + + if ($this->matchChar('(')) { + if ($this->matchChar(')')) { + $out = [Type::T_LIST, '', []]; + + return true; + } + + $this->inParens = true; + + if ( + $this->expression($exp) && + $this->matchChar(')') + ) { + $out = $exp; + $this->inParens = $inParens; + + return true; + } + } + + $this->inParens = $inParens; + $this->seek($s); + + return false; + } + + /** + * Parse "progid:" + * + * @param array $out + * + * @return boolean + */ + protected function progid(&$out) + { + $s = $this->count; + + if ( + $this->literal('progid:', 7, false) && + $this->openString('(', $fn) && + $this->matchChar('(') + ) { + $this->openString(')', $args, '('); + + if ($this->matchChar(')')) { + $out = [Type::T_STRING, '', [ + 'progid:', $fn, '(', $args, ')' + ]]; + + return true; + } + } + + $this->seek($s); + + return false; + } + + /** + * Parse function call + * + * @param string $name + * @param array $func + * + * @return boolean + */ + protected function func($name, &$func) + { + $s = $this->count; + + if ($this->matchChar('(')) { + if ($name === 'alpha' && $this->argumentList($args)) { + $func = [Type::T_FUNCTION, $name, [Type::T_STRING, '', $args]]; + + return true; + } + + if ($name !== 'expression' && ! preg_match('/^(-[a-z]+-)?calc$/', $name)) { + $ss = $this->count; + + if ( + $this->argValues($args) && + $this->matchChar(')') + ) { + $func = [Type::T_FUNCTION_CALL, $name, $args]; + + return true; + } + + $this->seek($ss); + } + + if ( + ($this->openString(')', $str, '(') || true) && + $this->matchChar(')') + ) { + $args = []; + + if (! empty($str)) { + $args[] = [null, [Type::T_STRING, '', [$str]]]; + } + + $func = [Type::T_FUNCTION_CALL, $name, $args]; + + return true; + } + } + + $this->seek($s); + + return false; + } + + /** + * Parse function call argument list + * + * @param array $out + * + * @return boolean + */ + protected function argumentList(&$out) + { + $s = $this->count; + $this->matchChar('('); + + $args = []; + + while ($this->keyword($var)) { + if ( + $this->matchChar('=') && + $this->expression($exp) + ) { + $args[] = [Type::T_STRING, '', [$var . '=']]; + $arg = $exp; + } else { + break; + } + + $args[] = $arg; + + if (! $this->matchChar(',')) { + break; + } + + $args[] = [Type::T_STRING, '', [', ']]; + } + + if (! $this->matchChar(')') || ! $args) { + $this->seek($s); + + return false; + } + + $out = $args; + + return true; + } + + /** + * Parse mixin/function definition argument list + * + * @param array $out + * + * @return boolean + */ + protected function argumentDef(&$out) + { + $s = $this->count; + $this->matchChar('('); + + $args = []; + + while ($this->variable($var)) { + $arg = [$var[1], null, false]; + + $ss = $this->count; + + if ( + $this->matchChar(':') && + $this->genericList($defaultVal, 'expression', '', true) + ) { + $arg[1] = $defaultVal; + } else { + $this->seek($ss); + } + + $ss = $this->count; + + if ($this->literal('...', 3)) { + $sss = $this->count; + + if (! $this->matchChar(')')) { + throw $this->parseError('... has to be after the final argument'); + } + + $arg[2] = true; + + $this->seek($sss); + } else { + $this->seek($ss); + } + + $args[] = $arg; + + if (! $this->matchChar(',')) { + break; + } + } + + if (! $this->matchChar(')')) { + $this->seek($s); + + return false; + } + + $out = $args; + + return true; + } + + /** + * Parse map + * + * @param array $out + * + * @return boolean + */ + protected function map(&$out) + { + $s = $this->count; + + if (! $this->matchChar('(')) { + return false; + } + + $keys = []; + $values = []; + + while ( + $this->genericList($key, 'expression', '', true) && + $this->matchChar(':') && + $this->genericList($value, 'expression', '', true) + ) { + $keys[] = $key; + $values[] = $value; + + if (! $this->matchChar(',')) { + break; + } + } + + if (! $keys || ! $this->matchChar(')')) { + $this->seek($s); + + return false; + } + + $out = [Type::T_MAP, $keys, $values]; + + return true; + } + + /** + * Parse color + * + * @param array $out + * + * @return boolean + */ + protected function color(&$out) + { + $s = $this->count; + + if ($this->match('(#([0-9a-f]+)\b)', $m)) { + if (\in_array(\strlen($m[2]), [3,4,6,8])) { + $out = [Type::T_KEYWORD, $m[0]]; + + return true; + } + + $this->seek($s); + + return false; + } + + return false; + } + + /** + * Parse number with unit + * + * @param array $unit + * + * @return boolean + */ + protected function unit(&$unit) + { + $s = $this->count; + + if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m, false)) { + if (\strlen($this->buffer) === $this->count || ! ctype_digit($this->buffer[$this->count])) { + $this->whitespace(); + + $unit = new Node\Number($m[1], empty($m[3]) ? '' : $m[3]); + + return true; + } + + $this->seek($s); + } + + return false; + } + + /** + * Parse string + * + * @param array $out + * + * @return boolean + */ + protected function string(&$out, $keepDelimWithInterpolation = false) + { + $s = $this->count; + + if ($this->matchChar('"', false)) { + $delim = '"'; + } elseif ($this->matchChar("'", false)) { + $delim = "'"; + } else { + return false; + } + + $content = []; + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + $hasInterpolation = false; + + while ($this->matchString($m, $delim)) { + if ($m[1] !== '') { + $content[] = $m[1]; + } + + if ($m[2] === '#{') { + $this->count -= \strlen($m[2]); + + if ($this->interpolation($inter, false)) { + $content[] = $inter; + $hasInterpolation = true; + } else { + $this->count += \strlen($m[2]); + $content[] = '#{'; // ignore it + } + } elseif ($m[2] === "\r") { + $content[] = chr(10); + // TODO : warning + # DEPRECATION WARNING on line x, column y of zzz: + # Unescaped multiline strings are deprecated and will be removed in a future version of Sass. + # To include a newline in a string, use "\a" or "\a " as in CSS. + if ($this->matchChar("\n", false)) { + $content[] = ' '; + } + } elseif ($m[2] === '\\') { + if ( + $this->literal("\r\n", 2, false) || + $this->matchChar("\r", false) || + $this->matchChar("\n", false) || + $this->matchChar("\f", false) + ) { + // this is a continuation escaping, to be ignored + } elseif ($this->matchEscapeCharacter($c)) { + $content[] = $c; + } else { + throw $this->parseError('Unterminated escape sequence'); + } + } else { + $this->count -= \strlen($delim); + break; // delim + } + } + + $this->eatWhiteDefault = $oldWhite; + + if ($this->literal($delim, \strlen($delim))) { + if ($hasInterpolation && ! $keepDelimWithInterpolation) { + $delim = '"'; + } + + $out = [Type::T_STRING, $delim, $content]; + + return true; + } + + $this->seek($s); + + return false; + } + + /** + * @param string $out + * @param bool $inKeywords + * @return bool + */ + protected function matchEscapeCharacter(&$out, $inKeywords = false) + { + $s = $this->count; + if ($this->match('[a-f0-9]', $m, false)) { + $hex = $m[0]; + + for ($i = 5; $i--;) { + if ($this->match('[a-f0-9]', $m, false)) { + $hex .= $m[0]; + } else { + break; + } + } + + // CSS allows Unicode escape sequences to be followed by a delimiter space + // (necessary in some cases for shorter sequences to disambiguate their end) + $this->matchChar(' ', false); + + $value = hexdec($hex); + + if (!$inKeywords && ($value == 0 || ($value >= 0xD800 && $value <= 0xDFFF) || $value >= 0x10FFFF)) { + $out = "\xEF\xBF\xBD"; // "\u{FFFD}" but with a syntax supported on PHP 5 + } elseif ($value < 0x20) { + $out = Util::mbChr($value); + } else { + $out = Util::mbChr($value); + } + + return true; + } + + if ($this->match('.', $m, false)) { + if ($inKeywords && in_array($m[0], ["'",'"','@','&',' ','\\',':','/','%'])) { + $this->seek($s); + return false; + } + $out = $m[0]; + + return true; + } + + return false; + } + + /** + * Parse keyword or interpolation + * + * @param array $out + * @param boolean $restricted + * + * @return boolean + */ + protected function mixedKeyword(&$out, $restricted = false) + { + $parts = []; + + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + + for (;;) { + if ($restricted ? $this->restrictedKeyword($key) : $this->keyword($key)) { + $parts[] = $key; + continue; + } + + if ($this->interpolation($inter)) { + $parts[] = $inter; + continue; + } + + break; + } + + $this->eatWhiteDefault = $oldWhite; + + if (! $parts) { + return false; + } + + if ($this->eatWhiteDefault) { + $this->whitespace(); + } + + $out = $parts; + + return true; + } + + /** + * Parse an unbounded string stopped by $end + * + * @param string $end + * @param array $out + * @param string $nestOpen + * @param string $nestClose + * @param boolean $rtrim + * @param string $disallow + * + * @return boolean + */ + protected function openString($end, &$out, $nestOpen = null, $nestClose = null, $rtrim = true, $disallow = null) + { + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + + if ($nestOpen && ! $nestClose) { + $nestClose = $end; + } + + $patt = ($disallow ? '[^' . $this->pregQuote($disallow) . ']' : '.'); + $patt = '(' . $patt . '*?)([\'"]|#\{|' + . $this->pregQuote($end) . '|' + . (($nestClose && $nestClose !== $end) ? $this->pregQuote($nestClose) . '|' : '') + . static::$commentPattern . ')'; + + $nestingLevel = 0; + + $content = []; + + while ($this->match($patt, $m, false)) { + if (isset($m[1]) && $m[1] !== '') { + $content[] = $m[1]; + + if ($nestOpen) { + $nestingLevel += substr_count($m[1], $nestOpen); + } + } + + $tok = $m[2]; + + $this->count -= \strlen($tok); + + if ($tok === $end && ! $nestingLevel) { + break; + } + + if ($tok === $nestClose) { + $nestingLevel--; + } + + if (($tok === "'" || $tok === '"') && $this->string($str, true)) { + $content[] = $str; + continue; + } + + if ($tok === '#{' && $this->interpolation($inter)) { + $content[] = $inter; + continue; + } + + $content[] = $tok; + $this->count += \strlen($tok); + } + + $this->eatWhiteDefault = $oldWhite; + + if (! $content || $tok !== $end) { + return false; + } + + // trim the end + if ($rtrim && \is_string(end($content))) { + $content[\count($content) - 1] = rtrim(end($content)); + } + + $out = [Type::T_STRING, '', $content]; + + return true; + } + + /** + * Parser interpolation + * + * @param string|array $out + * @param boolean $lookWhite save information about whitespace before and after + * + * @return boolean + */ + protected function interpolation(&$out, $lookWhite = true) + { + $oldWhite = $this->eatWhiteDefault; + $allowVars = $this->allowVars; + $this->allowVars = true; + $this->eatWhiteDefault = true; + + $s = $this->count; + + if ( + $this->literal('#{', 2) && + $this->valueList($value) && + $this->matchChar('}', false) + ) { + if ($value === [Type::T_SELF]) { + $out = $value; + } else { + if ($lookWhite) { + $left = ($s > 0 && preg_match('/\s/', $this->buffer[$s - 1])) ? ' ' : ''; + $right = ( + ! empty($this->buffer[$this->count]) && + preg_match('/\s/', $this->buffer[$this->count]) + ) ? ' ' : ''; + } else { + $left = $right = false; + } + + $out = [Type::T_INTERPOLATE, $value, $left, $right]; + } + + $this->eatWhiteDefault = $oldWhite; + $this->allowVars = $allowVars; + + if ($this->eatWhiteDefault) { + $this->whitespace(); + } + + return true; + } + + $this->seek($s); + + $this->eatWhiteDefault = $oldWhite; + $this->allowVars = $allowVars; + + return false; + } + + /** + * Parse property name (as an array of parts or a string) + * + * @param array $out + * + * @return boolean + */ + protected function propertyName(&$out) + { + $parts = []; + + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + + for (;;) { + if ($this->interpolation($inter)) { + $parts[] = $inter; + continue; + } + + if ($this->keyword($text)) { + $parts[] = $text; + continue; + } + + if (! $parts && $this->match('[:.#]', $m, false)) { + // css hacks + $parts[] = $m[0]; + continue; + } + + break; + } + + $this->eatWhiteDefault = $oldWhite; + + if (! $parts) { + return false; + } + + // match comment hack + if (preg_match(static::$whitePattern, $this->buffer, $m, 0, $this->count)) { + if (! empty($m[0])) { + $parts[] = $m[0]; + $this->count += \strlen($m[0]); + } + } + + $this->whitespace(); // get any extra whitespace + + $out = [Type::T_STRING, '', $parts]; + + return true; + } + + /** + * Parse custom property name (as an array of parts or a string) + * + * @param array $out + * + * @return boolean + */ + protected function customProperty(&$out) + { + $s = $this->count; + + if (! $this->literal('--', 2, false)) { + return false; + } + + $parts = ['--']; + + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + + for (;;) { + if ($this->interpolation($inter)) { + $parts[] = $inter; + continue; + } + + if ($this->matchChar('&', false)) { + $parts[] = [Type::T_SELF]; + continue; + } + + if ($this->variable($var)) { + $parts[] = $var; + continue; + } + + if ($this->keyword($text)) { + $parts[] = $text; + continue; + } + + break; + } + + $this->eatWhiteDefault = $oldWhite; + + if (\count($parts) == 1) { + $this->seek($s); + + return false; + } + + $this->whitespace(); // get any extra whitespace + + $out = [Type::T_STRING, '', $parts]; + + return true; + } + + /** + * Parse comma separated selector list + * + * @param array $out + * @param string|boolean $subSelector + * + * @return boolean + */ + protected function selectors(&$out, $subSelector = false) + { + $s = $this->count; + $selectors = []; + + while ($this->selector($sel, $subSelector)) { + $selectors[] = $sel; + + if (! $this->matchChar(',', true)) { + break; + } + + while ($this->matchChar(',', true)) { + ; // ignore extra + } + } + + if (! $selectors) { + $this->seek($s); + + return false; + } + + $out = $selectors; + + return true; + } + + /** + * Parse whitespace separated selector list + * + * @param array $out + * @param string|boolean $subSelector + * + * @return boolean + */ + protected function selector(&$out, $subSelector = false) + { + $selector = []; + + $discardComments = $this->discardComments; + $this->discardComments = true; + + for (;;) { + $s = $this->count; + + if ($this->match('[>+~]+', $m, true)) { + if ( + $subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0 && + $m[0] === '+' && $this->match("(\d+|n\b)", $counter) + ) { + $this->seek($s); + } else { + $selector[] = [$m[0]]; + continue; + } + } + + if ($this->selectorSingle($part, $subSelector)) { + $selector[] = $part; + $this->whitespace(); + continue; + } + + break; + } + + $this->discardComments = $discardComments; + + if (! $selector) { + return false; + } + + $out = $selector; + + return true; + } + + /** + * parsing escaped chars in selectors: + * - escaped single chars are kept escaped in the selector but in a normalized form + * (if not in 0-9a-f range as this would be ambigous) + * - other escaped sequences (multibyte chars or 0-9a-f) are kept in their initial escaped form, + * normalized to lowercase + * + * TODO: this is a fallback solution. Ideally escaped chars in selectors should be encoded as the genuine chars, + * and escaping added when printing in the Compiler, where/if it's mandatory + * - but this require a better formal selector representation instead of the array we have now + * + * @param string $out + * @param bool $keepEscapedNumber + * @return bool + */ + protected function matchEscapeCharacterInSelector(&$out, $keepEscapedNumber = false) + { + $s_escape = $this->count; + if ($this->match('\\\\', $m)) { + $out = '\\' . $m[0]; + return true; + } + + if ($this->matchEscapeCharacter($escapedout, true)) { + if (strlen($escapedout) === 1) { + if (!preg_match(",\w,", $escapedout)) { + $out = '\\' . $escapedout; + return true; + } elseif (! $keepEscapedNumber || ! \is_numeric($escapedout)) { + $out = $escapedout; + return true; + } + } + $escape_sequence = rtrim(substr($this->buffer, $s_escape, $this->count - $s_escape)); + if (strlen($escape_sequence) < 6) { + $escape_sequence .= ' '; + } + $out = '\\' . strtolower($escape_sequence); + return true; + } + if ($this->match('\\S', $m)) { + $out = '\\' . $m[0]; + return true; + } + + + return false; + } + + /** + * Parse the parts that make up a selector + * + * {@internal + * div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder + * }} + * + * @param array $out + * @param string|boolean $subSelector + * + * @return boolean + */ + protected function selectorSingle(&$out, $subSelector = false) + { + $oldWhite = $this->eatWhiteDefault; + $this->eatWhiteDefault = false; + + $parts = []; + + if ($this->matchChar('*', false)) { + $parts[] = '*'; + } + + for (;;) { + if (! isset($this->buffer[$this->count])) { + break; + } + + $s = $this->count; + $char = $this->buffer[$this->count]; + + // see if we can stop early + if ($char === '{' || $char === ',' || $char === ';' || $char === '}' || $char === '@') { + break; + } + + // parsing a sub selector in () stop with the closing ) + if ($subSelector && $char === ')') { + break; + } + + //self + switch ($char) { + case '&': + $parts[] = Compiler::$selfSelector; + $this->count++; + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + continue 2; + + case '.': + $parts[] = '.'; + $this->count++; + continue 2; + + case '|': + $parts[] = '|'; + $this->count++; + continue 2; + } + + // handling of escaping in selectors : get the escaped char + if ($char === '\\') { + $this->count++; + if ($this->matchEscapeCharacterInSelector($escaped, true)) { + $parts[] = $escaped; + continue; + } + $this->count--; + } + + if ($char === '%') { + $this->count++; + + if ($this->placeholder($placeholder)) { + $parts[] = '%'; + $parts[] = $placeholder; + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + continue; + } + + break; + } + + if ($char === '#') { + if ($this->interpolation($inter)) { + $parts[] = $inter; + ! $this->cssOnly || $this->assertPlainCssValid(false, $s); + continue; + } + + $parts[] = '#'; + $this->count++; + continue; + } + + // a pseudo selector + if ($char === ':') { + if ($this->buffer[$this->count + 1] === ':') { + $this->count += 2; + $part = '::'; + } else { + $this->count++; + $part = ':'; + } + + if ($this->mixedKeyword($nameParts, true)) { + $parts[] = $part; + + foreach ($nameParts as $sub) { + $parts[] = $sub; + } + + $ss = $this->count; + + if ( + $nameParts === ['not'] || + $nameParts === ['is'] || + $nameParts === ['has'] || + $nameParts === ['where'] || + $nameParts === ['slotted'] || + $nameParts === ['nth-child'] || + $nameParts === ['nth-last-child'] || + $nameParts === ['nth-of-type'] || + $nameParts === ['nth-last-of-type'] + ) { + if ( + $this->matchChar('(', true) && + ($this->selectors($subs, reset($nameParts)) || true) && + $this->matchChar(')') + ) { + $parts[] = '('; + + while ($sub = array_shift($subs)) { + while ($ps = array_shift($sub)) { + foreach ($ps as &$p) { + $parts[] = $p; + } + + if (\count($sub) && reset($sub)) { + $parts[] = ' '; + } + } + + if (\count($subs) && reset($subs)) { + $parts[] = ', '; + } + } + + $parts[] = ')'; + } else { + $this->seek($ss); + } + } elseif ( + $this->matchChar('(', true) && + ($this->openString(')', $str, '(') || true) && + $this->matchChar(')') + ) { + $parts[] = '('; + + if (! empty($str)) { + $parts[] = $str; + } + + $parts[] = ')'; + } else { + $this->seek($ss); + } + + continue; + } + } + + $this->seek($s); + + // 2n+1 + if ($subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0) { + if ($this->match("(\s*(\+\s*|\-\s*)?(\d+|n|\d+n))+", $counter)) { + $parts[] = $counter[0]; + //$parts[] = str_replace(' ', '', $counter[0]); + continue; + } + } + + $this->seek($s); + + // attribute selector + if ( + $char === '[' && + $this->matchChar('[') && + ($this->openString(']', $str, '[') || true) && + $this->matchChar(']') + ) { + $parts[] = '['; + + if (! empty($str)) { + $parts[] = $str; + } + + $parts[] = ']'; + continue; + } + + $this->seek($s); + + // for keyframes + if ($this->unit($unit)) { + $parts[] = $unit; + continue; + } + + if ($this->restrictedKeyword($name, false, true)) { + $parts[] = $name; + continue; + } + + break; + } + + $this->eatWhiteDefault = $oldWhite; + + if (! $parts) { + return false; + } + + $out = $parts; + + return true; + } + + /** + * Parse a variable + * + * @param array $out + * + * @return boolean + */ + protected function variable(&$out) + { + $s = $this->count; + + if ( + $this->matchChar('$', false) && + $this->keyword($name) + ) { + if ($this->allowVars) { + $out = [Type::T_VARIABLE, $name]; + } else { + $out = [Type::T_KEYWORD, '$' . $name]; + } + + return true; + } + + $this->seek($s); + + return false; + } + + /** + * Parse a keyword + * + * @param string $word + * @param boolean $eatWhitespace + * @param boolean $inSelector + * + * @return boolean + */ + protected function keyword(&$word, $eatWhitespace = null, $inSelector = false) + { + $s = $this->count; + $match = $this->match( + $this->utf8 + ? '(([\pL\w\x{00A0}-\x{10FFFF}_\-\*!"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)([\pL\w\x{00A0}-\x{10FFFF}\-_"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)*)' + : '(([\w_\-\*!"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)([\w\-_"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)*)', + $m, + false + ); + + if ($match) { + $word = $m[1]; + + // handling of escaping in keyword : get the escaped char + if (strpos($word, '\\') !== false) { + $send = $this->count; + $escapedWord = []; + $this->seek($s); + $previousEscape = false; + while ($this->count < $send) { + $char = $this->buffer[$this->count]; + $this->count++; + if ( + $this->count < $send + && $char === '\\' + && !$previousEscape + && ( + $inSelector ? + $this->matchEscapeCharacterInSelector($out) + : + $this->matchEscapeCharacter($out, true) + ) + ) { + $escapedWord[] = $out; + } else { + if ($previousEscape) { + $previousEscape = false; + } elseif ($char === '\\') { + $previousEscape = true; + } + $escapedWord[] = $char; + } + } + + $word = implode('', $escapedWord); + } + + if (is_null($eatWhitespace) ? $this->eatWhiteDefault : $eatWhitespace) { + $this->whitespace(); + } + + return true; + } + + return false; + } + + /** + * Parse a keyword that should not start with a number + * + * @param string $word + * @param boolean $eatWhitespace + * @param boolean $inSelector + * + * @return boolean + */ + protected function restrictedKeyword(&$word, $eatWhitespace = null, $inSelector = false) + { + $s = $this->count; + + if ($this->keyword($word, $eatWhitespace, $inSelector) && (\ord($word[0]) > 57 || \ord($word[0]) < 48)) { + return true; + } + + $this->seek($s); + + return false; + } + + /** + * Parse a placeholder + * + * @param string|array $placeholder + * + * @return boolean + */ + protected function placeholder(&$placeholder) + { + $match = $this->match( + $this->utf8 + ? '([\pL\w\-_]+)' + : '([\w\-_]+)', + $m + ); + + if ($match) { + $placeholder = $m[1]; + + return true; + } + + if ($this->interpolation($placeholder)) { + return true; + } + + return false; + } + + /** + * Parse a url + * + * @param array $out + * + * @return boolean + */ + protected function url(&$out) + { + if ($this->literal('url(', 4)) { + $s = $this->count; + + if ( + ($this->string($out) || $this->spaceList($out)) && + $this->matchChar(')') + ) { + $out = [Type::T_STRING, '', ['url(', $out, ')']]; + + return true; + } + + $this->seek($s); + + if ( + $this->openString(')', $out) && + $this->matchChar(')') + ) { + $out = [Type::T_STRING, '', ['url(', $out, ')']]; + + return true; + } + } + + return false; + } + + /** + * Consume an end of statement delimiter + * @param bool $eatWhitespace + * + * @return boolean + */ + protected function end($eatWhitespace = null) + { + if ($this->matchChar(';', $eatWhitespace)) { + return true; + } + + if ($this->count === \strlen($this->buffer) || $this->buffer[$this->count] === '}') { + // if there is end of file or a closing block next then we don't need a ; + return true; + } + + return false; + } + + /** + * Strip assignment flag from the list + * + * @param array $value + * + * @return array + */ + protected function stripAssignmentFlags(&$value) + { + $flags = []; + + for ($token = &$value; $token[0] === Type::T_LIST && ($s = \count($token[2])); $token = &$lastNode) { + $lastNode = &$token[2][$s - 1]; + + while ($lastNode[0] === Type::T_KEYWORD && \in_array($lastNode[1], ['!default', '!global'])) { + array_pop($token[2]); + + $node = end($token[2]); + $token = $this->flattenList($token); + $flags[] = $lastNode[1]; + $lastNode = $node; + } + } + + return $flags; + } + + /** + * Strip optional flag from selector list + * + * @param array $selectors + * + * @return string + */ + protected function stripOptionalFlag(&$selectors) + { + $optional = false; + $selector = end($selectors); + $part = end($selector); + + if ($part === ['!optional']) { + array_pop($selectors[\count($selectors) - 1]); + + $optional = true; + } + + return $optional; + } + + /** + * Turn list of length 1 into value type + * + * @param array $value + * + * @return array + */ + protected function flattenList($value) + { + if ($value[0] === Type::T_LIST && \count($value[2]) === 1) { + return $this->flattenList($value[2][0]); + } + + return $value; + } + + /** + * Quote regular expression + * + * @param string $what + * + * @return string + */ + private function pregQuote($what) + { + return preg_quote($what, '/'); + } + + /** + * Extract line numbers from buffer + * + * @param string $buffer + */ + private function extractLineNumbers($buffer) + { + $this->sourcePositions = [0 => 0]; + $prev = 0; + + while (($pos = strpos($buffer, "\n", $prev)) !== false) { + $this->sourcePositions[] = $pos; + $prev = $pos + 1; + } + + $this->sourcePositions[] = \strlen($buffer); + + if (substr($buffer, -1) !== "\n") { + $this->sourcePositions[] = \strlen($buffer) + 1; + } + } + + /** + * Get source line number and column (given character position in the buffer) + * + * @param integer $pos + * + * @return array + */ + private function getSourcePosition($pos) + { + $low = 0; + $high = \count($this->sourcePositions); + + while ($low < $high) { + $mid = (int) (($high + $low) / 2); + + if ($pos < $this->sourcePositions[$mid]) { + $high = $mid - 1; + continue; + } + + if ($pos >= $this->sourcePositions[$mid + 1]) { + $low = $mid + 1; + continue; + } + + return [$mid + 1, $pos - $this->sourcePositions[$mid]]; + } + + return [$low + 1, $pos - $this->sourcePositions[$low]]; + } + + /** + * Save internal encoding of mbstring + * + * When mbstring.func_overload is used to replace the standard PHP string functions, + * this method configures the internal encoding to a single-byte one so that the + * behavior matches the normal behavior of PHP string functions while using the parser. + * The existing internal encoding is saved and will be restored when calling {@see restoreEncoding}. + * + * If mbstring.func_overload is not used (or does not override string functions), this method is a no-op. + * + * @return void + */ + private function saveEncoding() + { + if (\PHP_VERSION_ID < 80000 && \extension_loaded('mbstring') && (2 & (int) ini_get('mbstring.func_overload')) > 0) { + $this->encoding = mb_internal_encoding(); + + mb_internal_encoding('iso-8859-1'); + } + } + + /** + * Restore internal encoding + * + * @return void + */ + private function restoreEncoding() + { + if (\extension_loaded('mbstring') && $this->encoding) { + mb_internal_encoding($this->encoding); + } + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php new file mode 100644 index 0000000..4a5ed8b --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php @@ -0,0 +1,187 @@ + + * + * @internal + */ +class Base64 +{ + /** + * @var array + */ + private static $encodingMap = [ + 0 => 'A', + 1 => 'B', + 2 => 'C', + 3 => 'D', + 4 => 'E', + 5 => 'F', + 6 => 'G', + 7 => 'H', + 8 => 'I', + 9 => 'J', + 10 => 'K', + 11 => 'L', + 12 => 'M', + 13 => 'N', + 14 => 'O', + 15 => 'P', + 16 => 'Q', + 17 => 'R', + 18 => 'S', + 19 => 'T', + 20 => 'U', + 21 => 'V', + 22 => 'W', + 23 => 'X', + 24 => 'Y', + 25 => 'Z', + 26 => 'a', + 27 => 'b', + 28 => 'c', + 29 => 'd', + 30 => 'e', + 31 => 'f', + 32 => 'g', + 33 => 'h', + 34 => 'i', + 35 => 'j', + 36 => 'k', + 37 => 'l', + 38 => 'm', + 39 => 'n', + 40 => 'o', + 41 => 'p', + 42 => 'q', + 43 => 'r', + 44 => 's', + 45 => 't', + 46 => 'u', + 47 => 'v', + 48 => 'w', + 49 => 'x', + 50 => 'y', + 51 => 'z', + 52 => '0', + 53 => '1', + 54 => '2', + 55 => '3', + 56 => '4', + 57 => '5', + 58 => '6', + 59 => '7', + 60 => '8', + 61 => '9', + 62 => '+', + 63 => '/', + ]; + + /** + * @var array + */ + private static $decodingMap = [ + 'A' => 0, + 'B' => 1, + 'C' => 2, + 'D' => 3, + 'E' => 4, + 'F' => 5, + 'G' => 6, + 'H' => 7, + 'I' => 8, + 'J' => 9, + 'K' => 10, + 'L' => 11, + 'M' => 12, + 'N' => 13, + 'O' => 14, + 'P' => 15, + 'Q' => 16, + 'R' => 17, + 'S' => 18, + 'T' => 19, + 'U' => 20, + 'V' => 21, + 'W' => 22, + 'X' => 23, + 'Y' => 24, + 'Z' => 25, + 'a' => 26, + 'b' => 27, + 'c' => 28, + 'd' => 29, + 'e' => 30, + 'f' => 31, + 'g' => 32, + 'h' => 33, + 'i' => 34, + 'j' => 35, + 'k' => 36, + 'l' => 37, + 'm' => 38, + 'n' => 39, + 'o' => 40, + 'p' => 41, + 'q' => 42, + 'r' => 43, + 's' => 44, + 't' => 45, + 'u' => 46, + 'v' => 47, + 'w' => 48, + 'x' => 49, + 'y' => 50, + 'z' => 51, + 0 => 52, + 1 => 53, + 2 => 54, + 3 => 55, + 4 => 56, + 5 => 57, + 6 => 58, + 7 => 59, + 8 => 60, + 9 => 61, + '+' => 62, + '/' => 63, + ]; + + /** + * Convert to base64 + * + * @param integer $value + * + * @return string + */ + public static function encode($value) + { + return self::$encodingMap[$value]; + } + + /** + * Convert from base64 + * + * @param string $value + * + * @return integer + */ + public static function decode($value) + { + return self::$decodingMap[$value]; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php new file mode 100644 index 0000000..d47b96a --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php @@ -0,0 +1,151 @@ + + * @author Anthon Pang + * + * @internal + */ +class Base64VLQ +{ + // A Base64 VLQ digit can represent 5 bits, so it is base-32. + const VLQ_BASE_SHIFT = 5; + + // A mask of bits for a VLQ digit (11111), 31 decimal. + const VLQ_BASE_MASK = 31; + + // The continuation bit is the 6th bit. + const VLQ_CONTINUATION_BIT = 32; + + /** + * Returns the VLQ encoded value. + * + * @param integer $value + * + * @return string + */ + public static function encode($value) + { + $encoded = ''; + $vlq = self::toVLQSigned($value); + + do { + $digit = $vlq & self::VLQ_BASE_MASK; + + //$vlq >>>= self::VLQ_BASE_SHIFT; // unsigned right shift + $vlq = (($vlq >> 1) & PHP_INT_MAX) >> (self::VLQ_BASE_SHIFT - 1); + + if ($vlq > 0) { + $digit |= self::VLQ_CONTINUATION_BIT; + } + + $encoded .= Base64::encode($digit); + } while ($vlq > 0); + + return $encoded; + } + + /** + * Decodes VLQValue. + * + * @param string $str + * @param integer $index + * + * @return integer + */ + public static function decode($str, &$index) + { + $result = 0; + $shift = 0; + + do { + $c = $str[$index++]; + $digit = Base64::decode($c); + $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0; + $digit &= self::VLQ_BASE_MASK; + $result = $result + ($digit << $shift); + $shift = $shift + self::VLQ_BASE_SHIFT; + } while ($continuation); + + return self::fromVLQSigned($result); + } + + /** + * Converts from a two-complement value to a value where the sign bit is + * is placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + * + * @param integer $value + * + * @return integer + */ + private static function toVLQSigned($value) + { + if ($value < 0) { + return ((-$value) << 1) + 1; + } + + return ($value << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * is placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + * + * @param integer $value + * + * @return integer + */ + private static function fromVLQSigned($value) + { + $negate = ($value & 1) === 1; + + //$value >>>= 1; // unsigned right shift + $value = ($value >> 1) & PHP_INT_MAX; + + if (! $negate) { + return $value; + } + + // We need to OR 0x80000000 here to ensure the 32nd bit (the sign bit) is + // always set for negative numbers. If `value` were 1, (meaning `negate` is + // true and all other bits were zeros), `value` would now be 0. -0 is just + // 0, and doesn't flip the 32nd bit as intended. All positive numbers will + // successfully flip the 32nd bit without issue, so it's a noop for them. + return -$value | 0x80000000; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php new file mode 100644 index 0000000..4f14bdc --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php @@ -0,0 +1,381 @@ + + * @author Nicolas FRANÇOIS + * + * @internal + */ +class SourceMapGenerator +{ + /** + * What version of source map does the generator generate? + */ + const VERSION = 3; + + /** + * Array of default options + * + * @var array + * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string} + */ + protected $defaultOptions = [ + // an optional source root, useful for relocating source files + // on a server or removing repeated values in the 'sources' entry. + // This value is prepended to the individual entries in the 'source' field. + 'sourceRoot' => '', + + // an optional name of the generated code that this source map is associated with. + 'sourceMapFilename' => null, + + // url of the map + 'sourceMapURL' => null, + + // absolute path to a file to write the map to + 'sourceMapWriteTo' => null, + + // output source contents? + 'outputSourceFiles' => false, + + // base path for filename normalization + 'sourceMapRootpath' => '', + + // base path for filename normalization + 'sourceMapBasepath' => '' + ]; + + /** + * The base64 VLQ encoder + * + * @var \ScssPhp\ScssPhp\SourceMap\Base64VLQ + */ + protected $encoder; + + /** + * Array of mappings + * + * @var array + * @phpstan-var list + */ + protected $mappings = []; + + /** + * Array of contents map + * + * @var array + */ + protected $contentsMap = []; + + /** + * File to content map + * + * @var array + */ + protected $sources = []; + + /** + * @var array + */ + protected $sourceKeys = []; + + /** + * @var array + * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string} + */ + private $options; + + /** + * @phpstan-param array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} $options + */ + public function __construct(array $options = []) + { + $this->options = array_merge($this->defaultOptions, $options); + $this->encoder = new Base64VLQ(); + } + + /** + * Adds a mapping + * + * @param integer $generatedLine The line number in generated file + * @param integer $generatedColumn The column number in generated file + * @param integer $originalLine The line number in original file + * @param integer $originalColumn The column number in original file + * @param string $sourceFile The original source file + * + * @return void + */ + public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile) + { + $this->mappings[] = [ + 'generated_line' => $generatedLine, + 'generated_column' => $generatedColumn, + 'original_line' => $originalLine, + 'original_column' => $originalColumn, + 'source_file' => $sourceFile + ]; + + $this->sources[$sourceFile] = $sourceFile; + } + + /** + * Saves the source map to a file + * + * @param string $content The content to write + * + * @return string + * + * @throws \ScssPhp\ScssPhp\Exception\CompilerException If the file could not be saved + * @deprecated + */ + public function saveMap($content) + { + $file = $this->options['sourceMapWriteTo']; + $dir = \dirname($file); + + // directory does not exist + if (! is_dir($dir)) { + // FIXME: create the dir automatically? + throw new CompilerException( + sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir) + ); + } + + // FIXME: proper saving, with dir write check! + if (file_put_contents($file, $content) === false) { + throw new CompilerException(sprintf('Cannot save the source map to "%s"', $file)); + } + + return $this->options['sourceMapURL']; + } + + /** + * Generates the JSON source map + * + * @param string $prefix A prefix added in the output file, which needs to shift mappings + * + * @return string + * + * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit# + */ + public function generateJson($prefix = '') + { + $sourceMap = []; + $mappings = $this->generateMappings($prefix); + + // File version (always the first entry in the object) and must be a positive integer. + $sourceMap['version'] = self::VERSION; + + // An optional name of the generated code that this source map is associated with. + $file = $this->options['sourceMapFilename']; + + if ($file) { + $sourceMap['file'] = $file; + } + + // An optional source root, useful for relocating source files on a server or removing repeated values in the + // 'sources' entry. This value is prepended to the individual entries in the 'source' field. + $root = $this->options['sourceRoot']; + + if ($root) { + $sourceMap['sourceRoot'] = $root; + } + + // A list of original sources used by the 'mappings' entry. + $sourceMap['sources'] = []; + + foreach ($this->sources as $sourceUri => $sourceFilename) { + $sourceMap['sources'][] = $this->normalizeFilename($sourceFilename); + } + + // A list of symbol names used by the 'mappings' entry. + $sourceMap['names'] = []; + + // A string with the encoded mapping data. + $sourceMap['mappings'] = $mappings; + + if ($this->options['outputSourceFiles']) { + // An optional list of source content, useful when the 'source' can't be hosted. + // The contents are listed in the same order as the sources above. + // 'null' may be used if some original sources should be retrieved by name. + $sourceMap['sourcesContent'] = $this->getSourcesContent(); + } + + // less.js compat fixes + if (\count($sourceMap['sources']) && empty($sourceMap['sourceRoot'])) { + unset($sourceMap['sourceRoot']); + } + + return json_encode($sourceMap, JSON_UNESCAPED_SLASHES); + } + + /** + * Returns the sources contents + * + * @return string[]|null + */ + protected function getSourcesContent() + { + if (empty($this->sources)) { + return null; + } + + $content = []; + + foreach ($this->sources as $sourceFile) { + $content[] = file_get_contents($sourceFile); + } + + return $content; + } + + /** + * Generates the mappings string + * + * @param string $prefix A prefix added in the output file, which needs to shift mappings + * + * @return string + */ + public function generateMappings($prefix = '') + { + if (! \count($this->mappings)) { + return ''; + } + + $prefixLines = substr_count($prefix, "\n"); + $lastPrefixNewLine = strrpos($prefix, "\n"); + $lastPrefixLineStart = false === $lastPrefixNewLine ? 0 : $lastPrefixNewLine + 1; + $prefixColumn = strlen($prefix) - $lastPrefixLineStart; + + $this->sourceKeys = array_flip(array_keys($this->sources)); + + // group mappings by generated line number. + $groupedMap = $groupedMapEncoded = []; + + foreach ($this->mappings as $m) { + $groupedMap[$m['generated_line']][] = $m; + } + + ksort($groupedMap); + + $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0; + + foreach ($groupedMap as $lineNumber => $lineMap) { + if ($lineNumber > 1) { + // The prefix only impacts the column for the first line of the original output + $prefixColumn = 0; + } + $lineNumber += $prefixLines; + + while (++$lastGeneratedLine < $lineNumber) { + $groupedMapEncoded[] = ';'; + } + + $lineMapEncoded = []; + $lastGeneratedColumn = 0; + + foreach ($lineMap as $m) { + $generatedColumn = $m['generated_column'] + $prefixColumn; + + $mapEncoded = $this->encoder->encode($generatedColumn - $lastGeneratedColumn); + $lastGeneratedColumn = $generatedColumn; + + // find the index + if ($m['source_file']) { + $index = $this->findFileIndex($m['source_file']); + + if ($index !== false) { + $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex); + $lastOriginalIndex = $index; + // lines are stored 0-based in SourceMap spec version 3 + $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine); + $lastOriginalLine = $m['original_line'] - 1; + $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn); + $lastOriginalColumn = $m['original_column']; + } + } + + $lineMapEncoded[] = $mapEncoded; + } + + $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';'; + } + + return rtrim(implode($groupedMapEncoded), ';'); + } + + /** + * Finds the index for the filename + * + * @param string $filename + * + * @return integer|false + */ + protected function findFileIndex($filename) + { + return $this->sourceKeys[$filename]; + } + + /** + * Normalize filename + * + * @param string $filename + * + * @return string + */ + protected function normalizeFilename($filename) + { + $filename = $this->fixWindowsPath($filename); + $rootpath = $this->options['sourceMapRootpath']; + $basePath = $this->options['sourceMapBasepath']; + + // "Trim" the 'sourceMapBasepath' from the output filename. + if (\strlen($basePath) && strpos($filename, $basePath) === 0) { + $filename = substr($filename, \strlen($basePath)); + } + + // Remove extra leading path separators. + if (strpos($filename, '\\') === 0 || strpos($filename, '/') === 0) { + $filename = substr($filename, 1); + } + + return $rootpath . $filename; + } + + /** + * Fix windows paths + * + * @param string $path + * @param boolean $addEndSlash + * + * @return string + */ + public function fixWindowsPath($path, $addEndSlash = false) + { + $slash = ($addEndSlash) ? '/' : ''; + + if (! empty($path)) { + $path = str_replace('\\', '/', $path); + $path = rtrim($path, '/') . $slash; + } + + return $path; + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Type.php b/plugins/admin/vendor/scssphp/scssphp/src/Type.php new file mode 100644 index 0000000..fb2a1d7 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Type.php @@ -0,0 +1,76 @@ + + */ +class Type +{ + const T_ASSIGN = 'assign'; + const T_AT_ROOT = 'at-root'; + const T_BLOCK = 'block'; + /** @deprecated */ + const T_BREAK = 'break'; + const T_CHARSET = 'charset'; + const T_COLOR = 'color'; + const T_COMMENT = 'comment'; + /** @deprecated */ + const T_CONTINUE = 'continue'; + /** @deprecated */ + const T_CONTROL = 'control'; + const T_CUSTOM_PROPERTY = 'custom'; + const T_DEBUG = 'debug'; + const T_DIRECTIVE = 'directive'; + const T_EACH = 'each'; + const T_ELSE = 'else'; + const T_ELSEIF = 'elseif'; + const T_ERROR = 'error'; + const T_EXPRESSION = 'exp'; + const T_EXTEND = 'extend'; + const T_FOR = 'for'; + const T_FUNCTION = 'function'; + const T_FUNCTION_REFERENCE = 'function-reference'; + const T_FUNCTION_CALL = 'fncall'; + const T_HSL = 'hsl'; + const T_HWB = 'hwb'; + const T_IF = 'if'; + const T_IMPORT = 'import'; + const T_INCLUDE = 'include'; + const T_INTERPOLATE = 'interpolate'; + const T_INTERPOLATED = 'interpolated'; + const T_KEYWORD = 'keyword'; + const T_LIST = 'list'; + const T_MAP = 'map'; + const T_MEDIA = 'media'; + const T_MEDIA_EXPRESSION = 'mediaExp'; + const T_MEDIA_TYPE = 'mediaType'; + const T_MEDIA_VALUE = 'mediaValue'; + const T_MIXIN = 'mixin'; + const T_MIXIN_CONTENT = 'mixin_content'; + const T_NESTED_PROPERTY = 'nestedprop'; + const T_NOT = 'not'; + const T_NULL = 'null'; + const T_NUMBER = 'number'; + const T_RETURN = 'return'; + const T_ROOT = 'root'; + const T_SCSSPHP_IMPORT_ONCE = 'scssphp-import-once'; + const T_SELF = 'self'; + const T_STRING = 'string'; + const T_UNARY = 'unary'; + const T_VARIABLE = 'var'; + const T_WARN = 'warn'; + const T_WHILE = 'while'; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Util.php b/plugins/admin/vendor/scssphp/scssphp/src/Util.php new file mode 100644 index 0000000..62cd2a2 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Util.php @@ -0,0 +1,184 @@ + + * + * @internal + */ +class Util +{ + /** + * Asserts that `value` falls within `range` (inclusive), leaving + * room for slight floating-point errors. + * + * @param string $name The name of the value. Used in the error message. + * @param Range $range Range of values. + * @param array|Number $value The value to check. + * @param string $unit The unit of the value. Used in error reporting. + * + * @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin. + * + * @throws \ScssPhp\ScssPhp\Exception\RangeException + */ + public static function checkRange($name, Range $range, $value, $unit = '') + { + $val = $value[1]; + $grace = new Range(-0.00001, 0.00001); + + if (! \is_numeric($val)) { + throw new RangeException("$name {$val} is not a number."); + } + + if ($range->includes($val)) { + return $val; + } + + if ($grace->includes($val - $range->first)) { + return $range->first; + } + + if ($grace->includes($val - $range->last)) { + return $range->last; + } + + throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit"); + } + + /** + * Encode URI component + * + * @param string $string + * + * @return string + */ + public static function encodeURIComponent($string) + { + $revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')']; + + return strtr(rawurlencode($string), $revert); + } + + /** + * mb_chr() wrapper + * + * @param integer $code + * + * @return string + */ + public static function mbChr($code) + { + // Use the native implementation if available, but not on PHP 7.2 as mb_chr(0) is buggy there + if (\PHP_VERSION_ID > 70300 && \function_exists('mb_chr')) { + return mb_chr($code, 'UTF-8'); + } + + if (0x80 > $code %= 0x200000) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xC0 | $code >> 6) . \chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = \chr(0xE0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F); + } else { + $s = \chr(0xF0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3F) + . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F); + } + + return $s; + } + + /** + * mb_strlen() wrapper + * + * @param string $string + * @return int + */ + public static function mbStrlen($string) + { + // Use the native implementation if available. + if (\function_exists('mb_strlen')) { + return mb_strlen($string, 'UTF-8'); + } + + if (\function_exists('iconv_strlen')) { + return (int) @iconv_strlen($string, 'UTF-8'); + } + + throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); + } + + /** + * mb_substr() wrapper + * @param string $string + * @param int $start + * @param null|int $length + * @return string + */ + public static function mbSubstr($string, $start, $length = null) + { + // Use the native implementation if available. + if (\function_exists('mb_substr')) { + return mb_substr($string, $start, $length, 'UTF-8'); + } + + if (\function_exists('iconv_substr')) { + if ($start < 0) { + $start = static::mbStrlen($string) + $start; + if ($start < 0) { + $start = 0; + } + } + + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = static::mbStrlen($string) + $length - $start; + if ($length < 0) { + return ''; + } + } + + return (string)iconv_substr($string, $start, $length, 'UTF-8'); + } + + throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); + } + + /** + * mb_strpos wrapper + * @param string $haystack + * @param string $needle + * @param int $offset + * + * @return int|false + */ + public static function mbStrpos($haystack, $needle, $offset = 0) + { + if (\function_exists('mb_strpos')) { + return mb_strpos($haystack, $needle, $offset, 'UTF-8'); + } + + if (\function_exists('iconv_strpos')) { + return iconv_strpos($haystack, $needle, $offset, 'UTF-8'); + } + + throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php b/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php new file mode 100644 index 0000000..f399e41 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php @@ -0,0 +1,77 @@ +parseValue($source, $value)) { + throw new \InvalidArgumentException(sprintf('Invalid value source "%s".', $source)); + } + + return $value; + } + + /** + * Converts a PHP value to a Sass value + * + * The returned value is guaranteed to be supported by the + * Compiler methods for registering custom variables. No other + * guarantee about it is provided. It should be considered + * opaque values by the caller. + * + * @param mixed $value + * + * @return mixed + */ + public static function fromPhp($value) + { + if ($value instanceof Number) { + return $value; + } + + if (is_array($value) && isset($value[0]) && \in_array($value[0], [Type::T_NULL, Type::T_COLOR, Type::T_KEYWORD, Type::T_LIST, Type::T_MAP, Type::T_STRING])) { + return $value; + } + + if ($value === null) { + return Compiler::$null; + } + + if ($value === true) { + return Compiler::$true; + } + + if ($value === false) { + return Compiler::$false; + } + + if ($value === '') { + return Compiler::$emptyString; + } + + if (\is_int($value) || \is_float($value)) { + return new Number($value, ''); + } + + if (\is_string($value)) { + return [Type::T_STRING, '"', [$value]]; + } + + throw new \InvalidArgumentException(sprintf('Cannot convert the value of type "%s" to a Sass value.', gettype($value))); + } +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Version.php b/plugins/admin/vendor/scssphp/scssphp/src/Version.php new file mode 100644 index 0000000..62c8006 --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Version.php @@ -0,0 +1,23 @@ + + */ +class Version +{ + const VERSION = '1.8.1'; +} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Warn.php b/plugins/admin/vendor/scssphp/scssphp/src/Warn.php new file mode 100644 index 0000000..592b44c --- /dev/null +++ b/plugins/admin/vendor/scssphp/scssphp/src/Warn.php @@ -0,0 +1,84 @@ + + + + + + \ No newline at end of file diff --git a/plugins/anchors/CHANGELOG.md b/plugins/anchors/CHANGELOG.md new file mode 100644 index 0000000..d5ada54 --- /dev/null +++ b/plugins/anchors/CHANGELOG.md @@ -0,0 +1,65 @@ +# v1.6.0 +## 11/24/2021 + +1. [](#new) + * Added new option `copy_to_clipboard` to automatically copy the link to clipboard +2. [](#improved) + * Removed reliance on `JQuery` for DOM ready check + * Updated `anchors.js` to version 4.3.1 + +# v1.5.4 +## 12/02/2020 + +1. [](#improved) + * Updated `anchors.js` to version 4.3.0 + * Requires Grav 1.6 + +# v1.5.3 +## 03/30/2019 + +1. [](#improved) + * Updated `anchors.js` to version 4.2.0 + * Improved documentation + +# v1.5.2 +## 09/28/2017 + +1. [](#improved) + * Updated `anchors.js` to version 4.1.0 + +# v1.5.1 +## 07/14/2016 + +1. [](#improved) + * Translate some blueprint options + +# v1.5.0 +## 01/06/2016 + +1. [](#improved) + * Disable anchors in Admin + +# v1.4.0 +## 08/25/2015 + +1. [](#improved) + * Added blueprints for Grav Admin plugin + +# v1.3.0 +## 07/20/2015 + +1. [](#new) + * Updated `anchors.js` to version 1.2.1 + * Added new options such as 'placement', 'visible', 'icon' and 'class' + +# v1.2.0 +## 03/01/2015 + +1. [](#new) + * Updated `anchors.js` to version 0.3.0 + +# v1.1.0 +## 11/30/2014 + +1. [](#new) + * ChangeLog started... diff --git a/plugins/anchors/LICENSE b/plugins/anchors/LICENSE new file mode 100644 index 0000000..484793a --- /dev/null +++ b/plugins/anchors/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Grav + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/anchors/README.md b/plugins/anchors/README.md new file mode 100644 index 0000000..cb615da --- /dev/null +++ b/plugins/anchors/README.md @@ -0,0 +1,106 @@ +# Grav Anchors Plugin + + +`anchors` is a [Grav](http://github.com/getgrav/grav) plugin that provides automatic header anchors via the [anchorjs](http://bryanbraun.github.io/anchorjs) Vanilla JS plugin. + +# Installation + +## GPM Installation (Preferred) + +The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm). From the root of your Grav install type: + + bin/gpm install anchors + +## Manual Installation + +If for some reason you can't use GPM you can manually install this plugin. Download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `anchors`. + +You should now have all the plugin files under + + /your/site/grav/user/plugins/anchors + +# Usage + +To best understand how Anchors works, you should read through the original [project documentation](https://github.com/bryanbraun/anchorjs). + +## Show Menu of Anchors + +If you want to use the generated links to also generate a menu from these anchors, just put the function below in the template file Twig: + +``` +{{ anchors(content, tag, terms) }} +``` + +The function accepts 3 parameters: + +* **content:** this parameter is the content of the page in which the function will search for all content and separate only the tags and their contents defined by the second parameter. E.g. `page.content` +* **tag:** this parameter will be the string of the tag used to make the menu. E.g. `h2` +* **terms:** this parameter is to exclude terms that you do not wish to include in the menu formation that is between the tag passed in the second parameter. The value passed is a string separated by comma to identify each term. Ex: `title 01, title 02` + +For example: + +``` +{{ anchors(page.content, 'h2') }} +``` + +When rendered the function will return a formed HTML with `